From f7315c3d9e218ee92bbcce630bf5c3343be34c36 Mon Sep 17 00:00:00 2001 From: Mike Rourke Date: Sat, 22 Jul 2017 17:02:09 -0500 Subject: [PATCH] Implement custom rate limiter due to security issues Remove the request-rate-limiter dependency because it was relying on an older insecure version of request. --- package.json | 8 +- src/utils/api-request.js | 14 +- src/utils/query-args-stringifier.js | 10 +- src/utils/request-rate-limiter.js | 120 +++++++++++ yarn.lock | 322 +++++++++------------------- 5 files changed, 234 insertions(+), 240 deletions(-) create mode 100644 src/utils/request-rate-limiter.js diff --git a/package.json b/package.json index 12a5d2a..82ddca7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "trello-for-wolves", - "version": "1.4.6", + "version": "1.4.7", "description": "Node.js wrapper for Trello API...for wolves.", "engines": { "node": ">=6.11.0" @@ -47,8 +47,10 @@ "LICENSE" ], "dependencies": { + "async-method": "^0.1.1", + "leaky-bucket": "^2.1.1", "lodash.snakecase": "^4.1.1", - "request-rate-limiter": "^1.0.2" + "request": "^2.81.0" }, "devDependencies": { "apidoc": "^0.17.6", @@ -71,7 +73,7 @@ "eslint-config-airbnb-base": "^11.2.0", "eslint-plugin-flowtype": "^2.33.0", "eslint-plugin-import": "^2.2.0", - "flow-bin": "^0.49.1", + "flow-bin": "^0.51.0", "flow-copy-source": "^1.1.0", "jsonfile": "^3.0.0", "mocha": "^3.4.2", diff --git a/src/utils/api-request.js b/src/utils/api-request.js index ef7d07c..5712593 100644 --- a/src/utils/api-request.js +++ b/src/utils/api-request.js @@ -1,10 +1,8 @@ /* @flow */ -/* External dependencies */ -import RateLimiter from 'request-rate-limiter'; - /* Internal dependencies */ import { ApiCallResponseError } from '../utils/errors'; +import RequestRateLimiter from '../utils/request-rate-limiter'; /* Types */ import type { HttpMethod } from '../types'; @@ -57,23 +55,21 @@ const performApiRequest = ( // Build the configuration object for sending the request. const requestConfig = getRequestConfig(httpMethod, requestUrl, queryArgs); - const limiter = new RateLimiter({ - rate: 100, - interval: 10, + const limiter = new RequestRateLimiter({ backoffTime, maxWaitingTime, }); limiter.request(requestConfig, (error, response) => { - /* instanbul ignore next */ + /* instanbul ignore if */ if (error) { reject(new Error(`Error performing request: ${error}`)); } - /* instanbul ignore next */ + /* instanbul ignore if */ if (!response) { reject(new Error('No response present when performing request.')); } - const { statusCode = 400, body, ...responseData } = response; + const { statusCode /* instanbul ignore next */ = 400, body, ...responseData } = response; if (statusCode > 299 || statusCode < 200) { reject(new ApiCallResponseError(statusCode, httpMethod, requestUrl, body)); } diff --git a/src/utils/query-args-stringifier.js b/src/utils/query-args-stringifier.js index 936d990..c44264e 100644 --- a/src/utils/query-args-stringifier.js +++ b/src/utils/query-args-stringifier.js @@ -96,6 +96,7 @@ const getKeyForQueryString = (key: string): string => { } // Ensure this doesn't get converted to one word. + /* istanbul ignore if */ if (key === 'cardBoard') { return 'card_board'; } @@ -119,11 +120,14 @@ const getKeyForQueryString = (key: string): string => { if (recasedKey.includes('_state')) { recasedKey = recasedKey.replace('_state', 'State'); } - } else /* istanbul ignore if */ if (recasedKey.includes('sort_by')) { + /* istanbul ignore else */ + } else if (recasedKey.includes('sort_by')) { recasedKey = recasedKey.replace('sort_by', 'sortBy'); - } else /* istanbul ignore if */ if (recasedKey.includes('sort_order')) { + /* istanbul ignore else */ + } else if (recasedKey.includes('sort_order')) { recasedKey = recasedKey.replace('sort_order', 'sortOrder'); - } else /* istanbul ignore if */ if (recasedKey.includes('start_index')) { + /* istanbul ignore else */ + } else if (recasedKey.includes('start_index')) { recasedKey = recasedKey.replace('start_index', 'startIndex'); } diff --git a/src/utils/request-rate-limiter.js b/src/utils/request-rate-limiter.js new file mode 100644 index 0000000..5f3b766 --- /dev/null +++ b/src/utils/request-rate-limiter.js @@ -0,0 +1,120 @@ +/* @flow */ + +/** + * This code was taken from the request-rate-limiter library on npm. I added Flow + * typing and removed some of the logging functionality. I copied it over because + * the library is using an old version of the request library that is insecure. + * @see https://www.npmjs.com/package/request-rate-limiter + */ + +/* External dependencies */ +import asyncMethod from 'async-method'; +import request from 'request'; +import LeakyBucket from 'leaky-bucket'; + +export default class RequestRateLimiter { + bucket: Object; + backoffTime: number; + backoffTimer: any; + request: Function; + + constructor( + options: { + backoffTime: number, + maxWaitingTime: number, + }, + ) { + const { backoffTime, maxWaitingTime } = options; + this.backoffTime = backoffTime; + this.bucket = new LeakyBucket({ + capacity: 100, + interval: 10, + maxWaitingTime, + }); + this.assignRequest(); + } + + /* istanbul ignore next */ + isConfigAFunction(config: Object | Function): boolean { + return !!(config && config.constructor && config.call && config.apply); + } + + assignRequest(): void { + this.request = asyncMethod((requestConfig, callback) => { + const executeRequest = (error, executeCallback) => { + const config = executeCallback || requestConfig; + /* istanbul ignore if */ + if (error) { + this.handleError(config, callback); + } else { + /* istanbul ignore if */ + if (typeof config !== 'object' && this.isConfigAFunction(config)) { // eslint-disable-line + config(null, () => { + this.backoff(() => executeRequest(null, config)); + }); + } else { + this.performRequest(config, callback); + } + } + }; + this.bucket.throttle(executeRequest); + }); + } + + /* istanbul ignore next */ + handleError(config: Object | Function, callback: Function): void { + const errorMessage = 'The request was not executed because it would not be scheduled within ' + + 'the max waiting time!'; + /* istanbul ignore if */ + if (typeof config !== 'object' && this.isConfigAFunction(config)) { + config(new Error(errorMessage)); + /* istanbul ignore else */ + } else { + callback(new Error(errorMessage)); + } + } + + backoff( + /* istanbul ignore next */ + config?: Object | Function = {}, + /* istanbul ignore next */ + callback?: Function = () => {}, + ): void { + if (!this.backoffTimer) { + this.backoffTimer = setTimeout(() => { + this.backoffTimer = null; + }, this.backoffTime * 1000); + + this.bucket.pause(this.backoffTime); + } + this.bucket.reAdd((error) => { + /* istanbul ignore if */ + if (error) { + this.handleError(config, callback); + } else { + /* istanbul ignore if */ + if (typeof config !== 'object' && this.isConfigAFunction(config)) { // eslint-disable-line + config(); + } else { + this.performRequest(config, callback); + } + } + }); + } + + performRequest( + config: Object | Function, + callback: Function, + ): void { + request(config, (error, response) => { + /* istanbul ignore if */ + if (error) { + callback(error); + } else if (response.statusCode === 429) { + this.backoff(config, callback); + } else { + callback(null, response); + } + }); + } +} diff --git a/yarn.lock b/yarn.lock index 5e6973b..4c37d20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,8 +17,8 @@ acorn@^3.0.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" acorn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.0.tgz#e468bf609b0672700e02f878ae2f1b360fe24b4f" + version "5.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" ajv-keywords@^1.0.0: version "1.5.1" @@ -31,6 +31,15 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -153,10 +162,6 @@ arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" -asn1@0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7" - asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -165,10 +170,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" -assert-plus@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" - assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" @@ -181,7 +182,7 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -async-method@0.x.x: +async-method@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/async-method/-/async-method-0.1.1.tgz#8459089eef0ecd47def5e5f6d9edef3b2ac809d7" dependencies: @@ -194,10 +195,6 @@ async@^1.4.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@~0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" @@ -206,10 +203,6 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -aws-sign2@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63" - aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" @@ -708,12 +701,6 @@ binary-extensions@^1.0.0: version "1.8.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" -bl@~0.9.0: - version "0.9.5" - resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054" - dependencies: - readable-stream "~1.0.26" - block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -787,10 +774,6 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" -caseless@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.9.0.tgz#b7b65ce6bf1413886539cfd533f0b30effa9cf88" - center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" @@ -805,8 +788,8 @@ chai-as-promised@^7.0.0: check-error "^1.0.2" chai@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.0.2.tgz#2f7327c4de6f385dd7787999e2ab02697a32b83b" + version "4.1.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.0.tgz#331a0391b55c3af8740ae9c3b7458bc1c3805e6d" dependencies: assertion-error "^1.0.1" check-error "^1.0.1" @@ -815,7 +798,7 @@ chai@^4.0.2: pathval "^1.0.0" type-detect "^4.0.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -825,7 +808,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1: +chalk@^2.0.0, chalk@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" dependencies: @@ -905,8 +888,8 @@ color-convert@^1.0.0: color-name "^1.1.1" color-name@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" colors@1.0.x: version "1.0.3" @@ -918,12 +901,6 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -combined-stream@~0.0.4, combined-stream@~0.0.5: - version "0.0.7" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f" - dependencies: - delayed-stream "0.0.5" - commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -987,14 +964,14 @@ cross-env@^5.0.0: cross-spawn "^5.1.0" is-windows "^1.0.0" -cross-spawn@^4, cross-spawn@^4.0.0: +cross-spawn@^4: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" dependencies: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^5.1.0: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -1008,10 +985,6 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" -ctype@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f" - cycle@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" @@ -1074,10 +1047,6 @@ del@^2.0.2: pinkie-promise "^2.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" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1140,13 +1109,6 @@ ee-log@0.3.x: ee-class "1.x" ee-types "2.x" -ee-log@1.x: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ee-log/-/ee-log-1.1.0.tgz#31b1ef1bda720ccec29523df05482428ceea3582" - dependencies: - ee-class "1.x" - ee-types "2.x" - ee-types@0.1.x: version "0.1.3" resolved "https://registry.yarnpkg.com/ee-types/-/ee-types-0.1.3.tgz#785baa2f50a78aab48943f335111b8fb79ac61b9" @@ -1194,7 +1156,7 @@ eslint-import-resolver-node@^0.3.1: debug "^2.6.8" resolve "^1.2.0" -eslint-module-utils@^2.0.0: +eslint-module-utils@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" dependencies: @@ -1202,21 +1164,21 @@ eslint-module-utils@^2.0.0: pkg-dir "^1.0.0" eslint-plugin-flowtype@^2.33.0: - version "2.34.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.34.1.tgz#ea109175645b05d37baeac53b9b65066d79b9446" + version "2.35.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.35.0.tgz#d17494f0ae8b727c632d8b9d4b4a848e7e0c04af" dependencies: lodash "^4.15.0" eslint-plugin-import@^2.2.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.6.1.tgz#f580be62bb809421d46e338372764afcc9f59bf6" + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" debug "^2.6.8" doctrine "1.5.0" eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.0.0" + eslint-module-utils "^2.1.1" has "^1.0.1" lodash.cond "^4.3.0" minimatch "^3.0.3" @@ -1230,12 +1192,14 @@ eslint-scope@^3.7.1: estraverse "^4.1.1" eslint@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.1.1.tgz#facbdfcfe3e0facd3a8b80dc98c4e6c13ae582df" + version "4.3.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.3.0.tgz#fcd7c96376bbf34c85ee67ed0012a299642b108f" dependencies: + ajv "^5.2.0" babel-code-frame "^6.22.0" chalk "^1.1.3" concat-stream "^1.6.0" + cross-spawn "^5.1.0" debug "^2.6.8" doctrine "^2.0.0" eslint-scope "^3.7.1" @@ -1244,12 +1208,12 @@ eslint@^4.0.0: estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" glob "^7.1.2" globals "^9.17.0" ignore "^3.3.3" imurmurhash "^0.1.4" inquirer "^3.0.6" - is-my-json-valid "^2.16.0" is-resolvable "^1.0.0" js-yaml "^3.8.4" json-stable-stringify "^1.0.1" @@ -1263,6 +1227,7 @@ eslint@^4.0.0: pluralize "^4.0.0" progress "^2.0.0" require-uncached "^1.0.3" + semver "^5.3.0" strip-json-comments "~2.0.1" table "^4.0.1" text-table "~0.2.0" @@ -1278,9 +1243,9 @@ esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" esquery@^1.0.0: version "1.0.0" @@ -1303,12 +1268,12 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -execa@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" dependencies: - cross-spawn "^4.0.0" - get-stream "^2.2.0" + 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" @@ -1353,6 +1318,10 @@ eyes@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -1414,9 +1383,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.49.1: - version "0.49.1" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.49.1.tgz#c9e456b3173a7535a4ffaf28956352c63bb8e3e9" +flow-bin@^0.51.0: + version "0.51.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.51.0.tgz#97a3c511a17caa25d8fad58fc17aaabcb86319fe" flow-copy-source@^1.1.0: version "1.2.0" @@ -1445,22 +1414,10 @@ foreground-child@^1.5.3, foreground-child@^1.5.6: 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" - forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.2.0.tgz#26f8bc26da6440e299cbdcfb69035c4f77a6e466" - dependencies: - async "~0.9.0" - combined-stream "~0.0.4" - mime-types "~2.0.3" - form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" @@ -1513,6 +1470,10 @@ function-bind@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" +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" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1544,12 +1505,9 @@ get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" getpass@^0.1.1: version "0.1.7" @@ -1677,15 +1635,6 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" -hawk@~2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-2.3.1.tgz#1e731ce39447fa1d0f6d707f7bceebec0fd1ec1f" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -1710,14 +1659,6 @@ hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" -http-signature@~0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66" - dependencies: - asn1 "0.1.11" - assert-plus "^0.1.5" - ctype "0.5.3" - http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -1745,7 +1686,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -1754,11 +1695,11 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" inquirer@^3.0.6: - version "3.1.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534" + version "3.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.0.tgz#45b44c2160c729d7578c54060b3eed94487bb42b" dependencies: ansi-escapes "^2.0.0" - chalk "^1.0.0" + chalk "^2.0.0" cli-cursor "^2.1.0" cli-width "^2.0.0" external-editor "^2.0.4" @@ -1768,8 +1709,8 @@ inquirer@^3.0.6: run-async "^2.2.0" rx-lite "^4.0.8" rx-lite-aggregates "^4.0.8" - string-width "^2.0.0" - strip-ansi "^3.0.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" through "^2.3.6" invariant@^2.2.0: @@ -1842,7 +1783,7 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-my-json-valid@^2.12.4, is-my-json-valid@^2.16.0: +is-my-json-valid@^2.12.4: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" dependencies: @@ -1917,10 +1858,6 @@ is-windows@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - 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" @@ -1935,7 +1872,7 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" -isstream@0.1.x, isstream@~0.1.1, isstream@~0.1.2: +isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -1949,9 +1886,9 @@ istanbul-lib-hook@^1.0.7: dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.7.2, istanbul-lib-instrument@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.3.tgz#925b239163eabdd68cc4048f52c2fa4f899ecfa7" +istanbul-lib-instrument@^1.7.2, istanbul-lib-instrument@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz#e9fd920e4767f3d19edc765e2d6b3f5ccbd0eea8" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" @@ -1998,19 +1935,19 @@ js-yaml@3.6.1: esprima "^2.6.0" js-yaml@^3.8.4: - version "3.8.4" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" + version "3.9.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.0.tgz#4ffbbf25c2ac963b8299dc74da7e3740de1c18ce" dependencies: argparse "^1.0.7" - esprima "^3.1.1" + esprima "^4.0.0" jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" jschardet@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.4.2.tgz#2aa107f142af4121d145659d44f50830961e699a" + version "1.5.0" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.0.tgz#a61f310306a5a71188e1b1acd08add3cfbb08b1e" jsesc@^1.3.0: version "1.3.0" @@ -2020,6 +1957,10 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -2030,7 +1971,7 @@ json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1: +json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -2066,8 +2007,8 @@ jsprim@^1.2.2: verror "1.3.6" kefir@^3.2.0: - version "3.7.2" - resolved "https://registry.yarnpkg.com/kefir/-/kefir-3.7.2.tgz#fb713ecc0b24d741964e0b3e308026fae5c0806d" + version "3.7.3" + resolved "https://registry.yarnpkg.com/kefir/-/kefir-3.7.3.tgz#c1d4e0a7a9f63cfd73720ae38e0630c14784ed97" dependencies: symbol-observable "1.0.4" @@ -2103,7 +2044,7 @@ lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" -leaky-bucket@2.x: +leaky-bucket@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/leaky-bucket/-/leaky-bucket-2.1.1.tgz#6a1d8a4a6391bc4b10506c29ef49cbb27b515847" dependencies: @@ -2285,10 +2226,6 @@ micromatch@^2.1.5, micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -mime-db@~1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.12.0.tgz#3d0c63180f458eb10d325aaa37d7c58ae312e9d7" - mime-db@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" @@ -2299,12 +2236,6 @@ mime-types@^2.1.12, mime-types@~2.1.7: dependencies: mime-db "~1.27.0" -mime-types@~2.0.1, mime-types@~2.0.3: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.0.14.tgz#310e159db23e077f8bb22b748dabfa4957140aa6" - dependencies: - mime-db "~1.12.0" - mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" @@ -2387,10 +2318,6 @@ node-pre-gyp@^0.6.36: tar "^2.2.1" tar-pack "^3.4.0" -node-uuid@~1.4.0: - version "1.4.8" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" - nomnom@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" @@ -2440,8 +2367,8 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" nyc@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.0.3.tgz#0c28bc669a851621709bf7a08503034bee3812b6" + version "11.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.1.0.tgz#d6b3c5e16892a25af63138ba484676aa8a22eda7" dependencies: archy "^1.0.0" arrify "^1.0.1" @@ -2455,7 +2382,7 @@ nyc@^11.0.3: glob "^7.0.6" istanbul-lib-coverage "^1.1.1" istanbul-lib-hook "^1.0.7" - istanbul-lib-instrument "^1.7.3" + istanbul-lib-instrument "^1.7.4" istanbul-lib-report "^1.1.1" istanbul-lib-source-maps "^1.2.1" istanbul-reports "^1.1.1" @@ -2466,15 +2393,11 @@ nyc@^11.0.3: resolve-from "^2.0.0" rimraf "^2.5.4" signal-exit "^3.0.1" - spawn-wrap "^1.3.7" + spawn-wrap "^1.3.8" test-exclude "^4.1.1" yargs "^8.0.1" yargs-parser "^5.0.0" -oauth-sign@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.6.0.tgz#7dbeae44f6ca454e1f168451d630746735813ce3" - oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -2525,10 +2448,10 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" os-locale@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.0.0.tgz#15918ded510522b81ee7ae5a309d54f639fc39a4" + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" dependencies: - execa "^0.5.0" + execa "^0.7.0" lcid "^1.0.0" mem "^1.1.0" @@ -2680,10 +2603,6 @@ punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -qs@~2.3.1: - version "2.3.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" - qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" @@ -2750,15 +2669,6 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@~1.0.26: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -2827,40 +2737,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request-rate-limiter@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/request-rate-limiter/-/request-rate-limiter-1.0.2.tgz#fd4653612ff7b843b8e613e7bf6c52fe742381f0" - dependencies: - async-method "0.x.x" - ee-argv "0.1.x" - ee-class "1.x" - ee-log "1.x" - ee-types "2.x" - leaky-bucket "2.x" - request "2.53.x" - -request@2.53.x: - version "2.53.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.53.0.tgz#180a3ae92b7b639802e4f9545dd8fcdeb71d760c" - dependencies: - aws-sign2 "~0.5.0" - bl "~0.9.0" - caseless "~0.9.0" - combined-stream "~0.0.5" - forever-agent "~0.5.0" - form-data "~0.2.0" - hawk "~2.3.0" - http-signature "~0.10.0" - isstream "~0.1.1" - json-stringify-safe "~5.0.0" - mime-types "~2.0.1" - node-uuid "~1.4.0" - oauth-sign "~0.6.0" - qs "~2.3.1" - stringstream "~0.0.4" - tough-cookie ">=0.12.0" - tunnel-agent "~0.4.0" - request@2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" @@ -3041,9 +2917,9 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -spawn-wrap@^1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.7.tgz#beb8bf4426d64b2b06871e0d7dee2643f1f8d1bc" +spawn-wrap@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" dependencies: foreground-child "^1.5.6" mkdirp "^0.5.0" @@ -3096,17 +2972,13 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" +string-width@^2.0.0, string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" @@ -3168,8 +3040,8 @@ supports-color@^3.1.2: has-flag "^1.0.0" supports-color@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.1.0.tgz#92cc14bb3dad8928ca5656c33e19a19f20af5c7a" + version "4.2.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.1.tgz#65a4bb2631e90e02420dba5554c375a4754bb836" dependencies: has-flag "^2.0.0" @@ -3237,7 +3109,7 @@ to-fast-properties@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" -tough-cookie@>=0.12.0, tough-cookie@~2.3.0: +tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" dependencies: @@ -3257,7 +3129,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel-agent@~0.4.0, tunnel-agent@~0.4.1: +tunnel-agent@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" @@ -3309,8 +3181,8 @@ underscore@~1.6.0: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" universalify@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.0.tgz#9eb1c4651debcc670cc94f1a75762332bb967778" + version "0.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" user-home@^1.1.1: version "1.1.1"