diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 000000000..31f0e385b --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,5 @@ +# Browsers that we support + +> 1% +last 2 versions +ie 9 diff --git a/.dist.babelrc b/.dist.babelrc new file mode 100644 index 000000000..c73854dbf --- /dev/null +++ b/.dist.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + ["@babel/env", { + "targets": { + "browsers": [ "> 1%", "last 2 versions", "ie 9" ] + } + }] + ], + "plugins": [ "@babel/transform-runtime" ] +} diff --git a/.dist.eslintrc b/.dist.eslintrc new file mode 100644 index 000000000..7fa53158e --- /dev/null +++ b/.dist.eslintrc @@ -0,0 +1,33 @@ +{ + "extends": ["eslint:recommended"], + "env": { + "node": true, + "browser": true, + "amd": true, + "es6": true + }, + "plugins": ["compat"], + "rules": { + "compat/compat": "error", + "no-console": "off", + "no-empty": "off", + "no-extra-semi": "off", + "no-func-assign": "off", + "no-undef": "off", + "no-unused-vars": "off", + "no-useless-escape": "off", + "no-cond-assign": "off" + }, + "globals": { + "regeneratorRuntime": "writable" + }, + "settings": { + "polyfills": [ + "Promise", + "Array.from", + "Symbol", + "Object.getOwnPropertySymbols", + "Object.setPrototypeOf" + ] + } +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..c6c8b3621 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..176a458f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore index d7700a71b..ef4ee3814 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,9 @@ components test/node/fixtures/tmp.json .idea superagent.js -package-lock.json \ No newline at end of file +package-lock.json +*.log +coverage +.nyc_output +lib +dist diff --git a/.lib.babelrc b/.lib.babelrc new file mode 100644 index 000000000..4bc878a65 --- /dev/null +++ b/.lib.babelrc @@ -0,0 +1,9 @@ +{ + "presets": [ + ["@babel/env", { + "targets": { + "node": "6.4.0" + } + }] + ] +} diff --git a/.lib.eslintrc b/.lib.eslintrc new file mode 100644 index 000000000..3a7b69619 --- /dev/null +++ b/.lib.eslintrc @@ -0,0 +1,18 @@ +{ + "extends": ["eslint:recommended", "plugin:node/recommended"], + "rules": { + "node/no-deprecated-api": "off", + "no-console": "off", + "no-unused-vars": "off", + "no-empty": "off" + }, + "overrides": [ + { + "files": [ "lib/client.js" ], + "env": { "browser": true }, + "globals": { + "ActiveXObject": "readable" + } + } + ] +} diff --git a/.npmignore b/.npmignore index c44fd573b..5fb9de452 100644 --- a/.npmignore +++ b/.npmignore @@ -5,3 +5,8 @@ examples lib-cov coverage.html bower.json +coverage +src +.travis.yml +.nojekyll +.nyc_output diff --git a/.remarkignore b/.remarkignore new file mode 100644 index 000000000..9e60a0859 --- /dev/null +++ b/.remarkignore @@ -0,0 +1,3 @@ +CONTRIBUTING.md +HISTORY.md +docs diff --git a/.travis.yml b/.travis.yml index 2eb41ccdf..cd6758155 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,12 +4,12 @@ node_js: - "10" - "8" - "6" - +after_success: + npm run coverage env: global: - SAUCE_USERNAME='shtylman-superagent' - SAUCE_ACCESS_KEY='39a45464-cb1d-4b8d-aa1f-83c7c04fa673' - matrix: include: - node_js: "9" diff --git a/.zuul.yml b/.zuul.yml index a38ee899c..8b229ec5f 100644 --- a/.zuul.yml +++ b/.zuul.yml @@ -13,5 +13,4 @@ browsers: browserify: - transform: name: babelify - presets: - - [ babel-preset-es2015, { loose: true } ] + configFile: './.dist.babelrc' diff --git a/Contributing.md b/CONTRIBUTING.md similarity index 100% rename from Contributing.md rename to CONTRIBUTING.md diff --git a/History.md b/HISTORY.md similarity index 100% rename from History.md rename to HISTORY.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..656b85b62 --- /dev/null +++ b/README.md @@ -0,0 +1,243 @@ +# superagent + +[![build status](https://img.shields.io/travis/visionmedia/superagent.svg)](https://travis-ci.org/visionmedia/superagent) +[![code coverage](https://img.shields.io/codecov/c/github/visionmedia/superagent.svg)](https://codecov.io/gh/visionmedia/superagent) +[![code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) +[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) +[![made with lass](https://img.shields.io/badge/made_with-lass-95CC28.svg)](https://lass.js.org) +[![license](https://img.shields.io/github/license/visionmedia/superagent.svg)](LICENSE) + +> Small progressive client-side HTTP request library, and Node.js module with the same API, sporting many high-level HTTP client features + + +## Table of Contents + +* [Install](#install) +* [Usage](#usage) + * [Node](#node) + * [Browser](#browser) +* [Supported Platforms](#supported-platforms) + * [Required Browser Features](#required-browser-features) +* [Plugins](#plugins) +* [Upgrading from previous versions](#upgrading-from-previous-versions) +* [Contributors](#contributors) +* [License](#license) + + +## Install + +[npm][]: + +```sh +npm install superagent +``` + +[yarn][]: + +```sh +yarn add superagent +``` + + +## Usage + +### Node + +```js +const superagent = require('superagent'); + +superagent + .post('/api/pet') + .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body + .set('X-API-Key', 'foobar') + .set('accept', 'json') + .end((err, res) => { + // Calling the end function will send the request + }); +``` + +### Browser + +**The browser-ready, minified version of `superagent` is only 19 KB!** + +Browser-ready versions of this module are available via [jsdelivr][], [unpkg][], and also in the `node_modules/superagent/dist` folder in downloads of the `superagent` package. + +> Note that we also provide unminified versions with `.js` instead of `.min.js` file extensions. + +#### VanillaJS + +This is the solution for you if you're just using ` + + + +``` + +#### Bundler + +If you are using [browserify][], [webpack][], [rollup][], or another bundler, then you can follow the same usage as [Node](#node) above. + + +## Supported Platforms + +* Node: v6.x+ +* Browsers (see [.browserslistrc](.browserslistrc)): + + ```sh + npx browserslist + ``` + + ```sh + and_chr 71 + and_ff 64 + and_qq 1.2 + and_uc 11.8 + android 67 + android 4.4.3-4.4.4 + baidu 7.12 + bb 10 + bb 7 + chrome 73 + chrome 72 + chrome 71 + edge 18 + edge 17 + firefox 66 + firefox 65 + ie 11 + ie 10 + ie 9 + ie_mob 11 + ie_mob 10 + ios_saf 12.0-12.1 + ios_saf 11.3-11.4 + op_mini all + op_mob 46 + op_mob 12.1 + opera 58 + opera 57 + safari 12 + safari 11.1 + samsung 8.2 + samsung 7.2-7.4 + ``` + +### Required Browser Features + +* IE9 requires a polyfill for `window.FormData` (we recommend [formdata-polyfill][]) + + +## Plugins + +SuperAgent is easily extended via plugins. + +```js +const nocache = require('superagent-no-cache'); +const superagent = require('superagent'); +const prefix = require('superagent-prefix')('/static'); + +superagent + .get('/some-url') + .query({ action: 'edit', city: 'London' }) // query string + .use(prefix) // Prefixes *only* this request + .use(nocache) // Prevents caching of *only* this request + .end((err, res) => { + // Do something + }); +``` + +Existing plugins: + +* [superagent-no-cache](https://github.com/johntron/superagent-no-cache) - prevents caching by including Cache-Control header +* [superagent-prefix](https://github.com/johntron/superagent-prefix) - prefixes absolute URLs (useful in test environment) +* [superagent-suffix](https://github.com/timneutkens1/superagent-suffix) - suffix URLs with a given path +* [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL +* [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API +* [superagent-cache](https://github.com/jpodwys/superagent-cache) - A global SuperAgent patch with built-in, flexible caching +* [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching +* [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent +* [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases +* [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax +* [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests +* [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent +* [superagent-verbose-errors](https://github.com/jcoreio/superagent-verbose-errors) - include response body in error messages for failed requests + +Please prefix your plugin with `superagent-*` so that it can easily be found by others. + +For SuperAgent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki). + + +## Upgrading from previous versions + +Our breaking changes are mostly in rarely used functionality and from stricter error handling. + +* [4.x to 5.x](https://github.com/visionmedia/superagent/releases/tag/v5.0.0): + * Ensure you're running Node 8.8.1 or later. + * We've implemented the build setup of [Lass](https://lass.js.org) to simplify our stack and linting + * Browserified build size has been reduced from 48KB to 19KB (via `tinyify` and the latest version of Babel using `@babel/preset-env` and `.browserslistrc`) + * Linting support has been added using `caniuse-lite` and `eslint-plugin-compat` + * We can now target what versions of Node we wish to support more easily using `.babelrc` +* [3.x to 4.x](https://github.com/visionmedia/superagent/releases/tag/v4.0.0-alpha.1): + * Ensure you're running Node 6 or later. We've dropped support for Node 4. + * We've started using ES6 and for compatibility with Internet Explorer you may need to use Babel. + * We suggest migrating from `.end()` callbacks to `.then()` or `await`. +* [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0): + * Ensure you're running Node 4 or later. We've dropped support for Node 0.x. + * Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage. +* [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0): + * If you use `.parse()` in the _browser_ version, rename it to `.serialize()`. + * If you rely on `undefined` in query-string values being sent literally as the text "undefined", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value). + * If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object. +* 0.x to 1.x: + * Instead of 1-argument callback `.end(function(res){})` use `.then(res => {})`. + + +## Contributors + +| Name | +| ------------------- | +| **Kornel Lesiński** | +| **Peter Lyons** | +| **Hunter Loftis** | +| **Nick Baugh** | + + +## License + +[MIT](LICENSE) © TJ Holowaychuk + + +## + +[npm]: https://www.npmjs.com/ + +[yarn]: https://yarnpkg.com/ + +[formdata-polyfill]: https://www.npmjs.com/package/formdata-polyfill + +[jsdelivr]: https://www.jsdelivr.com/ + +[unpkg]: https://unpkg.com/ + +[browserify]: https://github.com/browserify/browserify + +[webpack]: https://github.com/webpack/webpack + +[rollup]: https://github.com/rollup/rollup diff --git a/Readme.md b/Readme.md deleted file mode 100644 index fc2057c37..000000000 --- a/Readme.md +++ /dev/null @@ -1,136 +0,0 @@ -# SuperAgent [![Build Status](https://travis-ci.org/visionmedia/superagent.svg?branch=master)](https://travis-ci.org/visionmedia/superagent) [![passively maintained.](https://img.shields.io/badge/maintenance-passively--maintained-yellowgreen.svg) ![Maintainers Wanted](https://img.shields.io/badge/maintainers-wanted-red.svg)](https://github.com/visionmedia/superagent/issues/1450) - -SuperAgent is a small progressive __client-side__ and __Node.js__ HTTP request library, sporting many high-level HTTP client features. View the [docs](https://visionmedia.github.io/superagent/). - -![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png) - -## Installation - -node: - -``` -$ npm install superagent -``` - -Works with [browserify](https://github.com/substack/node-browserify) and [webpack](https://github.com/visionmedia/superagent/wiki/SuperAgent-for-Webpack). - -```js -const res = await request - .post('/api/pet') - .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body - .set('X-API-Key', 'foobar') - .set('accept', 'json'); -``` - -## Supported browsers and Node versions - -Tested browsers: - -- Latest Firefox, Chrome, Safari -- Latest Android, iPhone -- IE10 through latest. IE9 with polyfills. Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`. - -Node 6 or later is required. For older browsers ES6-to-ES5 translation (like Babel) is required. - -## Plugins - -SuperAgent is easily extended via plugins. - -```js -const nocache = require('superagent-no-cache'); -const request = require('superagent'); -const prefix = require('superagent-prefix')('/static'); - -request - .get('/some-url') - .query({ action: 'edit', city: 'London' }) // query string - .use(prefix) // Prefixes *only* this request - .use(nocache) // Prevents caching of *only* this request - .end((err, res) => { - // Do something - }); -``` - -Existing plugins: - * [superagent-no-cache](https://github.com/johntron/superagent-no-cache) - prevents caching by including Cache-Control header - * [superagent-prefix](https://github.com/johntron/superagent-prefix) - prefixes absolute URLs (useful in test environment) - * [superagent-suffix](https://github.com/timneutkens1/superagent-suffix) - suffix URLs with a given path - * [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL - * [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API - * [superagent-cache](https://github.com/jpodwys/superagent-cache) - A global SuperAgent patch with built-in, flexible caching - * [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching - * [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent - * [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases - * [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax - * [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests - * [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent - * [superagent-verbose-errors](https://github.com/jcoreio/superagent-verbose-errors) - include response body in error messages for failed requests - * [superagent-cheerio](https://github.com/mmmmmrob/superagent-cheerio) - include cheerio as `res.$` on html responses - -Please prefix your plugin with `superagent-*` so that it can easily be found by others. - -For SuperAgent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki). - -## Upgrading from previous versions: - -Our breaking changes are mostly in rarely used functionality and from stricter error handling. - -* [3.x to 4.x](https://github.com/visionmedia/superagent/releases/tag/v4.0.0-alpha.1): - - Ensure you're running Node 6 or later. We've dropped support for Node 4. - - We've started using ES6 and for compatibility with Internet Explorer you may need to use Babel. - - We suggest migrating from `.end()` callbacks to `.then()` or `await`. -* [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0): - - Ensure you're running Node 4 or later. We've dropped support for Node 0.x. - - Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage. -* [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0): - - If you use `.parse()` in the *browser* version, rename it to `.serialize()`. - - If you rely on `undefined` in query-string values being sent literally as the text "undefined", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value). - - If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object. -* 0.x to 1.x: - - Instead of 1-argument callback `.end(function(res){})` use `.then(res => {})`. - -## Running node tests - -Install dependencies: - -```shell -$ npm install -``` -Run em! - -```shell -$ make test -``` - -## Running browser tests - -Install dependencies: - -```shell -$ npm install -``` - -Start the test runner: - -```shell -$ make test-browser-local -``` - -Visit `http://localhost:4000/__zuul` in your browser. - -Edit tests and refresh your browser. You do not have to restart the test runner. - - -## Packaging Notes for Developers - -**npm (for node)** is configured via the `package.json` file and the `.npmignore` file. Key metadata in the `package.json` file is the `version` field which should be changed according to semantic versioning and have a 1-1 correspondence with git tags. So for example, if you were to `git show v1.5.0:package.json | grep version`, you should see `"version": "1.5.0",` and this should hold true for every release. This can be handled via the `npm version` command. Be aware that when publishing, npm will presume the version being published should also be tagged in npm as `latest`, which is OK for normal incremental releases. For betas and minor/patch releases to older versions, be sure to include `--tag` appropriately to avoid an older release getting tagged as `latest`. - -**npm (for browser standalone)** When we publish versions to npm, we run `make superagent.js` which generates the standalone `superagent.js` file via `browserify`, and this file is included in the package published to npm (but this file is never checked into the git repository). If users want to install via npm but serve a single `.js` file directly to the browser, the `node_modules/superagent/superagent.js` is a standalone browserified file ready to go for that purpose. It is not minified. - -**npm (for browserify)** is handled via the `package.json` `browser` field which allows users to install SuperAgent via npm, reference it from their browser code with `require('superagent')`, and then build their own application bundle via `browserify`, which will use `lib/client.js` as the SuperAgent entrypoint. - -**bower** is configured via the `bower.json` file. Bower installs files directly from git/github without any transformation, so you *must* use Browserify or Webpack (or use npm). - -## License - -MIT diff --git a/bower.json b/bower.json deleted file mode 100644 index a5fcf4f88..000000000 --- a/bower.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "superagent", - "main": "lib/client.js", - "dependencies": { - "emitter": "component-emitter#^1.1.2" - } -} diff --git a/examples/simple-get.js b/examples/simple-get.js index 68a9de993..df61e4cd3 100644 --- a/examples/simple-get.js +++ b/examples/simple-get.js @@ -1,13 +1,13 @@ - /** * Module dependencies. */ -var request = require('..'); +const request = require('..'); -var url = 'https://gist.githubusercontent.com/reinaldo13/cdbb4d663ba23410a77b/raw/0345267767d50790051951ddc460e2699649de2b/it-works.txt'; +const url = + 'https://gist.githubusercontent.com/reinaldo13/cdbb4d663ba23410a77b/raw/0345267767d50790051951ddc460e2699649de2b/it-works.txt'; -request.get(url, function(err, res){ +request.get(url, (err, res) => { if (err) throw err; console.log(res.text); }); diff --git a/lib/agent-base.js b/lib/agent-base.js index 546fb3bee..cfda373e7 100644 --- a/lib/agent-base.js +++ b/lib/agent-base.js @@ -1,20 +1,25 @@ +"use strict"; + function Agent() { this._defaults = []; } -["use", "on", "once", "set", "query", "type", "accept", "auth", "withCredentials", "sortQuery", "retry", "ok", "redirects", - "timeout", "buffer", "serialize", "parse", "ca", "key", "pfx", "cert"].forEach(fn => { - /** Default setting for all requests from this agent */ - Agent.prototype[fn] = function(...args) { - this._defaults.push({fn, args}); +['use', 'on', 'once', 'set', 'query', 'type', 'accept', 'auth', 'withCredentials', 'sortQuery', 'retry', 'ok', 'redirects', 'timeout', 'buffer', 'serialize', 'parse', 'ca', 'key', 'pfx', 'cert'].forEach(fn => { + // Default setting for all requests from this agent + Agent.prototype[fn] = function (...args) { + this._defaults.push({ + fn, + args + }); + return this; - } + }; }); -Agent.prototype._setDefaults = function(req) { - this._defaults.forEach(def => { - req[def.fn].apply(req, def.args); - }); +Agent.prototype._setDefaults = function (req) { + this._defaults.forEach(def => { + req[def.fn](...def.args); + }); }; -module.exports = Agent; +module.exports = Agent; \ No newline at end of file diff --git a/lib/client.js b/lib/client.js index b1d192e67..30788219c 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1,67 +1,102 @@ +"use strict"; + /** * Root reference for iframes. */ - let root; -if (typeof window !== 'undefined') { // Browser window + +if (typeof window !== 'undefined') { + // Browser window root = window; -} else if (typeof self !== 'undefined') { // Web Worker +} else if (typeof self === 'undefined') { + // Other environments + console.warn('Using browser-only version of superagent in non-browser environment'); + root = void 0; +} else { + // Web Worker root = self; -} else { // Other environments - console.warn("Using browser-only version of superagent in non-browser environment"); - root = this; -} +} // Array.from() is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import + + +require('core-js/features/array/from'); // Symbol is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import + + +require('core-js/features/symbol'); // Object.getOwnPropertySymbols() is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import + + +require('core-js/features/object/get-own-property-symbols'); // Object.setPrototypeOf() is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import + + +require('core-js/features/object/set-prototype-of'); const Emitter = require('component-emitter'); + const RequestBase = require('./request-base'); + const isObject = require('./is-object'); + const ResponseBase = require('./response-base'); -const Agent = require('./agent-base'); +const Agent = require('./agent-base'); /** * Noop. */ -function noop(){}; +function noop() {} /** * Expose `request`. */ -const request = exports = module.exports = function(method, url) { + +module.exports = function (method, url) { // callback - if ('function' == typeof url) { + if (typeof url === 'function') { return new exports.Request('GET', method).end(url); - } + } // url first + - // url first - if (1 == arguments.length) { + if (arguments.length === 1) { return new exports.Request('GET', method); } return new exports.Request(method, url); }; +exports = module.exports; +const request = exports; exports.Request = Request; - /** * Determine XHR. */ request.getXHR = () => { - if (root.XMLHttpRequest - && (!root.location || 'file:' != root.location.protocol - || !root.ActiveXObject)) { - return new XMLHttpRequest; - } else { - try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} - try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + if (root.XMLHttpRequest && (!root.location || root.location.protocol !== 'file:' || !root.ActiveXObject)) { + return new XMLHttpRequest(); } - throw Error("Browser-only version of superagent could not find XHR"); -}; + try { + return new ActiveXObject('Microsoft.XMLHTTP'); + } catch (err) {} + + try { + return new ActiveXObject('Msxml2.XMLHTTP.6.0'); + } catch (err) {} + + try { + return new ActiveXObject('Msxml2.XMLHTTP.3.0'); + } catch (err) {} + + try { + return new ActiveXObject('Msxml2.XMLHTTP'); + } catch (err) {} + + throw new Error('Browser-only version of superagent could not find XHR'); +}; /** * Removes leading and trailing whitespace, added to support IE. * @@ -70,10 +105,8 @@ request.getXHR = () => { * @api private */ -const trim = ''.trim - ? s => s.trim() - : s => s.replace(/(^\s*|\s*$)/g, ''); +const trim = ''.trim ? s => s.trim() : s => s.replace(/(^\s*|\s*$)/g, ''); /** * Serialize the given `obj`. * @@ -85,12 +118,13 @@ const trim = ''.trim function serialize(obj) { if (!isObject(obj)) return obj; const pairs = []; + for (const key in obj) { - pushEncodedKeyValuePair(pairs, key, obj[key]); + if (Object.prototype.hasOwnProperty.call(obj, key)) pushEncodedKeyValuePair(pairs, key, obj[key]); } + return pairs.join('&'); } - /** * Helps 'serialize' with serializing arrays. * Mutates the pairs array. @@ -100,38 +134,37 @@ function serialize(obj) { * @param {Mixed} val */ + function pushEncodedKeyValuePair(pairs, key, val) { - if (val != null) { + if (val !== null) { if (Array.isArray(val)) { val.forEach(v => { pushEncodedKeyValuePair(pairs, key, v); }); } else if (isObject(val)) { - for(const subkey in val) { - pushEncodedKeyValuePair(pairs, `${key}[${subkey}]`, val[subkey]); + for (const subkey in val) { + if (Object.prototype.hasOwnProperty.call(val, subkey)) pushEncodedKeyValuePair(pairs, `${key}[${subkey}]`, val[subkey]); } } else { - pairs.push(encodeURIComponent(key) - + '=' + encodeURIComponent(val)); + pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); } } else if (val === null) { pairs.push(encodeURIComponent(key)); } } - /** * Expose serialization method. */ -request.serializeObject = serialize; +request.serializeObject = serialize; /** - * Parse the given x-www-form-urlencoded `str`. - * - * @param {String} str - * @return {Object} - * @api private - */ + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ function parseString(str) { const obj = {}; @@ -142,23 +175,22 @@ function parseString(str) { for (let i = 0, len = pairs.length; i < len; ++i) { pair = pairs[i]; pos = pair.indexOf('='); - if (pos == -1) { + + if (pos === -1) { obj[decodeURIComponent(pair)] = ''; } else { - obj[decodeURIComponent(pair.slice(0, pos))] = - decodeURIComponent(pair.slice(pos + 1)); + obj[decodeURIComponent(pair.slice(0, pos))] = decodeURIComponent(pair.slice(pos + 1)); } } return obj; } - /** * Expose parser. */ -request.parseString = parseString; +request.parseString = parseString; /** * Default MIME type map. * @@ -171,10 +203,9 @@ request.types = { json: 'application/json', xml: 'text/xml', urlencoded: 'application/x-www-form-urlencoded', - 'form': 'application/x-www-form-urlencoded', + form: 'application/x-www-form-urlencoded', 'form-data': 'application/x-www-form-urlencoded' }; - /** * Default serialization map. * @@ -188,21 +219,19 @@ request.serialize = { 'application/x-www-form-urlencoded': serialize, 'application/json': JSON.stringify }; - /** - * Default parsers. - * - * superagent.parse['application/xml'] = function(str){ - * return { object parsed from str }; - * }; - * - */ + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ request.parse = { 'application/x-www-form-urlencoded': parseString, 'application/json': JSON.parse }; - /** * Parse the given header `str` into * an object containing the mapped fields. @@ -223,9 +252,12 @@ function parseHeader(str) { for (let i = 0, len = lines.length; i < len; ++i) { line = lines[i]; index = line.indexOf(':'); - if (index === -1) { // could be empty line, just skip it + + if (index === -1) { + // could be empty line, just skip it continue; } + field = line.slice(0, index).toLowerCase(); val = trim(line.slice(index + 1)); fields[field] = val; @@ -233,7 +265,6 @@ function parseHeader(str) { return fields; } - /** * Check if `mime` is json or has +json structured syntax suffix. * @@ -242,12 +273,12 @@ function parseHeader(str) { * @api private */ + function isJSON(mime) { // should match /json or +json // but not /json-seq - return /[\/+]json($|[^-\w])/.test(mime); + return /[/+]json($|[^-\w])/.test(mime); } - /** * Initialize a new `Response` with the given `xhr`. * @@ -294,38 +325,39 @@ function isJSON(mime) { * @api private */ + function Response(req) { this.req = req; - this.xhr = this.req.xhr; - // responseText is accessible only if responseType is '' or 'text' and on older browsers - this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') - ? this.xhr.responseText - : null; + this.xhr = this.req.xhr; // responseText is accessible only if responseType is '' or 'text' and on older browsers + + this.text = this.req.method !== 'HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text') || typeof this.xhr.responseType === 'undefined' ? this.xhr.responseText : null; this.statusText = this.req.xhr.statusText; - let status = this.xhr.status; - // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + let status = this.xhr.status; // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { status = 204; } + this._setStatusProperties(status); - this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); - // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + + this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + this.header = this.headers; // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but // getResponseHeader still works. so we get content-type even if getting // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this._setHeaderProperties(this.header); - if (null === this.text && req._responseType) { + if (this.text === null && req._responseType) { this.body = this.xhr.response; } else { - this.body = this.req.method != 'HEAD' - ? this._parseBody(this.text ? this.text : this.xhr.response) - : null; + this.body = this.req.method === 'HEAD' ? null : this._parseBody(this.text ? this.text : this.xhr.response); } -} +} // eslint-disable-next-line new-cap -ResponseBase(Response.prototype); +ResponseBase(Response.prototype); /** * Parse the given body `str`. * @@ -337,19 +369,19 @@ ResponseBase(Response.prototype); * @api private */ -Response.prototype._parseBody = function(str) { +Response.prototype._parseBody = function (str) { let parse = request.parse[this.type]; + if (this.req._parser) { return this.req._parser(this, str); } + if (!parse && isJSON(this.type)) { parse = request.parse['application/json']; } - return parse && str && (str.length || str instanceof Object) - ? parse(str) - : null; -}; + return parse && str && (str.length > 0 || str instanceof Object) ? parse(str) : null; +}; /** * Return an `Error` representative of this response. * @@ -357,26 +389,24 @@ Response.prototype._parseBody = function(str) { * @api public */ -Response.prototype.toError = function(){ + +Response.prototype.toError = function () { const req = this.req; const method = req.method; const url = req.url; - const msg = `cannot ${method} ${url} (${this.status})`; const err = new Error(msg); err.status = this.status; err.method = method; err.url = url; - return err; }; - /** * Expose `Response`. */ -request.Response = Response; +request.Response = Response; /** * Initialize a new `Request` with the given `method` and `url`. * @@ -391,22 +421,24 @@ function Request(method, url) { this.method = method; this.url = url; this.header = {}; // preserves header name case + this._header = {}; // coerces header names to lowercase + this.on('end', () => { let err = null; let res = null; try { res = new Response(self); - } catch(e) { + } catch (err2) { err = new Error('Parser is unable to parse the response'); err.parse = true; - err.original = e; - // issue #675: return the raw response if the response parsing fails + err.original = err2; // issue #675: return the raw response if the response parsing fails + if (self.xhr) { // ie9 doesn't have 'response' property - err.rawResponse = typeof self.xhr.responseType == 'undefined' ? self.xhr.responseText : self.xhr.response; - // issue #876: return the http status code if the response parsing fails + err.rawResponse = typeof self.xhr.responseType === 'undefined' ? self.xhr.responseText : self.xhr.response; // issue #876: return the http status code if the response parsing fails + err.status = self.xhr.status ? self.xhr.status : null; err.statusCode = err.status; // backwards-compat only } else { @@ -418,17 +450,17 @@ function Request(method, url) { } self.emit('response', res); - let new_err; + try { if (!self._isResponseOK(res)) { new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); } - } catch(custom_err) { - new_err = custom_err; // ok() callback can throw - } + } catch (err2) { + new_err = err2; // ok() callback can throw + } // #1000 don't catch errors from the callback to avoid double calling it + - // #1000 don't catch errors from the callback to avoid double calling it if (new_err) { new_err.original = err; new_err.response = res; @@ -439,14 +471,15 @@ function Request(method, url) { } }); } - /** * Mixin `Emitter` and `RequestBase`. */ +// eslint-disable-next-line new-cap -Emitter(Request.prototype); -RequestBase(Request.prototype); +Emitter(Request.prototype); // eslint-disable-next-line new-cap + +RequestBase(Request.prototype); /** * Set Content-Type to `type`, mapping values from `request.types`. * @@ -469,11 +502,10 @@ RequestBase(Request.prototype); * @api public */ -Request.prototype.type = function(type){ +Request.prototype.type = function (type) { this.set('Content-Type', request.types[type] || type); return this; }; - /** * Set Accept to `type`, mapping values from `request.types`. * @@ -494,11 +526,11 @@ Request.prototype.type = function(type){ * @api public */ -Request.prototype.accept = function(type){ + +Request.prototype.accept = function (type) { this.set('Accept', request.types[type] || type); return this; }; - /** * Set Authorization field value with `user` and `pass`. * @@ -509,28 +541,32 @@ Request.prototype.accept = function(type){ * @api public */ -Request.prototype.auth = function(user, pass, options){ - if (1 === arguments.length) pass = ''; - if (typeof pass === 'object' && pass !== null) { // pass is optional and can be replaced with options + +Request.prototype.auth = function (user, pass, options) { + if (arguments.length === 1) pass = ''; + + if (typeof pass === 'object' && pass !== null) { + // pass is optional and can be replaced with options options = pass; pass = ''; } + if (!options) { options = { - type: 'function' === typeof btoa ? 'basic' : 'auto', + type: typeof btoa === 'function' ? 'basic' : 'auto' }; } const encoder = string => { - if ('function' === typeof btoa) { + if (typeof btoa === 'function') { return btoa(string); } + throw new Error('Cannot use basic auth, btoa is not a function'); }; return this._auth(user, pass, options, encoder); }; - /** * Add query-string `val`. * @@ -545,12 +581,12 @@ Request.prototype.auth = function(user, pass, options){ * @api public */ -Request.prototype.query = function(val){ - if ('string' != typeof val) val = serialize(val); + +Request.prototype.query = function (val) { + if (typeof val !== 'string') val = serialize(val); if (val) this._query.push(val); return this; }; - /** * Queue the given `file` as an attachment to the specified `field`, * with optional `options` (or filename). @@ -568,24 +604,26 @@ Request.prototype.query = function(val){ * @api public */ -Request.prototype.attach = function(field, file, options){ + +Request.prototype.attach = function (field, file, options) { if (file) { if (this._data) { - throw Error("superagent can't mix .send() and .attach()"); + throw new Error("superagent can't mix .send() and .attach()"); } this._getFormData().append(field, file, options || file.name); } + return this; }; -Request.prototype._getFormData = function(){ +Request.prototype._getFormData = function () { if (!this._formData) { this._formData = new root.FormData(); } + return this._formData; }; - /** * Invoke the callback with `err` and `res` * and handle arity check. @@ -595,7 +633,8 @@ Request.prototype._getFormData = function(){ * @api private */ -Request.prototype.callback = function(err, res){ + +Request.prototype.callback = function (err, res) { if (this._shouldRetry(err, res)) { return this._retry(); } @@ -610,48 +649,49 @@ Request.prototype.callback = function(err, res){ fn(err, res); }; - /** * Invoke callback with x-domain error. * * @api private */ -Request.prototype.crossDomainError = function(){ + +Request.prototype.crossDomainError = function () { const err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); err.crossDomain = true; - err.status = this.status; err.method = this.method; err.url = this.url; - this.callback(err); -}; +}; // This only warns, because the request is still likely to work + -// This only warns, because the request is still likely to work -Request.prototype.buffer = Request.prototype.ca = Request.prototype.agent = function(){ - console.warn("This is not supported in browser version of superagent"); +Request.prototype.agent = function () { + console.warn('This is not supported in browser version of superagent'); return this; }; -// This throws, because it can't send/receive data as expected -Request.prototype.pipe = Request.prototype.write = () => { - throw Error("Streaming is not supported in browser version of superagent"); +Request.prototype.buffer = Request.prototype.ca; +Request.prototype.ca = Request.prototype.agent; // This throws, because it can't send/receive data as expected + +Request.prototype.write = () => { + throw new Error('Streaming is not supported in browser version of superagent'); }; +Request.prototype.pipe = Request.prototype.write; /** * Check if `obj` is a host object, * we don't want to serialize these :) * - * @param {Object} obj - * @return {Boolean} + * @param {Object} obj host object + * @return {Boolean} is a host object * @api private */ -Request.prototype._isHost = function _isHost(obj) { - // Native objects stringify to [object File], [object Blob], [object FormData], etc. - return obj && 'object' === typeof obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]'; -} +Request.prototype._isHost = function (obj) { + // Native objects stringify to [object File], [object Blob], [object FormData], etc. + return obj && typeof obj === 'object' && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]'; +}; /** * Initiate request, invoking callback `fn(res)` * with an instanceof `Response`. @@ -661,95 +701,103 @@ Request.prototype._isHost = function _isHost(obj) { * @api public */ -Request.prototype.end = function(fn){ + +Request.prototype.end = function (fn) { if (this._endCalled) { - console.warn("Warning: .end() was called twice. This is not supported in superagent"); + console.warn('Warning: .end() was called twice. This is not supported in superagent'); } - this._endCalled = true; - // store callback - this._callback = fn || noop; + this._endCalled = true; // store callback + + this._callback = fn || noop; // querystring - // querystring this._finalizeQueryString(); this._end(); }; Request.prototype._setUploadTimeout = function () { - const self = this; + const self = this; // upload timeout it's wokrs only if deadline timeout is off - // upload timeout it's wokrs only if deadline timeout is off if (this._uploadTimeout && !this._uploadTimeoutTimer) { this._uploadTimeoutTimer = setTimeout(() => { self._timeoutError('Upload timeout of ', self._uploadTimeout, 'ETIMEDOUT'); }, this._uploadTimeout); } -}; +}; // eslint-disable-next-line complexity -Request.prototype._end = function() { - if (this._aborted) return this.callback(Error("The request has been aborted even before .end() was called")); +Request.prototype._end = function () { + if (this._aborted) return this.callback(new Error('The request has been aborted even before .end() was called')); const self = this; - const xhr = (this.xhr = request.getXHR()); + this.xhr = request.getXHR(); + const xhr = this.xhr; let data = this._formData || this._data; - this._setTimeouts(); + this._setTimeouts(); // state change + - // state change xhr.onreadystatechange = () => { const readyState = xhr.readyState; + if (readyState >= 2 && self._responseTimeoutTimer) { clearTimeout(self._responseTimeoutTimer); } - if (4 != readyState) { - return; - } - // In IE9, reads to any property (e.g. status) off of an aborted XHR will + if (readyState !== 4) { + return; + } // In IE9, reads to any property (e.g. status) off of an aborted XHR will // result in the error "Could not complete the operation due to error c00c023f" + + let status; - try { status = xhr.status } catch(e) { status = 0; } + + try { + status = xhr.status; + } catch (err) { + status = 0; + } if (!status) { if (self.timedout || self._aborted) return; return self.crossDomainError(); } + self.emit('end'); - }; + }; // progress - // progress - const handleProgress = (direction, e) => { + const handleProgress = (direction, e) => { if (e.total > 0) { e.percent = e.loaded / e.total * 100; - - if(e.percent === 100) { - clearTimeout(self._uploadTimeoutTimer); + + if (e.percent === 100) { + clearTimeout(self._uploadTimeoutTimer); } } e.direction = direction; self.emit('progress', e); }; + if (this.hasListeners('progress')) { try { - xhr.onprogress = handleProgress.bind(null, 'download'); + xhr.addEventListener('progress', handleProgress.bind(null, 'download')); + if (xhr.upload) { - xhr.upload.onprogress = handleProgress.bind(null, 'upload'); + xhr.upload.addEventListener('progress', handleProgress.bind(null, 'upload')); } - } catch(e) { - // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + } catch (err) {// Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. // Reported here: // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context } } - if(xhr.upload){ + if (xhr.upload) { this._setUploadTimeout(); - } + } // initiate request + - // initiate request try { if (this.username && this.password) { xhr.open(this.method, this.url, true, this.username, this.password); @@ -759,57 +807,56 @@ Request.prototype._end = function() { } catch (err) { // see #1149 return this.callback(err); - } + } // CORS + - // CORS - if (this._withCredentials) xhr.withCredentials = true; + if (this._withCredentials) xhr.withCredentials = true; // body - // body - if (!this._formData && 'GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { + if (!this._formData && this.method !== 'GET' && this.method !== 'HEAD' && typeof data !== 'string' && !this._isHost(data)) { // serialize stuff const contentType = this._header['content-type']; let serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; + if (!serialize && isJSON(contentType)) { serialize = request.serialize['application/json']; } + if (serialize) data = serialize(data); - } + } // set header fields - // set header fields - for (const field in this.header) { - if (null == this.header[field]) continue; - if (this.header.hasOwnProperty(field)) - xhr.setRequestHeader(field, this.header[field]); + for (const field in this.header) { + if (this.header[field] === null) continue; + if (Object.prototype.hasOwnProperty.call(this.header, field)) xhr.setRequestHeader(field, this.header[field]); } if (this._responseType) { xhr.responseType = this._responseType; - } + } // send stuff - // send stuff - this.emit('request', this); - // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) + this.emit('request', this); // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) // We need null here if data is undefined - xhr.send(typeof data !== 'undefined' ? data : null); + + xhr.send(typeof data === 'undefined' ? null : data); }; request.agent = () => new Agent(); -["GET", "POST", "OPTIONS", "PATCH", "PUT", "DELETE"].forEach(method => { - Agent.prototype[method.toLowerCase()] = function(url, fn) { +['GET', 'POST', 'OPTIONS', 'PATCH', 'PUT', 'DELETE'].forEach(method => { + Agent.prototype[method.toLowerCase()] = function (url, fn) { const req = new request.Request(method, url); + this._setDefaults(req); + if (fn) { req.end(fn); } + return req; }; }); - -Agent.prototype.del = Agent.prototype['delete']; - +Agent.prototype.del = Agent.prototype.delete; /** * GET `url` with optional callback `fn(res)`. * @@ -822,12 +869,16 @@ Agent.prototype.del = Agent.prototype['delete']; request.get = (url, data, fn) => { const req = request('GET', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.query(data); if (fn) req.end(fn); return req; }; - /** * HEAD `url` with optional callback `fn(res)`. * @@ -838,14 +889,19 @@ request.get = (url, data, fn) => { * @api public */ + request.head = (url, data, fn) => { const req = request('HEAD', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.query(data); if (fn) req.end(fn); return req; }; - /** * OPTIONS query to `url` with optional callback `fn(res)`. * @@ -856,14 +912,19 @@ request.head = (url, data, fn) => { * @api public */ + request.options = (url, data, fn) => { const req = request('OPTIONS', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.send(data); if (fn) req.end(fn); return req; }; - /** * DELETE `url` with optional `data` and callback `fn(res)`. * @@ -874,17 +935,22 @@ request.options = (url, data, fn) => { * @api public */ + function del(url, data, fn) { const req = request('DELETE', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.send(data); if (fn) req.end(fn); return req; } -request['del'] = del; -request['delete'] = del; - +request.del = del; +request.delete = del; /** * PATCH `url` with optional `data` and callback `fn(res)`. * @@ -897,12 +963,16 @@ request['delete'] = del; request.patch = (url, data, fn) => { const req = request('PATCH', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.send(data); if (fn) req.end(fn); return req; }; - /** * POST `url` with optional `data` and callback `fn(res)`. * @@ -913,14 +983,19 @@ request.patch = (url, data, fn) => { * @api public */ + request.post = (url, data, fn) => { const req = request('POST', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.send(data); if (fn) req.end(fn); return req; }; - /** * PUT `url` with optional `data` and callback `fn(res)`. * @@ -931,10 +1006,16 @@ request.post = (url, data, fn) => { * @api public */ + request.put = (url, data, fn) => { const req = request('PUT', url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) req.send(data); if (fn) req.end(fn); return req; -}; +}; \ No newline at end of file diff --git a/lib/is-object.js b/lib/is-object.js index fa69d81a9..77b6a126b 100644 --- a/lib/is-object.js +++ b/lib/is-object.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Check if `obj` is an object. @@ -7,9 +7,8 @@ * @return {Boolean} * @api private */ - function isObject(obj) { - return null !== obj && 'object' === typeof obj; + return obj !== null && typeof obj === 'object'; } -module.exports = isObject; +module.exports = isObject; \ No newline at end of file diff --git a/lib/node/agent.js b/lib/node/agent.js index 4de7422f7..8bd3398d6 100644 --- a/lib/node/agent.js +++ b/lib/node/agent.js @@ -1,22 +1,29 @@ 'use strict'; - /** * Module dependencies. */ +// eslint-disable-next-line node/no-deprecated-api + +const _require = require('url'), + parse = _require.parse; + +const _require2 = require('cookiejar'), + CookieJar = _require2.CookieJar; + +const _require3 = require('cookiejar'), + CookieAccessInfo = _require3.CookieAccessInfo; + +const methods = require('methods'); -const CookieJar = require('cookiejar').CookieJar; -const CookieAccess = require('cookiejar').CookieAccessInfo; -const parse = require('url').parse; const request = require('../..'); -const AgentBase = require('../agent-base'); -let methods = require('methods'); +const AgentBase = require('../agent-base'); /** * Expose `Agent`. */ -module.exports = Agent; +module.exports = Agent; /** * Initialize a new `Agent`. * @@ -27,19 +34,30 @@ function Agent(options) { if (!(this instanceof Agent)) { return new Agent(options); } + AgentBase.call(this); this.jar = new CookieJar(); if (options) { - if (options.ca) {this.ca(options.ca);} - if (options.key) {this.key(options.key);} - if (options.pfx) {this.pfx(options.pfx);} - if (options.cert) {this.cert(options.cert);} + if (options.ca) { + this.ca(options.ca); + } + + if (options.key) { + this.key(options.key); + } + + if (options.pfx) { + this.pfx(options.pfx); + } + + if (options.cert) { + this.cert(options.cert); + } } } Agent.prototype = Object.create(AgentBase.prototype); - /** * Save the cookies in the given `res` to * the agent's cookie jar for persistence. @@ -48,11 +66,10 @@ Agent.prototype = Object.create(AgentBase.prototype); * @api private */ -Agent.prototype._saveCookies = function(res) { +Agent.prototype._saveCookies = function (res) { const cookies = res.headers['set-cookie']; if (cookies) this.jar.setCookies(cookies); }; - /** * Attach cookies when available to the given `req`. * @@ -60,33 +77,32 @@ Agent.prototype._saveCookies = function(res) { * @api private */ -Agent.prototype._attachCookies = function(req) { + +Agent.prototype._attachCookies = function (req) { const url = parse(req.url); - const access = CookieAccess( - url.hostname, - url.pathname, - 'https:' == url.protocol - ); + const access = new CookieAccessInfo(url.hostname, url.pathname, url.protocol === 'https:'); const cookies = this.jar.getCookies(access).toValueString(); req.cookies = cookies; }; methods.forEach(name => { const method = name.toUpperCase(); - Agent.prototype[name] = function(url, fn) { - const req = new request.Request(method, url); + Agent.prototype[name] = function (url, fn) { + const req = new request.Request(method, url); req.on('response', this._saveCookies.bind(this)); req.on('redirect', this._saveCookies.bind(this)); req.on('redirect', this._attachCookies.bind(this, req)); + this._attachCookies(req); + this._setDefaults(req); if (fn) { req.end(fn); } + return req; }; }); - -Agent.prototype.del = Agent.prototype['delete']; +Agent.prototype.del = Agent.prototype.delete; \ No newline at end of file diff --git a/lib/node/http2wrapper.js b/lib/node/http2wrapper.js index 2fa7d2ec2..49df6aaae 100644 --- a/lib/node/http2wrapper.js +++ b/lib/node/http2wrapper.js @@ -1,89 +1,97 @@ 'use strict'; +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + const http2 = require('http2'); + const Stream = require('stream'); + const util = require('util'); + const net = require('net'); -const tls = require('tls'); -const parse = require('url').parse; -const { - HTTP2_HEADER_PATH, - HTTP2_HEADER_STATUS, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_AUTHORITY, - HTTP2_HEADER_HOST, - HTTP2_HEADER_SET_COOKIE, - NGHTTP2_CANCEL, -} = http2.constants; +const tls = require('tls'); // eslint-disable-next-line node/no-deprecated-api + + +const _require = require('url'), + parse = _require.parse; +const _http2$constants = http2.constants, + HTTP2_HEADER_PATH = _http2$constants.HTTP2_HEADER_PATH, + HTTP2_HEADER_STATUS = _http2$constants.HTTP2_HEADER_STATUS, + HTTP2_HEADER_METHOD = _http2$constants.HTTP2_HEADER_METHOD, + HTTP2_HEADER_AUTHORITY = _http2$constants.HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_HOST = _http2$constants.HTTP2_HEADER_HOST, + HTTP2_HEADER_SET_COOKIE = _http2$constants.HTTP2_HEADER_SET_COOKIE, + NGHTTP2_CANCEL = _http2$constants.NGHTTP2_CANCEL; function setProtocol(protocol) { return { - request: function (options) { + request(options) { return new Request(protocol, options); } - } + + }; } function Request(protocol, options) { Stream.call(this); const defaultPort = protocol === 'https:' ? 443 : 80; - const defaultHost = 'localhost' + const defaultHost = 'localhost'; const port = options.port || defaultPort; const host = options.host || defaultHost; - - delete options.port - delete options.host - + delete options.port; + delete options.host; this.method = options.method; this.path = options.path; this.protocol = protocol; this.host = host; + delete options.method; + delete options.path; - delete options.method - delete options.path + const sessionOptions = _objectSpread({}, options); - const sessionOptions = Object.assign({}, options); if (options.socketPath) { sessionOptions.socketPath = options.socketPath; sessionOptions.createConnection = this.createUnixConnection.bind(this); } this._headers = {}; - const session = http2.connect(`${protocol}//${host}:${port}`, sessionOptions); - this.setHeader('host', `${host}:${port}`) - - session.on('error', (err) => this.emit('error', err)); - + this.setHeader('host', `${host}:${port}`); + session.on('error', err => this.emit('error', err)); this.session = session; } - /** * Inherit from `Stream` (which inherits from `EventEmitter`). */ + + util.inherits(Request, Stream); Request.prototype.createUnixConnection = function (authority, options) { switch (this.protocol) { case 'http:': return net.connect(options.socketPath); + case 'https:': options.ALPNProtocols = ['h2']; options.servername = this.host; options.allowHalfOpen = true; return tls.connect(options.socketPath, options); + default: throw new Error('Unsupported protocol', this.protocol); } -} +}; // eslint-disable-next-line no-unused-vars + -Request.prototype.setNoDelay = function (bool) { - // We can not use setNoDelay with HTTP/2. +Request.prototype.setNoDelay = function (bool) {// We can not use setNoDelay with HTTP/2. // Node 10 limits http2session.socket methods to ones safe to use with HTTP/2. // See also https://nodejs.org/api/http2.html#http2_http2session_socket -} +}; Request.prototype.getFrame = function () { if (this.frame) { @@ -92,77 +100,83 @@ Request.prototype.getFrame = function () { const method = { [HTTP2_HEADER_PATH]: this.path, - [HTTP2_HEADER_METHOD]: this.method, - } - + [HTTP2_HEADER_METHOD]: this.method + }; let headers = this.mapToHttp2Header(this._headers); - headers = Object.assign(headers, method); + const frame = this.session.request(headers); // eslint-disable-next-line no-unused-vars - const frame = this.session.request(headers); frame.once('response', (headers, flags) => { headers = this.mapToHttpHeader(headers); frame.headers = headers; - frame.status = frame.statusCode = headers[HTTP2_HEADER_STATUS]; + frame.statusCode = headers[HTTP2_HEADER_STATUS]; + frame.status = frame.statusCode; this.emit('response', frame); }); - this._headerSent = true; - frame.once('drain', () => this.emit('drain')); - frame.on('error', (err) => this.emit('error', err)); + frame.on('error', err => this.emit('error', err)); frame.on('close', () => this.session.close()); - this.frame = frame; return frame; -} +}; Request.prototype.mapToHttpHeader = function (headers) { const keys = Object.keys(headers); const http2Headers = {}; - for (var i = 0; i < keys.length; i++) { + + for (let i = 0; i < keys.length; i++) { let key = keys[i]; let value = headers[key]; key = key.toLowerCase(); + switch (key) { case HTTP2_HEADER_SET_COOKIE: value = Array.isArray(value) ? value : [value]; break; + default: break; } + http2Headers[key] = value; } + return http2Headers; -} +}; Request.prototype.mapToHttp2Header = function (headers) { const keys = Object.keys(headers); const http2Headers = {}; - for (var i = 0; i < keys.length; i++) { + + for (let i = 0; i < keys.length; i++) { let key = keys[i]; let value = headers[key]; key = key.toLowerCase(); + switch (key) { case HTTP2_HEADER_HOST: key = HTTP2_HEADER_AUTHORITY; - value = /^http\:\/\/|^https\:\/\//.test(value) ? parse(value).host : value; + value = /^http:\/\/|^https:\/\//.test(value) ? parse(value).host : value; break; + default: break; } + http2Headers[key] = value; } + return http2Headers; -} +}; Request.prototype.setHeader = function (name, value) { this._headers[name.toLowerCase()] = value; -} +}; Request.prototype.getHeader = function (name) { return this._headers[name.toLowerCase()]; -} +}; Request.prototype.write = function (data, encoding) { const frame = this.getFrame(); @@ -172,17 +186,18 @@ Request.prototype.write = function (data, encoding) { Request.prototype.pipe = function (stream, options) { const frame = this.getFrame(); return frame.pipe(stream, options); -} +}; Request.prototype.end = function (data) { const frame = this.getFrame(); frame.end(data); -} +}; // eslint-disable-next-line no-unused-vars + Request.prototype.abort = function (data) { const frame = this.getFrame(); frame.close(NGHTTP2_CANCEL); this.session.destroy(); -} +}; -exports.setProtocol = setProtocol; +exports.setProtocol = setProtocol; \ No newline at end of file diff --git a/lib/node/index.js b/lib/node/index.js index 921382793..16817685a 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -1,75 +1,94 @@ 'use strict'; - /** * Module dependencies. */ +// eslint-disable-next-line node/no-deprecated-api + +const _require = require('url'), + parse = _require.parse, + format = _require.format, + resolve = _require.resolve; -const debug = require('debug')('superagent'); -const formidable = require('formidable'); -const FormData = require('form-data'); -const Response = require('./response'); -const parse = require('url').parse; -const format = require('url').format; -const resolve = require('url').resolve; -let methods = require('methods'); const Stream = require('stream'); -const utils = require('../utils'); -const unzip = require('./unzip').unzip; -const mime = require('mime'); + const https = require('https'); + const http = require('http'); + const fs = require('fs'); -const qs = require('qs'); + const zlib = require('zlib'); + const util = require('util'); + +const qs = require('qs'); + +const mime = require('mime'); + +let methods = require('methods'); + +const FormData = require('form-data'); + +const formidable = require('formidable'); + +const debug = require('debug')('superagent'); + +const CookieJar = require('cookiejar'); + +const utils = require('../utils'); + const pkg = require('../../package.json'); + const RequestBase = require('../request-base'); -const CookieJar = require('cookiejar'); + +const _require2 = require('./unzip'), + unzip = _require2.unzip; + +const Response = require('./response'); let http2; + try { http2 = require('./http2wrapper'); } catch (_) {} function request(method, url) { // callback - if ('function' == typeof url) { + if (typeof url === 'function') { return new exports.Request('GET', method).end(url); - } + } // url first + - // url first - if (1 == arguments.length) { + if (arguments.length === 1) { return new exports.Request('GET', method); } return new exports.Request(method, url); } -exports = module.exports = request; +module.exports = request; +exports = module.exports; /** * Expose `Request`. */ exports.Request = Request; - /** * Expose the agent function */ exports.agent = require('./agent'); - /** * Noop. */ -function noop(){}; - +function noop() {} /** * Expose `Response`. */ -exports.Response = Response; +exports.Response = Response; /** * Define "form" mime type. */ @@ -77,7 +96,6 @@ exports.Response = Response; mime.define({ 'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data'] }, true); - /** * Protocol map. */ @@ -85,9 +103,8 @@ mime.define({ exports.protocols = { 'http:': http, 'https:': https, - 'http2:': http2, + 'http2:': http2 }; - /** * Default serialization map. * @@ -99,9 +116,8 @@ exports.protocols = { exports.serialize = { 'application/x-www-form-urlencoded': qs.stringify, - 'application/json': JSON.stringify, + 'application/json': JSON.stringify }; - /** * Default parsers. * @@ -112,32 +128,32 @@ exports.serialize = { */ exports.parse = require('./parsers'); - - /** * Default buffering map. Can be used to set certain * response types to buffer/not buffer. * * superagent.buffer['application/xml'] = true; */ -exports.buffer = {}; +exports.buffer = {}; /** * Initialize internal header tracking properties on a request instance. * * @param {Object} req the instance * @api private */ + function _initHeaders(req) { const ua = `node-superagent/${pkg.version}`; - req._header = { // coerces header names to lowercase + req._header = { + // coerces header names to lowercase 'user-agent': ua }; - req.header = { // preserves header name case + req.header = { + // preserves header name case 'User-Agent': ua }; } - /** * Initialize a new `Request` with the given `method` and `url`. * @@ -146,15 +162,19 @@ function _initHeaders(req) { * @api public */ + function Request(method, url) { Stream.call(this); - if ('string' != typeof url) url = format(url); - this._enableHttp2 = !!process.env.HTTP2_TEST; // internal only + if (typeof url !== 'string') url = format(url); + this._enableHttp2 = Boolean(process.env.HTTP2_TEST); // internal only + this._agent = false; this._formData = null; this.method = method; this.url = url; + _initHeaders(this); + this.writable = true; this._redirects = 0; this.redirects(method === 'HEAD' ? 0 : 5); @@ -162,18 +182,20 @@ function Request(method, url) { this.qs = {}; this._query = []; this.qsRaw = this._query; // Unused, for backwards compatibility only + this._redirectList = []; this._streamRequest = false; this.once('end', this.clearTimeout.bind(this)); } - /** * Inherit from `Stream` (which inherits from `EventEmitter`). * Mixin `RequestBase`. */ -util.inherits(Request, Stream); -RequestBase(Request.prototype); + +util.inherits(Request, Stream); // eslint-disable-next-line new-cap + +RequestBase(Request.prototype); /** * Enable or Disable http2. * @@ -203,14 +225,14 @@ RequestBase(Request.prototype); * @api public */ -Request.prototype.http2 = function(bool){ +Request.prototype.http2 = function (bool) { if (exports.protocols['http2:'] === undefined) { throw new Error('superagent: this version of Node.js does not support http2'); } + this._enableHttp2 = bool === undefined ? true : bool; return this; -} - +}; /** * Queue the given `file` as an attachment to the specified `field`, * with optional `options` (or filename). @@ -236,18 +258,22 @@ Request.prototype.http2 = function(bool){ * @api public */ -Request.prototype.attach = function(field, file, options){ + +Request.prototype.attach = function (field, file, options) { if (file) { if (this._data) { - throw Error("superagent can't mix .send() and .attach()"); + throw new Error("superagent can't mix .send() and .attach()"); } let o = options || {}; - if ('string' == typeof options) { - o = { filename: options }; + + if (typeof options === 'string') { + o = { + filename: options + }; } - if ('string' == typeof file) { + if (typeof file === 'string') { if (!o.filename) o.filename = file; debug('creating `fs.ReadStream` instance for file: %s', file); file = fs.createReadStream(file); @@ -257,26 +283,30 @@ Request.prototype.attach = function(field, file, options){ this._getFormData().append(field, file, o); } + return this; }; -Request.prototype._getFormData = function() { +Request.prototype._getFormData = function () { if (!this._formData) { this._formData = new FormData(); + this._formData.on('error', err => { debug('FormData error', err); + if (this.called) { // The request has already finished and the callback was called. // Silently ignore the error. return; } + this.callback(err); this.abort(); }); } + return this._formData; }; - /** * Gets/sets the `Agent` to use for this HTTP request. The default (if this * function is not called) is to opt out of connection pooling (`agent: false`). @@ -286,12 +316,12 @@ Request.prototype._getFormData = function() { * @api public */ -Request.prototype.agent = function(agent){ - if (!arguments.length) return this._agent; + +Request.prototype.agent = function (agent) { + if (arguments.length === 0) return this._agent; this._agent = agent; return this; }; - /** * Set _Content-Type_ response header passed through `mime.getType()`. * @@ -317,13 +347,10 @@ Request.prototype.agent = function(agent){ * @api public */ -Request.prototype.type = function(type) { - return this.set( - 'Content-Type', - ~type.indexOf('/') ? type : mime.getType(type) - ); -}; +Request.prototype.type = function (type) { + return this.set('Content-Type', type.indexOf('/') === -1 ? mime.getType(type) : type); +}; /** * Set _Accept_ response header passed through `mime.getType()`. * @@ -344,12 +371,10 @@ Request.prototype.type = function(type) { * @api public */ -Request.prototype.accept = function(type){ - return this.set('Accept', ~type.indexOf('/') - ? type - : mime.getType(type)); -}; +Request.prototype.accept = function (type) { + return this.set('Accept', type.indexOf('/') === -1 ? mime.getType(type) : type); +}; /** * Add query-string `val`. * @@ -364,15 +389,16 @@ Request.prototype.accept = function(type){ * @api public */ -Request.prototype.query = function(val){ - if ('string' == typeof val) { + +Request.prototype.query = function (val) { + if (typeof val === 'string') { this._query.push(val); } else { Object.assign(this.qs, val); } + return this; }; - /** * Write raw `data` / `encoding` to the socket. * @@ -382,14 +408,16 @@ Request.prototype.query = function(val){ * @api public */ -Request.prototype.write = function(data, encoding){ + +Request.prototype.write = function (data, encoding) { const req = this.request(); + if (!this._streamRequest) { this._streamRequest = true; } + return req.write(data, encoding); }; - /** * Pipe the request body to `stream`. * @@ -399,45 +427,52 @@ Request.prototype.write = function(data, encoding){ * @api public */ -Request.prototype.pipe = function(stream, options){ + +Request.prototype.pipe = function (stream, options) { this.piped = true; // HACK... + this.buffer(false); this.end(); return this._pipeContinue(stream, options); }; -Request.prototype._pipeContinue = function(stream, options){ +Request.prototype._pipeContinue = function (stream, options) { this.req.once('response', res => { // redirect const redirect = isRedirect(res.statusCode); - if (redirect && this._redirects++ != this._maxRedirects) { + + if (redirect && this._redirects++ !== this._maxRedirects) { return this._redirect(res)._pipeContinue(stream, options); } this.res = res; + this._emitResponse(); + if (this._aborted) return; if (this._shouldUnzip(res)) { const unzipObj = zlib.createUnzip(); unzipObj.on('error', err => { - if (err && err.code === 'Z_BUF_ERROR') { // unexpected end of file is ignored by browsers and curl + if (err && err.code === 'Z_BUF_ERROR') { + // unexpected end of file is ignored by browsers and curl stream.emit('end'); return; } + stream.emit('error', err); }); res.pipe(unzipObj).pipe(stream, options); } else { res.pipe(stream, options); } + res.once('end', () => { this.emit('end'); }); }); return stream; }; - /** * Enable / disable buffering. * @@ -446,11 +481,11 @@ Request.prototype._pipeContinue = function(stream, options){ * @api public */ -Request.prototype.buffer = function(val){ - this._buffer = (false !== val); + +Request.prototype.buffer = function (val) { + this._buffer = val !== false; return this; }; - /** * Redirect to `url * @@ -459,73 +494,65 @@ Request.prototype.buffer = function(val){ * @api private */ -Request.prototype._redirect = function(res){ + +Request.prototype._redirect = function (res) { let url = res.headers.location; + if (!url) { return this.callback(new Error('No location header for redirect'), res); } - debug('redirect %s -> %s', this.url, url); + debug('redirect %s -> %s', this.url, url); // location - // location - url = resolve(this.url, url); - - // ensure the response is being consumed + url = resolve(this.url, url); // ensure the response is being consumed // this is required for Node v0.10+ - res.resume(); + res.resume(); let headers = this.req._headers; + const changesOrigin = parse(url).host !== parse(this.url).host; // implementation of 302 following defacto standard - const changesOrigin = parse(url).host !== parse(this.url).host; - - // implementation of 302 following defacto standard - if (res.statusCode == 301 || res.statusCode == 302){ + if (res.statusCode === 301 || res.statusCode === 302) { // strip Content-* related fields // in case of POST etc - headers = utils.cleanHeader(this.req._headers, changesOrigin); + headers = utils.cleanHeader(this.req._headers, changesOrigin); // force GET - // force GET - this.method = 'HEAD' == this.method - ? 'HEAD' - : 'GET'; + this.method = this.method === 'HEAD' ? 'HEAD' : 'GET'; // clear data - // clear data this._data = null; - } - // 303 is always GET - if (res.statusCode == 303) { + } // 303 is always GET + + + if (res.statusCode === 303) { // strip Content-* related fields // in case of POST etc - headers = utils.cleanHeader(this.req._headers, changesOrigin); + headers = utils.cleanHeader(this.req._headers, changesOrigin); // force method - // force method - this.method = 'GET'; + this.method = 'GET'; // clear data - // clear data this._data = null; - } - // 307 preserves method + } // 307 preserves method // 308 preserves method - delete headers.host; + + delete headers.host; delete this.req; - delete this._formData; + delete this._formData; // remove all add header except User-Agent + + _initHeaders(this); // redirect - // remove all add header except User-Agent - _initHeaders(this); - // redirect this._endCalled = false; this.url = url; this.qs = {}; this._query.length = 0; this.set(headers); this.emit('redirect', res); + this._redirectList.push(this.url); + this.end(this._callback); return this; }; - /** * Set Authorization field value with `user` and `pass`. * @@ -543,21 +570,26 @@ Request.prototype._redirect = function(res){ * @api public */ -Request.prototype.auth = function(user, pass, options){ - if (1 === arguments.length) pass = ''; - if (typeof pass === 'object' && pass !== null) { // pass is optional and can be replaced with options + +Request.prototype.auth = function (user, pass, options) { + if (arguments.length === 1) pass = ''; + + if (typeof pass === 'object' && pass !== null) { + // pass is optional and can be replaced with options options = pass; pass = ''; } + if (!options) { - options = { type: 'basic' }; + options = { + type: 'basic' + }; } - const encoder = string => new Buffer.from(string).toString('base64'); + const encoder = string => Buffer.from(string).toString('base64'); return this._auth(user, pass, options, encoder); }; - /** * Set the certificate authority option for https request. * @@ -566,11 +598,11 @@ Request.prototype.auth = function(user, pass, options){ * @api public */ -Request.prototype.ca = function(cert){ + +Request.prototype.ca = function (cert) { this._ca = cert; return this; }; - /** * Set the client certificate key option for https request. * @@ -579,11 +611,11 @@ Request.prototype.ca = function(cert){ * @api public */ -Request.prototype.key = function(cert){ + +Request.prototype.key = function (cert) { this._key = cert; return this; }; - /** * Set the key, certificate, and CA certs of the client in PFX or PKCS12 format. * @@ -592,16 +624,17 @@ Request.prototype.key = function(cert){ * @api public */ -Request.prototype.pfx = function(cert) { + +Request.prototype.pfx = function (cert) { if (typeof cert === 'object' && !Buffer.isBuffer(cert)) { this._pfx = cert.pfx; this._passphrase = cert.passphrase; } else { this._pfx = cert; } + return this; }; - /** * Set the client certificate option for https request. * @@ -610,95 +643,102 @@ Request.prototype.pfx = function(cert) { * @api public */ -Request.prototype.cert = function(cert){ + +Request.prototype.cert = function (cert) { this._cert = cert; return this; }; - /** * Return an http[s] request. * * @return {OutgoingMessage} * @api private */ +// eslint-disable-next-line complexity -Request.prototype.request = function(){ - if (this.req) return this.req; +Request.prototype.request = function () { + if (this.req) return this.req; const options = {}; try { const query = qs.stringify(this.qs, { indices: false, - strictNullHandling: true, + strictNullHandling: true }); + if (query) { this.qs = {}; + this._query.push(query); } + this._finalizeQueryString(); - } catch (e) { - return this.emit('error', e); + } catch (err) { + return this.emit('error', err); } let url = this.url; - const retries = this._retries; - - // Capture backticks as-is from the final query string built above. + const retries = this._retries; // Capture backticks as-is from the final query string built above. // Note: this'll only find backticks entered in req.query(String) // calls, because qs.stringify unconditionally encodes backticks. + let queryStringBackticks; - if(url.indexOf('`') > -1) { - const queryStartIndex = url.indexOf("?"); - if(queryStartIndex !== -1) { + if (url.indexOf('`') > -1) { + const queryStartIndex = url.indexOf('?'); + + if (queryStartIndex !== -1) { const queryString = url.substr(queryStartIndex + 1); - queryStringBackticks = queryString.match(/`|\%60/g); + queryStringBackticks = queryString.match(/`|%60/g); } - } + } // default to http:// - // default to http:// - if (0 != url.indexOf('http')) url = `http://${url}`; - url = parse(url); - // See https://github.com/visionmedia/superagent/issues/1367 - if(queryStringBackticks) { + if (url.indexOf('http') !== 0) url = `http://${url}`; + url = parse(url); // See https://github.com/visionmedia/superagent/issues/1367 + + if (queryStringBackticks) { let i = 0; - url.query = url.query.replace(/\%60/g, () => queryStringBackticks[i++]); + url.query = url.query.replace(/%60/g, () => queryStringBackticks[i++]); url.search = `?${url.query}`; url.path = url.pathname + url.search; - } + } // support unix sockets + - // support unix sockets if (/^https?\+unix:/.test(url.protocol) === true) { // get the protocol - url.protocol = `${url.protocol.split('+')[0]}:`; + url.protocol = `${url.protocol.split('+')[0]}:`; // get the socket, path - // get the socket, path const unixParts = url.path.match(/^([^/]+)(.+)$/); options.socketPath = unixParts[1].replace(/%2F/g, '/'); url.path = unixParts[2]; - } + } // Override IP address of a hostname + - // Override IP address of a hostname if (this._connectOverride) { - const hostname = url.hostname; + const _url = url, + hostname = _url.hostname; const match = hostname in this._connectOverride ? this._connectOverride[hostname] : this._connectOverride['*']; + if (match) { // backup the real host - if (!this._header['host']) { + if (!this._header.host) { this.set('host', url.host); - } - // wrap [ipv6] + } // wrap [ipv6] + + url.host = /:/.test(match) ? `[${match}]` : match; + if (url.port) { url.host += `:${url.port}`; } + url.hostname = match; } - } + } // options + - // options options.method = this.method; options.port = url.port; options.path = url.path; @@ -708,70 +748,69 @@ Request.prototype.request = function(){ options.pfx = this._pfx; options.cert = this._cert; options.passphrase = this._passphrase; - options.agent = this._agent; + options.agent = this._agent; // Allows request.get('https://1.2.3.4/').set('Host', 'example.com') - // Allows request.get('https://1.2.3.4/').set('Host', 'example.com') - if (this._header['host']) { - options.servername = this._header['host'].replace(/:[0-9]+$/,''); + if (this._header.host) { + options.servername = this._header.host.replace(/:\d+$/, ''); } if (this._trustLocalhost && /^(?:localhost|127\.0\.0\.\d+|(0*:)+:0*1)$/.test(url.hostname)) { options.rejectUnauthorized = false; - } + } // initiate request - // initiate request - const mod = this._enableHttp2 ? exports.protocols['http2:'].setProtocol(url.protocol) : exports.protocols[url.protocol]; - // request - const req = (this.req = mod.request(options)); + const mod = this._enableHttp2 ? exports.protocols['http2:'].setProtocol(url.protocol) : exports.protocols[url.protocol]; // request + + this.req = mod.request(options); + const req = this.req; // set tcp no delay - // set tcp no delay req.setNoDelay(true); - if ('HEAD' != options.method) { + if (options.method !== 'HEAD') { req.setHeader('Accept-Encoding', 'gzip, deflate'); } - this.protocol = url.protocol; - this.host = url.host; - // expose events - req.once('drain', () => { this.emit('drain'); }); + this.protocol = url.protocol; + this.host = url.host; // expose events + req.once('drain', () => { + this.emit('drain'); + }); req.on('error', err => { // flag abortion here for out timeouts // because node will emit a faux-error "socket hang up" // when request is aborted before a connection is made - if (this._aborted) return; - // if not the same, we are in the **old** (cancelled) request, + if (this._aborted) return; // if not the same, we are in the **old** (cancelled) request, // so need to continue (same as for above) - if (this._retries !== retries) return; - // if we've received a response then we don't want to let + + if (this._retries !== retries) return; // if we've received a response then we don't want to let // an error in the request blow up the response + if (this.response) return; this.callback(err); - }); + }); // auth - // auth if (url.auth) { const auth = url.auth.split(':'); this.auth(auth[0], auth[1]); } + if (this.username && this.password) { this.auth(this.username, this.password); } + for (const key in this.header) { - if (this.header.hasOwnProperty(key)) - req.setHeader(key, this.header[key]); - } + if (Object.prototype.hasOwnProperty.call(this.header, key)) req.setHeader(key, this.header[key]); + } // add cookies + - // add cookies if (this.cookies) { - if(this._header.hasOwnProperty('cookie')) { + if (Object.prototype.hasOwnProperty.call(this._header, 'cookie')) { // merge const tmpJar = new CookieJar.CookieJar(); tmpJar.setCookies(this._header.cookie.split(';')); tmpJar.setCookies(this.cookies.split(';')); - req.setHeader('Cookie',tmpJar.getCookies(CookieJar.CookieAccessInfo.All).toValueString()); + req.setHeader('Cookie', tmpJar.getCookies(CookieJar.CookieAccessInfo.All).toValueString()); } else { req.setHeader('Cookie', this.cookies); } @@ -779,7 +818,6 @@ Request.prototype.request = function(){ return req; }; - /** * Invoke the callback with `err` and `res` * and handle arity check. @@ -789,12 +827,13 @@ Request.prototype.request = function(){ * @api private */ -Request.prototype.callback = function(err, res){ + +Request.prototype.callback = function (err, res) { if (this._shouldRetry(err, res)) { return this._retry(); - } + } // Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime. + - // Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime. const fn = this._callback || noop; this.clearTimeout(); if (this.called) return console.warn('superagent: double callback bug'); @@ -804,45 +843,47 @@ Request.prototype.callback = function(err, res){ try { if (!this._isResponseOK(res)) { let msg = 'Unsuccessful HTTP response'; + if (res) { msg = http.STATUS_CODES[res.status] || msg; } + err = new Error(msg); err.status = res ? res.status : undefined; } - } catch (new_err) { - err = new_err; + } catch (err2) { + err = err2; } - } - // It's important that the callback is called outside try/catch + } // It's important that the callback is called outside try/catch // to avoid double callback + + if (!err) { return fn(null, res); } err.response = res; - if (this._maxRetries) err.retries = this._retries - 1; - - // only emit error event if there is a listener + if (this._maxRetries) err.retries = this._retries - 1; // only emit error event if there is a listener // otherwise we assume the callback to `.end()` will get the error + if (err && this.listeners('error').length > 0) { this.emit('error', err); } fn(err, res); }; - /** * Check if `obj` is a host object, * - * @param {Object} obj - * @return {Boolean} + * @param {Object} obj host object + * @return {Boolean} is a host object * @api private */ -Request.prototype._isHost = function _isHost(obj) { - return Buffer.isBuffer(obj) || obj instanceof Stream || obj instanceof FormData; -} + +Request.prototype._isHost = function (obj) { + return Buffer.isBuffer(obj) || obj instanceof Stream || obj instanceof FormData; +}; /** * Initiate request, invoking callback `fn(err, res)` * with an instanceof `Response`. @@ -852,70 +893,75 @@ Request.prototype._isHost = function _isHost(obj) { * @api public */ -Request.prototype._emitResponse = function(body, files) { + +Request.prototype._emitResponse = function (body, files) { const response = new Response(this); this.response = response; response.redirects = this._redirectList; + if (undefined !== body) { response.body = body; } + response.files = files; + if (this._endCalled) { - response.pipe = function() { - throw Error("end() has already been called, so it's too late to start piping"); - } + response.pipe = function () { + throw new Error("end() has already been called, so it's too late to start piping"); + }; } + this.emit('response', response); return response; }; -Request.prototype.end = function(fn) { +Request.prototype.end = function (fn) { this.request(); debug('%s %s', this.method, this.url); if (this._endCalled) { - throw Error( - '.end() was called twice. This is not supported in superagent' - ); + throw new Error('.end() was called twice. This is not supported in superagent'); } - this._endCalled = true; - // store callback + this._endCalled = true; // store callback + this._callback = fn || noop; this._end(); }; -Request.prototype._end = function() { - if (this._aborted) return this.callback(Error("The request has been aborted even before .end() was called")); - +Request.prototype._end = function () { + if (this._aborted) return this.callback(new Error('The request has been aborted even before .end() was called')); let data = this._data; const req = this.req; const method = this.method; - this._setTimeouts(); + this._setTimeouts(); // body - // body - if ('HEAD' != method && !req._headerSent) { + + if (method !== 'HEAD' && !req._headerSent) { // serialize stuff - if ('string' != typeof data) { - let contentType = req.getHeader('Content-Type'); - // Parse out just the content type from the header (ignore the charset) + if (typeof data !== 'string') { + let contentType = req.getHeader('Content-Type'); // Parse out just the content type from the header (ignore the charset) + if (contentType) contentType = contentType.split(';')[0]; let serialize = this._serializer || exports.serialize[contentType]; + if (!serialize && isJSON(contentType)) { serialize = exports.serialize['application/json']; } + if (serialize) data = serialize(data); - } + } // content-length + - // content-length if (data && !req.getHeader('Content-Length')) { req.setHeader('Content-Length', Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data)); } - } + } // response + // eslint-disable-next-line complexity + - // response req.once('response', res => { debug('%s %s -> %s', this.method, this.url, res.statusCode); @@ -930,34 +976,34 @@ Request.prototype._end = function() { const max = this._maxRedirects; const mime = utils.type(res.headers['content-type'] || '') || 'text/plain'; const type = mime.split('/')[0]; - const multipart = 'multipart' == type; + const multipart = type === 'multipart'; const redirect = isRedirect(res.statusCode); const responseType = this._responseType; + this.res = res; // redirect - this.res = res; - - // redirect - if (redirect && this._redirects++ != max) { + if (redirect && this._redirects++ !== max) { return this._redirect(res); } - if ('HEAD' == this.method) { + if (this.method === 'HEAD') { this.emit('end'); this.callback(null, this._emitResponse()); return; - } + } // zlib support + - // zlib support if (this._shouldUnzip(res)) { unzip(req, res); } let buffer = this._buffer; - if (buffer === undefined && mime in exports.buffer){ - buffer = !!exports.buffer[mime]; + + if (buffer === undefined && mime in exports.buffer) { + buffer = Boolean(exports.buffer[mime]); } let parser = this._parser; + if (undefined === buffer) { if (parser) { console.warn("A custom superagent parser has been set, but buffering strategy for the parser hasn't been configured. Call `req.buffer(true or false)` or set `superagent.buffer[mime] = true or false`"); @@ -968,6 +1014,7 @@ Request.prototype._end = function() { if (!parser) { if (responseType) { parser = exports.parse.image; // It's actually a generic Buffer + buffer = true; } else if (multipart) { const form = new formidable.IncomingForm(); @@ -978,42 +1025,43 @@ Request.prototype._end = function() { buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent } else if (exports.parse[mime]) { parser = exports.parse[mime]; - } else if ('text' == type) { + } else if (type === 'text') { parser = exports.parse.text; - buffer = (buffer !== false); - - // everyone wants their own white-labeled json + buffer = buffer !== false; // everyone wants their own white-labeled json } else if (isJSON(mime)) { parser = exports.parse['application/json']; - buffer = (buffer !== false); + buffer = buffer !== false; } else if (buffer) { parser = exports.parse.text; } else if (undefined === buffer) { parser = exports.parse.image; // It's actually a generic Buffer + buffer = true; } - } + } // by default only buffer text/*, json and messed up thing from hell + - // by default only buffer text/*, json and messed up thing from hell - if ((undefined === buffer && isText(mime)) || isJSON(mime)) { + if (undefined === buffer && isText(mime) || isJSON(mime)) { buffer = true; } this._resBuffered = buffer; let parserHandlesEnd = false; + if (buffer) { // Protectiona against zip bombs and other nuisance let responseBytesLeft = this._maxResponseSize || 200000000; res.on('data', buf => { responseBytesLeft -= buf.byteLength || buf.length; + if (responseBytesLeft < 0) { // This will propagate through error event - const err = Error("Maximum response size reached"); - err.code = "ETOOLARGE"; - // Parsers aren't required to observe error event, + const err = new Error('Maximum response size reached'); + err.code = 'ETOOLARGE'; // Parsers aren't required to observe error event, // so would incorrectly report success - parserHandlesEnd = false; - // Will emit error event + + parserHandlesEnd = false; // Will emit error event + res.destroy(err); } }); @@ -1024,15 +1072,14 @@ Request.prototype._end = function() { // Unbuffered parsers are supposed to emit response early, // which is weird BTW, because response.body won't be there. parserHandlesEnd = buffer; - parser(res, (err, obj, files) => { if (this.timedout) { // Timeout has already handled all callbacks return; - } - - // Intentional (non-timeout) abort is supposed to preserve partial response, + } // Intentional (non-timeout) abort is supposed to preserve partial response, // even if it doesn't parse. + + if (err && !this._aborted) { return this.callback(err); } @@ -1048,57 +1095,57 @@ Request.prototype._end = function() { } } - this.res = res; + this.res = res; // unbuffered - // unbuffered if (!buffer) { debug('unbuffered %s %s', this.method, this.url); this.callback(null, this._emitResponse()); if (multipart) return; // allow multipart to handle end event + res.once('end', () => { debug('end %s %s', this.method, this.url); this.emit('end'); }); return; - } + } // terminating events + - // terminating events res.once('error', err => { parserHandlesEnd = false; this.callback(err, null); }); - if (!parserHandlesEnd) - res.once('end', () => { - debug('end %s %s', this.method, this.url); - // TODO: unless buffering emit earlier to stream - this.emit('end'); - this.callback(null, this._emitResponse()); - }); - }); + if (!parserHandlesEnd) res.once('end', () => { + debug('end %s %s', this.method, this.url); // TODO: unless buffering emit earlier to stream + this.emit('end'); + this.callback(null, this._emitResponse()); + }); + }); this.emit('request', this); const getProgressMonitor = () => { const lengthComputable = true; const total = req.getHeader('Content-Length'); let loaded = 0; - const progress = new Stream.Transform(); + progress._transform = (chunk, encoding, cb) => { loaded += chunk.length; this.emit('progress', { direction: 'upload', lengthComputable, loaded, - total, + total }); cb(null, chunk); }; + return progress; }; - const bufferToChunks = (buffer) => { + const bufferToChunks = buffer => { const chunkSize = 16 * 1024; // default highWaterMark value + const chunking = new Stream.Readable(); const totalLength = buffer.length; const remainder = totalLength % chunkSize; @@ -1117,25 +1164,29 @@ Request.prototype._end = function() { chunking.push(null); // no more data return chunking; - } + }; // if a FormData instance got created, then we send that as the request body + - // if a FormData instance got created, then we send that as the request body const formData = this._formData; - if (formData) { + if (formData) { // set headers const headers = formData.getHeaders(); + for (const i in headers) { - debug('setting FormData header: "%s: %s"', i, headers[i]); - req.setHeader(i, headers[i]); - } + if (Object.prototype.hasOwnProperty.call(headers, i)) { + debug('setting FormData header: "%s: %s"', i, headers[i]); + req.setHeader(i, headers[i]); + } + } // attempt to get "Content-Length" header + // eslint-disable-next-line handle-callback-err + - // attempt to get "Content-Length" header formData.getLength((err, length) => { // TODO: Add chunked encoding when no length (if err) - debug('got FormData Content-Length: %s', length); - if ('number' == typeof length) { + + if (typeof length === 'number') { req.setHeader('Content-Length', length); } @@ -1146,26 +1197,24 @@ Request.prototype._end = function() { } else { req.end(data); } -}; +}; // Check whether response has a non-0-sized gzip-encoded body + -/** - * Check whether response has a non-0-sized gzip-encoded body - */ Request.prototype._shouldUnzip = res => { if (res.statusCode === 204 || res.statusCode === 304) { // These aren't supposed to have any body return false; - } + } // header content is a string, and distinction between 0 and no information is crucial - // header content is a string, and distinction between 0 and no information is crucial - if ('0' === res.headers['content-length']) { + + if (res.headers['content-length'] === '0') { // We know that the body is empty (unfortunately, this check does not cover chunked encoding) return false; - } + } // console.log(res); + - // console.log(res); return /^\s*(?:deflate|gzip)\s*$/.test(res.headers['content-encoding']); -}; +}; // eslint-disable-next-line valid-jsdoc /** * Overrides DNS for selected hostnames. Takes object mapping hostnames to IP addresses. @@ -1180,38 +1229,49 @@ Request.prototype._shouldUnzip = res => { * 'ipv6.example.com': '::1', * }) */ -Request.prototype.connect = function(connectOverride) { - if ('string' === typeof connectOverride) { - this._connectOverride = {'*': connectOverride}; - } else if ('object' === typeof connectOverride) { + + +Request.prototype.connect = function (connectOverride) { + if (typeof connectOverride === 'string') { + this._connectOverride = { + '*': connectOverride + }; + } else if (typeof connectOverride === 'object') { this._connectOverride = connectOverride; } else { this._connectOverride = undefined; } + return this; }; -Request.prototype.trustLocalhost = function(toggle) { - this._trustLocalhost = toggle === undefined ? true : toggle; - return this; -}; +Request.prototype.trustLocalhost = function (toggle) { + this._trustLocalhost = toggle === undefined ? true : toggle; + return this; +}; // generate HTTP verb methods + -// generate HTTP verb methods -if (methods.indexOf('del') == -1) { +if (methods.indexOf('del') === -1) { // create a copy so we don't cause conflicts with // other packages using the methods package and // npm 3.x methods = methods.slice(0); methods.push('del'); } + methods.forEach(method => { const name = method; - method = 'del' == method ? 'delete' : method; - + method = method === 'del' ? 'delete' : method; method = method.toUpperCase(); + request[name] = (url, data, fn) => { const req = request(method, url); - if ('function' == typeof data) (fn = data), (data = null); + + if (typeof data === 'function') { + fn = data; + data = null; + } + if (data) { if (method === 'GET' || method === 'HEAD') { req.query(data); @@ -1219,11 +1279,11 @@ methods.forEach(method => { req.send(data); } } - fn && req.end(fn); + + if (fn) req.end(fn); return req; }; }); - /** * Check if `mime` is text and should be buffered. * @@ -1236,16 +1296,13 @@ function isText(mime) { const parts = mime.split('/'); const type = parts[0]; const subtype = parts[1]; - - return 'text' == type || 'x-www-form-urlencoded' == subtype; + return type === 'text' || subtype === 'x-www-form-urlencoded'; } function isImageOrVideo(mime) { const type = mime.split('/')[0]; - - return 'image' == type || 'video' == type; + return type === 'image' || type === 'video'; } - /** * Check if `mime` is json or has +json structured syntax suffix. * @@ -1254,12 +1311,12 @@ function isImageOrVideo(mime) { * @api private */ + function isJSON(mime) { // should match /json or +json // but not /json-seq - return /[\/+]json($|[^-\w])/.test(mime); + return /[/+]json($|[^-\w])/.test(mime); } - /** * Check if we should follow the redirect `code`. * @@ -1268,6 +1325,7 @@ function isJSON(mime) { * @api private */ + function isRedirect(code) { - return ~[301, 302, 303, 305, 307, 308].indexOf(code); -} + return [301, 302, 303, 305, 307, 308].indexOf(code) !== -1; +} \ No newline at end of file diff --git a/lib/node/parsers/image.js b/lib/node/parsers/image.js index b3fadd9ae..649e80411 100644 --- a/lib/node/parsers/image.js +++ b/lib/node/parsers/image.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; module.exports = (res, fn) => { const data = []; // Binary data needs binary storage @@ -9,4 +9,4 @@ module.exports = (res, fn) => { res.on('end', () => { fn(null, Buffer.concat(data)); }); -}; +}; \ No newline at end of file diff --git a/lib/node/parsers/index.js b/lib/node/parsers/index.js index 8be68ca3a..549f6fcc6 100644 --- a/lib/node/parsers/index.js +++ b/lib/node/parsers/index.js @@ -1,10 +1,11 @@ -'use strict'; +"use strict"; exports['application/x-www-form-urlencoded'] = require('./urlencoded'); exports['application/json'] = require('./json'); exports.text = require('./text'); const binary = require('./image'); + exports['application/octet-stream'] = binary; exports['application/pdf'] = binary; -exports.image = binary; +exports.image = binary; \ No newline at end of file diff --git a/lib/node/parsers/json.js b/lib/node/parsers/json.js index 05899428a..04dee2bd9 100644 --- a/lib/node/parsers/json.js +++ b/lib/node/parsers/json.js @@ -1,22 +1,25 @@ -'use strict'; +"use strict"; -module.exports = function parseJSON(res, fn){ +module.exports = function (res, fn) { res.text = ''; res.setEncoding('utf8'); res.on('data', chunk => { res.text += chunk; }); res.on('end', () => { + let body; + let err; + try { - var body = res.text && JSON.parse(res.text); - } catch (e) { - var err = e; - // issue #675: return the raw response if the response parsing fails - err.rawResponse = res.text || null; - // issue #876: return the http status code if the response parsing fails + body = res.text && JSON.parse(res.text); + } catch (err2) { + err = err2; // issue #675: return the raw response if the response parsing fails + + err.rawResponse = res.text || null; // issue #876: return the http status code if the response parsing fails + err.statusCode = res.statusCode; } finally { fn(err, body); } }); -}; +}; \ No newline at end of file diff --git a/lib/node/parsers/text.js b/lib/node/parsers/text.js index 4883e28ab..6911179da 100644 --- a/lib/node/parsers/text.js +++ b/lib/node/parsers/text.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; module.exports = (res, fn) => { res.text = ''; @@ -7,4 +7,4 @@ module.exports = (res, fn) => { res.text += chunk; }); res.on('end', fn); -}; +}; \ No newline at end of file diff --git a/lib/node/parsers/urlencoded.js b/lib/node/parsers/urlencoded.js index 57f2246d8..ed40b61c0 100644 --- a/lib/node/parsers/urlencoded.js +++ b/lib/node/parsers/urlencoded.js @@ -1,9 +1,8 @@ -'use strict'; +"use strict"; /** * Module dependencies. */ - const qs = require('qs'); module.exports = (res, fn) => { @@ -19,4 +18,4 @@ module.exports = (res, fn) => { fn(err); } }); -}; +}; \ No newline at end of file diff --git a/lib/node/response.js b/lib/node/response.js index 325b1266f..50ab806ed 100644 --- a/lib/node/response.js +++ b/lib/node/response.js @@ -1,19 +1,19 @@ 'use strict'; - /** * Module dependencies. */ const util = require('util'); + const Stream = require('stream'); -const ResponseBase = require('../response-base'); +const ResponseBase = require('../response-base'); /** * Expose `Response`. */ -module.exports = Response; +module.exports = Response; /** * Initialize a new `Response` with the given `xhr`. * @@ -30,54 +30,58 @@ module.exports = Response; function Response(req) { Stream.call(this); - const res = (this.res = req.res); + this.res = req.res; + const res = this.res; this.request = req; this.req = req.req; this.text = res.text; - this.body = res.body !== undefined ? res.body : {}; + this.body = res.body === undefined ? {} : res.body; this.files = res.files || {}; this.buffered = req._resBuffered; - this.header = this.headers = res.headers; + this.headers = res.headers; + this.header = this.headers; + this._setStatusProperties(res.statusCode); + this._setHeaderProperties(this.header); + this.setEncoding = res.setEncoding.bind(res); res.on('data', this.emit.bind(this, 'data')); res.on('end', this.emit.bind(this, 'end')); res.on('close', this.emit.bind(this, 'close')); res.on('error', this.emit.bind(this, 'error')); } - /** * Inherit from `Stream`. */ -util.inherits(Response, Stream); -ResponseBase(Response.prototype); +util.inherits(Response, Stream); // eslint-disable-next-line new-cap + +ResponseBase(Response.prototype); /** * Implements methods of a `ReadableStream` */ -Response.prototype.destroy = function(err){ +Response.prototype.destroy = function (err) { this.res.destroy(err); }; - /** * Pause. */ -Response.prototype.pause = function(){ + +Response.prototype.pause = function () { this.res.pause(); }; - /** * Resume. */ -Response.prototype.resume = function(){ + +Response.prototype.resume = function () { this.res.resume(); }; - /** * Return an `Error` representative of this response. * @@ -85,27 +89,24 @@ Response.prototype.resume = function(){ * @api public */ -Response.prototype.toError = function() { + +Response.prototype.toError = function () { const req = this.req; const method = req.method; const path = req.path; - const msg = `cannot ${method} ${path} (${this.status})`; const err = new Error(msg); err.status = this.status; err.text = this.text; err.method = method; err.path = path; - return err; }; - -Response.prototype.setStatusProperties = function(status){ - console.warn("In superagent 2.x setStatusProperties is a private method"); +Response.prototype.setStatusProperties = function (status) { + console.warn('In superagent 2.x setStatusProperties is a private method'); return this._setStatusProperties(status); }; - /** * To json. * @@ -113,11 +114,12 @@ Response.prototype.setStatusProperties = function(status){ * @api public */ -Response.prototype.toJSON = function() { + +Response.prototype.toJSON = function () { return { req: this.request.toJSON(), header: this.header, status: this.status, - text: this.text, + text: this.text }; -}; +}; \ No newline at end of file diff --git a/lib/node/unzip.js b/lib/node/unzip.js index eeb26328d..d4988fdff 100644 --- a/lib/node/unzip.js +++ b/lib/node/unzip.js @@ -1,13 +1,14 @@ 'use strict'; - /** * Module dependencies. */ -const StringDecoder = require('string_decoder').StringDecoder; +const _require = require('string_decoder'), + StringDecoder = _require.StringDecoder; + const Stream = require('stream'); -const zlib = require('zlib'); +const zlib = require('zlib'); /** * Buffers response data events and re-emits when they're unzipped. * @@ -16,56 +17,55 @@ const zlib = require('zlib'); * @api private */ + exports.unzip = (req, res) => { const unzip = zlib.createUnzip(); const stream = new Stream(); - let decoder; + let decoder; // make node responseOnEnd() happy - // make node responseOnEnd() happy stream.req = req; - unzip.on('error', err => { if (err && err.code === 'Z_BUF_ERROR') { // unexpected end of file is ignored by browsers and curl stream.emit('end'); return; } + stream.emit('error', err); - }); + }); // pipe to unzip - // pipe to unzip - res.pipe(unzip); + res.pipe(unzip); // override `setEncoding` to capture encoding - // override `setEncoding` to capture encoding res.setEncoding = type => { decoder = new StringDecoder(type); - }; + }; // decode upon decompressing with captured encoding + - // decode upon decompressing with captured encoding unzip.on('data', buf => { if (decoder) { const str = decoder.write(buf); - if (str.length) stream.emit('data', str); + if (str.length > 0) stream.emit('data', str); } else { stream.emit('data', buf); } }); - unzip.on('end', () => { stream.emit('end'); - }); + }); // override `on` to capture data listeners - // override `on` to capture data listeners const _on = res.on; - res.on = function(type, fn) { - if ('data' == type || 'end' == type) { + + res.on = function (type, fn) { + if (type === 'data' || type === 'end') { stream.on(type, fn.bind(res)); - } else if ('error' == type) { + } else if (type === 'error') { stream.on(type, fn.bind(res)); + _on.call(res, type, fn); } else { _on.call(res, type, fn); } + return this; }; -}; +}; \ No newline at end of file diff --git a/lib/request-base.js b/lib/request-base.js index e4346bb94..d3cf20566 100644 --- a/lib/request-base.js +++ b/lib/request-base.js @@ -1,16 +1,15 @@ -'use strict'; +"use strict"; /** * Module of mixed-in functions shared between node and client code */ const isObject = require('./is-object'); - /** * Expose `RequestBase`. */ -module.exports = RequestBase; +module.exports = RequestBase; /** * Initialize a new `RequestBase`. * @@ -20,7 +19,6 @@ module.exports = RequestBase; function RequestBase(obj) { if (obj) return mixin(obj); } - /** * Mixin the prototype properties. * @@ -29,13 +27,14 @@ function RequestBase(obj) { * @api private */ + function mixin(obj) { for (const key in RequestBase.prototype) { - obj[key] = RequestBase.prototype[key]; + if (Object.prototype.hasOwnProperty.call(RequestBase.prototype, key)) obj[key] = RequestBase.prototype[key]; } + return obj; } - /** * Clear previous timeout. * @@ -43,7 +42,8 @@ function mixin(obj) { * @api public */ -RequestBase.prototype.clearTimeout = function _clearTimeout(){ + +RequestBase.prototype.clearTimeout = function () { clearTimeout(this._timer); clearTimeout(this._responseTimeoutTimer); clearTimeout(this._uploadTimeoutTimer); @@ -52,7 +52,6 @@ RequestBase.prototype.clearTimeout = function _clearTimeout(){ delete this._uploadTimeoutTimer; return this; }; - /** * Override default response body parser * @@ -62,11 +61,11 @@ RequestBase.prototype.clearTimeout = function _clearTimeout(){ * @api public */ -RequestBase.prototype.parse = function parse(fn){ + +RequestBase.prototype.parse = function (fn) { this._parser = fn; return this; }; - /** * Set format of binary response body. * In browser valid formats are 'blob' and 'arraybuffer', @@ -85,11 +84,11 @@ RequestBase.prototype.parse = function parse(fn){ * @api public */ -RequestBase.prototype.responseType = function(val){ + +RequestBase.prototype.responseType = function (val) { this._responseType = val; return this; }; - /** * Override default request body serializer * @@ -99,11 +98,11 @@ RequestBase.prototype.responseType = function(val){ * @api public */ -RequestBase.prototype.serialize = function serialize(fn){ + +RequestBase.prototype.serialize = function (fn) { this._serializer = fn; return this; }; - /** * Set timeouts. * @@ -118,32 +117,38 @@ RequestBase.prototype.serialize = function serialize(fn){ * @api public */ -RequestBase.prototype.timeout = function timeout(options){ - if (!options || 'object' !== typeof options) { + +RequestBase.prototype.timeout = function (options) { + if (!options || typeof options !== 'object') { this._timeout = options; this._responseTimeout = 0; this._uploadTimeout = 0; return this; } - for(const option in options) { - switch(option) { - case 'deadline': - this._timeout = options.deadline; - break; - case 'response': - this._responseTimeout = options.response; - break; - case 'upload': - this._uploadTimeout = options.upload; - break; - default: - console.warn("Unknown timeout option", option); + for (const option in options) { + if (Object.prototype.hasOwnProperty.call(options, option)) { + switch (option) { + case 'deadline': + this._timeout = options.deadline; + break; + + case 'response': + this._responseTimeout = options.response; + break; + + case 'upload': + this._uploadTimeout = options.upload; + break; + + default: + console.warn('Unknown timeout option', option); + } } } + return this; }; - /** * Set number of retry attempts on error. * @@ -155,7 +160,8 @@ RequestBase.prototype.timeout = function timeout(options){ * @api public */ -RequestBase.prototype.retry = function retry(count, fn){ + +RequestBase.prototype.retry = function (count, fn) { // Default to 1 if no count passed or true if (arguments.length === 0 || count === true) count = 1; if (count <= 0) count = 0; @@ -165,45 +171,43 @@ RequestBase.prototype.retry = function retry(count, fn){ return this; }; -const ERROR_CODES = [ - 'ECONNRESET', - 'ETIMEDOUT', - 'EADDRINFO', - 'ESOCKETTIMEDOUT' -]; - +const ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT', 'EADDRINFO', 'ESOCKETTIMEDOUT']; /** * Determine if a request should be retried. * (Borrowed from segmentio/superagent-retry) * - * @param {Error} err - * @param {Response} [res] - * @returns {Boolean} + * @param {Error} err an error + * @param {Response} [res] response + * @returns {Boolean} if segment should be retried */ -RequestBase.prototype._shouldRetry = function(err, res) { + +RequestBase.prototype._shouldRetry = function (err, res) { if (!this._maxRetries || this._retries++ >= this._maxRetries) { return false; } + if (this._retryCallback) { try { const override = this._retryCallback(err, res); + if (override === true) return true; - if (override === false) return false; - // undefined falls back to defaults - } catch(e) { - console.error(e); + if (override === false) return false; // undefined falls back to defaults + } catch (err2) { + console.error(err2); } } - if (res && res.status && res.status >= 500 && res.status != 501) return true; + + if (res && res.status && res.status >= 500 && res.status !== 501) return true; + if (err) { - if (err.code && ~ERROR_CODES.indexOf(err.code)) return true; - // Superagent timeout - if (err.timeout && err.code == 'ECONNABORTED') return true; + if (err.code && ERROR_CODES.indexOf(err.code) !== -1) return true; // Superagent timeout + + if (err.timeout && err.code === 'ECONNABORTED') return true; if (err.crossDomain) return true; } + return false; }; - /** * Retry request * @@ -211,11 +215,10 @@ RequestBase.prototype._shouldRetry = function(err, res) { * @api private */ -RequestBase.prototype._retry = function() { - this.clearTimeout(); +RequestBase.prototype._retry = function () { + this.clearTimeout(); // node - // node if (this.req) { this.req = null; this.req = this.request(); @@ -223,10 +226,8 @@ RequestBase.prototype._retry = function() { this._aborted = false; this.timedout = false; - return this._end(); }; - /** * Promise support * @@ -235,50 +236,55 @@ RequestBase.prototype._retry = function() { * @return {Request} */ -RequestBase.prototype.then = function then(resolve, reject) { + +RequestBase.prototype.then = function (resolve, reject) { if (!this._fullfilledPromise) { const self = this; + if (this._endCalled) { - console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises"); + console.warn('Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises'); } - this._fullfilledPromise = new Promise((innerResolve, innerReject) => { + + this._fullfilledPromise = new Promise((resolve, reject) => { self.on('abort', () => { const err = new Error('Aborted'); - err.code = "ABORTED"; + err.code = 'ABORTED'; err.status = this.status; err.method = this.method; err.url = this.url; - innerReject(err); + reject(err); }); self.end((err, res) => { - if (err) innerReject(err); - else innerResolve(res); + if (err) reject(err);else resolve(res); }); }); - } + } // eslint-disable-next-line promise/prefer-await-to-then + + return this._fullfilledPromise.then(resolve, reject); }; -RequestBase.prototype['catch'] = function(cb) { +RequestBase.prototype.catch = function (cb) { + // eslint-disable-next-line promise/prefer-await-to-then return this.then(undefined, cb); }; - /** * Allow for extension */ -RequestBase.prototype.use = function use(fn) { + +RequestBase.prototype.use = function (fn) { fn(this); return this; }; -RequestBase.prototype.ok = function(cb) { - if ('function' !== typeof cb) throw Error("Callback required"); +RequestBase.prototype.ok = function (cb) { + if (typeof cb !== 'function') throw new Error('Callback required'); this._okCallback = cb; return this; }; -RequestBase.prototype._isResponseOK = function(res) { +RequestBase.prototype._isResponseOK = function (res) { if (!res) { return false; } @@ -289,7 +295,6 @@ RequestBase.prototype._isResponseOK = function(res) { return res.status >= 200 && res.status < 300; }; - /** * Get request header `field`. * Case-insensitive. @@ -299,10 +304,10 @@ RequestBase.prototype._isResponseOK = function(res) { * @api public */ -RequestBase.prototype.get = function(field){ + +RequestBase.prototype.get = function (field) { return this._header[field.toLowerCase()]; }; - /** * Get case-insensitive header `field` value. * This is a deprecated internal API. Use `.get(field)` instead. @@ -315,8 +320,8 @@ RequestBase.prototype.get = function(field){ * @deprecated */ -RequestBase.prototype.getHeader = RequestBase.prototype.get; +RequestBase.prototype.getHeader = RequestBase.prototype.get; /** * Set header `field` to `val`, or multiple fields with one object. * Case-insensitive. @@ -338,17 +343,19 @@ RequestBase.prototype.getHeader = RequestBase.prototype.get; * @api public */ -RequestBase.prototype.set = function(field, val){ +RequestBase.prototype.set = function (field, val) { if (isObject(field)) { for (const key in field) { - this.set(key, field[key]); + if (Object.prototype.hasOwnProperty.call(field, key)) this.set(key, field[key]); } + return this; } + this._header[field.toLowerCase()] = val; this.header[field] = val; return this; -}; +}; // eslint-disable-next-line valid-jsdoc /** * Remove header `field`. @@ -360,14 +367,15 @@ RequestBase.prototype.set = function(field, val){ * .unset('User-Agent') * .end(callback); * - * @param {String} field + * @param {String} field field name */ -RequestBase.prototype.unset = function(field){ + + +RequestBase.prototype.unset = function (field) { delete this._header[field.toLowerCase()]; delete this.header[field]; return this; }; - /** * Write the field `name` and `val`, or multiple fields with one object * for "multipart/form-data" request bodies. @@ -382,14 +390,16 @@ RequestBase.prototype.unset = function(field){ * .end(callback); * ``` * - * @param {String|Object} name - * @param {String|Blob|File|Buffer|fs.ReadStream} val + * @param {String|Object} name name of field + * @param {String|Blob|File|Buffer|fs.ReadStream} val value of field * @return {Request} for chaining * @api public */ -RequestBase.prototype.field = function(name, val) { + + +RequestBase.prototype.field = function (name, val) { // name should be either a string or an object. - if (null === name || undefined === name) { + if (name === null || undefined === name) { throw new Error('.field(name, val) name can not be empty'); } @@ -399,48 +409,57 @@ RequestBase.prototype.field = function(name, val) { if (isObject(name)) { for (const key in name) { - this.field(key, name[key]); + if (Object.prototype.hasOwnProperty.call(name, key)) this.field(key, name[key]); } + return this; } if (Array.isArray(val)) { for (const i in val) { - this.field(name, val[i]); + if (Object.prototype.hasOwnProperty.call(val, i)) this.field(name, val[i]); } + return this; - } + } // val should be defined now - // val should be defined now - if (null === val || undefined === val) { + + if (val === null || undefined === val) { throw new Error('.field(name, val) val can not be empty'); } - if ('boolean' === typeof val) { - val = '' + val; + + if (typeof val === 'boolean') { + val = String(val); } + this._getFormData().append(name, val); + return this; }; - /** * Abort the request, and clear potential timeout. * - * @return {Request} + * @return {Request} request * @api public */ -RequestBase.prototype.abort = function(){ + + +RequestBase.prototype.abort = function () { if (this._aborted) { return this; } + this._aborted = true; - this.xhr && this.xhr.abort(); // browser - this.req && this.req.abort(); // node + if (this.xhr) this.xhr.abort(); // browser + + if (this.req) this.req.abort(); // node + this.clearTimeout(); this.emit('abort'); return this; }; -RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { +RequestBase.prototype._auth = function (user, pass, options, base64Encoder) { switch (options.type) { case 'basic': this.set('Authorization', `Basic ${base64Encoder(`${user}:${pass}`)}`); @@ -451,13 +470,17 @@ RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { this.password = pass; break; - case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) + case 'bearer': + // usage would be .auth(accessToken, { type: 'bearer' }) this.set('Authorization', `Bearer ${user}`); break; + + default: + break; } + return this; }; - /** * Enable transmission of cookies with x-domain requests. * @@ -469,13 +492,13 @@ RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { * @api public */ -RequestBase.prototype.withCredentials = function(on) { + +RequestBase.prototype.withCredentials = function (on) { // This is browser-only functionality. Node side is no-op. - if (on == undefined) on = true; + if (on === undefined) on = true; this._withCredentials = on; return this; }; - /** * Set the max redirects to `n`. Does noting in browser XHR implementation. * @@ -484,26 +507,28 @@ RequestBase.prototype.withCredentials = function(on) { * @api public */ -RequestBase.prototype.redirects = function(n){ + +RequestBase.prototype.redirects = function (n) { this._maxRedirects = n; return this; }; - /** * Maximum size of buffered response body, in bytes. Counts uncompressed size. * Default 200MB. * - * @param {Number} n + * @param {Number} n number of bytes * @return {Request} for chaining */ -RequestBase.prototype.maxResponseSize = function(n){ - if ('number' !== typeof n) { - throw TypeError("Invalid argument"); + + +RequestBase.prototype.maxResponseSize = function (n) { + if (typeof n !== 'number') { + throw new TypeError('Invalid argument'); } + this._maxResponseSize = n; return this; }; - /** * Convert to a plain javascript object (not JSON string) of scalar properties. * Note as this method is designed to return a useful non-this value, @@ -513,15 +538,15 @@ RequestBase.prototype.maxResponseSize = function(n){ * @api public */ -RequestBase.prototype.toJSON = function() { + +RequestBase.prototype.toJSON = function () { return { method: this.method, url: this.url, data: this._data, - headers: this._header, + headers: this._header }; }; - /** * Send `data` as the request body, defaulting the `.type()` to "json" when * an object is given. @@ -561,8 +586,10 @@ RequestBase.prototype.toJSON = function() { * @return {Request} for chaining * @api public */ +// eslint-disable-next-line complexity -RequestBase.prototype.send = function(data){ + +RequestBase.prototype.send = function (data) { const isObj = isObject(data); let type = this._header['content-type']; @@ -577,22 +604,21 @@ RequestBase.prototype.send = function(data){ this._data = {}; } } else if (data && this._data && this._isHost(this._data)) { - throw Error("Can't merge these send calls"); - } + throw new Error("Can't merge these send calls"); + } // merge + - // merge if (isObj && isObject(this._data)) { for (const key in data) { - this._data[key] = data[key]; + if (Object.prototype.hasOwnProperty.call(data, key)) this._data[key] = data[key]; } - } else if ('string' == typeof data) { + } else if (typeof data === 'string') { // default to x-www-form-urlencoded if (!type) this.type('form'); type = this._header['content-type']; - if ('application/x-www-form-urlencoded' == type) { - this._data = this._data - ? `${this._data}&${data}` - : data; + + if (type === 'application/x-www-form-urlencoded') { + this._data = this._data ? `${this._data}&${data}` : data; } else { this._data = (this._data || '') + data; } @@ -602,13 +628,12 @@ RequestBase.prototype.send = function(data){ if (!isObj || this._isHost(data)) { return this; - } + } // default to json + - // default to json if (!type) this.type('json'); return this; }; - /** * Sort `querystring` by the sort function * @@ -637,51 +662,61 @@ RequestBase.prototype.send = function(data){ * @api public */ -RequestBase.prototype.sortQuery = function(sort) { + +RequestBase.prototype.sortQuery = function (sort) { // _sort default to true but otherwise can be a function or boolean this._sort = typeof sort === 'undefined' ? true : sort; return this; }; - /** * Compose querystring to append to req.url * * @api private */ -RequestBase.prototype._finalizeQueryString = function(){ + + +RequestBase.prototype._finalizeQueryString = function () { const query = this._query.join('&'); + if (query) { this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query; } + this._query.length = 0; // Makes the call idempotent if (this._sort) { const index = this.url.indexOf('?'); + if (index >= 0) { const queryArr = this.url.substring(index + 1).split('&'); - if ('function' === typeof this._sort) { + + if (typeof this._sort === 'function') { queryArr.sort(this._sort); } else { queryArr.sort(); } + this.url = this.url.substring(0, index) + '?' + queryArr.join('&'); } } -}; +}; // For backwards compat only -// For backwards compat only -RequestBase.prototype._appendQueryString = () => {console.trace("Unsupported");} +RequestBase.prototype._appendQueryString = () => { + console.warn('Unsupported'); +}; /** * Invoke callback with timeout error. * * @api private */ -RequestBase.prototype._timeoutError = function(reason, timeout, errno){ + +RequestBase.prototype._timeoutError = function (reason, timeout, errno) { if (this._aborted) { return; } + const err = new Error(`${reason + timeout}ms exceeded`); err.timeout = timeout; err.code = 'ECONNABORTED'; @@ -691,20 +726,19 @@ RequestBase.prototype._timeoutError = function(reason, timeout, errno){ this.callback(err); }; -RequestBase.prototype._setTimeouts = function() { - const self = this; +RequestBase.prototype._setTimeouts = function () { + const self = this; // deadline - // deadline if (this._timeout && !this._timer) { this._timer = setTimeout(() => { self._timeoutError('Timeout of ', self._timeout, 'ETIME'); }, this._timeout); - } - // response timeout + } // response timeout + + if (this._responseTimeout && !this._responseTimeoutTimer) { this._responseTimeoutTimer = setTimeout(() => { self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT'); }, this._responseTimeout); } - -}; +}; \ No newline at end of file diff --git a/lib/response-base.js b/lib/response-base.js index 3d44682aa..53ebeab57 100644 --- a/lib/response-base.js +++ b/lib/response-base.js @@ -1,17 +1,15 @@ -'use strict'; +"use strict"; /** * Module dependencies. */ - const utils = require('./utils'); - /** * Expose `ResponseBase`. */ -module.exports = ResponseBase; +module.exports = ResponseBase; /** * Initialize a new `ResponseBase`. * @@ -21,7 +19,6 @@ module.exports = ResponseBase; function ResponseBase(obj) { if (obj) return mixin(obj); } - /** * Mixin the prototype properties. * @@ -30,13 +27,14 @@ function ResponseBase(obj) { * @api private */ + function mixin(obj) { for (const key in ResponseBase.prototype) { - obj[key] = ResponseBase.prototype[key]; + if (Object.prototype.hasOwnProperty.call(ResponseBase.prototype, key)) obj[key] = ResponseBase.prototype[key]; } + return obj; } - /** * Get case-insensitive `field` value. * @@ -45,10 +43,10 @@ function mixin(obj) { * @api public */ -ResponseBase.prototype.get = function(field) { + +ResponseBase.prototype.get = function (field) { return this.header[field.toLowerCase()]; }; - /** * Set header related properties: * @@ -61,30 +59,29 @@ ResponseBase.prototype.get = function(field) { * @api private */ -ResponseBase.prototype._setHeaderProperties = function(header){ - // TODO: moar! - // TODO: make this a util - // content-type - const ct = header['content-type'] || ''; - this.type = utils.type(ct); +ResponseBase.prototype._setHeaderProperties = function (header) { + // TODO: moar! + // TODO: make this a util + // content-type + const ct = header['content-type'] || ''; + this.type = utils.type(ct); // params - // params - const params = utils.params(ct); - for (const key in params) this[key] = params[key]; + const params = utils.params(ct); + + for (const key in params) { + if (Object.prototype.hasOwnProperty.call(params, key)) this[key] = params[key]; + } - this.links = {}; + this.links = {}; // links - // links - try { - if (header.link) { - this.links = utils.parseLinks(header.link); - } - } catch (err) { - // ignore + try { + if (header.link) { + this.links = utils.parseLinks(header.link); } + } catch (err) {// ignore + } }; - /** * Set flags such as `.ok` based on `status`. * @@ -106,31 +103,28 @@ ResponseBase.prototype._setHeaderProperties = function(header){ * @api private */ -ResponseBase.prototype._setStatusProperties = function(status){ - const type = status / 100 | 0; - - // status / class - this.status = this.statusCode = status; - this.statusType = type; - - // basics - this.info = 1 == type; - this.ok = 2 == type; - this.redirect = 3 == type; - this.clientError = 4 == type; - this.serverError = 5 == type; - this.error = (4 == type || 5 == type) - ? this.toError() - : false; - - // sugar - this.created = 201 == status; - this.accepted = 202 == status; - this.noContent = 204 == status; - this.badRequest = 400 == status; - this.unauthorized = 401 == status; - this.notAcceptable = 406 == status; - this.forbidden = 403 == status; - this.notFound = 404 == status; - this.unprocessableEntity = 422 == status; -}; + +ResponseBase.prototype._setStatusProperties = function (status) { + const type = status / 100 | 0; // status / class + + this.statusCode = status; + this.status = this.statusCode; + this.statusType = type; // basics + + this.info = type === 1; + this.ok = type === 2; + this.redirect = type === 3; + this.clientError = type === 4; + this.serverError = type === 5; + this.error = type === 4 || type === 5 ? this.toError() : false; // sugar + + this.created = status === 201; + this.accepted = status === 202; + this.noContent = status === 204; + this.badRequest = status === 400; + this.unauthorized = status === 401; + this.notAcceptable = status === 406; + this.forbidden = status === 403; + this.notFound = status === 404; + this.unprocessableEntity = status === 422; +}; \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js index d75f5c476..1e2e58c96 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; /** * Return the mime type for the given `str`. @@ -7,9 +7,7 @@ * @return {String} * @api private */ - exports.type = str => str.split(/ *; */).shift(); - /** * Return header field parameters. * @@ -18,15 +16,14 @@ exports.type = str => str.split(/ *; */).shift(); * @api private */ + exports.params = str => str.split(/ *; */).reduce((obj, str) => { const parts = str.split(/ *= */); const key = parts.shift(); const val = parts.shift(); - if (key && val) obj[key] = val; return obj; }, {}); - /** * Parse Link header fields. * @@ -35,6 +32,7 @@ exports.params = str => str.split(/ *; */).reduce((obj, str) => { * @api private */ + exports.parseLinks = str => str.split(/ *, */).reduce((obj, str) => { const parts = str.split(/ *; */); const url = parts[0].slice(1, -1); @@ -42,7 +40,6 @@ exports.parseLinks = str => str.split(/ *, */).reduce((obj, str) => { obj[rel] = url; return obj; }, {}); - /** * Strip content related fields from `header`. * @@ -51,15 +48,17 @@ exports.parseLinks = str => str.split(/ *, */).reduce((obj, str) => { * @api private */ + exports.cleanHeader = (header, changesOrigin) => { delete header['content-type']; delete header['content-length']; delete header['transfer-encoding']; - delete header['host']; - // secuirty + delete header.host; // secuirty + if (changesOrigin) { - delete header['authorization']; - delete header['cookie']; + delete header.authorization; + delete header.cookie; } + return header; -}; +}; \ No newline at end of file diff --git a/package.json b/package.json index 7c24bb8aa..f82571785 100644 --- a/package.json +++ b/package.json @@ -1,69 +1,222 @@ { "name": "superagent", - "version": "4.1.0", "description": "elegant & feature rich browser / node HTTP with a fluent API", - "scripts": { - "prepare": "make all", - "test": "make test", - "test-http2": "make test-node-http2" - }, - "keywords": [ - "http", - "ajax", - "request", - "agent" - ], - "license": "MIT", + "version": "4.1.0", "author": "TJ Holowaychuk ", + "browser": { + "./src/node/index.js": "./src/client.js", + "./test/support/server.js": "./test/support/blank.js" + }, + "bugs": { + "url": "https://github.com/visionmedia/superagent/issues" + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, "contributors": [ "Kornel Lesiński ", "Peter Lyons ", - "Hunter Loftis " + "Hunter Loftis ", + "Nick Baugh " ], - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/superagent.git" - }, "dependencies": { - "component-emitter": "^1.2.0", + "component-emitter": "^1.2.1", "cookiejar": "^2.1.2", - "debug": "^4.1.0", + "core-js": "^3.0.0", + "debug": "^4.1.1", "form-data": "^2.3.3", - "formidable": "^1.2.0", - "methods": "^1.1.1", + "formidable": "^1.2.1", + "methods": "^1.1.2", "mime": "^2.4.0", - "qs": "^6.6.0", - "readable-stream": "^3.0.6" + "qs": "^6.7.0", + "readable-stream": "^3.2.0" }, "devDependencies": { - "Base64": "^1.0.1", - "babel-core": "^6.26.3", - "babel-preset-es2015": "^6.24.1", - "babelify": "^8.0.0", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.4.0", + "@babel/plugin-transform-runtime": "^7.4.0", + "@babel/preset-env": "^7.4.2", + "@commitlint/cli": "^7.5.2", + "@commitlint/config-conventional": "^7.5.0", + "Base64": "^1.0.2", + "babelify": "^10.0.0", "basic-auth-connect": "^1.0.0", - "body-parser": "^1.18.2", + "body-parser": "^1.18.3", "browserify": "^16.2.3", - "cookie-parser": "^1.4.3", - "express": "^4.16.3", + "caniuse-lite": "^1.0.30000954", + "codecov": "^3.2.0", + "cookie-parser": "^1.4.4", + "cross-env": "^5.2.0", + "eslint": "^5.15.3", + "eslint-config-xo-lass": "^1.0.3", + "eslint-plugin-compat": "^3.1.0", + "eslint-plugin-node": "^8.0.1", + "express": "^4.16.4", "express-session": "^1.15.6", - "marked": "^0.5.2", - "mocha": "^3.5.3", + "fixpack": "^2.3.1", + "husky": "^1.3.1", + "lint-staged": "^8.1.5", + "marked": "^0.6.1", + "mocha": "3.5.3", "multer": "^1.4.1", - "should": "^13.2.0", + "nyc": "^13.3.0", + "remark-cli": "^6.0.1", + "remark-preset-github": "^0.0.13", + "rimraf": "^2.6.3", + "should": "^13.2.3", "should-http": "^0.1.1", + "tinyify": "^2.5.0", + "uglify-js": "^3.5.2", + "xo": "0.24.0", "zuul": "^3.12.0" }, - "browser": { - "./lib/node/index.js": "./lib/client.js", - "./test/support/server.js": "./test/support/blank.js" + "engines": { + "node": ">= 8.8.1" }, - "component": { - "scripts": { - "superagent": "lib/client.js" + "homepage": "https://github.com/visionmedia/superagent", + "husky": { + "hooks": { + "pre-commit": "npm test", + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } }, - "main": "./lib/node/index.js", - "engines": { - "node": ">= 6.0" + "jsdelivr": "dist/superagent.min.js", + "keywords": [ + "agent", + "ajax", + "ajax", + "api", + "async", + "await", + "axios", + "cancel", + "client", + "frisbee", + "got", + "http", + "http", + "https", + "ky", + "promise", + "promise", + "promises", + "request", + "request", + "requests", + "response", + "rest", + "retry", + "super", + "superagent", + "timeout", + "transform", + "xhr", + "xmlhttprequest" + ], + "license": "MIT", + "lint-staged": { + "linters": { + "*.js": [ + "xo --fix", + "git add" + ], + "*.md": [ + "remark . -qfo", + "git add" + ], + "package.json": [ + "fixpack", + "git add" + ] + } + }, + "main": "lib/node/index.js", + "prettier": { + "singleQuote": true, + "bracketSpacing": true, + "trailingComma": "none" + }, + "remarkConfig": { + "plugins": [ + "preset-github" + ] + }, + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/superagent.git" + }, + "scripts": { + "browserify": "browserify src/node/index.js -o dist/superagent.js -s superagent -d -t [ babelify --configFile ./.dist.babelrc ]", + "build": "npm run build:clean && npm run build:lib && npm run build:dist", + "build:clean": "rimraf lib dist", + "build:dist": "npm run browserify && npm run minify", + "build:lib": "babel --config-file ./.lib.babelrc src --out-dir lib", + "coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov", + "lint": "xo && remark . -qfo && eslint -c .lib.eslintrc lib && eslint -c .dist.eslintrc dist", + "minify": "cross-env NODE_ENV=production browserify src/node/index.js -o dist/superagent.min.js -s superagent -t [ babelify --configFile ./.dist.babelrc ] -p tinyify", + "nyc": "cross-env NODE_ENV=test nyc ava", + "test": "npm run build && npm run lint && make test", + "test-http2": "npm run build && npm run lint && make test-node-http2" + }, + "unpkg": "dist/superagent.min.js", + "xo": { + "prettier": true, + "space": true, + "extends": [ + "xo-lass" + ], + "env": [ + "node", + "browser" + ], + "overrides": [ + { + "files": "test/**/*.js", + "env": [ + "mocha" + ], + "rules": { + "block-scoped-var": "off", + "complexity": "off", + "default-case": "off", + "eqeqeq": "off", + "func-name-matching": "off", + "func-names": "off", + "guard-for-in": "off", + "handle-callback-err": "off", + "import/no-extraneous-dependencies": "off", + "import/no-unassigned-import": "off", + "import/order": "off", + "max-nested-callbacks": "off", + "new-cap": "off", + "no-eq-null": "off", + "no-extend-native": "off", + "no-implicit-coercion": "off", + "no-multi-assign": "off", + "no-negated-condition": "off", + "no-prototype-builtins": "off", + "no-redeclare": "off", + "no-undef": "off", + "no-unused-expressions": "off", + "no-unused-vars": "off", + "no-use-extend-native/no-use-extend-native": "off", + "no-useless-escape": "off", + "no-var": "off", + "no-void": "off", + "node/no-deprecated-api": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "promise/prefer-await-to-then": "off", + "promise/valid-params": "off", + "unicorn/filename-case": "off", + "valid-jsdoc": "off" + } + } + ], + "globals": [ + "ActiveXObject" + ] } } diff --git a/src/agent-base.js b/src/agent-base.js new file mode 100644 index 000000000..d7a1666c2 --- /dev/null +++ b/src/agent-base.js @@ -0,0 +1,41 @@ +function Agent() { + this._defaults = []; +} + +[ + 'use', + 'on', + 'once', + 'set', + 'query', + 'type', + 'accept', + 'auth', + 'withCredentials', + 'sortQuery', + 'retry', + 'ok', + 'redirects', + 'timeout', + 'buffer', + 'serialize', + 'parse', + 'ca', + 'key', + 'pfx', + 'cert' +].forEach(fn => { + // Default setting for all requests from this agent + Agent.prototype[fn] = function(...args) { + this._defaults.push({ fn, args }); + return this; + }; +}); + +Agent.prototype._setDefaults = function(req) { + this._defaults.forEach(def => { + req[def.fn](...def.args); + }); +}; + +module.exports = Agent; diff --git a/src/client.js b/src/client.js new file mode 100644 index 000000000..7d3e677b5 --- /dev/null +++ b/src/client.js @@ -0,0 +1,1075 @@ +/** + * Root reference for iframes. + */ + +let root; +if (typeof window !== 'undefined') { + // Browser window + root = window; +} else if (typeof self === 'undefined') { + // Other environments + console.warn( + 'Using browser-only version of superagent in non-browser environment' + ); + root = this; +} else { + // Web Worker + root = self; +} + +// Array.from() is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import +require('core-js/features/array/from'); + +// Symbol is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import +require('core-js/features/symbol'); + +// Object.getOwnPropertySymbols() is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import +require('core-js/features/object/get-own-property-symbols'); + +// Object.setPrototypeOf() is not supported in IE 10 +// eslint-disable-next-line import/no-unassigned-import +require('core-js/features/object/set-prototype-of'); + +const Emitter = require('component-emitter'); +const RequestBase = require('./request-base'); +const isObject = require('./is-object'); +const ResponseBase = require('./response-base'); +const Agent = require('./agent-base'); + +/** + * Noop. + */ + +function noop() {} + +/** + * Expose `request`. + */ + +module.exports = function(method, url) { + // callback + if (typeof url === 'function') { + return new exports.Request('GET', method).end(url); + } + + // url first + if (arguments.length === 1) { + return new exports.Request('GET', method); + } + + return new exports.Request(method, url); +}; + +exports = module.exports; + +const request = exports; + +exports.Request = Request; + +/** + * Determine XHR. + */ + +request.getXHR = () => { + if ( + root.XMLHttpRequest && + (!root.location || + root.location.protocol !== 'file:' || + !root.ActiveXObject) + ) { + return new XMLHttpRequest(); + } + + try { + return new ActiveXObject('Microsoft.XMLHTTP'); + } catch (err) {} + + try { + return new ActiveXObject('Msxml2.XMLHTTP.6.0'); + } catch (err) {} + + try { + return new ActiveXObject('Msxml2.XMLHTTP.3.0'); + } catch (err) {} + + try { + return new ActiveXObject('Msxml2.XMLHTTP'); + } catch (err) {} + + throw new Error('Browser-only version of superagent could not find XHR'); +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +const trim = ''.trim ? s => s.trim() : s => s.replace(/(^\s*|\s*$)/g, ''); + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + const pairs = []; + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) + pushEncodedKeyValuePair(pairs, key, obj[key]); + } + + return pairs.join('&'); +} + +/** + * Helps 'serialize' with serializing arrays. + * Mutates the pairs array. + * + * @param {Array} pairs + * @param {String} key + * @param {Mixed} val + */ + +function pushEncodedKeyValuePair(pairs, key, val) { + if (val !== null) { + if (Array.isArray(val)) { + val.forEach(v => { + pushEncodedKeyValuePair(pairs, key, v); + }); + } else if (isObject(val)) { + for (const subkey in val) { + if (Object.prototype.hasOwnProperty.call(val, subkey)) + pushEncodedKeyValuePair(pairs, `${key}[${subkey}]`, val[subkey]); + } + } else { + pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + } + } else if (val === null) { + pairs.push(encodeURIComponent(key)); + } +} + +/** + * Expose serialization method. + */ + +request.serializeObject = serialize; + +/** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + const obj = {}; + const pairs = str.split('&'); + let pair; + let pos; + + for (let i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + pos = pair.indexOf('='); + if (pos === -1) { + obj[decodeURIComponent(pair)] = ''; + } else { + obj[decodeURIComponent(pair.slice(0, pos))] = decodeURIComponent( + pair.slice(pos + 1) + ); + } + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'text/xml', + urlencoded: 'application/x-www-form-urlencoded', + form: 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + +request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify +}; + +/** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + const lines = str.split(/\r?\n/); + const fields = {}; + let index; + let line; + let field; + let val; + + for (let i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + if (index === -1) { + // could be empty line, just skip it + continue; + } + + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Check if `mime` is json or has +json structured syntax suffix. + * + * @param {String} mime + * @return {Boolean} + * @api private + */ + +function isJSON(mime) { + // should match /json or +json + // but not /json-seq + return /[/+]json($|[^-\w])/.test(mime); +} + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req) { + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = + (this.req.method !== 'HEAD' && + (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || + typeof this.xhr.responseType === 'undefined' + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + let { status } = this.xhr; + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + this._setStatusProperties(status); + this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + this.header = this.headers; + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this._setHeaderProperties(this.header); + + if (this.text === null && req._responseType) { + this.body = this.xhr.response; + } else { + this.body = + this.req.method === 'HEAD' + ? null + : this._parseBody(this.text ? this.text : this.xhr.response); + } +} + +// eslint-disable-next-line new-cap +ResponseBase(Response.prototype); + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype._parseBody = function(str) { + let parse = request.parse[this.type]; + if (this.req._parser) { + return this.req._parser(this, str); + } + + if (!parse && isJSON(this.type)) { + parse = request.parse['application/json']; + } + + return parse && str && (str.length > 0 || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function() { + const { req } = this; + const { method } = req; + const { url } = req; + + const msg = `cannot ${method} ${url} (${this.status})`; + const err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + const self = this; + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; // preserves header name case + this._header = {}; // coerces header names to lowercase + this.on('end', () => { + let err = null; + let res = null; + + try { + res = new Response(self); + } catch (err2) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = err2; + // issue #675: return the raw response if the response parsing fails + if (self.xhr) { + // ie9 doesn't have 'response' property + err.rawResponse = + typeof self.xhr.responseType === 'undefined' + ? self.xhr.responseText + : self.xhr.response; + // issue #876: return the http status code if the response parsing fails + err.status = self.xhr.status ? self.xhr.status : null; + err.statusCode = err.status; // backwards-compat only + } else { + err.rawResponse = null; + err.status = null; + } + + return self.callback(err); + } + + self.emit('response', res); + + let new_err; + try { + if (!self._isResponseOK(res)) { + new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + } + } catch (err2) { + new_err = err2; // ok() callback can throw + } + + // #1000 don't catch errors from the callback to avoid double calling it + if (new_err) { + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + self.callback(new_err, res); + } else { + self.callback(null, res); + } + }); +} + +/** + * Mixin `Emitter` and `RequestBase`. + */ + +// eslint-disable-next-line new-cap +Emitter(Request.prototype); +// eslint-disable-next-line new-cap +RequestBase(Request.prototype); + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type) { + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type) { + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} [pass] optional in case of using 'bearer' as type + * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic') + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass, options) { + if (arguments.length === 1) pass = ''; + if (typeof pass === 'object' && pass !== null) { + // pass is optional and can be replaced with options + options = pass; + pass = ''; + } + + if (!options) { + options = { + type: typeof btoa === 'function' ? 'basic' : 'auto' + }; + } + + const encoder = string => { + if (typeof btoa === 'function') { + return btoa(string); + } + + throw new Error('Cannot use basic auth, btoa is not a function'); + }; + + return this._auth(user, pass, options, encoder); +}; + +/** + * Add query-string `val`. + * + * Examples: + * + * request.get('/shoes') + * .query('size=10') + * .query({ color: 'blue' }) + * + * @param {Object|String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.query = function(val) { + if (typeof val !== 'string') val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `options` (or filename). + * + * ``` js + * request.post('/upload') + * .attach('content', new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String|Object} options + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, options) { + if (file) { + if (this._data) { + throw new Error("superagent can't mix .send() and .attach()"); + } + + this._getFormData().append(field, file, options || file.name); + } + + return this; +}; + +Request.prototype._getFormData = function() { + if (!this._formData) { + this._formData = new root.FormData(); + } + + return this._formData; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res) { + if (this._shouldRetry(err, res)) { + return this._retry(); + } + + const fn = this._callback; + this.clearTimeout(); + + if (err) { + if (this._maxRetries) err.retries = this._retries - 1; + this.emit('error', err); + } + + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function() { + const err = new Error( + 'Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.' + ); + err.crossDomain = true; + + err.status = this.status; + err.method = this.method; + err.url = this.url; + + this.callback(err); +}; + +// This only warns, because the request is still likely to work +Request.prototype.agent = function() { + console.warn('This is not supported in browser version of superagent'); + return this; +}; + +Request.prototype.buffer = Request.prototype.ca; +Request.prototype.ca = Request.prototype.agent; + +// This throws, because it can't send/receive data as expected +Request.prototype.write = () => { + throw new Error( + 'Streaming is not supported in browser version of superagent' + ); +}; + +Request.prototype.pipe = Request.prototype.write; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * @param {Object} obj host object + * @return {Boolean} is a host object + * @api private + */ +Request.prototype._isHost = function(obj) { + // Native objects stringify to [object File], [object Blob], [object FormData], etc. + return ( + obj && + typeof obj === 'object' && + !Array.isArray(obj) && + Object.prototype.toString.call(obj) !== '[object Object]' + ); +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn) { + if (this._endCalled) { + console.warn( + 'Warning: .end() was called twice. This is not supported in superagent' + ); + } + + this._endCalled = true; + + // store callback + this._callback = fn || noop; + + // querystring + this._finalizeQueryString(); + + this._end(); +}; + +Request.prototype._setUploadTimeout = function() { + const self = this; + + // upload timeout it's wokrs only if deadline timeout is off + if (this._uploadTimeout && !this._uploadTimeoutTimer) { + this._uploadTimeoutTimer = setTimeout(() => { + self._timeoutError( + 'Upload timeout of ', + self._uploadTimeout, + 'ETIMEDOUT' + ); + }, this._uploadTimeout); + } +}; + +// eslint-disable-next-line complexity +Request.prototype._end = function() { + if (this._aborted) + return this.callback( + new Error('The request has been aborted even before .end() was called') + ); + + const self = this; + this.xhr = request.getXHR(); + const { xhr } = this; + let data = this._formData || this._data; + + this._setTimeouts(); + + // state change + xhr.onreadystatechange = () => { + const { readyState } = xhr; + if (readyState >= 2 && self._responseTimeoutTimer) { + clearTimeout(self._responseTimeoutTimer); + } + + if (readyState !== 4) { + return; + } + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + let status; + try { + status = xhr.status; + } catch (err) { + status = 0; + } + + if (!status) { + if (self.timedout || self._aborted) return; + return self.crossDomainError(); + } + + self.emit('end'); + }; + + // progress + const handleProgress = (direction, e) => { + if (e.total > 0) { + e.percent = (e.loaded / e.total) * 100; + + if (e.percent === 100) { + clearTimeout(self._uploadTimeoutTimer); + } + } + + e.direction = direction; + self.emit('progress', e); + }; + + if (this.hasListeners('progress')) { + try { + xhr.addEventListener('progress', handleProgress.bind(null, 'download')); + if (xhr.upload) { + xhr.upload.addEventListener( + 'progress', + handleProgress.bind(null, 'upload') + ); + } + } catch (err) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + } + + if (xhr.upload) { + this._setUploadTimeout(); + } + + // initiate request + try { + if (this.username && this.password) { + xhr.open(this.method, this.url, true, this.username, this.password); + } else { + xhr.open(this.method, this.url, true); + } + } catch (err) { + // see #1149 + return this.callback(err); + } + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ( + !this._formData && + this.method !== 'GET' && + this.method !== 'HEAD' && + typeof data !== 'string' && + !this._isHost(data) + ) { + // serialize stuff + const contentType = this._header['content-type']; + let serialize = + this._serializer || + request.serialize[contentType ? contentType.split(';')[0] : '']; + if (!serialize && isJSON(contentType)) { + serialize = request.serialize['application/json']; + } + + if (serialize) data = serialize(data); + } + + // set header fields + for (const field in this.header) { + if (this.header[field] === null) continue; + + if (Object.prototype.hasOwnProperty.call(this.header, field)) + xhr.setRequestHeader(field, this.header[field]); + } + + if (this._responseType) { + xhr.responseType = this._responseType; + } + + // send stuff + this.emit('request', this); + + // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) + // We need null here if data is undefined + xhr.send(typeof data === 'undefined' ? null : data); +}; + +request.agent = () => new Agent(); + +['GET', 'POST', 'OPTIONS', 'PATCH', 'PUT', 'DELETE'].forEach(method => { + Agent.prototype[method.toLowerCase()] = function(url, fn) { + const req = new request.Request(method, url); + this._setDefaults(req); + if (fn) { + req.end(fn); + } + + return req; + }; +}); + +Agent.prototype.del = Agent.prototype.delete; + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.get = (url, data, fn) => { + const req = request('GET', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.head = (url, data, fn) => { + const req = request('HEAD', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * OPTIONS query to `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.options = (url, data, fn) => { + const req = request('OPTIONS', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +function del(url, data, fn) { + const req = request('DELETE', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.send(data); + if (fn) req.end(fn); + return req; +} + +request.del = del; +request.delete = del; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.patch = (url, data, fn) => { + const req = request('PATCH', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.post = (url, data, fn) => { + const req = request('POST', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.put = (url, data, fn) => { + const req = request('PUT', url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; diff --git a/src/is-object.js b/src/is-object.js new file mode 100644 index 000000000..a73e8408c --- /dev/null +++ b/src/is-object.js @@ -0,0 +1,13 @@ +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return obj !== null && typeof obj === 'object'; +} + +module.exports = isObject; diff --git a/src/node/agent.js b/src/node/agent.js new file mode 100644 index 000000000..cb1a71c8c --- /dev/null +++ b/src/node/agent.js @@ -0,0 +1,106 @@ +'use strict'; + +/** + * Module dependencies. + */ + +// eslint-disable-next-line node/no-deprecated-api +const { parse } = require('url'); +const { CookieJar } = require('cookiejar'); +const { CookieAccessInfo } = require('cookiejar'); +const methods = require('methods'); +const request = require('../..'); +const AgentBase = require('../agent-base'); + +/** + * Expose `Agent`. + */ + +module.exports = Agent; + +/** + * Initialize a new `Agent`. + * + * @api public + */ + +function Agent(options) { + if (!(this instanceof Agent)) { + return new Agent(options); + } + + AgentBase.call(this); + this.jar = new CookieJar(); + + if (options) { + if (options.ca) { + this.ca(options.ca); + } + + if (options.key) { + this.key(options.key); + } + + if (options.pfx) { + this.pfx(options.pfx); + } + + if (options.cert) { + this.cert(options.cert); + } + } +} + +Agent.prototype = Object.create(AgentBase.prototype); + +/** + * Save the cookies in the given `res` to + * the agent's cookie jar for persistence. + * + * @param {Response} res + * @api private + */ + +Agent.prototype._saveCookies = function(res) { + const cookies = res.headers['set-cookie']; + if (cookies) this.jar.setCookies(cookies); +}; + +/** + * Attach cookies when available to the given `req`. + * + * @param {Request} req + * @api private + */ + +Agent.prototype._attachCookies = function(req) { + const url = parse(req.url); + const access = new CookieAccessInfo( + url.hostname, + url.pathname, + url.protocol === 'https:' + ); + const cookies = this.jar.getCookies(access).toValueString(); + req.cookies = cookies; +}; + +methods.forEach(name => { + const method = name.toUpperCase(); + Agent.prototype[name] = function(url, fn) { + const req = new request.Request(method, url); + + req.on('response', this._saveCookies.bind(this)); + req.on('redirect', this._saveCookies.bind(this)); + req.on('redirect', this._attachCookies.bind(this, req)); + this._attachCookies(req); + this._setDefaults(req); + + if (fn) { + req.end(fn); + } + + return req; + }; +}); + +Agent.prototype.del = Agent.prototype.delete; diff --git a/src/node/http2wrapper.js b/src/node/http2wrapper.js new file mode 100644 index 000000000..af9d7e3bc --- /dev/null +++ b/src/node/http2wrapper.js @@ -0,0 +1,201 @@ +'use strict'; + +const http2 = require('http2'); +const Stream = require('stream'); +const util = require('util'); +const net = require('net'); +const tls = require('tls'); +// eslint-disable-next-line node/no-deprecated-api +const { parse } = require('url'); + +const { + HTTP2_HEADER_PATH, + HTTP2_HEADER_STATUS, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_HOST, + HTTP2_HEADER_SET_COOKIE, + NGHTTP2_CANCEL +} = http2.constants; + +function setProtocol(protocol) { + return { + request(options) { + return new Request(protocol, options); + } + }; +} + +function Request(protocol, options) { + Stream.call(this); + const defaultPort = protocol === 'https:' ? 443 : 80; + const defaultHost = 'localhost'; + const port = options.port || defaultPort; + const host = options.host || defaultHost; + + delete options.port; + delete options.host; + + this.method = options.method; + this.path = options.path; + this.protocol = protocol; + this.host = host; + + delete options.method; + delete options.path; + + const sessionOptions = { ...options }; + if (options.socketPath) { + sessionOptions.socketPath = options.socketPath; + sessionOptions.createConnection = this.createUnixConnection.bind(this); + } + + this._headers = {}; + + const session = http2.connect(`${protocol}//${host}:${port}`, sessionOptions); + this.setHeader('host', `${host}:${port}`); + + session.on('error', err => this.emit('error', err)); + + this.session = session; +} + +/** + * Inherit from `Stream` (which inherits from `EventEmitter`). + */ +util.inherits(Request, Stream); + +Request.prototype.createUnixConnection = function(authority, options) { + switch (this.protocol) { + case 'http:': + return net.connect(options.socketPath); + case 'https:': + options.ALPNProtocols = ['h2']; + options.servername = this.host; + options.allowHalfOpen = true; + return tls.connect(options.socketPath, options); + default: + throw new Error('Unsupported protocol', this.protocol); + } +}; + +// eslint-disable-next-line no-unused-vars +Request.prototype.setNoDelay = function(bool) { + // We can not use setNoDelay with HTTP/2. + // Node 10 limits http2session.socket methods to ones safe to use with HTTP/2. + // See also https://nodejs.org/api/http2.html#http2_http2session_socket +}; + +Request.prototype.getFrame = function() { + if (this.frame) { + return this.frame; + } + + const method = { + [HTTP2_HEADER_PATH]: this.path, + [HTTP2_HEADER_METHOD]: this.method + }; + + let headers = this.mapToHttp2Header(this._headers); + + headers = Object.assign(headers, method); + + const frame = this.session.request(headers); + // eslint-disable-next-line no-unused-vars + frame.once('response', (headers, flags) => { + headers = this.mapToHttpHeader(headers); + frame.headers = headers; + frame.statusCode = headers[HTTP2_HEADER_STATUS]; + frame.status = frame.statusCode; + this.emit('response', frame); + }); + + this._headerSent = true; + + frame.once('drain', () => this.emit('drain')); + frame.on('error', err => this.emit('error', err)); + frame.on('close', () => this.session.close()); + + this.frame = frame; + return frame; +}; + +Request.prototype.mapToHttpHeader = function(headers) { + const keys = Object.keys(headers); + const http2Headers = {}; + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + let value = headers[key]; + key = key.toLowerCase(); + switch (key) { + case HTTP2_HEADER_SET_COOKIE: + value = Array.isArray(value) ? value : [value]; + break; + default: + break; + } + + http2Headers[key] = value; + } + + return http2Headers; +}; + +Request.prototype.mapToHttp2Header = function(headers) { + const keys = Object.keys(headers); + const http2Headers = {}; + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; + let value = headers[key]; + key = key.toLowerCase(); + switch (key) { + case HTTP2_HEADER_HOST: + key = HTTP2_HEADER_AUTHORITY; + value = /^http:\/\/|^https:\/\//.test(value) + ? parse(value).host + : value; + break; + default: + break; + } + + http2Headers[key] = value; + } + + return http2Headers; +}; + +Request.prototype.setHeader = function(name, value) { + this._headers[name.toLowerCase()] = value; +}; + +Request.prototype.getHeader = function(name) { + return this._headers[name.toLowerCase()]; +}; + +Request.prototype.write = function(data, encoding) { + const frame = this.getFrame(); + return frame.write(data, encoding); +}; + +Request.prototype.pipe = function(stream, options) { + const frame = this.getFrame(); + return frame.pipe( + stream, + options + ); +}; + +Request.prototype.end = function(data) { + const frame = this.getFrame(); + frame.end(data); +}; + +// eslint-disable-next-line no-unused-vars +Request.prototype.abort = function(data) { + const frame = this.getFrame(); + frame.close(NGHTTP2_CANCEL); + this.session.destroy(); +}; + +exports.setProtocol = setProtocol; diff --git a/src/node/index.js b/src/node/index.js new file mode 100644 index 000000000..bb7b2f7bb --- /dev/null +++ b/src/node/index.js @@ -0,0 +1,1351 @@ +'use strict'; + +/** + * Module dependencies. + */ + +// eslint-disable-next-line node/no-deprecated-api +const { parse, format, resolve } = require('url'); +const Stream = require('stream'); +const https = require('https'); +const http = require('http'); +const fs = require('fs'); +const zlib = require('zlib'); +const util = require('util'); +const qs = require('qs'); +const mime = require('mime'); +let methods = require('methods'); +const FormData = require('form-data'); +const formidable = require('formidable'); +const debug = require('debug')('superagent'); +const CookieJar = require('cookiejar'); +const utils = require('../utils'); +const pkg = require('../../package.json'); +const RequestBase = require('../request-base'); +const { unzip } = require('./unzip'); +const Response = require('./response'); + +let http2; +try { + http2 = require('./http2wrapper'); +} catch (_) {} + +function request(method, url) { + // callback + if (typeof url === 'function') { + return new exports.Request('GET', method).end(url); + } + + // url first + if (arguments.length === 1) { + return new exports.Request('GET', method); + } + + return new exports.Request(method, url); +} + +module.exports = request; +exports = module.exports; + +/** + * Expose `Request`. + */ + +exports.Request = Request; + +/** + * Expose the agent function + */ + +exports.agent = require('./agent'); + +/** + * Noop. + */ + +function noop() {} + +/** + * Expose `Response`. + */ + +exports.Response = Response; + +/** + * Define "form" mime type. + */ + +mime.define( + { + 'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data'] + }, + true +); + +/** + * Protocol map. + */ + +exports.protocols = { + 'http:': http, + 'https:': https, + 'http2:': http2 +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + +exports.serialize = { + 'application/x-www-form-urlencoded': qs.stringify, + 'application/json': JSON.stringify +}; + +/** + * Default parsers. + * + * superagent.parse['application/xml'] = function(res, fn){ + * fn(null, res); + * }; + * + */ + +exports.parse = require('./parsers'); + +/** + * Default buffering map. Can be used to set certain + * response types to buffer/not buffer. + * + * superagent.buffer['application/xml'] = true; + */ +exports.buffer = {}; + +/** + * Initialize internal header tracking properties on a request instance. + * + * @param {Object} req the instance + * @api private + */ +function _initHeaders(req) { + const ua = `node-superagent/${pkg.version}`; + req._header = { + // coerces header names to lowercase + 'user-agent': ua + }; + req.header = { + // preserves header name case + 'User-Agent': ua + }; +} + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String|Object} url + * @api public + */ + +function Request(method, url) { + Stream.call(this); + if (typeof url !== 'string') url = format(url); + this._enableHttp2 = Boolean(process.env.HTTP2_TEST); // internal only + this._agent = false; + this._formData = null; + this.method = method; + this.url = url; + _initHeaders(this); + this.writable = true; + this._redirects = 0; + this.redirects(method === 'HEAD' ? 0 : 5); + this.cookies = ''; + this.qs = {}; + this._query = []; + this.qsRaw = this._query; // Unused, for backwards compatibility only + this._redirectList = []; + this._streamRequest = false; + this.once('end', this.clearTimeout.bind(this)); +} + +/** + * Inherit from `Stream` (which inherits from `EventEmitter`). + * Mixin `RequestBase`. + */ +util.inherits(Request, Stream); +// eslint-disable-next-line new-cap +RequestBase(Request.prototype); + +/** + * Enable or Disable http2. + * + * Enable http2. + * + * ``` js + * request.get('http://localhost/') + * .http2() + * .end(callback); + * + * request.get('http://localhost/') + * .http2(true) + * .end(callback); + * ``` + * + * Disable http2. + * + * ``` js + * request = request.http2(); + * request.get('http://localhost/') + * .http2(false) + * .end(callback); + * ``` + * + * @param {Boolean} enable + * @return {Request} for chaining + * @api public + */ + +Request.prototype.http2 = function(bool) { + if (exports.protocols['http2:'] === undefined) { + throw new Error( + 'superagent: this version of Node.js does not support http2' + ); + } + + this._enableHttp2 = bool === undefined ? true : bool; + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `options` (or filename). + * + * ``` js + * request.post('http://localhost/upload') + * .attach('field', Buffer.from('Hello world'), 'hello.html') + * .end(callback); + * ``` + * + * A filename may also be used: + * + * ``` js + * request.post('http://localhost/upload') + * .attach('files', 'image.jpg') + * .end(callback); + * ``` + * + * @param {String} field + * @param {String|fs.ReadStream|Buffer} file + * @param {String|Object} options + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, options) { + if (file) { + if (this._data) { + throw new Error("superagent can't mix .send() and .attach()"); + } + + let o = options || {}; + if (typeof options === 'string') { + o = { filename: options }; + } + + if (typeof file === 'string') { + if (!o.filename) o.filename = file; + debug('creating `fs.ReadStream` instance for file: %s', file); + file = fs.createReadStream(file); + } else if (!o.filename && file.path) { + o.filename = file.path; + } + + this._getFormData().append(field, file, o); + } + + return this; +}; + +Request.prototype._getFormData = function() { + if (!this._formData) { + this._formData = new FormData(); + this._formData.on('error', err => { + debug('FormData error', err); + if (this.called) { + // The request has already finished and the callback was called. + // Silently ignore the error. + return; + } + + this.callback(err); + this.abort(); + }); + } + + return this._formData; +}; + +/** + * Gets/sets the `Agent` to use for this HTTP request. The default (if this + * function is not called) is to opt out of connection pooling (`agent: false`). + * + * @param {http.Agent} agent + * @return {http.Agent} + * @api public + */ + +Request.prototype.agent = function(agent) { + if (arguments.length === 0) return this._agent; + this._agent = agent; + return this; +}; + +/** + * Set _Content-Type_ response header passed through `mime.getType()`. + * + * Examples: + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('json') + * .send(jsonstring) + * .end(callback); + * + * request.post('/') + * .type('application/json') + * .send(jsonstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type) { + return this.set( + 'Content-Type', + type.indexOf('/') === -1 ? mime.getType(type) : type + ); +}; + +/** + * Set _Accept_ response header passed through `mime.getType()`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type) { + return this.set( + 'Accept', + type.indexOf('/') === -1 ? mime.getType(type) : type + ); +}; + +/** + * Add query-string `val`. + * + * Examples: + * + * request.get('/shoes') + * .query('size=10') + * .query({ color: 'blue' }) + * + * @param {Object|String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.query = function(val) { + if (typeof val === 'string') { + this._query.push(val); + } else { + Object.assign(this.qs, val); + } + + return this; +}; + +/** + * Write raw `data` / `encoding` to the socket. + * + * @param {Buffer|String} data + * @param {String} encoding + * @return {Boolean} + * @api public + */ + +Request.prototype.write = function(data, encoding) { + const req = this.request(); + if (!this._streamRequest) { + this._streamRequest = true; + } + + return req.write(data, encoding); +}; + +/** + * Pipe the request body to `stream`. + * + * @param {Stream} stream + * @param {Object} options + * @return {Stream} + * @api public + */ + +Request.prototype.pipe = function(stream, options) { + this.piped = true; // HACK... + this.buffer(false); + this.end(); + return this._pipeContinue(stream, options); +}; + +Request.prototype._pipeContinue = function(stream, options) { + this.req.once('response', res => { + // redirect + const redirect = isRedirect(res.statusCode); + if (redirect && this._redirects++ !== this._maxRedirects) { + return this._redirect(res)._pipeContinue(stream, options); + } + + this.res = res; + this._emitResponse(); + if (this._aborted) return; + + if (this._shouldUnzip(res)) { + const unzipObj = zlib.createUnzip(); + unzipObj.on('error', err => { + if (err && err.code === 'Z_BUF_ERROR') { + // unexpected end of file is ignored by browsers and curl + stream.emit('end'); + return; + } + + stream.emit('error', err); + }); + res.pipe(unzipObj).pipe( + stream, + options + ); + } else { + res.pipe( + stream, + options + ); + } + + res.once('end', () => { + this.emit('end'); + }); + }); + return stream; +}; + +/** + * Enable / disable buffering. + * + * @return {Boolean} [val] + * @return {Request} for chaining + * @api public + */ + +Request.prototype.buffer = function(val) { + this._buffer = val !== false; + return this; +}; + +/** + * Redirect to `url + * + * @param {IncomingMessage} res + * @return {Request} for chaining + * @api private + */ + +Request.prototype._redirect = function(res) { + let url = res.headers.location; + if (!url) { + return this.callback(new Error('No location header for redirect'), res); + } + + debug('redirect %s -> %s', this.url, url); + + // location + url = resolve(this.url, url); + + // ensure the response is being consumed + // this is required for Node v0.10+ + res.resume(); + + let headers = this.req._headers; + + const changesOrigin = parse(url).host !== parse(this.url).host; + + // implementation of 302 following defacto standard + if (res.statusCode === 301 || res.statusCode === 302) { + // strip Content-* related fields + // in case of POST etc + headers = utils.cleanHeader(this.req._headers, changesOrigin); + + // force GET + this.method = this.method === 'HEAD' ? 'HEAD' : 'GET'; + + // clear data + this._data = null; + } + + // 303 is always GET + if (res.statusCode === 303) { + // strip Content-* related fields + // in case of POST etc + headers = utils.cleanHeader(this.req._headers, changesOrigin); + + // force method + this.method = 'GET'; + + // clear data + this._data = null; + } + + // 307 preserves method + // 308 preserves method + delete headers.host; + + delete this.req; + delete this._formData; + + // remove all add header except User-Agent + _initHeaders(this); + + // redirect + this._endCalled = false; + this.url = url; + this.qs = {}; + this._query.length = 0; + this.set(headers); + this.emit('redirect', res); + this._redirectList.push(this.url); + this.end(this._callback); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * Examples: + * + * .auth('tobi', 'learnboost') + * .auth('tobi:learnboost') + * .auth('tobi') + * .auth(accessToken, { type: 'bearer' }) + * + * @param {String} user + * @param {String} [pass] + * @param {Object} [options] options with authorization type 'basic' or 'bearer' ('basic' is default) + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass, options) { + if (arguments.length === 1) pass = ''; + if (typeof pass === 'object' && pass !== null) { + // pass is optional and can be replaced with options + options = pass; + pass = ''; + } + + if (!options) { + options = { type: 'basic' }; + } + + const encoder = string => Buffer.from(string).toString('base64'); + + return this._auth(user, pass, options, encoder); +}; + +/** + * Set the certificate authority option for https request. + * + * @param {Buffer | Array} cert + * @return {Request} for chaining + * @api public + */ + +Request.prototype.ca = function(cert) { + this._ca = cert; + return this; +}; + +/** + * Set the client certificate key option for https request. + * + * @param {Buffer | String} cert + * @return {Request} for chaining + * @api public + */ + +Request.prototype.key = function(cert) { + this._key = cert; + return this; +}; + +/** + * Set the key, certificate, and CA certs of the client in PFX or PKCS12 format. + * + * @param {Buffer | String} cert + * @return {Request} for chaining + * @api public + */ + +Request.prototype.pfx = function(cert) { + if (typeof cert === 'object' && !Buffer.isBuffer(cert)) { + this._pfx = cert.pfx; + this._passphrase = cert.passphrase; + } else { + this._pfx = cert; + } + + return this; +}; + +/** + * Set the client certificate option for https request. + * + * @param {Buffer | String} cert + * @return {Request} for chaining + * @api public + */ + +Request.prototype.cert = function(cert) { + this._cert = cert; + return this; +}; + +/** + * Return an http[s] request. + * + * @return {OutgoingMessage} + * @api private + */ + +// eslint-disable-next-line complexity +Request.prototype.request = function() { + if (this.req) return this.req; + + const options = {}; + + try { + const query = qs.stringify(this.qs, { + indices: false, + strictNullHandling: true + }); + if (query) { + this.qs = {}; + this._query.push(query); + } + + this._finalizeQueryString(); + } catch (err) { + return this.emit('error', err); + } + + let { url } = this; + const retries = this._retries; + + // Capture backticks as-is from the final query string built above. + // Note: this'll only find backticks entered in req.query(String) + // calls, because qs.stringify unconditionally encodes backticks. + let queryStringBackticks; + if (url.indexOf('`') > -1) { + const queryStartIndex = url.indexOf('?'); + + if (queryStartIndex !== -1) { + const queryString = url.substr(queryStartIndex + 1); + queryStringBackticks = queryString.match(/`|%60/g); + } + } + + // default to http:// + if (url.indexOf('http') !== 0) url = `http://${url}`; + url = parse(url); + + // See https://github.com/visionmedia/superagent/issues/1367 + if (queryStringBackticks) { + let i = 0; + url.query = url.query.replace(/%60/g, () => queryStringBackticks[i++]); + url.search = `?${url.query}`; + url.path = url.pathname + url.search; + } + + // support unix sockets + if (/^https?\+unix:/.test(url.protocol) === true) { + // get the protocol + url.protocol = `${url.protocol.split('+')[0]}:`; + + // get the socket, path + const unixParts = url.path.match(/^([^/]+)(.+)$/); + options.socketPath = unixParts[1].replace(/%2F/g, '/'); + url.path = unixParts[2]; + } + + // Override IP address of a hostname + if (this._connectOverride) { + const { hostname } = url; + const match = + hostname in this._connectOverride + ? this._connectOverride[hostname] + : this._connectOverride['*']; + if (match) { + // backup the real host + if (!this._header.host) { + this.set('host', url.host); + } + + // wrap [ipv6] + url.host = /:/.test(match) ? `[${match}]` : match; + if (url.port) { + url.host += `:${url.port}`; + } + + url.hostname = match; + } + } + + // options + options.method = this.method; + options.port = url.port; + options.path = url.path; + options.host = url.hostname; + options.ca = this._ca; + options.key = this._key; + options.pfx = this._pfx; + options.cert = this._cert; + options.passphrase = this._passphrase; + options.agent = this._agent; + + // Allows request.get('https://1.2.3.4/').set('Host', 'example.com') + if (this._header.host) { + options.servername = this._header.host.replace(/:\d+$/, ''); + } + + if ( + this._trustLocalhost && + /^(?:localhost|127\.0\.0\.\d+|(0*:)+:0*1)$/.test(url.hostname) + ) { + options.rejectUnauthorized = false; + } + + // initiate request + const mod = this._enableHttp2 + ? exports.protocols['http2:'].setProtocol(url.protocol) + : exports.protocols[url.protocol]; + + // request + this.req = mod.request(options); + const { req } = this; + + // set tcp no delay + req.setNoDelay(true); + + if (options.method !== 'HEAD') { + req.setHeader('Accept-Encoding', 'gzip, deflate'); + } + + this.protocol = url.protocol; + this.host = url.host; + + // expose events + req.once('drain', () => { + this.emit('drain'); + }); + + req.on('error', err => { + // flag abortion here for out timeouts + // because node will emit a faux-error "socket hang up" + // when request is aborted before a connection is made + if (this._aborted) return; + // if not the same, we are in the **old** (cancelled) request, + // so need to continue (same as for above) + if (this._retries !== retries) return; + // if we've received a response then we don't want to let + // an error in the request blow up the response + if (this.response) return; + this.callback(err); + }); + + // auth + if (url.auth) { + const auth = url.auth.split(':'); + this.auth(auth[0], auth[1]); + } + + if (this.username && this.password) { + this.auth(this.username, this.password); + } + + for (const key in this.header) { + if (Object.prototype.hasOwnProperty.call(this.header, key)) + req.setHeader(key, this.header[key]); + } + + // add cookies + if (this.cookies) { + if (Object.prototype.hasOwnProperty.call(this._header, 'cookie')) { + // merge + const tmpJar = new CookieJar.CookieJar(); + tmpJar.setCookies(this._header.cookie.split(';')); + tmpJar.setCookies(this.cookies.split(';')); + req.setHeader( + 'Cookie', + tmpJar.getCookies(CookieJar.CookieAccessInfo.All).toValueString() + ); + } else { + req.setHeader('Cookie', this.cookies); + } + } + + return req; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res) { + if (this._shouldRetry(err, res)) { + return this._retry(); + } + + // Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime. + const fn = this._callback || noop; + this.clearTimeout(); + if (this.called) return console.warn('superagent: double callback bug'); + this.called = true; + + if (!err) { + try { + if (!this._isResponseOK(res)) { + let msg = 'Unsuccessful HTTP response'; + if (res) { + msg = http.STATUS_CODES[res.status] || msg; + } + + err = new Error(msg); + err.status = res ? res.status : undefined; + } + } catch (err2) { + err = err2; + } + } + + // It's important that the callback is called outside try/catch + // to avoid double callback + if (!err) { + return fn(null, res); + } + + err.response = res; + if (this._maxRetries) err.retries = this._retries - 1; + + // only emit error event if there is a listener + // otherwise we assume the callback to `.end()` will get the error + if (err && this.listeners('error').length > 0) { + this.emit('error', err); + } + + fn(err, res); +}; + +/** + * Check if `obj` is a host object, + * + * @param {Object} obj host object + * @return {Boolean} is a host object + * @api private + */ +Request.prototype._isHost = function(obj) { + return ( + Buffer.isBuffer(obj) || obj instanceof Stream || obj instanceof FormData + ); +}; + +/** + * Initiate request, invoking callback `fn(err, res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype._emitResponse = function(body, files) { + const response = new Response(this); + this.response = response; + response.redirects = this._redirectList; + if (undefined !== body) { + response.body = body; + } + + response.files = files; + if (this._endCalled) { + response.pipe = function() { + throw new Error( + "end() has already been called, so it's too late to start piping" + ); + }; + } + + this.emit('response', response); + return response; +}; + +Request.prototype.end = function(fn) { + this.request(); + debug('%s %s', this.method, this.url); + + if (this._endCalled) { + throw new Error( + '.end() was called twice. This is not supported in superagent' + ); + } + + this._endCalled = true; + + // store callback + this._callback = fn || noop; + + this._end(); +}; + +Request.prototype._end = function() { + if (this._aborted) + return this.callback( + new Error('The request has been aborted even before .end() was called') + ); + + let data = this._data; + const { req } = this; + const { method } = this; + + this._setTimeouts(); + + // body + if (method !== 'HEAD' && !req._headerSent) { + // serialize stuff + if (typeof data !== 'string') { + let contentType = req.getHeader('Content-Type'); + // Parse out just the content type from the header (ignore the charset) + if (contentType) contentType = contentType.split(';')[0]; + let serialize = this._serializer || exports.serialize[contentType]; + if (!serialize && isJSON(contentType)) { + serialize = exports.serialize['application/json']; + } + + if (serialize) data = serialize(data); + } + + // content-length + if (data && !req.getHeader('Content-Length')) { + req.setHeader( + 'Content-Length', + Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data) + ); + } + } + + // response + // eslint-disable-next-line complexity + req.once('response', res => { + debug('%s %s -> %s', this.method, this.url, res.statusCode); + + if (this._responseTimeoutTimer) { + clearTimeout(this._responseTimeoutTimer); + } + + if (this.piped) { + return; + } + + const max = this._maxRedirects; + const mime = utils.type(res.headers['content-type'] || '') || 'text/plain'; + const type = mime.split('/')[0]; + const multipart = type === 'multipart'; + const redirect = isRedirect(res.statusCode); + const responseType = this._responseType; + + this.res = res; + + // redirect + if (redirect && this._redirects++ !== max) { + return this._redirect(res); + } + + if (this.method === 'HEAD') { + this.emit('end'); + this.callback(null, this._emitResponse()); + return; + } + + // zlib support + if (this._shouldUnzip(res)) { + unzip(req, res); + } + + let buffer = this._buffer; + if (buffer === undefined && mime in exports.buffer) { + buffer = Boolean(exports.buffer[mime]); + } + + let parser = this._parser; + if (undefined === buffer) { + if (parser) { + console.warn( + "A custom superagent parser has been set, but buffering strategy for the parser hasn't been configured. Call `req.buffer(true or false)` or set `superagent.buffer[mime] = true or false`" + ); + buffer = true; + } + } + + if (!parser) { + if (responseType) { + parser = exports.parse.image; // It's actually a generic Buffer + buffer = true; + } else if (multipart) { + const form = new formidable.IncomingForm(); + parser = form.parse.bind(form); + buffer = true; + } else if (isImageOrVideo(mime)) { + parser = exports.parse.image; + buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent + } else if (exports.parse[mime]) { + parser = exports.parse[mime]; + } else if (type === 'text') { + parser = exports.parse.text; + buffer = buffer !== false; + + // everyone wants their own white-labeled json + } else if (isJSON(mime)) { + parser = exports.parse['application/json']; + buffer = buffer !== false; + } else if (buffer) { + parser = exports.parse.text; + } else if (undefined === buffer) { + parser = exports.parse.image; // It's actually a generic Buffer + buffer = true; + } + } + + // by default only buffer text/*, json and messed up thing from hell + if ((undefined === buffer && isText(mime)) || isJSON(mime)) { + buffer = true; + } + + this._resBuffered = buffer; + let parserHandlesEnd = false; + if (buffer) { + // Protectiona against zip bombs and other nuisance + let responseBytesLeft = this._maxResponseSize || 200000000; + res.on('data', buf => { + responseBytesLeft -= buf.byteLength || buf.length; + if (responseBytesLeft < 0) { + // This will propagate through error event + const err = new Error('Maximum response size reached'); + err.code = 'ETOOLARGE'; + // Parsers aren't required to observe error event, + // so would incorrectly report success + parserHandlesEnd = false; + // Will emit error event + res.destroy(err); + } + }); + } + + if (parser) { + try { + // Unbuffered parsers are supposed to emit response early, + // which is weird BTW, because response.body won't be there. + parserHandlesEnd = buffer; + + parser(res, (err, obj, files) => { + if (this.timedout) { + // Timeout has already handled all callbacks + return; + } + + // Intentional (non-timeout) abort is supposed to preserve partial response, + // even if it doesn't parse. + if (err && !this._aborted) { + return this.callback(err); + } + + if (parserHandlesEnd) { + this.emit('end'); + this.callback(null, this._emitResponse(obj, files)); + } + }); + } catch (err) { + this.callback(err); + return; + } + } + + this.res = res; + + // unbuffered + if (!buffer) { + debug('unbuffered %s %s', this.method, this.url); + this.callback(null, this._emitResponse()); + if (multipart) return; // allow multipart to handle end event + res.once('end', () => { + debug('end %s %s', this.method, this.url); + this.emit('end'); + }); + return; + } + + // terminating events + res.once('error', err => { + parserHandlesEnd = false; + this.callback(err, null); + }); + if (!parserHandlesEnd) + res.once('end', () => { + debug('end %s %s', this.method, this.url); + // TODO: unless buffering emit earlier to stream + this.emit('end'); + this.callback(null, this._emitResponse()); + }); + }); + + this.emit('request', this); + + const getProgressMonitor = () => { + const lengthComputable = true; + const total = req.getHeader('Content-Length'); + let loaded = 0; + + const progress = new Stream.Transform(); + progress._transform = (chunk, encoding, cb) => { + loaded += chunk.length; + this.emit('progress', { + direction: 'upload', + lengthComputable, + loaded, + total + }); + cb(null, chunk); + }; + + return progress; + }; + + const bufferToChunks = buffer => { + const chunkSize = 16 * 1024; // default highWaterMark value + const chunking = new Stream.Readable(); + const totalLength = buffer.length; + const remainder = totalLength % chunkSize; + const cutoff = totalLength - remainder; + + for (let i = 0; i < cutoff; i += chunkSize) { + const chunk = buffer.slice(i, i + chunkSize); + chunking.push(chunk); + } + + if (remainder > 0) { + const remainderBuffer = buffer.slice(-remainder); + chunking.push(remainderBuffer); + } + + chunking.push(null); // no more data + + return chunking; + }; + + // if a FormData instance got created, then we send that as the request body + const formData = this._formData; + if (formData) { + // set headers + const headers = formData.getHeaders(); + for (const i in headers) { + if (Object.prototype.hasOwnProperty.call(headers, i)) { + debug('setting FormData header: "%s: %s"', i, headers[i]); + req.setHeader(i, headers[i]); + } + } + + // attempt to get "Content-Length" header + // eslint-disable-next-line handle-callback-err + formData.getLength((err, length) => { + // TODO: Add chunked encoding when no length (if err) + + debug('got FormData Content-Length: %s', length); + if (typeof length === 'number') { + req.setHeader('Content-Length', length); + } + + formData.pipe(getProgressMonitor()).pipe(req); + }); + } else if (Buffer.isBuffer(data)) { + bufferToChunks(data) + .pipe(getProgressMonitor()) + .pipe(req); + } else { + req.end(data); + } +}; + +// Check whether response has a non-0-sized gzip-encoded body +Request.prototype._shouldUnzip = res => { + if (res.statusCode === 204 || res.statusCode === 304) { + // These aren't supposed to have any body + return false; + } + + // header content is a string, and distinction between 0 and no information is crucial + if (res.headers['content-length'] === '0') { + // We know that the body is empty (unfortunately, this check does not cover chunked encoding) + return false; + } + + // console.log(res); + return /^\s*(?:deflate|gzip)\s*$/.test(res.headers['content-encoding']); +}; + +// eslint-disable-next-line valid-jsdoc +/** + * Overrides DNS for selected hostnames. Takes object mapping hostnames to IP addresses. + * + * When making a request to a URL with a hostname exactly matching a key in the object, + * use the given IP address to connect, instead of using DNS to resolve the hostname. + * + * A special host `*` matches every hostname (keep redirects in mind!) + * + * request.connect({ + * 'test.example.com': '127.0.0.1', + * 'ipv6.example.com': '::1', + * }) + */ +Request.prototype.connect = function(connectOverride) { + if (typeof connectOverride === 'string') { + this._connectOverride = { '*': connectOverride }; + } else if (typeof connectOverride === 'object') { + this._connectOverride = connectOverride; + } else { + this._connectOverride = undefined; + } + + return this; +}; + +Request.prototype.trustLocalhost = function(toggle) { + this._trustLocalhost = toggle === undefined ? true : toggle; + return this; +}; + +// generate HTTP verb methods +if (methods.indexOf('del') === -1) { + // create a copy so we don't cause conflicts with + // other packages using the methods package and + // npm 3.x + methods = methods.slice(0); + methods.push('del'); +} + +methods.forEach(method => { + const name = method; + method = method === 'del' ? 'delete' : method; + + method = method.toUpperCase(); + request[name] = (url, data, fn) => { + const req = request(method, url); + if (typeof data === 'function') { + fn = data; + data = null; + } + + if (data) { + if (method === 'GET' || method === 'HEAD') { + req.query(data); + } else { + req.send(data); + } + } + + if (fn) req.end(fn); + return req; + }; +}); + +/** + * Check if `mime` is text and should be buffered. + * + * @param {String} mime + * @return {Boolean} + * @api public + */ + +function isText(mime) { + const parts = mime.split('/'); + const type = parts[0]; + const subtype = parts[1]; + + return type === 'text' || subtype === 'x-www-form-urlencoded'; +} + +function isImageOrVideo(mime) { + const type = mime.split('/')[0]; + + return type === 'image' || type === 'video'; +} + +/** + * Check if `mime` is json or has +json structured syntax suffix. + * + * @param {String} mime + * @return {Boolean} + * @api private + */ + +function isJSON(mime) { + // should match /json or +json + // but not /json-seq + return /[/+]json($|[^-\w])/.test(mime); +} + +/** + * Check if we should follow the redirect `code`. + * + * @param {Number} code + * @return {Boolean} + * @api private + */ + +function isRedirect(code) { + return [301, 302, 303, 305, 307, 308].indexOf(code) !== -1; +} diff --git a/src/node/parsers/image.js b/src/node/parsers/image.js new file mode 100644 index 000000000..16ac3bd46 --- /dev/null +++ b/src/node/parsers/image.js @@ -0,0 +1,10 @@ +module.exports = (res, fn) => { + const data = []; // Binary data needs binary storage + + res.on('data', chunk => { + data.push(chunk); + }); + res.on('end', () => { + fn(null, Buffer.concat(data)); + }); +}; diff --git a/src/node/parsers/index.js b/src/node/parsers/index.js new file mode 100644 index 000000000..08c9b95c0 --- /dev/null +++ b/src/node/parsers/index.js @@ -0,0 +1,9 @@ +exports['application/x-www-form-urlencoded'] = require('./urlencoded'); +exports['application/json'] = require('./json'); +exports.text = require('./text'); + +const binary = require('./image'); + +exports['application/octet-stream'] = binary; +exports['application/pdf'] = binary; +exports.image = binary; diff --git a/src/node/parsers/json.js b/src/node/parsers/json.js new file mode 100644 index 000000000..1a5e68e43 --- /dev/null +++ b/src/node/parsers/json.js @@ -0,0 +1,22 @@ +module.exports = function(res, fn) { + res.text = ''; + res.setEncoding('utf8'); + res.on('data', chunk => { + res.text += chunk; + }); + res.on('end', () => { + let body; + let err; + try { + body = res.text && JSON.parse(res.text); + } catch (err2) { + err = err2; + // issue #675: return the raw response if the response parsing fails + err.rawResponse = res.text || null; + // issue #876: return the http status code if the response parsing fails + err.statusCode = res.statusCode; + } finally { + fn(err, body); + } + }); +}; diff --git a/src/node/parsers/text.js b/src/node/parsers/text.js new file mode 100644 index 000000000..451477a27 --- /dev/null +++ b/src/node/parsers/text.js @@ -0,0 +1,8 @@ +module.exports = (res, fn) => { + res.text = ''; + res.setEncoding('utf8'); + res.on('data', chunk => { + res.text += chunk; + }); + res.on('end', fn); +}; diff --git a/src/node/parsers/urlencoded.js b/src/node/parsers/urlencoded.js new file mode 100644 index 000000000..f3ad63c74 --- /dev/null +++ b/src/node/parsers/urlencoded.js @@ -0,0 +1,20 @@ +/** + * Module dependencies. + */ + +const qs = require('qs'); + +module.exports = (res, fn) => { + res.text = ''; + res.setEncoding('ascii'); + res.on('data', chunk => { + res.text += chunk; + }); + res.on('end', () => { + try { + fn(null, qs.parse(res.text)); + } catch (err) { + fn(err); + } + }); +}; diff --git a/src/node/response.js b/src/node/response.js new file mode 100644 index 000000000..d88b5e1aa --- /dev/null +++ b/src/node/response.js @@ -0,0 +1,125 @@ +'use strict'; + +/** + * Module dependencies. + */ + +const util = require('util'); +const Stream = require('stream'); +const ResponseBase = require('../response-base'); + +/** + * Expose `Response`. + */ + +module.exports = Response; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * @param {Request} req + * @param {Object} options + * @constructor + * @extends {Stream} + * @implements {ReadableStream} + * @api private + */ + +function Response(req) { + Stream.call(this); + this.res = req.res; + const { res } = this; + this.request = req; + this.req = req.req; + this.text = res.text; + this.body = res.body === undefined ? {} : res.body; + this.files = res.files || {}; + this.buffered = req._resBuffered; + this.headers = res.headers; + this.header = this.headers; + this._setStatusProperties(res.statusCode); + this._setHeaderProperties(this.header); + this.setEncoding = res.setEncoding.bind(res); + res.on('data', this.emit.bind(this, 'data')); + res.on('end', this.emit.bind(this, 'end')); + res.on('close', this.emit.bind(this, 'close')); + res.on('error', this.emit.bind(this, 'error')); +} + +/** + * Inherit from `Stream`. + */ + +util.inherits(Response, Stream); +// eslint-disable-next-line new-cap +ResponseBase(Response.prototype); + +/** + * Implements methods of a `ReadableStream` + */ + +Response.prototype.destroy = function(err) { + this.res.destroy(err); +}; + +/** + * Pause. + */ + +Response.prototype.pause = function() { + this.res.pause(); +}; + +/** + * Resume. + */ + +Response.prototype.resume = function() { + this.res.resume(); +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function() { + const { req } = this; + const { method } = req; + const { path } = req; + + const msg = `cannot ${method} ${path} (${this.status})`; + const err = new Error(msg); + err.status = this.status; + err.text = this.text; + err.method = method; + err.path = path; + + return err; +}; + +Response.prototype.setStatusProperties = function(status) { + console.warn('In superagent 2.x setStatusProperties is a private method'); + return this._setStatusProperties(status); +}; + +/** + * To json. + * + * @return {Object} + * @api public + */ + +Response.prototype.toJSON = function() { + return { + req: this.request.toJSON(), + header: this.header, + status: this.status, + text: this.text + }; +}; diff --git a/src/node/unzip.js b/src/node/unzip.js new file mode 100644 index 000000000..e882a336c --- /dev/null +++ b/src/node/unzip.js @@ -0,0 +1,73 @@ +'use strict'; + +/** + * Module dependencies. + */ + +const { StringDecoder } = require('string_decoder'); +const Stream = require('stream'); +const zlib = require('zlib'); + +/** + * Buffers response data events and re-emits when they're unzipped. + * + * @param {Request} req + * @param {Response} res + * @api private + */ + +exports.unzip = (req, res) => { + const unzip = zlib.createUnzip(); + const stream = new Stream(); + let decoder; + + // make node responseOnEnd() happy + stream.req = req; + + unzip.on('error', err => { + if (err && err.code === 'Z_BUF_ERROR') { + // unexpected end of file is ignored by browsers and curl + stream.emit('end'); + return; + } + + stream.emit('error', err); + }); + + // pipe to unzip + res.pipe(unzip); + + // override `setEncoding` to capture encoding + res.setEncoding = type => { + decoder = new StringDecoder(type); + }; + + // decode upon decompressing with captured encoding + unzip.on('data', buf => { + if (decoder) { + const str = decoder.write(buf); + if (str.length > 0) stream.emit('data', str); + } else { + stream.emit('data', buf); + } + }); + + unzip.on('end', () => { + stream.emit('end'); + }); + + // override `on` to capture data listeners + const _on = res.on; + res.on = function(type, fn) { + if (type === 'data' || type === 'end') { + stream.on(type, fn.bind(res)); + } else if (type === 'error') { + stream.on(type, fn.bind(res)); + _on.call(res, type, fn); + } else { + _on.call(res, type, fn); + } + + return this; + }; +}; diff --git a/src/request-base.js b/src/request-base.js new file mode 100644 index 000000000..e700c99af --- /dev/null +++ b/src/request-base.js @@ -0,0 +1,744 @@ +/** + * Module of mixed-in functions shared between node and client code + */ +const isObject = require('./is-object'); + +/** + * Expose `RequestBase`. + */ + +module.exports = RequestBase; + +/** + * Initialize a new `RequestBase`. + * + * @api public + */ + +function RequestBase(obj) { + if (obj) return mixin(obj); +} + +/** + * Mixin the prototype properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (const key in RequestBase.prototype) { + if (Object.prototype.hasOwnProperty.call(RequestBase.prototype, key)) + obj[key] = RequestBase.prototype[key]; + } + + return obj; +} + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.clearTimeout = function() { + clearTimeout(this._timer); + clearTimeout(this._responseTimeoutTimer); + clearTimeout(this._uploadTimeoutTimer); + delete this._timer; + delete this._responseTimeoutTimer; + delete this._uploadTimeoutTimer; + return this; +}; + +/** + * Override default response body parser + * + * This function will be called to convert incoming data into request.body + * + * @param {Function} + * @api public + */ + +RequestBase.prototype.parse = function(fn) { + this._parser = fn; + return this; +}; + +/** + * Set format of binary response body. + * In browser valid formats are 'blob' and 'arraybuffer', + * which return Blob and ArrayBuffer, respectively. + * + * In Node all values result in Buffer. + * + * Examples: + * + * req.get('/') + * .responseType('blob') + * .end(callback); + * + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.responseType = function(val) { + this._responseType = val; + return this; +}; + +/** + * Override default request body serializer + * + * This function will be called to convert data set via .send or .attach into payload to send + * + * @param {Function} + * @api public + */ + +RequestBase.prototype.serialize = function(fn) { + this._serializer = fn; + return this; +}; + +/** + * Set timeouts. + * + * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time. + * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections. + * - upload is the time since last bit of data was sent or received. This timeout works only if deadline timeout is off + * + * Value of 0 or false means no timeout. + * + * @param {Number|Object} ms or {response, deadline} + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.timeout = function(options) { + if (!options || typeof options !== 'object') { + this._timeout = options; + this._responseTimeout = 0; + this._uploadTimeout = 0; + return this; + } + + for (const option in options) { + if (Object.prototype.hasOwnProperty.call(options, option)) { + switch (option) { + case 'deadline': + this._timeout = options.deadline; + break; + case 'response': + this._responseTimeout = options.response; + break; + case 'upload': + this._uploadTimeout = options.upload; + break; + default: + console.warn('Unknown timeout option', option); + } + } + } + + return this; +}; + +/** + * Set number of retry attempts on error. + * + * Failed requests will be retried 'count' times if timeout or err.code >= 500. + * + * @param {Number} count + * @param {Function} [fn] + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.retry = function(count, fn) { + // Default to 1 if no count passed or true + if (arguments.length === 0 || count === true) count = 1; + if (count <= 0) count = 0; + this._maxRetries = count; + this._retries = 0; + this._retryCallback = fn; + return this; +}; + +const ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT', 'EADDRINFO', 'ESOCKETTIMEDOUT']; + +/** + * Determine if a request should be retried. + * (Borrowed from segmentio/superagent-retry) + * + * @param {Error} err an error + * @param {Response} [res] response + * @returns {Boolean} if segment should be retried + */ +RequestBase.prototype._shouldRetry = function(err, res) { + if (!this._maxRetries || this._retries++ >= this._maxRetries) { + return false; + } + + if (this._retryCallback) { + try { + const override = this._retryCallback(err, res); + if (override === true) return true; + if (override === false) return false; + // undefined falls back to defaults + } catch (err2) { + console.error(err2); + } + } + + if (res && res.status && res.status >= 500 && res.status !== 501) return true; + if (err) { + if (err.code && ERROR_CODES.indexOf(err.code) !== -1) return true; + // Superagent timeout + if (err.timeout && err.code === 'ECONNABORTED') return true; + if (err.crossDomain) return true; + } + + return false; +}; + +/** + * Retry request + * + * @return {Request} for chaining + * @api private + */ + +RequestBase.prototype._retry = function() { + this.clearTimeout(); + + // node + if (this.req) { + this.req = null; + this.req = this.request(); + } + + this._aborted = false; + this.timedout = false; + + return this._end(); +}; + +/** + * Promise support + * + * @param {Function} resolve + * @param {Function} [reject] + * @return {Request} + */ + +RequestBase.prototype.then = function(resolve, reject) { + if (!this._fullfilledPromise) { + const self = this; + if (this._endCalled) { + console.warn( + 'Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises' + ); + } + + this._fullfilledPromise = new Promise((resolve, reject) => { + self.on('abort', () => { + const err = new Error('Aborted'); + err.code = 'ABORTED'; + err.status = this.status; + err.method = this.method; + err.url = this.url; + reject(err); + }); + self.end((err, res) => { + if (err) reject(err); + else resolve(res); + }); + }); + } + + // eslint-disable-next-line promise/prefer-await-to-then + return this._fullfilledPromise.then(resolve, reject); +}; + +RequestBase.prototype.catch = function(cb) { + // eslint-disable-next-line promise/prefer-await-to-then + return this.then(undefined, cb); +}; + +/** + * Allow for extension + */ + +RequestBase.prototype.use = function(fn) { + fn(this); + return this; +}; + +RequestBase.prototype.ok = function(cb) { + if (typeof cb !== 'function') throw new Error('Callback required'); + this._okCallback = cb; + return this; +}; + +RequestBase.prototype._isResponseOK = function(res) { + if (!res) { + return false; + } + + if (this._okCallback) { + return this._okCallback(res); + } + + return res.status >= 200 && res.status < 300; +}; + +/** + * Get request header `field`. + * Case-insensitive. + * + * @param {String} field + * @return {String} + * @api public + */ + +RequestBase.prototype.get = function(field) { + return this._header[field.toLowerCase()]; +}; + +/** + * Get case-insensitive header `field` value. + * This is a deprecated internal API. Use `.get(field)` instead. + * + * (getHeader is no longer used internally by the superagent code base) + * + * @param {String} field + * @return {String} + * @api private + * @deprecated + */ + +RequestBase.prototype.getHeader = RequestBase.prototype.get; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * Case-insensitive. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.set = function(field, val) { + if (isObject(field)) { + for (const key in field) { + if (Object.prototype.hasOwnProperty.call(field, key)) + this.set(key, field[key]); + } + + return this; + } + + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +// eslint-disable-next-line valid-jsdoc +/** + * Remove header `field`. + * Case-insensitive. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field field name + */ +RequestBase.prototype.unset = function(field) { + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Write the field `name` and `val`, or multiple fields with one object + * for "multipart/form-data" request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * + * request.post('/upload') + * .field({ foo: 'bar', baz: 'qux' }) + * .end(callback); + * ``` + * + * @param {String|Object} name name of field + * @param {String|Blob|File|Buffer|fs.ReadStream} val value of field + * @return {Request} for chaining + * @api public + */ +RequestBase.prototype.field = function(name, val) { + // name should be either a string or an object. + if (name === null || undefined === name) { + throw new Error('.field(name, val) name can not be empty'); + } + + if (this._data) { + throw new Error( + ".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()" + ); + } + + if (isObject(name)) { + for (const key in name) { + if (Object.prototype.hasOwnProperty.call(name, key)) + this.field(key, name[key]); + } + + return this; + } + + if (Array.isArray(val)) { + for (const i in val) { + if (Object.prototype.hasOwnProperty.call(val, i)) + this.field(name, val[i]); + } + + return this; + } + + // val should be defined now + if (val === null || undefined === val) { + throw new Error('.field(name, val) val can not be empty'); + } + + if (typeof val === 'boolean') { + val = String(val); + } + + this._getFormData().append(name, val); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} request + * @api public + */ +RequestBase.prototype.abort = function() { + if (this._aborted) { + return this; + } + + this._aborted = true; + if (this.xhr) this.xhr.abort(); // browser + if (this.req) this.req.abort(); // node + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +RequestBase.prototype._auth = function(user, pass, options, base64Encoder) { + switch (options.type) { + case 'basic': + this.set('Authorization', `Basic ${base64Encoder(`${user}:${pass}`)}`); + break; + + case 'auto': + this.username = user; + this.password = pass; + break; + + case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' }) + this.set('Authorization', `Bearer ${user}`); + break; + default: + break; + } + + return this; +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +RequestBase.prototype.withCredentials = function(on) { + // This is browser-only functionality. Node side is no-op. + if (on === undefined) on = true; + this._withCredentials = on; + return this; +}; + +/** + * Set the max redirects to `n`. Does noting in browser XHR implementation. + * + * @param {Number} n + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.redirects = function(n) { + this._maxRedirects = n; + return this; +}; + +/** + * Maximum size of buffered response body, in bytes. Counts uncompressed size. + * Default 200MB. + * + * @param {Number} n number of bytes + * @return {Request} for chaining + */ +RequestBase.prototype.maxResponseSize = function(n) { + if (typeof n !== 'number') { + throw new TypeError('Invalid argument'); + } + + this._maxResponseSize = n; + return this; +}; + +/** + * Convert to a plain javascript object (not JSON string) of scalar properties. + * Note as this method is designed to return a useful non-this value, + * it cannot be chained. + * + * @return {Object} describing method, url, and data of this request + * @api public + */ + +RequestBase.prototype.toJSON = function() { + return { + method: this.method, + url: this.url, + data: this._data, + headers: this._header + }; +}; + +/** + * Send `data` as the request body, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}') + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +// eslint-disable-next-line complexity +RequestBase.prototype.send = function(data) { + const isObj = isObject(data); + let type = this._header['content-type']; + + if (this._formData) { + throw new Error( + ".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()" + ); + } + + if (isObj && !this._data) { + if (Array.isArray(data)) { + this._data = []; + } else if (!this._isHost(data)) { + this._data = {}; + } + } else if (data && this._data && this._isHost(this._data)) { + throw new Error("Can't merge these send calls"); + } + + // merge + if (isObj && isObject(this._data)) { + for (const key in data) { + if (Object.prototype.hasOwnProperty.call(data, key)) + this._data[key] = data[key]; + } + } else if (typeof data === 'string') { + // default to x-www-form-urlencoded + if (!type) this.type('form'); + type = this._header['content-type']; + if (type === 'application/x-www-form-urlencoded') { + this._data = this._data ? `${this._data}&${data}` : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!isObj || this._isHost(data)) { + return this; + } + + // default to json + if (!type) this.type('json'); + return this; +}; + +/** + * Sort `querystring` by the sort function + * + * + * Examples: + * + * // default order + * request.get('/user') + * .query('name=Nick') + * .query('search=Manny') + * .sortQuery() + * .end(callback) + * + * // customized sort function + * request.get('/user') + * .query('name=Nick') + * .query('search=Manny') + * .sortQuery(function(a, b){ + * return a.length - b.length; + * }) + * .end(callback) + * + * + * @param {Function} sort + * @return {Request} for chaining + * @api public + */ + +RequestBase.prototype.sortQuery = function(sort) { + // _sort default to true but otherwise can be a function or boolean + this._sort = typeof sort === 'undefined' ? true : sort; + return this; +}; + +/** + * Compose querystring to append to req.url + * + * @api private + */ +RequestBase.prototype._finalizeQueryString = function() { + const query = this._query.join('&'); + if (query) { + this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query; + } + + this._query.length = 0; // Makes the call idempotent + + if (this._sort) { + const index = this.url.indexOf('?'); + if (index >= 0) { + const queryArr = this.url.substring(index + 1).split('&'); + if (typeof this._sort === 'function') { + queryArr.sort(this._sort); + } else { + queryArr.sort(); + } + + this.url = this.url.substring(0, index) + '?' + queryArr.join('&'); + } + } +}; + +// For backwards compat only +RequestBase.prototype._appendQueryString = () => { + console.warn('Unsupported'); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +RequestBase.prototype._timeoutError = function(reason, timeout, errno) { + if (this._aborted) { + return; + } + + const err = new Error(`${reason + timeout}ms exceeded`); + err.timeout = timeout; + err.code = 'ECONNABORTED'; + err.errno = errno; + this.timedout = true; + this.abort(); + this.callback(err); +}; + +RequestBase.prototype._setTimeouts = function() { + const self = this; + + // deadline + if (this._timeout && !this._timer) { + this._timer = setTimeout(() => { + self._timeoutError('Timeout of ', self._timeout, 'ETIME'); + }, this._timeout); + } + + // response timeout + if (this._responseTimeout && !this._responseTimeoutTimer) { + this._responseTimeoutTimer = setTimeout(() => { + self._timeoutError( + 'Response timeout of ', + self._responseTimeout, + 'ETIMEDOUT' + ); + }, this._responseTimeout); + } +}; diff --git a/src/response-base.js b/src/response-base.js new file mode 100644 index 000000000..6cac97d39 --- /dev/null +++ b/src/response-base.js @@ -0,0 +1,138 @@ +/** + * Module dependencies. + */ + +const utils = require('./utils'); + +/** + * Expose `ResponseBase`. + */ + +module.exports = ResponseBase; + +/** + * Initialize a new `ResponseBase`. + * + * @api public + */ + +function ResponseBase(obj) { + if (obj) return mixin(obj); +} + +/** + * Mixin the prototype properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (const key in ResponseBase.prototype) { + if (Object.prototype.hasOwnProperty.call(ResponseBase.prototype, key)) + obj[key] = ResponseBase.prototype[key]; + } + + return obj; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +ResponseBase.prototype.get = function(field) { + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +ResponseBase.prototype._setHeaderProperties = function(header) { + // TODO: moar! + // TODO: make this a util + + // content-type + const ct = header['content-type'] || ''; + this.type = utils.type(ct); + + // params + const params = utils.params(ct); + for (const key in params) { + if (Object.prototype.hasOwnProperty.call(params, key)) + this[key] = params[key]; + } + + this.links = {}; + + // links + try { + if (header.link) { + this.links = utils.parseLinks(header.link); + } + } catch (err) { + // ignore + } +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +ResponseBase.prototype._setStatusProperties = function(status) { + const type = (status / 100) | 0; + + // status / class + this.statusCode = status; + this.status = this.statusCode; + this.statusType = type; + + // basics + this.info = type === 1; + this.ok = type === 2; + this.redirect = type === 3; + this.clientError = type === 4; + this.serverError = type === 5; + this.error = type === 4 || type === 5 ? this.toError() : false; + + // sugar + this.created = status === 201; + this.accepted = status === 202; + this.noContent = status === 204; + this.badRequest = status === 400; + this.unauthorized = status === 401; + this.notAcceptable = status === 406; + this.forbidden = status === 403; + this.notFound = status === 404; + this.unprocessableEntity = status === 422; +}; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 000000000..651bb0750 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,66 @@ +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.type = str => str.split(/ *; */).shift(); + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +exports.params = str => + str.split(/ *; */).reduce((obj, str) => { + const parts = str.split(/ *= */); + const key = parts.shift(); + const val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); + +/** + * Parse Link header fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +exports.parseLinks = str => + str.split(/ *, */).reduce((obj, str) => { + const parts = str.split(/ *; */); + const url = parts[0].slice(1, -1); + const rel = parts[1].split(/ *= */)[1].slice(1, -1); + obj[rel] = url; + return obj; + }, {}); + +/** + * Strip content related fields from `header`. + * + * @param {Object} header + * @return {Object} header + * @api private + */ + +exports.cleanHeader = (header, changesOrigin) => { + delete header['content-type']; + delete header['content-length']; + delete header['transfer-encoding']; + delete header.host; + // secuirty + if (changesOrigin) { + delete header.authorization; + delete header.cookie; + } + + return header; +}; diff --git a/test/agent-base.js b/test/agent-base.js index 1ed6f3fde..a46116fec 100644 --- a/test/agent-base.js +++ b/test/agent-base.js @@ -1,38 +1,45 @@ const setup = require('./support/setup'); + const base = setup.uri; const assert = require('assert'); const request = require('./support/client'); describe('Agent', () => { - it("should remember defaults", () => { - if ('undefined' === typeof Promise) { + it('should remember defaults', () => { + if (typeof Promise === 'undefined') { return; } let called = 0; let event_called = 0; - const agent = request.agent() + const agent = request + .agent() .accept('json') - .use(() => {called++}) - .once('request', () => {event_called++}) - .query({hello:"world"}) - .set("X-test", "testing"); + .use(() => { + called++; + }) + .once('request', () => { + event_called++; + }) + .query({ hello: 'world' }) + .set('X-test', 'testing'); assert.equal(0, called); assert.equal(0, event_called); - return agent.get(`${base}/echo`) - .then(res => { - assert.equal(1, called); - assert.equal(1, event_called); - assert.equal('application/json', res.headers.accept); - assert.equal('testing', res.headers['x-test']); + return agent + .get(`${base}/echo`) + .then(res => { + assert.equal(1, called); + assert.equal(1, event_called); + assert.equal('application/json', res.headers.accept); + assert.equal('testing', res.headers['x-test']); - return agent.get(`${base}/querystring`); - }) - .then(res => { - assert.equal(2, called); - assert.equal(2, event_called); - assert.deepEqual({hello:"world"}, res.body); - }); + return agent.get(`${base}/querystring`); + }) + .then(res => { + assert.equal(2, called); + assert.equal(2, event_called); + assert.deepEqual({ hello: 'world' }, res.body); + }); }); }); diff --git a/test/basic.js b/test/basic.js index 0e0325f31..4127ba9a8 100644 --- a/test/basic.js +++ b/test/basic.js @@ -1,215 +1,230 @@ const setup = require('./support/setup'); -const NODE = setup.NODE; -const uri = setup.uri; + +const { NODE } = setup; +const { uri } = setup; const assert = require('assert'); const request = require('./support/client'); -describe('request', function(){ +describe('request', function() { this.timeout(20000); describe('res.statusCode', () => { it('should set statusCode', done => { - request - .get(`${uri}/login`, (err, res) => { + request.get(`${uri}/login`, (err, res) => { try { - assert.strictEqual(res.statusCode, 200); - done(); - } catch(e) { done(e); } + assert.strictEqual(res.statusCode, 200); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('should allow the send shorthand', () => { it('with callback in the method call', done => { - request - .get(`${uri}/login`, (err, res) => { - assert.equal(res.status, 200); - done(); + request.get(`${uri}/login`, (err, res) => { + assert.equal(res.status, 200); + done(); }); - }) + }); it('with data in the method call', done => { - request - .post(`${uri}/echo`, { foo: 'bar' }) - .end((err, res) => { + request.post(`${uri}/echo`, { foo: 'bar' }).end((err, res) => { assert.equal('{"foo":"bar"}', res.text); done(); }); - }) + }); it('with callback and data in the method call', done => { - request - .post(`${uri}/echo`, { foo: 'bar' }, (err, res) => { + request.post(`${uri}/echo`, { foo: 'bar' }, (err, res) => { assert.equal('{"foo":"bar"}', res.text); done(); }); - }) - }) + }); + }); describe('with a callback', () => { it('should invoke .end()', done => { - request - .get(`${uri}/login`, (err, res) => { + request.get(`${uri}/login`, (err, res) => { try { - assert.equal(res.status, 200); - done(); - } catch(e) { done(e); } + assert.equal(res.status, 200); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('.end()', () => { it('should issue a request', done => { - request - .get(`${uri}/login`) - .end((err, res) => { + request.get(`${uri}/login`).end((err, res) => { try { - assert.equal(res.status, 200); - done(); - } catch(e) { done(e); } + assert.equal(res.status, 200); + done(); + } catch (err2) { + done(err2); + } }); - }) + }); it('is optional with a promise', () => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return; } - return request.get(`${uri}/login`) - .then(res => res.status) - .then() - .then(status => { - assert.equal(200, status, "Real promises pass results through"); - }); + return request + .get(`${uri}/login`) + .then(res => res.status) + .then() + .then(status => { + assert.equal(200, status, 'Real promises pass results through'); + }); }); it('called only once with a promise', () => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return; } const req = request.get(`${uri}/unique`); - return Promise.all([req, req, req]) - .then(results => { + return Promise.all([req, req, req]).then(results => { results.forEach(item => { - assert.equal(item.body, results[0].body, "It should keep returning the same result after being called once"); + assert.equal( + item.body, + results[0].body, + 'It should keep returning the same result after being called once' + ); }); }); }); - }) - + }); describe('res.error', () => { it('ok', done => { let calledErrorEvent = false; let calledOKHandler = false; request - .get(`${uri}/error`) - .ok(res => { - assert.strictEqual(500, res.status); - calledOKHandler = true; - return true; - }) - .on('error', err => { - calledErrorEvent = true; - }) - .end((err, res) => { - try{ - assert.ifError(err); - assert.strictEqual(res.status, 500); - assert(!calledErrorEvent); - assert(calledOKHandler); - done(); - } catch(e) { done(e); } - }); + .get(`${uri}/error`) + .ok(res => { + assert.strictEqual(500, res.status); + calledOKHandler = true; + return true; + }) + .on('error', err => { + calledErrorEvent = true; + }) + .end((err, res) => { + try { + assert.ifError(err); + assert.strictEqual(res.status, 500); + assert(!calledErrorEvent); + assert(calledOKHandler); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should should be an Error object', done => { let calledErrorEvent = false; request - .get(`${uri}/error`) - .on('error', err => { - assert.strictEqual(err.status, 500); - calledErrorEvent = true; - }) - .end((err, res) => { - try { - if (NODE) { - res.error.message.should.equal('cannot GET /error (500)'); - } - else { - res.error.message.should.equal(`cannot GET ${uri}/error (500)`); - } - assert.strictEqual(res.error.status, 500); - assert(err, 'should have an error for 500'); - assert.equal(err.message, 'Internal Server Error'); - assert(calledErrorEvent); - done(); - } catch(e) { done(e); } - }); - }) + .get(`${uri}/error`) + .on('error', err => { + assert.strictEqual(err.status, 500); + calledErrorEvent = true; + }) + .end((err, res) => { + try { + if (NODE) { + res.error.message.should.equal('cannot GET /error (500)'); + } else { + res.error.message.should.equal(`cannot GET ${uri}/error (500)`); + } + + assert.strictEqual(res.error.status, 500); + assert(err, 'should have an error for 500'); + assert.equal(err.message, 'Internal Server Error'); + assert(calledErrorEvent); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('with .then() promise', () => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return; } - return request - .get(`${uri}/error`) - .then(() => { - assert.fail(); - }, err => { - assert.equal(err.message, 'Internal Server Error'); - }); - }) + return request.get(`${uri}/error`).then( + () => { + assert.fail(); + }, + err => { + assert.equal(err.message, 'Internal Server Error'); + } + ); + }); it('with .ok() returning false', () => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return; } return request - .get(`${uri}/echo`) - .ok(() => false) - .then(() => { - assert.fail(); - }, err => { - assert.equal(200, err.response.status); - assert.equal(err.message, 'OK'); - }); - }) + .get(`${uri}/echo`) + .ok(() => false) + .then( + () => { + assert.fail(); + }, + err => { + assert.equal(200, err.response.status); + assert.equal(err.message, 'OK'); + } + ); + }); it('with .ok() throwing an Error', () => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return; } return request - .get(`${uri}/echo`) - .ok(() => {throw new Error('boom');}) - .then(() => { - assert.fail(); - }, err => { - assert.equal(200, err.response.status); - assert.equal(err.message, 'boom'); - }); - }) - }) + .get(`${uri}/echo`) + .ok(() => { + throw new Error('boom'); + }) + .then( + () => { + assert.fail(); + }, + err => { + assert.equal(200, err.response.status); + assert.equal(err.message, 'boom'); + } + ); + }); + }); describe('res.header', () => { it('should be an object', done => { - request - .get(`${uri}/login`) - .end((err, res) => { + request.get(`${uri}/login`).end((err, res) => { try { - assert.equal('Express', res.header['x-powered-by']); - done(); - } catch(e) { done(e); } + assert.equal('Express', res.header['x-powered-by']); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('set headers', () => { before(() => { @@ -226,242 +241,278 @@ describe('request', function(){ .get(`${uri}/echo-headers`) .set('valid', 'ok') .end((err, res) => { - if (!err && res.body && res.body.valid && !res.body.hasOwnProperty('invalid')) { + if ( + !err && + res.body && + res.body.valid && + !res.body.hasOwnProperty('invalid') + ) { return done(); } - done(err || Error("fail")); + + done(err || new Error('fail')); }); - } catch (e) { - done(e) + } catch (err) { + done(err); } }); }); describe('res.charset', () => { it('should be set when present', done => { - request - .get(`${uri}/login`) - .end((err, res) => { + request.get(`${uri}/login`).end((err, res) => { try { - res.charset.should.equal('utf-8'); - done(); - } catch(e) { done(e); } + res.charset.should.equal('utf-8'); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('res.statusType', () => { it('should provide the first digit', done => { - request - .get(`${uri}/login`) - .end((err, res) => { + request.get(`${uri}/login`).end((err, res) => { try { - assert(!err, 'should not have an error for success responses'); - assert.equal(200, res.status); - assert.equal(2, res.statusType); - done(); - } catch(e) { done(e); } + assert(!err, 'should not have an error for success responses'); + assert.equal(200, res.status); + assert.equal(2, res.statusType); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('res.type', () => { it('should provide the mime-type void of params', done => { - request - .get(`${uri}/login`) - .end((err, res) => { + request.get(`${uri}/login`).end((err, res) => { try { - res.type.should.equal('text/html'); - res.charset.should.equal('utf-8'); - done(); - } catch(e) { done(e); } + res.type.should.equal('text/html'); + res.charset.should.equal('utf-8'); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('req.set(field, val)', () => { it('should set the header field', done => { request - .post(`${uri}/echo`) - .set('X-Foo', 'bar') - .set('X-Bar', 'baz') - .end((err, res) => { - try { - assert.equal('bar', res.header['x-foo']); - assert.equal('baz', res.header['x-bar']); - done(); - } catch(e) { done(e); } - }); - }) - }) + .post(`${uri}/echo`) + .set('X-Foo', 'bar') + .set('X-Bar', 'baz') + .end((err, res) => { + try { + assert.equal('bar', res.header['x-foo']); + assert.equal('baz', res.header['x-bar']); + done(); + } catch (err2) { + done(err2); + } + }); + }); + }); describe('req.set(obj)', () => { it('should set the header fields', done => { request - .post(`${uri}/echo`) - .set({ 'X-Foo': 'bar', 'X-Bar': 'baz' }) - .end((err, res) => { - try { - assert.equal('bar', res.header['x-foo']); - assert.equal('baz', res.header['x-bar']); - done(); - } catch(e) { done(e); } - }); - }) - }) + .post(`${uri}/echo`) + .set({ 'X-Foo': 'bar', 'X-Bar': 'baz' }) + .end((err, res) => { + try { + assert.equal('bar', res.header['x-foo']); + assert.equal('baz', res.header['x-bar']); + done(); + } catch (err2) { + done(err2); + } + }); + }); + }); describe('req.type(str)', () => { it('should set the Content-Type', done => { request - .post(`${uri}/echo`) - .type('text/x-foo') - .end((err, res) => { - try { - res.header['content-type'].should.equal('text/x-foo'); - done(); - } catch(e) { done(e); } - }); - }) + .post(`${uri}/echo`) + .type('text/x-foo') + .end((err, res) => { + try { + res.header['content-type'].should.equal('text/x-foo'); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should map "json"', done => { request - .post(`${uri}/echo`) - .type('json') - .send('{"a": 1}') - .end((err, res) => { - try { - res.should.be.json(); - done(); - } catch(e) { done(e); } - }); - }) + .post(`${uri}/echo`) + .type('json') + .send('{"a": 1}') + .end((err, res) => { + try { + res.should.be.json(); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should map "html"', done => { request - .post(`${uri}/echo`) - .type('html') - .end((err, res) => { - try { - res.header['content-type'].should.equal('text/html'); - done(); - } catch(e) { done(e); } - }); - }) - }) + .post(`${uri}/echo`) + .type('html') + .end((err, res) => { + try { + res.header['content-type'].should.equal('text/html'); + done(); + } catch (err2) { + done(err2); + } + }); + }); + }); describe('req.accept(str)', () => { it('should set Accept', done => { request - .get(`${uri}/echo`) - .accept('text/x-foo') - .end((err, res) => { - try { - res.header['accept'].should.equal('text/x-foo'); - done(); - } catch(e) { done(e); } - }); - }) + .get(`${uri}/echo`) + .accept('text/x-foo') + .end((err, res) => { + try { + res.header.accept.should.equal('text/x-foo'); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should map "json"', done => { request - .get(`${uri}/echo`) - .accept('json') - .end((err, res) => { - try { - res.header['accept'].should.equal('application/json'); - done(); - } catch(e) { done(e); } - }); - }) + .get(`${uri}/echo`) + .accept('json') + .end((err, res) => { + try { + res.header.accept.should.equal('application/json'); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should map "xml"', done => { request - .get(`${uri}/echo`) - .accept('xml') - .end((err, res) => { - try { - // Mime module keeps changing this :( - assert(res.header['accept'] == "application/xml" || res.header['accept'] == "text/xml"); - done(); - } catch(e) { done(e); } - }); - }) + .get(`${uri}/echo`) + .accept('xml') + .end((err, res) => { + try { + // Mime module keeps changing this :( + assert( + res.header.accept == 'application/xml' || + res.header.accept == 'text/xml' + ); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should map "html"', done => { request - .get(`${uri}/echo`) - .accept('html') - .end((err, res) => { - try { - res.header['accept'].should.equal('text/html'); - done(); - } catch(e) { done(e); } - }); - }) - }) + .get(`${uri}/echo`) + .accept('html') + .end((err, res) => { + try { + res.header.accept.should.equal('text/html'); + done(); + } catch (err2) { + done(err2); + } + }); + }); + }); describe('req.send(str)', () => { it('should write the string', done => { request - .post(`${uri}/echo`) - .type('json') - .send('{"name":"tobi"}') - .end((err, res) => { - try { - res.text.should.equal('{"name":"tobi"}'); - done(); - } catch(e) { done(e); } - }); - }) - }) + .post(`${uri}/echo`) + .type('json') + .send('{"name":"tobi"}') + .end((err, res) => { + try { + res.text.should.equal('{"name":"tobi"}'); + done(); + } catch (err2) { + done(err2); + } + }); + }); + }); describe('req.send(Object)', () => { it('should default to json', done => { request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .end((err, res) => { - try { - res.should.be.json(); - res.text.should.equal('{"name":"tobi"}'); - done(); - } catch(e) { done(e); } - }); - }) + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .end((err, res) => { + try { + res.should.be.json(); + res.text.should.equal('{"name":"tobi"}'); + done(); + } catch (err2) { + done(err2); + } + }); + }); describe('when called several times', () => { it('should merge the objects', done => { request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .send({ age: 1 }) - .end((err, res) => { + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .send({ age: 1 }) + .end((err, res) => { try { - res.should.be.json(); - if (NODE) { - res.buffered.should.be.true(); - } - res.text.should.equal('{"name":"tobi","age":1}'); - done(); - } catch(e) { done(e); } + res.should.be.json(); + if (NODE) { + res.buffered.should.be.true(); + } + + res.text.should.equal('{"name":"tobi","age":1}'); + done(); + } catch (err2) { + done(err2); + } + }); }); - }) - }) - }) + }); + }); describe('.end(fn)', () => { it('should check arity', done => { request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .end((err, res) => { - try { - assert.ifError(err) - res.text.should.equal('{"name":"tobi"}'); - done(); - } catch(e) { done(e); } - }); - }) + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .end((err, res) => { + try { + assert.ifError(err); + res.text.should.equal('{"name":"tobi"}'); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should emit request', done => { const req = request.post(`${uri}/echo`); @@ -470,75 +521,72 @@ describe('request', function(){ done(); }); req.end(); - }) + }); it('should emit response', done => { request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .on('response', res => { - res.text.should.equal('{"name":"tobi"}'); - done(); - }) - .end(); - }) - }) + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .on('response', res => { + res.text.should.equal('{"name":"tobi"}'); + done(); + }) + .end(); + }); + }); describe('.then(fulfill, reject)', () => { it('should support successful fulfills with .then(fulfill)', done => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return done(); } request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .then(res => { - res.type.should.equal('application/json'); - res.text.should.equal('{"name":"tobi"}'); - done(); - }) - }) + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .then(res => { + res.type.should.equal('application/json'); + res.text.should.equal('{"name":"tobi"}'); + done(); + }); + }); it('should reject an error with .then(null, reject)', done => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return done(); } - request - .get(`${uri}/error`) - .then(null, err => { + request.get(`${uri}/error`).then(null, err => { assert.equal(err.status, 500); assert.equal(err.response.text, 'boom'); done(); - }) - }) - }) + }); + }); + }); describe('.catch(reject)', () => { it('should reject an error with .catch(reject)', done => { - if ('undefined' === typeof Promise) { + if (typeof Promise === 'undefined') { return done(); } - request - .get(`${uri}/error`) - .catch(err => { + request.get(`${uri}/error`).catch(err => { assert.equal(err.status, 500); assert.equal(err.response.text, 'boom'); done(); - }) - }) - }) + }); + }); + }); describe('.abort()', () => { it('should abort the request', done => { - const req = request - .get(`${uri}/delay/3000`); + const req = request.get(`${uri}/delay/3000`); req.end((err, res) => { try { - assert(false, 'should not complete the request'); - } catch(e) { done(e); } + assert(false, 'should not complete the request'); + } catch (err2) { + done(err2); + } }); req.on('error', error => { @@ -549,132 +597,150 @@ describe('request', function(){ setTimeout(() => { req.abort(); }, 500); - }) + }); it('should abort the promise', () => { const req = request.get(`${uri}/delay/3000`); setTimeout(() => { req.abort(); }, 10); - return req.then(() => { - assert.fail('should not complete the request'); - }, err => { - assert.equal("ABORTED", err.code); - }); - }) + return req.then( + () => { + assert.fail('should not complete the request'); + }, + err => { + assert.equal('ABORTED', err.code); + } + ); + }); it('should allow chaining .abort() several times', done => { - const req = request - .get(`${uri}/delay/3000`); + const req = request.get(`${uri}/delay/3000`); req.end((err, res) => { try { - assert(false, 'should not complete the request'); - } catch(e) { done(e); } + assert(false, 'should not complete the request'); + } catch (err2) { + done(err2); + } }); // This also verifies only a single 'done' event is emitted req.on('abort', done); setTimeout(() => { - req.abort().abort().abort(); + req + .abort() + .abort() + .abort(); }, 1000); - }) + }); it('should not allow abort then end', done => { request - .get(`${uri}/delay/3000`) - .abort() - .end((err, res) => { - done(err ? undefined : Error("Expected abort error")); - }); - }) - }) + .get(`${uri}/delay/3000`) + .abort() + .end((err, res) => { + done(err ? undefined : new Error('Expected abort error')); + }); + }); + }); describe('req.toJSON()', () => { it('should describe the request', done => { - const req = request - .post(`${uri}/echo`) - .send({ foo: 'baz' }); + const req = request.post(`${uri}/echo`).send({ foo: 'baz' }); req.end((err, res) => { try { - const json = req.toJSON(); - assert.equal('POST', json.method); - assert(/\/echo$/.test(json.url)); - assert.equal('baz', json.data.foo); - done(); - } catch(e) { done(e); } + const json = req.toJSON(); + assert.equal('POST', json.method); + assert(/\/echo$/.test(json.url)); + assert.equal('baz', json.data.foo); + done(); + } catch (err2) { + done(err2); + } }); - }) - }) + }); + }); describe('req.options()', () => { it('should allow request body', done => { - request.options(`${uri}/options/echo/body`) - .send({ foo: 'baz' }) - .end((err, res) => { - try { - assert.equal(err, null); - assert.strictEqual(res.body.foo, 'baz'); - done(); - } catch(e) { done(e); } - }); + request + .options(`${uri}/options/echo/body`) + .send({ foo: 'baz' }) + .end((err, res) => { + try { + assert.equal(err, null); + assert.strictEqual(res.body.foo, 'baz'); + done(); + } catch (err2) { + done(err2); + } + }); }); }); describe('req.sortQuery()', () => { it('nop with no querystring', done => { request - .get(`${uri}/url`) - .sortQuery() - .end((err, res) => { - try { - assert.equal(res.text, '/url') - done(); - } catch(e) { done(e); } - }); + .get(`${uri}/url`) + .sortQuery() + .end((err, res) => { + try { + assert.equal(res.text, '/url'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should sort the request querystring', done => { request - .get(`${uri}/url`) - .query('search=Manny') - .query('order=desc') - .sortQuery() - .end((err, res) => { - try { - assert.equal(res.text, '/url?order=desc&search=Manny') - done(); - } catch(e) { done(e); } - }); + .get(`${uri}/url`) + .query('search=Manny') + .query('order=desc') + .sortQuery() + .end((err, res) => { + try { + assert.equal(res.text, '/url?order=desc&search=Manny'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should allow disabling sorting', done => { request - .get(`${uri}/url`) - .query('search=Manny') - .query('order=desc') - .sortQuery() // take default of true - .sortQuery(false) // override it in later call - .end((err, res) => { - try { - assert.equal(res.text, '/url?search=Manny&order=desc') - done(); - } catch(e) { done(e); } - }); + .get(`${uri}/url`) + .query('search=Manny') + .query('order=desc') + .sortQuery() // take default of true + .sortQuery(false) // override it in later call + .end((err, res) => { + try { + assert.equal(res.text, '/url?search=Manny&order=desc'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should sort the request querystring using customized function', done => { request - .get(`${uri}/url`) - .query('name=Nick') - .query('search=Manny') - .query('order=desc') - .sortQuery((a, b) => a.length - b.length) - .end((err, res) => { - try { - assert.equal(res.text, '/url?name=Nick&order=desc&search=Manny') - done(); - } catch(e) { done(e); } - }); + .get(`${uri}/url`) + .query('name=Nick') + .query('search=Manny') + .query('order=desc') + .sortQuery((a, b) => a.length - b.length) + .end((err, res) => { + try { + assert.equal(res.text, '/url?name=Nick&order=desc&search=Manny'); + done(); + } catch (err2) { + done(err2); + } + }); }); - }) -}) + }); +}); diff --git a/test/client/request.js b/test/client/request.js index 5c33d5b3b..d04e35d1b 100644 --- a/test/client/request.js +++ b/test/client/request.js @@ -1,313 +1,311 @@ - const assert = require('assert'); const request = require('../support/client'); describe('request', function() { this.timeout(20000); -it('request() error object', next => { - request('GET', '/error').end((err, res) => { - assert(err); - assert(res.error, 'response should be an error'); - assert.equal(res.error.message, 'cannot GET /error (500)'); - assert.equal(res.error.status, 500); - assert.equal(res.error.method, 'GET'); - assert.equal(res.error.url, '/error'); - next(); - }); -}); - -// This test results in a weird Jetty error on IE9 and IE11 saying PATCH is not a supported method. Looks like something's up with SauceLabs -const isIE11 = !!navigator.userAgent.match(/Trident.*rv[ :]*11\./); -const isIE9OrOlder = !window.atob; -if (!isIE9OrOlder && !isIE11) { // Don't run on IE9 or older, or IE11 - it('patch()', next => { - request.patch('/user/12').end((err, res) => { - assert.equal('updated', res.text); + it('request() error object', next => { + request('GET', '/error').end((err, res) => { + assert(err); + assert(res.error, 'response should be an error'); + assert.equal(res.error.message, 'cannot GET /error (500)'); + assert.equal(res.error.status, 500); + assert.equal(res.error.method, 'GET'); + assert.equal(res.error.url, '/error'); next(); }); }); -} - -it('POST native FormData', next => { - if (!window.FormData) { - // Skip test if FormData is not supported by browser - return next(); - } - - const data = new FormData(); - data.append('foo', 'bar'); - request - .post('/echo') - .send(data) - .end((err, res) => { - assert.equal('multipart/form-data', res.type); - next(); + // This test results in a weird Jetty error on IE9 and IE11 saying PATCH is not a supported method. Looks like something's up with SauceLabs + const isIE11 = Boolean(navigator.userAgent.match(/Trident.*rv[ :]*11\./)); + const isIE9OrOlder = !window.atob; + if (!isIE9OrOlder && !isIE11) { + // Don't run on IE9 or older, or IE11 + it('patch()', next => { + request.patch('/user/12').end((err, res) => { + assert.equal('updated', res.text); + next(); + }); }); -}); - -it('defaults attached files to original file names', next => { - if (!window.FormData) { - // Skip test if FormData is are not supported by browser - return next(); } - try { - var file = new File([""], "image.jpg", { type: "image/jpeg" }); - } catch(e) { - // Skip if file constructor not supported. - return next(); - } - - request - .post('/echo') - .attach('image', file) - .end((err, res) => { - const regx = new RegExp(`filename="${file.name}"`); - assert.notEqual(res.text.match(regx), null); - next(); - }); -}); + it('POST native FormData', next => { + if (!window.FormData) { + // Skip test if FormData is not supported by browser + return next(); + } -it('attach() cannot be mixed with send()', () => { - if (!window.FormData || !window.File) { - // Skip test if FormData is are not supported by browser - return; - } + const data = new FormData(); + data.append('foo', 'bar'); - assert.throws(() => { - const file = new File([""], "image.jpg", { type: "image/jpeg" }); request - .post('/echo') - .attach('image', file) - .send('hi'); + .post('/echo') + .send(data) + .end((err, res) => { + assert.equal('multipart/form-data', res.type); + next(); + }); }); - assert.throws(() => { - const file = new File([""], "image.jpg", { type: "image/jpeg" }); + it('defaults attached files to original file names', next => { + if (!window.FormData) { + // Skip test if FormData is are not supported by browser + return next(); + } + + try { + var file = new File([''], 'image.jpg', { type: 'image/jpeg' }); + } catch (err) { + // Skip if file constructor not supported. + return next(); + } + request - .post('/echo') - .send('hi') - .attach('image', file); + .post('/echo') + .attach('image', file) + .end((err, res) => { + const regx = new RegExp(`filename="${file.name}"`); + assert.notEqual(res.text.match(regx), null); + next(); + }); }); -}); -it('GET invalid json', next => { - request - .get('/invalid-json') - .end((err, res) => { - assert(err.parse); - assert.deepEqual(err.rawResponse, ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}"); - next(); - }); -}); + it('attach() cannot be mixed with send()', () => { + if (!window.FormData || !window.File) { + // Skip test if FormData is are not supported by browser + return; + } + + assert.throws(() => { + const file = new File([''], 'image.jpg', { type: 'image/jpeg' }); + request + .post('/echo') + .attach('image', file) + .send('hi'); + }); -it('GET querystring empty objects', next => { - const req = request - .get('/querystring') - .query({}); - req.end((err, res) => { - assert.deepEqual(req._query, []); - assert.deepEqual(res.body, {}); - next(); + assert.throws(() => { + const file = new File([''], 'image.jpg', { type: 'image/jpeg' }); + request + .post('/echo') + .send('hi') + .attach('image', file); + }); }); -}); -it('GET querystring object .get(uri, obj)', next => { - request - .get('/querystring', { search: 'Manny' }) - .end((err, res) => { - assert.deepEqual(res.body, { search: 'Manny' }); - next(); + it('GET invalid json', next => { + request.get('/invalid-json').end((err, res) => { + assert(err.parse); + assert.deepEqual( + err.rawResponse, + ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}" + ); + next(); + }); }); -}); -it('GET querystring object .get(uri, obj, fn)', next => { - request - .get('/querystring', { search: 'Manny'}, (err, res) => { - assert.deepEqual(res.body, { search: 'Manny' }); - next(); + it('GET querystring empty objects', next => { + const req = request.get('/querystring').query({}); + req.end((err, res) => { + assert.deepEqual(req._query, []); + assert.deepEqual(res.body, {}); + next(); + }); }); -}); -it('GET querystring object with null value', next => { - request - .get('/url', { nil: null }) - .end((err, res) => { - assert.equal(res.text, '/url?nil'); - next(); + it('GET querystring object .get(uri, obj)', next => { + request.get('/querystring', { search: 'Manny' }).end((err, res) => { + assert.deepEqual(res.body, { search: 'Manny' }); + next(); + }); }); -}); -it('GET blob object', next => { - if ('undefined' === typeof Blob) { - return next(); - } - request - .get('/blob', { foo: 'bar'}) - .responseType('blob') - .end((err, res) => { - assert(res.xhr.response instanceof Blob); - assert(res.body instanceof Blob); + it('GET querystring object .get(uri, obj, fn)', next => { + request.get('/querystring', { search: 'Manny' }, (err, res) => { + assert.deepEqual(res.body, { search: 'Manny' }); next(); }); -}); - -it('Reject node-only function', () => { - assert.throws(() => { - request.get().write(); - }); - assert.throws(() => { - request.get().pipe(); }); -}); -window.btoa = window.btoa || null; -it('basic auth', next => { - window.btoa = window.btoa || require('Base64').btoa; - - request - .post('/auth') - .auth('foo', 'bar') - .end((err, res) => { - assert.equal('foo', res.body.user); - assert.equal('bar', res.body.pass); - next(); + it('GET querystring object with null value', next => { + request.get('/url', { nil: null }).end((err, res) => { + assert.equal(res.text, '/url?nil'); + next(); + }); }); -}); -it('auth type "basic"', next => { - window.btoa = window.btoa || require('Base64').btoa; + it('GET blob object', next => { + if (typeof Blob === 'undefined') { + return next(); + } - request - .post('/auth') - .auth('foo', 'bar', {type: 'basic'}) - .end((err, res) => { - assert.equal('foo', res.body.user); - assert.equal('bar', res.body.pass); - next(); + request + .get('/blob', { foo: 'bar' }) + .responseType('blob') + .end((err, res) => { + assert(res.xhr.response instanceof Blob); + assert(res.body instanceof Blob); + next(); + }); }); -}); - -it('auth type "auto"', next => { - window.btoa = window.btoa || require('Base64').btoa; - request - .post('/auth') - .auth('foo', 'bar', {type: 'auto'}) - .end((err, res) => { - assert.equal('foo', res.body.user); - assert.equal('bar', res.body.pass); - next(); + it('Reject node-only function', () => { + assert.throws(() => { + request.get().write(); + }); + assert.throws(() => { + request.get().pipe(); + }); }); -}); -it('progress event listener on xhr object registered when some on the request', () => { - const req = request - .get('/foo') - .on('progress', data => { + window.btoa = window.btoa || null; + it('basic auth', next => { + window.btoa = window.btoa || require('Base64').btoa; + + request + .post('/auth') + .auth('foo', 'bar') + .end((err, res) => { + assert.equal('foo', res.body.user); + assert.equal('bar', res.body.pass); + next(); + }); }); - req.end(); - if (req.xhr.upload) { // Only run assertion on capable browsers - assert.notEqual(null, req.xhr.upload.onprogress); - } -}); + it('auth type "basic"', next => { + window.btoa = window.btoa || require('Base64').btoa; -it('no progress event listener on xhr object when none registered on request', () => { - const req = request - .get('/foo'); - req.end(); + request + .post('/auth') + .auth('foo', 'bar', { type: 'basic' }) + .end((err, res) => { + assert.equal('foo', res.body.user); + assert.equal('bar', res.body.pass); + next(); + }); + }); - if (req.xhr.upload) { // Only run assertion on capable browsers - assert.strictEqual(null, req.xhr.upload.onprogress); - } -}); + it('auth type "auto"', next => { + window.btoa = window.btoa || require('Base64').btoa; -it('Request#parse overrides body parser no matter Content-Type', done => { - let runParser = false; + request + .post('/auth') + .auth('foo', 'bar', { type: 'auto' }) + .end((err, res) => { + assert.equal('foo', res.body.user); + assert.equal('bar', res.body.pass); + next(); + }); + }); - function testParser(data){ - runParser = true; - return JSON.stringify(data); - } + it('progress event listener on xhr object registered when some on the request', () => { + const req = request.get('/foo').on('progress', data => {}); + req.end(); - request - .post('/user') - .serialize(testParser) - .type('json') - .send({ foo: 123 }) - .end(err => { - if (err) return done(err); - assert(runParser); - done(); + if (req.xhr.upload) { + // Only run assertion on capable browsers + assert.notEqual(null, req.xhr.upload.onprogress); + } }); -}); -// Don't run on browsers without xhr2 support -if ('FormData' in window) { - it('xhr2 download file old hack', next => { - request.parse['application/vnd.superagent'] = obj => obj; + it('no progress event listener on xhr object when none registered on request', () => { + const req = request.get('/foo'); + req.end(); - request - .get('/arraybuffer') - .on('request', function () { - this.xhr.responseType = 'arraybuffer'; - }) - .on('response', res => { - assert(res.body instanceof ArrayBuffer); - next(); - }) - .end(); + if (req.xhr.upload) { + // Only run assertion on capable browsers + assert.strictEqual(null, req.xhr.upload.onprogress); + } }); - it('xhr2 download file responseType', next => { - request.parse['application/vnd.superagent'] = obj => obj; + it('Request#parse overrides body parser no matter Content-Type', done => { + let runParser = false; + + function testParser(data) { + runParser = true; + return JSON.stringify(data); + } request - .get('/arraybuffer') - .responseType('arraybuffer') - .on('response', res => { - assert(res.body instanceof ArrayBuffer); - next(); - }) - .end(); + .post('/user') + .serialize(testParser) + .type('json') + .send({ foo: 123 }) + .end(err => { + if (err) return done(err); + assert(runParser); + done(); + }); }); - it('get error status code and rawResponse on file download', next => { - request - .get('/arraybuffer-unauthorized') - .responseType('arraybuffer') - .end((err, res) => { - assert.equal(err.status, 401); - assert(res.body instanceof ArrayBuffer); - assert(err.response.body instanceof ArrayBuffer); - const decodedString = String.fromCharCode.apply(null, new Uint8Array(res.body)); - assert(decodedString, '{"message":"Authorization has been denied for this request."}'); - next(); + // Don't run on browsers without xhr2 support + if ('FormData' in window) { + it('xhr2 download file old hack', next => { + request.parse['application/vnd.superagent'] = obj => obj; + + request + .get('/arraybuffer') + .on('request', function() { + this.xhr.responseType = 'arraybuffer'; + }) + .on('response', res => { + assert(res.body instanceof ArrayBuffer); + next(); + }) + .end(); }); - }); -} - -it('parse should take precedence over default parse', done => { - request - .get('/foo') - .parse((res, text) => `customText: ${res.status}`) - .end((err, res) => { - assert(res.ok); - assert(res.body === 'customText: 200'); - done(); - }); -}); -it('handles `xhr.open()` errors', done => { - request - .get('http://foo\0.com') // throws "Failed to execute 'open' on 'XMLHttpRequest': Invalid URL" - .end((err, res) => { - assert(err); - done(); + it('xhr2 download file responseType', next => { + request.parse['application/vnd.superagent'] = obj => obj; + + request + .get('/arraybuffer') + .responseType('arraybuffer') + .on('response', res => { + assert(res.body instanceof ArrayBuffer); + next(); + }) + .end(); + }); + + it('get error status code and rawResponse on file download', next => { + request + .get('/arraybuffer-unauthorized') + .responseType('arraybuffer') + .end((err, res) => { + assert.equal(err.status, 401); + assert(res.body instanceof ArrayBuffer); + assert(err.response.body instanceof ArrayBuffer); + const decodedString = String.fromCharCode.apply( + null, + new Uint8Array(res.body) + ); + assert( + decodedString, + '{"message":"Authorization has been denied for this request."}' + ); + next(); + }); + }); + } + + it('parse should take precedence over default parse', done => { + request + .get('/foo') + .parse((res, text) => `customText: ${res.status}`) + .end((err, res) => { + assert(res.ok); + assert(res.body === 'customText: 200'); + done(); + }); }); -}); + it('handles `xhr.open()` errors', done => { + request + .get('http://foo\0.com') // throws "Failed to execute 'open' on 'XMLHttpRequest': Invalid URL" + .end((err, res) => { + assert(err); + done(); + }); + }); }); diff --git a/test/client/serialize.js b/test/client/serialize.js index ae427f64f..77e8f9e8b 100644 --- a/test/client/serialize.js +++ b/test/client/serialize.js @@ -4,15 +4,22 @@ const request = require('../support/client'); function serialize(obj, res) { const val = request.serializeObject(obj); - assert.equal(val, res - , `${JSON.stringify(obj)} to "${res}" serialization failed. got: "${val}"`); + assert.equal( + val, + res, + `${JSON.stringify(obj)} to "${res}" serialization failed. got: "${val}"` + ); } function parse(str, obj) { const val = request.parseString(str); - assert.deepEqual(val - , obj - , `"${str}" to ${JSON.stringify(obj)} parse failed. got: ${JSON.stringify(val)}`); + assert.deepEqual( + val, + obj, + `"${str}" to ${JSON.stringify(obj)} parse failed. got: ${JSON.stringify( + val + )}` + ); } describe('request.serializeObject()', () => { @@ -27,7 +34,7 @@ describe('request.serializeObject()', () => { serialize({ name: 'tj', age: 24 }, 'name=tj&age=24'); serialize({ name: '&tj&' }, 'name=%26tj%26'); serialize({ '&name&': 'tj' }, '%26name%26=tj'); - serialize({ hello: "`test`" }, "hello=%60test%60"); + serialize({ hello: '`test`' }, 'hello=%60test%60'); }); }); @@ -38,12 +45,12 @@ describe('request.parseString()', () => { parse('redirect=/&ok', { redirect: '/', ok: '' }); parse('%26name=tj', { '&name': 'tj' }); parse('name=tj%26', { name: 'tj&' }); - parse("%60", { "`": "" }); + parse('%60', { '`': '' }); }); }); describe('Merging objects', () => { - it('Don\'t mix FormData and JSON', () => { + it("Don't mix FormData and JSON", () => { if (!window.FormData) { // Skip test if FormData is not supported by browser return; @@ -56,26 +63,26 @@ describe('Merging objects', () => { request .post('/echo') .send(data) - .send({allowed:false}) + .send({ allowed: false }); }); }); - it('Don\'t mix Blob and JSON', () => { + it("Don't mix Blob and JSON", () => { if (!window.Blob) { return; } request .post('/echo') - .send(new Blob(["will be cleared"])) + .send(new Blob(['will be cleared'])) .send(false) - .send({allowed:true}); + .send({ allowed: true }); assert.throws(() => { request .post('/echo') - .send(new Blob(["hello"])) - .send({allowed:false}) + .send(new Blob(['hello'])) + .send({ allowed: false }); }); }); }); diff --git a/test/client/xdomain.js b/test/client/xdomain.js index 41d480371..e1bd6ab4e 100644 --- a/test/client/xdomain.js +++ b/test/client/xdomain.js @@ -1,30 +1,29 @@ const assert = require('assert'); const request = require('../support/client'); -describe('xdomain', function(){ +describe('xdomain', function() { this.timeout(20000); // TODO (defunctzombie) I am not certain this actually forces xdomain request // use localtunnel.me and tunnel127.com alias instead it('should support req.withCredentials()', next => { request - .get(`//${window.location.host}/xdomain`) - .withCredentials() - .end((err, res) => { - assert.equal(200, res.status); - assert.equal('tobi', res.text); - next(); - }); + .get(`//${window.location.host}/xdomain`) + .withCredentials() + .end((err, res) => { + assert.equal(200, res.status); + assert.equal('tobi', res.text); + next(); + }); }); // xdomain not supported in old IE and IE11 gives weird Jetty errors (looks like a SauceLabs issue) - const isIE11 = !!navigator.userAgent.match(/Trident.*rv[ :]*11\./); + const isIE11 = Boolean(navigator.userAgent.match(/Trident.*rv[ :]*11\./)); const isIE9OrOlder = !window.atob; - if (!isIE9OrOlder && !isIE11) { // Don't run on IE9 or older, or IE11 + if (!isIE9OrOlder && !isIE11) { + // Don't run on IE9 or older, or IE11 it('should handle x-domain failure', next => { - request - .get('//tunne127.com') - .end((err, res) => { + request.get('//tunne127.com').end((err, res) => { assert(err, 'error missing'); assert(err.crossDomain, 'not .crossDomain'); next(); @@ -33,18 +32,18 @@ describe('xdomain', function(){ it('should handle x-domain failure after repeat attempts', next => { request - .get('//tunne127.com') - .retry(2) - .end((err, res) => { - try { - assert(err, 'error missing'); - assert(err.crossDomain, 'not .crossDomain'); - assert.equal(2, err.retries, 'expected an error with .retries'); - next(); - } catch(err) { - next(err); - } - }); + .get('//tunne127.com') + .retry(2) + .end((err, res) => { + try { + assert(err, 'error missing'); + assert(err.crossDomain, 'not .crossDomain'); + assert.equal(2, err.retries, 'expected an error with .retries'); + next(); + } catch (err2) { + next(err2); + } + }); }); } }); diff --git a/test/content-type.js b/test/content-type.js index b8a141a25..25f2fe6cf 100644 --- a/test/content-type.js +++ b/test/content-type.js @@ -1,32 +1,32 @@ const setup = require('./support/setup'); -const uri = setup.uri; + +const { uri } = setup; const assert = require('assert'); const request = require('./support/client'); -describe('req.set("Content-Type", contentType)', function(){ +describe('req.set("Content-Type", contentType)', function() { this.timeout(20000); it('should work with just the contentType component', done => { request - .post(`${uri}/echo`) - .set('Content-Type', 'application/json') - .send({ name: 'tobi' }) - .end((err, res) => { - assert(!err); - done(); - }); + .post(`${uri}/echo`) + .set('Content-Type', 'application/json') + .send({ name: 'tobi' }) + .end((err, res) => { + assert(!err); + done(); + }); }); it('should work with the charset component', done => { request - .post(`${uri}/echo`) - .set('Content-Type', 'application/json; charset=utf-8') - .send({ name: 'tobi' }) - .end((err, res) => { - assert(!err); - done(); - }); + .post(`${uri}/echo`) + .set('Content-Type', 'application/json; charset=utf-8') + .send({ name: 'tobi' }) + .end((err, res) => { + assert(!err); + done(); + }); }); - }); diff --git a/test/form.js b/test/form.js index 9289015e7..4ce496625 100644 --- a/test/form.js +++ b/test/form.js @@ -1,43 +1,51 @@ const setup = require('./support/setup'); + const base = setup.uri; const should = require('should'); const request = require('./support/client'); const assert = require('assert'); + if (!assert.deepStrictEqual) assert.deepStrictEqual = assert.deepEqual; -const formDataSupported = setup.NODE || 'undefined' !== FormData; +const formDataSupported = setup.NODE || FormData !== 'undefined'; describe('req.send(Object) as "form"', () => { describe('with req.type() set to form', () => { it('should send x-www-form-urlencoded data', done => { request - .post(`${base}/echo`) - .type('form') - .send({ name: 'tobi' }) - .end((err, res) => { - res.header['content-type'].should.equal('application/x-www-form-urlencoded'); - res.text.should.equal('name=tobi'); - done(); - }); - }) - }) + .post(`${base}/echo`) + .type('form') + .send({ name: 'tobi' }) + .end((err, res) => { + res.header['content-type'].should.equal( + 'application/x-www-form-urlencoded' + ); + res.text.should.equal('name=tobi'); + done(); + }); + }); + }); describe('when called several times', () => { it('should merge the objects', done => { request - .post(`${base}/echo`) - .type('form') - .send({ name: { first: 'tobi', last: 'holowaychuk' } }) - .send({ age: '1' }) - .end((err, res) => { - res.header['content-type'].should.equal('application/x-www-form-urlencoded'); - res.text.should.equal('name%5Bfirst%5D=tobi&name%5Blast%5D=holowaychuk&age=1'); - done(); - }); - }) - }) -}) + .post(`${base}/echo`) + .type('form') + .send({ name: { first: 'tobi', last: 'holowaychuk' } }) + .send({ age: '1' }) + .end((err, res) => { + res.header['content-type'].should.equal( + 'application/x-www-form-urlencoded' + ); + res.text.should.equal( + 'name%5Bfirst%5D=tobi&name%5Blast%5D=holowaychuk&age=1' + ); + done(); + }); + }); + }); +}); describe('req.attach', () => { it('ignores null file', done => { @@ -51,7 +59,7 @@ describe('req.attach', () => { }); describe('req.field', function() { - this.timeout(5000) + this.timeout(5000); it('allow bools', done => { if (!formDataSupported) { return done(); @@ -63,7 +71,7 @@ describe('req.field', function() { .field('strings', 'true') .end((err, res) => { assert.ifError(err); - assert.deepStrictEqual(res.body, {bools:'true', strings:'true'}); + assert.deepStrictEqual(res.body, { bools: 'true', strings: 'true' }); done(); }); }); @@ -75,10 +83,10 @@ describe('req.field', function() { request .post(`${base}/formecho`) - .field({bools: true, strings: 'true'}) + .field({ bools: true, strings: 'true' }) .end((err, res) => { assert.ifError(err); - assert.deepStrictEqual(res.body, {bools:'true', strings:'true'}); + assert.deepStrictEqual(res.body, { bools: 'true', strings: 'true' }); done(); }); }); @@ -90,10 +98,10 @@ describe('req.field', function() { request .post(`${base}/formecho`) - .field({numbers: [1,2,3]}) + .field({ numbers: [1, 2, 3] }) .end((err, res) => { assert.ifError(err); - assert.deepStrictEqual(res.body, {numbers:['1','2','3']}); + assert.deepStrictEqual(res.body, { numbers: ['1', '2', '3'] }); done(); }); }); @@ -108,38 +116,34 @@ describe('req.field', function() { .field('letters', ['a', 'b', 'c']) .end((err, res) => { assert.ifError(err); - assert.deepStrictEqual(res.body, {letters: ['a', 'b', 'c']}); + assert.deepStrictEqual(res.body, { letters: ['a', 'b', 'c'] }); done(); }); }); it('throw when empty', () => { should.throws(() => { - request - .post(`${base}/echo`) - .field() + request.post(`${base}/echo`).field(); }, /name/); should.throws(() => { - request - .post(`${base}/echo`) - .field('name') + request.post(`${base}/echo`).field('name'); }, /val/); }); it('cannot be mixed with send()', () => { assert.throws(() => { request - .post('/echo') - .field('form', 'data') - .send('hi'); + .post('/echo') + .field('form', 'data') + .send('hi'); }); assert.throws(() => { request - .post('/echo') - .send('hi') - .field('form', 'data'); + .post('/echo') + .send('hi') + .field('form', 'data'); }); }); }); diff --git a/test/json.js b/test/json.js index af321c8d2..db33183c0 100644 --- a/test/json.js +++ b/test/json.js @@ -1,213 +1,216 @@ const setup = require('./support/setup'); -const uri = setup.uri; + +const { uri } = setup; const doesntWorkInBrowserYet = setup.NODE; const doesntWorkInHttp2 = !process.env.HTTP2_TEST; const assert = require('assert'); const request = require('./support/client'); -describe('req.send(Object) as "json"', function(){ +describe('req.send(Object) as "json"', function() { this.timeout(20000); it('should default to json', done => { request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .end((err, res) => { - res.should.be.json(); - res.text.should.equal('{"name":"tobi"}'); - done(); - }); - }) + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .end((err, res) => { + res.should.be.json(); + res.text.should.equal('{"name":"tobi"}'); + done(); + }); + }); it('should work with arrays', done => { request - .post(`${uri}/echo`) - .send([1,2,3]) - .end((err, res) => { - res.should.be.json(); - res.text.should.equal('[1,2,3]'); - done(); - }); + .post(`${uri}/echo`) + .send([1, 2, 3]) + .end((err, res) => { + res.should.be.json(); + res.text.should.equal('[1,2,3]'); + done(); + }); }); it('should work with value null', done => { request - .post(`${uri}/echo`) - .type('json') - .send('null') - .end((err, res) => { - res.should.be.json(); - assert.strictEqual(res.body, null); - done(); - }); + .post(`${uri}/echo`) + .type('json') + .send('null') + .end((err, res) => { + res.should.be.json(); + assert.strictEqual(res.body, null); + done(); + }); }); it('should work with value false', done => { request - .post(`${uri}/echo`) - .type('json') - .send('false') - .end((err, res) => { - res.should.be.json(); - res.body.should.equal(false); - done(); - }); + .post(`${uri}/echo`) + .type('json') + .send('false') + .end((err, res) => { + res.should.be.json(); + res.body.should.equal(false); + done(); + }); }); - if (doesntWorkInBrowserYet) it('should work with value 0', done => { // fails in IE9 - request - .post(`${uri}/echo`) - .type('json') - .send('0') - .end((err, res) => { - res.should.be.json(); - res.body.should.equal(0); - done(); + if (doesntWorkInBrowserYet) + it('should work with value 0', done => { + // fails in IE9 + request + .post(`${uri}/echo`) + .type('json') + .send('0') + .end((err, res) => { + res.should.be.json(); + res.body.should.equal(0); + done(); + }); }); - }); it('should work with empty string value', done => { request - .post(`${uri}/echo`) - .type('json') - .send('""') - .end((err, res) => { - res.should.be.json(); - res.body.should.equal(""); - done(); - }); - }); - - if (doesntWorkInBrowserYet && doesntWorkInHttp2) it('should work with GET', done => { - request - .get(`${uri}/echo`) - .send({ tobi: 'ferret' }) - .end((err, res) => { - try { + .post(`${uri}/echo`) + .type('json') + .send('""') + .end((err, res) => { res.should.be.json(); - res.text.should.equal('{"tobi":"ferret"}'); - ({"tobi":"ferret"}).should.eql(res.body); + res.body.should.equal(''); done(); - } catch(e) {done(e);} - }); + }); }); + if (doesntWorkInBrowserYet && doesntWorkInHttp2) + it('should work with GET', done => { + request + .get(`${uri}/echo`) + .send({ tobi: 'ferret' }) + .end((err, res) => { + try { + res.should.be.json(); + res.text.should.equal('{"tobi":"ferret"}'); + ({ tobi: 'ferret' }.should.eql(res.body)); + done(); + } catch (err2) { + done(err2); + } + }); + }); + it('should work with vendor MIME type', done => { request - .post(`${uri}/echo`) - .set('Content-Type', 'application/vnd.example+json') - .send({ name: 'vendor' }) - .end((err, res) => { - res.text.should.equal('{"name":"vendor"}'); - ({"name":"vendor"}).should.eql(res.body); - done(); - }); + .post(`${uri}/echo`) + .set('Content-Type', 'application/vnd.example+json') + .send({ name: 'vendor' }) + .end((err, res) => { + res.text.should.equal('{"name":"vendor"}'); + ({ name: 'vendor' }.should.eql(res.body)); + done(); + }); }); describe('when called several times', () => { it('should merge the objects', done => { request - .post(`${uri}/echo`) - .send({ name: 'tobi' }) - .send({ age: 1 }) - .end((err, res) => { - res.should.be.json(); - res.text.should.equal('{"name":"tobi","age":1}'); - ({"name":"tobi","age":1}).should.eql(res.body); - done(); - }); - }) - }) -}) + .post(`${uri}/echo`) + .send({ name: 'tobi' }) + .send({ age: 1 }) + .end((err, res) => { + res.should.be.json(); + res.text.should.equal('{"name":"tobi","age":1}'); + ({ name: 'tobi', age: 1 }.should.eql(res.body)); + done(); + }); + }); + }); +}); -describe('res.body', function(){ +describe('res.body', function() { this.timeout(20000); describe('application/json', () => { it('should parse the body', done => { - request - .get(`${uri}/json`) - .end((err, res) => { + request.get(`${uri}/json`).end((err, res) => { res.text.should.equal('{"name":"manny"}'); res.body.should.eql({ name: 'manny' }); done(); }); - }) - }) + }); + }); - if (doesntWorkInBrowserYet) describe('HEAD requests', () => { - it('should not throw a parse error', done => { - request - .head(`${uri}/json`) - .end((err, res) => { - try { - assert.strictEqual(err, null); - assert.strictEqual(res.text, undefined) - assert.strictEqual(Object.keys(res.body).length, 0) - done(); - } catch(e) {done(e);} + if (doesntWorkInBrowserYet) + describe('HEAD requests', () => { + it('should not throw a parse error', done => { + request.head(`${uri}/json`).end((err, res) => { + try { + assert.strictEqual(err, null); + assert.strictEqual(res.text, undefined); + assert.strictEqual(Object.keys(res.body).length, 0); + done(); + } catch (err2) { + done(err2); + } + }); }); }); - }); describe('Invalid JSON response', () => { it('should return the raw response', done => { - request - .get(`${uri}/invalid-json`) - .end((err, res) => { - assert.deepEqual(err.rawResponse, ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}"); + request.get(`${uri}/invalid-json`).end((err, res) => { + assert.deepEqual( + err.rawResponse, + ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}" + ); done(); }); }); it('should return the http status code', done => { - request - .get(`${uri}/invalid-json-forbidden`) - .end((err, res) => { + request.get(`${uri}/invalid-json-forbidden`).end((err, res) => { assert.equal(err.statusCode, 403); done(); }); }); }); - if (doesntWorkInBrowserYet) describe('No content', () => { - it('should not throw a parse error', done => { - request - .get(`${uri}/no-content`) - .end((err, res) => { - try { - assert.strictEqual(err, null); - assert.strictEqual(res.text, ''); - assert.strictEqual(Object.keys(res.body).length, 0); - done(); - } catch(e) {done(e);} + if (doesntWorkInBrowserYet) + describe('No content', () => { + it('should not throw a parse error', done => { + request.get(`${uri}/no-content`).end((err, res) => { + try { + assert.strictEqual(err, null); + assert.strictEqual(res.text, ''); + assert.strictEqual(Object.keys(res.body).length, 0); + done(); + } catch (err2) { + done(err2); + } + }); }); }); - }); - if (doesntWorkInBrowserYet) describe('application/json+hal', () => { - it('should parse the body', done => { - request - .get(`${uri}/json-hal`) - .end((err, res) => { - if (err) return done(err); - res.text.should.equal('{"name":"hal 5000"}'); - res.body.should.eql({ name: 'hal 5000' }); - done(); + if (doesntWorkInBrowserYet) + describe('application/json+hal', () => { + it('should parse the body', done => { + request.get(`${uri}/json-hal`).end((err, res) => { + if (err) return done(err); + res.text.should.equal('{"name":"hal 5000"}'); + res.body.should.eql({ name: 'hal 5000' }); + done(); + }); }); - }) - }) + }); - if (doesntWorkInBrowserYet) describe('vnd.collection+json', () => { - it('should parse the body', done => { - request - .get(`${uri}/collection-json`) - .end((err, res) => { - res.text.should.equal('{"name":"chewbacca"}'); - res.body.should.eql({ name: 'chewbacca' }); - done(); + if (doesntWorkInBrowserYet) + describe('vnd.collection+json', () => { + it('should parse the body', done => { + request.get(`${uri}/collection-json`).end((err, res) => { + res.text.should.equal('{"name":"chewbacca"}'); + res.body.should.eql({ name: 'chewbacca' }); + done(); + }); }); - }) - }) -}) + }); +}); diff --git a/test/node/agency.js b/test/node/agency.js index e163ab061..2b8ef4984 100644 --- a/test/node/agency.js +++ b/test/node/agency.js @@ -1,67 +1,69 @@ -"use strict"; +'use strict'; -require("should-http"); +require('should-http'); + +const express = require('../support/express'); -const express = require("../support/express"); const app = express(); -const request = require("../support/client"); -const assert = require("assert"); -const should = require("should"); -const cookieParser = require("cookie-parser"); -const session = require("express-session"); +const request = require('../support/client'); +const assert = require('assert'); +const should = require('should'); +const cookieParser = require('cookie-parser'); +const session = require('express-session'); let http = require('http'); -if(process.env.HTTP2_TEST){ + +if (process.env.HTTP2_TEST) { http = require('http2'); } app.use(cookieParser()); app.use( session({ - secret: "secret", + secret: 'secret', resave: true, - saveUninitialized: true, + saveUninitialized: true }) ); -app.post("/signin", (req, res) => { - req.session.user = "hunter@hunterloftis.com"; - res.redirect("/dashboard"); +app.post('/signin', (req, res) => { + req.session.user = 'hunter@hunterloftis.com'; + res.redirect('/dashboard'); }); -app.post("/setcookie", (req, res) => { - res.cookie("cookie", "jar"); +app.post('/setcookie', (req, res) => { + res.cookie('cookie', 'jar'); res.sendStatus(200); }); -app.get("/getcookie", (req, res) => { +app.get('/getcookie', (req, res) => { res.status(200).send(req.cookies.cookie); }); -app.get("/dashboard", (req, res) => { - if (req.session.user) return res.status(200).send("dashboard"); - res.status(401).send("dashboard"); +app.get('/dashboard', (req, res) => { + if (req.session.user) return res.status(200).send('dashboard'); + res.status(401).send('dashboard'); }); -app.all("/signout", (req, res) => { +app.all('/signout', (req, res) => { req.session.regenerate(() => { - res.status(200).send("signout"); + res.status(200).send('signout'); }); }); -app.get("/", (req, res) => { - if (req.session.user) return res.redirect("/dashboard"); - res.status(200).send("home"); +app.get('/', (req, res) => { + if (req.session.user) return res.redirect('/dashboard'); + res.status(200).send('home'); }); -app.post("/redirect", (req, res) => { - res.redirect("/simple"); +app.post('/redirect', (req, res) => { + res.redirect('/simple'); }); -app.get("/simple", (req, res) => { - res.status(200).send("simple"); +app.get('/simple', (req, res) => { + res.status(200).send('simple'); }); -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { server = http.createServer(app); @@ -71,51 +73,51 @@ before(function listen(done) { }); }); -describe("request", () => { - describe("persistent agent", () => { +describe('request', () => { + describe('persistent agent', () => { const agent1 = request.agent(); const agent2 = request.agent(); const agent3 = request.agent(); const agent4 = request.agent(); - it("should gain a session on POST", () => + it('should gain a session on POST', () => agent3.post(`${base}/signin`).then(res => { res.should.have.status(200); - should.not.exist(res.headers["set-cookie"]); - res.text.should.containEql("dashboard"); + should.not.exist(res.headers['set-cookie']); + res.text.should.containEql('dashboard'); })); - it("should start with empty session (set cookies)", done => { + it('should start with empty session (set cookies)', done => { agent1.get(`${base}/dashboard`).end((err, res) => { should.exist(err); res.should.have.status(401); - should.exist(res.headers["set-cookie"]); + should.exist(res.headers['set-cookie']); done(); }); }); - it("should gain a session (cookies already set)", () => + it('should gain a session (cookies already set)', () => agent1.post(`${base}/signin`).then(res => { res.should.have.status(200); - should.not.exist(res.headers["set-cookie"]); - res.text.should.containEql("dashboard"); + should.not.exist(res.headers['set-cookie']); + res.text.should.containEql('dashboard'); })); - it("should persist cookies across requests", () => + it('should persist cookies across requests', () => agent1.get(`${base}/dashboard`).then(res => { res.should.have.status(200); })); - it("should have the cookie set in the end callback", () => + it('should have the cookie set in the end callback', () => agent4 .post(`${base}/setcookie`) .then(() => agent4.get(`${base}/getcookie`)) .then(res => { res.should.have.status(200); - assert.strictEqual(res.text, "jar"); + assert.strictEqual(res.text, 'jar'); })); - it("should not share cookies", done => { + it('should not share cookies', done => { agent2.get(`${base}/dashboard`).end((err, res) => { should.exist(err); res.should.have.status(401); @@ -123,28 +125,28 @@ describe("request", () => { }); }); - it("should not lose cookies between agents", () => + it('should not lose cookies between agents', () => agent1.get(`${base}/dashboard`).then(res => { res.should.have.status(200); })); - it("should be able to follow redirects", () => + it('should be able to follow redirects', () => agent1.get(base).then(res => { res.should.have.status(200); - res.text.should.containEql("dashboard"); + res.text.should.containEql('dashboard'); })); - it("should be able to post redirects", () => + it('should be able to post redirects', () => agent1 .post(`${base}/redirect`) - .send({ foo: "bar", baz: "blaaah" }) + .send({ foo: 'bar', baz: 'blaaah' }) .then(res => { res.should.have.status(200); - res.text.should.containEql("simple"); + res.text.should.containEql('simple'); res.redirects.should.eql([`${base}/simple`]); })); - it("should be able to limit redirects", done => { + it('should be able to limit redirects', done => { agent1 .get(base) .redirects(0) @@ -152,22 +154,22 @@ describe("request", () => { should.exist(err); res.should.have.status(302); res.redirects.should.eql([]); - res.header.location.should.equal("/dashboard"); + res.header.location.should.equal('/dashboard'); done(); }); }); - it("should be able to create a new session (clear cookie)", () => + it('should be able to create a new session (clear cookie)', () => agent1.post(`${base}/signout`).then(res => { res.should.have.status(200); - should.exist(res.headers["set-cookie"]); + should.exist(res.headers['set-cookie']); })); - it("should regenerate with an empty session", done => { + it('should regenerate with an empty session', done => { agent1.get(`${base}/dashboard`).end((err, res) => { should.exist(err); res.should.have.status(401); - should.not.exist(res.headers["set-cookie"]); + should.not.exist(res.headers['set-cookie']); done(); }); }); diff --git a/test/node/basic-auth.js b/test/node/basic-auth.js index c4c4a3e01..51489c860 100644 --- a/test/node/basic-auth.js +++ b/test/node/basic-auth.js @@ -1,15 +1,16 @@ -"use strict"; -const request = require("../support/client"); -const setup = require("../support/setup"); +'use strict'; +const request = require('../support/client'); +const setup = require('../support/setup'); + const base = setup.uri; -const URL = require("url"); +const URL = require('url'); -describe("Basic auth", () => { - describe("when credentials are present in url", () => { - it("should set Authorization", done => { +describe('Basic auth', () => { + describe('when credentials are present in url', () => { + it('should set Authorization', done => { const new_url = URL.parse(base); - new_url.auth = "tobi:learnboost"; - new_url.pathname = "/basic-auth"; + new_url.auth = 'tobi:learnboost'; + new_url.pathname = '/basic-auth'; request.get(URL.format(new_url)).end((err, res) => { res.status.should.equal(200); @@ -18,11 +19,11 @@ describe("Basic auth", () => { }); }); - describe("req.auth(user, pass)", () => { - it("should set Authorization", done => { + describe('req.auth(user, pass)', () => { + it('should set Authorization', done => { request .get(`${base}/basic-auth`) - .auth("tobi", "learnboost") + .auth('tobi', 'learnboost') .end((err, res) => { res.status.should.equal(200); done(); @@ -31,10 +32,10 @@ describe("Basic auth", () => { }); describe('req.auth(user + ":" + pass)', () => { - it("should set authorization", done => { + it('should set authorization', done => { request .get(`${base}/basic-auth/again`) - .auth("tobi") + .auth('tobi') .end((err, res) => { res.status.should.eql(200); done(); diff --git a/test/node/basic.js b/test/node/basic.js index dfd9051e0..d6b44934c 100644 --- a/test/node/basic.js +++ b/test/node/basic.js @@ -1,102 +1,104 @@ -"use strict"; +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const { EventEmitter } = require('events'); +const { StringDecoder } = require('string_decoder'); +const url = require('url'); +const setup = require('../support/setup'); +const request = require('../support/client'); -const request = require("../support/client"); -const setup = require("../support/setup"); const base = setup.uri; -const assert = require("assert"); -const fs = require("fs"); -const EventEmitter = require("events").EventEmitter; -const StringDecoder = require("string_decoder").StringDecoder; -const url = require("url"); + const doesntWorkInHttp2 = !process.env.HTTP2_TEST; -describe("[node] request", () => { - describe("with an url", () => { - it("should preserve the encoding of the url", done => { +describe('[node] request', () => { + describe('with an url', () => { + it('should preserve the encoding of the url', done => { request.get(`${base}/url?a=(b%29`).end((err, res) => { - assert.equal("/url?a=(b%29", res.text); + assert.equal('/url?a=(b%29', res.text); done(); }); }); }); - describe("with an object", () => { - it("should format the url", () => + describe('with an object', () => { + it('should format the url', () => request.get(url.parse(`${base}/login`)).then(res => { assert(res.ok); })); }); - describe("without a schema", () => { - it("should default to http", () => - request.get("localhost:5000/login").then(res => { + describe('without a schema', () => { + it('should default to http', () => + request.get('localhost:5000/login').then(res => { assert.equal(res.status, 200); })); }); - describe("res.toJSON()", () => { - it("should describe the response", () => + describe('res.toJSON()', () => { + it('should describe the response', () => request .post(`${base}/echo`) - .send({ foo: "baz" }) + .send({ foo: 'baz' }) .then(res => { const obj = res.toJSON(); - assert.equal("object", typeof obj.header); - assert.equal("object", typeof obj.req); + assert.equal('object', typeof obj.header); + assert.equal('object', typeof obj.req); assert.equal(200, obj.status); assert.equal('{"foo":"baz"}', obj.text); })); }); - describe("res.links", () => { - it("should default to an empty object", () => + describe('res.links', () => { + it('should default to an empty object', () => request.get(`${base}/login`).then(res => { res.links.should.eql({}); })); - it("should parse the Link header field", done => { + it('should parse the Link header field', done => { request.get(`${base}/links`).end((err, res) => { res.links.next.should.equal( - "https://api.github.com/repos/visionmedia/mocha/issues?page=2" + 'https://api.github.com/repos/visionmedia/mocha/issues?page=2' ); done(); }); }); }); - describe("req.unset(field)", () => { - it("should remove the header field", done => { + describe('req.unset(field)', () => { + it('should remove the header field', done => { request .post(`${base}/echo`) - .unset("User-Agent") + .unset('User-Agent') .end((err, res) => { - assert.equal(void 0, res.header["user-agent"]); + assert.equal(void 0, res.header['user-agent']); done(); }); }); }); - describe("case-insensitive", () => { - it("should set/get header fields case-insensitively", () => { + describe('case-insensitive', () => { + it('should set/get header fields case-insensitively', () => { const r = request.post(`${base}/echo`); - r.set("MiXeD", "helloes"); - assert.strictEqual(r.get("mixed"), "helloes"); + r.set('MiXeD', 'helloes'); + assert.strictEqual(r.get('mixed'), 'helloes'); }); - it("should unset header fields case-insensitively", () => { + it('should unset header fields case-insensitively', () => { const r = request.post(`${base}/echo`); - r.set("MiXeD", "helloes"); - r.unset("MIXED"); - assert.strictEqual(r.get("mixed"), undefined); + r.set('MiXeD', 'helloes'); + r.unset('MIXED'); + assert.strictEqual(r.get('mixed'), undefined); }); }); - describe("req.write(str)", () => { - it("should write the given data", done => { + describe('req.write(str)', () => { + it('should write the given data', done => { const req = request.post(`${base}/echo`); - req.set("Content-Type", "application/json"); - assert.equal("boolean", typeof req.write('{"name"')); - assert.equal("boolean", typeof req.write(':"tobi"}')); + req.set('Content-Type', 'application/json'); + assert.equal('boolean', typeof req.write('{"name"')); + assert.equal('boolean', typeof req.write(':"tobi"}')); req.end((err, res) => { res.text.should.equal('{"name":"tobi"}'); done(); @@ -104,11 +106,11 @@ describe("[node] request", () => { }); }); - describe("req.pipe(stream)", () => { - it("should pipe the response to the given stream", done => { + describe('req.pipe(stream)', () => { + it('should pipe the response to the given stream', done => { const stream = new EventEmitter(); - stream.buf = ""; + stream.buf = ''; stream.writable = true; stream.write = function(chunk) { @@ -127,111 +129,111 @@ describe("[node] request", () => { }); }); - describe(".buffer()", () => { - it("should enable buffering", done => { + describe('.buffer()', () => { + it('should enable buffering', done => { request .get(`${base}/custom`) .buffer() .end((err, res) => { - assert.ifError(err) - assert.equal("custom stuff", res.text); + assert.ifError(err); + assert.equal('custom stuff', res.text); assert(res.buffered); done(); }); }); it("should take precedence over request.buffer['someMimeType'] = false", done => { - const type = 'application/barbaz'; - const send = 'some text'; - request.buffer[type] = false; - request - .post(`${base}/echo`) - .type(type) - .send(send) - .buffer() - .end((err, res) => { - delete request.buffer[type]; - assert.ifError(err) - assert.equal(res.type, type); - assert.equal(send, res.text); - assert(res.buffered); - done(); - }) - }) + const type = 'application/barbaz'; + const send = 'some text'; + request.buffer[type] = false; + request + .post(`${base}/echo`) + .type(type) + .send(send) + .buffer() + .end((err, res) => { + delete request.buffer[type]; + assert.ifError(err); + assert.equal(res.type, type); + assert.equal(send, res.text); + assert(res.buffered); + done(); + }); + }); }); - describe(".buffer(false)", () => { - it("should disable buffering", done => { + describe('.buffer(false)', () => { + it('should disable buffering', done => { request .post(`${base}/echo`) - .type("application/x-dog") - .send("hello this is dog") + .type('application/x-dog') + .send('hello this is dog') .buffer(false) .end((err, res) => { - assert.ifError(err) + assert.ifError(err); assert.equal(null, res.text); res.body.should.eql({}); - let buf = ""; - res.setEncoding("utf8"); - res.on("data", chunk => { + let buf = ''; + res.setEncoding('utf8'); + res.on('data', chunk => { buf += chunk; }); - res.on("end", () => { - buf.should.equal("hello this is dog"); + res.on('end', () => { + buf.should.equal('hello this is dog'); + done(); + }); + }); + }); + it("should take precedence over request.buffer['someMimeType'] = true", done => { + const type = 'application/foobar'; + const send = 'hello this is a dog'; + request.buffer[type] = true; + request + .post(`${base}/echo`) + .type(type) + .send(send) + .buffer(false) + .end((err, res) => { + delete request.buffer[type]; + assert.ifError(err); + assert.equal(null, res.text); + assert.equal(res.type, type); + assert(!res.buffered); + res.body.should.eql({}); + let buf = ''; + res.setEncoding('utf8'); + res.on('data', chunk => { + buf += chunk; + }); + res.on('end', () => { + buf.should.equal(send); done(); }); }); }); - it("should take precedence over request.buffer['someMimeType'] = true", done => { - const type = 'application/foobar'; - const send = 'hello this is a dog'; - request.buffer[type] = true; - request - .post(`${base}/echo`) - .type(type) - .send(send) - .buffer(false) - .end((err, res) => { - delete request.buffer[type]; - assert.ifError(err) - assert.equal(null, res.text); - assert.equal(res.type, type); - assert(!res.buffered); - res.body.should.eql({}); - let buf = ""; - res.setEncoding("utf8"); - res.on("data", chunk => { - buf += chunk; - }); - res.on("end", () => { - buf.should.equal(send); - done(); - }); - }); - }); }); - describe(".withCredentials()", () => { + describe('.withCredentials()', () => { it('should not throw an error when using the client-side "withCredentials" method', done => { request .get(`${base}/custom`) .withCredentials() .end((err, res) => { - assert.ifError(err) + assert.ifError(err); done(); }); }); }); - describe(".agent()", () => { - it("should return the defaut agent", done => { + describe('.agent()', () => { + it('should return the defaut agent', done => { const req = request.post(`${base}/echo`); req.agent().should.equal(false); done(); }); }); - describe(".agent(undefined)", () => { - it("should set an agent to undefined and ensure it is chainable", done => { + describe('.agent(undefined)', () => { + it('should set an agent to undefined and ensure it is chainable', done => { const req = request.get(`${base}/echo`); const ret = req.agent(undefined); ret.should.equal(req); @@ -240,9 +242,9 @@ describe("[node] request", () => { }); }); - describe(".agent(new http.Agent())", () => { - it("should set passed agent", done => { - const http = require("http"); + describe('.agent(new http.Agent())', () => { + it('should set passed agent', done => { + const http = require('http'); const req = request.get(`${base}/echo`); const agent = new http.Agent(); const ret = req.agent(agent); @@ -252,66 +254,67 @@ describe("[node] request", () => { }); }); - describe("with a content type other than application/json or text/*", () => { - it("should still use buffering", () => { + describe('with a content type other than application/json or text/*', () => { + it('should still use buffering', () => { return request .post(`${base}/echo`) - .type("application/x-dog") - .send("hello this is dog") + .type('application/x-dog') + .send('hello this is dog') .then(res => { assert.equal(null, res.text); - assert.equal(res.body.toString(), "hello this is dog"); + assert.equal(res.body.toString(), 'hello this is dog'); res.buffered.should.be.true; }); }); }); - describe("content-length", () => { - it("should be set to the byte length of a non-buffer object", done => { - const decoder = new StringDecoder("utf8"); + describe('content-length', () => { + it('should be set to the byte length of a non-buffer object', done => { + const decoder = new StringDecoder('utf8'); let img = fs.readFileSync(`${__dirname}/fixtures/test.png`); img = decoder.write(img); request .post(`${base}/echo`) - .type("application/x-image") + .type('application/x-image') .send(img) .buffer(false) .end((err, res) => { - assert.ifError(err) + assert.ifError(err); assert(!res.buffered); - assert.equal(res.header["content-length"], Buffer.byteLength(img)); + assert.equal(res.header['content-length'], Buffer.byteLength(img)); done(); }); }); - it("should be set to the length of a buffer object", done => { + it('should be set to the length of a buffer object', done => { const img = fs.readFileSync(`${__dirname}/fixtures/test.png`); request .post(`${base}/echo`) - .type("application/x-image") + .type('application/x-image') .send(img) .buffer(true) .end((err, res) => { - assert.ifError(err) + assert.ifError(err); assert(res.buffered); - assert.equal(res.header["content-length"], img.length); + assert.equal(res.header['content-length'], img.length); done(); }); }); }); - if(doesntWorkInHttp2) it("should send body with .get().send()", next => { - request - .get(`${base}/echo`) - .set("Content-Type", "text/plain") - .send("wahoo") - .end((err, res) => { - try { - assert.equal("wahoo", res.text); - next(); - } catch (e) { - next(e); - } - }); - }); + if (doesntWorkInHttp2) + it('should send body with .get().send()', next => { + request + .get(`${base}/echo`) + .set('Content-Type', 'text/plain') + .send('wahoo') + .end((err, res) => { + try { + assert.equal('wahoo', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); }); diff --git a/test/node/buffers.js b/test/node/buffers.js index 2c018dccd..0e91c3aec 100644 --- a/test/node/buffers.js +++ b/test/node/buffers.js @@ -1,114 +1,114 @@ -"use strict"; -const assert = require("assert"); -const request = require("../support/client"); -const setup = require("../support/setup"); +'use strict'; +const assert = require('assert'); +const request = require('../support/client'); +const setup = require('../support/setup'); + const base = setup.uri; describe("req.buffer['someMimeType']", () => { + it('should respect that agent.buffer(true) takes precedent', done => { + const agent = request.agent(); + agent.buffer(true); + const type = 'application/somerandomtype'; + const send = 'somerandomtext'; + request.buffer[type] = false; + agent + .post(`${base}/echo`) + .type(type) + .send(send) + .end((err, res) => { + delete request.buffer[type]; + assert.ifError(err); + assert.equal(res.type, type); + assert.equal(send, res.text); + assert(res.buffered); + done(); + }); + }); - it('should respect that agent.buffer(true) takes precedent', done => { - const agent = request.agent(); - agent.buffer(true); - const type = 'application/somerandomtype'; - const send = 'somerandomtext'; - request.buffer[type] = false; - agent - .post(`${base}/echo`) - .type(type) - .send(send) - .end((err, res) => { - delete request.buffer[type]; - assert.ifError(err) - assert.equal(res.type, type); - assert.equal(send, res.text); - assert(res.buffered); - done(); - }) - }); - - it('should respect that agent.buffer(false) takes precedent', done => { - const agent = request.agent(); - agent.buffer(false); - const type = 'application/barrr'; - const send = 'some random text2'; - request.buffer[type] = true; - agent - .post(`${base}/echo`) - .type(type) - .send(send) - .end((err, res) => { - delete request.buffer[type]; - assert.ifError(err) - assert.equal(null, res.text); - assert.equal(res.type, type); - assert(!res.buffered); - res.body.should.eql({}); - let buf = ""; - res.setEncoding("utf8"); - res.on("data", chunk => { - buf += chunk; - }); - res.on("end", () => { - buf.should.equal(send); - done(); - }); - }); - }); + it('should respect that agent.buffer(false) takes precedent', done => { + const agent = request.agent(); + agent.buffer(false); + const type = 'application/barrr'; + const send = 'some random text2'; + request.buffer[type] = true; + agent + .post(`${base}/echo`) + .type(type) + .send(send) + .end((err, res) => { + delete request.buffer[type]; + assert.ifError(err); + assert.equal(null, res.text); + assert.equal(res.type, type); + assert(!res.buffered); + res.body.should.eql({}); + let buf = ''; + res.setEncoding('utf8'); + res.on('data', chunk => { + buf += chunk; + }); + res.on('end', () => { + buf.should.equal(send); + done(); + }); + }); + }); - it("should disable buffering for that mimetype when false", done => { - const type = 'application/bar'; - const send = 'some random text'; - request.buffer[type] = false; - request - .post(`${base}/echo`) - .type(type) - .send(send) - .end((err, res) => { - delete request.buffer[type]; - assert.ifError(err) - assert.equal(null, res.text); - assert.equal(res.type, type); - assert(!res.buffered); - res.body.should.eql({}); - let buf = ""; - res.setEncoding("utf8"); - res.on("data", chunk => { - buf += chunk; - }); - res.on("end", () => { - buf.should.equal(send); - done(); - }); - }); - }); - it('should enable buffering for that mimetype when true', done => { - const type = 'application/baz'; - const send = 'woooo'; - request.buffer[type] = true; - request - .post(`${base}/echo`) - .type(type) - .send(send) - .end((err, res) => { - delete request.buffer[type]; - assert.ifError(err) - assert.equal(res.type, type); - assert.equal(send, res.text); - assert(res.buffered); - done(); - }) - }); - it('should fallback to default handling for that mimetype when undefined', () => { - const type = 'application/bazzz'; - const send = 'woooooo'; - return request - .post(`${base}/echo`) - .type(type) - .send(send) - .then(res => { - assert.equal(res.type, type); - assert.equal(send, res.body.toString()); - assert(res.buffered); - }) - }) + it('should disable buffering for that mimetype when false', done => { + const type = 'application/bar'; + const send = 'some random text'; + request.buffer[type] = false; + request + .post(`${base}/echo`) + .type(type) + .send(send) + .end((err, res) => { + delete request.buffer[type]; + assert.ifError(err); + assert.equal(null, res.text); + assert.equal(res.type, type); + assert(!res.buffered); + res.body.should.eql({}); + let buf = ''; + res.setEncoding('utf8'); + res.on('data', chunk => { + buf += chunk; + }); + res.on('end', () => { + buf.should.equal(send); + done(); + }); + }); + }); + it('should enable buffering for that mimetype when true', done => { + const type = 'application/baz'; + const send = 'woooo'; + request.buffer[type] = true; + request + .post(`${base}/echo`) + .type(type) + .send(send) + .end((err, res) => { + delete request.buffer[type]; + assert.ifError(err); + assert.equal(res.type, type); + assert.equal(send, res.text); + assert(res.buffered); + done(); + }); + }); + it('should fallback to default handling for that mimetype when undefined', () => { + const type = 'application/bazzz'; + const send = 'woooooo'; + return request + .post(`${base}/echo`) + .type(type) + .send(send) + .then(res => { + assert.equal(res.type, type); + assert.equal(send, res.body.toString()); + assert(res.buffered); + }); + }); }); diff --git a/test/node/exports.js b/test/node/exports.js index e3c2fd953..37a954b44 100644 --- a/test/node/exports.js +++ b/test/node/exports.js @@ -1,30 +1,30 @@ -"use strict"; -const request = require("../support/client"); +'use strict'; +const request = require('../support/client'); -describe("exports", () => { - it("should expose .protocols", () => { - Object.keys(request.protocols).should.eql(["http:", "https:", "http2:"]); +describe('exports', () => { + it('should expose .protocols', () => { + Object.keys(request.protocols).should.eql(['http:', 'https:', 'http2:']); }); - it("should expose .serialize", () => { + it('should expose .serialize', () => { Object.keys(request.serialize).should.eql([ - "application/x-www-form-urlencoded", - "application/json", + 'application/x-www-form-urlencoded', + 'application/json' ]); }); - it("should expose .parse", () => { + it('should expose .parse', () => { Object.keys(request.parse).should.eql([ - "application/x-www-form-urlencoded", - "application/json", - "text", - "application/octet-stream", - "application/pdf", - "image", + 'application/x-www-form-urlencoded', + 'application/json', + 'text', + 'application/octet-stream', + 'application/pdf', + 'image' ]); }); - it("should export .buffer", () => { + it('should export .buffer', () => { Object.keys(request.buffer).should.eql([]); }); }); diff --git a/test/node/flags.js b/test/node/flags.js index 4ab913b47..6934cf7a5 100644 --- a/test/node/flags.js +++ b/test/node/flags.js @@ -1,103 +1,107 @@ -"use strict"; +'use strict'; + +const request = require('../support/client'); +const setup = require('../support/setup'); -const request = require("../support/client"); -const setup = require("../support/setup"); const base = setup.uri; -const assert = require("assert"); +const assert = require('assert'); -describe("flags", () => { - describe("with 4xx response", () => { - it("should set res.error and res.clientError", done => { +describe('flags', () => { + describe('with 4xx response', () => { + it('should set res.error and res.clientError', done => { request.get(`${base}/notfound`).end((err, res) => { assert(err); - assert(!res.ok, "response should not be ok"); - assert(res.error, "response should be an error"); - assert(res.clientError, "response should be a client error"); - assert(!res.serverError, "response should not be a server error"); + assert(!res.ok, 'response should not be ok'); + assert(res.error, 'response should be an error'); + assert(res.clientError, 'response should be a client error'); + assert(!res.serverError, 'response should not be a server error'); done(); }); }); }); - describe("with 5xx response", () => { - it("should set res.error and res.serverError", done => { + describe('with 5xx response', () => { + it('should set res.error and res.serverError', done => { request.get(`${base}/error`).end((err, res) => { assert(err); - assert(!res.ok, "response should not be ok"); - assert(!res.notFound, "response should not be notFound"); - assert(res.error, "response should be an error"); - assert(!res.clientError, "response should not be a client error"); - assert(res.serverError, "response should be a server error"); + assert(!res.ok, 'response should not be ok'); + assert(!res.notFound, 'response should not be notFound'); + assert(res.error, 'response should be an error'); + assert(!res.clientError, 'response should not be a client error'); + assert(res.serverError, 'response should be a server error'); done(); }); }); }); - describe("with 404 Not Found", () => { - it("should res.notFound", done => { + describe('with 404 Not Found', () => { + it('should res.notFound', done => { request.get(`${base}/notfound`).end((err, res) => { assert(err); - assert(res.notFound, "response should be .notFound"); + assert(res.notFound, 'response should be .notFound'); done(); }); }); }); - describe("with 400 Bad Request", () => { - it("should set req.badRequest", done => { + describe('with 400 Bad Request', () => { + it('should set req.badRequest', done => { request.get(`${base}/bad-request`).end((err, res) => { assert(err); - assert(res.badRequest, "response should be .badRequest"); + assert(res.badRequest, 'response should be .badRequest'); done(); }); }); }); - describe("with 401 Bad Request", () => { - it("should set res.unauthorized", done => { + describe('with 401 Bad Request', () => { + it('should set res.unauthorized', done => { request.get(`${base}/unauthorized`).end((err, res) => { assert(err); - assert(res.unauthorized, "response should be .unauthorized"); + assert(res.unauthorized, 'response should be .unauthorized'); done(); }); }); }); - describe("with 406 Not Acceptable", () => { - it("should set res.notAcceptable", done => { + describe('with 406 Not Acceptable', () => { + it('should set res.notAcceptable', done => { request.get(`${base}/not-acceptable`).end((err, res) => { assert(err); - assert(res.notAcceptable, "response should be .notAcceptable"); + assert(res.notAcceptable, 'response should be .notAcceptable'); done(); }); }); }); - describe("with 204 No Content", () => { - it("should set res.noContent", done => { + describe('with 204 No Content', () => { + it('should set res.noContent', done => { request.get(`${base}/no-content`).end((err, res) => { assert(!err); - assert(res.noContent, "response should be .noContent"); + assert(res.noContent, 'response should be .noContent'); done(); }); }); }); - describe("with 201 Created", () => { - it("should set res.created", done => { + describe('with 201 Created', () => { + it('should set res.created', done => { request.post(`${base}/created`).end((err, res) => { assert(!err); - assert(res.created, "response should be .created"); + assert(res.created, 'response should be .created'); done(); }); }); }); - describe("with 422 Unprocessable Entity", () => { - it("should set res.unprocessableEntity", done => { + describe('with 422 Unprocessable Entity', () => { + it('should set res.unprocessableEntity', done => { request.post(`${base}/unprocessable-entity`).end((err, res) => { assert(err); - assert(res.unprocessableEntity, "response should be .unprocessableEntity"); + assert( + res.unprocessableEntity, + 'response should be .unprocessableEntity' + ); done(); }); }); diff --git a/test/node/form.js b/test/node/form.js index ee4f9272c..fb639cf1d 100644 --- a/test/node/form.js +++ b/test/node/form.js @@ -1,45 +1,46 @@ -"use strict"; +'use strict'; + +const request = require('../support/client'); +const setup = require('../support/setup'); -const request = require("../support/client"); -const setup = require("../support/setup"); const base = setup.uri; -const assert = require("assert"); +const assert = require('assert'); -describe("Merging objects", () => { +describe('Merging objects', () => { it("Don't mix Buffer and JSON", () => { assert.throws(() => { request - .post("/echo") - .send(Buffer.from("some buffer")) + .post('/echo') + .send(Buffer.from('some buffer')) .send({ allowed: false }); }); }); }); -describe("req.send(String)", () => { +describe('req.send(String)', () => { it('should default to "form"', done => { request .post(`${base}/echo`) - .send("user[name]=tj") - .send("user[email]=tj@vision-media.ca") + .send('user[name]=tj') + .send('user[email]=tj@vision-media.ca') .end((err, res) => { - res.header["content-type"].should.equal( - "application/x-www-form-urlencoded" + res.header['content-type'].should.equal( + 'application/x-www-form-urlencoded' ); res.body.should.eql({ - user: { name: "tj", email: "tj@vision-media.ca" }, + user: { name: 'tj', email: 'tj@vision-media.ca' } }); done(); }); }); }); -describe("res.body", () => { - describe("application/x-www-form-urlencoded", () => { - it("should parse the body", done => { +describe('res.body', () => { + describe('application/x-www-form-urlencoded', () => { + it('should parse the body', done => { request.get(`${base}/form-data`).end((err, res) => { - res.text.should.equal("pet[name]=manny"); - res.body.should.eql({ pet: { name: "manny" } }); + res.text.should.equal('pet[name]=manny'); + res.body.should.eql({ pet: { name: 'manny' } }); done(); }); }); diff --git a/test/node/http2.js b/test/node/http2.js index b017a2bc9..79d514b8e 100644 --- a/test/node/http2.js +++ b/test/node/http2.js @@ -1,28 +1,39 @@ -"use strict"; -if(!process.env.HTTP2_TEST){ +'use strict'; +if (!process.env.HTTP2_TEST) { return; } -const request = require("../.."); -const setup = require("../support/setup"); -const assert = require("assert"); -const url = require("url"); + +const assert = require('assert'); +const url = require('url'); +const request = require('../..'); +const setup = require('../support/setup'); + const base = setup.uri; -describe("request.get().http2()", () => { - it("should preserve the encoding of the url", done => { - request.get(`${base}/url?a=(b%29`).http2().end((err, res) => { - assert.equal("/url?a=(b%29", res.text); - done(); - }); +describe('request.get().http2()', () => { + it('should preserve the encoding of the url', done => { + request + .get(`${base}/url?a=(b%29`) + .http2() + .end((err, res) => { + assert.equal('/url?a=(b%29', res.text); + done(); + }); }); - it("should format the url", () => - request.get(url.parse(`${base}/login`)).http2().then(res => { - assert(res.ok); - })); + it('should format the url', () => + request + .get(url.parse(`${base}/login`)) + .http2() + .then(res => { + assert(res.ok); + })); - it("should default to http", () => - request.get("localhost:5000/login").http2().then(res => { - assert.equal(res.status, 200); - })); + it('should default to http', () => + request + .get('localhost:5000/login') + .http2() + .then(res => { + assert.equal(res.status, 200); + })); }); diff --git a/test/node/https.js b/test/node/https.js index 879bbb0f8..d16635b57 100644 --- a/test/node/https.js +++ b/test/node/https.js @@ -1,12 +1,15 @@ -"use strict"; +'use strict'; + +const assert = require('assert'); + +const url = require('url'); +const https = require('https'); +const fs = require('fs'); +const express = require('../support/express'); +const request = require('../support/client'); -const request = require("../support/client"); -const express = require("../support/express");; -const assert = require("assert"); const app = express(); -const url = require("url"); -const https = require("https"); -const fs = require("fs"); + const ca = fs.readFileSync(`${__dirname}/fixtures/ca.cert.pem`); const key = fs.readFileSync(`${__dirname}/fixtures/key.pem`); const pfx = fs.readFileSync(`${__dirname}/fixtures/cert.pfx`); @@ -28,40 +31,42 @@ openssl pkcs12 -export -in cert.pem -inkey key.pem -out passcert.pfx # password */ let http2; -if(process.env.HTTP2_TEST){ +if (process.env.HTTP2_TEST) { http2 = require('http2'); } + let server; -app.get("/", (req, res) => { - res.send("Safe and secure!"); +app.get('/', (req, res) => { + res.send('Safe and secure!'); }); // WARNING: this .listen() boilerplate is slightly different from most tests // due to HTTPS. Do not copy/paste without examination. -const base = "https://localhost"; +const base = 'https://localhost'; let testEndpoint; -describe("https", () => { - describe("certificate authority", () => { +describe('https', () => { + describe('certificate authority', () => { before(function listen(done) { - if(process.env.HTTP2_TEST){ + if (process.env.HTTP2_TEST) { server = http2.createSecureServer( { key, - cert, + cert }, app ); - }else{ + } else { server = https.createServer( { key, - cert, + cert }, app ); } + server.listen(0, function listening() { testEndpoint = `${base}:${server.address().port}`; done(); @@ -72,53 +77,54 @@ describe("https", () => { if (server) server.close(); }); - describe("request", () => { - it("should give a good response", done => { + describe('request', () => { + it('should give a good response', done => { request .get(testEndpoint) .ca(ca) .end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); - it("should reject unauthorized response", () => { + it('should reject unauthorized response', () => { return request .get(testEndpoint) .trustLocalhost(false) - .then(() => { - throw Error("Allows MITM") - }, () => {}); + .then( + () => { + throw new Error('Allows MITM'); + }, + () => {} + ); }); - it("should trust localhost unauthorized response", () => { - return request - .get(testEndpoint) - .trustLocalhost(true) + it('should trust localhost unauthorized response', () => { + return request.get(testEndpoint).trustLocalhost(true); }); - it("should trust overriden localhost unauthorized response", () => { + it('should trust overriden localhost unauthorized response', () => { return request .get(`https://example.com:${server.address().port}`) - .connect("127.0.0.1") - .trustLocalhost() + .connect('127.0.0.1') + .trustLocalhost(); }); }); - describe(".agent", () => { - it("should be able to make multiple requests without redefining the certificate", done => { + describe('.agent', () => { + it('should be able to make multiple requests without redefining the certificate', done => { const agent = request.agent({ ca }); agent.get(testEndpoint).end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); agent.get(url.parse(testEndpoint)).end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); @@ -126,31 +132,32 @@ describe("https", () => { }); }); - describe.skip("client certificates", () => { + describe.skip('client certificates', () => { before(function listen(done) { - if(process.env.HTTP2_TEST){ + if (process.env.HTTP2_TEST) { server = http2.createSecureServer( { ca, key, cert, requestCert: true, - rejectUnauthorized: true, + rejectUnauthorized: true }, app ); - }else{ + } else { server = https.createServer( { ca, key, cert, requestCert: true, - rejectUnauthorized: true, + rejectUnauthorized: true }, app ); } + server.listen(0, function listening() { testEndpoint = `${base}:${server.address().port}`; done(); @@ -161,8 +168,8 @@ describe("https", () => { if (server) server.close(); }); - describe("request", () => { - it("should give a good response with client certificates and CA", done => { + describe('request', () => { + it('should give a good response with client certificates and CA', done => { request .get(testEndpoint) .ca(ca) @@ -171,62 +178,62 @@ describe("https", () => { .end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); - it("should give a good response with client pfx", done => { + it('should give a good response with client pfx', done => { request .get(testEndpoint) .pfx(pfx) .end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); - it("should give a good response with client pfx with passphrase", done => { + it('should give a good response with client pfx with passphrase', done => { request .get(testEndpoint) .pfx({ pfx: passpfx, - passphrase: "test", + passphrase: 'test' }) .end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); }); - describe(".agent", () => { - it("should be able to make multiple requests without redefining the certificates", done => { + describe('.agent', () => { + it('should be able to make multiple requests without redefining the certificates', done => { const agent = request.agent({ ca, key, cert }); agent.get(testEndpoint).end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); agent.get(url.parse(testEndpoint)).end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); }); - it("should be able to make multiple requests without redefining pfx", done => { + it('should be able to make multiple requests without redefining pfx', done => { const agent = request.agent({ pfx }); agent.get(testEndpoint).end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); agent.get(url.parse(testEndpoint)).end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("Safe and secure!", res.text); + assert.strictEqual('Safe and secure!', res.text); done(); }); }); diff --git a/test/node/image.js b/test/node/image.js index b952dc271..4cebb3d9a 100644 --- a/test/node/image.js +++ b/test/node/image.js @@ -1,43 +1,44 @@ -"use strict"; +'use strict'; + +const request = require('../support/client'); +const setup = require('../support/setup'); -const request = require("../support/client"); -const setup = require("../support/setup"); const base = setup.uri; -const fs = require("fs"); +const fs = require('fs'); const img = fs.readFileSync(`${__dirname}/fixtures/test.png`); -describe("res.body", () => { - describe("image/png", () => { - it("should parse the body", done => { +describe('res.body', () => { + describe('image/png', () => { + it('should parse the body', done => { request.get(`${base}/image`).end((err, res) => { - res.type.should.equal("image/png"); + res.type.should.equal('image/png'); Buffer.isBuffer(res.body).should.be.true(); (res.body.length - img.length).should.equal(0); done(); }); }); }); - describe("application/octet-stream", () => { - it("should parse the body", done => { + describe('application/octet-stream', () => { + it('should parse the body', done => { request .get(`${base}/image-as-octets`) .buffer(true) // that's tech debt :( .end((err, res) => { - res.type.should.equal("application/octet-stream"); + res.type.should.equal('application/octet-stream'); Buffer.isBuffer(res.body).should.be.true(); (res.body.length - img.length).should.equal(0); done(); }); }); }); - describe("application/octet-stream", () => { - it("should parse the body (using responseType)", done => { + describe('application/octet-stream', () => { + it('should parse the body (using responseType)', done => { request .get(`${base}/image-as-octets`) - .responseType("blob") + .responseType('blob') .end((err, res) => { - res.type.should.equal("application/octet-stream"); + res.type.should.equal('application/octet-stream'); Buffer.isBuffer(res.body).should.be.true(); (res.body.length - img.length).should.equal(0); done(); diff --git a/test/node/incoming-multipart.js b/test/node/incoming-multipart.js index d540b10ce..ad18fdf3a 100644 --- a/test/node/incoming-multipart.js +++ b/test/node/incoming-multipart.js @@ -1,4 +1,3 @@ - // var request = require('../support/client') // , express = require('express') // , assert = require('assert') diff --git a/test/node/inflate.js b/test/node/inflate.js index aa980c5c6..bfe662c2c 100644 --- a/test/node/inflate.js +++ b/test/node/inflate.js @@ -1,20 +1,21 @@ -"use strict"; -require("should"); -require("should-http"); - -const request = require("../support/client"); -const assert = require("assert"); -const express = require("../support/express"); -const zlib = require("zlib"); +'use strict'; +require('should'); +require('should-http'); + +const assert = require('assert'); +const zlib = require('zlib'); let http = require('http'); -if(process.env.HTTP2_TEST){ +const express = require('../support/express'); +const request = require('../support/client'); + +if (process.env.HTTP2_TEST) { http = require('http2'); } -const app = express(), - subject = "some long long long long string"; +const app = express(); +const subject = 'some long long long long string'; -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { @@ -24,75 +25,75 @@ before(function listen(done) { done(); }); }); -app.get("/binary", (req, res) => { +app.get('/binary', (req, res) => { zlib.deflate(subject, (err, buf) => { - res.set("Content-Encoding", "gzip"); + res.set('Content-Encoding', 'gzip'); res.send(buf); }); }); -app.get("/corrupt", (req, res) => { - res.set("Content-Encoding", "gzip"); - res.send("blah"); +app.get('/corrupt', (req, res) => { + res.set('Content-Encoding', 'gzip'); + res.send('blah'); }); -app.get("/nocontent", (req, res, next) => { +app.get('/nocontent', (req, res, next) => { res.statusCode = 204; - res.set("Content-Type", "text/plain"); - res.set("Content-Encoding", "gzip"); - res.send(""); + res.set('Content-Type', 'text/plain'); + res.set('Content-Encoding', 'gzip'); + res.send(''); }); -app.get("/", (req, res, next) => { +app.get('/', (req, res, next) => { zlib.deflate(subject, (err, buf) => { - res.set("Content-Type", "text/plain"); - res.set("Content-Encoding", "gzip"); + res.set('Content-Type', 'text/plain'); + res.set('Content-Encoding', 'gzip'); res.send(buf); }); }); -app.get("/junk", (req, res) => { +app.get('/junk', (req, res) => { zlib.deflate(subject, (err, buf) => { - res.set("Content-Type", "text/plain"); - res.set("Content-Encoding", "gzip"); + res.set('Content-Type', 'text/plain'); + res.set('Content-Encoding', 'gzip'); res.write(buf); - res.end(" 0 junk"); + res.end(' 0 junk'); }); }); -app.get("/chopped", (req, res) => { +app.get('/chopped', (req, res) => { zlib.deflate(`${subject}123456`, (err, buf) => { - res.set("Content-Type", "text/plain"); - res.set("Content-Encoding", "gzip"); + res.set('Content-Type', 'text/plain'); + res.set('Content-Encoding', 'gzip'); res.send(buf.slice(0, -1)); }); }); -describe("zlib", () => { - it("should deflate the content", done => { +describe('zlib', () => { + it('should deflate the content', done => { request.get(base).end((err, res) => { res.should.have.status(200); res.text.should.equal(subject); - res.headers["content-length"].should.be.below(subject.length); + res.headers['content-length'].should.be.below(subject.length); done(); }); }); - it("should protect from zip bombs", done => { + it('should protect from zip bombs', done => { request .get(base) .buffer(true) .maxResponseSize(1) .end((err, res) => { try { - assert.equal("Maximum response size reached", err && err.message); + assert.equal('Maximum response size reached', err && err.message); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should ignore trailing junk", done => { + it('should ignore trailing junk', done => { request.get(`${base}/junk`).end((err, res) => { res.should.have.status(200); res.text.should.equal(subject); @@ -100,7 +101,7 @@ describe("zlib", () => { }); }); - it("should ignore missing data", done => { + it('should ignore missing data', done => { request.get(`${base}/chopped`).end((err, res) => { assert.equal(undefined, err); res.should.have.status(200); @@ -109,47 +110,48 @@ describe("zlib", () => { }); }); - it("should handle corrupted responses", done => { + it('should handle corrupted responses', done => { request.get(`${base}/corrupt`).end((err, res) => { - assert(err, "missing error"); - assert(!res, "response should not be defined"); + assert(err, 'missing error'); + assert(!res, 'response should not be defined'); done(); }); }); - it("should handle no content with gzip header", done => { + it('should handle no content with gzip header', done => { request.get(`${base}/nocontent`).end((err, res) => { assert.ifError(err); assert(res); res.should.have.status(204); - res.text.should.equal(""); - res.headers.should.not.have.property("content-length"); + res.text.should.equal(''); + res.headers.should.not.have.property('content-length'); done(); }); }); - describe("without encoding set", () => { - it("should buffer if asked", () => { - return request.get(`${base}/binary`) - .buffer(true) - .then(res => { - res.should.have.status(200); - assert(res.headers["content-length"]); - assert(res.body.byteLength); - assert.equal(subject, res.body.toString()); - }); + describe('without encoding set', () => { + it('should buffer if asked', () => { + return request + .get(`${base}/binary`) + .buffer(true) + .then(res => { + res.should.have.status(200); + assert(res.headers['content-length']); + assert(res.body.byteLength); + assert.equal(subject, res.body.toString()); + }); }); - it("should emit buffers", done => { + it('should emit buffers', done => { request.get(`${base}/binary`).end((err, res) => { res.should.have.status(200); - res.headers["content-length"].should.be.below(subject.length); + res.headers['content-length'].should.be.below(subject.length); - res.on("data", chunk => { + res.on('data', chunk => { chunk.should.have.length(subject.length); }); - res.on("end", done); + res.on('end', done); }); }); }); diff --git a/test/node/multipart.js b/test/node/multipart.js index e671dd4b1..ae62b92c4 100644 --- a/test/node/multipart.js +++ b/test/node/multipart.js @@ -1,201 +1,207 @@ -"use strict"; +'use strict'; + +const request = require('../support/client'); +const setup = require('../support/setup'); -const request = require("../support/client"); -const setup = require("../support/setup"); const base = setup.uri; -const assert = require("assert"); -const fs = require("fs"); +const assert = require('assert'); +const fs = require('fs'); function read(file) { - return fs.readFileSync(file, "utf8"); + return fs.readFileSync(file, 'utf8'); } -describe("Multipart", () => { - describe("#field(name, value)", () => { - it("should set a multipart field value", () => { +describe('Multipart', () => { + describe('#field(name, value)', () => { + it('should set a multipart field value', () => { const req = request.post(`${base}/echo`); - req.field("user[name]", "tobi"); - req.field("user[age]", "2"); - req.field("user[species]", "ferret"); + req.field('user[name]', 'tobi'); + req.field('user[age]', '2'); + req.field('user[species]', 'ferret'); return req.then(res => { - res.body["user[name]"].should.equal("tobi"); - res.body["user[age]"].should.equal("2"); - res.body["user[species]"].should.equal("ferret"); + res.body['user[name]'].should.equal('tobi'); + res.body['user[age]'].should.equal('2'); + res.body['user[species]'].should.equal('ferret'); }); }); - it("should work with file attachments", () => { + it('should work with file attachments', () => { const req = request.post(`${base}/echo`); - req.field("name", "Tobi"); - req.attach("document", "test/node/fixtures/user.html"); - req.field("species", "ferret"); + req.field('name', 'Tobi'); + req.attach('document', 'test/node/fixtures/user.html'); + req.field('species', 'ferret'); return req.then(res => { - res.body.name.should.equal("Tobi"); - res.body.species.should.equal("ferret"); + res.body.name.should.equal('Tobi'); + res.body.species.should.equal('ferret'); const html = res.files.document; - html.name.should.equal("user.html"); - html.type.should.equal("text/html"); - read(html.path).should.equal("

name

"); + html.name.should.equal('user.html'); + html.type.should.equal('text/html'); + read(html.path).should.equal('

name

'); }); }); }); - describe("#attach(name, path)", () => { - it("should attach a file", () => { + describe('#attach(name, path)', () => { + it('should attach a file', () => { const req = request.post(`${base}/echo`); - req.attach("one", "test/node/fixtures/user.html"); - req.attach("two", "test/node/fixtures/user.json"); - req.attach("three", "test/node/fixtures/user.txt"); + req.attach('one', 'test/node/fixtures/user.html'); + req.attach('two', 'test/node/fixtures/user.json'); + req.attach('three', 'test/node/fixtures/user.txt'); return req.then(res => { const html = res.files.one; const json = res.files.two; const text = res.files.three; - html.name.should.equal("user.html"); - html.type.should.equal("text/html"); - read(html.path).should.equal("

name

"); + html.name.should.equal('user.html'); + html.type.should.equal('text/html'); + read(html.path).should.equal('

name

'); - json.name.should.equal("user.json"); - json.type.should.equal("application/json"); + json.name.should.equal('user.json'); + json.type.should.equal('application/json'); read(json.path).should.equal('{"name":"tobi"}'); - text.name.should.equal("user.txt"); - text.type.should.equal("text/plain"); - read(text.path).should.equal("Tobi"); + text.name.should.equal('user.txt'); + text.type.should.equal('text/plain'); + read(text.path).should.equal('Tobi'); }); }); - describe("when a file does not exist", () => { - it("should fail the request with an error", done => { + describe('when a file does not exist', () => { + it('should fail the request with an error', done => { const req = request.post(`${base}/echo`); - req.attach("name", "foo"); - req.attach("name2", "bar"); - req.attach("name3", "baz"); + req.attach('name', 'foo'); + req.attach('name2', 'bar'); + req.attach('name3', 'baz'); req.end((err, res) => { - assert.ok(!!err, "Request should have failed."); - err.code.should.equal("ENOENT"); - err.message.should.containEql("ENOENT"); - err.path.should.equal("foo"); + assert.ok(Boolean(err), 'Request should have failed.'); + err.code.should.equal('ENOENT'); + err.message.should.containEql('ENOENT'); + err.path.should.equal('foo'); done(); }); }); - it("promise should fail", () => { - return request.post(`${base}/echo`) - .field({a:1,b:2}) + it('promise should fail', () => { + return request + .post(`${base}/echo`) + .field({ a: 1, b: 2 }) .attach('c', 'does-not-exist.txt') .then( - res => assert.fail("It should not allow this"), + res => assert.fail('It should not allow this'), err => { - err.code.should.equal("ENOENT"); - err.path.should.equal("does-not-exist.txt"); - }); + err.code.should.equal('ENOENT'); + err.path.should.equal('does-not-exist.txt'); + } + ); }); - it("should report ECONNREFUSED via the callback", done => { - request.post('http://127.0.0.1:1') // nobody is listening there - .attach("name", "file-does-not-exist") + it('should report ECONNREFUSED via the callback', done => { + request + .post('http://127.0.0.1:1') // nobody is listening there + .attach('name', 'file-does-not-exist') .end((err, res) => { - assert.ok(!!err, "Request should have failed"); - err.code.should.equal("ECONNREFUSED"); + assert.ok(Boolean(err), 'Request should have failed'); + err.code.should.equal('ECONNREFUSED'); done(); }); }); - it("should report ECONNREFUSED via Promise", () => { - return request.post('http://127.0.0.1:1') // nobody is listening there - .attach("name", "file-does-not-exist") + it('should report ECONNREFUSED via Promise', () => { + return request + .post('http://127.0.0.1:1') // nobody is listening there + .attach('name', 'file-does-not-exist') .then( - res => assert.fail("Request should have failed"), - err => err.code.should.equal("ECONNREFUSED")); + res => assert.fail('Request should have failed'), + err => err.code.should.equal('ECONNREFUSED') + ); }); }); }); - describe("#attach(name, path, filename)", () => { - it("should use the custom filename", () => + describe('#attach(name, path, filename)', () => { + it('should use the custom filename', () => request .post(`${base}/echo`) - .attach("document", "test/node/fixtures/user.html", "doc.html") + .attach('document', 'test/node/fixtures/user.html', 'doc.html') .then(res => { const html = res.files.document; - html.name.should.equal("doc.html"); - html.type.should.equal("text/html"); - read(html.path).should.equal("

name

"); + html.name.should.equal('doc.html'); + html.type.should.equal('text/html'); + read(html.path).should.equal('

name

'); })); - it("should fire progress event", done => { + it('should fire progress event', done => { let loaded = 0; let total = 0; let uploadEventWasFired = false; request .post(`${base}/echo`) - .attach("document", "test/node/fixtures/user.html") - .on("progress", event => { + .attach('document', 'test/node/fixtures/user.html') + .on('progress', event => { total = event.total; loaded = event.loaded; - if (event.direction === "upload") { + if (event.direction === 'upload') { uploadEventWasFired = true; } }) .end((err, res) => { if (err) return done(err); const html = res.files.document; - html.name.should.equal("user.html"); - html.type.should.equal("text/html"); - read(html.path).should.equal("

name

"); + html.name.should.equal('user.html'); + html.type.should.equal('text/html'); + read(html.path).should.equal('

name

'); total.should.equal(223); loaded.should.equal(223); uploadEventWasFired.should.equal(true); done(); }); }); - it("filesystem errors should be caught", done => { + it('filesystem errors should be caught', done => { request .post(`${base}/echo`) - .attach("filedata", "test/node/fixtures/non-existent-file.ext") + .attach('filedata', 'test/node/fixtures/non-existent-file.ext') .end((err, res) => { - assert.ok(!!err, "Request should have failed."); - err.code.should.equal("ENOENT"); - err.path.should.equal("test/node/fixtures/non-existent-file.ext"); + assert.ok(Boolean(err), 'Request should have failed.'); + err.code.should.equal('ENOENT'); + err.path.should.equal('test/node/fixtures/non-existent-file.ext'); done(); }); }); }); - describe("#field(name, val)", () => { - it("should set a multipart field value", done => { + describe('#field(name, val)', () => { + it('should set a multipart field value', done => { request .post(`${base}/echo`) - .field("first-name", "foo") - .field("last-name", "bar") + .field('first-name', 'foo') + .field('last-name', 'bar') .end((err, res) => { if (err) done(err); res.should.be.ok(); - res.body["first-name"].should.equal("foo"); - res.body["last-name"].should.equal("bar"); + res.body['first-name'].should.equal('foo'); + res.body['last-name'].should.equal('bar'); done(); }); }); }); - describe("#field(object)", () => { - it("should set multiple multipart fields", done => { + describe('#field(object)', () => { + it('should set multiple multipart fields', done => { request .post(`${base}/echo`) - .field({ "first-name": "foo", "last-name": "bar" }) + .field({ 'first-name': 'foo', 'last-name': 'bar' }) .end((err, res) => { if (err) done(err); res.should.be.ok(); - res.body["first-name"].should.equal("foo"); - res.body["last-name"].should.equal("bar"); + res.body['first-name'].should.equal('foo'); + res.body['last-name'].should.equal('bar'); done(); }); }); diff --git a/test/node/network-error.js b/test/node/network-error.js index f4b768803..f0bde2b49 100644 --- a/test/node/network-error.js +++ b/test/node/network-error.js @@ -1,20 +1,20 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - assert = require("assert"), - net = require("net"); +'use strict'; +const assert = require('assert'); +const net = require('net'); +const request = require('../support/client'); +const express = require('../support/express'); function getFreePort(fn) { const server = net.createServer(); server.listen(0, () => { - const port = server.address().port; + const { port } = server.address(); server.close(() => { fn(port); }); }); } -describe("with network error", () => { +describe('with network error', () => { before(function(done) { // connecting to a free port // will trigger a connection refused @@ -24,9 +24,9 @@ describe("with network error", () => { }); }); - it("should error", function(done) { + it('should error', function(done) { request.get(`http://localhost:${this.port}/`).end((err, res) => { - assert(err, "expected an error"); + assert(err, 'expected an error'); done(); }); }); diff --git a/test/node/not-modified.js b/test/node/not-modified.js index ba1b2673e..1b9a20b95 100644 --- a/test/node/not-modified.js +++ b/test/node/not-modified.js @@ -1,24 +1,25 @@ -"use strict"; -const request = require("../support/client"); -const setup = require("../support/setup"); +'use strict'; +const request = require('../support/client'); +const setup = require('../support/setup'); + const base = setup.uri; -describe("request", () => { - describe("not modified", () => { +describe('request', () => { + describe('not modified', () => { let ts; - it("should start with 200", done => { + it('should start with 200', done => { request.get(`${base}/if-mod`).end((err, res) => { res.should.have.status(200); res.text.should.match(/^\d+$/); - ts = +res.text; + ts = Number(res.text); done(); }); }); - it("should then be 304", done => { + it('should then be 304', done => { request .get(`${base}/if-mod`) - .set("If-Modified-Since", new Date(ts).toUTCString()) + .set('If-Modified-Since', new Date(ts).toUTCString()) .end((err, res) => { res.should.have.status(304); // res.text.should.be.empty diff --git a/test/node/parsers.js b/test/node/parsers.js index d3faa6949..6b3a975d4 100644 --- a/test/node/parsers.js +++ b/test/node/parsers.js @@ -1,29 +1,30 @@ -"use strict"; -const assert = require("assert"); -const request = require("../support/client"); -const setup = require("../support/setup"); +'use strict'; +const assert = require('assert'); +const request = require('../support/client'); +const setup = require('../support/setup'); + const base = setup.uri; const doesntWorkInHttp2 = !process.env.HTTP2_TEST; -describe("req.parse(fn)", () => { - it("should take precedence over default parsers", done => { +describe('req.parse(fn)', () => { + it('should take precedence over default parsers', done => { request .get(`${base}/manny`) - .parse(request.parse["application/json"]) + .parse(request.parse['application/json']) .end((err, res) => { assert(res.ok); assert.equal('{"name":"manny"}', res.text); - assert.equal("manny", res.body.name); + assert.equal('manny', res.body.name); done(); }); }); - it("should be the only parser", () => + it('should be the only parser', () => request .get(`${base}/image`) .buffer(false) .parse((res, fn) => { - res.on("data", () => {}); + res.on('data', () => {}); }) .then(res => { assert(res.ok); @@ -31,48 +32,50 @@ describe("req.parse(fn)", () => { res.body.should.eql({}); })); - it("should emit error if parser throws", done => { + it('should emit error if parser throws', done => { request .get(`${base}/manny`) .parse(() => { - throw new Error("I am broken"); + throw new Error('I am broken'); }) - .on("error", err => { - err.message.should.equal("I am broken"); + .on('error', err => { + err.message.should.equal('I am broken'); done(); }) .end(); }); - it("should emit error if parser returns an error", done => { + it('should emit error if parser returns an error', done => { request .get(`${base}/manny`) .parse((res, fn) => { - fn(new Error("I am broken")); + fn(new Error('I am broken')); }) - .on("error", err => { - err.message.should.equal("I am broken"); + .on('error', err => { + err.message.should.equal('I am broken'); done(); }) .end(); }); - if(doesntWorkInHttp2) it("should not emit error on chunked json", done => { - request.get(`${base}/chunked-json`).end(err => { - assert.ifError(err); - done(); + if (doesntWorkInHttp2) + it('should not emit error on chunked json', done => { + request.get(`${base}/chunked-json`).end(err => { + assert.ifError(err); + done(); + }); }); - }); - if(doesntWorkInHttp2) it("should not emit error on aborted chunked json", done => { - const req = request.get(`${base}/chunked-json`); - req.end(err => { - assert.ifError(err); - done(); - }); + if (doesntWorkInHttp2) + it('should not emit error on aborted chunked json', done => { + const req = request.get(`${base}/chunked-json`); + req.end(err => { + assert.ifError(err); + done(); + }); - setTimeout(() => { - req.abort(); - }, 50); - }); + setTimeout(() => { + req.abort(); + }, 50); + }); }); diff --git a/test/node/pipe-redirect.js b/test/node/pipe-redirect.js index 11ee91915..88d4794c2 100644 --- a/test/node/pipe-redirect.js +++ b/test/node/pipe-redirect.js @@ -1,28 +1,31 @@ -"use strict"; -const request = require("../support/client"); -const setup = require("../support/setup"); +'use strict'; +const request = require('../support/client'); +const setup = require('../support/setup'); + const base = setup.uri; -const fs = require("fs"); +const fs = require('fs'); -describe("pipe on redirect", () => { - const destPath = "test/node/fixtures/pipe.txt"; +describe('pipe on redirect', () => { + const destPath = 'test/node/fixtures/pipe.txt'; after(function removeTmpfile(done) { fs.unlink(destPath, done); }); - it("should follow Location", done => { + it('should follow Location', done => { const stream = fs.createWriteStream(destPath); const redirects = []; - const req = request.get(base).on("redirect", res => { - redirects.push(res.headers.location); - }) - .connect({ - 'inapplicable': 'should be ignored', - }); - stream.on("finish", () => { - redirects.should.eql(["/movies", "/movies/all", "/movies/all/0"]); - fs.readFileSync(destPath, "utf8").should.eql("first movie page"); + const req = request + .get(base) + .on('redirect', res => { + redirects.push(res.headers.location); + }) + .connect({ + inapplicable: 'should be ignored' + }); + stream.on('finish', () => { + redirects.should.eql(['/movies', '/movies/all', '/movies/all/0']); + fs.readFileSync(destPath, 'utf8').should.eql('first movie page'); done(); }); req.pipe(stream); diff --git a/test/node/pipe.js b/test/node/pipe.js index 8227e9025..23ca369ba 100644 --- a/test/node/pipe.js +++ b/test/node/pipe.js @@ -1,23 +1,24 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - app = express(), - fs = require("fs"), - bodyParser = require("body-parser"); +'use strict'; +const request = require('../support/client'); +const express = require('../support/express'); + +const app = express(); +const fs = require('fs'); +const bodyParser = require('body-parser'); let http = require('http'); -if (process.env.HTTP2_TEST){ +if (process.env.HTTP2_TEST) { http = require('http2'); } app.use(bodyParser.json()); -app.get("/", (req, res) => { - fs.createReadStream("test/node/fixtures/user.json").pipe(res); +app.get('/', (req, res) => { + fs.createReadStream('test/node/fixtures/user.json').pipe(res); }); -app.post("/", (req, res) => { - if (process.env.HTTP2_TEST){ +app.post('/', (req, res) => { + if (process.env.HTTP2_TEST) { // body-parser does not support http2 yet. // This section can be remove after body-parser supporting http2. res.set('content-type', 'application/json'); @@ -27,7 +28,7 @@ app.post("/", (req, res) => { } }); -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { server = http.createServer(app); @@ -37,55 +38,55 @@ before(function listen(done) { }); }); -describe("request pipe", () => { - const destPath = "test/node/fixtures/tmp.json"; +describe('request pipe', () => { + const destPath = 'test/node/fixtures/tmp.json'; after(function removeTmpfile(done) { fs.unlink(destPath, done); }); - it("should act as a writable stream", done => { + it('should act as a writable stream', done => { const req = request.post(base); - const stream = fs.createReadStream("test/node/fixtures/user.json"); + const stream = fs.createReadStream('test/node/fixtures/user.json'); - req.type("json"); + req.type('json'); - req.on("response", res => { - res.body.should.eql({ name: "tobi" }); + req.on('response', res => { + res.body.should.eql({ name: 'tobi' }); done(); }); stream.pipe(req); }); - it("end() stops piping", done => { + it('end() stops piping', done => { const stream = fs.createWriteStream(destPath); - request.get(base) - .end((err, res) => { - try { - res.pipe(stream); - return done(Error("Did not prevent nonsense pipe")); - } catch(_e) { - /* expected error */ - } - done() - }); + request.get(base).end((err, res) => { + try { + res.pipe(stream); + return done(new Error('Did not prevent nonsense pipe')); + } catch (err2) { + /* expected error */ + } + + done(); + }); }); - it("should act as a readable stream", done => { + it('should act as a readable stream', done => { const stream = fs.createWriteStream(destPath); let responseCalled = false; const req = request.get(base); - req.type("json"); + req.type('json'); - req.on("response", res => { + req.on('response', res => { res.status.should.eql(200); responseCalled = true; }); - stream.on("finish", () => { - JSON.parse(fs.readFileSync(destPath, "utf8")).should.eql({ - name: "tobi", + stream.on('finish', () => { + JSON.parse(fs.readFileSync(destPath, 'utf8')).should.eql({ + name: 'tobi' }); responseCalled.should.be.true(); done(); diff --git a/test/node/query.js b/test/node/query.js index 7f1733a0c..1235fe715 100644 --- a/test/node/query.js +++ b/test/node/query.js @@ -1,35 +1,37 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - assert = require("assert"), - fs = require("fs"), - app = express(); +'use strict'; let http = require('http'); +const assert = require('assert'); +const fs = require('fs'); +const request = require('../support/client'); +const express = require('../support/express'); + +const app = express(); + if (process.env.HTTP2_TEST) { http = require('http2'); } -app.get("/raw-query", (req, res) => { +app.get('/raw-query', (req, res) => { res.status(200).send(req.url.substr(req.url.indexOf('?') + 1)); -}) +}); -app.get("/", (req, res) => { +app.get('/', (req, res) => { res.status(200).send(req.query); }); -app.delete("/url", (req, res) => { +app.delete('/url', (req, res) => { res.status(200).send(req.url); }); -app.delete("/", (req, res) => { +app.delete('/', (req, res) => { res.status(200).send(req.query); }); -app.put("/", (req, res) => { +app.put('/', (req, res) => { res.status(200).send(req.query); }); -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { server = http.createServer(app); @@ -39,115 +41,113 @@ before(function listen(done) { }); }); -describe("req.query(String)", () => { +describe('req.query(String)', () => { // This is no longer true as of qs v3.0.0 (https://github.com/ljharb/qs/commit/0c6f2a6318c94f6226d3cf7fe36094e9685042b6) // it('should supply uri malformed error to the callback') - it("should support passing in a string", done => { + it('should support passing in a string', done => { request .del(base) - .query("name=t%F6bi") + .query('name=t%F6bi') .end((err, res) => { - res.body.should.eql({ name: "t%F6bi" }); + res.body.should.eql({ name: 't%F6bi' }); done(); }); }); - it("should work with url query-string and string for query", done => { + it('should work with url query-string and string for query', done => { request .del(`${base}/?name=tobi`) - .query("age=2%20") + .query('age=2%20') .end((err, res) => { - res.body.should.eql({ name: "tobi", age: "2 " }); + res.body.should.eql({ name: 'tobi', age: '2 ' }); done(); }); }); - it("should support compound elements in a string", done => { + it('should support compound elements in a string', done => { request .del(base) - .query("name=t%F6bi&age=2") + .query('name=t%F6bi&age=2') .end((err, res) => { - res.body.should.eql({ name: "t%F6bi", age: "2" }); + res.body.should.eql({ name: 't%F6bi', age: '2' }); done(); }); }); - it("should work when called multiple times with a string", done => { + it('should work when called multiple times with a string', done => { request .del(base) - .query("name=t%F6bi") - .query("age=2%F6") + .query('name=t%F6bi') + .query('age=2%F6') .end((err, res) => { - res.body.should.eql({ name: "t%F6bi", age: "2%F6" }); + res.body.should.eql({ name: 't%F6bi', age: '2%F6' }); done(); }); }); - it("should work with normal `query` object and query string", done => { + it('should work with normal `query` object and query string', done => { request .del(base) - .query("name=t%F6bi") - .query({ age: "2" }) + .query('name=t%F6bi') + .query({ age: '2' }) .end((err, res) => { - res.body.should.eql({ name: "t%F6bi", age: "2" }); + res.body.should.eql({ name: 't%F6bi', age: '2' }); done(); }); }); - it("should not encode raw backticks, but leave encoded ones as is", () => { + it('should not encode raw backticks, but leave encoded ones as is', () => { return Promise.all([ request .get(`${base}/raw-query`) - .query("name=`t%60bi`&age`=2") + .query('name=`t%60bi`&age`=2') .then(res => { - res.text.should.eql("name=`t%60bi`&age`=2"); + res.text.should.eql('name=`t%60bi`&age`=2'); }), - request - .get(base + "/raw-query?`age%60`=2%60\`") - .then(res => { - res.text.should.eql("`age%60`=2%60`"); - }), + request.get(base + '/raw-query?`age%60`=2%60`').then(res => { + res.text.should.eql('`age%60`=2%60`'); + }), request .get(`${base}/raw-query`) - .query("name=`t%60bi`") - .query("age`=2") + .query('name=`t%60bi`') + .query('age`=2') .then(res => { - res.text.should.eql("name=`t%60bi`&age`=2"); + res.text.should.eql('name=`t%60bi`&age`=2'); }) ]); }); }); -describe("req.query(Object)", () => { - it("should construct the query-string", done => { +describe('req.query(Object)', () => { + it('should construct the query-string', done => { request .del(base) - .query({ name: "tobi" }) - .query({ order: "asc" }) - .query({ limit: ["1", "2"] }) + .query({ name: 'tobi' }) + .query({ order: 'asc' }) + .query({ limit: ['1', '2'] }) .end((err, res) => { - res.body.should.eql({ name: "tobi", order: "asc", limit: ["1", "2"] }); + res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] }); done(); }); }); // See commit message for the reasoning here. - it("should encode raw backticks", done => { + it('should encode raw backticks', done => { request .get(`${base}/raw-query`) - .query({ name: "`tobi`" }) - .query({ "orde%60r": null }) - .query({ "`limit`": ["%602`"] }) + .query({ name: '`tobi`' }) + .query({ 'orde%60r': null }) + .query({ '`limit`': ['%602`'] }) .end((err, res) => { - res.text.should.eql("name=%60tobi%60&orde%2560r&%60limit%60=%25602%60"); + res.text.should.eql('name=%60tobi%60&orde%2560r&%60limit%60=%25602%60'); done(); }); }); - it("should not error on dates", done => { + it('should not error on dates', done => { const date = new Date(0); request @@ -159,53 +159,53 @@ describe("req.query(Object)", () => { }); }); - it("should work after setting header fields", done => { + it('should work after setting header fields', done => { request .del(base) - .set("Foo", "bar") - .set("Bar", "baz") - .query({ name: "tobi" }) - .query({ order: "asc" }) - .query({ limit: ["1", "2"] }) + .set('Foo', 'bar') + .set('Bar', 'baz') + .query({ name: 'tobi' }) + .query({ order: 'asc' }) + .query({ limit: ['1', '2'] }) .end((err, res) => { - res.body.should.eql({ name: "tobi", order: "asc", limit: ["1", "2"] }); + res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] }); done(); }); }); - it("should append to the original query-string", done => { + it('should append to the original query-string', done => { request .del(`${base}/?name=tobi`) - .query({ order: "asc" }) + .query({ order: 'asc' }) .end((err, res) => { - res.body.should.eql({ name: "tobi", order: "asc" }); + res.body.should.eql({ name: 'tobi', order: 'asc' }); done(); }); }); - it("should retain the original query-string", done => { + it('should retain the original query-string', done => { request.del(`${base}/?name=tobi`).end((err, res) => { - res.body.should.eql({ name: "tobi" }); + res.body.should.eql({ name: 'tobi' }); done(); }); }); - it("should keep only keys with null querystring values", done => { + it('should keep only keys with null querystring values', done => { request .del(`${base}/url`) .query({ nil: null }) .end((err, res) => { - res.text.should.equal("/url?nil"); + res.text.should.equal('/url?nil'); done(); }); }); - it("query-string should be sent on pipe", done => { + it('query-string should be sent on pipe', done => { const req = request.put(`${base}/?name=tobi`); - const stream = fs.createReadStream("test/node/fixtures/user.json"); + const stream = fs.createReadStream('test/node/fixtures/user.json'); - req.on("response", res => { - res.body.should.eql({ name: "tobi" }); + req.on('response', res => { + res.body.should.eql({ name: 'tobi' }); done(); }); diff --git a/test/node/redirects-other-host.js b/test/node/redirects-other-host.js index cc318f722..b9b06a73d 100644 --- a/test/node/redirects-other-host.js +++ b/test/node/redirects-other-host.js @@ -1,16 +1,18 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - assert = require("assert"), - app = express(), - app2 = express(), - should = require("should"); +'use strict'; +const assert = require('assert'); +const request = require('../support/client'); +const express = require('../support/express'); + +const app = express(); +const app2 = express(); +const should = require('should'); let http = require('http'); + if (process.env.HTTP2_TEST) { http = require('http2'); } -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { server = http.createServer(app); @@ -20,7 +22,7 @@ before(function listen(done) { }); }); -let base2 = "http://localhost"; +let base2 = 'http://localhost'; let server2; before(function listen(done) { server2 = http.createServer(app2); @@ -30,176 +32,136 @@ before(function listen(done) { }); }); -app.all("/test-301", (req, res) => { +app.all('/test-301', (req, res) => { res.redirect(301, `${base2}/`); }); -app.all("/test-302", (req, res) => { +app.all('/test-302', (req, res) => { res.redirect(302, `${base2}/`); }); -app.all("/test-303", (req, res) => { +app.all('/test-303', (req, res) => { res.redirect(303, `${base2}/`); }); -app.all("/test-307", (req, res) => { +app.all('/test-307', (req, res) => { res.redirect(307, `${base2}/`); }); -app.all("/test-308", (req, res) => { +app.all('/test-308', (req, res) => { res.redirect(308, `${base2}/`); }); -app2.all("/", (req, res) => { +app2.all('/', (req, res) => { res.send(req.method); }); -describe("request.get", () => { - describe("on 301 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .get(`${base}/test-301`) - .redirects(1); +describe('request.get', () => { + describe('on 301 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.get(`${base}/test-301`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 302 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .get(`${base}/test-302`) - .redirects(1); + describe('on 302 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.get(`${base}/test-302`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 303 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .get(`${base}/test-303`) - .redirects(1); + describe('on 303 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.get(`${base}/test-303`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 307 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .get(`${base}/test-307`) - .redirects(1); + describe('on 307 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.get(`${base}/test-307`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 308 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .get(`${base}/test-308`) - .redirects(1); + describe('on 308 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.get(`${base}/test-308`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); }); -describe("request.post", () => { - describe("on 301 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .post(`${base}/test-301`) - .redirects(1); +describe('request.post', () => { + describe('on 301 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.post(`${base}/test-301`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 302 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .post(`${base}/test-302`) - .redirects(1); + describe('on 302 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.post(`${base}/test-302`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 303 redirect", () => { - it("should follow Location with a GET request", done => { - const req = request - .post(`${base}/test-303`) - .redirects(1); + describe('on 303 redirect', () => { + it('should follow Location with a GET request', done => { + const req = request.post(`${base}/test-303`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("GET"); + res.text.should.eql('GET'); done(); }); }); }); - describe("on 307 redirect", () => { - it("should follow Location with a POST request", done => { - const req = request - .post(`${base}/test-307`) - .redirects(1); + describe('on 307 redirect', () => { + it('should follow Location with a POST request', done => { + const req = request.post(`${base}/test-307`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("POST"); + res.text.should.eql('POST'); done(); }); }); }); - describe("on 308 redirect", () => { - it("should follow Location with a POST request", done => { - const req = request - .post(`${base}/test-308`) - .redirects(1); + describe('on 308 redirect', () => { + it('should follow Location with a POST request', done => { + const req = request.post(`${base}/test-308`).redirects(1); req.end((err, res) => { - req.req._headers.host.should.eql( - `localhost:${server2.address().port}` - ); + req.req._headers.host.should.eql(`localhost:${server2.address().port}`); res.status.should.eql(200); - res.text.should.eql("POST"); + res.text.should.eql('POST'); done(); }); }); diff --git a/test/node/redirects.js b/test/node/redirects.js index 49a28429a..173cb61f1 100644 --- a/test/node/redirects.js +++ b/test/node/redirects.js @@ -1,125 +1,115 @@ -"use strict"; -const setup = require("../support/setup"); -const base = setup.uri; +'use strict'; -const URL = require("url"); -const assert = require("assert"); -const request = require("../support/client"); +const URL = require('url'); +const assert = require('assert'); +const setup = require('../support/setup'); +const request = require('../support/client'); -describe("request", () => { - describe("on redirect", () => { +const base = setup.uri; +describe('request', () => { + describe('on redirect', () => { it('should merge cookies if agent is used', done => { request - .agent() - .get(`${base}/cookie-redirect`) - .set('Cookie', 'orig=1; replaced=not') - .end((err, res) => { - try { - assert.ifError(err); - assert(/orig=1/.test(res.text), "orig=1/.test"); - assert(/replaced=yes/.test(res.text), "replaced=yes/.test"); - assert(/from-redir=1/.test(res.text), "from-redir=1"); - done(); - } catch(err) { - done(err); - } - }); - }) + .agent() + .get(`${base}/cookie-redirect`) + .set('Cookie', 'orig=1; replaced=not') + .end((err, res) => { + try { + assert.ifError(err); + assert(/orig=1/.test(res.text), 'orig=1/.test'); + assert(/replaced=yes/.test(res.text), 'replaced=yes/.test'); + assert(/from-redir=1/.test(res.text), 'from-redir=1'); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should not merge cookies if agent is not used', done => { request - .get(`${base}/cookie-redirect`) - .set('Cookie', 'orig=1; replaced=not') - .end((err, res) => { - try { - assert.ifError(err); - assert(/orig=1/.test(res.text), "/orig=1"); - assert(/replaced=not/.test(res.text), "/replaced=not"); - assert(!/replaced=yes/.test(res.text), "!/replaced=yes"); - assert(!/from-redir/.test(res.text), "!/from-redir"); - done(); - } catch(err) { - done(err); - } - }); - }) - - it("should have previously set cookie for subsquent requests when agent is used", done => { - const agent = request.agent(); - agent - .get(`${base}/set-cookie`) - .end((err) => { - assert.ifError(err); - agent - .get(`${base}/show-cookies`) - .set({'Cookie': 'orig=1'}) + .get(`${base}/cookie-redirect`) + .set('Cookie', 'orig=1; replaced=not') .end((err, res) => { try { assert.ifError(err); - assert(/orig=1/.test(res.text), "orig=1/.test"); - assert(/persist=123/.test(res.text), "persist=123"); + assert(/orig=1/.test(res.text), '/orig=1'); + assert(/replaced=not/.test(res.text), '/replaced=not'); + assert(!/replaced=yes/.test(res.text), '!/replaced=yes'); + assert(!/from-redir/.test(res.text), '!/from-redir'); done(); - } catch(err) { - done(err); + } catch (err2) { + done(err2); } }); + }); + + it('should have previously set cookie for subsquent requests when agent is used', done => { + const agent = request.agent(); + agent.get(`${base}/set-cookie`).end(err => { + assert.ifError(err); + agent + .get(`${base}/show-cookies`) + .set({ Cookie: 'orig=1' }) + .end((err, res) => { + try { + assert.ifError(err); + assert(/orig=1/.test(res.text), 'orig=1/.test'); + assert(/persist=123/.test(res.text), 'persist=123'); + done(); + } catch (err2) { + done(err2); + } + }); }); - }) + }); - it("should follow Location", done => { + it('should follow Location', done => { const redirects = []; request .get(base) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .end((err, res) => { try { - const arr = [ - "/movies", - "/movies/all", - "/movies/all/0", - ]; + const arr = ['/movies', '/movies/all', '/movies/all/0']; redirects.should.eql(arr); - res.text.should.equal("first movie page"); + res.text.should.equal('first movie page'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should follow Location with IP override", () => { + it('should follow Location with IP override', () => { const redirects = []; const url = URL.parse(base); return request .get(`http://redir.example.com:${url.port || '80'}${url.pathname}`) .connect({ - '*': url.hostname, + '*': url.hostname }) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .then(res => { - const arr = [ - "/movies", - "/movies/all", - "/movies/all/0", - ]; + const arr = ['/movies', '/movies/all', '/movies/all/0']; redirects.should.eql(arr); - res.text.should.equal("first movie page"); + res.text.should.equal('first movie page'); }); }); - it("should not follow on HEAD by default", () => { + it('should not follow on HEAD by default', () => { const redirects = []; return request .head(base) .ok(() => true) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .then(res => { @@ -128,204 +118,204 @@ describe("request", () => { }); }); - it("should follow on HEAD when redirects are set", done => { + it('should follow on HEAD when redirects are set', done => { const redirects = []; request .head(base) .redirects(10) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .end((err, res) => { try { const arr = []; - arr.push("/movies"); - arr.push("/movies/all"); - arr.push("/movies/all/0"); + arr.push('/movies'); + arr.push('/movies/all'); + arr.push('/movies/all/0'); redirects.should.eql(arr); assert(!res.text); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should remove Content-* fields", done => { + it('should remove Content-* fields', done => { request .post(`${base}/header`) - .type("txt") - .set("X-Foo", "bar") - .set("X-Bar", "baz") - .send("hey") + .type('txt') + .set('X-Foo', 'bar') + .set('X-Bar', 'baz') + .send('hey') .end((err, res) => { try { assert(res.body); - res.body.should.have.property("x-foo", "bar"); - res.body.should.have.property("x-bar", "baz"); - res.body.should.not.have.property("content-type"); - res.body.should.not.have.property("content-length"); - res.body.should.not.have.property("transfer-encoding"); + res.body.should.have.property('x-foo', 'bar'); + res.body.should.have.property('x-bar', 'baz'); + res.body.should.not.have.property('content-type'); + res.body.should.not.have.property('content-length'); + res.body.should.not.have.property('transfer-encoding'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should retain cookies", done => { + it('should retain cookies', done => { request .get(`${base}/header`) - .set("Cookie", "foo=bar;") + .set('Cookie', 'foo=bar;') .end((err, res) => { try { assert(res.body); - res.body.should.have.property("cookie", "foo=bar;"); + res.body.should.have.property('cookie', 'foo=bar;'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should not resend query parameters", done => { + it('should not resend query parameters', done => { const redirects = []; const query = []; request .get(`${base}/?foo=bar`) - .on("redirect", res => { + .on('redirect', res => { query.push(res.headers.query); redirects.push(res.headers.location); }) .end((err, res) => { try { const arr = []; - arr.push("/movies"); - arr.push("/movies/all"); - arr.push("/movies/all/0"); + arr.push('/movies'); + arr.push('/movies/all'); + arr.push('/movies/all/0'); redirects.should.eql(arr); - res.text.should.equal("first movie page"); + res.text.should.equal('first movie page'); - query.should.eql(['{"foo":"bar"}', "{}", "{}"]); - res.headers.query.should.eql("{}"); + query.should.eql(['{"foo":"bar"}', '{}', '{}']); + res.headers.query.should.eql('{}'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should handle no location header", done => { + it('should handle no location header', done => { request.get(`${base}/bad-redirect`).end((err, res) => { try { - err.message.should.equal("No location header for redirect"); + err.message.should.equal('No location header for redirect'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - describe("when relative", () => { - it("should redirect to a sibling path", done => { + describe('when relative', () => { + it('should redirect to a sibling path', done => { const redirects = []; request .get(`${base}/relative`) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .end((err, res) => { try { - redirects.should.eql(["tobi"]); - res.text.should.equal("tobi"); + redirects.should.eql(['tobi']); + res.text.should.equal('tobi'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); - it("should redirect to a parent path", done => { + it('should redirect to a parent path', done => { const redirects = []; request .get(`${base}/relative/sub`) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .end((err, res) => { try { - redirects.should.eql(["../tobi"]); - res.text.should.equal("tobi"); + redirects.should.eql(['../tobi']); + res.text.should.equal('tobi'); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); }); }); - describe("req.redirects(n)", () => { - it("should alter the default number of redirects to follow", done => { + describe('req.redirects(n)', () => { + it('should alter the default number of redirects to follow', done => { const redirects = []; request .get(base) .redirects(2) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .end((err, res) => { try { const arr = []; - assert(res.redirect, "res.redirect"); - arr.push("/movies"); - arr.push("/movies/all"); + assert(res.redirect, 'res.redirect'); + arr.push('/movies'); + arr.push('/movies/all'); redirects.should.eql(arr); res.text.should.match(/Moved Temporarily|Found/); done(); - } catch (err) { - done(err); + } catch (err2) { + done(err2); } }); }); }); - describe("on POST", () => { - it("should redirect as GET", () => { + describe('on POST', () => { + it('should redirect as GET', () => { const redirects = []; return request .post(`${base}/movie`) - .send({ name: "Tobi" }) + .send({ name: 'Tobi' }) .redirects(2) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .then(res => { - redirects.should.eql(["/movies/all/0"]); - res.text.should.equal("first movie page"); + redirects.should.eql(['/movies/all/0']); + res.text.should.equal('first movie page'); }); }); - it("using multipart/form-data should redirect as GET", () => { + it('using multipart/form-data should redirect as GET', () => { const redirects = []; request .post(`${base}/movie`) - .type("form") - .field("name", "Tobi") + .type('form') + .field('name', 'Tobi') .redirects(2) - .on("redirect", res => { + .on('redirect', res => { redirects.push(res.headers.location); }) .then(res => { - redirects.should.eql(["/movies/all/0"]); - res.text.should.equal("first movie page"); + redirects.should.eql(['/movies/all/0']); + res.text.should.equal('first movie page'); }); }); }); diff --git a/test/node/response-readable-stream.js b/test/node/response-readable-stream.js index bc0e75d80..5c15df4e1 100644 --- a/test/node/response-readable-stream.js +++ b/test/node/response-readable-stream.js @@ -1,18 +1,20 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - app = express(), - fs = require("fs"); +'use strict'; +const request = require('../support/client'); +const express = require('../support/express'); + +const app = express(); +const fs = require('fs'); let http = require('http'); + if (process.env.HTTP2_TEST) { http = require('http2'); } -app.get("/", (req, res) => { - fs.createReadStream("test/node/fixtures/user.json").pipe(res); +app.get('/', (req, res) => { + fs.createReadStream('test/node/fixtures/user.json').pipe(res); }); -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { server = http.createServer(app); @@ -22,8 +24,8 @@ before(function listen(done) { }); }); -describe("response", () => { - it("should act as a readable stream", done => { +describe('response', () => { + it('should act as a readable stream', done => { const req = request.get(base).buffer(false); req.end((err, res) => { @@ -31,16 +33,17 @@ describe("response", () => { let trackEndEvent = 0; let trackCloseEvent = 0; - res.on("end", () => { + res.on('end', () => { trackEndEvent++; trackEndEvent.should.equal(1); if (!process.env.HTTP2_TEST) { trackCloseEvent.should.equal(0); // close should not have been called } + done(); }); - res.on("close", () => { + res.on('close', () => { trackCloseEvent++; }); diff --git a/test/node/serialize.js b/test/node/serialize.js index f3f0f6393..cb72cad1d 100644 --- a/test/node/serialize.js +++ b/test/node/serialize.js @@ -1,15 +1,16 @@ -"use strict"; +'use strict'; + +const request = require('../support/client'); +const setup = require('../support/setup'); -const request = require("../support/client"); -const setup = require("../support/setup"); const base = setup.uri; -const assert = require("assert"); +const assert = require('assert'); -describe("req.serialize(fn)", () => { - it("should take precedence over default parsers", done => { +describe('req.serialize(fn)', () => { + it('should take precedence over default parsers', done => { request .post(`${base}/echo`) - .send({foo:123}) + .send({ foo: 123 }) .serialize(data => '{"bar":456}') .end((err, res) => { assert.ifError(err); diff --git a/test/node/set-host.js b/test/node/set-host.js index 495646f3a..9d44e7826 100644 --- a/test/node/set-host.js +++ b/test/node/set-host.js @@ -1,14 +1,16 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - app = express(); -let http = require('http'); -let assert = require('assert'); +'use strict'; +const request = require('../support/client'); +const express = require('../support/express'); -describe("request.get().set()", () => { +const app = express(); +const http = require('http'); +const assert = require('assert'); + +describe('request.get().set()', () => { if (process.env.HTTP2_TEST) { return; // request object doesn't look the same } + let server; after(function exitServer() { @@ -19,15 +21,14 @@ describe("request.get().set()", () => { } }); - it("should set host header after get()", done => { - app.get("/", (req, res) => { + it('should set host header after get()', done => { + app.get('/', (req, res) => { assert.equal(req.hostname, 'example.com'); res.end(); }); server = http.createServer(app); server.listen(0, function listening() { - request .get(`http://localhost:${server.address().port}`) .set('host', 'example.com') @@ -35,8 +36,8 @@ describe("request.get().set()", () => { return request .get(`http://example.com:${server.address().port}`) .connect({ - "example.com": "localhost", - "*": "fail", + 'example.com': 'localhost', + '*': 'fail' }); }) .then(() => done(), done); diff --git a/test/node/toError.js b/test/node/toError.js index d8186be0b..5069f8893 100644 --- a/test/node/toError.js +++ b/test/node/toError.js @@ -1,18 +1,20 @@ -"use strict"; -const request = require("../support/client"), - express = require("../support/express"), - assert = require("assert"), - app = express(); +'use strict'; +const assert = require('assert'); +const request = require('../support/client'); +const express = require('../support/express'); + +const app = express(); let http = require('http'); + if (process.env.HTTP2_TEST) { http = require('http2'); } -app.get("/", (req, res) => { - res.status(400).send("invalid json"); +app.get('/', (req, res) => { + res.status(400).send('invalid json'); }); -let base = "http://localhost"; +let base = 'http://localhost'; let server; before(function listen(done) { server = http.createServer(app); @@ -22,15 +24,15 @@ before(function listen(done) { }); }); -describe("res.toError()", () => { - it("should return an Error", done => { +describe('res.toError()', () => { + it('should return an Error', done => { request.get(base).end((err, res) => { var err = res.toError(); assert.equal(err.status, 400); - assert.equal(err.method, "GET"); - assert.equal(err.path, "/"); - assert.equal(err.message, "cannot GET / (400)"); - assert.equal(err.text, "invalid json"); + assert.equal(err.method, 'GET'); + assert.equal(err.path, '/'); + assert.equal(err.message, 'cannot GET / (400)'); + assert.equal(err.text, 'invalid json'); done(); }); }); diff --git a/test/node/unix-sockets.js b/test/node/unix-sockets.js index aa8a09496..e9608e820 100644 --- a/test/node/unix-sockets.js +++ b/test/node/unix-sockets.js @@ -1,17 +1,20 @@ -"use strict"; -const request = require("../support/client"); -const express = require("../support/express"); -const assert = require("assert"); +'use strict'; +const assert = require('assert'); + +let http = require('http'); +let https = require('https'); +const os = require('os'); +const fs = require('fs'); +const express = require('../support/express'); +const request = require('../support/client'); + const app = express(); -let http = require("http"); -let https = require("https"); -const os = require("os"); -const fs = require("fs"); + const key = fs.readFileSync(`${__dirname}/fixtures/key.pem`); const cert = fs.readFileSync(`${__dirname}/fixtures/cert.pem`); const cacert = fs.readFileSync(`${__dirname}/fixtures/ca.cert.pem`); -const httpSockPath = [os.tmpdir(), "superagent-http.sock"].join("/"); -const httpsSockPath = [os.tmpdir(), "superagent-https.sock"].join("/"); +const httpSockPath = [os.tmpdir(), 'superagent-http.sock'].join('/'); +const httpsSockPath = [os.tmpdir(), 'superagent-https.sock'].join('/'); let httpServer; let httpsServer; @@ -19,16 +22,16 @@ if (process.env.HTTP2_TEST) { http = https = require('http2'); } -app.get("/", (req, res) => { - res.send("root ok!"); +app.get('/', (req, res) => { + res.send('root ok!'); }); -app.get("/request/path", (req, res) => { - res.send("request path ok!"); +app.get('/request/path', (req, res) => { + res.send('request path ok!'); }); -describe("[unix-sockets] http", () => { - if (process.platform === "win32") { +describe('[unix-sockets] http', () => { + if (process.platform === 'win32') { return; } @@ -37,25 +40,26 @@ describe("[unix-sockets] http", () => { // try unlink if sock file exists fs.unlinkSync(httpSockPath); } + httpServer = http.createServer(app); httpServer.listen(httpSockPath, done); }); - const base = `http+unix://${httpSockPath.replace(/\//g, "%2F")}`; + const base = `http+unix://${httpSockPath.replace(/\//g, '%2F')}`; - describe("request", () => { - it("path: / (root)", done => { + describe('request', () => { + it('path: / (root)', done => { request.get(`${base}/`).end((err, res) => { assert(res.ok); - assert.strictEqual("root ok!", res.text); + assert.strictEqual('root ok!', res.text); done(); }); }); - it("path: /request/path", done => { + it('path: /request/path', done => { request.get(`${base}/request/path`).end((err, res) => { assert(res.ok); - assert.strictEqual("request path ok!", res.text); + assert.strictEqual('request path ok!', res.text); done(); }); }); @@ -64,13 +68,12 @@ describe("[unix-sockets] http", () => { after(() => { if (typeof httpServer.close === 'function') { httpServer.close(); - } else - httpServer.destroy(); + } else httpServer.destroy(); }); }); -describe("[unix-sockets] https", () => { - if (process.platform === "win32") { +describe('[unix-sockets] https', () => { + if (process.platform === 'win32') { return; } @@ -79,37 +82,39 @@ describe("[unix-sockets] https", () => { // try unlink if sock file exists fs.unlinkSync(httpsSockPath); } + if (process.env.HTTP2_TEST) { httpsServer = https.createSecureServer({ key, cert }, app); } else { httpsServer = https.createServer({ key, cert }, app); } + httpsServer.listen(httpsSockPath, done); }); - const base = `https+unix://${httpsSockPath.replace(/\//g, "%2F")}`; + const base = `https+unix://${httpsSockPath.replace(/\//g, '%2F')}`; - describe("request", () => { - it("path: / (root)", done => { + describe('request', () => { + it('path: / (root)', done => { request .get(`${base}/`) .ca(cacert) .end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("root ok!", res.text); + assert.strictEqual('root ok!', res.text); done(); }); }); - it("path: /request/path", done => { + it('path: /request/path', done => { request .get(`${base}/request/path`) .ca(cacert) .end((err, res) => { assert.ifError(err); assert(res.ok); - assert.strictEqual("request path ok!", res.text); + assert.strictEqual('request path ok!', res.text); done(); }); }); diff --git a/test/node/user-agent.js b/test/node/user-agent.js index 9ceb9c398..1254419a4 100644 --- a/test/node/user-agent.js +++ b/test/node/user-agent.js @@ -1,36 +1,37 @@ -"use strict"; -const assert = require("assert"); -const request = require("../support/client"); -const setup = require("../support/setup"); +'use strict'; +const assert = require('assert'); +const request = require('../support/client'); +const setup = require('../support/setup'); + const base = setup.uri; -describe("req.get()", () => { - it("should set a default user-agent", () => +describe('req.get()', () => { + it('should set a default user-agent', () => request.get(`${base}/ua`).then(res => { assert(res.headers); - assert(res.headers["user-agent"]); + assert(res.headers['user-agent']); assert( /^node-superagent\/\d+\.\d+\.\d+(?:-[a-z]+\.\d+|$)/.test( - res.headers["user-agent"] + res.headers['user-agent'] ) ); })); - it("should be able to override user-agent", () => + it('should be able to override user-agent', () => request .get(`${base}/ua`) - .set("User-Agent", "foo/bar") + .set('User-Agent', 'foo/bar') .then(res => { assert(res.headers); - assert.equal(res.headers["user-agent"], "foo/bar"); + assert.equal(res.headers['user-agent'], 'foo/bar'); })); - it("should be able to wipe user-agent", () => + it('should be able to wipe user-agent', () => request .get(`${base}/ua`) - .unset("User-Agent") + .unset('User-Agent') .then(res => { assert(res.headers); - assert.equal(res.headers["user-agent"], void 0); + assert.equal(res.headers['user-agent'], void 0); })); }); diff --git a/test/node/utils.js b/test/node/utils.js index fc6da7b8e..23ae2d529 100644 --- a/test/node/utils.js +++ b/test/node/utils.js @@ -1,37 +1,37 @@ -"use strict"; -const assert = require("assert"); -const utils = require("../../lib/utils"); +'use strict'; +const assert = require('assert'); +const utils = require('../../lib/utils'); -describe("utils.type(str)", () => { - it("should return the mime type", () => { +describe('utils.type(str)', () => { + it('should return the mime type', () => { utils - .type("application/json; charset=utf-8") - .should.equal("application/json"); + .type('application/json; charset=utf-8') + .should.equal('application/json'); - utils.type("application/json").should.equal("application/json"); + utils.type('application/json').should.equal('application/json'); }); }); -describe("utils.params(str)", () => { - it("should return the field parameters", () => { - const obj = utils.params("application/json; charset=utf-8; foo = bar"); - obj.charset.should.equal("utf-8"); - obj.foo.should.equal("bar"); +describe('utils.params(str)', () => { + it('should return the field parameters', () => { + const obj = utils.params('application/json; charset=utf-8; foo = bar'); + obj.charset.should.equal('utf-8'); + obj.foo.should.equal('bar'); - utils.params("application/json").should.eql({}); + utils.params('application/json').should.eql({}); }); }); -describe("utils.parseLinks(str)", () => { - it("should parse links", () => { +describe('utils.parseLinks(str)', () => { + it('should parse links', () => { const str = '; rel="next", ; rel="last"'; const ret = utils.parseLinks(str); ret.next.should.equal( - "https://api.github.com/repos/visionmedia/mocha/issues?page=2" + 'https://api.github.com/repos/visionmedia/mocha/issues?page=2' ); ret.last.should.equal( - "https://api.github.com/repos/visionmedia/mocha/issues?page=5" + 'https://api.github.com/repos/visionmedia/mocha/issues?page=5' ); }); }); diff --git a/test/redirects.js b/test/redirects.js index 30037bfc9..dd944e02e 100644 --- a/test/redirects.js +++ b/test/redirects.js @@ -1,131 +1,134 @@ const setup = require('./support/setup'); + const base = setup.uri; const isMSIE = !setup.NODE && /Trident\//.test(navigator.userAgent); const assert = require('assert'); const request = require('./support/client'); -describe('request', function(){ +describe('request', function() { this.timeout(20000); describe('on redirect', () => { it('should retain header fields', done => { request - .get(`${base}/header`) - .set('X-Foo', 'bar') - .end((err, res) => { - try { - assert(res.body); - res.body.should.have.property('x-foo', 'bar'); - done(); - } catch(err) { - done(err); - } - }); - }) + .get(`${base}/header`) + .set('X-Foo', 'bar') + .end((err, res) => { + try { + assert(res.body); + res.body.should.have.property('x-foo', 'bar'); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should preserve timeout across redirects', done => { request - .get(`${base}/movies/random`) - .timeout(250) - .end((err, res) => { - try { - assert(err instanceof Error, 'expected an error'); - err.should.have.property('timeout', 250); - done(); - } catch(err) { - done(err); - } - }); - }) + .get(`${base}/movies/random`) + .timeout(250) + .end((err, res) => { + try { + assert(err instanceof Error, 'expected an error'); + err.should.have.property('timeout', 250); + done(); + } catch (err2) { + done(err2); + } + }); + }); it('should successfully redirect after retry on error', done => { const id = Math.random() * 1000000 * Date.now(); request - .get(`${base}/error/redirect/${id}`) - .retry(2) - .end((err, res) => { - assert(res.ok, 'response should be ok'); - assert(res.text, 'first movie page'); - done(); - }); + .get(`${base}/error/redirect/${id}`) + .retry(2) + .end((err, res) => { + assert(res.ok, 'response should be ok'); + assert(res.text, 'first movie page'); + done(); + }); }); it('should preserve retries across redirects', done => { const id = Math.random() * 1000000 * Date.now(); request - .get(`${base}/error/redirect-error${id}`) - .retry(2) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal(2, err.retries, 'expected an error with .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - }); - + .get(`${base}/error/redirect-error${id}`) + .retry(2) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal(2, err.retries, 'expected an error with .retries'); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + }); }); }); describe('on 303', () => { it('should redirect with same method', done => { request - .put(`${base}/redirect-303`) - .send({msg: "hello"}) - .redirects(1) - .on('redirect', res => { - res.headers.location.should.equal('/reply-method') - }) - .end((err, res) => { - if (err) { - done(err); - return; - } - res.text.should.equal('method=get'); - done(); - }) - }) - }) + .put(`${base}/redirect-303`) + .send({ msg: 'hello' }) + .redirects(1) + .on('redirect', res => { + res.headers.location.should.equal('/reply-method'); + }) + .end((err, res) => { + if (err) { + done(err); + return; + } + + res.text.should.equal('method=get'); + done(); + }); + }); + }); describe('on 307', () => { it('should redirect with same method', done => { if (isMSIE) return done(); // IE9 broken request - .put(`${base}/redirect-307`) - .send({msg: "hello"}) - .redirects(1) - .on('redirect', res => { - res.headers.location.should.equal('/reply-method') - }) - .end((err, res) => { - if (err) { - done(err); - return; - } - res.text.should.equal('method=put'); - done(); - }) - }) - }) + .put(`${base}/redirect-307`) + .send({ msg: 'hello' }) + .redirects(1) + .on('redirect', res => { + res.headers.location.should.equal('/reply-method'); + }) + .end((err, res) => { + if (err) { + done(err); + return; + } + + res.text.should.equal('method=put'); + done(); + }); + }); + }); describe('on 308', () => { it('should redirect with same method', done => { if (isMSIE) return done(); // IE9 broken request - .put(`${base}/redirect-308`) - .send({msg: "hello"}) - .redirects(1) - .on('redirect', res => { - res.headers.location.should.equal('/reply-method') - }) - .end((err, res) => { - if (err) { - done(err); - return; - } - res.text.should.equal('method=put'); - done(); - }) - }) - }) -}) + .put(`${base}/redirect-308`) + .send({ msg: 'hello' }) + .redirects(1) + .on('redirect', res => { + res.headers.location.should.equal('/reply-method'); + }) + .end((err, res) => { + if (err) { + done(err); + return; + } + + res.text.should.equal('method=put'); + done(); + }); + }); + }); +}); diff --git a/test/request.js b/test/request.js index 7b470df65..9e5bc2f56 100644 --- a/test/request.js +++ b/test/request.js @@ -1,801 +1,967 @@ const setup = require('./support/setup'); -const uri = setup.uri; + +const { uri } = setup; const assert = require('assert'); const request = require('./support/client'); describe('request', function() { this.timeout(20000); -it('Request inheritance', () => { - assert(request.get(`${uri}/`) instanceof request.Request); -}); - -it('request() simple GET without callback', next => { - request('GET', 'test/test.request.js').end(); - next(); -}); - -it('request() simple GET', next => { - request('GET', `${uri}/ok`).end((err, res) => { - try { - assert(res instanceof request.Response, 'respond with Response'); - assert(res.ok, 'response should be ok'); - assert(res.text, 'res.text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() simple HEAD', next => { - request.head(`${uri}/ok`).end((err, res) => { - try { - assert(res instanceof request.Response, 'respond with Response'); - assert(res.ok, 'response should be ok'); - assert(!res.text, 'res.text'); - next(); - } catch(e) { next(e); } - }); -}); - - -it('request() GET 5xx', next => { - request('GET', `${uri}/error`).end((err, res) => { - try { - assert(err); - assert.equal(err.message, 'Internal Server Error'); - assert(!res.ok, 'response should not be ok'); - assert(res.error, 'response should be an error'); - assert(!res.clientError, 'response should not be a client error'); - assert(res.serverError, 'response should be a server error'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() GET 4xx', next => { - request('GET', `${uri}/notfound`).end((err, res) => { - try { - assert(err); - assert.equal(err.message, 'Not Found'); - assert(!res.ok, 'response should not be ok'); - assert(res.error, 'response should be an error'); - assert(res.clientError, 'response should be a client error'); - assert(!res.serverError, 'response should not be a server error'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() GET 404 Not Found', next => { - request('GET', `${uri}/notfound`).end((err, res) => { - try { - assert(err); - assert(res.notFound, 'response should be .notFound'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() GET 400 Bad Request', next => { - request('GET', `${uri}/bad-request`).end((err, res) => { - try { - assert(err); - assert(res.badRequest, 'response should be .badRequest'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() GET 401 Bad Request', next => { - request('GET', `${uri}/unauthorized`).end((err, res) => { - try { - assert(err); - assert(res.unauthorized, 'response should be .unauthorized'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() GET 406 Not Acceptable', next => { - request('GET', `${uri}/not-acceptable`).end((err, res) => { - try { - assert(err); - assert(res.notAcceptable, 'response should be .notAcceptable'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() GET 204 No Content', next => { - request('GET', `${uri}/no-content`).end((err, res) => { - try { - assert.ifError(err); - assert(res.noContent, 'response should be .noContent'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() DELETE 204 No Content', next => { - request('DELETE', `${uri}/no-content`).end((err, res) => { - try { - assert.ifError(err); - assert(res.noContent, 'response should be .noContent'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() header parsing', next => { - request('GET', `${uri}/notfound`).end((err, res) => { - try { - assert(err); - assert.equal('text/html; charset=utf-8', res.header['content-type']); - assert.equal('Express', res.header['x-powered-by']); - next(); - } catch(e) { next(e); } - }); -}); - -it('request() .status', next => { - request('GET', `${uri}/notfound`).end((err, res) => { - try { - assert(err); - assert.equal(404, res.status, 'response .status'); - assert.equal(4, res.statusType, 'response .statusType'); - next(); - } catch(e) { next(e); } - }); -}); - -it('get()', next => { - request.get( `${uri}/notfound`).end((err, res) => { - try { - assert(err); - assert.equal(404, res.status, 'response .status'); - assert.equal(4, res.statusType, 'response .statusType'); - next(); - } catch(e) { next(e); } - }); -}); - - -it('put()', next => { - request.put(`${uri}/user/12`).end((err, res) => { - try { - assert.equal('updated', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('put().send()', next => { - request.put(`${uri}/user/13/body`).send({user:"new"}).end((err, res) => { - try { - assert.equal('received new', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('post()', next => { - request.post(`${uri}/user`).end((err, res) => { - try { - assert.equal('created', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('del()', next => { - request.del(`${uri}/user/12`).end((err, res) => { - try { - assert.equal('deleted', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('delete()', next => { - request['delete'](`${uri}/user/12`).end((err, res) => { - try { - assert.equal('deleted', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('post() data', next => { - request.post(`${uri}/todo/item`) - .type('application/octet-stream') - .send('tobi') - .end((err, res) => { - try { - assert.equal('added "tobi"', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .type()', next => { - request - .post(`${uri}/user/12/pet`) - .type('urlencoded') - .send('pet=tobi') - .end((err, res) => { - try { - assert.equal('added pet "tobi"', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .type() with alias', next => { - request - .post(`${uri}/user/12/pet`) - .type('application/x-www-form-urlencoded') - .send('pet=tobi') - .end((err, res) => { - try { - assert.equal('added pet "tobi"', res.text, 'response text'); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .get() with no data or callback', next => { - request.get(`${uri}/echo-header/content-type`); - next(); -}); - -it('request .send() with no data only', next => { - request.post(`${uri}/user/5/pet`).type('urlencoded').send('pet=tobi'); - next(); -}); - -it('request .send() with callback only', next => { - request - .get(`${uri}/echo-header/accept`) - .set('Accept', 'foo/bar') - .end((err, res) => { - try { - assert.equal('foo/bar', res.text); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .accept() with json', next => { - request - .get(`${uri}/echo-header/accept`) - .accept('json') - .end((err, res) => { - try { - assert.equal('application/json', res.text); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .accept() with application/json', next => { - request - .get(`${uri}/echo-header/accept`) - .accept('application/json') - .end((err, res) => { - try { - assert.equal('application/json', res.text); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .accept() with xml', next => { - request - .get(`${uri}/echo-header/accept`) - .accept('xml') - .end((err, res) => { - try { - // We can't depend on mime module to be consistent with this - assert(res.text == "application/xml" || res.text == "text/xml"); - next(); - } catch(e) { next(e); } - }); -}); - -it('request .accept() with application/xml', next => { - request - .get(`${uri}/echo-header/accept`) - .accept('application/xml') - .end((err, res) => { - try { - assert.equal('application/xml', res.text); - next(); - } catch(e) { next(e); } + it('Request inheritance', () => { + assert(request.get(`${uri}/`) instanceof request.Request); }); -}); - -// FIXME: ie6 will POST rather than GET here due to data(), -// but I'm not 100% sure why. Newer IEs are OK. -it('request .end()', next => { - request - .put(`${uri}/echo-header/content-type`) - .set('Content-Type', 'text/plain') - .send('wahoo') - .end((err, res) => { - try { - assert.equal('text/plain', res.text); + it('request() simple GET without callback', next => { + request('GET', 'test/test.request.js').end(); next(); - } catch(e) { next(e); } }); -}); -it('request .send()', next => { - request - .put(`${uri}/echo-header/content-type`) - .set('Content-Type', 'text/plain') - .send('wahoo') - .end((err, res) => { - try { - assert.equal('text/plain', res.text); - next(); - } catch(e) { next(e); } + it('request() simple GET', next => { + request('GET', `${uri}/ok`).end((err, res) => { + try { + assert(res instanceof request.Response, 'respond with Response'); + assert(res.ok, 'response should be ok'); + assert(res.text, 'res.text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('request .set()', next => { - request - .put(`${uri}/echo-header/content-type`) - .set('Content-Type', 'text/plain') - .send('wahoo') - .end((err, res) => { - try { - assert.equal('text/plain', res.text); - next(); - } catch(e) { next(e); } + it('request() simple HEAD', next => { + request.head(`${uri}/ok`).end((err, res) => { + try { + assert(res instanceof request.Response, 'respond with Response'); + assert(res.ok, 'response should be ok'); + assert(!res.text, 'res.text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('request .set(object)', next => { - request - .put(`${uri}/echo-header/content-type`) - .set({ 'Content-Type': 'text/plain' }) - .send('wahoo') - .end((err, res) => { - try { - assert.equal('text/plain', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 5xx', next => { + request('GET', `${uri}/error`).end((err, res) => { + try { + assert(err); + assert.equal(err.message, 'Internal Server Error'); + assert(!res.ok, 'response should not be ok'); + assert(res.error, 'response should be an error'); + assert(!res.clientError, 'response should not be a client error'); + assert(res.serverError, 'response should be a server error'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST urlencoded', next => { - request - .post(`${uri}/pet`) - .type('urlencoded') - .send({ name: 'Manny', species: 'cat' }) - .end((err, res) => { - try { - assert.equal('added Manny the cat', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 4xx', next => { + request('GET', `${uri}/notfound`).end((err, res) => { + try { + assert(err); + assert.equal(err.message, 'Not Found'); + assert(!res.ok, 'response should not be ok'); + assert(res.error, 'response should be an error'); + assert(res.clientError, 'response should be a client error'); + assert(!res.serverError, 'response should not be a server error'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST json', next => { - request - .post(`${uri}/pet`) - .type('json') - .send({ name: 'Manny', species: 'cat' }) - .end((err, res) => { - try { - assert.equal('added Manny the cat', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 404 Not Found', next => { + request('GET', `${uri}/notfound`).end((err, res) => { + try { + assert(err); + assert(res.notFound, 'response should be .notFound'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST json array', next => { - request - .post(`${uri}/echo`) - .send([1,2,3]) - .end((err, res) => { - try { - assert.equal('application/json', res.header['content-type'].split(';')[0]); - assert.equal('[1,2,3]', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 400 Bad Request', next => { + request('GET', `${uri}/bad-request`).end((err, res) => { + try { + assert(err); + assert(res.badRequest, 'response should be .badRequest'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST json default', next => { - request - .post(`${uri}/pet`) - .send({ name: 'Manny', species: 'cat' }) - .end((err, res) => { - try { - assert.equal('added Manny the cat', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 401 Bad Request', next => { + request('GET', `${uri}/unauthorized`).end((err, res) => { + try { + assert(err); + assert(res.unauthorized, 'response should be .unauthorized'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST json contentType charset', next => { - request - .post(`${uri}/echo`) - .set('Content-Type', 'application/json; charset=UTF-8') - .send({ data: ['data1', 'data2'] }) - .end((err, res) => { - try { - assert.equal('{"data":["data1","data2"]}', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 406 Not Acceptable', next => { + request('GET', `${uri}/not-acceptable`).end((err, res) => { + try { + assert(err); + assert(res.notAcceptable, 'response should be .notAcceptable'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST json contentType vendor', next => { - request - .post(`${uri}/echo`) - .set('Content-Type', 'application/vnd.example+json') - .send({ data: ['data1', 'data2'] }) - .end((err, res) => { - try { - assert.equal('{"data":["data1","data2"]}', res.text); - next(); - } catch(e) { next(e); } + it('request() GET 204 No Content', next => { + request('GET', `${uri}/no-content`).end((err, res) => { + try { + assert.ifError(err); + assert(res.noContent, 'response should be .noContent'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST multiple .send() calls', next => { - request - .post(`${uri}/pet`) - .send({ name: 'Manny' }) - .send({ species: 'cat' }) - .end((err, res) => { - try { - assert.equal('added Manny the cat', res.text); - next(); - } catch(e) { next(e); } + it('request() DELETE 204 No Content', next => { + request('DELETE', `${uri}/no-content`).end((err, res) => { + try { + assert.ifError(err); + assert(res.noContent, 'response should be .noContent'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); - -it('POST multiple .send() strings', next => { - request - .post(`${uri}/echo`) - .send('user[name]=tj') - .send('user[email]=tj@vision-media.ca') - .end((err, res) => { - try { - assert.equal('application/x-www-form-urlencoded', res.header['content-type'].split(';')[0]); - assert.equal(res.text, 'user[name]=tj&user[email]=tj@vision-media.ca') - next(); - } catch(e) { next(e); } - }) -}); -it('POST with no data', next => { - request - .post(`${uri}/empty-body`) - .send().end((err, res) => { - try { - assert.ifError(err); - assert(res.noContent, 'response should be .noContent'); - next(); - } catch(e) { next(e); } + it('request() header parsing', next => { + request('GET', `${uri}/notfound`).end((err, res) => { + try { + assert(err); + assert.equal('text/html; charset=utf-8', res.header['content-type']); + assert.equal('Express', res.header['x-powered-by']); + next(); + } catch (err2) { + next(err2); + } }); -}); - -it('GET .type', next => { - request - .get(`${uri}/pets`) - .end((err, res) => { - try { - assert.equal('application/json', res.type); - next(); - } catch(e) { next(e); } }); -}); -it('GET Content-Type params', next => { - request - .get(`${uri}/text`) - .end((err, res) => { - try { - assert.equal('utf-8', res.charset); - next(); - } catch(e) { next(e); } + it('request() .status', next => { + request('GET', `${uri}/notfound`).end((err, res) => { + try { + assert(err); + assert.equal(404, res.status, 'response .status'); + assert.equal(4, res.statusType, 'response .statusType'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET json', next => { - request - .get(`${uri}/pets`) - .end((err, res) => { - try { - assert.deepEqual(res.body, ['tobi', 'loki', 'jane']); - next(); - } catch(e) { next(e); } + it('get()', next => { + request.get(`${uri}/notfound`).end((err, res) => { + try { + assert(err); + assert.equal(404, res.status, 'response .status'); + assert.equal(4, res.statusType, 'response .statusType'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET json-seq', next => { - request - .get(`${uri}/json-seq`) - .buffer() - .end((err, res) => { - try{ - assert.ifError(err); - assert.deepEqual(res.text, '\x1e{"id":1}\n\x1e{"id":2}\n'); - next(); - } catch(e) { next(e); } + it('put()', next => { + request.put(`${uri}/user/12`).end((err, res) => { + try { + assert.equal('updated', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET x-www-form-urlencoded', next => { - request - .get(`${uri}/foo`) - .end((err, res) => { - try { - assert.deepEqual(res.body, { foo: 'bar' }); - next(); - } catch(e) { next(e); } + it('put().send()', next => { + request + .put(`${uri}/user/13/body`) + .send({ user: 'new' }) + .end((err, res) => { + try { + assert.equal('received new', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET shorthand', next => { - request.get(`${uri}/foo`, (err, res) => { - try { - assert.equal('foo=bar', res.text); - next(); - } catch(e) { next(e); } + it('post()', next => { + request.post(`${uri}/user`).end((err, res) => { + try { + assert.equal('created', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST shorthand', next => { - request.post(`${uri}/user/0/pet`, { pet: 'tobi' }, (err, res) => { - try { - assert.equal('added pet "tobi"', res.text); - next(); - } catch(e) { next(e); } + it('del()', next => { + request.del(`${uri}/user/12`).end((err, res) => { + try { + assert.equal('deleted', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('POST shorthand without callback', next => { - request.post(`${uri}/user/0/pet`, { pet: 'tobi' }).end((err, res) => { - try { - assert.equal('added pet "tobi"', res.text); - next(); - } catch(e) { next(e); } + it('delete()', next => { + request.delete(`${uri}/user/12`).end((err, res) => { + try { + assert.equal('deleted', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring object with array', next => { - request - .get(`${uri}/querystring`) - .query({ val: ['a', 'b', 'c'] }) - .end((err, res) => { - try { - assert.deepEqual(res.body, { val: ['a', 'b', 'c'] }); - next(); - } catch(e) { next(e); } + it('post() data', next => { + request + .post(`${uri}/todo/item`) + .type('application/octet-stream') + .send('tobi') + .end((err, res) => { + try { + assert.equal('added "tobi"', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .type()', next => { + request + .post(`${uri}/user/12/pet`) + .type('urlencoded') + .send('pet=tobi') + .end((err, res) => { + try { + assert.equal('added pet "tobi"', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .type() with alias', next => { + request + .post(`${uri}/user/12/pet`) + .type('application/x-www-form-urlencoded') + .send('pet=tobi') + .end((err, res) => { + try { + assert.equal('added pet "tobi"', res.text, 'response text'); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .get() with no data or callback', next => { + request.get(`${uri}/echo-header/content-type`); + next(); + }); + + it('request .send() with no data only', next => { + request + .post(`${uri}/user/5/pet`) + .type('urlencoded') + .send('pet=tobi'); + next(); + }); + + it('request .send() with callback only', next => { + request + .get(`${uri}/echo-header/accept`) + .set('Accept', 'foo/bar') + .end((err, res) => { + try { + assert.equal('foo/bar', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .accept() with json', next => { + request + .get(`${uri}/echo-header/accept`) + .accept('json') + .end((err, res) => { + try { + assert.equal('application/json', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .accept() with application/json', next => { + request + .get(`${uri}/echo-header/accept`) + .accept('application/json') + .end((err, res) => { + try { + assert.equal('application/json', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .accept() with xml', next => { + request + .get(`${uri}/echo-header/accept`) + .accept('xml') + .end((err, res) => { + try { + // We can't depend on mime module to be consistent with this + assert(res.text == 'application/xml' || res.text == 'text/xml'); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .accept() with application/xml', next => { + request + .get(`${uri}/echo-header/accept`) + .accept('application/xml') + .end((err, res) => { + try { + assert.equal('application/xml', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + // FIXME: ie6 will POST rather than GET here due to data(), + // but I'm not 100% sure why. Newer IEs are OK. + it('request .end()', next => { + request + .put(`${uri}/echo-header/content-type`) + .set('Content-Type', 'text/plain') + .send('wahoo') + .end((err, res) => { + try { + assert.equal('text/plain', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .send()', next => { + request + .put(`${uri}/echo-header/content-type`) + .set('Content-Type', 'text/plain') + .send('wahoo') + .end((err, res) => { + try { + assert.equal('text/plain', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .set()', next => { + request + .put(`${uri}/echo-header/content-type`) + .set('Content-Type', 'text/plain') + .send('wahoo') + .end((err, res) => { + try { + assert.equal('text/plain', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('request .set(object)', next => { + request + .put(`${uri}/echo-header/content-type`) + .set({ 'Content-Type': 'text/plain' }) + .send('wahoo') + .end((err, res) => { + try { + assert.equal('text/plain', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST urlencoded', next => { + request + .post(`${uri}/pet`) + .type('urlencoded') + .send({ name: 'Manny', species: 'cat' }) + .end((err, res) => { + try { + assert.equal('added Manny the cat', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST json', next => { + request + .post(`${uri}/pet`) + .type('json') + .send({ name: 'Manny', species: 'cat' }) + .end((err, res) => { + try { + assert.equal('added Manny the cat', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST json array', next => { + request + .post(`${uri}/echo`) + .send([1, 2, 3]) + .end((err, res) => { + try { + assert.equal( + 'application/json', + res.header['content-type'].split(';')[0] + ); + assert.equal('[1,2,3]', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST json default', next => { + request + .post(`${uri}/pet`) + .send({ name: 'Manny', species: 'cat' }) + .end((err, res) => { + try { + assert.equal('added Manny the cat', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST json contentType charset', next => { + request + .post(`${uri}/echo`) + .set('Content-Type', 'application/json; charset=UTF-8') + .send({ data: ['data1', 'data2'] }) + .end((err, res) => { + try { + assert.equal('{"data":["data1","data2"]}', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST json contentType vendor', next => { + request + .post(`${uri}/echo`) + .set('Content-Type', 'application/vnd.example+json') + .send({ data: ['data1', 'data2'] }) + .end((err, res) => { + try { + assert.equal('{"data":["data1","data2"]}', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST multiple .send() calls', next => { + request + .post(`${uri}/pet`) + .send({ name: 'Manny' }) + .send({ species: 'cat' }) + .end((err, res) => { + try { + assert.equal('added Manny the cat', res.text); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST multiple .send() strings', next => { + request + .post(`${uri}/echo`) + .send('user[name]=tj') + .send('user[email]=tj@vision-media.ca') + .end((err, res) => { + try { + assert.equal( + 'application/x-www-form-urlencoded', + res.header['content-type'].split(';')[0] + ); + assert.equal( + res.text, + 'user[name]=tj&user[email]=tj@vision-media.ca' + ); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('POST with no data', next => { + request + .post(`${uri}/empty-body`) + .send() + .end((err, res) => { + try { + assert.ifError(err); + assert(res.noContent, 'response should be .noContent'); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET .type', next => { + request.get(`${uri}/pets`).end((err, res) => { + try { + assert.equal('application/json', res.type); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring object with array and primitives', next => { - request - .get(`${uri}/querystring`) - .query({ array: ['a', 'b', 'c'], string: 'foo', number: 10 }) - .end((err, res) => { - try { - assert.deepEqual(res.body, { array: ['a', 'b', 'c'], string: 'foo', number: 10 }); - next(); - } catch(e) { next(e); } + it('GET Content-Type params', next => { + request.get(`${uri}/text`).end((err, res) => { + try { + assert.equal('utf-8', res.charset); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring object with two arrays', next => { - request - .get(`${uri}/querystring`) - .query({ array1: ['a', 'b', 'c'], array2: [1, 2, 3]}) - .end((err, res) => { - try { - assert.deepEqual(res.body, { array1: ['a', 'b', 'c'], array2: [1, 2, 3]}); - next(); - } catch(e) { next(e); } + it('GET json', next => { + request.get(`${uri}/pets`).end((err, res) => { + try { + assert.deepEqual(res.body, ['tobi', 'loki', 'jane']); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring object', next => { - request - .get(`${uri}/querystring`) - .query({ search: 'Manny' }) - .end((err, res) => { - try { - assert.deepEqual(res.body, { search: 'Manny' }); - next(); - } catch(e) { next(e); } + it('GET json-seq', next => { + request + .get(`${uri}/json-seq`) + .buffer() + .end((err, res) => { + try { + assert.ifError(err); + assert.deepEqual(res.text, '\u001E{"id":1}\n\u001E{"id":2}\n'); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring append original', next => { - request - .get(`${uri}/querystring?search=Manny`) - .query({ range: '1..5' }) - .end((err, res) => { - try { - assert.deepEqual(res.body, { search: 'Manny', range: '1..5' }); - next(); - } catch(e) { next(e); } + it('GET x-www-form-urlencoded', next => { + request.get(`${uri}/foo`).end((err, res) => { + try { + assert.deepEqual(res.body, { foo: 'bar' }); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring multiple objects', next => { - request - .get(`${uri}/querystring`) - .query({ search: 'Manny' }) - .query({ range: '1..5' }) - .query({ order: 'desc' }) - .end((err, res) => { - try { - assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' }); - next(); - } catch(e) { next(e); } + it('GET shorthand', next => { + request.get(`${uri}/foo`, (err, res) => { + try { + assert.equal('foo=bar', res.text); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring with strings', next => { - request - .get(`${uri}/querystring`) - .query('search=Manny') - .query('range=1..5') - .query('order=desc') - .end((err, res) => { - try { - assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' }); - next(); - } catch(e) { next(e); } + it('POST shorthand', next => { + request.post(`${uri}/user/0/pet`, { pet: 'tobi' }, (err, res) => { + try { + assert.equal('added pet "tobi"', res.text); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET querystring with strings and objects', next => { - request - .get(`${uri}/querystring`) - .query('search=Manny') - .query({ order: 'desc', range: '1..5' }) - .end((err, res) => { - try { - assert.deepEqual(res.body, { search: 'Manny', range: '1..5', order: 'desc' }); - next(); - } catch(e) { next(e); } + it('POST shorthand without callback', next => { + request.post(`${uri}/user/0/pet`, { pet: 'tobi' }).end((err, res) => { + try { + assert.equal('added pet "tobi"', res.text); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('GET shorthand payload goes to querystring', next => { - request - .get(`${uri}/querystring`, {foo: 'FOO', bar: 'BAR'}, (err, res) => { - try { - assert.deepEqual(res.body, { foo: 'FOO', bar: 'BAR' }); - next(); - } catch(e) { next(e); } + it('GET querystring object with array', next => { + request + .get(`${uri}/querystring`) + .query({ val: ['a', 'b', 'c'] }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { val: ['a', 'b', 'c'] }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring object with array and primitives', next => { + request + .get(`${uri}/querystring`) + .query({ array: ['a', 'b', 'c'], string: 'foo', number: 10 }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { + array: ['a', 'b', 'c'], + string: 'foo', + number: 10 + }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring object with two arrays', next => { + request + .get(`${uri}/querystring`) + .query({ array1: ['a', 'b', 'c'], array2: [1, 2, 3] }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { + array1: ['a', 'b', 'c'], + array2: [1, 2, 3] + }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring object', next => { + request + .get(`${uri}/querystring`) + .query({ search: 'Manny' }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { search: 'Manny' }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring append original', next => { + request + .get(`${uri}/querystring?search=Manny`) + .query({ range: '1..5' }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { search: 'Manny', range: '1..5' }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring multiple objects', next => { + request + .get(`${uri}/querystring`) + .query({ search: 'Manny' }) + .query({ range: '1..5' }) + .query({ order: 'desc' }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { + search: 'Manny', + range: '1..5', + order: 'desc' + }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring with strings', next => { + request + .get(`${uri}/querystring`) + .query('search=Manny') + .query('range=1..5') + .query('order=desc') + .end((err, res) => { + try { + assert.deepEqual(res.body, { + search: 'Manny', + range: '1..5', + order: 'desc' + }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET querystring with strings and objects', next => { + request + .get(`${uri}/querystring`) + .query('search=Manny') + .query({ order: 'desc', range: '1..5' }) + .end((err, res) => { + try { + assert.deepEqual(res.body, { + search: 'Manny', + range: '1..5', + order: 'desc' + }); + next(); + } catch (err2) { + next(err2); + } + }); + }); + + it('GET shorthand payload goes to querystring', next => { + request.get( + `${uri}/querystring`, + { foo: 'FOO', bar: 'BAR' }, + (err, res) => { + try { + assert.deepEqual(res.body, { foo: 'FOO', bar: 'BAR' }); + next(); + } catch (err2) { + next(err2); + } + } + ); + }); + + it('HEAD shorthand payload goes to querystring', next => { + request.head( + `${uri}/querystring-in-header`, + { foo: 'FOO', bar: 'BAR' }, + (err, res) => { + try { + assert.deepEqual(JSON.parse(res.headers.query), { + foo: 'FOO', + bar: 'BAR' + }); + next(); + } catch (err2) { + next(err2); + } + } + ); + }); + + it('request(method, url)', next => { + request('GET', `${uri}/foo`).end((err, res) => { + try { + assert.equal('bar', res.body.foo); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('HEAD shorthand payload goes to querystring', next => { - request - .head(`${uri}/querystring-in-header`, {foo: 'FOO', bar: 'BAR'}, (err, res) => { - try { - assert.deepEqual(JSON.parse(res.headers.query), { foo: 'FOO', bar: 'BAR' }); - next(); - } catch(e) { next(e); } + it('request(url)', next => { + request(`${uri}/foo`).end((err, res) => { + try { + assert.equal('bar', res.body.foo); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('request(method, url)', next => { - request('GET', `${uri}/foo`).end((err, res) => { - try { - assert.equal('bar', res.body.foo); - next(); - } catch(e) { next(e); } + it('request(url, fn)', next => { + request(`${uri}/foo`, (err, res) => { + try { + assert.equal('bar', res.body.foo); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('request(url)', next => { - request(`${uri}/foo`).end((err, res) => { - try { - assert.equal('bar', res.body.foo); - next(); - } catch(e) { next(e); } + it('req.timeout(ms)', next => { + const req = request.get(`${uri}/delay/3000`).timeout(1000); + req.end((err, res) => { + try { + assert(err, 'error missing'); + assert.equal(1000, err.timeout, 'err.timeout missing'); + assert.equal( + 'Timeout of 1000ms exceeded', + err.message, + 'err.message incorrect' + ); + assert.equal(null, res); + assert(req.timedout, true); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('request(url, fn)', next => { - request(`${uri}/foo`, (err, res) => { - try { - assert.equal('bar', res.body.foo); - next(); - } catch(e) { next(e); } + it('req.timeout(ms) with redirect', next => { + const req = request.get(`${uri}/delay/const`).timeout(1000); + req.end((err, res) => { + try { + assert(err, 'error missing'); + assert.equal(1000, err.timeout, 'err.timeout missing'); + assert.equal( + 'Timeout of 1000ms exceeded', + err.message, + 'err.message incorrect' + ); + assert.equal(null, res); + assert(req.timedout, true); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); -it('req.timeout(ms)', next => { - const req = request - .get(`${uri}/delay/3000`) - .timeout(1000); - req.end((err, res) => { - try { - assert(err, 'error missing'); - assert.equal(1000, err.timeout, 'err.timeout missing'); - assert.equal('Timeout of 1000ms exceeded', err.message, 'err.message incorrect'); - assert.equal(null, res); - assert(req.timedout, true); - next(); - } catch(e) { next(e); } - }); -}) - -it('req.timeout(ms) with redirect', next => { - const req = request - .get(`${uri}/delay/const`) - .timeout(1000); - req.end((err, res) => { - try { - assert(err, 'error missing'); - assert.equal(1000, err.timeout, 'err.timeout missing'); - assert.equal('Timeout of 1000ms exceeded', err.message, 'err.message incorrect'); - assert.equal(null, res); - assert(req.timedout, true); - next(); - } catch(e) { next(e); } + it('request event', next => { + request + .get(`${uri}/foo`) + .on('request', req => { + try { + assert.equal(`${uri}/foo`, req.url); + next(); + } catch (err) { + next(err); + } + }) + .end(); + }); + + it('response event', next => { + request + .get(`${uri}/foo`) + .on('response', res => { + try { + assert.equal('bar', res.body.foo); + next(); + } catch (err) { + next(err); + } + }) + .end(); + }); + + it('response should set statusCode', next => { + request.get(`${uri}/ok`, (err, res) => { + try { + assert.strictEqual(res.statusCode, 200); + next(); + } catch (err2) { + next(err2); + } + }); }); -}); - -it('request event', next => { - request - .get(`${uri}/foo`) - .on('request', req => { - try { - assert.equal(`${uri}/foo`, req.url); - next(); - } catch(e) { next(e); } - }) - .end(); -}); - -it('response event', next => { - request - .get(`${uri}/foo`) - .on('response', res => { - try { - assert.equal('bar', res.body.foo); - next(); - } catch(e) { next(e); } - }) - .end(); -}); - -it('response should set statusCode', next => { - request - .get(`${uri}/ok`, (err, res) => { + it('req.toJSON()', next => { + request.get(`${uri}/ok`).end((err, res) => { try { - assert.strictEqual(res.statusCode, 200); - next(); - } catch(e) { next(e); } - }) -}); - -it('req.toJSON()', next => { - request - .get(`${uri}/ok`) - .end((err, res) => { - try { - const j = (res.request || res.req).toJSON(); - ['url', 'method', 'data', 'headers'].forEach(prop => { - assert(j.hasOwnProperty(prop)); + const j = (res.request || res.req).toJSON(); + ['url', 'method', 'data', 'headers'].forEach(prop => { + assert(j.hasOwnProperty(prop)); + }); + next(); + } catch (err2) { + next(err2); + } }); - next(); - } catch(e) { next(e); } }); }); - -}); diff --git a/test/retry.js b/test/retry.js index 56ae043b1..634e68316 100644 --- a/test/retry.js +++ b/test/retry.js @@ -1,4 +1,5 @@ const setup = require('./support/setup'); + const base = setup.uri; const assert = require('assert'); const request = require('./support/client'); @@ -7,170 +8,188 @@ function uniqid() { return Math.random() * 10000000; } -describe('.retry(count)', function(){ +describe('.retry(count)', function() { this.timeout(15000); it('should not retry if passed "0"', done => { request - .get(`${base}/error`) - .retry(0) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(undefined, err.retries, 'expected an error without .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry(0) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal( + undefined, + err.retries, + 'expected an error without .retries' + ); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should not retry if passed an invalid number', done => { request - .get(`${base}/error`) - .retry(-2) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(undefined, err.retries, 'expected an error without .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry(-2) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal( + undefined, + err.retries, + 'expected an error without .retries' + ); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should not retry if passed undefined', done => { request - .get(`${base}/error`) - .retry(undefined) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(undefined, err.retries, 'expected an error without .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry(undefined) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal( + undefined, + err.retries, + 'expected an error without .retries' + ); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should handle server error after repeat attempt', done => { request - .get(`${base}/error`) - .retry(2) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(2, err.retries, 'expected an error with .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry(2) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal(2, err.retries, 'expected an error with .retries'); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should retry if passed nothing', done => { request - .get(`${base}/error`) - .retry() - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(1, err.retries, 'expected an error with .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry() + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal(1, err.retries, 'expected an error with .retries'); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should retry if passed "true"', done => { request - .get(`${base}/error`) - .retry(true) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(1, err.retries, 'expected an error with .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry(true) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal(1, err.retries, 'expected an error with .retries'); + assert.equal(500, err.status, 'expected an error status of 500'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should handle successful request after repeat attempt from server error', done => { request - .get(`${base}/error/ok/${uniqid()}`) - .query({qs:'present'}) - .retry(2) - .end((err, res) => { - try { - assert.ifError(err); - assert(res.ok, 'response should be ok'); - assert(res.text, 'res.text'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error/ok/${uniqid()}`) + .query({ qs: 'present' }) + .retry(2) + .end((err, res) => { + try { + assert.ifError(err); + assert(res.ok, 'response should be ok'); + assert(res.text, 'res.text'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should handle server timeout error after repeat attempt', done => { request - .get(`${base}/delay/400`) - .timeout(200) - .retry(2) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(2, err.retries, 'expected an error with .retries'); - assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/delay/400`) + .timeout(200) + .retry(2) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal(2, err.retries, 'expected an error with .retries'); + assert.equal( + 'number', + typeof err.timeout, + 'expected an error with .timeout' + ); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should handle successful request after repeat attempt from server timeout', done => { const url = `/delay/1200/ok/${uniqid()}?built=in`; request - .get(base + url) - .query("string=ified") - .query({"json":"ed"}) - .timeout(600) - .retry(2) - .end((err, res) => { - try { - assert.ifError(err); - assert(res.ok, 'response should be ok'); - assert.equal(res.text, `ok = ${url}&string=ified&json=ed`); - done(); - } catch(err) { - done(err); - } - }); + .get(base + url) + .query('string=ified') + .query({ json: 'ed' }) + .timeout(600) + .retry(2) + .end((err, res) => { + try { + assert.ifError(err); + assert(res.ok, 'response should be ok'); + assert.equal(res.text, `ok = ${url}&string=ified&json=ed`); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should correctly abort a retry attempt', done => { let aborted = false; const req = request - .get(`${base}/delay/400`) - .timeout(200) - .retry(2); + .get(`${base}/delay/400`) + .timeout(200) + .retry(2); req.end((err, res) => { try { assert(false, 'should not complete the request'); - } catch(e) { done(e); } + } catch (err2) { + done(err2); + } }); req.on('abort', () => { @@ -181,47 +200,47 @@ describe('.retry(count)', function(){ req.abort(); setTimeout(() => { try { - assert(aborted, 'should be aborted'); - done(); - } catch(err) { + assert(aborted, 'should be aborted'); + done(); + } catch (err) { done(err); } - }, 150) + }, 150); }, 150); }); it('should correctly retain header fields', done => { request - .get(`${base}/error/ok/${uniqid()}`) - .query({qs:'present'}) - .retry(2) - .set('X-Foo', 'bar') - .end((err, res) => { - try { - assert.ifError(err); - assert(res.body); - res.body.should.have.property('x-foo', 'bar'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error/ok/${uniqid()}`) + .query({ qs: 'present' }) + .retry(2) + .set('X-Foo', 'bar') + .end((err, res) => { + try { + assert.ifError(err); + assert(res.body); + res.body.should.have.property('x-foo', 'bar'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should not retry on 4xx responses', done => { request - .get(`${base}/bad-request`) - .retry(2) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(0, err.retries, 'expected an error with 0 .retries'); - assert.equal(400, err.status, 'expected an error status of 400'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/bad-request`) + .retry(2) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal(0, err.retries, 'expected an error with 0 .retries'); + assert.equal(400, err.status, 'expected an error status of 400'); + done(); + } catch (err2) { + done(err2); + } + }); }); it('should execute callback on retry if passed', done => { @@ -229,19 +248,24 @@ describe('.retry(count)', function(){ function retryCallback(request) { callbackCallCount++; } + request - .get(`${base}/error`) - .retry(2, retryCallback) - .end((err, res) => { - try { - assert(err, 'expected an error'); - assert.equal(2, err.retries, 'expected an error with .retries'); - assert.equal(500, err.status, 'expected an error status of 500'); - assert.equal(2, callbackCallCount, 'expected the callback to be called on each retry'); - done(); - } catch(err) { - done(err); - } - }); + .get(`${base}/error`) + .retry(2, retryCallback) + .end((err, res) => { + try { + assert(err, 'expected an error'); + assert.equal(2, err.retries, 'expected an error with .retries'); + assert.equal(500, err.status, 'expected an error status of 500'); + assert.equal( + 2, + callbackCallCount, + 'expected the callback to be called on each retry' + ); + done(); + } catch (err2) { + done(err2); + } + }); }); -}) +}); diff --git a/test/support/express/index.js b/test/support/express/index.js index 478bfbbc3..49a3e5007 100644 --- a/test/support/express/index.js +++ b/test/support/express/index.js @@ -1,7 +1,8 @@ const express = require('express'); + let http2Req; let http2Res; -if(process.env.HTTP2_TEST){ +if (process.env.HTTP2_TEST) { const http2 = require('http2'); const reqDecorator = require('./requestDecorator'); const resDecorator = require('./responseDecorator'); @@ -9,9 +10,9 @@ if(process.env.HTTP2_TEST){ http2Res = resDecorator(Object.create(http2.Http2ServerResponse.prototype)); } -function createApp(){ +function createApp() { const app = express(); - if(process.env.HTTP2_TEST){ + if (process.env.HTTP2_TEST) { app.request = Object.create(http2Req, { app: { configurable: true, enumerable: true, writable: true, value: app } }); @@ -19,7 +20,8 @@ function createApp(){ app: { configurable: true, enumerable: true, writable: true, value: app } }); } + return app; } -module.exports = createApp; \ No newline at end of file +module.exports = createApp; diff --git a/test/support/express/requestDecorator.js b/test/support/express/requestDecorator.js index 540ca10a2..4f15ecf49 100644 --- a/test/support/express/requestDecorator.js +++ b/test/support/express/requestDecorator.js @@ -13,13 +13,13 @@ * @private */ -var accepts = require('accepts'); -var isIP = require('net').isIP; -var typeis = require('type-is'); -var fresh = require('fresh'); -var parseRange = require('range-parser'); -var parse = require('parseurl'); -var proxyaddr = require('proxy-addr'); +const accepts = require('accepts'); +const { isIP } = require('net'); +const typeis = require('type-is'); +const fresh = require('fresh'); +const parseRange = require('range-parser'); +const parse = require('parseurl'); +const proxyaddr = require('proxy-addr'); /** * Request prototype. @@ -34,7 +34,6 @@ var proxyaddr = require('proxy-addr'); module.exports = setMethods; function setMethods(req) { - /** * Return request header. * @@ -59,27 +58,25 @@ function setMethods(req) { * @public */ - req.get = - req.header = function header(name) { - if (!name) { - throw new TypeError('name argument is required to req.get'); - } + req.get = req.header = function header(name) { + if (!name) { + throw new TypeError('name argument is required to req.get'); + } - if (typeof name !== 'string') { - throw new TypeError('name must be a string to req.get'); - } + if (typeof name !== 'string') { + throw new TypeError('name must be a string to req.get'); + } - var lc = name.toLowerCase(); + const lc = name.toLowerCase(); - switch (lc) { - case 'referer': - case 'referrer': - return this.headers.referrer - || this.headers.referer; - default: - return this.headers[lc]; - } - }; + switch (lc) { + case 'referer': + case 'referrer': + return this.headers.referrer || this.headers.referer; + default: + return this.headers[lc]; + } + }; /** * To do: update docs. @@ -127,8 +124,8 @@ function setMethods(req) { * @public */ - req.accepts = function () { - var accept = accepts(this); + req.accepts = function() { + const accept = accepts(this); return accept.types.apply(accept, arguments); }; @@ -140,8 +137,8 @@ function setMethods(req) { * @public */ - req.acceptsEncodings = function () { - var accept = accepts(this); + req.acceptsEncodings = function() { + const accept = accepts(this); return accept.encodings.apply(accept, arguments); }; @@ -154,8 +151,8 @@ function setMethods(req) { * @public */ - req.acceptsCharsets = function () { - var accept = accepts(this); + req.acceptsCharsets = function() { + const accept = accepts(this); return accept.charsets.apply(accept, arguments); }; @@ -168,8 +165,8 @@ function setMethods(req) { * @public */ - req.acceptsLanguages = function () { - var accept = accepts(this); + req.acceptsLanguages = function() { + const accept = accepts(this); return accept.languages.apply(accept, arguments); }; @@ -199,7 +196,7 @@ function setMethods(req) { */ req.range = function range(size, options) { - var range = this.get('Range'); + const range = this.get('Range'); if (!range) return; return parseRange(size, range, options); }; @@ -214,15 +211,15 @@ function setMethods(req) { * @api public */ - defineGetter(req, 'query', function query(){ - var queryparse = this.app.get('query parser fn'); + defineGetter(req, 'query', function query() { + const queryparse = this.app.get('query parser fn'); if (!queryparse) { // parsing is disabled return Object.create(null); } - var querystring = parse(this).query; + const querystring = parse(this).query; return queryparse(querystring); }); @@ -254,12 +251,12 @@ function setMethods(req) { */ req.is = function is(types) { - var arr = types; + let arr = types; // support flattened arguments if (!Array.isArray(types)) { arr = new Array(arguments.length); - for (var i = 0; i < arr.length; i++) { + for (let i = 0; i < arr.length; i++) { arr[i] = arguments[i]; } } @@ -282,10 +279,8 @@ function setMethods(req) { */ defineGetter(req, 'protocol', function protocol() { - var proto = this.connection.encrypted - ? 'https' - : 'http'; - var trust = this.app.get('trust proxy fn'); + const proto = this.connection.encrypted ? 'https' : 'http'; + const trust = this.app.get('trust proxy fn'); if (!trust(this.connection.remoteAddress, 0)) { return proto; @@ -293,12 +288,10 @@ function setMethods(req) { // Note: X-Forwarded-Proto is normally only ever a // single value, but this is to be safe. - var header = this.get('X-Forwarded-Proto') || proto - var index = header.indexOf(',') + const header = this.get('X-Forwarded-Proto') || proto; + const index = header.indexOf(','); - return index !== -1 - ? header.substring(0, index).trim() - : header.trim() + return index !== -1 ? header.substring(0, index).trim() : header.trim(); }); /** @@ -325,7 +318,7 @@ function setMethods(req) { */ defineGetter(req, 'ip', function ip() { - var trust = this.app.get('trust proxy fn'); + const trust = this.app.get('trust proxy fn'); return proxyaddr(this, trust); }); @@ -342,14 +335,14 @@ function setMethods(req) { */ defineGetter(req, 'ips', function ips() { - var trust = this.app.get('trust proxy fn'); - var addrs = proxyaddr.all(this, trust); + const trust = this.app.get('trust proxy fn'); + const addrs = proxyaddr.all(this, trust); // reverse the order (to farthest -> closest) // and remove socket address - addrs.reverse().pop() + addrs.reverse().pop(); - return addrs + return addrs; }); /** @@ -368,12 +361,12 @@ function setMethods(req) { */ defineGetter(req, 'subdomains', function subdomains() { - var hostname = this.hostname; + const { hostname } = this; if (!hostname) return []; - var offset = this.app.get('subdomain offset'); - var subdomains = !isIP(hostname) + const offset = this.app.get('subdomain offset'); + const subdomains = !isIP(hostname) ? hostname.split('.').reverse() : [hostname]; @@ -403,8 +396,8 @@ function setMethods(req) { */ defineGetter(req, 'host', function host() { - var trust = this.app.get('trust proxy fn'); - var val = this.get('X-Forwarded-Host'); + const trust = this.app.get('trust proxy fn'); + let val = this.get('X-Forwarded-Host'); if (!val || !trust(this.connection.remoteAddress, 0)) { val = this.get('Host'); @@ -424,20 +417,16 @@ function setMethods(req) { * @api public */ - defineGetter(req, 'hostname', function hostname(){ - var host = this.host; + defineGetter(req, 'hostname', function hostname() { + const { host } = this; if (!host) return; // IPv6 literal support - var offset = host[0] === '[' - ? host.indexOf(']') + 1 - : 0; - var index = host.indexOf(':', offset); - - return index !== -1 - ? host.substring(0, index) - : host; + const offset = host[0] === '[' ? host.indexOf(']') + 1 : 0; + const index = host.indexOf(':', offset); + + return index !== -1 ? host.substring(0, index) : host; }); /** @@ -449,20 +438,20 @@ function setMethods(req) { * @public */ - defineGetter(req, 'fresh', function () { - var method = this.method; - var res = this.res - var status = res.statusCode + defineGetter(req, 'fresh', function() { + const { method } = this; + const { res } = this; + const status = res.statusCode; // GET or HEAD for weak freshness validation only - if ('GET' !== method && 'HEAD' !== method) return false; + if (method !== 'GET' && method !== 'HEAD') return false; // 2xx or 304 as per rfc2616 14.26 - if ((status >= 200 && status < 300) || 304 === status) { + if ((status >= 200 && status < 300) || status === 304) { return fresh(this.headers, { - 'etag': res.get('ETag'), + etag: res.get('ETag'), 'last-modified': res.get('Last-Modified') - }) + }); } return false; @@ -489,7 +478,7 @@ function setMethods(req) { */ defineGetter(req, 'xhr', function xhr() { - var val = this.get('X-Requested-With') || ''; + const val = this.get('X-Requested-With') || ''; return val.toLowerCase() === 'xmlhttprequest'; }); diff --git a/test/support/express/responseDecorator.js b/test/support/express/responseDecorator.js index d31f1c0f1..5008d2be6 100644 --- a/test/support/express/responseDecorator.js +++ b/test/support/express/responseDecorator.js @@ -12,25 +12,26 @@ * @private */ -var Buffer = require('safe-buffer').Buffer -var contentDisposition = require('content-disposition'); -var encodeUrl = require('encodeurl'); -var escapeHtml = require('escape-html'); -var onFinished = require('on-finished'); -var path = require('path'); -var pathIsAbsolute = require('path-is-absolute'); -var statuses = require('statuses') -var merge = require('utils-merge'); -var sign = require('cookie-signature').sign; -var normalizeType = require('./utils').normalizeType; -var normalizeTypes = require('./utils').normalizeTypes; -var setCharset = require('./utils').setCharset; -var cookie = require('cookie'); -var send = require('send'); -var extname = path.extname; -var mime = send.mime; -var resolve = path.resolve; -var vary = require('vary'); +const { Buffer } = require('safe-buffer'); +const contentDisposition = require('content-disposition'); +const encodeUrl = require('encodeurl'); +const escapeHtml = require('escape-html'); +const onFinished = require('on-finished'); +const path = require('path'); +const pathIsAbsolute = require('path-is-absolute'); +const statuses = require('statuses'); +const merge = require('utils-merge'); +const { sign } = require('cookie-signature'); +const { normalizeType } = require('./utils'); +const { normalizeTypes } = require('./utils'); +const { setCharset } = require('./utils'); +const cookie = require('cookie'); +const send = require('send'); + +const { extname } = path; +const { mime } = send; +const { resolve } = path; +const vary = require('vary'); /** * Module exports. * @public @@ -44,7 +45,7 @@ function setMethods(res) { * @private */ - var charsetRegExp = /;\s*charset\s*=/; + const charsetRegExp = /;\s*charset\s*=/; /** * Set status `code`. @@ -74,12 +75,18 @@ function setMethods(res) { * @public */ - res.links = function (links) { - var link = this.get('Link') || ''; + res.links = function(links) { + let link = this.get('Link') || ''; if (link) link += ', '; - return this.set('Link', link + Object.keys(links).map(function (rel) { - return '<' + links[rel] + '>; rel="' + rel + '"'; - }).join(', ')); + return this.set( + 'Link', + link + + Object.keys(links) + .map(rel => { + return '<' + links[rel] + '>; rel="' + rel + '"'; + }) + .join(', ') + ); }; /** @@ -96,13 +103,13 @@ function setMethods(res) { */ res.send = function send(body) { - var chunk = body; - var encoding; - var req = this.req; - var type; + let chunk = body; + let encoding; + const { req } = this; + let type; // settings - var app = this.app; + const { app } = this; switch (typeof chunk) { // string defaulting to html @@ -110,6 +117,7 @@ function setMethods(res) { if (!this.get('Content-Type')) { this.type('html'); } + break; case 'boolean': case 'number': @@ -123,6 +131,7 @@ function setMethods(res) { } else { return this.json(chunk); } + break; } @@ -138,30 +147,30 @@ function setMethods(res) { } // determine if ETag should be generated - var etagFn = app.get('etag fn') - var generateETag = !this.get('ETag') && typeof etagFn === 'function' + const etagFn = app.get('etag fn'); + const generateETag = !this.get('ETag') && typeof etagFn === 'function'; // populate Content-Length - var len + let len; if (chunk !== undefined) { if (Buffer.isBuffer(chunk)) { // get length of Buffer - len = chunk.length + len = chunk.length; } else if (!generateETag && chunk.length < 1000) { // just calculate length when no ETag + small chunk - len = Buffer.byteLength(chunk, encoding) + len = Buffer.byteLength(chunk, encoding); } else { // convert chunk to Buffer and calculate - chunk = Buffer.from(chunk, encoding) + chunk = Buffer.from(chunk, encoding); encoding = undefined; - len = chunk.length + len = chunk.length; } this.set('Content-Length', len); } // populate ETag - var etag; + let etag; if (generateETag && len !== undefined) { if ((etag = etagFn(chunk, encoding))) { this.set('ETag', etag); @@ -172,7 +181,7 @@ function setMethods(res) { if (req.fresh) this.statusCode = 304; // strip irrelevant headers - if (204 === this.statusCode || 304 === this.statusCode) { + if (this.statusCode === 204 || this.statusCode === 304) { this.removeHeader('Content-Type'); this.removeHeader('Content-Length'); this.removeHeader('Transfer-Encoding'); @@ -204,11 +213,11 @@ function setMethods(res) { res.json = function json(obj) { // settings - var app = this.app; - var escape = app.get('json escape') - var replacer = app.get('json replacer'); - var spaces = app.get('json spaces'); - var body = stringify(obj, replacer, spaces, escape) + const { app } = this; + const escape = app.get('json escape'); + const replacer = app.get('json replacer'); + const spaces = app.get('json spaces'); + const body = stringify(obj, replacer, spaces, escape); // content-type if (!this.get('Content-Type')) { @@ -232,12 +241,12 @@ function setMethods(res) { res.jsonp = function jsonp(obj) { // settings - var app = this.app; - var escape = app.get('json escape') - var replacer = app.get('json replacer'); - var spaces = app.get('json spaces'); - var body = stringify(obj, replacer, spaces, escape) - var callback = this.req.query[app.get('jsonp callback name')]; + const { app } = this; + const escape = app.get('json escape'); + const replacer = app.get('json replacer'); + const spaces = app.get('json spaces'); + let body = stringify(obj, replacer, spaces, escape); + let callback = this.req.query[app.get('jsonp callback name')]; // content-type if (!this.get('Content-Type')) { @@ -259,13 +268,18 @@ function setMethods(res) { callback = callback.replace(/[^\[\]\w$.]/g, ''); // replace chars not allowed in JavaScript that are in JSON - body = body - .replace(/\u2028/g, '\\u2028') - .replace(/\u2029/g, '\\u2029'); + body = body.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'); // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse" // the typeof check is just to reduce client error noise - body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');'; + body = + '/**/ typeof ' + + callback + + " === 'function' && " + + callback + + '(' + + body + + ');'; } return this.send(body); @@ -287,7 +301,7 @@ function setMethods(res) { */ res.sendStatus = function sendStatus(statusCode) { - var body = statuses[statusCode] || String(statusCode) + const body = statuses[statusCode] || String(statusCode); this.statusCode = statusCode; this.type('txt'); @@ -337,11 +351,11 @@ function setMethods(res) { */ res.sendFile = function sendFile(path, options, callback) { - var done = callback; - var req = this.req; - var res = this; - var next = req.next; - var opts = options || {}; + let done = callback; + const { req } = this; + const res = this; + const { next } = req; + let opts = options || {}; if (!path) { throw new TypeError('path argument is required to res.sendFile'); @@ -354,15 +368,17 @@ function setMethods(res) { } if (!opts.root && !pathIsAbsolute(path)) { - throw new TypeError('path must be absolute or specify root to res.sendFile'); + throw new TypeError( + 'path must be absolute or specify root to res.sendFile' + ); } // create file stream - var pathname = encodeURI(path); - var file = send(req, pathname, opts); + const pathname = encodeURI(path); + const file = send(req, pathname, opts); // transfer - sendfile(res, file, opts, function (err) { + sendfile(res, file, opts, err => { if (done) return done(err); if (err && err.code === 'EISDIR') return next(); @@ -391,46 +407,46 @@ function setMethods(res) { * @public */ - res.download = function download (path, filename, options, callback) { - var done = callback; - var name = filename; - var opts = options || null + res.download = function download(path, filename, options, callback) { + let done = callback; + let name = filename; + let opts = options || null; // support function as second or third arg if (typeof filename === 'function') { done = filename; name = null; - opts = null + opts = null; } else if (typeof options === 'function') { - done = options - opts = null + done = options; + opts = null; } // set Content-Disposition when file is sent - var headers = { + const headers = { 'Content-Disposition': contentDisposition(name || path) }; // merge user-provided headers if (opts && opts.headers) { - var keys = Object.keys(opts.headers) - for (var i = 0; i < keys.length; i++) { - var key = keys[i] + const keys = Object.keys(opts.headers); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; if (key.toLowerCase() !== 'content-disposition') { - headers[key] = opts.headers[key] + headers[key] = opts.headers[key]; } } } // merge user-provided options - opts = Object.create(opts) - opts.headers = headers + opts = Object.create(opts); + opts.headers = headers; // Resolve the full path for sendFile - var fullPath = resolve(path); + const fullPath = resolve(path); // send file - return this.sendFile(fullPath, opts, done) + return this.sendFile(fullPath, opts, done); }; /** @@ -450,14 +466,11 @@ function setMethods(res) { * @public */ - res.contentType = - res.type = function contentType(type) { - var ct = type.indexOf('/') === -1 - ? mime.lookup(type) - : type; + res.contentType = res.type = function contentType(type) { + const ct = type.indexOf('/') === -1 ? mime.lookup(type) : type; - return this.set('Content-Type', ct); - }; + return this.set('Content-Type', ct); + }; /** * Respond to the Acceptable formats using an `obj` @@ -516,19 +529,17 @@ function setMethods(res) { * @public */ - res.format = function (obj) { - var req = this.req; - var next = req.next; + res.format = function(obj) { + const { req } = this; + const { next } = req; - var fn = obj.default; + const fn = obj.default; if (fn) delete obj.default; - var keys = Object.keys(obj); + const keys = Object.keys(obj); - var key = keys.length > 0 - ? req.accepts(keys) - : false; + const key = keys.length > 0 ? req.accepts(keys) : false; - this.vary("Accept"); + this.vary('Accept'); if (key) { this.set('Content-Type', normalizeType(key).value); @@ -536,9 +547,11 @@ function setMethods(res) { } else if (fn) { fn(); } else { - var err = new Error('Not Acceptable'); + const err = new Error('Not Acceptable'); err.status = err.statusCode = 406; - err.types = normalizeTypes(keys).map(function (o) { return o.value }); + err.types = normalizeTypes(keys).map(o => { + return o.value; + }); next(err); } @@ -579,14 +592,16 @@ function setMethods(res) { */ res.append = function append(field, val) { - var prev = this.get(field); - var value = val; + const prev = this.get(field); + let value = val; if (prev) { // concat the new and prev vals - value = Array.isArray(prev) ? prev.concat(val) - : Array.isArray(val) ? [prev].concat(val) - : [prev, val]; + value = Array.isArray(prev) + ? prev.concat(val) + : Array.isArray(val) + ? [prev].concat(val) + : [prev, val]; } return this.set(field, value); @@ -610,32 +625,31 @@ function setMethods(res) { * @public */ - res.set = - res.header = function header(field, val) { - if (arguments.length === 2) { - var value = Array.isArray(val) - ? val.map(String) - : String(val); - - // add charset to content-type - if (field.toLowerCase() === 'content-type') { - if (Array.isArray(value)) { - throw new TypeError('Content-Type cannot be set to an Array'); - } - if (!charsetRegExp.test(value)) { - var charset = mime.charsets.lookup(value.split(';')[0]); - if (charset) value += '; charset=' + charset.toLowerCase(); - } + res.set = res.header = function header(field, val) { + if (arguments.length === 2) { + let value = Array.isArray(val) ? val.map(String) : String(val); + + // add charset to content-type + if (field.toLowerCase() === 'content-type') { + if (Array.isArray(value)) { + throw new TypeError('Content-Type cannot be set to an Array'); } - this.setHeader(field, value); - } else { - for (var key in field) { - this.set(key, field[key]); + if (!charsetRegExp.test(value)) { + const charset = mime.charsets.lookup(value.split(';')[0]); + if (charset) value += '; charset=' + charset.toLowerCase(); } } - return this; - }; + + this.setHeader(field, value); + } else { + for (const key in field) { + this.set(key, field[key]); + } + } + + return this; + }; /** * Get value for header `field`. @@ -645,7 +659,7 @@ function setMethods(res) { * @public */ - res.get = function (field) { + res.get = function(field) { return this.getHeader(field); }; @@ -659,7 +673,7 @@ function setMethods(res) { */ res.clearCookie = function clearCookie(name, options) { - var opts = merge({ expires: new Date(1), path: '/' }, options); + const opts = merge({ expires: new Date(1), path: '/' }, options); return this.cookie(name, '', opts); }; @@ -688,18 +702,17 @@ function setMethods(res) { * @public */ - res.cookie = function (name, value, options) { - var opts = merge({}, options); - var secret = this.req.secret; - var signed = opts.signed; + res.cookie = function(name, value, options) { + const opts = merge({}, options); + const { secret } = this.req; + const { signed } = opts; if (signed && !secret) { throw new Error('cookieParser("secret") required for signed cookies'); } - var val = typeof value === 'object' - ? 'j:' + JSON.stringify(value) - : String(value); + let val = + typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value); if (signed) { val = 's:' + sign(val, secret); @@ -737,7 +750,7 @@ function setMethods(res) { */ res.location = function location(url) { - var loc = url; + let loc = url; // "back" is an alias for the referrer if (url === 'back') { @@ -767,14 +780,14 @@ function setMethods(res) { */ res.redirect = function redirect(url) { - var address = url; - var body; - var status = 302; + let address = url; + let body; + let status = 302; // allow status / url if (arguments.length === 2) { - status = arguments[0] - address = arguments[1] + status = arguments[0]; + address = arguments[1]; } // Set location header @@ -782,16 +795,23 @@ function setMethods(res) { // Support text/{plain,html} by default this.format({ - text: function () { - body = statuses[status] + '. Redirecting to ' + address + text() { + body = statuses[status] + '. Redirecting to ' + address; }, - html: function () { - var u = escapeHtml(address); - body = '

' + statuses[status] + '. Redirecting to ' + u + '

' + html() { + const u = escapeHtml(address); + body = + '

' + + statuses[status] + + '. Redirecting to ' + + u + + '

'; }, - default: function () { + default() { body = ''; } }); @@ -816,7 +836,7 @@ function setMethods(res) { * @public */ - res.vary = function(field){ + res.vary = function(field) { vary(this, field); return this; @@ -836,11 +856,11 @@ function setMethods(res) { */ res.render = function render(view, options, callback) { - var app = this.req.app; - var done = callback; - var opts = options || {}; - var req = this.req; - var self = this; + const { app } = this.req; + let done = callback; + let opts = options || {}; + const { req } = this; + const self = this; // support callback function as second arg if (typeof options === 'function') { @@ -852,10 +872,12 @@ function setMethods(res) { opts._locals = self.locals; // default callback to respond - done = done || function (err, str) { - if (err) return req.next(err); - self.send(str); - }; + done = + done || + function(err, str) { + if (err) return req.next(err); + self.send(str); + }; // render app.render(view, opts, done); @@ -863,15 +885,15 @@ function setMethods(res) { // pipe the send file stream function sendfile(res, file, options, callback) { - var done = false; - var streaming; + let done = false; + let streaming; // request aborted function onaborted() { if (done) return; done = true; - var err = new Error('Request aborted'); + const err = new Error('Request aborted'); err.code = 'ECONNABORTED'; callback(err); } @@ -881,7 +903,7 @@ function setMethods(res) { if (done) return; done = true; - var err = new Error('EISDIR, read'); + const err = new Error('EISDIR, read'); err.code = 'EISDIR'; callback(err); } @@ -911,7 +933,7 @@ function setMethods(res) { if (err) return onerror(err); if (done) return; - setImmediate(function () { + setImmediate(() => { if (streaming !== false && !done) { onaborted(); return; @@ -937,11 +959,11 @@ function setMethods(res) { if (options.headers) { // set headers on successful transfer file.on('headers', function headers(res) { - var obj = options.headers; - var keys = Object.keys(obj); + const obj = options.headers; + const keys = Object.keys(obj); - for (var i = 0; i < keys.length; i++) { - var k = keys[i]; + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; res.setHeader(k, obj[k]); } }); @@ -968,27 +990,28 @@ function setMethods(res) { * @private */ -function stringify (value, replacer, spaces, escape) { +function stringify(value, replacer, spaces, escape) { // v8 checks arguments.length for optimizing simple call // https://bugs.chromium.org/p/v8/issues/detail?id=4730 - var json = replacer || spaces - ? JSON.stringify(value, replacer, spaces) - : JSON.stringify(value); + let json = + replacer || spaces + ? JSON.stringify(value, replacer, spaces) + : JSON.stringify(value); if (escape) { - json = json.replace(/[<>&]/g, function (c) { + json = json.replace(/[<>&]/g, c => { switch (c.charCodeAt(0)) { case 0x3c: - return '\\u003c' + return '\\u003c'; case 0x3e: - return '\\u003e' + return '\\u003e'; case 0x26: - return '\\u0026' + return '\\u0026'; default: - return c + return c; } - }) + }); } - return json + return json; } diff --git a/test/support/express/utils.js b/test/support/express/utils.js index afb5bd5f6..32814938f 100644 --- a/test/support/express/utils.js +++ b/test/support/express/utils.js @@ -12,14 +12,15 @@ * @api private */ -var Buffer = require('safe-buffer').Buffer -var contentType = require('content-type'); -var mime = require('send').mime; -var etag = require('etag'); -var proxyaddr = require('proxy-addr'); -var qs = require('qs'); -var querystring = require('querystring'); -var isHttp2Supported = true; +const { Buffer } = require('safe-buffer'); +const contentType = require('content-type'); +const { mime } = require('send'); +const etag = require('etag'); +const proxyaddr = require('proxy-addr'); +const qs = require('qs'); +const querystring = require('querystring'); + +let isHttp2Supported = true; /** * Test for http2 support @@ -39,7 +40,7 @@ try { * @api private */ -exports.etag = createETagGenerator({ weak: false }) +exports.etag = createETagGenerator({ weak: false }); /** * Return weak ETag for `body`. @@ -50,7 +51,7 @@ exports.etag = createETagGenerator({ weak: false }) * @api private */ -exports.wetag = createETagGenerator({ weak: true }) +exports.wetag = createETagGenerator({ weak: true }); /** * Normalize the given `type`, for example "html" becomes "text/html". @@ -60,7 +61,7 @@ exports.wetag = createETagGenerator({ weak: true }) * @api private */ -exports.normalizeType = function(type){ +exports.normalizeType = function(type) { return ~type.indexOf('/') ? acceptParams(type) : { value: mime.lookup(type), params: {} }; @@ -74,10 +75,10 @@ exports.normalizeType = function(type){ * @api private */ -exports.normalizeTypes = function(types){ - var ret = []; +exports.normalizeTypes = function(types) { + const ret = []; - for (var i = 0; i < types.length; ++i) { + for (let i = 0; i < types.length; ++i) { ret.push(exports.normalizeType(types[i])); } @@ -95,12 +96,12 @@ exports.normalizeTypes = function(types){ */ function acceptParams(str, index) { - var parts = str.split(/ *; */); - var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index }; + const parts = str.split(/ *; */); + const ret = { value: parts[0], quality: 1, params: {}, originalIndex: index }; - for (var i = 1; i < parts.length; ++i) { - var pms = parts[i].split(/ *= */); - if ('q' === pms[0]) { + for (let i = 1; i < parts.length; ++i) { + const pms = parts[i].split(/ *= */); + if (pms[0] === 'q') { ret.quality = parseFloat(pms[1]); } else { ret.params[pms[0]] = pms[1]; @@ -119,7 +120,7 @@ function acceptParams(str, index) { */ exports.compileETag = function(val) { - var fn; + let fn; if (typeof val === 'function') { return val; @@ -142,7 +143,7 @@ exports.compileETag = function(val) { } return fn; -} +}; /** * Compile "query parser" value to function. @@ -153,7 +154,7 @@ exports.compileETag = function(val) { */ exports.compileQueryParser = function compileQueryParser(val) { - var fn; + let fn; if (typeof val === 'function') { return val; @@ -176,7 +177,7 @@ exports.compileQueryParser = function compileQueryParser(val) { } return fn; -} +}; /** * Compile "proxy trust" value to function. @@ -191,12 +192,16 @@ exports.compileTrust = function(val) { if (val === true) { // Support plain true/false - return function(){ return true }; + return function() { + return true; + }; } if (typeof val === 'number') { // Support trusting hop count - return function(a, i){ return i < val }; + return function(a, i) { + return i < val; + }; } if (typeof val === 'string') { @@ -205,7 +210,7 @@ exports.compileTrust = function(val) { } return proxyaddr.compile(val || []); -} +}; /** * Flag for http2 support @@ -226,7 +231,7 @@ exports.setCharset = function setCharset(type, charset) { } // parse type - var parsed = contentType.parse(type); + const parsed = contentType.parse(type); // set charset parsed.parameters.charset = charset; @@ -244,14 +249,12 @@ exports.setCharset = function setCharset(type, charset) { * @private */ -function createETagGenerator (options) { - return function generateETag (body, encoding) { - var buf = !Buffer.isBuffer(body) - ? Buffer.from(body, encoding) - : body +function createETagGenerator(options) { + return function generateETag(body, encoding) { + const buf = !Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body; - return etag(buf, options) - } + return etag(buf, options); + }; } /** diff --git a/test/support/server.js b/test/support/server.js index 5721b4d14..b06b0c0a2 100644 --- a/test/support/server.js +++ b/test/support/server.js @@ -1,33 +1,34 @@ -const express = require('./express'); +const fs = require('fs'); +let http = require('http'); const multer = require('multer'); const bodyParser = require('body-parser'); const cookieParser = require('cookie-parser'); const basicAuth = require('basic-auth-connect'); -const fs = require('fs'); -let http = require('http'); +const express = require('./express'); + let isPseudoHeader; -if(process.env.HTTP2_TEST){ +if (process.env.HTTP2_TEST) { http = require('http2'); const { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_METHOD, HTTP2_HEADER_PATH, HTTP2_HEADER_SCHEME, - HTTP2_HEADER_STATUS, + HTTP2_HEADER_STATUS } = http.constants; isPseudoHeader = function(name) { switch (name) { - case HTTP2_HEADER_STATUS: // :status - case HTTP2_HEADER_METHOD: // :method - case HTTP2_HEADER_PATH: // :path + case HTTP2_HEADER_STATUS: // :status + case HTTP2_HEADER_METHOD: // :method + case HTTP2_HEADER_PATH: // :path case HTTP2_HEADER_AUTHORITY: // :authority - case HTTP2_HEADER_SCHEME: // :scheme + case HTTP2_HEADER_SCHEME: // :scheme return true; default: return false; } - } + }; } const app = express(); @@ -42,14 +43,15 @@ app.all('/url', (req, res) => { }); app.all('/echo', (req, res) => { - let headers = req.headers; - if(process.env.HTTP2_TEST){ - Object.keys(headers).forEach(function(name) { - if(isPseudoHeader(name)){ + const { headers } = req; + if (process.env.HTTP2_TEST) { + Object.keys(headers).forEach(name => { + if (isPseudoHeader(name)) { delete headers[name]; } }); } + res.writeHead(200, headers); req.pipe(res); }); @@ -63,9 +65,14 @@ app.use(bodyParser.urlencoded({ extended: true })); app.use(multer().none()); app.all('/formecho', (req, res) => { - if (!/application\/x-www-form-urlencoded|multipart\/form-data/.test(req.headers['content-type'])) { - return res.status(400).end("wrong type"); + if ( + !/application\/x-www-form-urlencoded|multipart\/form-data/.test( + req.headers['content-type'] + ) + ) { + return res.status(400).end('wrong type'); } + res.json(req.body); }); @@ -78,7 +85,7 @@ app.use('/xdomain', (req, res, next) => { res.set('Access-Control-Allow-Credentials', 'true'); res.set('Access-Control-Allow-Methods', 'POST'); res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type'); - if ('OPTIONS' == req.method) return res.send(200); + if (req.method == 'OPTIONS') return res.send(200); next(); }); @@ -149,7 +156,10 @@ app.get('/movie/4', (req, res) => { }); app.get('/links', (req, res) => { - res.header('Link', '; rel="next"'); + res.header( + 'Link', + '; rel="next"' + ); res.end(); }); @@ -189,7 +199,9 @@ app.delete('/user/:id', (req, res) => { app.post('/todo/item', (req, res) => { let buf = ''; - req.on('data', chunk => { buf += chunk; }); + req.on('data', chunk => { + buf += chunk; + }); req.on('end', () => { res.send(`added "${buf}"`); }); @@ -200,14 +212,17 @@ app.get('/delay/const', (req, res) => { }); app.get('/delay/zip', (req, res) => { - res.writeHead(200, {"Content-Type":"text/plain", "Content-Encoding":"gzip"}); + res.writeHead(200, { + 'Content-Type': 'text/plain', + 'Content-Encoding': 'gzip' + }); setTimeout(() => { res.end(); }, 10000); }); app.get('/delay/json', (req, res) => { - res.writeHead(200, {"Content-Type":"application/json"}); + res.writeHead(200, { 'Content-Type': 'application/json' }); setTimeout(() => { res.end(); }, 10000); @@ -215,7 +230,7 @@ app.get('/delay/json', (req, res) => { let slowBodyCallback; app.get('/delay/slowbody', (req, res) => { - res.writeHead(200, {"Content-Type":"application/octet-stream"}); + res.writeHead(200, { 'Content-Type': 'application/octet-stream' }); // Send lots of garbage data to overflow all buffers along the way, // so that the browser gets some data before the request is done @@ -228,7 +243,9 @@ app.get('/delay/slowbody', (req, res) => { // Make sure sending of request body takes over 1s, // so that the test can't pass by accident. - const minimumTime = new Promise(resolve => {setTimeout(resolve, 1001)}); + const minimumTime = new Promise(resolve => { + setTimeout(resolve, 1001); + }); new Promise(resolve => { // Waiting full 10 seconds for the test would be too annoying, @@ -236,10 +253,10 @@ app.get('/delay/slowbody', (req, res) => { slowBodyCallback = resolve; setTimeout(resolve, 10000); }) - .then(() => Promise.all([initialDataSent, minimumTime])) - .then(() => { - res.end('bye'); - }); + .then(() => Promise.all([initialDataSent, minimumTime])) + .then(() => { + res.end('bye'); + }); }); app.get('/delay/slowbody/finish', (req, res) => { @@ -280,22 +297,26 @@ app.get('/pets', (req, res) => { }); app.get('/json-seq', (req, res) => { - res.set('content-type', 'application/json-seq').send('\x1e{"id":1}\n\x1e{"id":2}\n'); + res + .set('content-type', 'application/json-seq') + .send('\u001E{"id":1}\n\u001E{"id":2}\n'); }); app.get('/invalid-json', (req, res) => { res.set('content-type', 'application/json'); // sample invalid json taken from https://github.com/swagger-api/swagger-ui/issues/1354 - res.send(")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}"); + res.send( + ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}" + ); }); app.get('/invalid-json-forbidden', (req, res) => { res.set('content-type', 'application/json'); - res.status(403).send("Forbidden"); + res.status(403).send('Forbidden'); }); app.get('/text', (req, res) => { - res.send("just some text"); + res.send('just some text'); }); app.get('/basic-auth', basicAuth('tobi', 'learnboost'), (req, res) => { @@ -307,7 +328,13 @@ app.get('/basic-auth/again', basicAuth('tobi', ''), (req, res) => { }); app.post('/auth', basicAuth('foo', 'bar'), (req, res) => { - const auth = req.headers.authorization, parts = auth.split(' '), credentials = new Buffer(parts[1], 'base64').toString().split(':'), user = credentials[0], pass = credentials[1]; + const auth = req.headers.authorization; + const parts = auth.split(' '); + const credentials = Buffer.from(parts[1], 'base64') + .toString() + .split(':'); + const user = credentials[0]; + const pass = credentials[1]; res.send({ user, pass }); }); @@ -353,19 +380,19 @@ app.get('/arraybuffer', (req, res) => { app.get('/arraybuffer-unauthorized', (req, res) => { res.set('Content-Type', 'application/json'); - res.status(401).send('{"message":"Authorization has been denied for this request."}'); + res + .status(401) + .send('{"message":"Authorization has been denied for this request."}'); }); app.post('/empty-body', bodyParser.text(), (req, res) => { if (typeof req.body === 'object' && Object.keys(req.body).length === 0) { res.sendStatus(204); - } - else { + } else { res.sendStatus(400); } }); - app.get('/collection-json', (req, res) => { res.set('content-type', 'application/vnd.collection+json'); res.send({ name: 'chewbacca' }); @@ -374,7 +401,9 @@ app.get('/collection-json', (req, res) => { app.get('/invalid-json', (req, res) => { res.set('content-type', 'application/json'); // sample invalid json taken from https://github.com/swagger-api/swagger-ui/issues/1354 - res.send(")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}"); + res.send( + ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}" + ); }); app.options('/options/echo/body', bodyParser.json(), (req, res) => { @@ -382,8 +411,8 @@ app.options('/options/echo/body', bodyParser.json(), (req, res) => { }); app.get('/cookie-redirect', (req, res) => { - res.set("Set-Cookie", "replaced=yes"); - res.append("Set-Cookie", "from-redir=1", true); + res.set('Set-Cookie', 'replaced=yes'); + res.append('Set-Cookie', 'from-redir=1', true); res.redirect(303, '/show-cookies'); }); @@ -442,27 +471,29 @@ app.get('/bad-redirect', (req, res) => { }); app.all('/ua', (req, res) => { - let headers = req.headers; - if(process.env.HTTP2_TEST){ - Object.keys(headers).forEach(function(name) { - if(isPseudoHeader(name)){ + const { headers } = req; + if (process.env.HTTP2_TEST) { + Object.keys(headers).forEach(name => { + if (isPseudoHeader(name)) { delete headers[name]; } }); } + res.writeHead(200, headers); req.pipe(res); }); app.get('/manny', (req, res) => { - res.status(200).json({name:"manny"}); + res.status(200).json({ name: 'manny' }); }); function serveImageWithType(res, type) { const img = fs.readFileSync(`${__dirname}/../node/fixtures/test.png`); - res.writeHead(200, {'Content-Type': type }); + res.writeHead(200, { 'Content-Type': type }); res.end(img, 'binary'); } + app.get('/image', (req, res) => { serveImageWithType(res, 'image/png'); }); @@ -477,14 +508,14 @@ app.get('/chunked-json', (req, res) => { let chunk = 0; const interval = setInterval(() => { chunk++; - if(chunk === 1) res.write(`{ "name_${chunk}": "`); - if(chunk > 1) res.write(`value_${chunk}", "name_${chunk}": "`); - if(chunk === 10) { + if (chunk === 1) res.write(`{ "name_${chunk}": "`); + if (chunk > 1) res.write(`value_${chunk}", "name_${chunk}": "`); + if (chunk === 10) { clearInterval(interval); res.write(`value_${chunk}"}`); res.end(); } - },10); + }, 10); }); app.get('/if-mod', (req, res) => { @@ -498,10 +529,10 @@ app.get('/if-mod', (req, res) => { const called = {}; app.get('/error/ok/:id', (req, res) => { if (req.query.qs != 'present') { - return res.status(400).end("query string lost"); + return res.status(400).end('query string lost'); } - const id = req.params.id; + const { id } = req.params; if (!called[id]) { called[id] = true; res.status(500).send('boom'); @@ -512,7 +543,7 @@ app.get('/error/ok/:id', (req, res) => { }); app.get('/delay/:ms/ok/:id', (req, res) => { - const id = req.params.id; + const { id } = req.params; if (!called[id]) { called[id] = true; const ms = ~~req.params.ms; @@ -526,7 +557,7 @@ app.get('/delay/:ms/ok/:id', (req, res) => { }); app.get('/error/redirect/:id', (req, res) => { - const id = req.params.id; + const { id } = req.params; if (!called[id]) { called[id] = true; res.status(500).send('boom'); @@ -537,7 +568,7 @@ app.get('/error/redirect/:id', (req, res) => { }); app.get('/error/redirect-error:id', (req, res) => { - const id = req.params.id; + const { id } = req.params; if (!called[id]) { called[id] = true; res.status(500).send('boom'); @@ -547,5 +578,5 @@ app.get('/error/redirect-error:id', (req, res) => { } }); -let server = http.createServer(app); +const server = http.createServer(app); server.listen(process.env.ZUUL_PORT); diff --git a/test/support/setup.js b/test/support/setup.js index 77fcee3b1..c6cb7397a 100644 --- a/test/support/setup.js +++ b/test/support/setup.js @@ -6,8 +6,7 @@ let uri = 'http://localhost:5000'; if (typeof window !== 'undefined') { NODE = false; uri = `//${window.location.host}`; -} -else { +} else { process.env.ZUUL_PORT = 5000; require('./server'); } diff --git a/test/timeout.js b/test/timeout.js index 32d713b00..d10eb1690 100644 --- a/test/timeout.js +++ b/test/timeout.js @@ -1,96 +1,117 @@ const setup = require('./support/setup'); + const base = setup.uri; const assert = require('assert'); const request = require('./support/client'); -describe('.timeout(ms)', function(){ +describe('.timeout(ms)', function() { this.timeout(15000); describe('when timeout is exceeded', () => { it('should error', done => { request - .get(`${base}/delay/500`) - .timeout(150) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - done(); - }); + .get(`${base}/delay/500`) + .timeout(150) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal( + 'number', + typeof err.timeout, + 'expected an error with .timeout' + ); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + done(); + }); }); it('should handle gzip timeout', done => { request - .get(`${base}/delay/zip`) - .timeout(150) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - done(); - }); + .get(`${base}/delay/zip`) + .timeout(150) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal( + 'number', + typeof err.timeout, + 'expected an error with .timeout' + ); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + done(); + }); }); it('should handle buffer timeout', done => { request - .get(`${base}/delay/json`) - .buffer(true) - .timeout(150) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - done(); - }); + .get(`${base}/delay/json`) + .buffer(true) + .timeout(150) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal( + 'number', + typeof err.timeout, + 'expected an error with .timeout' + ); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + done(); + }); }); it('should error on deadline', done => { request - .get(`${base}/delay/500`) - .timeout({deadline: 150}) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - done(); - }); + .get(`${base}/delay/500`) + .timeout({ deadline: 150 }) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal( + 'number', + typeof err.timeout, + 'expected an error with .timeout' + ); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + done(); + }); }); it('should support setting individual options', done => { request - .get(`${base}/delay/500`) - .timeout({deadline: 10}) - .timeout({response: 99999}) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - assert.equal('ETIME', err.errno); - done(); - }); + .get(`${base}/delay/500`) + .timeout({ deadline: 10 }) + .timeout({ response: 99999 }) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + assert.equal('ETIME', err.errno); + done(); + }); }); it('should error on response', done => { request - .get(`${base}/delay/500`) - .timeout({response: 150}) - .end((err, res) => { - assert(err, 'expected an error'); - assert.equal('number', typeof err.timeout, 'expected an error with .timeout'); - assert.equal('ECONNABORTED', err.code, 'expected abort error code') - assert.equal('ETIMEDOUT', err.errno); - done(); - }); + .get(`${base}/delay/500`) + .timeout({ response: 150 }) + .end((err, res) => { + assert(err, 'expected an error'); + assert.equal( + 'number', + typeof err.timeout, + 'expected an error with .timeout' + ); + assert.equal('ECONNABORTED', err.code, 'expected abort error code'); + assert.equal('ETIMEDOUT', err.errno); + done(); + }); }); it('should accept slow body with fast response', done => { request .get(`${base}/delay/slowbody`) - .timeout({response: 1000}) + .timeout({ response: 1000 }) .on('progress', () => { // This only makes the test faster without relying on arbitrary timeouts request.get(`${base}/delay/slowbody/finish`).end(); }) .end(done); }); - }) -}) + }); +}); diff --git a/test/use.js b/test/use.js index cd441c064..aedefa094 100644 --- a/test/use.js +++ b/test/use.js @@ -1,22 +1,25 @@ const setup = require('./support/setup'); -const uri = setup.uri; + +const { uri } = setup; const assert = require('assert'); const request = require('./support/client'); -describe('request', function(){ +describe('request', function() { this.timeout(20000); describe('use', () => { it('should use plugin success', done => { const now = `${Date.now()}`; - function uuid(req){ + function uuid(req) { req.set('X-UUID', now); return req; } - function prefix(req){ - req.url = uri + req.url + + function prefix(req) { + req.url = uri + req.url; return req; } + request .get('/echo') .use(uuid) @@ -25,10 +28,10 @@ describe('request', function(){ assert.strictEqual(res.statusCode, 200); assert.equal(res.get('X-UUID'), now); done(); - }) + }); }); }); -}) +}); describe('subclass', () => { let OriginalRequest; @@ -47,11 +50,13 @@ describe('subclass', () => { it('should use patched subclass', () => { assert(OriginalRequest); - let constructorCalled, sendCalled; + let constructorCalled; + let sendCalled; function NewRequest(...args) { constructorCalled = true; OriginalRequest.apply(this, args); } + NewRequest.prototype = Object.create(OriginalRequest.prototype); NewRequest.prototype.send = function() { sendCalled = true; @@ -73,6 +78,7 @@ describe('subclass', () => { function NewRequest(...args) { OriginalRequest.apply(this, args); } + NewRequest.prototype = Object.create(OriginalRequest.prototype); request.Request = NewRequest; @@ -80,4 +86,4 @@ describe('subclass', () => { assert(req instanceof NewRequest); assert(req instanceof OriginalRequest); }); -}) +}); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..a19344963 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,10906 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/cli@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.3.tgz#1b262e42a3e959d28ab3d205ba2718e1923cfee6" + integrity sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA== + dependencies: + commander "^2.8.1" + convert-source-map "^1.1.0" + fs-readdir-recursive "^1.1.0" + glob "^7.0.0" + lodash "^4.17.10" + mkdirp "^0.5.1" + output-file-sync "^2.0.0" + slash "^2.0.0" + source-map "^0.5.0" + optionalDependencies: + chokidar "^2.0.3" + +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/core@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.0.tgz#248fd6874b7d755010bfe61f557461d4f446d9e9" + integrity sha512-Dzl7U0/T69DFOTwqz/FJdnOSWS57NpjNfCwMKHABr589Lg8uX1RrlBIJ7L5Dubt/xkLsx0xH5EBFzlBVes1ayA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.0" + "@babel/helpers" "^7.4.0" + "@babel/parser" "^7.4.0" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.0.tgz#c230e79589ae7a729fd4631b9ded4dc220418196" + integrity sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ== + dependencies: + "@babel/types" "^7.4.0" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-call-delegate@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.4.0.tgz#f308eabe0d44f451217853aedf4dea5f6fe3294f" + integrity sha512-SdqDfbVdNQCBp3WhK2mNdDvHd3BD6qbmIc43CAyjnsfCmgHMeqgDcM3BzY2lchi7HBJGJ2CVdynLWbezaE4mmQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/helper-define-map@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.0.tgz#cbfd8c1b2f12708e262c26f600cd16ed6a3bc6c9" + integrity sha512-wAhQ9HdnLIywERVcSvX40CEJwKdAa1ID4neI9NXQPDOHwwA+57DqwLiPEVy2AIyWzAk0CQ8qx4awO0VUURwLtA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.4.0" + lodash "^4.17.11" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-hoist-variables@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.0.tgz#25b621399ae229869329730a62015bbeb0a6fbd6" + integrity sha512-/NErCuoe/et17IlAQFKWM24qtyYYie7sFIrW/tIQXpck6vAu2hhtYYsKLBWQV+BQZMbcIYPU/QMYuTufrY4aQw== + dependencies: + "@babel/types" "^7.4.0" + +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" + integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.1.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz#ab2f8e8d231409f8370c883d20c335190284b963" + integrity sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/template" "^7.2.2" + "@babel/types" "^7.2.2" + lodash "^4.17.10" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" + integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg== + dependencies: + lodash "^4.17.10" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.0.tgz#4f56adb6aedcd449d2da9399c2dcf0545463b64c" + integrity sha512-PVwCVnWWAgnal+kJ+ZSAphzyl58XrFeSKSAJRiqg5QToTsjL+Xu1f9+RJ+d+Q0aPhPfBGaYfkox66k86thxNSg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.0.0", "@babel/helper-split-export-declaration@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz#571bfd52701f492920d63b7f735030e9a3e10b55" + integrity sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw== + dependencies: + "@babel/types" "^7.4.0" + +"@babel/helper-wrap-function@^7.1.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.2.0" + +"@babel/helpers@^7.4.0": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.2.tgz#3bdfa46a552ca77ef5a0f8551be5f0845ae989be" + integrity sha512-gQR1eQeroDzFBikhrCccm5Gs2xBjZ57DNjGbqTaHo911IpmSxflOQWMAHPw/TXk8L3isv7s9lYzUkexOeTQUYg== + dependencies: + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.4.0": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.2.tgz#b4521a400cb5a871eab3890787b4bc1326d38d91" + integrity sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + +"@babel/plugin-proposal-object-rest-spread@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.0.tgz#e4960575205eadf2a1ab4e0c79f9504d5b82a97f" + integrity sha512-uTNi8pPYyUH2eWHyYWWSYJKwKg34hhgl4/dbejEjL+64OhbHjTX7wEVWMQl82tEmdDsGeu77+s8HHLS627h6OQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.0.tgz#202d91ee977d760ef83f4f416b280d568be84623" + integrity sha512-h/KjEZ3nK9wv1P1FSNb9G079jXrNYR0Ko+7XkOx85+gM24iZbPn0rh4vCftk+5QKY7y1uByFataBTmX7irEF1w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.5.4" + +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.0.tgz#234fe3e458dce95865c0d152d256119b237834b0" + integrity sha512-EeaFdCeUULM+GPFEsf7pFcNSxM7hYjoj5fiYbyuiXobW4JhFnjAv9OWzNwHyHcKoPNpAfeRDuW6VyaXEDUBa7g== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.0.tgz#164df3bb41e3deb954c4ca32ffa9fcaa56d30bcb" + integrity sha512-AWyt3k+fBXQqt2qb9r97tn3iBwFpiv9xdAiG+Gr2HpAZpuayvbL55yWrsV3MyHvXk/4vmSiedhDRl1YI2Iy5nQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.11" + +"@babel/plugin-transform-classes@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.0.tgz#e3428d3c8a3d01f33b10c529b998ba1707043d4d" + integrity sha512-XGg1Mhbw4LDmrO9rSTNe+uI79tQPdGs0YASlxgweYRLZqo/EQktjaOV4tchL/UZbM0F+/94uOipmdNGoaGOEYg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.4.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.4.0" + "@babel/helper-split-export-declaration" "^7.4.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.0.tgz#acbb9b2418d290107db333f4d6cd8aa6aea00343" + integrity sha512-HySkoatyYTY3ZwLI8GGvkRWCFrjAGXUHur5sMecmCIdIharnlcWWivOqDJI76vvmVZfzwb6G08NREsrY96RhGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49" + integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-for-of@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.0.tgz#56c8c36677f5d4a16b80b12f7b768de064aaeb5f" + integrity sha512-vWdfCEYLlYSxbsKj5lGtzA49K3KANtb8qCPQ1em07txJzsBwY+cKJzBHizj5fl3CCx7vt+WPdgDLTHmydkbQSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-commonjs@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.0.tgz#3b8ec61714d3b75d20c5ccfa157f2c2e087fd4ca" + integrity sha512-iWKAooAkipG7g1IY0eah7SumzfnIT3WNhT4uYB2kIsvHnNSB6MDYVa5qyICSwaTBDBY2c4SnJ3JtEa6ltJd6Jw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/plugin-transform-modules-systemjs@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.0.tgz#c2495e55528135797bc816f5d50f851698c586a1" + integrity sha512-gjPdHmqiNhVoBqus5qK60mWPp1CmYWp/tkh11mvb0rrys01HycEGD7NvvSoKXlWEfSM9TcL36CpsK8ElsADptQ== + dependencies: + "@babel/helper-hoist-variables" "^7.4.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.2.tgz#800391136d6cbcc80728dbdba3c1c6e46f86c12e" + integrity sha512-NsAuliSwkL3WO2dzWTOL1oZJHm0TM8ZY8ZSxk2ANyKkt5SQlToGA4pzctmq1BEjoacurdwZ3xp2dCQWJkME0gQ== + dependencies: + regexp-tree "^0.1.0" + +"@babel/plugin-transform-new-target@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.0.tgz#67658a1d944edb53c8d4fa3004473a0dd7838150" + integrity sha512-6ZKNgMQmQmrEX/ncuCwnnw1yVGoaOW5KpxNhoWI7pCQdA0uZ0HqHGqenCUIENAnxRjy2WwNQ30gfGdIgqJXXqw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + +"@babel/plugin-transform-parameters@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.0.tgz#a1309426fac4eecd2a9439a4c8c35124a11a48a9" + integrity sha512-Xqv6d1X+doyiuCGDoVJFtlZx0onAX0tnc3dY8w71pv/O0dODAbusVv2Ale3cGOwfiyi895ivOBhYa9DhAM8dUA== + dependencies: + "@babel/helper-call-delegate" "^7.4.0" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-regenerator@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.0.tgz#0780e27ee458cc3fdbad18294d703e972ae1f6d1" + integrity sha512-SZ+CgL4F0wm4npojPU6swo/cK4FcbLgxLd4cWpHaNXY/NJ2dpahODCqBbAwb2rDmVszVb3SSjnk9/vik3AYdBw== + dependencies: + regenerator-transform "^0.13.4" + +"@babel/plugin-transform-runtime@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.0.tgz#b4d8c925ed957471bc57e0b9da53408ebb1ed457" + integrity sha512-1uv2h9wnRj98XX3g0l4q+O3jFM6HfayKup7aIu4pnnlzGz0H+cYckGBC74FZIWJXJSXAmeJ9Yu5Gg2RQpS4hWg== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + resolve "^1.8.1" + semver "^5.5.1" + +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" + integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/preset-env@^7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.2.tgz#2f5ba1de2daefa9dcca653848f96c7ce2e406676" + integrity sha512-OEz6VOZaI9LW08CWVS3d9g/0jZA6YCn1gsKIy/fut7yZCJti5Lm1/Hi+uo/U+ODm7g4I6gULrCP+/+laT8xAsA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.4.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.4.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.4.0" + "@babel/plugin-transform-classes" "^7.4.0" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.4.0" + "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.4.0" + "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.4.0" + "@babel/plugin-transform-modules-systemjs" "^7.4.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.2" + "@babel/plugin-transform-new-target" "^7.4.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.4.0" + "@babel/plugin-transform-regenerator" "^7.4.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.2.0" + "@babel/types" "^7.4.0" + browserslist "^4.4.2" + core-js-compat "^3.0.0" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.3.0" + +"@babel/runtime@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" + integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA== + dependencies: + regenerator-runtime "^0.12.0" + +"@babel/runtime@^7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.2.tgz#f5ab6897320f16decd855eed70b705908a313fe8" + integrity sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b" + integrity sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.4.0" + "@babel/types" "^7.4.0" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.0.tgz#14006967dd1d2b3494cdd650c686db9daf0ddada" + integrity sha512-/DtIHKfyg2bBKnIN+BItaIlEg5pjAnzHOIQe5w+rHAw/rg9g0V7T4rqPX8BJPfW11kt3koyjAnTNwCzb28Y1PA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.0" + "@babel/parser" "^7.4.0" + "@babel/types" "^7.4.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" + integrity sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + +"@commitlint/cli@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-7.5.2.tgz#2475cd8f7ed3b2f9c2ab96c06bc24d61d23f8716" + integrity sha512-UQdW/wNb+XeANoYYLyuKEDIfWKSzdhJkPQZ8ie/IjfMNnsP+B23bkX4Ati+6U8zgz0yyngoxWl+3lfExiIL4hQ== + dependencies: + "@commitlint/format" "^7.5.0" + "@commitlint/lint" "^7.5.2" + "@commitlint/load" "^7.5.0" + "@commitlint/read" "^7.5.0" + babel-polyfill "6.26.0" + chalk "2.3.1" + get-stdin "5.0.1" + lodash "4.17.11" + meow "5.0.0" + resolve-from "4.0.0" + resolve-global "0.1.0" + +"@commitlint/config-conventional@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-7.5.0.tgz#3afd4e3e34e5c2f6ec6af03e78ae924fed883ce7" + integrity sha512-odLgBfQ5xntFAmMfAmDY2C4EWhW+cSTbvbsRS7seb55DCa3IaxxSHHC9eXrR+hN/BdUT5vqAxdX1PkR996sq9Q== + +"@commitlint/ensure@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-7.5.2.tgz#57bb7dcbf1e9913e27c3b294325d0d68dd14cebf" + integrity sha512-ZMJKHhSJC789chKy0kWp8EWbCpLPy6vKa+fopUVx+tWL7H8AeBbibXlqAnybg+HWNcb/RD7ORROx0IsgrK4IYA== + dependencies: + lodash "4.17.11" + +"@commitlint/execute-rule@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-7.5.0.tgz#c9cfbab71eb962e1c46e78d76375e32754ab1e38" + integrity sha512-K66aoly8mxSHmBA/Y8bKSPPcCAR4GpJEsvHaLDYOG7GsyChu8NgCD53L8GUqPW8lBCWwnmCiSL+RlOkNHJ0Gag== + dependencies: + babel-runtime "6.26.0" + +"@commitlint/format@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-7.5.0.tgz#57a2b92dc58a3409b2be67c4c8c10bd1b28e9fe8" + integrity sha512-DEeQXfTLUm9kARliCBfw3SlQRAYjK2aXeRAUMs1HPhLA2tjNFFGv6LOpFFNdiu/WV+o1ojcgIvBBjpHaVT+Tvw== + dependencies: + babel-runtime "^6.23.0" + chalk "^2.0.1" + +"@commitlint/is-ignored@^7.5.1": + version "7.5.1" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-7.5.1.tgz#c4f7ffc1c8b4cf9dc3204d22ef8e78ff82536d67" + integrity sha512-8JZCgy6bWSnjOT5cTTiyEAGp+Y4+5CUknhVbyiPxTRbjy6yF0aMKs1gMTfHrNHTKsasgmkCyPQd4C2eOPceuKA== + dependencies: + semver "5.6.0" + +"@commitlint/lint@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-7.5.2.tgz#26cb819c74f8770413c4f6ef1e7abf1b739eda77" + integrity sha512-DY/UfGFDquMno+5c6+tE50rMxpjdQK3CRG+nktgYlVz1UAqeUD+bRc3pvX5HwAsuGvyDrWAjtszHtEDeYJKcjw== + dependencies: + "@commitlint/is-ignored" "^7.5.1" + "@commitlint/parse" "^7.5.0" + "@commitlint/rules" "^7.5.2" + babel-runtime "^6.23.0" + lodash "4.17.11" + +"@commitlint/load@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-7.5.0.tgz#2b225b97d631c2235d8b2084bc2fefb4d4d66719" + integrity sha512-fhBER/rzPsteM6zq5qqMiOi+A2bHKCE/0PKmOzYgaqTKcG9c1SsOle9phPemW85to8Gxd2YgUOVLsZkCMltLtA== + dependencies: + "@commitlint/execute-rule" "^7.5.0" + "@commitlint/resolve-extends" "^7.5.0" + babel-runtime "^6.23.0" + cosmiconfig "^4.0.0" + lodash "4.17.11" + resolve-from "^4.0.0" + +"@commitlint/message@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-7.5.0.tgz#2572fad648c769dd210374c8b95fb37124302bc5" + integrity sha512-5YOhsqy/MgHH7vyDsmmzO6Jr3ygr1pXbCm9NR3XB51wjg55Kd6/6dVlkhS/FmDp99pfwTdHb0TyeDFEjP98waw== + +"@commitlint/parse@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-7.5.0.tgz#d9374266493e5229ec61d92316d28e02419c600f" + integrity sha512-hWASM8SBFTBtlFkKrEtD1qW6yTe2BsfoRiMKuYyRCTd+739TUF17og5vgQVuWttbGP0gXaciW44NygS2YjZmfA== + dependencies: + conventional-changelog-angular "^1.3.3" + conventional-commits-parser "^2.1.0" + lodash "^4.17.11" + +"@commitlint/read@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-7.5.0.tgz#35d563b0f3075da2ce6945978996b16fb4acb0f8" + integrity sha512-uqGFCKZGnBUCTkxoCCJp4MfWUkegXkyT0T0RVM9diyG6uNWPWlMH1509sjLFlyeJKG+cSyYGG/d6T103ScMb4Q== + dependencies: + "@commitlint/top-level" "^7.5.0" + "@marionebl/sander" "^0.6.0" + babel-runtime "^6.23.0" + git-raw-commits "^1.3.0" + +"@commitlint/resolve-extends@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-7.5.0.tgz#d95a3058e83ddbaef5e3045835b9a3a1fba3422c" + integrity sha512-FRIyPuqGvGa03OT4VgOHakizcw8YR5rdm77JsZff1rSnpxk6i+025I6qMeHqCIr5FaVIA0kR3FlC+MJFUs165A== + dependencies: + babel-runtime "6.26.0" + import-fresh "^3.0.0" + lodash "4.17.11" + resolve-from "^4.0.0" + resolve-global "^0.1.0" + +"@commitlint/rules@^7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-7.5.2.tgz#da03d754625b2e67c0a6b8b9ab89eae1952a4f2e" + integrity sha512-eDN1UFPcBOjdnlI3syuo7y99SjGH/dUV6S9NvBocAye8ln5dfKiI2shhWochJhl36r/kYWU8Wrvl2NZJL3c52g== + dependencies: + "@commitlint/ensure" "^7.5.2" + "@commitlint/message" "^7.5.0" + "@commitlint/to-lines" "^7.5.0" + babel-runtime "^6.23.0" + +"@commitlint/to-lines@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-7.5.0.tgz#a24410d25bb85a5fff3b8d610277b3145f899766" + integrity sha512-ZQ3LxPNuQ/J7q42hkiPWN5fUIjWae85H2HHoBB+/Rw1fo+oehvr4Xyt+Oa9Mx5WbBnev/wXnUFjXgoadv1RZ5A== + +"@commitlint/top-level@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-7.5.0.tgz#01e740167e3d15110794192cd754f49f27d4a16d" + integrity sha512-oTu185GufTYHjTXPHu6k6HL7iuASOvDOtQizZWRSxj0VXuoki6e0HzvGZsRsycDTOn04Q9hVu+PhF83IUwRpeg== + dependencies: + find-up "^2.1.0" + +"@goto-bus-stop/common-shake@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@goto-bus-stop/common-shake/-/common-shake-2.2.0.tgz#01deb388b0d7d00a66a00e032ae9b6adfc0c3cad" + integrity sha512-AlNzclZ0UebzHyxYfHSKqmlwCtwcECirZDLhN96gGuj5oHAkba/27+4AlCWyXaycM9cUh12L8/2vjmvjn60pkQ== + dependencies: + acorn "^5.1.1" + debug "^2.6.8" + escope "^3.6.0" + +"@marionebl/sander@^0.6.0": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@marionebl/sander/-/sander-0.6.1.tgz#1958965874f24bc51be48875feb50d642fc41f7b" + integrity sha1-GViWWHTyS8Ub5Ih1/rUNZC/EH3s= + dependencies: + graceful-fs "^4.1.3" + mkdirp "^0.5.1" + rimraf "^2.5.2" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "11.12.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.12.0.tgz#ec5594728811dc2797e42396cfcdf786f2052c12" + integrity sha512-Lg00egj78gM+4aE0Erw05cuDbvX9sLJbaaPwwRtdCdAMnIudqrQZ0oZX98Ek0yiSK/A2nubHgJfvII/rTT2Dwg== + +"@types/unist@*", "@types/unist@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" + integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + +"@types/vfile-message@*": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/vfile-message/-/vfile-message-1.0.1.tgz#e1e9895cc6b36c462d4244e64e6d0b6eaf65355a" + integrity sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA== + dependencies: + "@types/node" "*" + "@types/unist" "*" + +"@types/vfile@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/vfile/-/vfile-3.0.2.tgz#19c18cd232df11ce6fa6ad80259bc86c366b09b9" + integrity sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw== + dependencies: + "@types/node" "*" + "@types/unist" "*" + "@types/vfile-message" "*" + +Base64@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/Base64/-/Base64-1.0.2.tgz#82a36d43f4b98659d72488afe008a905d2cbccdb" + integrity sha512-WufIun24IbKXKBCGmxau2cYAaGLJ1GJjXcqTUyUzYiQImCreWwvTagnZd9k3nHGPAdPxpvC+4FNN1OhQH2Vz7g== + +JSON2@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/JSON2/-/JSON2-0.1.0.tgz#8d7493040a63d5835af75f47decb83ab6c8c0790" + integrity sha1-jXSTBApj1YNa919H3suDq2yMB5A= + +JSONStream@^1.0.3, JSONStream@^1.0.4, JSONStream@^1.3.2: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +accepts@~1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.2.13.tgz#e5f1f3928c6d95fd96558c36ec3d9d0de4a6ecea" + integrity sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo= + dependencies: + mime-types "~2.1.6" + negotiator "0.5.3" + +accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== + +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2, acorn-node@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.6.2.tgz#b7d7ceca6f22e6417af933a62cad4de01048d5d2" + integrity sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg== + dependencies: + acorn "^6.0.2" + acorn-dynamic-import "^4.0.0" + acorn-walk "^6.1.0" + xtend "^4.0.1" + +acorn-walk@^6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" + integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== + +acorn@^4.0.0: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= + +acorn@^5.0.0, acorn@^5.1.0, acorn@^5.1.1, acorn@^5.2.1: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.2, acorn@^6.0.7: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + +adm-zip@~0.4.3: + version "0.4.13" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a" + integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw== + +agent-base@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +ajv@^6.9.1: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alce@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/alce/-/alce-1.0.0.tgz#426184c98ee288d0eeac77fd63fed680b667cab6" + integrity sha1-QmGEyY7iiNDurHf9Y/7WgLZnyrY= + dependencies: + esprima "~1.0.4" + estraverse "~1.3.0" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-escapes@^3.0.0, ansi-escapes@^3.1.0, ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +archiver@0.14.x: + version "0.14.4" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-0.14.4.tgz#5b9ddb9f5ee1ceef21cb8f3b020e6240ecb4315c" + integrity sha1-W53bn17hzu8hy487Ag5iQOy0MVw= + dependencies: + async "~0.9.0" + buffer-crc32 "~0.2.1" + glob "~4.3.0" + lazystream "~0.1.0" + lodash "~3.2.0" + readable-stream "~1.0.26" + tar-stream "~1.1.0" + zip-stream "~0.5.0" + +archiver@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-0.12.0.tgz#b8ccde2508cab9092bb7106630139c0f39a280cc" + integrity sha1-uMzeJQjKuQkrtxBmMBOcDzmigMw= + dependencies: + async "~0.9.0" + buffer-crc32 "~0.2.1" + glob "~4.0.6" + lazystream "~0.1.0" + lodash "~2.4.1" + readable-stream "~1.0.26" + tar-stream "~1.0.0" + zip-stream "~0.4.0" + +archiver@~0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-0.7.1.tgz#cf152d794f86bbd93f9858da60d36aaeabad9bbf" + integrity sha1-zxUteU+Gu9k/mFjaYNNqrqutm78= + dependencies: + file-utils "~0.1.5" + lazystream "~0.1.0" + lodash "~2.4.1" + readable-stream "~1.0.24" + zip-stream "~0.2.0" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" + integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas= + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-differ@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-2.1.0.tgz#4b9c1c3f14b906757082925769e8ab904f4801b1" + integrity sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w== + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + +array-iterate@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.2.tgz#f66a57e84426f8097f4197fbb6c051b8e5cdf7d8" + integrity sha512-1hWSHTIlG/8wtYD+PPX5AOBtKWngpDFjrsrHgZpe+JdgNGz0udYu6ZIkAa/xuenIUEqFv7DvE2Yr60jxweJSrQ== + +array-map@0.0.0, array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= + +array-union@^1.0.1, array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" + integrity sha1-VZvhg3bQik7E2+gId9J4GGObLfc= + +assert-plus@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" + integrity sha1-7nQAlBMALYTOxyGcasgRgS5yMWA= + +assert@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assert@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.3.0.tgz#03939a622582a812cc202320a0b9a56c9b815849" + integrity sha1-A5OaYiWCqBLMICMgoLmlbJuBWEk= + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-metadata-inferer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz#66e24fae9d30ca961fac4880b7fc466f09b25165" + integrity sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw== + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.0, async-each@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.2.tgz#8b8a7ca2a658f927e9f307d6d1a42f4199f0f735" + integrity sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg== + +async@0.9.x, async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + +async@1.x: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@~0.2.6, async@~0.2.7, async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +asyncreduce@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/asyncreduce/-/asyncreduce-0.1.4.tgz#18210e01978bfdcba043955497a5cd315c0a6a41" + integrity sha1-GCEOAZeL/cugQ5VUl6XNMVwKakE= + dependencies: + runnel "~0.5.0" + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +author-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" + integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA= + +aws-sign2@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63" + integrity sha1-xXED96F/wDfwLXwuZLYC6iI/fWM= + +babel-polyfill@6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-runtime@6.26.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babelify@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/babelify/-/babelify-10.0.0.tgz#fe73b1a22583f06680d8d072e25a1e0d1d1d7fb5" + integrity sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg== + +bail@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3" + integrity sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth-connect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz#fdb0b43962ca7b40456a7c2bb48fe173da2d2122" + integrity sha1-/bC0OWLKe0BFanwrtI/hc9otISI= + +batch@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.0.tgz#fd2e05a7a5d696b4db9314013e285d8ff3557ec3" + integrity sha1-/S4Fp6XWlrTbkxQBPihdj/NVfsM= + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bl@^0.9.0, bl@~0.9.0: + version "0.9.5" + resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054" + integrity sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ= + dependencies: + readable-stream "~1.0.26" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.18.3, body-parser@^1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +body-parser@~1.12.3: + version "1.12.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.12.4.tgz#090700c4ba28862a8520ef378395fdee5f61c229" + integrity sha1-CQcAxLoohiqFIO83g5X97l9hwik= + dependencies: + bytes "1.0.0" + content-type "~1.0.1" + debug "~2.2.0" + depd "~1.0.1" + iconv-lite "0.4.8" + on-finished "~2.2.1" + qs "2.4.2" + raw-body "~2.0.1" + type-is "~1.6.2" + +boom@0.4.x: + version "0.4.2" + resolved "https://registry.yarnpkg.com/boom/-/boom-0.4.2.tgz#7a636e9ded4efcefb19cef4947a3c67dfaee911b" + integrity sha1-emNune1O/O+xnO9JR6PGffrukRs= + dependencies: + hoek "0.9.x" + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-pack-flat@^3.0.9: + version "3.3.0" + resolved "https://registry.yarnpkg.com/browser-pack-flat/-/browser-pack-flat-3.3.0.tgz#87536bf5929f4c16cda2445a190feae4fc86a0d9" + integrity sha512-jb9JQVHAvSD3EuehjyIOUCyevHXHSmuAbmefLHMmul3QLu1f5sqx25oC9D0df1N8zMPl9fAppaJdC8vrM4PeUA== + dependencies: + JSONStream "^1.3.2" + combine-source-map "^0.8.0" + convert-source-map "^1.5.1" + count-lines "^0.1.2" + dedent "^0.7.0" + estree-is-member-expression "^1.0.0" + estree-is-require "^1.0.0" + esutils "^2.0.2" + path-parse "^1.0.5" + scope-analyzer "^2.0.0" + stream-combiner "^0.2.2" + through2 "^2.0.3" + transform-ast "^2.4.2" + umd "^3.0.3" + wrap-comment "^1.0.0" + +browser-pack@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-5.0.1.tgz#4197719b20c6e0aaa09451c5111e53efb6fbc18d" + integrity sha1-QZdxmyDG4KqglFHFER5T77b7wY0= + dependencies: + JSONStream "^1.0.3" + combine-source-map "~0.6.1" + defined "^1.0.0" + through2 "^1.0.0" + umd "^3.0.0" + +browser-pack@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.1.0.tgz#c34ba10d0b9ce162b5af227c7131c92c2ecd5774" + integrity sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA== + dependencies: + JSONStream "^1.0.3" + combine-source-map "~0.8.0" + defined "^1.0.0" + safe-buffer "^5.1.1" + through2 "^2.0.0" + umd "^3.0.0" + +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browser-resolve@^1.11.0, browser-resolve@^1.7.0: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= + +browser-unpack@^1.1.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/browser-unpack/-/browser-unpack-1.4.2.tgz#7a708774dc7448df1c24a735d65d409708b95ce2" + integrity sha512-uHkiY4bmXjjBBWoKH1aRnEGTQxUUCCcVtoJfH9w1lmGGjETY4u93Zk+GRYkCE/SRMrdoMTINQ/1/manr/3aMVA== + dependencies: + acorn-node "^1.5.2" + concat-stream "^1.5.0" + minimist "^1.1.1" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-istanbul@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/browserify-istanbul/-/browserify-istanbul-0.1.5.tgz#01c8e31d6a358ee5150f4321c3f28995a964c39f" + integrity sha1-AcjjHWo1juUVD0Mhw/KJlalkw58= + dependencies: + istanbul "^0.2.8" + minimatch "^0.2.14" + through "^2.3.4" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@~0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + integrity sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0= + dependencies: + pako "~0.2.0" + +browserify-zlib@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserify@13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-13.0.0.tgz#8f223bb24ff4ee4335e6bea9671de294e43ba6a3" + integrity sha1-jyI7sk/07kM15r6pZx3ilOQ7pqM= + dependencies: + JSONStream "^1.0.3" + assert "~1.3.0" + browser-pack "^6.0.1" + browser-resolve "^1.11.0" + browserify-zlib "~0.1.2" + buffer "^4.1.0" + concat-stream "~1.5.1" + console-browserify "^1.1.0" + constants-browserify "~1.0.0" + crypto-browserify "^3.0.0" + defined "^1.0.0" + deps-sort "^2.0.0" + domain-browser "~1.1.0" + duplexer2 "~0.1.2" + events "~1.1.0" + glob "^5.0.15" + has "^1.0.0" + htmlescape "^1.1.0" + https-browserify "~0.0.0" + inherits "~2.0.1" + insert-module-globals "^7.0.0" + isarray "0.0.1" + labeled-stream-splicer "^2.0.0" + module-deps "^4.0.2" + os-browserify "~0.1.1" + parents "^1.0.1" + path-browserify "~0.0.0" + process "~0.11.0" + punycode "^1.3.2" + querystring-es3 "~0.2.0" + read-only-stream "^2.0.0" + readable-stream "^2.0.2" + resolve "^1.1.4" + shasum "^1.0.0" + shell-quote "^1.4.3" + stream-browserify "^2.0.0" + stream-http "^2.0.0" + string_decoder "~0.10.0" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "~0.0.0" + url "~0.11.0" + util "~0.10.1" + vm-browserify "~0.0.1" + xtend "^4.0.0" + +browserify@^13.0.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-13.3.0.tgz#b5a9c9020243f0c70e4675bec8223bc627e415ce" + integrity sha1-tanJAgJD8McORnW+yCI7xifkFc4= + dependencies: + JSONStream "^1.0.3" + assert "^1.4.0" + browser-pack "^6.0.1" + browser-resolve "^1.11.0" + browserify-zlib "~0.1.2" + buffer "^4.1.0" + cached-path-relative "^1.0.0" + concat-stream "~1.5.1" + console-browserify "^1.1.0" + constants-browserify "~1.0.0" + crypto-browserify "^3.0.0" + defined "^1.0.0" + deps-sort "^2.0.0" + domain-browser "~1.1.0" + duplexer2 "~0.1.2" + events "~1.1.0" + glob "^7.1.0" + has "^1.0.0" + htmlescape "^1.1.0" + https-browserify "~0.0.0" + inherits "~2.0.1" + insert-module-globals "^7.0.0" + labeled-stream-splicer "^2.0.0" + module-deps "^4.0.8" + os-browserify "~0.1.1" + parents "^1.0.1" + path-browserify "~0.0.0" + process "~0.11.0" + punycode "^1.3.2" + querystring-es3 "~0.2.0" + read-only-stream "^2.0.0" + readable-stream "^2.0.2" + resolve "^1.1.4" + shasum "^1.0.0" + shell-quote "^1.6.1" + stream-browserify "^2.0.0" + stream-http "^2.0.0" + string_decoder "~0.10.0" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "~0.0.0" + url "~0.11.0" + util "~0.10.1" + vm-browserify "~0.0.1" + xtend "^4.0.0" + +browserify@^16.2.3: + version "16.2.3" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.2.3.tgz#7ee6e654ba4f92bce6ab3599c3485b1cc7a0ad0b" + integrity sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ== + dependencies: + JSONStream "^1.0.3" + assert "^1.4.0" + browser-pack "^6.0.1" + browser-resolve "^1.11.0" + browserify-zlib "~0.2.0" + buffer "^5.0.2" + cached-path-relative "^1.0.0" + concat-stream "^1.6.0" + console-browserify "^1.1.0" + constants-browserify "~1.0.0" + crypto-browserify "^3.0.0" + defined "^1.0.0" + deps-sort "^2.0.0" + domain-browser "^1.2.0" + duplexer2 "~0.1.2" + events "^2.0.0" + glob "^7.1.0" + has "^1.0.0" + htmlescape "^1.1.0" + https-browserify "^1.0.0" + inherits "~2.0.1" + insert-module-globals "^7.0.0" + labeled-stream-splicer "^2.0.0" + mkdirp "^0.5.0" + module-deps "^6.0.0" + os-browserify "~0.3.0" + parents "^1.0.1" + path-browserify "~0.0.0" + process "~0.11.0" + punycode "^1.3.2" + querystring-es3 "~0.2.0" + read-only-stream "^2.0.0" + readable-stream "^2.0.2" + resolve "^1.1.4" + shasum "^1.0.0" + shell-quote "^1.6.1" + stream-browserify "^2.0.0" + stream-http "^2.0.0" + string_decoder "^1.1.1" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "0.0.1" + url "~0.11.0" + util "~0.10.1" + vm-browserify "^1.0.0" + xtend "^4.0.0" + +browserslist@^4.4.2, browserslist@^4.5.1, browserslist@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.5.2.tgz#36ad281f040af684555a23c780f5c2081c752df0" + integrity sha512-zmJVLiKLrzko0iszd/V4SsjTaomFeoVzQGYYOYgRgsbh7WNh95RgDB0CmBdFWYs/3MyFSt69NypjL/h3iaddKQ== + dependencies: + caniuse-lite "^1.0.30000951" + electron-to-chromium "^1.3.116" + node-releases "^1.1.11" + +buf-compare@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + integrity sha1-/vKNqLgROgoNtEMLC2Rntpcws0o= + +buffer-crc32@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.1.tgz#be3e5382fc02b6d6324956ac1af98aa98b08534c" + integrity sha1-vj5TgvwCttYySVasGvmKqYsIU0w= + +buffer-crc32@~0.2.1: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.1.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@^5.0.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bundle-collapser@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bundle-collapser/-/bundle-collapser-1.3.0.tgz#f4b4ff58b2f22ee7701b20fa76306e23f53a3fb6" + integrity sha1-9LT/WLLyLudwGyD6djBuI/U6P7Y= + dependencies: + browser-pack "^5.0.1" + browser-unpack "^1.1.0" + concat-stream "^1.5.0" + falafel "^2.1.0" + minimist "^1.1.1" + through2 "^2.0.0" + +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@0.2.1, bytes@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-0.2.1.tgz#555b08abcb063f8975905302523e4cd4ffdfdf31" + integrity sha1-VVsIq8sGP4l1kFMCUj5M1P/f3zE= + +bytes@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" + integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g= + +bytes@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.1.0.tgz#ac93c410e2ffc9cc7cf4b464b38289067f5e47b4" + integrity sha1-rJPEEOL/ycx89LRks4KJBn9eR7Q= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cached-path-relative@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.2.tgz#a13df4196d26776220cc3356eb147a52dba2c6db" + integrity sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg== + +caching-transform@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-3.0.2.tgz#601d46b91eca87687a281e71cef99791b0efca70" + integrity sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w== + dependencies: + hasha "^3.0.0" + make-dir "^2.0.0" + package-hash "^3.0.0" + write-file-atomic "^2.4.2" + +call-matcher@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.1.0.tgz#23b2c1bc7a8394c8be28609d77ddbd5786680432" + integrity sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw== + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" + integrity sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw== + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^4.0.0, camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.2.0.tgz#e7522abda5ed94cc0489e1b8466610e88404cf45" + integrity sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ== + +caniuse-db@^1.0.30000951: + version "1.0.30000954" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000954.tgz#ab9b0000d92a055747f380701684b9c9d017fca4" + integrity sha512-Rwd/JRb1/7wXzSOS5AQHXp4RBWXeNNPZW/9Gmv1kfO14ayrssFOM+vbu/0CPkYOCSZK6QZGMlrzaXznGLPkBAA== + +caniuse-lite@^1.0.30000951, caniuse-lite@^1.0.30000954: + version "1.0.30000954" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000954.tgz#227c2743e40f07c71e6683b6ca9491bfd5755b8e" + integrity sha512-Wopmc0eVSSG1d9/O4JTn0OmGhUfhEHNkHhoCjUrGSImvHI+2YQWkOI1RRNTUFNSHbSAD8J41jbdZrPP4r32cbQ== + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +caseless@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.6.0.tgz#8167c1ab8397fb5bb95f96d28e5a81c50f247ac4" + integrity sha1-gWfBq4OX+1u5X5bSjlqBxQ8kesQ= + +ccount@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" + integrity sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw== + +chalk@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" + integrity sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g== + dependencies: + ansi-styles "^3.2.0" + escape-string-regexp "^1.0.5" + supports-color "^5.2.0" + +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +char-split@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/char-split/-/char-split-0.2.0.tgz#8755eda641e5db277dd0f509b517c827e50a8edf" + integrity sha1-h1XtpkHl2yd90PUJtRfIJ+UKjt8= + dependencies: + through "2.3.4" + +character-entities-html4@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.2.tgz#c44fdde3ce66b52e8d321d6c1bf46101f0150610" + integrity sha512-sIrXwyna2+5b0eB9W149izTPJk/KkJTg6mEzDGibwBUkyH1SbDa+nf515Ppdi3MaH35lW0JFJDWeq9Luzes1Iw== + +character-entities-legacy@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz#7c6defb81648498222c9855309953d05f4d63a9c" + integrity sha512-9NB2VbXtXYWdXzqrvAHykE/f0QJxzaKIpZ5QzNZrrgQ7Iyxr2vnfS8fCBNVW9nUEZE0lo57nxKRqnzY/dKrwlA== + +character-entities@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363" + integrity sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ== + +character-reference-invalid@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed" + integrity sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ== + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.0.0, chokidar@^2.0.3: + version "2.1.5" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" + integrity sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" + integrity sha1-jffHquUf02h06PjQW5GAvBGj/tc= + dependencies: + escape-string-regexp "^1.0.5" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.0.0, cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +co@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/co/-/co-3.1.0.tgz#4ea54ea5a08938153185e15210c68d9092bc1b78" + integrity sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +codecov@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.2.0.tgz#4465ee19884528092d8c313e1f9e4bdc7d3065cd" + integrity sha512-3NJvNARXxilqnqVfgzDHyVrF4oeVgaYW1c1O6Oi5mn93exE7HTSSFNiYdwojWW6IwrCZABJ8crpNbKoo9aUHQw== + dependencies: + argv "^0.0.2" + ignore-walk "^3.0.1" + js-yaml "^3.12.0" + teeny-request "^3.7.0" + urlgrey "^0.4.4" + +collapse-white-space@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" + integrity sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +colors@*: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +colors@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" + integrity sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w= + +combine-source-map@^0.8.0, combine-source-map@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b" + integrity sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos= + dependencies: + convert-source-map "~1.1.0" + inline-source-map "~0.6.0" + lodash.memoize "~3.0.3" + source-map "~0.5.3" + +combine-source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.6.1.tgz#9b4a09c316033d768e0f11e029fa2730e079ad96" + integrity sha1-m0oJwxYDPXaODxHgKfonMOB5rZY= + dependencies: + convert-source-map "~1.1.0" + inline-source-map "~0.5.0" + lodash.memoize "~3.0.3" + source-map "~0.4.2" + +combined-stream@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +combined-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" + integrity sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8= + dependencies: + delayed-stream "0.0.5" + +commander@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-1.3.2.tgz#8a8f30ec670a6fdd64af52f1914b907d79ead5b5" + integrity sha1-io8w7GcKb91kr1LxkUuQfXnq1bU= + dependencies: + keypress "0.1.x" + +commander@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" + integrity sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E= + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.14.1, commander@^2.19.0, commander@^2.8.1, commander@^2.9.0, commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +common-shakeify@^0.5.2: + version "0.5.4" + resolved "https://registry.yarnpkg.com/common-shakeify/-/common-shakeify-0.5.4.tgz#b232cc760ad24e8dccc0e4e04d6e0509e12909a4" + integrity sha512-R2cFjh+3kwuNPO1QAQCFhkdu8iIQxl3cnEXO185F7cETg/CgM8OgvPI9QHtiXdDmXpfuJQ9CTGds/BqGDrvWcQ== + dependencies: + "@goto-bus-stop/common-shake" "^2.2.0" + convert-source-map "^1.5.1" + through2 "^2.0.3" + transform-ast "^2.4.3" + wrap-comment "^1.0.1" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + integrity sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg= + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +compress-commons@~0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-0.1.6.tgz#0c740870fde58cba516f0ac0c822e33a0b85dfa3" + integrity sha1-DHQIcP3ljLpRbwrAyCLjOguF36M= + dependencies: + buffer-crc32 "~0.2.1" + crc32-stream "~0.3.1" + readable-stream "~1.0.26" + +compress-commons@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-0.2.9.tgz#422d927430c01abd06cd455b6dfc04cb4cf8003c" + integrity sha1-Qi2SdDDAGr0GzUVbbfwEy0z4ADw= + dependencies: + buffer-crc32 "~0.2.1" + crc32-stream "~0.3.1" + node-int64 "~0.3.0" + readable-stream "~1.0.26" + +compressible@~2.0.3: + version "2.0.16" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.16.tgz#a49bf9858f3821b64ce1be0296afc7380466a77f" + integrity sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA== + dependencies: + mime-db ">= 1.38.0 < 2" + +compression@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.5.0.tgz#ccc1a54788da1b3ad7729c49f6a00b3ac9adf47f" + integrity sha1-zMGlR4jaGzrXcpxJ9qALOsmt9H8= + dependencies: + accepts "~1.2.9" + bytes "2.1.0" + compressible "~2.0.3" + debug "~2.2.0" + on-headers "~1.0.0" + vary "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0, concat-stream@^1.5.1, concat-stream@^1.5.2, concat-stream@^1.6.0, concat-stream@^1.6.1, concat-stream@~1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +concat-stream@~1.5.0, concat-stream@~1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + integrity sha1-cIl4Yk2FavQaWnQd790mHadSwmY= + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +connect@2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-2.12.0.tgz#31d8fa0dcacdf1908d822bd2923be8a2d2a7ed9a" + integrity sha1-Mdj6DcrN8ZCNgivSkjvootKn7Zo= + dependencies: + batch "0.5.0" + buffer-crc32 "0.2.1" + bytes "0.2.1" + cookie "0.1.0" + cookie-signature "1.0.1" + debug ">= 0.7.3 < 1" + fresh "0.2.0" + methods "0.1.0" + multiparty "2.2.0" + negotiator "0.3.0" + pause "0.0.1" + qs "0.6.6" + raw-body "1.1.2" + send "0.1.4" + uid2 "0.0.3" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@^1.0.2, content-type@~1.0.1, content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +conventional-changelog-angular@^1.3.3: + version "1.6.6" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f" + integrity sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg== + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-commits-parser@^2.1.0: + version "2.1.7" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz#eca45ed6140d72ba9722ee4132674d639e644e8e" + integrity sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ== + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +convert-source-map@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.0.0.tgz#dbdcb69523d3af582f7b5c94b3c25ecf2f3b7355" + integrity sha1-29y2lSPTr1gve1yUs8Jezy87c1U= + +convert-source-map@^1.1.0, convert-source-map@^1.1.1, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@~1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" + integrity sha1-SCnId+n+SbMWHzvzZziI4gRpmGA= + +cookie-parser@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.4.tgz#e6363de4ea98c3def9697b93421c09f30cf5d188" + integrity sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw== + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + +cookie-signature@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.1.tgz#44e072148af01e6e8e24afbf12690d68ae698ecb" + integrity sha1-ROByFIrwHm6OJK+/EmkNaK5pjss= + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.0.tgz#90eb469ddce905c866de687efc43131d8801f9d0" + integrity sha1-kOtGndzpBchm3mh+/EMTHYgB+dA= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookiejar@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-1.3.0.tgz#dd00b35679021e99cbd4e855b9ad041913474765" + integrity sha1-3QCzVnkCHpnL1OhVua0EGRNHR2U= + +cookiejar@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-assert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" + integrity sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8= + dependencies: + buf-compare "^1.0.0" + is-error "^2.2.0" + +core-js-compat@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.0.0.tgz#cd9810b8000742535a4a43773866185e310bd4f7" + integrity sha512-W/Ppz34uUme3LmXWjMgFlYyGnbo1hd9JvA0LNQ4EmieqVjg2GPYbj3H6tcdP2QGPGWdRKUqZVbVKLNIFVs/HiA== + dependencies: + browserslist "^4.5.1" + core-js "3.0.0" + core-js-pure "3.0.0" + semver "^5.6.0" + +core-js-pure@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.0.0.tgz#a5679adb4875427c8c0488afc93e6f5b7125859b" + integrity sha512-yPiS3fQd842RZDgo/TAKGgS0f3p2nxssF1H65DIZvZv0Od5CygP8puHXn3IQiM/39VAvgCbdaMQpresrbGgt9g== + +core-js@3.0.0, core-js@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0.tgz#a8dbfa978d29bfc263bfb66c556d0ca924c28957" + integrity sha512-WBmxlgH2122EzEJ6GH8o9L/FeoUKxxxZ6q6VUxoTlsE4EvbTWKJb447eyVxTEuq0LpXjlq/kCB2qgBvsYRkLvQ== + +core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0: + version "2.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" + integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + +cosmiconfig@^5.0.2, cosmiconfig@^5.0.7: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.0.tgz#45038e4d28a7fe787203aede9c25bca4a08b12c8" + integrity sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.0" + parse-json "^4.0.0" + +count-lines@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/count-lines/-/count-lines-0.1.2.tgz#e33493fb6860a82f7159d8237843fbfaefee5962" + integrity sha1-4zST+2hgqC9xWdgjeEP7+u/uWWI= + +crc32-stream@~0.3.1: + version "0.3.4" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-0.3.4.tgz#73bc25b45fac1db6632231a7bfce8927e9f06552" + integrity sha1-c7wltF+sHbZjIjGnv86JJ+nwZVI= + dependencies: + buffer-crc32 "~0.2.1" + readable-stream "~1.0.24" + +crc@3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" + integrity sha1-naHpgOO9RPxck79as9ozeNheRms= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-env@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" + integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== + dependencies: + cross-spawn "^6.0.5" + is-windows "^1.0.0" + +cross-spawn@^4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@0.2.x: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c" + integrity sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw= + dependencies: + boom "0.4.x" + +crypto-browserify@^3.0.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +ctype@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" + integrity sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + integrity sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc= + dependencies: + number-is-nan "^1.0.0" + +dash-ast@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-1.0.0.tgz#12029ba5fb2f8aa6f0a861795b23c1b4b6c27d37" + integrity sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA== + +date-fns@^1.27.2: + version "1.30.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" + integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +debug@*, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@0.7.4, debug@~0.7.2, debug@~0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" + integrity sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk= + +debug@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.1.0.tgz#33ab915659d8c2cc8a41443d94d6ebd37697ed21" + integrity sha1-M6uRVlnYwsyKQUQ9lNbr03aX7SE= + dependencies: + ms "0.6.2" + +debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= + dependencies: + ms "2.0.0" + +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +"debug@>= 0.7.3 < 1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.8.1.tgz#20ff4d26f5e422cb68a1bacbbb61039ad8c1c130" + integrity sha1-IP9NJvXkIstoobrLu2EDmtjBwTA= + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + integrity sha1-+HBX6ZWxofauaklgZkE3vFbwOdo= + dependencies: + ms "0.7.1" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-extend@~0.2.5: + version "0.2.11" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.2.11.tgz#7a16ba69729132340506170494bc83f7076fe08f" + integrity sha1-eha6aXKRMjQFBhcElLyD9wdv4I8= + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deep-strict-equal@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz#4a078147a8ab57f6a0d4f5547243cd22f44eb4e4" + integrity sha1-SgeBR6irV/ag1PVUckPNIvROtOQ= + dependencies: + core-assert "^0.2.0" + +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delayed-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f" + integrity sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8= + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.0.1.tgz#80aec64c9d6d97e65cc2a9caa93c0aa6abf73aaa" + integrity sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo= + +depd@~1.1.1, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +deps-sort@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5" + integrity sha1-CRckkC6EZYJg65EHSMzNGvbiH7U= + dependencies: + JSONStream "^1.0.3" + shasum "^1.0.0" + subarg "^1.0.0" + through2 "^2.0.0" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detective@^4.0.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" + integrity sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig== + dependencies: + acorn "^5.2.1" + defined "^1.0.0" + +detective@^5.0.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" + integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg== + dependencies: + acorn-node "^1.6.1" + defined "^1.0.0" + minimist "^1.1.1" + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +domain-browser@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domain-browser@~1.1.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + integrity sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw= + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.5.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ee-first@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.0.tgz#6a0d7c6221e490feefd92ec3f441c9ce8cd097f4" + integrity sha1-ag18YiHkkP7v2S7D9EHJzozQl/Q= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.116: + version "1.3.120" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.120.tgz#ee94e683f4686683674be0f626a5e468cccf7d15" + integrity sha512-p1pgKOSSgcROCRiZoJ5H5wFmhqdA0L3yLL9mlfcmdA4V60IDCrsvhNqN8rLPe9e3B772Gm02kBkL1GM/g2lENg== + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emitter-component@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/emitter-component/-/emitter-component-1.0.0.tgz#f04dd18fc3dc3e9a74cbc0f310b088666e4c016f" + integrity sha1-8E3Rj8PcPpp0y8DzELCIZm5MAW8= + +"emoji-regex@>=6.0.0 <=6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" + integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +enhance-visitors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/enhance-visitors/-/enhance-visitors-1.0.0.tgz#aa945d05da465672a1ebd38fee2ed3da8518e95a" + integrity sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo= + dependencies: + lodash "^4.13.1" + +env-editor@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/env-editor/-/env-editor-0.3.1.tgz#30d0540c2101414f258a94d4c0a524c06c13e3c6" + integrity sha1-MNBUDCEBQU8lipTUwKUkwGwT48Y= + +envify@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/envify/-/envify-4.1.0.tgz#f39ad3db9d6801b4e6b478b61028d3f0b6819f7e" + integrity sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw== + dependencies: + esprima "^4.0.0" + through "~2.3.4" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-1.3.6.tgz#e0e73b93e417138d1cd7c0b746b1a4a14854c292" + integrity sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI= + dependencies: + stackframe "^0.3.1" + +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.49" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.49.tgz#059a239de862c94494fec28f8150c977028c6c5e" + integrity sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "^1.0.0" + +es6-error@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3, es6-map@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-promise@^4.0.3: + version "4.2.6" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" + integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +es6-set@^0.1.5, es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@1.3.x: + version "1.3.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23" + integrity sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM= + dependencies: + esprima "~1.1.1" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.33" + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escodegen@^1.6.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" + integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-ast-utils@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz#3d58ba557801cfb1c941d68131ee9f8c34bd1586" + integrity sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA== + dependencies: + lodash.get "^4.4.2" + lodash.zip "^4.2.0" + +eslint-config-prettier@^3.3.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz#8ca3ffac4bd6eeef623a0651f9d754900e3ec217" + integrity sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ== + dependencies: + get-stdin "^6.0.0" + +eslint-config-xo-lass@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/eslint-config-xo-lass/-/eslint-config-xo-lass-1.0.3.tgz#2259fed4d18ef18ec00560360358aba538fb5ac6" + integrity sha512-hnry5qIMaVXAIt0QJwoTcRbny8E9x7K1GKW790ZLnAOWS42PK5BL5POpIG/NuumjwL/J5ThVgZpeVn8tFevhzw== + +eslint-config-xo@^0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/eslint-config-xo/-/eslint-config-xo-0.26.0.tgz#19dcfb1e3038dd440f5c5e4b4d11bb3128801b24" + integrity sha512-l+93kmBSNr5rMrsqwC6xVWsi8LI4He3z6jSk38e9bAkMNsVsQ8XYO+qzXfJFgFX4i/+hiTswyHtl+nDut9rPaA== + +eslint-formatter-pretty@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-formatter-pretty/-/eslint-formatter-pretty-2.1.1.tgz#0794a1009195d14e448053fe99667413b7d02e44" + integrity sha512-gWfagucSWBn82WxzwFloBTLAcwYDgnpAfiV5pQfyAV5YpZikuLflRU8nc3Ts9wnNvLhwk4blzb42/C495Yw7BA== + dependencies: + ansi-escapes "^3.1.0" + chalk "^2.1.0" + eslint-rule-docs "^1.1.5" + log-symbols "^2.0.0" + plur "^3.0.1" + string-width "^2.0.0" + supports-hyperlinks "^1.0.1" + +eslint-import-resolver-node@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49" + integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w== + dependencies: + debug "^2.6.8" + pkg-dir "^2.0.0" + +eslint-plugin-ava@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-ava/-/eslint-plugin-ava-5.1.1.tgz#709a03f6c56f9f316d83ebc739952cc28cea979a" + integrity sha512-3N7geVdXTabpngQOl+ih1ejMbFOXCUYROnTIP66KAQoMcEAkPSXYc/Jwo/qC4zpRR7PXMuf5afMzTEBpyZmWzQ== + dependencies: + arrify "^1.0.1" + deep-strict-equal "^0.2.0" + enhance-visitors "^1.0.0" + esm "^3.0.82" + espree "^4.0.0" + espurify "^1.8.1" + import-modules "^1.1.0" + is-plain-object "^2.0.4" + multimatch "^2.1.0" + pkg-up "^2.0.0" + +eslint-plugin-compat@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-compat/-/eslint-plugin-compat-3.1.0.tgz#3a0a0490bd8cb08eb06cbbe840ad612227ccadf2" + integrity sha512-N+FiugxY5Y8CKp6/sk76KtIFlA2fMx8Ogb3FqbwOePND6mnnkxZL/iPMC/3QhPtuq10RVNduYOmKU9laqna5+A== + dependencies: + "@babel/runtime" "^7.4.2" + ast-metadata-inferer "^0.1.1" + browserslist "^4.5.2" + caniuse-db "^1.0.30000951" + mdn-browser-compat-data "^0.0.72" + semver "^5.6.0" + +eslint-plugin-es@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" + integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== + dependencies: + eslint-utils "^1.3.0" + regexpp "^2.0.1" + +eslint-plugin-eslint-comments@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.1.tgz#32ff0afba8a48e17073817e6d03fbc5622f735b7" + integrity sha512-GZDKhOFqJLKlaABX+kdoLskcTINMrVOWxGca54KcFb1QCPd0CLmqgAMRxkkUfGSmN+5NJUMGh7NGccIMcWPSfQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + +eslint-plugin-import@^2.14.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f" + integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A== + dependencies: + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.3.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" + read-pkg-up "^2.0.0" + resolve "^1.9.0" + +eslint-plugin-no-use-extend-native@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.4.0.tgz#ececdf248a2336555a554f7b1217a612240c4eaf" + integrity sha512-9W2747CwC7aTJknLKY6ftdzj3AZz8DSaa64zONOMIemxH7YRr0+hqrvsNtHK/v9DusPuMxM9y9hBnfHwzKFmww== + dependencies: + is-get-set-prop "^1.0.0" + is-js-type "^2.0.0" + is-obj-prop "^1.0.0" + is-proto-prop "^2.0.0" + +eslint-plugin-node@^8.0.0, eslint-plugin-node@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz#55ae3560022863d141fa7a11799532340a685964" + integrity sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w== + dependencies: + eslint-plugin-es "^1.3.1" + eslint-utils "^1.3.1" + ignore "^5.0.2" + minimatch "^3.0.4" + resolve "^1.8.1" + semver "^5.5.0" + +eslint-plugin-prettier@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz#19d521e3981f69dd6d14f64aec8c6a6ac6eb0b0d" + integrity sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-promise@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" + integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== + +eslint-plugin-unicorn@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-7.1.0.tgz#9efef5c68fde0ebefb0241fbcfa274f1b959c04e" + integrity sha512-lW/ZwGR638V0XuZgR160qVQvPtw8tw3laKT5LjJPt+W+tN7kVf2S2V7x+ZrEEwSjEb3OiEzb3cppzaKuYtgYeg== + dependencies: + clean-regexp "^1.0.0" + eslint-ast-utils "^1.0.0" + import-modules "^1.1.0" + lodash.camelcase "^4.1.1" + lodash.kebabcase "^4.0.1" + lodash.snakecase "^4.0.1" + lodash.upperfirst "^4.2.0" + safe-regex "^2.0.1" + +eslint-rule-docs@^1.1.5: + version "1.1.85" + resolved "https://registry.yarnpkg.com/eslint-rule-docs/-/eslint-rule-docs-1.1.85.tgz#ba8a4629457da916b361576495670428c125984a" + integrity sha512-CrNaaB1aYymFbuyMkEDC2u/+p8T7UrIbi9u6ASTjoIYD6zLhPXHttYAwjS+8D+1FDMXjf03ByT04MUMlqUDKng== + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.0, eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^5.12.0, eslint@^5.15.3: + version "5.15.3" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.3.tgz#c79c3909dc8a7fa3714fb340c11e30fd2526b8b5" + integrity sha512-vMGi0PjCHSokZxE0NLp2VneGw5sio7SSiDNgIUn2tC0XkWJRNOIoHIg3CliLVfXnJsiHxGAYrkw0PieAu8+KYQ== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +esm@^3.0.82: + version "3.2.20" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.20.tgz#44f125117863427cdece7223baa411fc739c1939" + integrity sha512-NA92qDA8C/qGX/xMinDGa3+cSPs4wQoFxskRrSnDo/9UloifhONFm4sl4G+JsyCqM007z2K+BfQlH5rMta4K1Q== + +espree@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" + integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== + dependencies: + acorn "^6.0.2" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@1.2.x: + version "1.2.5" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9" + integrity sha1-CZNQL+r2aBODJXVvMPmlH+7sEek= + +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + integrity sha1-n1V+CPw7TSbs6d00+Pv0drYlha0= + +esprima@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" + integrity sha1-W28VR/TRAuZw4UDFCb5ncdautUk= + +espurify@^1.3.0, espurify@^1.6.0, espurify@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.8.1.tgz#5746c6c1ab42d302de10bd1d5bf7f0e8c0515056" + integrity sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg== + dependencies: + core-js "^2.0.0" + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +estraverse@~1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.3.2.tgz#37c2b893ef13d723f276d878d60d8535152a6c42" + integrity sha1-N8K4k+8T1yPydth41g2FNRUqbEI= + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + integrity sha1-hno+jlip+EYYr7bC3bzZFrfLr3E= + +estree-is-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/estree-is-function/-/estree-is-function-1.0.0.tgz#c0adc29806d7f18a74db7df0f3b2666702e37ad2" + integrity sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA== + +estree-is-identifier@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/estree-is-identifier/-/estree-is-identifier-1.0.0.tgz#50433fa88d3d00a1bf7a1d7df6e4e67f36aa89f7" + integrity sha512-2BDRGrkQJV/NhCAmmE33A35WAaxq3WQaGHgQuD//7orGWfpFqj8Srkwvx0TH+20yIdOF1yMQwi8anv5ISec2AQ== + +estree-is-member-expression@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/estree-is-member-expression/-/estree-is-member-expression-1.0.0.tgz#e724721e0a14949d363915fd71448eaa6312f590" + integrity sha512-Ec+X44CapIGExvSZN+pGkmr5p7HwUVQoPQSd458Lqwvaf4/61k/invHSh4BYK8OXnCkfEhWuIoG5hayKLQStIg== + +estree-is-require@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/estree-is-require/-/estree-is-require-1.0.0.tgz#fce2c6126d141d1f9316e8c07799d7f0a55bb69b" + integrity sha512-oWxQdSEmnUwNZsDQYiBNpVxKEhMmsJQSSxnDrwsr1MWtooCLfhgzsNGzmokdmfK0EzEIS5V4LPvqxv1Kmb1vvA== + dependencies: + estree-is-identifier "^1.0.0" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + integrity sha1-gVHTWOIMisx/t0XnRywAJf5JZXA= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg= + +events@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-2.1.0.tgz#2a9a1e18e6106e0e812aa9ebd4a819b3c29c0ba5" + integrity sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg== + +events@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + integrity sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA== + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +express-session@^1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.15.6.tgz#47b4160c88f42ab70fe8a508e31cbff76757ab0a" + integrity sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA== + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + crc "3.4.4" + debug "2.6.9" + depd "~1.1.1" + on-headers "~1.0.1" + parseurl "~1.3.2" + uid-safe "~2.1.5" + utils-merge "1.0.1" + +express-state@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/express-state/-/express-state-1.0.3.tgz#b6f368743a95d8a91b7683adf593d02b1577ec02" + integrity sha1-tvNodDqV2KkbdoOt9ZPQKxV37AI= + +express@3.4.8: + version "3.4.8" + resolved "https://registry.yarnpkg.com/express/-/express-3.4.8.tgz#aa7a8986de07053337f4bc5ed9a6453d9cc8e2e1" + integrity sha1-qnqJht4HBTM39Lxe2aZFPZzI4uE= + dependencies: + buffer-crc32 "0.2.1" + commander "1.3.2" + connect "2.12.0" + cookie "0.1.0" + cookie-signature "1.0.1" + debug ">= 0.7.3 < 1" + fresh "0.2.0" + merge-descriptors "0.0.1" + methods "0.1.0" + mkdirp "0.3.5" + range-parser "0.0.4" + send "0.1.4" + +express@4.x, express@^4.16.4: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-object@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/extend-object/-/extend-object-1.0.0.tgz#42514f84015d1356caf5187969dfb2bc1bda0823" + integrity sha1-QlFPhAFdE1bK9Rh5ad+yvBvaCCM= + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@3.0.2, extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extend@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-1.3.0.tgz#d1516fb0ff5624d2ebf9123ea1dac5a1994004f8" + integrity sha1-0VFvsP9WJNLr+RI+odrFoZlABPg= + +extend@~2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-2.0.2.tgz#1b74985400171b85554894459c978de6ef453ab7" + integrity sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ== + +external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +falafel@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.1.0.tgz#96bb17761daba94f46d001738b3cedf3a67fe06c" + integrity sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw= + dependencies: + acorn "^5.0.0" + foreach "^2.0.5" + isarray "0.0.1" + object-keys "^1.0.6" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.6.tgz#a5d5b697ec8deda468d85a74035290a025a95295" + integrity sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fault@^1.0.0, fault@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.2.tgz#c3d0fec202f172a3a4d414042ad2bb5e2a3ffbaa" + integrity sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw== + dependencies: + format "^0.2.2" + +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-utils@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/file-utils/-/file-utils-0.1.5.tgz#dc8153c855387cb4dacb0a1725531fa444a6b48c" + integrity sha1-3IFTyFU4fLTaywoXJVMfpESmtIw= + dependencies: + findup-sync "~0.1.2" + glob "~3.2.6" + iconv-lite "~0.2.11" + isbinaryfile "~0.1.9" + lodash "~2.1.0" + minimatch "~0.2.12" + rimraf "~2.2.2" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fileset@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.1.8.tgz#506b91a9396eaa7e32fb42a84077c7a0c736b741" + integrity sha1-UGuRqTluqn4y+0KoQHfHoMc2t0E= + dependencies: + glob "3.x" + minimatch "0.x" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +find-cache-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-nearest-file@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-nearest-file/-/find-nearest-file-1.0.0.tgz#bf539d7d0f02996631fa2196680f6776762b9f70" + integrity sha1-v1OdfQ8CmWYx+iGWaA9ndnYrn3A= + +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +findup-sync@~0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.1.3.tgz#7f3e7a97b82392c653bf06589bd85190e93c3683" + integrity sha1-fz56l7gjksZTvwZYm9hRkOk8NoM= + dependencies: + glob "~3.2.9" + lodash "~2.4.1" + +firefox-profile@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/firefox-profile/-/firefox-profile-0.2.7.tgz#fe46afc2ed6a96f62c5c3bd446fa259f6014a909" + integrity sha1-/kavwu1qlvYsXDvURvoln2AUqQk= + dependencies: + adm-zip "~0.4.3" + archiver "~0.7.1" + async "~0.2.9" + fs-extra "~0.8.1" + lazystream "~0.1.0" + node-uuid "~1.4.1" + wrench "~1.5.1" + xml2js "~0.4.0" + +fixpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fixpack/-/fixpack-2.3.1.tgz#53f03d88aab7d5123259282f0088a9a3b19836c2" + integrity sha1-U/A9iKq31RIyWSgvAIipo7GYNsI= + dependencies: + alce "1.0.0" + colors "*" + extend-object "^1.0.0" + rc "^0.6.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" + integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== + +fn-name@^2.0.1, fn-name@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forEachAsync@~2.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/forEachAsync/-/forEachAsync-2.2.1.tgz#e3723f00903910e1eb4b1db3ad51b5c64a319fec" + integrity sha1-43I/AJA5EOHrSx2zrVG1xkoxn+w= + dependencies: + sequence "2.x" + +foreach-shim@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/foreach-shim/-/foreach-shim-0.1.1.tgz#be61d75f46abb7176f5abd295e35885751b71d94" + integrity sha1-vmHXX0artxdvWr0pXjWIV1G3HZQ= + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + +forever-agent@~0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130" + integrity sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA= + +form-data@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@~0.0.3: + version "0.0.10" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.0.10.tgz#db345a5378d86aeeb1ed5d553b869ac192d2f5ed" + integrity sha1-2zRaU3jYau6x7V1VO4aawZLS9e0= + dependencies: + async "~0.2.7" + combined-stream "~0.0.4" + mime "~1.2.2" + +form-data@~0.1.0: + version "0.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12" + integrity sha1-kavXiKupcCsaq/qLwBAxoqyeOxI= + dependencies: + async "~0.9.0" + combined-stream "~0.0.4" + mime "~1.2.11" + +format@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= + +formidable@1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.0.14.tgz#2b3f4c411cbb5fdd695c44843e2a23514a43231a" + integrity sha1-Kz9MQRy7X91pXESEPiojUUpDIxo= + +formidable@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659" + integrity sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg== + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.2.0.tgz#bfd9402cf3df12c4a4c310c79f99a3dde13d34a7" + integrity sha1-v9lALPPfEsSkwxDHn5mj3eE9NKc= + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2-string@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/from2-string/-/from2-string-1.1.0.tgz#18282b27d08a267cb3030cd2b8b4b0f212af752a" + integrity sha1-GCgrJ9CKJnyzAwzSuLSw8hKvdSo= + dependencies: + from2 "^2.0.3" + +from2@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@~0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.8.1.tgz#0e5779ffbfedf511bc755595c7f03c06d4b43e8d" + integrity sha1-Dld5/7/t9RG8dVWVx/A8BtS0Po0= + dependencies: + jsonfile "~1.1.0" + mkdirp "0.3.x" + ncp "~0.4.2" + rimraf "~2.2.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-readdir-recursive@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.0.0, fsevents@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" + integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-assigned-identifiers@^1.1.0, get-assigned-identifiers@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1" + integrity sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" + integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + +get-set-props@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-set-props/-/get-set-props-0.1.0.tgz#998475c178445686d0b32246da5df8dbcfbe8ea3" + integrity sha1-mYR1wXhEVobQsyJG2l3428++jqM= + +get-stdin@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +git-raw-commits@^1.3.0: + version "1.3.6" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.6.tgz#27c35a32a67777c1ecd412a239a6c19d71b95aff" + integrity sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg== + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +github-slugger@^1.0.0, github-slugger@^1.2.0, github-slugger@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.1.tgz#47e904e70bf2dccd0014748142d31126cfd49508" + integrity sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ== + dependencies: + emoji-regex ">=6.0.0 <=6.1.1" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@3.x, glob@~3.2.6, glob@~3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= + dependencies: + inherits "2" + minimatch "0.3" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg= + dependencies: + 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" + +glob@^5.0.10, glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.2, glob@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + 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@~4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.0.6.tgz#695c50bdd4e2fb5c5d370b091f388d3707e291a7" + integrity sha1-aVxQvdTi+1xdNwsJHziNNwfikac= + dependencies: + graceful-fs "^3.0.2" + inherits "2" + minimatch "^1.0.0" + once "^1.3.0" + +glob@~4.3.0: + version "4.3.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.3.5.tgz#80fbb08ca540f238acce5d11d1e9bc41e75173d3" + integrity sha1-gPuwjKVA8jiszl0R0em8QedRc9M= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +globals@^11.1.0, globals@^11.7.0: + version "11.11.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" + integrity sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.1.0.tgz#e90f4d5134109e6d855abdd31bdb1b085428592e" + integrity sha512-VtYjhHr7ncls724Of5W6Kaahz0ag7dB4G62/2HsN+xEKG6SrPzM1AJMerGxQTwJGnN9reeyxdvXbuZYpfssCvg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.1" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +globs-to-files@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/globs-to-files/-/globs-to-files-1.0.0.tgz#54490f6d1f4b9fd2de9d99445146ffb37550380d" + integrity sha1-VEkPbR9Ln9LenZlEUUb/s3VQOA0= + dependencies: + array-uniq "~1.0.2" + asyncreduce "~0.1.4" + glob "^5.0.10" + xtend "^4.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + integrity sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg= + dependencies: + natives "^1.1.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +handlebars@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-1.0.12.tgz#18c6d3440c35e91b19b3ff582b9151ab4985d4fc" + integrity sha1-GMbTRAw16RsZs/9YK5FRq0mF1Pw= + dependencies: + optimist "~0.3" + uglify-js "~2.3" + +handlebars@1.3.x: + version "1.3.0" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-1.3.0.tgz#9e9b130a93e389491322d975cf3ec1818c37ce34" + integrity sha1-npsTCpPjiUkTItl1zz7BgYw3zjQ= + dependencies: + optimist "~0.3" + optionalDependencies: + uglify-js "~2.3" + +handlebars@^4.0.1, handlebars@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.1.tgz#6e4e41c18ebe7719ae4d38e5aca3d32fa3dd23d3" + integrity sha512-3Zhi6C0euYZL5sM0Zcy7lInLXKQ+YLcF/olbN010mzGQ4XVm50JeyBnMqofHh696GrciGruC7kCcApPDJvVgwA== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" + integrity sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac= + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasha@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" + integrity sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk= + dependencies: + is-stream "^1.0.1" + +hawk@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-1.1.1.tgz#87cd491f9b46e4e2aeaca335416766885d2d1ed9" + integrity sha1-h81JH5tG5OKurKM1QWdmiF0tHtk= + dependencies: + boom "0.4.x" + cryptiles "0.2.x" + hoek "0.9.x" + sntp "0.2.x" + +hbs@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/hbs/-/hbs-2.4.0.tgz#f4c956cb660d6974dc61214b7c49a21f6aaa3f51" + integrity sha1-9MlWy2YNaXTcYSFLfEmiH2qqP1E= + dependencies: + handlebars "1.0.12" + walk "2.2.1" + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +highlight.js@7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-7.5.0.tgz#0052595eef15845d842e02a03313afadc3ebd6cc" + integrity sha1-AFJZXu8VhF2ELgKgMxOvrcPr1sw= + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@0.9.x: + version "0.9.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505" + integrity sha1-PTIkYrrfB3Fup+uFuviAec3c5QU= + +hosted-git-info@^2.1.4, hosted-git-info@^2.5.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +htmlescape@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" + integrity sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E= + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy@1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.11.2.tgz#c50d2fb06eca79d4238e66fd94393d2e41e63740" + integrity sha1-xQ0vsG7KedQjjmb9lDk9LkHmN0A= + dependencies: + eventemitter3 "1.x.x" + requires-port "0.x.x" + +http-signature@~0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66" + integrity sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY= + dependencies: + asn1 "0.1.11" + assert-plus "^0.1.5" + ctype "0.5.3" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https-browserify@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" + integrity sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI= + +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-duration@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-2.4.0.tgz#04da89e6784af1c881b06ebc9f494dda07b08a17" + integrity sha1-BNqJ5nhK8ciBsG68n0lN2gewihc= + +husky@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" + integrity sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg== + dependencies: + cosmiconfig "^5.0.7" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^2.0.0" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.4.8: + version "0.4.8" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.8.tgz#c6019a7595f2cefca702eab694a010bcd9298d20" + integrity sha1-xgGadZXyzvynAuq2lKAQvNkpjSA= + +iconv-lite@^0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@~0.2.11: + version "0.2.11" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8" + integrity sha1-HOYKOleGSiktEyH/RgnKS7llrcg= + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^3.2.0: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.3, ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.0.2, ignore@^5.0.5: + version "5.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.6.tgz#562dacc7ec27d672dde433aa683c543b24c17694" + integrity sha512-/+hp3kUf/Csa32ktIaj0OlRqQxrgs30n62M90UBpNd9k+ENEch5S+hmbW3DtcJGz3sYFTh4F3A6fQ0q7KWsp4w== + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-modules@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/import-modules/-/import-modules-1.1.0.tgz#748db79c5cc42bb9701efab424f894e72600e9dc" + integrity sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inline-source-map@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.5.0.tgz#4a4c5dd8e4fb5e9b3cda60c822dfadcaee66e0af" + integrity sha1-Skxd2OT7Xps82mDIIt+tyu5m4K8= + dependencies: + source-map "~0.4.0" + +inline-source-map@~0.6.0: + version "0.6.2" + resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5" + integrity sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU= + dependencies: + source-map "~0.5.3" + +inquirer@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" + integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.11" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.0.0" + through "^2.3.6" + +insert-module-globals@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.0.tgz#ec87e5b42728479e327bd5c5c71611ddfb4752ba" + integrity sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw== + dependencies: + JSONStream "^1.0.3" + acorn-node "^1.5.2" + combine-source-map "^0.8.0" + concat-stream "^1.6.1" + is-buffer "^1.1.0" + path-is-absolute "^1.0.1" + process "~0.11.0" + through2 "^2.0.0" + undeclared-identifiers "^1.1.2" + xtend "^4.0.0" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= + +irregular-plurals@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" + integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= + +irregular-plurals@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-2.0.0.tgz#39d40f05b00f656d0b7fa471230dd3b714af2872" + integrity sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-alphabetical@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.2.tgz#1fa6e49213cb7885b75d15862fb3f3d96c884f41" + integrity sha512-V0xN4BYezDHcBSKb1QHUFMlR4as/XEuCZBzMJUU4n7+Cbt33SmUnSol+pnXFvLxSHNq2CemUXNdaXV6Flg7+xg== + +is-alphanumeric@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4" + integrity sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ= + +is-alphanumerical@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz#1138e9ae5040158dc6ff76b820acd6b7a181fd40" + integrity sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.0, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-decimal@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff" + integrity sha512-TRzl7mOCchnhchN+f3ICUCzYvL9ul7R+TYOsZ8xia++knyZAJfv/uA1FvQXsAnYIl1T3B2X5E/J7Wb1QXiIBXg== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-empty@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-empty/-/is-empty-1.2.0.tgz#de9bb5b278738a05a0b09a57e1fb4d4a341a9f6b" + integrity sha1-3pu1snhzigWgsJpX4ftNSjQan2s= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-error@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" + integrity sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw= + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-get-set-prop@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz#2731877e4d78a6a69edcce6bb9d68b0779e76312" + integrity sha1-JzGHfk14pqae3M5rudaLB3nnYxI= + dependencies: + get-set-props "^0.1.0" + lowercase-keys "^1.0.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz#b6e710d7d07bb66b98cb8cece5c9b4921deeb835" + integrity sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A== + +is-hidden@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-hidden/-/is-hidden-1.1.1.tgz#82ee6a93aeef3fb007ad5b9457c0584d45329f38" + integrity sha512-175UKecS8+U4hh2PSY0j4xnm2GKYzvSKnbh+naC93JjuBA7LgIo6YxlbcsSo6seFBdQO3RuIcH980yvqqD/2cA== + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-js-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-js-type/-/is-js-type-2.0.0.tgz#73617006d659b4eb4729bba747d28782df0f7e22" + integrity sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI= + dependencies: + js-types "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj-prop@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-obj-prop/-/is-obj-prop-1.0.0.tgz#b34de79c450b8d7c73ab2cdf67dc875adb85f80e" + integrity sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4= + dependencies: + lowercase-keys "^1.0.0" + obj-props "^1.0.0" + +is-obj@^1.0.0, is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-proto-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-proto-prop/-/is-proto-prop-2.0.0.tgz#99ab2863462e44090fd083efd1929058f9d935e1" + integrity sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg== + dependencies: + lowercase-keys "^1.0.0" + proto-props "^2.0.0" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + dependencies: + text-extensions "^1.0.0" + +is-url@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-whitespace-character@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed" + integrity sha512-SzM+T5GKUCtLhlHFKt2SDAX2RFzfS6joT91F2/WSi9LxgFdsnhfPK/UIA+JhRR2xuyLdrCys2PiFDrtn1fU5hQ== + +is-windows@^1.0.0, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-word-character@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.2.tgz#46a5dac3f2a1840898b91e576cd40d493f3ae553" + integrity sha512-T3FlsX8rCHAH8e7RE7PfOPZVFQlcV3XRF9eOOBQ1uf70OxO7CjjSOjeImMPCADBdYWcStAbVbYvJ1m2D3tb+EA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.4.tgz#38e7bcbb0f3ba1b7933c86ba1894ddfc3781bbb7" + integrity sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA== + +isbinaryfile@~0.1.9: + version "0.1.9" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-0.1.9.tgz#15eece35c4ab708d8924da99fb874f2b5cc0b6c4" + integrity sha1-Fe7ONcSrcI2JJNqZ+4dPK1zAtsQ= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +istanbul-lib-coverage@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" + integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw== + +istanbul-lib-hook@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz#e0e581e461c611be5d0e5ef31c5f0109759916fb" + integrity sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA== + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" + integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" + istanbul-lib-coverage "^2.0.3" + semver "^5.5.0" + +istanbul-lib-report@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4" + integrity sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA== + dependencies: + istanbul-lib-coverage "^2.0.3" + make-dir "^1.3.0" + supports-color "^6.0.0" + +istanbul-lib-source-maps@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz#f1e817229a9146e8424a28e5d69ba220fda34156" + integrity sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.3" + make-dir "^1.3.0" + rimraf "^2.6.2" + source-map "^0.6.1" + +istanbul-middleware@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/istanbul-middleware/-/istanbul-middleware-0.2.2.tgz#83c4c13c128e1a0d6a147792391af3c15a8ab8e0" + integrity sha1-g8TBPBKOGg1qFHeSORrzwVqKuOA= + dependencies: + archiver "0.14.x" + body-parser "~1.12.3" + express "4.x" + istanbul "0.4.x" + +istanbul-reports@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9" + integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw== + dependencies: + handlebars "^4.1.0" + +istanbul@0.4.x: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +istanbul@^0.2.8: + version "0.2.16" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.2.16.tgz#870545a0d4f4b4ce161039e9e805a98c2c700bd9" + integrity sha1-hwVFoNT0tM4WEDnp6AWpjCxwC9k= + dependencies: + abbrev "1.0.x" + async "0.9.x" + escodegen "1.3.x" + esprima "1.2.x" + fileset "0.1.x" + handlebars "1.3.x" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + resolve "0.7.x" + which "1.0.x" + wordwrap "0.0.x" + +js-levenshtein@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-types@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/js-types/-/js-types-1.0.0.tgz#d242e6494ed572ad3c92809fc8bed7f7687cbf03" + integrity sha1-0kLmSU7Vcq08koCfyL7X92h8vwM= + +js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.6.1, js-yaml@^3.9.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e" + integrity sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stable-stringify@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45" + integrity sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + +json5@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonfile@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-1.1.1.tgz#da4fd6ad77f1a255203ea63c7bc32dc31ef64433" + integrity sha1-2k/WrXfxolUgPqY8e8Mtwx72RDM= + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +keypress@0.1.x: + version "0.1.0" + resolved "https://registry.yarnpkg.com/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a" + integrity sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +labeled-stream-splicer@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz#9cffa32fd99e1612fd1d86a8db962416d5292926" + integrity sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg== + dependencies: + inherits "^2.0.1" + isarray "^2.0.4" + stream-splicer "^2.0.0" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +lazystream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-0.1.0.tgz#1b25d63c772a4c20f0a5ed0a9d77f484b6e16920" + integrity sha1-GyXWPHcqTCDwpe0KnXf0hLbhaSA= + dependencies: + readable-stream "~1.0.2" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +levenshtein-edit-distance@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/levenshtein-edit-distance/-/levenshtein-edit-distance-1.0.0.tgz#895baf478cce8b5c1a0d27e45d7c1d978a661e49" + integrity sha1-iVuvR4zOi1waDSfkXXwdl4pmHkk= + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +line-column-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/line-column-path/-/line-column-path-1.0.0.tgz#383b83fca8488faa7a59940ebf28b82058c16c55" + integrity sha1-ODuD/KhIj6p6WZQOvyi4IFjBbFU= + +lint-staged@^8.1.5: + version "8.1.5" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.5.tgz#372476fe1a58b8834eb562ed4c99126bd60bdd79" + integrity sha512-e5ZavfnSLcBJE1BTzRTqw6ly8OkqVyO3GL2M6teSmTBYQ/2BuueD5GIt2RPsP31u/vjKdexUyDCxSyK75q4BDA== + dependencies: + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "^5.0.2" + debug "^3.1.0" + dedent "^0.7.0" + del "^3.0.0" + execa "^1.0.0" + find-parent-dir "^0.3.0" + g-status "^2.0.2" + is-glob "^4.0.0" + is-windows "^1.0.2" + listr "^0.14.2" + listr-update-renderer "^0.5.0" + lodash "^4.17.11" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.2" + string-argv "^0.0.2" + stringify-object "^3.2.2" + yup "^0.26.10" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.2: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +load-plugin@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/load-plugin/-/load-plugin-2.3.0.tgz#577b6a956b344fd2ae80d8ecff5944febeea8eb7" + integrity sha512-OxHNMfT3aeHFSpzeMQRcE40kXULv3KA8fGgnySC+rO3Be+0oMWkcRKMJ5zWzUCTuUnabCsQyJzNjo/BLdbmRxA== + dependencies: + npm-prefix "^1.2.0" + resolve-from "^4.0.0" + +load-script@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/load-script/-/load-script-0.0.5.tgz#cbd54b27cd7309902b749640c70e996f4c643b63" + integrity sha1-y9VLJ81zCZArdJZAxw6Zb0xkO2M= + +localtunnel@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.5.0.tgz#5be949779325e9f3273021a3f38d2e7a8dcd7c4f" + integrity sha1-W+lJd5Ml6fMnMCGj840ueo3NfE8= + dependencies: + debug "0.7.4" + optimist "0.3.4" + request "2.11.4" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._isnative@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" + integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw= + +lodash._objecttypes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" + integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE= + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._shimkeys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" + integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.camelcase@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c= + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.defaults@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-2.4.1.tgz#a7e8885f05e68851144b6e12a8f3678026bc4c54" + integrity sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ= + dependencies: + lodash._objecttypes "~2.4.1" + lodash.keys "~2.4.1" + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isobject@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" + integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.kebabcase@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.keys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" + integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc= + dependencies: + lodash._isnative "~2.4.1" + lodash._shimkeys "~2.4.1" + lodash.isobject "~2.4.1" + +lodash.memoize@~3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" + integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8= + +lodash.mergewith@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" + integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== + +lodash.snakecase@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= + +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + integrity sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A= + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + integrity sha1-K01OlbpEDZFf8IvImeRVNmZxMxY= + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash.upperfirst@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" + integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= + +lodash.zip@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" + integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= + +lodash@3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= + +lodash@4.17.11, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.2.1: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +lodash@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.1.0.tgz#0637eaaa36a8a1cfc865c3adfb942189bfb0998d" + integrity sha1-Bjfqqjaooc/IZcOt+5Qhib+wmY0= + +lodash@~2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4= + +lodash@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.2.0.tgz#4bf50a3243f9aeb0bac41a55d3d5990675a462fb" + integrity sha1-S/UKMkP5rrC6xBpV09WZBnWkYvs= + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^2.0.0, log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + +longest-streak@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e" + integrity sha512-TmYTeEYxiAmSVdpbnQDXGtvYOIRsCMg89CVZzwzc2o7GFL1CjoiRPjH5ec0NFAVlAx3fVof9dX/t6KKRAo2OWA== + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +magic-string@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.23.2.tgz#204d7c3ea36c7d940209fcc54c39b9f243f13369" + integrity sha512-oIUZaAxbcxYIp4AyLafV6OVKoB3YouZs0UTCJ8mOKBHNyJgGDaMJ4TgA+VylJh6fx7EQCC52XkbURxxG9IoJXA== + dependencies: + sourcemap-codec "^1.4.1" + +make-dir@^1.0.0, make-dir@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-escapes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122" + integrity sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA== + +markdown-extensions@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" + integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== + +markdown-table@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.2.tgz#c78db948fa879903a41bce522e3b96f801c63786" + integrity sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw== + +marked@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.6.1.tgz#a63addde477bca9613028de4b2bc3629e53a0562" + integrity sha512-+H0L3ibcWhAZE02SKMqmvYsErLo4EAVJxu5h3bHBBDvvjeWXtl92rGUSBYHL2++5Y+RSNgl8dYOAXcYe7lp1fA== + +match-casing@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/match-casing/-/match-casing-1.0.1.tgz#baa22d0b0279b848bf63e7cc33dd19f161377d8e" + integrity sha512-zUroBN1AtMqqtIOb2qfwgncEuUAG7b5wQ1J9/D8jYRxbdvUZnpuRIlkqFyrX/1RbWJNzERwHG4BMj2LTtZW48g== + +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdast-comment-marker@^1.0.0, mdast-comment-marker@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-comment-marker/-/mdast-comment-marker-1.1.0.tgz#81129dd4182eaeafbd40bb1f79be4da587a1dc52" + integrity sha512-NqHAs8nmu08I6MGzpKzgTd9qiCP7oshkyzQrlZxLMsLPUOPjp/Zb/ZtorKD0oOJ38vdZxFCdOlXvlDf77AqEDg== + +mdast-util-compact@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.2.tgz#c12ebe16fffc84573d3e19767726de226e95f649" + integrity sha512-d2WS98JSDVbpSsBfVvD9TaDMlqPRz7ohM/11G0rp5jOBb5q96RJ6YLszQ/09AAixyzh23FeIpCGqfaamEADtWg== + dependencies: + unist-util-visit "^1.1.0" + +mdast-util-definitions@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.3.tgz#49f936b09207c45b438db19551652934312f04f0" + integrity sha512-P6wpRO8YVQ1iv30maMc93NLh7COvufglBE8/ldcOyYmk5EbfF0YeqlLgtqP/FOBU501Kqar1x5wYWwB3Nga74g== + dependencies: + unist-util-visit "^1.0.0" + +mdast-util-heading-range@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/mdast-util-heading-range/-/mdast-util-heading-range-2.1.2.tgz#eccd6ff96d6231227c8456acd05c4e1b8e7f4c79" + integrity sha512-Zif68w/iFthWHYbCoT+R3Kb5arOzWriIw4Kc2pPmJNgKfmcsBZqc60zN8Kr3+cNlGyS6wJz/v4oJLy9Jm06C5g== + dependencies: + mdast-util-to-string "^1.0.0" + +mdast-util-heading-style@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mdast-util-heading-style/-/mdast-util-heading-style-1.0.4.tgz#8e796de77f91c141691620ebbb5c9140609e3fd2" + integrity sha512-n4fUvwpR5Uj1Ti658KxYDq9gR0UF3FK1UVTVig12imrSOssQU2OpUysje8nps5Cb85b6eau5akpWW7Zkxtv1XA== + +mdast-util-to-nlcst@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/mdast-util-to-nlcst/-/mdast-util-to-nlcst-3.2.2.tgz#71972eecd64dc03d5cf2713f08555e2d9e2d7d10" + integrity sha512-TmJlri8dHt7duRU6jfWBMqf5gW+VZ6o/8GHaWzwdxslseB2lL8bSOiox6c8VwYX5v2E4CzUWm/1GkAYqgbNw9A== + dependencies: + nlcst-to-string "^2.0.0" + repeat-string "^1.5.2" + unist-util-position "^3.0.0" + vfile-location "^2.0.0" + +mdast-util-to-string@^1.0.0, mdast-util-to-string@^1.0.1, mdast-util-to-string@^1.0.2, mdast-util-to-string@^1.0.4, mdast-util-to-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.0.5.tgz#3552b05428af22ceda34f156afe62ec8e6d731ca" + integrity sha512-2qLt/DEOo5F6nc2VFScQiHPzQ0XXcabquRJxKMhKte8nt42o08HUxNDPk7tt0YPxnWjAT11I1SYi0X0iPnfI5A== + +mdast-util-toc@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz#395eeb877f067f9d2165d990d77c7eea6f740934" + integrity sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w== + dependencies: + github-slugger "^1.2.1" + mdast-util-to-string "^1.0.5" + unist-util-is "^2.1.2" + unist-util-visit "^1.1.0" + +mdn-browser-compat-data@^0.0.72: + version "0.0.72" + resolved "https://registry.yarnpkg.com/mdn-browser-compat-data/-/mdn-browser-compat-data-0.0.72.tgz#b1d2026bfbf61c82e71c4157059b9d161c8791a9" + integrity sha512-vt3BxJRpV638ncYLigX91k0qP1VcpKxgExqPtX+QKFvV4/ZruZ31Sl35LsDDq5q+D7Lt7mfGWnCEuZ0d6bJW1g== + dependencies: + extend "3.0.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.2.0.tgz#5ee057680ed9cb8dad8a78d820f9a8897a102025" + integrity sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +meow@5.0.0, meow@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== + dependencies: + 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" + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== + dependencies: + 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" + +merge-descriptors@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-0.0.1.tgz#2ff0980c924cf81d0b5d1fb601177cb8bb56c0d0" + integrity sha1-L/CYDJJM+B0LXR+2ARd8uLtWwNA= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-source-map@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" + integrity sha1-pd5GU42uhNQRTMXqArR3KmNGcB8= + dependencies: + source-map "^0.5.6" + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + +methods@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/methods/-/methods-0.0.1.tgz#277c90f8bef39709645a8371c51c3b6c648e068c" + integrity sha1-J3yQ+L7zlwlkWoNxxRw7bGSOBow= + +methods@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/methods/-/methods-0.1.0.tgz#335d429eefd21b7bacf2e9c922a8d2bd14a30e4f" + integrity sha1-M11Cnu/SG3us8unJIqjSvRSjDk8= + +methods@^1.1.2, methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +"mime-db@>= 1.38.0 < 2", mime-db@~1.38.0: + version "1.38.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" + integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== + +mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.6: + version "2.1.22" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" + integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== + dependencies: + mime-db "~1.38.0" + +mime-types@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce" + integrity sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4= + +mime@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.5.tgz#9eed073022a8bf5e16c8566c6867b8832bfbfa13" + integrity sha1-nu0HMCKov14WyFZsaGe4gyv7+hM= + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" + integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== + +mime@~1.2.11, mime@~1.2.2, mime@~1.2.7, mime@~1.2.9: + version "1.2.11" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" + integrity sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA= + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.0.0.tgz#0913ff0b121db44ef5848242c38bbb35d44cabde" + integrity sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA== + +minify-stream@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minify-stream/-/minify-stream-1.2.0.tgz#23862be654191a9df0d1243a1a98b2d7bb1b8f8f" + integrity sha512-bIjBH7uGROwzWwgtbLO7U/yi+NBTLGs5YYidUiGD9nJZ5wuxX0485c48vtJ7WlNZNnKvHXA1D1ZXpfWJqf4fyg== + dependencies: + concat-stream "^1.6.0" + convert-source-map "^1.5.0" + duplexify "^3.5.1" + from2-string "^1.1.0" + terser "^3.7.5" + xtend "^4.0.1" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimatch@0.x: + version "0.4.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.4.0.tgz#bd2c7d060d2c8c8fd7cde7f1f2ed2d5b270fdb1b" + integrity sha1-vSx9Bg0sjI/Xzefx8u0tWycP2xs= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^0.2.14, minimatch@~0.2.12: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimatch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-1.0.0.tgz#e0dd2120b49e1b724ce8d714c520822a9438576d" + integrity sha1-4N0hILSeG3JM6NcUxSCCKpQ4V20= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc= + dependencies: + brace-expansion "^1.0.0" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" + integrity sha1-Tf/lJdriuGTGbC4jxicdev3s784= + +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1, minimist@~0.0.7: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.3.5, mkdirp@0.3.x: + version "0.3.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= + +mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +module-deps@^4.0.2, module-deps@^4.0.8: + version "4.1.1" + resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-4.1.1.tgz#23215833f1da13fd606ccb8087b44852dcb821fd" + integrity sha1-IyFYM/HaE/1gbMuAh7RIUty4If0= + dependencies: + JSONStream "^1.0.3" + browser-resolve "^1.7.0" + cached-path-relative "^1.0.0" + concat-stream "~1.5.0" + defined "^1.0.0" + detective "^4.0.0" + duplexer2 "^0.1.2" + inherits "^2.0.1" + parents "^1.0.0" + readable-stream "^2.0.2" + resolve "^1.1.3" + stream-combiner2 "^1.1.1" + subarg "^1.0.0" + through2 "^2.0.0" + xtend "^4.0.0" + +module-deps@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-6.2.0.tgz#d41a2e790245ce319171e4e7c4d8c73993ba3cd5" + integrity sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA== + dependencies: + JSONStream "^1.0.3" + browser-resolve "^1.7.0" + cached-path-relative "^1.0.0" + concat-stream "~1.6.0" + defined "^1.0.0" + detective "^5.0.2" + duplexer2 "^0.1.2" + inherits "^2.0.1" + parents "^1.0.0" + readable-stream "^2.0.2" + resolve "^1.4.0" + stream-combiner2 "^1.1.1" + subarg "^1.0.0" + through2 "^2.0.0" + xtend "^4.0.0" + +ms@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.6.2.tgz#d89c2124c6fdc1353d65a8b77bf1aac4b193708c" + integrity sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw= + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + integrity sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg= + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +multer@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.1.tgz#24b12a416a22fec2ade810539184bf138720159e" + integrity sha512-zzOLNRxzszwd+61JFuAo0fxdQfvku12aNJgnla0AQ+hHxFmfc/B7jBVuPr5Rmvu46Jze/iJrFpSOsD7afO8SDw== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + +multi-stage-sourcemap@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz#b09fc8586eaa17f81d575c4ad02e0f7a3f6b1105" + integrity sha1-sJ/IWG6qF/gdV1xK0C4Pej9rEQU= + dependencies: + source-map "^0.1.34" + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multimatch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-3.0.0.tgz#0e2534cc6bc238d9ab67e1b9cd5fcd85a6dbf70b" + integrity sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA== + dependencies: + array-differ "^2.0.3" + array-union "^1.0.2" + arrify "^1.0.1" + minimatch "^3.0.4" + +multiparty@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/multiparty/-/multiparty-2.2.0.tgz#a567c2af000ad22dc8f2a653d91978ae1f5316f4" + integrity sha1-pWfCrwAK0i3I8qZT2Rl4rh9TFvQ= + dependencies: + readable-stream "~1.1.9" + stream-counter "~0.2.0" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +mutexify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mutexify/-/mutexify-1.2.0.tgz#45597975a2b035f56dcf61ff15cc8d73c28e7639" + integrity sha512-oprzxd2zhfrJqEuB98qc1dRMMonClBQ57UPDjnbcrah4orEMTq1jq3+AcdFe5ePzdbJXI7zmdhfftIdMnhYFoQ== + +nan@^2.9.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nanobench@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nanobench/-/nanobench-2.1.1.tgz#c2f23fcce116d50b4998b1954ba114674c137269" + integrity sha512-z+Vv7zElcjN+OpzAxAquUayFLGK3JI/ubCl0Oh64YQqsTGG09CGqieJVQw4ui8huDnnAgrvTv93qi5UaOoNj8A== + dependencies: + browser-process-hrtime "^0.1.2" + chalk "^1.1.3" + mutexify "^1.1.0" + pretty-hrtime "^1.0.2" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natives@^1.1.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb" + integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +ncp@~0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-0.4.2.tgz#abcc6cbd3ec2ed2a729ff6e7c1fa8f01784a8574" + integrity sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ= + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.3.0.tgz#706d692efeddf574d57ea9fb1ab89a4fa7ee8f60" + integrity sha1-cG1pLv7d9XTVfqn7GriaT6fuj2A= + +negotiator@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.5.3.tgz#269d5c476810ec92edbe7b6c2f28316384f9a7e8" + integrity sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g= + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +neo-async@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +next-tick@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +nlcst-is-literal@^1.0.0, nlcst-is-literal@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/nlcst-is-literal/-/nlcst-is-literal-1.1.2.tgz#f941989ca46c6dfc635e96df6b25dcebdb2eb89d" + integrity sha512-eFdFvG7XE/YwPFbRk3ryzinTVGWpAEBQNH/FWc4sVSHXUumZtdSVaJYsz0axK4uF1pmlIAWgYWhzDuQ8NTf79A== + dependencies: + nlcst-to-string "^2.0.0" + +nlcst-normalize@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/nlcst-normalize/-/nlcst-normalize-2.1.2.tgz#5c7413ab5d0b280e1d66f20433377b83d3c0d04c" + integrity sha512-fvXY7r3MsPFoB7nAUxhuBUJ8UC8wzBpWXuPRNL5DYca805CvThsV1wEIbkD9X/t506vvRfL3rRjXnfmbcl7O4Q== + dependencies: + nlcst-to-string "^2.0.0" + +nlcst-search@^1.0.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/nlcst-search/-/nlcst-search-1.5.0.tgz#7769e0adf77b5b0022e98f2dfdf4bebe075ae936" + integrity sha512-2OYlim0rafAJRtwhqUxgwyXskQNSiDHrMWXjUaPzzYwWfG3XnM3OAextLxj0i/iObl1mG4ZAGKY6nwtfogJMzQ== + dependencies: + nlcst-is-literal "^1.1.0" + nlcst-normalize "^2.1.0" + unist-util-visit "^1.0.0" + +nlcst-to-string@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/nlcst-to-string/-/nlcst-to-string-2.0.2.tgz#7125af4d4d369850c697192a658f01f36af9937b" + integrity sha512-DV7wVvMcAsmZ5qEwvX1JUNF4lKkAAKbChwNlIH7NLsPR7LWWoeIt53YlZ5CQH5KDXEXQ9Xa3mw0PbPewymrtew== + +node-fetch@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" + integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + +node-int64@~0.3.0: + version "0.3.3" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.3.3.tgz#2d6e6b2ece5de8588b43d88d1bc41b26cd1fa84d" + integrity sha1-LW5rLs5d6FiLQ9iNG8QbJs0fqE0= + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.11.tgz#9a0841a4b0d92b7d5141ed179e764f42ad22724a" + integrity sha512-8v1j5KfP+s5WOTa1spNUAOfreajQPN12JXbRR0oDE+YrJBQCXBnNqUDj27EKpPLOoSiU3tKi3xGPB+JaOdUEQQ== + dependencies: + semver "^5.3.0" + +node-uuid@~1.4.0, node-uuid@~1.4.1: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= + +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" + integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== + dependencies: + which "^1.2.10" + +npm-prefix@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/npm-prefix/-/npm-prefix-1.2.0.tgz#e619455f7074ba54cc66d6d0d37dd9f1be6bcbc0" + integrity sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A= + dependencies: + rc "^1.1.0" + shellsubstitute "^1.1.0" + untildify "^2.1.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +number-to-words@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/number-to-words/-/number-to-words-1.2.4.tgz#e0f124de9628f8d86c4eeb89bac6c07699264501" + integrity sha512-/fYevVkXRcyBiZDg6yzZbm0RuaD6i0qRfn8yr+6D0KgBMOndFPxuW10qCHpzs50nN8qKuv78k8MuotZhcVX6Pw== + +nyc@^13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-13.3.0.tgz#da4dbe91a9c8b9ead3f4f3344c76f353e3c78c75" + integrity sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w== + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^3.0.1" + convert-source-map "^1.6.0" + find-cache-dir "^2.0.0" + find-up "^3.0.0" + foreground-child "^1.5.6" + glob "^7.1.3" + istanbul-lib-coverage "^2.0.3" + istanbul-lib-hook "^2.0.3" + istanbul-lib-instrument "^3.1.0" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.2" + istanbul-reports "^2.1.1" + make-dir "^1.3.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.1.0" + uuid "^3.3.2" + yargs "^12.0.5" + yargs-parser "^11.1.1" + +oauth-sign@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.4.0.tgz#f22956f31ea7151a821e5f2fb32c113cad8b9f69" + integrity sha1-8ilW8x6nFRqCHl8vsywRPK2Ln2k= + +obj-props@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/obj-props/-/obj-props-1.1.0.tgz#626313faa442befd4a44e9a02c3cb6bde937b511" + integrity sha1-YmMT+qRCvv1KROmgLDy2vek3tRE= + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.6, object-keys@^1.0.9: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.0.tgz#11bd22348dd2e096a045ab06f6c85bcc340fa032" + integrity sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg== + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +on-finished@^2.3.0, on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-finished@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.2.1.tgz#5c85c1cc36299f78029653f667f27b6b99ebc029" + integrity sha1-XIXBzDYpn3gCllP2Z/J7a5nrwCk= + dependencies: + ee-first "1.1.0" + +on-headers@~1.0.0, on-headers@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +open-editor@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/open-editor/-/open-editor-1.2.0.tgz#75ca23f0b74d4b3f55ee0b8a4e0f5c2325eb775f" + integrity sha1-dcoj8LdNSz9V7guKTg9cIyXrd18= + dependencies: + env-editor "^0.3.1" + line-column-path "^1.0.0" + opn "^5.0.0" + +opener@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.0.tgz#d11f86eeeb076883735c9d509f538fe82d10b941" + integrity sha1-0R+G7usHaINzXJ1Qn1OP6C0QuUE= + +opn@^5.0.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optimist@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.4.tgz#4d6d0bd71ffad0da4ba4f6d876d5eeb04e07480b" + integrity sha1-TW0L1x/60NpLpPbYdtXusE4HSAs= + dependencies: + wordwrap "~0.0.2" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optimist@~0.3, optimist@~0.3.5: + version "0.3.7" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9" + integrity sha1-yQlBrVnkJzMokjB00s8ufLxuwNk= + dependencies: + wordwrap "~0.0.2" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-browserify@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" + integrity sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ= + +os-browserify@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.0.3.tgz#cd6ad8ddb290915ad9e22765576025d411f29cb6" + integrity sha1-zWrY3bKQkVrZ4idlV2Al1BHynLY= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +outpipe@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/outpipe/-/outpipe-1.1.1.tgz#50cf8616365e87e031e29a5ec9339a3da4725fa2" + integrity sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I= + dependencies: + shell-quote "^1.4.2" + +output-file-sync@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" + integrity sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ== + dependencies: + graceful-fs "^4.1.11" + is-plain-obj "^1.1.0" + mkdirp "^0.5.1" + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.0.0.tgz#7554e3d572109a87e1f3f53f6a7d85d1b194f4c5" + integrity sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" + integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.1.0.tgz#c1a0f1030e97de018bb2c718929d2af59463e505" + integrity sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA== + +package-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e" + integrity sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA== + dependencies: + graceful-fs "^4.1.15" + hasha "^3.0.0" + lodash.flattendeep "^4.4.0" + release-zalgo "^1.0.0" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU= + +pako@~1.0.5: + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + +parent-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.0.tgz#df250bdc5391f4a085fb589dad761f5ad6b865b5" + integrity sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA== + dependencies: + callsites "^3.0.0" + +parents@^1.0.0, parents@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" + integrity sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E= + dependencies: + path-platform "~0.11.15" + +parse-asn1@^5.0.0: + version "5.1.4" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" + integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-author@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" + integrity sha1-00YL8d3Q367tQtp1QkLmX7aEqB8= + dependencies: + author-regex "^1.0.0" + +parse-english@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/parse-english/-/parse-english-4.1.1.tgz#2f75872e617769d857d9b6992dcde2a891f1b2d3" + integrity sha512-g7hegR9AFIlGXl5645mG8nQeeWW7SrK7lgmgIWR0KKWvGyZO5mxa4GGoNxRLm6VW2LGpLnn6g4O9yyLJQ4IzQw== + dependencies: + nlcst-to-string "^2.0.0" + parse-latin "^4.0.0" + unist-util-modify-children "^1.0.0" + unist-util-visit-children "^1.0.0" + +parse-entities@^1.0.2, parse-entities@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.1.tgz#2c761ced065ba7dc68148580b5a225e4918cdd69" + integrity sha512-NBWYLQm1KSoDKk7GAHyioLTvCZ5QjdH/ASBBQTD3iLiAWJXS5bg1jEWI8nIJ+vgVvsceBVBcDGRWSo0KVQBvvg== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-latin@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/parse-latin/-/parse-latin-4.1.1.tgz#3a3edef405b2d5dce417b7157d3d8a5c7cdfab1d" + integrity sha512-9fPVvDdw6G8LxL3o/PL6IzSGNGpF+3HEjCzFe0dN83sZPstftyr+McP9dNi3+EnR7ICYOHbHKCZ0l7JD90K5xQ== + dependencies: + nlcst-to-string "^2.0.0" + unist-util-modify-children "^1.0.0" + unist-util-visit-children "^1.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.5, path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-platform@~0.11.15: + version "0.11.15" + resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + integrity sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I= + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-conf@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" + integrity sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg= + dependencies: + find-up "^2.0.0" + load-json-file "^4.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + +plur@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= + dependencies: + irregular-plurals "^1.0.0" + +plur@^3.0.0, plur@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/plur/-/plur-3.0.1.tgz#268652d605f816699b42b86248de73c9acd06a7c" + integrity sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA== + dependencies: + irregular-plurals "^2.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^1.15.2: + version "1.16.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" + integrity sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g== + +pretty-hrtime@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +private@^0.1.6: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@~0.11.0: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +property-expr@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" + integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== + +propose@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/propose/-/propose-0.0.5.tgz#48a065d9ec7d4c8667f4050b15c4a2d85dbca56b" + integrity sha1-SKBl2ex9TIZn9AULFcSi2F28pWs= + dependencies: + levenshtein-edit-distance "^1.0.0" + +proto-props@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/proto-props/-/proto-props-2.0.0.tgz#8ac6e6dec658545815c623a3bc81580deda9a181" + integrity sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ== + +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +q@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.0.1.tgz#11872aeedee89268110b10a718448ffb10112a14" + integrity sha1-EYcq7t7okmgRCxCnGESP+xARKhQ= + +qs@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/qs/-/qs-0.6.5.tgz#294b268e4b0d4250f6dde19b3b8b34935dff14ef" + integrity sha1-KUsmjksNQlD23eGbO4s0k13/FO8= + +qs@0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-0.6.6.tgz#6e015098ff51968b8a3c819001d5f2c89bc4b107" + integrity sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc= + +qs@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.4.2.tgz#f7ce788e5777df0b5010da7f7c4e73ba32470f5a" + integrity sha1-9854jld33wtQENp/fE5zujJHD1o= + +qs@6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +qs@^6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.2.tgz#19b57ff24dc2a99ce1f8bdf6afcda59f8ef61f88" + integrity sha1-GbV/8k3CqZzh+L32r82ln472H4g= + +querystring-es3@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +quotation@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/quotation/-/quotation-1.1.1.tgz#b599a2b7361a566086458014fda9d6b00326f169" + integrity sha512-bjz7kEsfg6D3uMeed+VbeypnooGlX7enMnDbx0KLYEEM8J1k24jk2pc+1nyQ1sExnERz8xKXRSZ0EYNIwLM83g== + +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-0.0.4.tgz#c0427ffef51c10acba0782a46c9602e744ff620b" + integrity sha1-wEJ//vUcEKy6B4KkbJYC50T/Ygs= + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.2.tgz#c74b3004dea5defd1696171106ac740ec31d62be" + integrity sha1-x0swBN6l3v0WlhcRBqx0DsMdYr4= + dependencies: + bytes "~0.2.1" + +raw-body@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +raw-body@~2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.0.2.tgz#a2c2f98c8531cee99c63d8d238b7de97bb659fca" + integrity sha1-osL5jIUxzumcY9jSOLfel7tln8o= + dependencies: + bytes "2.1.0" + iconv-lite "0.4.8" + +rc@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/rc/-/rc-0.6.0.tgz#e1c930059af831c85413fe275ae2f40f4e3c5371" + integrity sha1-4ckwBZr4MchUE/4nWuL0D048U3E= + dependencies: + deep-extend "~0.2.5" + ini "~1.3.0" + minimist "~0.0.7" + strip-json-comments "0.1.x" + +rc@^1.0.1, rc@^1.1.0, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-only-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0" + integrity sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A= + dependencies: + readable-stream "^2.0.2" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + +readable-stream@1.1.x, "readable-stream@>=1.1.13-1 <1.2.0-0", readable-stream@^1.0.27-1, readable-stream@~1.1.11, readable-stream@~1.1.8, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + 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" + +readable-stream@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.2.0.tgz#de17f229864c120a9f56945756e4f32c4045245d" + integrity sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.0.2, readable-stream@~1.0.24, readable-stream@~1.0.26, readable-stream@~1.0.33: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0, readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +reduce-component@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-component/-/reduce-component-1.0.1.tgz#e0c93542c574521bea13df0f9488ed82ab77c5da" + integrity sha1-4Mk1QsV0UhvqE98PlIjtgqt3xdo= + +regenerate-unicode-properties@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.0.2.tgz#7b38faa296252376d363558cfbda90c9ce709662" + integrity sha512-SbA/iNrBUf6Pv2zU8Ekv1Qbhv92yxL4hiDa2siuxs4KKn4oOoMDHXjAf7+Nz9qinUQ46B1LcWEi/PhJfPWpZWQ== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== + +regenerator-transform@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.4.tgz#18f6763cf1382c69c36df76c6ce122cc694284fb" + integrity sha512-T0QMBjK3J0MtxjPmdIMXm72Wvj2Abb0Bd4HADdfijwMdoIsyQZ6fWC7kDFhk2YinBBEMZDL7Y7wh0J1sGx3S4A== + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp-tree@^0.1.0, regexp-tree@~0.1.1: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.5.tgz#7cd71fca17198d04b4176efd79713f2998009397" + integrity sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ== + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.1.3, regexpu-core@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" + integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.0.2" + regjsgen "^0.5.0" + regjsparser "^0.6.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.1.0" + +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== + dependencies: + jsesc "~0.5.0" + +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + +remark-cli@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/remark-cli/-/remark-cli-6.0.1.tgz#ace67b94c05df0516b6be8dd70f326b6fa9c3770" + integrity sha512-h7Hwnfdcm5J03t2mxhl9BAav+Goqauqfz3LhpE7TP+RIiPnK6njU7qRDD7qlUd/hLyMSB+WBjYc7gVDQT3pv0A== + dependencies: + markdown-extensions "^1.1.0" + remark "^10.0.0" + unified-args "^6.0.0" + +remark-comment-config@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/remark-comment-config/-/remark-comment-config-5.0.3.tgz#54a04b0eeff293bc10b72afe67086fcc001fcae9" + integrity sha512-8UG1UKxXKGQNUcrS22xyooZMnK9XwURyxwIX8GrMYcr5QzbNdAim/AxZ0QGn7We+DcOipCKp8cxNgo4qnTM/hA== + dependencies: + mdast-comment-marker "^1.0.1" + +remark-contributors@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/remark-contributors/-/remark-contributors-3.1.0.tgz#1945979ba8bc957994ec38ae51ba7ad00a49b00b" + integrity sha1-GUWXm6i8lXmU7DiuUbp60ApJsAs= + dependencies: + is-url "^1.2.2" + mdast-util-to-string "^1.0.0" + parse-author "^2.0.0" + +remark-github@^7.0.4: + version "7.0.6" + resolved "https://registry.yarnpkg.com/remark-github/-/remark-github-7.0.6.tgz#bd66299924a0971b5632573d39bddc52d0998882" + integrity sha512-AjBZ/MynNq149wmuvZIz3YcuM8JNFdkTQhpVEZymnkWrgV3jK+kPHNYw9uBQ0XYCPd+qVe21hI4YMwVSj5NjJA== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + mdast-util-to-string "^1.0.1" + unist-util-visit "^1.0.0" + +remark-heading-gap@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/remark-heading-gap/-/remark-heading-gap-3.1.0.tgz#6a1851b4226fa82441ae1365bbd599d34b12d812" + integrity sha512-KxH9CTgfDnVTZVMMLJRw73zxZSWGX+p6x/trG7ed2UsEYqMRr8Dqtu/SXp2vD1ZZhPM8CpS7SjS+qjmiaRFotw== + +remark-license@niftylettuce/remark-license: + version "4.0.1" + resolved "https://codeload.github.com/niftylettuce/remark-license/tar.gz/17ecb8f64f8f6082414d14f9267a12764e6ddbfb" + dependencies: + mdast-util-heading-range "^2.0.0" + parse-author "^2.0.0" + spdx-license-list "^3.0.1" + +remark-lint-blockquote-indentation@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-1.0.2.tgz#e84ab0dc4bf468ca10c53f09e1cb8dd0c2f56a95" + integrity sha512-u3ruA+4ZZOpt3YmTCdCOcYiGBMSQ/b/iJvZs/fibF6rwSBmkod48aGGJVoOLMuIuTYYbbXpzigxS+PeJwN0CDQ== + dependencies: + mdast-util-to-string "^1.0.2" + plur "^3.0.0" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-checkbox-character-style@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-1.0.2.tgz#0dc33eb1a2753e2c4212799cbf15cd4153aeef55" + integrity sha512-8hTvHHGj0Ko5Qx9RjBVj9yPO/pOpSFzWVMvszyhZkuH/uy92bab/bmfUwl0/4f8gqsxqyRS/QC/Sp+KivWvYlw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + vfile-location "^2.0.1" + +remark-lint-checkbox-content-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-1.0.2.tgz#8e145a0d030254c17a6542c4377b473d621f16d2" + integrity sha512-9cPEpd3GpN5ZoAEBTl6qkVOIXpJSms+AC6L/gGLHOcfmSaR5jfgzQWE7GkCj6OvUqjV69zrGGHlWLu7uMujf3g== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + vfile-location "^2.0.1" + +remark-lint-code-block-style@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-code-block-style/-/remark-lint-code-block-style-1.0.2.tgz#f24ef71767d5933ed83de93a54a85faf9e02c197" + integrity sha512-fTSCga/lJ710zBaD808NwqzAatVoLQFizvXWpetygKwoAfXCyMYQ9DUdDE5jdDhwOu2JPnKbxY+4t6m4SrKKWA== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-definition-case@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-definition-case/-/remark-lint-definition-case-1.0.3.tgz#4dbc9322eeb7f8d0402f4f1056eaf97812a47557" + integrity sha512-ORRDV+ETVWnXoPE3fX0zXFGC5NQvdsB1Ihjeqmw38IWVKnOR34f5s/9BZNnbflBzdKWnLVg1g3IwQLf8eVBsow== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.4.0" + +remark-lint-definition-spacing@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-definition-spacing/-/remark-lint-definition-spacing-1.0.3.tgz#f7fc54d0fe7b3cd6b94e2e1290220dd1a3cfb1ff" + integrity sha512-8lFBtgSE3xbvvSuO95B6lUiD6Ph1wZr5xevKokwwfKoyfOkXDpN85wh7JepIZnUj1OnTXvupCwr7yYUEji/Rrw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.4.0" + +remark-lint-emphasis-marker@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-emphasis-marker/-/remark-lint-emphasis-marker-1.0.2.tgz#df77c6b62b87a61ddf683e791d13ccfae050c318" + integrity sha512-c+uvvnYesMaqy/X0dU62dbI6/rk+4dxMXdnfLC/NKBA8GU+4kljWqluW797S6nBG94QZjKIv8m49zJl38QfImQ== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-fenced-code-flag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-1.0.2.tgz#614232ab7923fc0a3e8694b485bc7ae664c7046b" + integrity sha512-6/412zYtz+qKpFJryEPSMurWr6tO5MTVohJF3byFc3+3SSEZLWY3Dg8gbwFlumZ9T4HgmfUm/LT7Idm96zj0nw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-fenced-code-marker@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-1.0.2.tgz#07959311cf7b9cbe35ae279ea3cb7823205cb29f" + integrity sha512-yAP59Q1JoI1jjOFCn0GoNx4uDji99ROLvdwvmz7+9YR9guDArBcR4i9Wem/wN6apauWPk2DbAZFavHvbZaT8HQ== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-file-extension@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-file-extension/-/remark-lint-file-extension-1.0.2.tgz#c52c6e00c9d1f5e729f515c1bb9c23de9aef4983" + integrity sha512-qx0uki74rmALIKE3r5J3neasbXnz6h+l88OngvpwWkELsnJmfk81JdxfEd0tZ++uTj6CN0TZuhMKad9smfNtRw== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-final-definition@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-final-definition/-/remark-lint-final-definition-1.0.2.tgz#63e013c9f95c9b52197f19c6e0d14b622352e0f3" + integrity sha512-F+n8eauYOJGdcSrnD7w2YgQSERx1rAwXTxStaJ2tLmoXlT7eQgpVGHz1U4Y76cg8OANbq8pT0KTNJ85JNqkq4g== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-final-newline@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-final-newline/-/remark-lint-final-newline-1.0.2.tgz#13b9ff6bd3e9c377286b439d8f14b04efde3898f" + integrity sha512-hW/lbDwVKtME3jIcJWJ16wBtoJdFPWIiu0fEI93yzNTjeB1g3VSWJp66dHbtCLYwquRS5fr8UlGx7JxIu1kiuA== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-first-heading-level@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/remark-lint-first-heading-level/-/remark-lint-first-heading-level-1.1.3.tgz#905e163282bef82fcbffd6c8cd4be54897c1a658" + integrity sha512-7dKkiVrzlMoeZJX/TwKIrqaBLYIwGUG5a8sS8dxlGG00LnL2S8koAFL8t/U+dZsfDdF7p0kf4jhcwJWB4U26rA== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.4.0" + +remark-lint-hard-break-spaces@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.3.tgz#0485fc09265dcea436f5eb3420a3b6f616c6fad7" + integrity sha512-GiC0uXeFwef6/Pfo+EYBN0WIVlEFffh+9TdeJ4uLt89ZweaRVDPCTJQqkkuXoiXSPnZGD7cGHdkWCfXU1PaU7Q== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-heading-style@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-heading-style/-/remark-lint-heading-style-1.0.2.tgz#87bdab061c9d259f50b5c51ce478d1c65bd31ae8" + integrity sha512-d0aIbL8PU5LWfZVI8p49vEV5wWIfD/DdUjc+O8j5E0UWUgcRgPGB66xznkOb8AiniXpcaYggRW8hGZsxoYNt1g== + dependencies: + mdast-util-heading-style "^1.0.2" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.1.1" + +remark-lint-list-item-bullet-indent@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.2.tgz#82461e7295b9e208e7c41b62d30476a69727b0cb" + integrity sha512-zvyQD6mJLRratZjk4Dw7D4vh73L43NXNCcap/6TxcmU9SKO7dXzoh8Ap9tyaFLic0LnHFc3Gx1pqYiPQ7PnL2g== + dependencies: + plur "^3.0.0" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-list-item-indent@1.0.3, remark-lint-list-item-indent@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.3.tgz#93dac0cc312ee8dd9c8a0749b44b17b95b765f53" + integrity sha512-/IcVUPIxQ2X/oCKzqiAtH85CS8An3xQbcMD0DRBHZjBrIUO0Ot7lBiQedSHwCg9lnh7pDOTvHrmNS3FaWjVQqw== + dependencies: + plur "^3.0.0" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-auto-link-without-protocol@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.2.tgz#4532087419b1b131b4057ecf0a3a446f0afc2c6e" + integrity sha512-3GtkSxOyd6we4b8JdtJsNgt8+3UN+hpw1UiMoE9X96ahc1rqsCFm6miorNUnF/gfPQ1liHBvZUed2SIenDmpkg== + dependencies: + mdast-util-to-string "^1.0.2" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-blockquote-without-marker@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.2.tgz#61b6a0a74fbfba8fd168ac0fcc2a673eb47b9880" + integrity sha512-jkfZ4hFiviZttEo7Ac7GZWFgMQ/bdVPfSluLeuf+qwL8sQvR4ClklKJ0Xbkk3cLRjvlGsc8U8uZR8qqH5MSLoA== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + vfile-location "^2.0.1" + +remark-lint-no-consecutive-blank-lines@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-1.0.2.tgz#ba7c8944335a80e67c811028732f12e521d07d93" + integrity sha512-KbOm6EX5Yl9uzRC93soTB+HlqtCzu9XJWsV9CVcoDKtNnpKfyTwQOy6dmUbQrLp4xBdNk4s9S9CsemRaHEkFGA== + dependencies: + plur "^3.0.0" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-duplicate-definitions@^1.0.0, remark-lint-no-duplicate-definitions@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.3.tgz#d35e21718e230b2e75a88f166efcfe84267baa82" + integrity sha512-8iQhawbIMwQILRpCsoYCVYrSF2rrWEfF7KPvIIJavp0TA02Wv+SX7b3hQslNtvso0Ka2VX+kI1+x+QzG16Duqg== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-stringify-position "^1.1.2" + unist-util-visit "^1.4.0" + +remark-lint-no-emphasis-as-heading@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-emphasis-as-heading/-/remark-lint-no-emphasis-as-heading-1.0.2.tgz#a4616ad3f085e4db013132306312973b3fe76ac0" + integrity sha512-lKlwiRQOFOoPSwjbZf065RaUr6RZmO82zZYjXhVT9xwMkWXIAQyG0GJuLB2/+rlMEtlgoUD3ePch+Pzf+KrSJQ== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.1.1" + +remark-lint-no-file-name-articles@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.2.tgz#a8187e44584e56ccc37fcd7bbc758e940a5b1829" + integrity sha512-5FuxJ0Hd2AgVSP1javG51qPbMBWxma1LrCKI6JmBsu/GM7ZYOgemMyH5v4I1ejTPGj7P30xmIjMNSnV8IBMq3g== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-no-file-name-consecutive-dashes@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.2.tgz#e8536f4c9f349965d9b4990a75a27857dac72488" + integrity sha512-VvCxG3AfRm6ROFNJ8+tdOOkk61mEKj+PytB8xg5WNQypKWhhJ734mJ3GzXD4XEov7Bdd1GVXJFXlLFtfoAewHw== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-no-file-name-irregular-characters@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-file-name-irregular-characters/-/remark-lint-no-file-name-irregular-characters-1.0.2.tgz#0dffe8f4dc7ffe79f634d4609a8f28261a981552" + integrity sha512-8A+DYXsiPBu0q4cvqtYwzRj6SWrKnPh+oI1H1t64pCQiSnLmG9e3mAUXMxH9PiM6y5OW7Vw8Xh4KYsnRwGEuMQ== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-no-file-name-mixed-case@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-file-name-mixed-case/-/remark-lint-no-file-name-mixed-case-1.0.2.tgz#965606ac41b53fef8a4c8d0c7bd1bed63e26a357" + integrity sha512-OMH2kpjvDAsyyw8ar9h6WI1kUXSpQ2r2c5JZv3NBNYxwzTBfhCR2MSQq+eEI7yUmD2ehqNUY5LwZTQZG6cK4vw== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-no-file-name-outer-dashes@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.3.tgz#d5b217a8341ac79b4a378770488b3ccc8bc4a5b5" + integrity sha512-imUWm8Bi9PxV+IQtQC2/BV1Yj0VboC9hPMZh3sae8pZvCjXquTyYiSFa7hQxX6KWCNUiRPHMSlaSVvfvM2e4pQ== + dependencies: + unified-lint-rule "^1.0.0" + +remark-lint-no-heading-content-indent@^1.0.0, remark-lint-no-heading-content-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.2.tgz#812c4af2a18491bbf278f15a6f533169203a1b3c" + integrity sha512-g2MVmJhHbfFungca5WGWVB9bBY4YTrY6og20U+6DxkdS4ngoc8ezXUt8zV1HHEn0M/GdKr9F7fYhXcekJd/qaw== + dependencies: + mdast-util-heading-style "^1.0.2" + plur "^3.0.0" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-heading-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-1.0.2.tgz#fdd16a802bbf7f21cdbea8497ef1fd8c7b8718bd" + integrity sha512-BJ9mPGIFn6Pv0KN9Qwy27wQGllM6mPCv6VI6khDcURlzdAaX5hfFarGJVGKEgPWoL8zs8fPRoXMpsAHIonnnyA== + dependencies: + plur "^3.0.0" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-heading-punctuation@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-heading-punctuation/-/remark-lint-no-heading-punctuation-1.0.2.tgz#c520d8614d641b05ac75c25502901df9218b4b5e" + integrity sha512-nYc2a0ihQ5cPy7elaM0lRPYKEMpEK6EjyJH6pHYlgG8NQwjKXhsVaek0fmAm12PaYoYOGW1pDxfzxnFUocU20g== + dependencies: + mdast-util-to-string "^1.0.2" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.1.1" + +remark-lint-no-inline-padding@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.3.tgz#a31e3a04ab0d47ea7e7be8416b5d2d668ad8f7cf" + integrity sha512-zEe7LjM13kQshdBtPnSzzCUNzGIX/XiGspMb7HZBCDWYsPJ73s01X+m+YI99Dz7wKvB3EUTZ7/MFhTUIvqcGRw== + dependencies: + mdast-util-to-string "^1.0.2" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.4.0" + +remark-lint-no-literal-urls@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.2.tgz#1c60160a76bd9ddacd42819b43dadeb481a530df" + integrity sha512-+mWZIJA4yAqpKIclcFP5wRy/6hxcPnfU9Xmgp4fR7OD4JQ4JHkKq9O7MUbda14PLez1aMX+Is0O0hWI7OuqsSw== + dependencies: + mdast-util-to-string "^1.0.2" + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-missing-blank-lines@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-missing-blank-lines/-/remark-lint-no-missing-blank-lines-1.0.2.tgz#5d3ec89b4d117eaadbebbcbf8f265439c4390f0c" + integrity sha512-Q/47tKY7fs+hb2avIw8/KkmbtqFg6SHbBGijIpk53wtaAEItCvuGIym7dUapwV3nHtNhkaQ450bQ66yfdf9o7w== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-no-multiple-toplevel-headings@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-1.0.2.tgz#65f7288f66a1a14394f6c6f0910d36112f60e3eb" + integrity sha512-Zxkw7wIyMOyYQb5C5NTswSttZPCLqm/60Wnt0TEWzXVDkVk5DrxrCCxbMKgpXve1Co5CXPmMixNr/xYBqzxzWg== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-stringify-position "^1.1.2" + unist-util-visit "^1.1.1" + +remark-lint-no-shell-dollars@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-1.0.2.tgz#361599631271f7237b2147e692be40e08975330c" + integrity sha512-eIjBebX9iOFWbMdjol5JJBXI7ku+7UyJpNrd++rl8QenLLZ76beh+xONCzJw/k5dhEw5voBmQLh7VK9HPU/ang== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.1.1" + +remark-lint-no-shortcut-reference-image@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.2.tgz#784011b832173ad9e87d4f40c90f935de0841764" + integrity sha512-IVYv5pgyf70jYcrn+BNHVO37BuQJg26rFOLzi2mj+/8EdFpolJiJcTvkChJgz5yip7317DmQQSNLX6gCExuDrQ== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.1.1" + +remark-lint-no-shortcut-reference-link@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.3.tgz#4210d37d234b427dd131eb11473a7a2d3719a819" + integrity sha512-v5mk4wYQL+YRmlOTqi8avpzhoGZg+P42dDRda2jedysDIx7TJBEXUH6oMFEbo/qV6PMmtr7fr066M3RrOrLpiQ== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.1.1" + +remark-lint-no-table-indentation@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-1.0.3.tgz#03eaa9c9d4609999cda101451451270656809c78" + integrity sha512-argI2JADlVrlwsdORdbmE89QXB9XtBtAy2YBHZv/q/d247CyL+h+hw9wpg06P1lLQwbllxYJD5u1bNtfgv3XVg== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.4.0" + +remark-lint-no-tabs@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-no-tabs/-/remark-lint-no-tabs-1.0.2.tgz#a6605c63140b2bb50f6183297cd1e02ac3213455" + integrity sha512-jPjRLHyzO4lO6orhOmHd6AN6mVc/uMWvYZ3qD41dniktnLyHEbIG6DpPxixjfpmEe0wi73RXMywKHrWshLJwAg== + dependencies: + unified-lint-rule "^1.0.0" + vfile-location "^2.0.1" + +remark-lint-no-undefined-references@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.0.3.tgz#93255cfd5a8cb81850d7848d41fe176cc2be058a" + integrity sha512-yQxSpTQ3aGY4aszGSktAzeBC+h/k/YR/bf4ATrjCK5dz4C3InodCcrW/mtarLHR/3/kvM7NcGiOl0PElKJW5mg== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.4.0" + +remark-lint-no-unused-definitions@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.4.tgz#c627146f89ab8aec0f3c4e587e29e41ee6ab2ea9" + integrity sha512-wKh10+2hiVKEkVXfW5zC8lyDCJQM6lpyRsyIVxq0ROHkrAjsO+seljEQCOsIJ55nZHbdCOCFDQosA0/5wgryRw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-visit "^1.4.0" + +remark-lint-ordered-list-marker-style@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.2.tgz#ad7461306a7701fc931245300dfd7dbd9fbb589f" + integrity sha512-4EHuHxZqy8IT4k+4Vc8P38I34AiZfgl07fS5/iqGhCdoSMCvvxdOuzTWTgpDFbx/W2QpHelBfJ+FtOp+E0J4Lg== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-ordered-list-marker-value@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-ordered-list-marker-value/-/remark-lint-ordered-list-marker-value-1.0.2.tgz#26f5f1ddfadb7c958f8e2c15cd3aa9f2be985be6" + integrity sha512-vIPD07u+FBjTjEETZ+UWUp2nydzvOe5AHIX812JlNXWuHYuCybq8DGnkYUcoiK3HbIE+KdG+e7C5xHkim0PSjw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-rule-style@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-rule-style/-/remark-lint-rule-style-1.0.2.tgz#51f82acb1e6cdf76ea6107bb231d2336615fa98d" + integrity sha512-D9mMPKA7rtCe4Yx+ryip6FyfNG9uGOaHxRgJClfte7D66QzxiiWtHYyNCXI4rkv8Ax9PrEdpWCPcIl3D2LrXhw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-strong-marker@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-strong-marker/-/remark-lint-strong-marker-1.0.2.tgz#6ce3670f79bf5978b7518af35e6072c8425f0f46" + integrity sha512-oUSKqYJVLgbXe25NmcTOfQ8wsFasc+qhEoGjPEGPuJMV2aZIGuOEbGVqD5B1ckYGBEwbTuet3btvMohz8HaBDQ== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-table-cell-padding@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-1.0.3.tgz#fafec50deb8476cb3241f2da4ef0b8b66f549741" + integrity sha512-beXwMK8KAGIDQWixf7wzte4GhyB9w33DxTGgmP4HWOWMVXHvBnufJvnIozBBOH9nOsi1fP8NYRb/01hrgjNnmw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.4.0" + +remark-lint-table-pipe-alignment@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-table-pipe-alignment/-/remark-lint-table-pipe-alignment-1.0.2.tgz#3d79927c18b5a5713079a7890a392b740e0bc45a" + integrity sha512-gLJwduvBI2soR7Dyf39KGUl3M9ZCK/7pFfWBeOv8J27D7px/1lXooqlX4Y9NQ/+9jc7DyLF9upPxh7UWm7UXGg== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-table-pipes@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-table-pipes/-/remark-lint-table-pipes-1.0.2.tgz#a7e95c93d6908c2b515651aa44fc8c922626ad32" + integrity sha512-BGKcOviuUC6fILIOPYFe6awqk57ApzNJpK3OYBrweGoFF55nZ/qf3q6JpzA0chd6wKj7VrcfQEd3QSQQ+8Wcrw== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint-unordered-list-marker-style@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-1.0.2.tgz#2d631c3e7e0604e1d45d5586a0bbb21474bb89a4" + integrity sha512-qdnF9JuMWzFJzGIfdAWfOHyjad8dqIQSs+cTzqMlNZHOGrrCJdTUWzybzcZMGn1yuwreklZdHKhOglXQFwSD3A== + dependencies: + unified-lint-rule "^1.0.0" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.1" + +remark-lint@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/remark-lint/-/remark-lint-6.0.4.tgz#13def899efd7d7d105188c274663a60e0fe8fa59" + integrity sha512-miD6SKhjEkLgdJXgAmNhGsdY1yIGAzwpoGIn/59MR6nZhshdxSm9/pLPiw9fK3loNASA3j7k//kea6x5vHb+jQ== + dependencies: + remark-message-control "^4.0.0" + +remark-message-control@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/remark-message-control/-/remark-message-control-4.1.1.tgz#a3f0b08dffda484e7196f0539de1488220f1d251" + integrity sha512-DojJPPeSux/U7aHCN6GUWBgp6F1EQFPUNvnk2gfuGgiMCHVubz/xAC3TkvPaf5w1F0PEGaOEpCtvxJK6O4Kmiw== + dependencies: + mdast-comment-marker "^1.0.0" + unified-message-control "^1.0.0" + xtend "^4.0.1" + +remark-parse@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-6.0.3.tgz#c99131052809da482108413f87b0ee7f52180a3a" + integrity sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg== + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.1.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + +remark-preset-github@^0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/remark-preset-github/-/remark-preset-github-0.0.13.tgz#9ab58ecf794fb9191823de7a764b2d32694d274d" + integrity sha512-D4K53JEOThvvYZ3YgP4DMMUbUpFBSEEShkt5XwobSRPb5gAPYML9PL/Aj3N3IKoayEbcHtPeCb0+5sQmSvbowg== + dependencies: + remark-comment-config "^5.0.2" + remark-contributors "^3.1.0" + remark-github "^7.0.4" + remark-heading-gap "^3.0.0" + remark-license niftylettuce/remark-license + remark-lint-blockquote-indentation "^1.0.2" + remark-lint-checkbox-character-style "^1.0.2" + remark-lint-checkbox-content-indent "^1.0.2" + remark-lint-code-block-style "^1.0.2" + remark-lint-definition-case "^1.0.2" + remark-lint-definition-spacing "^1.0.2" + remark-lint-emphasis-marker "^1.0.2" + remark-lint-fenced-code-flag "^1.0.2" + remark-lint-fenced-code-marker "^1.0.2" + remark-lint-file-extension "^1.0.2" + remark-lint-final-definition "^1.0.2" + remark-lint-first-heading-level "^1.1.2" + remark-lint-heading-style "^1.0.2" + remark-lint-list-item-indent "1.0.3" + remark-lint-no-consecutive-blank-lines "^1.0.2" + remark-lint-no-duplicate-definitions "^1.0.2" + remark-lint-no-emphasis-as-heading "^1.0.2" + remark-lint-no-file-name-articles "^1.0.2" + remark-lint-no-file-name-consecutive-dashes "^1.0.2" + remark-lint-no-file-name-irregular-characters "^1.0.2" + remark-lint-no-file-name-mixed-case "^1.0.2" + remark-lint-no-file-name-outer-dashes "^1.0.3" + remark-lint-no-heading-content-indent "^1.0.2" + remark-lint-no-heading-indent "^1.0.2" + remark-lint-no-heading-punctuation "^1.0.2" + remark-lint-no-missing-blank-lines "^1.0.2" + remark-lint-no-multiple-toplevel-headings "^1.0.2" + remark-lint-no-shell-dollars "^1.0.2" + remark-lint-no-table-indentation "^1.0.2" + remark-lint-no-tabs "^1.0.2" + remark-lint-ordered-list-marker-value "^1.0.2" + remark-lint-rule-style "^1.0.2" + remark-lint-strong-marker "^1.0.2" + remark-lint-table-cell-padding "^1.0.2" + remark-lint-table-pipe-alignment "^1.0.2" + remark-lint-table-pipes "^1.0.2" + remark-lint-unordered-list-marker-style "^1.0.2" + remark-preset-lint-recommended "^3.0.2" + remark-retext "^3.1.1" + remark-toc "^5.1.0" + remark-validate-links "^7.1.0" + retext-english "^3.0.0" + retext-preset-github "^0.0.5" + unified "^7.0.0" + +remark-preset-lint-recommended@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.2.tgz#5ce675678895ce7131326c12b6df9105a5d0632c" + integrity sha512-os4YNWLbkorjvDHVB4o+zCCufZLzGoD4Iwdk7SV7bSIZurUTrMp/ZrpNytyetN9ugIMXuHbWJUE+dF0ND+WorQ== + dependencies: + remark-lint "^6.0.0" + remark-lint-final-newline "^1.0.0" + remark-lint-hard-break-spaces "^1.0.0" + remark-lint-list-item-bullet-indent "^1.0.0" + remark-lint-list-item-indent "^1.0.0" + remark-lint-no-auto-link-without-protocol "^1.0.0" + remark-lint-no-blockquote-without-marker "^2.0.0" + remark-lint-no-duplicate-definitions "^1.0.0" + remark-lint-no-heading-content-indent "^1.0.0" + remark-lint-no-inline-padding "^1.0.0" + remark-lint-no-literal-urls "^1.0.0" + remark-lint-no-shortcut-reference-image "^1.0.0" + remark-lint-no-shortcut-reference-link "^1.0.0" + remark-lint-no-undefined-references "^1.0.0" + remark-lint-no-unused-definitions "^1.0.0" + remark-lint-ordered-list-marker-style "^1.0.0" + +remark-retext@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/remark-retext/-/remark-retext-3.1.2.tgz#983003d7495cf9198aa450c5ae5a7737011eec5f" + integrity sha512-+48KzJdSXvsPupY5pj5AY7oBUSiDOqFPZBKebX5WemrMyIG+RImIt9hgeqelluVDd1kooHen33K/aybTPyoI9g== + dependencies: + mdast-util-to-nlcst "^3.2.0" + +remark-slug@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-5.1.1.tgz#eb5dba0cf779487ef7ddf65c735ba4d4ca017542" + integrity sha512-r591rdoDPJkSSAVvEaTVUkqbMp7c7AyZfif14V0Dp66GQkOHzaPAS6wyhawSbqpS0ZdTnfJS+TltFoxzi6bdIA== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^1.0.0" + +remark-stringify@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-6.0.4.tgz#16ac229d4d1593249018663c7bddf28aafc4e088" + integrity sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg== + dependencies: + ccount "^1.0.0" + is-alphanumeric "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + longest-streak "^2.0.1" + markdown-escapes "^1.0.0" + markdown-table "^1.1.0" + mdast-util-compact "^1.0.0" + parse-entities "^1.0.2" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + stringify-entities "^1.0.1" + unherit "^1.0.4" + xtend "^4.0.1" + +remark-toc@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/remark-toc/-/remark-toc-5.1.1.tgz#8c229d6f834cdb43fde6685e2d43248d3fc82d78" + integrity sha512-vCPW4YOsm2CfyuScdktM9KDnJXVHJsd/ZeRtst+dnBU3B3KKvt8bc+bs5syJjyptAHfqo7H+5Uhz+2blWBfwow== + dependencies: + mdast-util-toc "^3.0.0" + remark-slug "^5.0.0" + +remark-validate-links@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/remark-validate-links/-/remark-validate-links-7.1.2.tgz#be6ec6b45f360717ecb0ba9c4b03a3c84fc358df" + integrity sha512-FrnRGfy6iuFooGPGLwQTqytKWZhe87YHb319PkzVjJizETkxatw2RFwMPf4Q1FY4kR1ajh27HaEG/Hu1MtVxeg== + dependencies: + github-slugger "^1.2.0" + hosted-git-info "^2.5.0" + mdast-util-definitions "^1.0.0" + mdast-util-to-string "^1.0.4" + propose "0.0.5" + unist-util-visit "^1.0.0" + urljoin "^0.1.5" + xtend "^4.0.1" + +remark@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/remark/-/remark-10.0.1.tgz#3058076dc41781bf505d8978c291485fe47667df" + integrity sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ== + dependencies: + remark-parse "^6.0.0" + remark-stringify "^6.0.0" + unified "^7.0.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.0, repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request@2.11.4: + version "2.11.4" + resolved "https://registry.yarnpkg.com/request/-/request-2.11.4.tgz#6347d7d44e52dc588108cc1ce5cee975fc8926de" + integrity sha1-Y0fX1E5S3FiBCMwc5c7pdfyJJt4= + dependencies: + form-data "~0.0.3" + mime "~1.2.7" + +request@~2.46.0: + version "2.46.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.46.0.tgz#359195d52eaf720bc69742579d04ad6d265a8274" + integrity sha1-NZGV1S6vcgvGl0JXnQStbSZagnQ= + dependencies: + aws-sign2 "~0.5.0" + bl "~0.9.0" + caseless "~0.6.0" + forever-agent "~0.5.0" + form-data "~0.1.0" + hawk "1.1.1" + http-signature "~0.10.0" + json-stringify-safe "~5.0.0" + mime-types "~1.0.1" + node-uuid "~1.4.0" + oauth-sign "~0.4.0" + qs "~1.2.0" + stringstream "~0.0.4" + tough-cookie ">=0.12.0" + tunnel-agent "~0.4.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +requires-port@0.x.x: + version "0.0.1" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-0.0.1.tgz#4b4414411d9df7c855995dd899a8c78a2951c16d" + integrity sha1-S0QUQR2d98hVmV3YmajHiilRwW0= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@4.0.0, resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-global@0.1.0, resolve-global@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-0.1.0.tgz#8fb02cfd5b7db20118e886311f15af95bd15fbd9" + integrity sha1-j7As/Vt9sgEY6IYxHxWvlb0V+9k= + dependencies: + global-dirs "^0.1.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@0.7.x: + version "0.7.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.7.4.tgz#395a9ef9e873fbfe12bd14408bd91bb936003d69" + integrity sha1-OVqe+ehz+/4SvRRAi9kbuTYAPWk= + +resolve@1.1.7, resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@^1.1.3, resolve@^1.1.4, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" + integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retext-contractions@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/retext-contractions/-/retext-contractions-2.1.3.tgz#c1a3f44b22ccf505266ef83aa60c0d07162e377c" + integrity sha512-HN5iDZZ0WC0tJPuC+KAz00YuCLYcgM9b8sr0kQuBniqz8YsyqKiGFBQJ40sSwTVpz7GL378/5qIBr8n04eMEiA== + dependencies: + nlcst-is-literal "^1.0.0" + nlcst-to-string "^2.0.0" + unist-util-visit "^1.1.0" + +retext-diacritics@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/retext-diacritics/-/retext-diacritics-1.2.2.tgz#a328f6c556e59a9d1ac347fa64387352371a062d" + integrity sha512-1i8FFyAiFMUwqsRENuPr9tPxcL7Ges6Troiz6NMnQL4hpVKvzdZkPGfKK2PGKJaM16rmbU3zSZKbYDSC9BObug== + dependencies: + match-casing "^1.0.0" + nlcst-search "^1.0.0" + nlcst-to-string "^2.0.0" + object-keys "^1.0.9" + quotation "^1.0.1" + unist-util-position "^3.0.0" + +retext-english@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/retext-english/-/retext-english-3.0.2.tgz#efc239c445b112d13f3f511b1856abc2b5476cb4" + integrity sha512-iWffdWUvJngqaRlE570SaYRgQbn4/QVBfGa/XseEBuBazymnyW24o37oLPY0vm+PJdLmDghnjZX0UbkZSZF0Cg== + dependencies: + parse-english "^4.0.0" + unherit "^1.0.4" + +retext-indefinite-article@^1.1.4: + version "1.1.6" + resolved "https://registry.yarnpkg.com/retext-indefinite-article/-/retext-indefinite-article-1.1.6.tgz#8749dc20c4be7ddbe7c56ad00b691cc5976f64ad" + integrity sha512-JevJ7OAz0Unk88Pu6qzQi9USYXrjzwfcQzWMpqHRp55RpzVXqwP8wfEp3MBCFORpKLdH72s2qV/VDvG7G+QP1w== + dependencies: + format "^0.2.2" + nlcst-to-string "^2.0.0" + number-to-words "^1.2.3" + unist-util-is "^2.0.0" + unist-util-visit "^1.1.0" + +retext-preset-github@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/retext-preset-github/-/retext-preset-github-0.0.5.tgz#5ff56b784b1eb2617392edcdf18a74a948e18435" + integrity sha512-FO5zkyC4z91Wj1OblkxKolDFyb0KYyXVcc/9oQpEfIRi8ungoFLyMG4pJlT48nVPTEd+6Pd8SO3RDHd45BDwYw== + dependencies: + retext-contractions "^2.1.2" + retext-diacritics "^1.2.1" + retext-indefinite-article "^1.1.4" + retext-quotes "^2.0.1" + retext-redundant-acronyms "^1.2.1" + retext-repeated-words "^1.2.1" + retext-sentence-spacing "^2.0.1" + +retext-quotes@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/retext-quotes/-/retext-quotes-2.0.3.tgz#7b1aa811e9a26cd5830e8495d7ef7aeb7a2a5ed3" + integrity sha512-GngYmhEhnuVX6Dv1flM08XgEBCnciH7elulGcgGH0kIc8KYShuScu3qmLAg7NCETytmmgBMvsHEnEOtocRCERw== + dependencies: + nlcst-to-string "^2.0.0" + unist-util-is "^2.0.0" + unist-util-visit "^1.1.0" + +retext-redundant-acronyms@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/retext-redundant-acronyms/-/retext-redundant-acronyms-1.2.2.tgz#61eec4d672fd5ce12209aacd1bad4ab8f5b7b37f" + integrity sha512-cAqICxNKKMOF299PYEea+sOPJtd4DQzDBhprUMmgZAx7Bm0Y8JRODMJuf3N6M4GvNmOdNXTfmz4/QCx677539Q== + dependencies: + match-casing "^1.0.0" + nlcst-search "^1.0.0" + nlcst-to-string "^2.0.0" + object-keys "^1.0.9" + quotation "^1.0.1" + unist-util-position "^3.0.0" + +retext-repeated-words@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/retext-repeated-words/-/retext-repeated-words-1.2.2.tgz#2f9562f646c7412aad3a39211e678f6466613333" + integrity sha512-dpe/iQfYiFqPGrRubzj/oymdFlqed9W7d4qT7VKqt10Sln2Tf+nbdc0w0A5UpcLRMjgza2KnLWTObuy6iV4ffQ== + dependencies: + nlcst-to-string "^2.0.0" + unist-util-is "^2.0.0" + unist-util-visit "^1.1.0" + +retext-sentence-spacing@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/retext-sentence-spacing/-/retext-sentence-spacing-2.1.0.tgz#cef60a0fd8c8301927383fcd35a4e2cced084869" + integrity sha512-s2cfNnhXrKvy/uilfeFzUj/gawZT2CV2ZegGVxRxTs+JYASD3TMPr6EH5m9gd5ORpFG52ALuZaizoF1UZvMXhg== + dependencies: + nlcst-to-string "^2.0.0" + plur "^2.1.2" + unist-util-is "^2.0.0" + unist-util-visit "^1.1.0" + +rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@~2.2.0, rimraf@~2.2.2: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + +runnel@~0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/runnel/-/runnel-0.5.3.tgz#f9362b165a05fc6f5e46e458f77a1f7ecdc0daec" + integrity sha1-+TYrFloF/G9eRuRY93offs3A2uw= + +rxjs@^6.3.3, rxjs@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +safe-regex@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.0.2.tgz#3601b28d3aefe4b963d42f6c2cdb241265cbd63c" + integrity sha512-rRALJT0mh4qVFIJ9HvfjKDN77F9vp7kltOpFFI/8e6oKyHFmmxz4aSkY/YVauRDe7U0RrHdw9Lsxdel3E19s0A== + dependencies: + regexp-tree "~0.1.1" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scope-analyzer@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/scope-analyzer/-/scope-analyzer-2.0.5.tgz#72c9c6770c3e66984f84c7d3c7045998a1a7db8a" + integrity sha512-+U5H0417mnTEstCD5VwOYO7V4vYuSqwqjFap40ythe67bhMFL5C3UgPwyBv7KDJsqUBIKafOD57xMlh1rN7eaw== + dependencies: + array-from "^2.1.1" + es6-map "^0.1.5" + es6-set "^0.1.5" + es6-symbol "^3.1.1" + estree-is-function "^1.0.0" + get-assigned-identifiers "^1.1.0" + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +semver@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +send@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/send/-/send-0.1.4.tgz#be70d8d1be01de61821af13780b50345a4f71abd" + integrity sha1-vnDY0b4B3mGCGvE3gLUDRaT3Gr0= + dependencies: + debug "*" + fresh "0.2.0" + mime "~1.2.9" + range-parser "0.0.4" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +sequence@2.x: + version "2.2.1" + resolved "https://registry.yarnpkg.com/sequence/-/sequence-2.2.1.tgz#7f5617895d44351c0a047e764467690490a16b03" + integrity sha1-f1YXiV1ENRwKBH52RGdpBJChawM= + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shallow-copy@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" + integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= + +shasum@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f" + integrity sha1-5wEjENj0F/TetXEhUOVni4euVl8= + dependencies: + json-stable-stringify "~0.0.0" + sha.js "~2.4.4" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.4.1.tgz#ae18442b536a08c720239b079d2f228acbedee40" + integrity sha1-rhhEK1NqCMcgI5sHnS8iisvt7kA= + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shell-quote@^1.4.2, shell-quote@^1.4.3, shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shellsubstitute@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shellsubstitute/-/shellsubstitute-1.2.0.tgz#e4f702a50c518b0f6fe98451890d705af29b6b70" + integrity sha1-5PcCpQxRiw9v6YRRiQ1wWvKba3A= + +should-equal@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" + integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== + dependencies: + should-type "^1.4.0" + +should-format@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" + integrity sha1-m/yPdPo5IFxT04w01xcwPidxJPE= + dependencies: + should-type "^1.3.0" + should-type-adaptors "^1.0.1" + +should-http@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/should-http/-/should-http-0.1.1.tgz#9b793843f4024885781eb6abacc4030e1e9f21f0" + integrity sha1-m3k4Q/QCSIV4HrarrMQDDh6fIfA= + dependencies: + content-type "^1.0.2" + +should-type-adaptors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" + integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== + dependencies: + should-type "^1.3.0" + should-util "^1.0.0" + +should-type@^1.3.0, should-type@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" + integrity sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM= + +should-util@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063" + integrity sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM= + +should@^13.2.3: + version "13.2.3" + resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" + integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== + dependencies: + should-equal "^2.0.0" + should-format "^3.0.3" + should-type "^1.4.0" + should-type-adaptors "^1.0.1" + should-util "^1.0.0" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-git@^1.85.0: + version "1.110.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.110.0.tgz#54eb179089d055a7783d32399246cebc9d9933e9" + integrity sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ== + dependencies: + debug "^4.0.1" + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +sliced@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" + integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E= + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sntp@0.2.x: + version "0.2.4" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-0.2.4.tgz#fb885f18b0f3aad189f824862536bceeec750900" + integrity sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA= + dependencies: + hoek "0.9.x" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-map-cjs@~0.1.31: + version "0.1.32" + resolved "https://registry.yarnpkg.com/source-map-cjs/-/source-map-cjs-0.1.32.tgz#b113f00065b484f4d3a1123ef084046a56228ce7" + integrity sha1-sRPwAGW0hPTToRI+8IQEalYijOc= + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.10: + version "0.5.11" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.11.tgz#efac2ce0800355d026326a0ca23e162aeac9a4e2" + integrity sha512-//sajEx/fGL3iw6fltKMdPvy8kL3kJ2O3iuYlRoT3k9Kb4BjOoZ+BZzaNHeuaruSt+Kf3Zk9tnfAQg9/AJqUVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + +source-map@^0.1.34, source-map@~0.1.33, source-map@~0.1.7: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.3: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + +source-map@~0.4.0, source-map@~0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +sourcemap-codec@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f" + integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg== + +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" + integrity sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.6.2" + signal-exit "^3.0.2" + which "^1.3.0" + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== + +spdx-license-list@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-license-list/-/spdx-license-list-3.0.1.tgz#163d72123e00f4f8bd6e18125696b009f1248ff5" + integrity sha1-Fj1yEj4A9Pi9bhgSVpawCfEkj/U= + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== + dependencies: + through2 "^2.0.2" + +split@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/split/-/split-0.1.2.tgz#f0710744c453d551fc7143ead983da6014e336cc" + integrity sha1-8HEHRMRT1VH8cUPq2YPaYBTjNsw= + dependencies: + through "1" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +stack-generator@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-1.1.0.tgz#36f6a920751a6c10f499a13c32cbb5f51a0b8b25" + integrity sha1-NvapIHUabBD0maE8Msu19RoLiyU= + dependencies: + stackframe "^1.0.2" + +stack-mapper@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stack-mapper/-/stack-mapper-0.2.2.tgz#789029054937b7d47c1b5b67612cbb1e7cfe7071" + integrity sha1-eJApBUk3t9R8G1tnYSy7Hnz+cHE= + dependencies: + array-map "0.0.0" + foreach-shim "~0.1.1" + isarray "0.0.1" + source-map-cjs "~0.1.31" + +stackframe@^0.3.1, stackframe@~0.3: + version "0.3.1" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" + integrity sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ= + +stackframe@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" + integrity sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw== + +stacktrace-gps@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-2.4.4.tgz#69c827e9d6d6f41cf438d7f195e2e3cbfcf28c44" + integrity sha1-acgn6dbW9Bz0ONfxleLjy/zyjEQ= + dependencies: + source-map "0.5.6" + stackframe "~0.3" + +stacktrace-js@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-1.3.1.tgz#67cab2589af5c417b962f7369940277bb3b6a18b" + integrity sha1-Z8qyWJr1xBe5Yvc2mUAne7O2oYs= + dependencies: + error-stack-parser "^1.3.6" + stack-generator "^1.0.7" + stacktrace-gps "^2.4.3" + +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== + +state-toggle@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a" + integrity sha512-Qe8QntFrrpWTnHwvwj2FZTgv+PKIsp0B9VxLzLLbSpPXWOgRgc5LVj/aTiSfK1RqIeF9jeC1UeOH8Q8y60A7og== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stream-browserify@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-combiner2@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" + integrity sha1-+02KFCDqNidk4hrUeAOXvry0HL4= + dependencies: + duplexer2 "~0.1.0" + readable-stream "^2.0.2" + +stream-combiner@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + integrity sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg= + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +stream-counter@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/stream-counter/-/stream-counter-0.2.0.tgz#ded266556319c8b0e222812b9cf3b26fa7d947de" + integrity sha1-3tJmVWMZyLDiIoErnPOyb6fZR94= + dependencies: + readable-stream "~1.1.8" + +stream-http@^2.0.0: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +stream-splicer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83" + integrity sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.2" + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.0, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-entities@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.2.tgz#a98417e5471fd227b3e45d3db1861c11caf668f7" + integrity sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A== + dependencies: + character-entities-html4 "^1.0.0" + character-entities-legacy "^1.0.0" + is-alphanumerical "^1.0.0" + is-hexadecimal "^1.0.0" + +stringify-object@^3.2.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +stringstream@~0.0.4: + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@0.1.x: + version "0.1.3" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-0.1.3.tgz#164c64e370a8a3cc00c9e01b539e569823f0ee54" + integrity sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ= + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +subarg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" + integrity sha1-9izxdYHplrSPyWVpn1TAauJouNI= + dependencies: + minimist "^1.1.0" + +superagent@0.15.7: + version "0.15.7" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-0.15.7.tgz#095c70b8afffbc072f1458f39684d4854d6333a3" + integrity sha1-CVxwuK//vAcvFFjzloTUhU1jM6M= + dependencies: + cookiejar "1.3.0" + debug "~0.7.2" + emitter-component "1.0.0" + formidable "1.0.14" + methods "0.0.1" + mime "1.2.5" + qs "0.6.5" + reduce-component "1.0.1" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU= + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.0.0, supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-hyperlinks@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" + integrity sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw== + dependencies: + has-flag "^2.0.0" + supports-color "^5.0.0" + +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +synchronous-promise@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.6.tgz#de76e0ea2b3558c1e673942e47e714a930fa64aa" + integrity sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g== + +syntax-error@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c" + integrity sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w== + dependencies: + acorn-node "^1.2.0" + +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== + dependencies: + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tap-finished@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tap-finished/-/tap-finished-0.0.1.tgz#08b5b543fdc04830290c6c561279552e71c4bd67" + integrity sha1-CLW1Q/3ASDApDGxWEnlVLnHEvWc= + dependencies: + tap-parser "~0.2.0" + through "~2.3.4" + +tap-parser@0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-0.7.0.tgz#728a61d64680a5b48d5dbd9dbd0a4d48f5c35bcb" + integrity sha1-coph1kaApbSNXb2dvQpNSPXDW8s= + dependencies: + inherits "~2.0.1" + minimist "^0.2.0" + readable-stream "~1.1.11" + +tap-parser@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-0.2.1.tgz#8e1e823f2114ee21d032e2f31e4fb642a296f50b" + integrity sha1-jh6CPyEU7iHQMuLzHk+2QqKW9Qs= + dependencies: + split "~0.1.2" + +tar-stream@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.0.2.tgz#fd19b4a17900fa704f6a133e3045aead0562ab95" + integrity sha1-/Rm0oXkA+nBPahM+MEWurQViq5U= + dependencies: + bl "^0.9.0" + end-of-stream "^1.0.0" + readable-stream "^1.0.27-1" + xtend "^4.0.0" + +tar-stream@~1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.1.5.tgz#be9218c130c20029e107b0f967fb23de0579d13c" + integrity sha1-vpIYwTDCACnhB7D5Z/sj3gV50Tw= + dependencies: + bl "^0.9.0" + end-of-stream "^1.0.0" + readable-stream "~1.0.33" + xtend "^4.0.0" + +tar@^4: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +teeny-request@^3.7.0: + version "3.11.3" + resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-3.11.3.tgz#335c629f7645e5d6599362df2f3230c4cbc23a55" + integrity sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw== + dependencies: + https-proxy-agent "^2.2.1" + node-fetch "^2.2.0" + uuid "^3.3.2" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +terser@^3.7.5: + version "3.17.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" + integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ== + dependencies: + commander "^2.19.0" + source-map "~0.6.1" + source-map-support "~0.5.10" + +test-exclude@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" + integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA== + dependencies: + arrify "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^1.0.1" + +text-extensions@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +the-argv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/the-argv/-/the-argv-1.0.0.tgz#0084705005730dd84db755253c931ae398db9522" + integrity sha1-AIRwUAVzDdhNt1UlPJMa45jblSI= + +through2@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-1.1.1.tgz#0847cbc4449f3405574dbdccd9bb841b83ac3545" + integrity sha1-CEfLxESfNAVXTb3M2buEG4OsNUU= + dependencies: + readable-stream ">=1.1.13-1 <1.2.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.2, through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/through/-/through-1.1.2.tgz#344a5425a3773314ca7e0eb6512fbafaf76c0bfe" + integrity sha1-NEpUJaN3MxTKfg62US+6+vdsC/4= + +through@2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.4.tgz#495e40e8d8a8eaebc7c275ea88c2b8fc14c56455" + integrity sha1-SV5A6Nio6uvHwnXqiMK4/BTFZFU= + +"through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.7, through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^1.0.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" + integrity sha1-ycWLV1voQHN1y14kYtrO50NZ9B0= + dependencies: + process "~0.11.0" + +tinyify@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tinyify/-/tinyify-2.5.0.tgz#7bacba9a2b8e1196584234d5d98718c2b5dd817f" + integrity sha512-SdKsUZM0k57hwdhjqZedWI4YSUcuVMmJabP6kOAvwHSlJJFR9PkTJ5meIiBRwjOnVwc0Q1xiTdj/FjzyGi099A== + dependencies: + browser-pack-flat "^3.0.9" + bundle-collapser "^1.3.0" + common-shakeify "^0.5.2" + envify "^4.1.0" + minify-stream "^1.1.0" + uglifyify "^5.0.0" + unassertify "^2.1.1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-vfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/to-vfile/-/to-vfile-4.0.0.tgz#465ade5fc2b9e97e6c80b854d378a5d0f4b5d04a" + integrity sha512-Y7EDM+uoU8TZxF5ej2mUR0dLO4qbuuNRnJKxEht2QJWEq2421pyG1D1x8YxPKmyTc6nHh7Td/jLGFxYo+9vkLA== + dependencies: + is-buffer "^2.0.0" + vfile "^3.0.0" + +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + +tough-cookie@>=0.12.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + +transform-ast@^2.4.2, transform-ast@^2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/transform-ast/-/transform-ast-2.4.4.tgz#bebf494e2e73f024746f76348bc86a5992851d00" + integrity sha512-AxjeZAcIOUO2lev2GDe3/xZ1Q0cVGjIMk5IsriTy8zbWlsEnjeB025AhkhBJHoy997mXpLd4R+kRbvnnQVuQHQ== + dependencies: + acorn-node "^1.3.0" + convert-source-map "^1.5.1" + dash-ast "^1.0.0" + is-buffer "^2.0.0" + magic-string "^0.23.2" + merge-source-map "1.0.4" + nanobench "^2.1.1" + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +trim-trailing-lines@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz#e0ec0810fd3c3f1730516b45f49083caaf2774d9" + integrity sha512-bWLv9BbWbbd7mlqqs2oQYnLD/U/ZqeJeJwbO0FG2zA1aTq+HTvxfHNKFa/HGCVyJpDiioUYaBhfiT6rgk+l4mg== + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +trough@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24" + integrity sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw== + +tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tty-browserify@0.0.1, tty-browserify@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + +tunnel-agent@~0.4.0: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@^1.6.4, type-is@~1.6.16, type-is@~1.6.2: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray@^0.0.6, typedarray@~0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uglify-js@^3.1.4, uglify-js@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.2.tgz#dc0c7ac2da0a4b7d15e84266818ff30e82529474" + integrity sha512-imog1WIsi9Yb56yRt5TfYVxGmnWs3WSGU73ieSOlMVFwhJCA9W8fqFFMMj4kgDqiS/80LGdsYnWL7O9UcjEBlg== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uglify-js@~2.3: + version "2.3.6" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.3.6.tgz#fa0984770b428b7a9b2a8058f46355d14fef211a" + integrity sha1-+gmEdwtCi3qbKoBY9GNV0U/vIRo= + dependencies: + async "~0.2.6" + optimist "~0.3.5" + source-map "~0.1.7" + +uglifyify@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/uglifyify/-/uglifyify-5.0.1.tgz#70b1d8b413c410348c8e35e7f8bd1330a422d5f6" + integrity sha512-PO44rgExvwj3rkK0UzenHVnPU18drBy9x9HOUmgkuRh6K2KIsDqrB5LqxGtjybgGTOS1JeP8SBc+TN5rhiva6w== + dependencies: + convert-source-map "~1.1.0" + extend "^1.2.1" + minimatch "^3.0.2" + terser "^3.7.5" + through "~2.3.4" + +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +umd@^3.0.0, umd@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf" + integrity sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow== + +unassert@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/unassert/-/unassert-1.5.1.tgz#cbc88ec387417c5a5e4c02d3cd07be98bd75ff76" + integrity sha1-y8iOw4dBfFpeTALTzQe+mL11/3Y= + dependencies: + acorn "^4.0.0" + call-matcher "^1.0.1" + deep-equal "^1.0.0" + espurify "^1.3.0" + estraverse "^4.1.0" + esutils "^2.0.2" + object-assign "^4.1.0" + +unassertify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/unassertify/-/unassertify-2.1.1.tgz#23772d76c136fb3d5df7dad4911c737d952357d3" + integrity sha512-YIAaIlc6/KC9Oib8cVZLlpDDhK1UTEuaDyx9BwD97xqxDZC0cJOqwFcs/Y6K3m73B5VzHsRTBLXNO0dxS/GkTw== + dependencies: + acorn "^5.1.0" + convert-source-map "^1.1.1" + escodegen "^1.6.1" + multi-stage-sourcemap "^0.2.1" + through "^2.3.7" + unassert "^1.3.1" + +undeclared-identifiers@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz#9254c1d37bdac0ac2b52de4b6722792d2a91e30f" + integrity sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw== + dependencies: + acorn-node "^1.3.0" + dash-ast "^1.0.0" + get-assigned-identifiers "^1.2.0" + simple-concat "^1.0.0" + xtend "^4.0.1" + +underscore.string@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.3.3.tgz#71c08bf6b428b1133f37e78fa3a21c82f7329b0d" + integrity sha1-ccCL9rQosRM/N+ePo6Icgvcymw0= + +unherit@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c" + integrity sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g== + dependencies: + inherits "^2.0.1" + xtend "^4.0.1" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" + integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" + integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + +unified-args@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/unified-args/-/unified-args-6.0.0.tgz#ffa3be9372ebe311099b30435b17269b0000d04c" + integrity sha512-1m2pGiTClgcCtCvgtABkJLze8JJiZpzsqujRhzBjZsRwaIIU1Yj36YHY6t2RvidO8d6fucZdk3KX+8eS4+uv9g== + dependencies: + camelcase "^5.0.0" + chalk "^2.0.0" + chokidar "^2.0.0" + fault "^1.0.2" + json5 "^1.0.0" + minimist "^1.2.0" + text-table "^0.2.0" + unified-engine "^6.0.0" + +unified-engine@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unified-engine/-/unified-engine-6.0.1.tgz#22236f1d253a6d07b6605eca83a2bcce08fc6f05" + integrity sha512-iDJYH82TgcezQA4IZzhCNJQx7vBsGk4h9s4Q7Fscrb3qcPsxBqVrVNYez2W3sBVTxuU1bFAhyRpA6ba/R4j93A== + dependencies: + concat-stream "^1.5.1" + debug "^3.1.0" + fault "^1.0.0" + fn-name "^2.0.1" + glob "^7.0.3" + ignore "^3.2.0" + is-empty "^1.0.0" + is-hidden "^1.0.1" + is-object "^1.0.1" + js-yaml "^3.6.1" + load-plugin "^2.0.0" + parse-json "^4.0.0" + to-vfile "^4.0.0" + trough "^1.0.0" + unist-util-inspect "^4.1.2" + vfile-reporter "^5.0.0" + vfile-statistics "^1.1.0" + x-is-string "^0.1.0" + xtend "^4.0.1" + +unified-lint-rule@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/unified-lint-rule/-/unified-lint-rule-1.0.3.tgz#e302b0c4a7ac428c0980e049a500e59528001299" + integrity sha512-6z+HH3mtlFdj/w3MaQpObrZAd9KRiro370GxBFh13qkV8LYR21lLozA4iQiZPhe7KuX/lHewoGOEgQ4AWrAR3Q== + dependencies: + wrapped "^1.0.1" + +unified-message-control@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unified-message-control/-/unified-message-control-1.0.4.tgz#a5e02c07112f78c6687b83a10392c2fba86dc09b" + integrity sha512-e1dEtN4Z/TvLn/qHm+xeZpzqhJTtfZusFErk336kkZVpqrJYiV9ptxq+SbRPFMlN0OkjDYHmVJ929KYjsMTo3g== + dependencies: + trim "0.0.1" + unist-util-visit "^1.0.0" + vfile-location "^2.0.0" + +unified@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-7.1.0.tgz#5032f1c1ee3364bd09da12e27fdd4a7553c7be13" + integrity sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw== + dependencies: + "@types/unist" "^2.0.0" + "@types/vfile" "^3.0.0" + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^1.1.0" + trough "^1.0.0" + vfile "^3.0.0" + x-is-string "^0.1.0" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +unist-util-generated@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.3.tgz#ca650470aef2fbcc5fe54c465bc26b41ca109e2b" + integrity sha512-qlPeDqnQnd84KIqwphzOR+l02cxjDzvEYEBl84EjmKRrX4eUmjyAo8xJv1SCDhJqNjyHRnBMZWNKAiBtXE6hBg== + +unist-util-inspect@^4.1.2: + version "4.1.3" + resolved "https://registry.yarnpkg.com/unist-util-inspect/-/unist-util-inspect-4.1.3.tgz#39470e6d77485db285966df78431219aa1287822" + integrity sha512-Fv9R88ZBbDp7mHN+wsbxS1r8VW3unyhZh/F18dcJRQsg0+g3DxNQnMS+AEG/uotB8Md+HMK/TfzSU5lUDWxkZg== + dependencies: + is-empty "^1.0.0" + +unist-util-is@^2.0.0, unist-util-is@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db" + integrity sha512-YkXBK/H9raAmG7KXck+UUpnKiNmUdB+aBGrknfQ4EreE1banuzrKABx3jP6Z5Z3fMSPMQQmeXBlKpCbMwBkxVw== + +unist-util-modify-children@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.3.tgz#d764a935f612dfb21b1bb92b0ea24321dc19a5f7" + integrity sha512-Aw3Us+NPrJGYWyLhcaqYzgxd/pryIanDNHVVvwdtTEEQ3Yfa/+sjnT2EeAAHbtTMAaYEdPW3XN6jxbzVWAo/BQ== + dependencies: + array-iterate "^1.0.0" + +unist-util-position@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.0.2.tgz#80ad4a05efc4ab01a66886cc70493893ba73c5eb" + integrity sha512-npmFu92l/+b1Ao6uGP4I1WFz9hsKv7qleZ4aliw6x0RVu6A9A3tAf57NMpFfzQ02jxRtJZuRn+C8xWT7GWnH0g== + +unist-util-remove-position@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz#86b5dad104d0bbfbeb1db5f5c92f3570575c12cb" + integrity sha512-XxoNOBvq1WXRKXxgnSYbtCF76TJrRoe5++pD4cCBsssSiWSnPEktyFrFLE8LTk3JW5mt9hB0Sk5zn4x/JeWY7Q== + dependencies: + unist-util-visit "^1.1.0" + +unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1, unist-util-stringify-position@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6" + integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ== + +unist-util-visit-children@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-children/-/unist-util-visit-children-1.1.2.tgz#bd78b53db9644b9c339ac502854f15471f964f5b" + integrity sha512-q4t6aprUcSQ2/+xlswuh2wUKwUUuMmDjSkfwkMjeVwCXc8NqX8g0FSmNf68CznCmbkrsOPDUR0wj14bCFXXqbA== + +unist-util-visit-parents@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217" + integrity sha512-6B0UTiMfdWql4cQ03gDTCSns+64Zkfo2OCbK31Ov0uMizEz+CJeAp0cgZVb5Fhmcd7Bct2iRNywejT0orpbqUA== + dependencies: + unist-util-is "^2.1.2" + +unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.1.1, unist-util-visit@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.0.tgz#1cb763647186dc26f5e1df5db6bd1e48b3cc2fb1" + integrity sha512-FiGu34ziNsZA3ZUteZxSFaczIjGmksfSgdKqBfOejrrfzyUy5b7YrlzT1Bcvi+djkYDituJDy2XB7tGTeBieKw== + dependencies: + unist-util-visit-parents "^2.0.0" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + integrity sha1-F+soB5h/dpUunASF/DEdBqgmouA= + dependencies: + os-homedir "^1.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +urlgrey@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" + integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8= + +urljoin@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/urljoin/-/urljoin-0.1.5.tgz#b25d2c6112c55ac9d50096a49a0f1fb7f4f53921" + integrity sha1-sl0sYRLFWsnVAJakmg8ft/T1OSE= + dependencies: + extend "~2.0.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@~0.10.1: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vargs@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" + integrity sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8= + +vary@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" + integrity sha1-meSYFWaihhGN+yuBc1ffeZM3bRA= + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vfile-location@^2.0.0, vfile-location@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.4.tgz#2a5e7297dd0d9e2da4381464d04acc6b834d3e55" + integrity sha512-KRL5uXQPoUKu+NGvQVL4XLORw45W62v4U4gxJ3vRlDfI9QsT4ZN1PNXn/zQpKUulqGDpYuT0XDfp5q9O87/y/w== + +vfile-message@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1" + integrity sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA== + dependencies: + unist-util-stringify-position "^1.1.1" + +vfile-reporter@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-5.1.1.tgz#419688c7e9dcaf65ba81bfdb0ad443e9e0248e09" + integrity sha512-A/cfKvfVmeEmAKx1yyOWggCjC/k184Vkl5pVJAw5CEdppHd5FHBVcdyJ1JBSqIdJjJqyhZY4ZD3JycHr/uwmlA== + dependencies: + repeat-string "^1.5.0" + string-width "^2.0.0" + supports-color "^5.4.0" + unist-util-stringify-position "^1.0.0" + vfile-sort "^2.1.2" + vfile-statistics "^1.1.0" + +vfile-sort@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-2.2.0.tgz#383a8727ec4c5daf37c05683684a5eb686366d39" + integrity sha512-RgxLXVWrJBWb2GuP8FsSkqK7HmbjXjnI8qx3nD6NTWhsWaelaKvJuxfh1F1d1lkCPD7imo4zzi8cf6IOMgaTnQ== + +vfile-statistics@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vfile-statistics/-/vfile-statistics-1.1.2.tgz#c50132627e4669a3afa07c64ff1e7aa7695e8151" + integrity sha512-16wAC9eEGXdsD35LX9m/iXCRIZyX5LIrDgDtAF92rbATSqsBRbC4n05e0Rj5vt3XRpcKu0UJeWnTxWsSyvNZ+w== + +vfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-3.0.1.tgz#47331d2abe3282424f4a4bb6acd20a44c4121803" + integrity sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ== + dependencies: + is-buffer "^2.0.0" + replace-ext "1.0.0" + unist-util-stringify-position "^1.0.0" + vfile-message "^1.0.0" + +vm-browserify@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" + integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== + +vm-browserify@~0.0.1: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +walk@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/walk/-/walk-2.2.1.tgz#5ada1f8e49e47d4b7445d8be7a2e1e631ab43016" + integrity sha1-WtofjknkfUt0Rdi+ei4eYxq0MBY= + dependencies: + forEachAsync "~2.2" + +watchify@3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/watchify/-/watchify-3.7.0.tgz#ee2f2c5c8c37312303f998b818b2b3450eefe648" + integrity sha1-7i8sXIw3MSMD+Zi4GLKzRQ7v5kg= + dependencies: + anymatch "^1.3.0" + browserify "^13.0.0" + chokidar "^1.0.0" + defined "^1.0.0" + outpipe "^1.1.0" + through2 "^2.0.0" + xtend "^4.0.0" + +wd@0.3.11: + version "0.3.11" + resolved "https://registry.yarnpkg.com/wd/-/wd-0.3.11.tgz#522716c79a7a10e781acbb2c6cafe588f701fcc0" + integrity sha1-UicWx5p6EOeBrLssbK/liPcB/MA= + dependencies: + archiver "~0.12.0" + async "~0.9.0" + lodash "~2.4.1" + q "~1.0.1" + request "~2.46.0" + underscore.string "~2.3.3" + vargs "~0.1.0" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/which/-/which-1.0.9.tgz#460c1da0f810103d0321a9b633af9e575e64486f" + integrity sha1-RgwdoPgQED0DIam2M6+eV15kSG8= + +which@^1.1.1, which@^1.2.10, which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +wordwrap@0.0.x, wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + +wrap-comment@^1.0.0, wrap-comment@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wrap-comment/-/wrap-comment-1.0.1.tgz#941bb1400b9b590bc007599e79cacc0bb3ea62f3" + integrity sha512-APccrMwl/ont0RHFTXNAQfM647duYYEfs6cngrIyTByTI0xbWnDnPSptFZhS68L4WCjt2ZxuhCFwuY6Pe88KZQ== + +wrapped@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wrapped/-/wrapped-1.0.1.tgz#c783d9d807b273e9b01e851680a938c87c907242" + integrity sha1-x4PZ2Aeyc+mwHoUWgKk4yHyQckI= + dependencies: + co "3.1.0" + sliced "^1.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +wrench@~1.5.1: + version "1.5.9" + resolved "https://registry.yarnpkg.com/wrench/-/wrench-1.5.9.tgz#411691c63a9b2531b1700267279bdeca23b2142a" + integrity sha1-QRaRxjqbJTGxcAJnJ5veyiOyFCo= + +write-file-atomic@^2.0.0, write-file-atomic@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-json-file@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +x-is-string@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xml2js@~0.4.0: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + +xo-init@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/xo-init/-/xo-init-0.7.0.tgz#634b4789e366b4f87f747ef0cee1a99ce273aa15" + integrity sha512-mrrCKMu52vz0u2tiOl8DoG709pBtnSp58bb4/j58a4jeXjrb1gV7dxfOBjOlXitYtfW2QnlxxxfAojoFcpynDg== + dependencies: + arrify "^1.0.0" + execa "^0.9.0" + has-yarn "^1.0.0" + minimist "^1.1.3" + path-exists "^3.0.0" + read-pkg-up "^3.0.0" + the-argv "^1.0.0" + write-pkg "^3.1.0" + +xo@0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/xo/-/xo-0.24.0.tgz#f931ff453f3440919d51da908591371e8ed714e0" + integrity sha512-eaXWpNtXHbJ+DSiDkdRnDcMYPeUi/MWFUoUgorBhzAueTCM+v4o9Xv6buYgyoL4r7JuTp5EWXx3lGn9Md4dgWA== + dependencies: + arrify "^1.0.1" + debug "^4.1.0" + eslint "^5.12.0" + eslint-config-prettier "^3.3.0" + eslint-config-xo "^0.26.0" + eslint-formatter-pretty "^2.0.0" + eslint-plugin-ava "^5.1.0" + eslint-plugin-eslint-comments "^3.0.1" + eslint-plugin-import "^2.14.0" + eslint-plugin-no-use-extend-native "^0.4.0" + eslint-plugin-node "^8.0.0" + eslint-plugin-prettier "^3.0.0" + eslint-plugin-promise "^4.0.0" + eslint-plugin-unicorn "^7.0.0" + find-cache-dir "^2.0.0" + get-stdin "^6.0.0" + globby "^9.0.0" + has-flag "^3.0.0" + lodash.isequal "^4.5.0" + lodash.mergewith "^4.6.1" + meow "^5.0.0" + multimatch "^3.0.0" + open-editor "^1.2.0" + path-exists "^3.0.0" + pkg-conf "^2.1.0" + prettier "^1.15.2" + resolve-cwd "^2.0.0" + resolve-from "^4.0.0" + semver "^5.5.0" + slash "^2.0.0" + update-notifier "^2.3.0" + xo-init "^0.7.0" + +xtend@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= + dependencies: + object-keys "~0.4.0" + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +"y18n@^3.2.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yamljs@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.2.8.tgz#ef23fb006e62f6ae07b406aa2a949561f336ea5c" + integrity sha1-7yP7AG5i9q4HtAaqKpSVYfM26lw= + dependencies: + argparse "^1.0.7" + glob "^7.0.5" + +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yup@^0.26.10: + version "0.26.10" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.26.10.tgz#3545839663289038faf25facfc07e11fd67c0cb1" + integrity sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw== + dependencies: + "@babel/runtime" "7.0.0" + fn-name "~2.0.1" + lodash "^4.17.10" + property-expr "^1.5.0" + synchronous-promise "^2.0.5" + toposort "^2.0.2" + +zip-stream@~0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-0.2.3.tgz#aef095376cfe138959a81341981d26338b46d8d3" + integrity sha1-rvCVN2z+E4lZqBNBmB0mM4tG2NM= + dependencies: + debug "~0.7.4" + lodash.defaults "~2.4.1" + readable-stream "~1.0.24" + +zip-stream@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-0.4.1.tgz#4ea795a8ce19e9fab49a31d1d0877214159f03a3" + integrity sha1-TqeVqM4Z6fq0mjHR0IdyFBWfA6M= + dependencies: + compress-commons "~0.1.0" + lodash "~2.4.1" + readable-stream "~1.0.26" + +zip-stream@~0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-0.5.2.tgz#32dcbc506d0dab4d21372625bd7ebaac3c2fff56" + integrity sha1-Mty8UG0Nq00hNyYlvX66rDwv/1Y= + dependencies: + compress-commons "~0.2.0" + lodash "~3.2.0" + readable-stream "~1.0.26" + +zuul-localtunnel@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/zuul-localtunnel/-/zuul-localtunnel-1.1.0.tgz#70ad27fb0a6af968a2151fc5d5e895daa1aed15d" + integrity sha1-cK0n+wpq+WiiFR/F1eiV2qGu0V0= + dependencies: + localtunnel "1.5.0" + +zuul@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/zuul/-/zuul-3.12.0.tgz#2ba48310588e173d74e61a9e51cf01e7cfe53e4d" + integrity sha512-ABOM+J+get8DsLXmFmCUjJOwxZILsedXZ0+bJnG9ajmDhVmtLqaUPJ9NEardYzSHxq6Vxi5qXf4mluA7PePq/A== + dependencies: + JSON2 "0.1.0" + batch "0.5.0" + browserify "13.0.0" + browserify-istanbul "0.1.5" + char-split "0.2.0" + colors "0.6.2" + commander "2.1.0" + compression "1.5.0" + convert-source-map "1.0.0" + debug "2.1.0" + express "3.4.8" + express-state "1.0.3" + find-nearest-file "1.0.0" + firefox-profile "0.2.7" + globs-to-files "1.0.0" + hbs "2.4.0" + highlight.js "7.5.0" + http-proxy "1.11.2" + humanize-duration "2.4.0" + istanbul-middleware "0.2.2" + load-script "0.0.5" + lodash "3.10.1" + opener "1.4.0" + osenv "0.0.3" + shallow-copy "0.0.1" + shell-quote "1.4.1" + stack-mapper "0.2.2" + stacktrace-js "1.3.1" + superagent "0.15.7" + tap-finished "0.0.1" + tap-parser "0.7.0" + watchify "3.7.0" + wd "0.3.11" + xtend "2.1.2" + yamljs "0.2.8" + zuul-localtunnel "1.1.0"