From fc81427d4ed8df51752608030aa289b8631531b3 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Thu, 15 Feb 2018 16:31:25 -0800 Subject: [PATCH 01/34] Publish firebase@4.10.0 --- integration/browserify/package.json | 2 +- integration/firebase-typings/package.json | 2 +- integration/messaging/package.json | 2 +- integration/typescript/package.json | 2 +- integration/webpack/package.json | 2 +- packages/app/package.json | 4 ++-- packages/database/package.json | 4 ++-- packages/firebase/package.json | 14 +++++++------- packages/firestore/package.json | 2 +- packages/messaging/package.json | 4 ++-- packages/polyfill/package.json | 2 +- packages/storage/package.json | 2 +- packages/util/package.json | 2 +- 13 files changed, 22 insertions(+), 22 deletions(-) diff --git a/integration/browserify/package.json b/integration/browserify/package.json index 7588b72c9e4..ffe283105af 100644 --- a/integration/browserify/package.json +++ b/integration/browserify/package.json @@ -7,7 +7,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.10.0" }, "devDependencies": { "browserify": "^14.5.0", diff --git a/integration/firebase-typings/package.json b/integration/firebase-typings/package.json index a8e1b0a972a..46752ce6218 100644 --- a/integration/firebase-typings/package.json +++ b/integration/firebase-typings/package.json @@ -6,7 +6,7 @@ "test": "tsc index.ts --outDir dist" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.10.0" }, "devDependencies": { "typescript": "^2.4.2" diff --git a/integration/messaging/package.json b/integration/messaging/package.json index 6a16a07f05a..33610590e5e 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -8,7 +8,7 @@ "test:manual": "mocha --exit" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.10.0" }, "devDependencies": { "chai": "^4.1.1", diff --git a/integration/typescript/package.json b/integration/typescript/package.json index 94c169910bb..d030dfe4f13 100644 --- a/integration/typescript/package.json +++ b/integration/typescript/package.json @@ -6,7 +6,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.10.0" }, "devDependencies": { "@types/chai": "^4.0.4", diff --git a/integration/webpack/package.json b/integration/webpack/package.json index d159273a94a..5a235a1f812 100644 --- a/integration/webpack/package.json +++ b/integration/webpack/package.json @@ -7,7 +7,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.10.0" }, "devDependencies": { "chai": "^4.1.1", diff --git a/packages/app/package.json b/packages/app/package.json index 309750b3173..66d75be6c4e 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app", - "version": "0.1.8", + "version": "0.1.9", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -16,7 +16,7 @@ "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.1.1", - "@firebase/util": "0.1.8" + "@firebase/util": "0.1.9" }, "devDependencies": { "@types/chai": "^4.0.4", diff --git a/packages/database/package.json b/packages/database/package.json index e04cbdd986a..1d662bcb1a3 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/database", - "version": "0.1.9", + "version": "0.1.10", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", @@ -20,7 +20,7 @@ }, "dependencies": { "@firebase/database-types": "0.1.1", - "@firebase/util": "0.1.8", + "@firebase/util": "0.1.9", "faye-websocket": "0.11.1" }, "devDependencies": { diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 2a0e53ce917..8fa17ae9dd9 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "firebase", - "version": "4.9.1", + "version": "4.10.0", "description": "Firebase JavaScript library for web and Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -27,13 +27,13 @@ "browser": "index.js", "react-native": "index.react-native.js", "dependencies": { - "@firebase/app": "0.1.8", + "@firebase/app": "0.1.9", "@firebase/auth": "0.3.3", - "@firebase/database": "0.1.9", - "@firebase/firestore": "0.3.2", - "@firebase/messaging": "0.1.9", - "@firebase/polyfill": "0.1.4", - "@firebase/storage": "0.1.6", + "@firebase/database": "0.1.10", + "@firebase/firestore": "0.3.3", + "@firebase/messaging": "0.2.0", + "@firebase/polyfill": "0.1.5", + "@firebase/storage": "0.1.7", "dom-storage": "^2.0.2", "xmlhttprequest": "^1.8.0" }, diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 445e4da54bc..4ec7e39aca9 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore", - "version": "0.3.2", + "version": "0.3.3", "description": "", "author": "Firebase (https://firebase.google.com/)", "scripts": { diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 4069141c19c..c61eb369576 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/messaging", - "version": "0.1.9", + "version": "0.2.0", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -17,7 +17,7 @@ }, "dependencies": { "@firebase/messaging-types": "0.1.1", - "@firebase/util": "0.1.8", + "@firebase/util": "0.1.9", "lcov-result-merger": "^1.2.0" }, "devDependencies": { diff --git a/packages/polyfill/package.json b/packages/polyfill/package.json index eb4eb49b5fe..4e5634d4c55 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/polyfill", - "version": "0.1.4", + "version": "0.1.5", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", diff --git a/packages/storage/package.json b/packages/storage/package.json index eb511e233b5..7e61b79409c 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/storage", - "version": "0.1.6", + "version": "0.1.7", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", diff --git a/packages/util/package.json b/packages/util/package.json index e31700aae0e..1c76d0c44b9 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/util", - "version": "0.1.8", + "version": "0.1.9", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", From 2e147ff61da8fc7a62c9b72d8e9a7e0c28d862c5 Mon Sep 17 00:00:00 2001 From: Tony Meng Date: Fri, 16 Feb 2018 13:53:30 -0800 Subject: [PATCH 02/34] Fix query string parsing (#518) * Fix query string parsing * [AUTOMATED]: Prettier Code Styling * Feedback --- packages/database/src/core/util/libs/parser.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/database/src/core/util/libs/parser.ts b/packages/database/src/core/util/libs/parser.ts index 0031774bf71..7869926cccc 100644 --- a/packages/database/src/core/util/libs/parser.ts +++ b/packages/database/src/core/util/libs/parser.ts @@ -47,11 +47,14 @@ function decodeQuery(queryString: string): { [key: string]: string } { queryString = queryString.substring(1); } for (const segment of queryString.split('&')) { + if (segment.length === 0) { + continue; + } const kv = segment.split('='); if (kv.length === 2) { results[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]); } else { - warn('Invalid query string segment: ' + segment); + warn(`Invalid query segment '${segment}' in query '${queryString}'`); } } return results; From b6b4e2fb968549dd1a680797c497af8a2466a493 Mon Sep 17 00:00:00 2001 From: Tony Meng Date: Fri, 16 Feb 2018 13:58:24 -0800 Subject: [PATCH 03/34] Add testing module (#514) * Adding testing module * Typescript it * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: License Headers * Do not register testing module with firebase * [AUTOMATED]: Prettier Code Styling * Feedback * Add owners --- .github/CODEOWNERS | 3 + packages/testing/README.md | 3 + packages/testing/gulpfile.js | 31 ++ packages/testing/index.ts | 30 ++ packages/testing/package.json | 38 ++ packages/testing/src/api/index.ts | 101 +++++ packages/testing/test/database.test.ts | 126 ++++++ packages/testing/tsconfig.json | 9 + yarn.lock | 510 ++++++++++++++++++++++++- 9 files changed, 837 insertions(+), 14 deletions(-) create mode 100644 packages/testing/README.md create mode 100644 packages/testing/gulpfile.js create mode 100644 packages/testing/index.ts create mode 100644 packages/testing/package.json create mode 100644 packages/testing/src/api/index.ts create mode 100644 packages/testing/test/database.test.ts create mode 100644 packages/testing/tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1c887fa09aa..ffc50584618 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -26,3 +26,6 @@ integration/messaging @gauntface @pinarx # Auth Code packages/auth @bojeil-google @wti806 @tmsch packages/auth-types @bojeil-google @wti806 @tmsch + +# Testing Code +packages/testing @tonymeng @ryanpbrewster diff --git a/packages/testing/README.md b/packages/testing/README.md new file mode 100644 index 00000000000..e5853764d91 --- /dev/null +++ b/packages/testing/README.md @@ -0,0 +1,3 @@ +# @firebase/testing + +This is the testing component for the Firebase JS SDK. diff --git a/packages/testing/gulpfile.js b/packages/testing/gulpfile.js new file mode 100644 index 00000000000..dc8ec17b593 --- /dev/null +++ b/packages/testing/gulpfile.js @@ -0,0 +1,31 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const gulp = require('gulp'); +const tools = require('../../tools/build'); + +const buildModule = gulp.parallel([ + tools.buildCjs(__dirname), + tools.buildEsm(__dirname) +]); + +const setupWatcher = () => { + gulp.watch(['index.ts', 'src/**/*'], buildModule); +}; + +gulp.task('build', buildModule); + +gulp.task('dev', gulp.parallel([setupWatcher])); diff --git a/packages/testing/index.ts b/packages/testing/index.ts new file mode 100644 index 00000000000..771308161a0 --- /dev/null +++ b/packages/testing/index.ts @@ -0,0 +1,30 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * The testing module does not need to be registered since it should not ever + * come by default. The only way to use the testing module is by explicitly + * creating a dependency on @firebase/testing. + */ + +export { + apps, + assertFails, + assertSucceeds, + initializeAdminApp, + initializeTestApp, + loadDatabaseRules +} from './src/api'; diff --git a/packages/testing/package.json b/packages/testing/package.json new file mode 100644 index 00000000000..daaf16e214c --- /dev/null +++ b/packages/testing/package.json @@ -0,0 +1,38 @@ +{ + "name": "@firebase/testing", + "version": "0.1.0", + "private": true, + "description": "", + "author": "Firebase (https://firebase.google.com/)", + "main": "dist/cjs/index.js", + "browser": "dist/cjs/index.js", + "module": "dist/esm/index.js", + "scripts": { + "dev": "gulp dev", + "test": "TS_NODE_CACHE=NO nyc --reporter lcovonly -- mocha 'test/{,!(browser)/**/}*.test.ts' --compilers ts:ts-node/register/type-check --retries 5 --timeout 5000 --exit", + "prepare": "gulp build" + }, + "license": "Apache-2.0", + "dependencies": { + "firebase-admin": "5.8.0", + "request-promise": "^4.2.2" + }, + "devDependencies": { + "chai": "^4.1.1", + "gulp": "gulpjs/gulp#4.0", + "mocha": "^4.0.1", + "nyc": "^11.2.1" + }, + "peerDependencies": { + "@firebase/app": "^0.1.0", + "@firebase/app-types": "^0.1.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/firebase/firebase-js-sdk/tree/master/packages/testing" + }, + "typings": "dist/esm/index.d.ts", + "bugs": { + "url": "https://github.com/firebase/firebase-js-sdk/issues" + } +} diff --git a/packages/testing/src/api/index.ts b/packages/testing/src/api/index.ts new file mode 100644 index 00000000000..f7a68844289 --- /dev/null +++ b/packages/testing/src/api/index.ts @@ -0,0 +1,101 @@ +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as admin from 'firebase-admin'; +import * as request from 'request-promise'; +import * as fs from 'fs'; + +const DBURL = 'http://localhost:9000'; + +class FakeCredentials { + getAccessToken() { + return Promise.resolve({ + expires_in: 1000000, + access_token: 'owner' + }); + } + getCertificate() { + return null; + } +} + +export function apps(): (admin.app.App | null)[] { + return admin.apps; +} + +export function initializeAdminApp(options: any): admin.app.App { + if (!('databaseName' in options)) { + throw new Error('databaseName not specified'); + } + return admin.initializeApp( + { + credential: new FakeCredentials(), + databaseURL: DBURL + '?ns=' + options.databaseName + }, + 'app-' + (new Date().getTime() + Math.random()) + ); +} + +export function initializeTestApp(options: any): admin.app.App { + if (!('databaseName' in options)) { + throw new Error('databaseName not specified'); + } + // if options.auth is not present, we will construct an app with auth == null + return admin.initializeApp( + { + credential: new FakeCredentials(), + databaseURL: DBURL + '?ns=' + options.databaseName, + databaseAuthVariableOverride: options.auth || null + }, + 'app-' + (new Date().getTime() + Math.random()) + ); +} + +export function loadDatabaseRules(options: any): void { + if (!('databaseName' in options)) { + throw new Error('databaseName not specified'); + } + if (!('rulesPath' in options)) { + throw new Error('rulesPath not specified'); + } + if (!fs.existsSync(options.rulesPath)) { + throw new Error('Could not find file: ' + options.rulesPath); + } + fs + .createReadStream(options.rulesPath) + .pipe( + request({ + uri: DBURL + '/.settings/rules.json?ns=' + options.databaseName, + method: 'PUT', + headers: { Authorization: 'Bearer owner' } + }) + ) + .catch(function(err) { + throw new Error('could not load rules: ' + err); + }); +} + +export function assertFails(pr: Promise): any { + return pr.then( + v => + Promise.reject(new Error('Expected request to fail, but it succeeded.')), + err => err + ); +} + +export function assertSucceeds(pr: Promise): any { + return pr; +} diff --git a/packages/testing/test/database.test.ts b/packages/testing/test/database.test.ts new file mode 100644 index 00000000000..69126fb745a --- /dev/null +++ b/packages/testing/test/database.test.ts @@ -0,0 +1,126 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import * as firebase from '../src/api'; + +describe('Testing Module Tests', function() { + it('assertSucceeds() iff success', async function() { + const success = Promise.resolve('success'); + const failure = Promise.reject('failure'); + await firebase.assertSucceeds(success).catch(() => { + throw new Error('Expected success to succeed.'); + }); + await firebase + .assertSucceeds(failure) + .then(() => { + throw new Error('Expected failure to fail.'); + }) + .catch(() => {}); + }); + + it('assertFails() iff failure', async function() { + const success = Promise.resolve('success'); + const failure = Promise.reject('failure'); + await firebase + .assertFails(success) + .then(() => { + throw new Error('Expected success to fail.'); + }) + .catch(() => {}); + await firebase.assertFails(failure).catch(() => { + throw new Error('Expected failure to succeed.'); + }); + }); + + it('initializeAdminApp() throws if no databaseName', function() { + expect(firebase.initializeAdminApp.bind(null, {})).to.throw( + /databaseName not specified/ + ); + expect( + firebase.initializeAdminApp.bind(null, { databaseName: 'foo' }) + ).to.not.throw(); + }); + + it('initializeAdminApp() provides admin', function() { + const app = firebase.initializeAdminApp({ databaseName: 'foo' }); + expect(app.options).to.not.have.any.keys('databaseAuthVariableOverride'); + }); + + it('initializeTestApp() throws if no databaseName', function() { + expect(firebase.initializeTestApp.bind(null, {})).to.throw( + /databaseName not specified/ + ); + expect( + firebase.initializeTestApp.bind(null, { databaseName: 'foo' }) + ).to.not.throw(); + }); + + it('initializeTestApp() uses specified auth.', function() { + let app = firebase.initializeTestApp({ databaseName: 'foo' }); + expect(app.options).to.have.any.keys('databaseAuthVariableOverride'); + + app = firebase.initializeTestApp({ + databaseName: 'foo', + auth: { uid: 'alice' } + }); + expect(app.options).to.have.any.keys('databaseAuthVariableOverride'); + expect(app.options.databaseAuthVariableOverride).to.have.all.keys('uid'); + expect(app.options.databaseAuthVariableOverride['uid']).to.be.equal( + 'alice' + ); + }); + + it('loadDatabaseRules() throws if no databaseName or rulesPath', async function() { + expect(firebase.loadDatabaseRules.bind(null, {})).to.throw( + /databaseName not specified/ + ); + expect( + firebase.loadDatabaseRules.bind(null, { databaseName: 'foo' }) + ).to.throw(/rulesPath not specified/); + expect( + firebase.loadDatabaseRules.bind(null, { + rulesPath: '/path/does/not/exist/file.json' + }) + ).to.throw(/databaseName not specified/); + expect( + firebase.loadDatabaseRules.bind(null, { + databaseName: 'foo', + rulesPath: '/path/does/not/exist/file.json' + }) + ).to.throw(/Could not find file/); + }); + + it('loadDatabaseRules() throws on file not found', function() { + const options = { + databaseName: 'foo', + rulesPath: '/path/does/not/exist/file.json' + }; + expect(firebase.loadDatabaseRules.bind(null, options)).to.throw( + /Could not find file/ + ); + }); + + it('apps() returns all created apps', async function() { + const numApps = firebase.apps().length; + await firebase.initializeAdminApp({ databaseName: 'foo' }); + expect(firebase.apps().length).to.equal(numApps + 1); + await firebase.initializeAdminApp({ databaseName: 'foo' }); + expect(firebase.apps().length).to.equal(numApps + 2); + await firebase.initializeTestApp({ databaseName: 'foo' }); + expect(firebase.apps().length).to.equal(numApps + 3); + }); +}); diff --git a/packages/testing/tsconfig.json b/packages/testing/tsconfig.json new file mode 100644 index 00000000000..09f747b4d46 --- /dev/null +++ b/packages/testing/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../config/tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "exclude": [ + "dist/**/*" + ] +} diff --git a/yarn.lock b/yarn.lock index e943b6b50b9..e9c9495a984 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,6 +8,20 @@ dependencies: acorn "^5.2.1" +"@google-cloud/common-grpc@^0.5.0": + version "0.5.5" + resolved "https://registry.npmjs.org/@google-cloud/common-grpc/-/common-grpc-0.5.5.tgz#ca805d7bbbcf47bbd82cf603e0386e963d6f5804" + dependencies: + "@google-cloud/common" "^0.16.1" + dot-prop "^4.2.0" + duplexify "^3.5.1" + extend "^3.0.1" + grpc "~1.7.2" + is "^3.2.0" + modelo "^4.2.0" + retry-request "^3.3.1" + through2 "^2.0.3" + "@google-cloud/common@^0.13.0": version "0.13.6" resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.13.6.tgz#a9d8e137bc429a44aba9689fe6a0e4331784f853" @@ -31,6 +45,67 @@ string-format-obj "^1.1.0" through2 "^2.0.3" +"@google-cloud/common@^0.15.0": + version "0.15.2" + resolved "https://registry.npmjs.org/@google-cloud/common/-/common-0.15.2.tgz#d8b5ba80f16b60a0ca53fc80ead4ae8b2c2e5b4a" + dependencies: + array-uniq "^1.0.3" + arrify "^1.0.1" + concat-stream "^1.6.0" + create-error-class "^3.0.2" + duplexify "^3.5.0" + ent "^2.2.0" + extend "^3.0.1" + google-auto-auth "^0.8.0" + is "^3.2.0" + log-driver "1.2.5" + methmeth "^1.1.0" + modelo "^4.2.0" + request "^2.79.0" + retry-request "^3.0.0" + split-array-stream "^1.0.0" + stream-events "^1.0.1" + string-format-obj "^1.1.0" + through2 "^2.0.3" + +"@google-cloud/common@^0.16.1": + version "0.16.1" + resolved "https://registry.npmjs.org/@google-cloud/common/-/common-0.16.1.tgz#e1f9fc49553362997e1fbff737444f1b460ded78" + dependencies: + array-uniq "^1.0.3" + arrify "^1.0.1" + concat-stream "^1.6.0" + create-error-class "^3.0.2" + duplexify "^3.5.0" + ent "^2.2.0" + extend "^3.0.1" + google-auto-auth "^0.9.0" + is "^3.2.0" + log-driver "1.2.5" + methmeth "^1.1.0" + modelo "^4.2.0" + request "^2.79.0" + retry-request "^3.0.0" + split-array-stream "^1.0.0" + stream-events "^1.0.1" + string-format-obj "^1.1.0" + through2 "^2.0.3" + +"@google-cloud/firestore@^0.10.0": + version "0.10.2" + resolved "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-0.10.2.tgz#1b045064d5b061e83bdb1e4cfe8b2a96d0f9d64a" + dependencies: + "@google-cloud/common" "^0.15.0" + "@google-cloud/common-grpc" "^0.5.0" + bun "^0.0.12" + extend "^3.0.1" + functional-red-black-tree "^1.0.1" + google-gax "^0.14.1" + grpc "1.7.1" + is "^3.2.0" + safe-buffer "^5.1.1" + through2 "^2.0.3" + "@google-cloud/functions-emulator@^1.0.0-alpha.23": version "1.0.0-alpha.27" resolved "https://registry.yarnpkg.com/@google-cloud/functions-emulator/-/functions-emulator-1.0.0-alpha.27.tgz#d2210a02bb4a09037de63a512e7d5a98c28123e7" @@ -81,6 +156,32 @@ string-format-obj "^1.0.0" through2 "^2.0.0" +"@google-cloud/storage@^1.2.1": + version "1.6.0" + resolved "https://registry.npmjs.org/@google-cloud/storage/-/storage-1.6.0.tgz#3dea740e24bf097d91f16596e2915052907679a2" + dependencies: + "@google-cloud/common" "^0.16.1" + arrify "^1.0.0" + async "^2.0.1" + compressible "^2.0.12" + concat-stream "^1.5.0" + create-error-class "^3.0.2" + duplexify "^3.5.0" + extend "^3.0.0" + gcs-resumable-upload "^0.9.0" + hash-stream-validation "^0.2.1" + is "^3.0.1" + mime "^2.2.0" + mime-types "^2.0.8" + once "^1.3.1" + pumpify "^1.3.3" + request "^2.83.0" + safe-buffer "^5.1.1" + snakeize "^0.1.0" + stream-events "^1.0.1" + string-format-obj "^1.0.0" + through2 "^2.0.0" + "@gulp-sourcemaps/identity-map@1.X": version "1.0.1" resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz#cfa23bc5840f9104ce32a65e74db7e7a974bbee1" @@ -145,6 +246,12 @@ version "4.0.5" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.5.tgz#b6e250e281b47e0192e236619e9b1afe62fd345c" +"@types/google-cloud__storage@^1.1.1": + version "1.1.7" + resolved "https://registry.npmjs.org/@types/google-cloud__storage/-/google-cloud__storage-1.1.7.tgz#f4b568b163cce16314f32f954f5b7d5c9001fa86" + dependencies: + "@types/node" "*" + "@types/long@^3.0.31": version "3.0.32" resolved "https://registry.yarnpkg.com/@types/long/-/long-3.0.32.tgz#f4e5af31e9e9b196d8e5fca8a5e2e20aa3d60b69" @@ -153,6 +260,10 @@ version "2.2.44" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e" +"@types/node@*": + version "9.4.6" + resolved "https://registry.npmjs.org/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e" + "@types/node@^6.0.46": version "6.0.92" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.92.tgz#e7f721ae282772e12ba2579968c00d9cce422c5d" @@ -165,6 +276,10 @@ version "8.0.53" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" +"@types/node@^8.0.53": + version "8.9.4" + resolved "https://registry.npmjs.org/@types/node/-/node-8.9.4.tgz#dfd327582a06c114eb6e0441fa3d6fab35edad48" + "@types/q@^0.0.32": version "0.0.32" resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" @@ -220,13 +335,17 @@ acorn-dynamic-import@^2.0.0: dependencies: acorn "^4.0.3" +acorn-es7-plugin@^1.0.12: + version "1.1.7" + resolved "https://registry.npmjs.org/acorn-es7-plugin/-/acorn-es7-plugin-1.1.7.tgz#f2ee1f3228a90eead1245f9ab1922eb2e71d336b" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" dependencies: acorn "^3.0.4" -acorn@4.X, acorn@^4.0.3, acorn@^4.0.4: +acorn@4.X, acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -460,6 +579,10 @@ array-each@^1.0.0, array-each@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" +array-filter@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -857,7 +980,7 @@ bluebird@3.4.6: version "3.4.6" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" -bluebird@^3.3.0: +bluebird@^3.3.0, bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1176,6 +1299,12 @@ 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" +bun@^0.0.12: + version "0.0.12" + resolved "https://registry.npmjs.org/bun/-/bun-0.0.12.tgz#d54fae69f895557f275423bc14b404030b20a5fc" + dependencies: + readable-stream "~1.0.32" + byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" @@ -1202,6 +1331,10 @@ caching-transform@^1.0.0: mkdirp "^0.5.1" write-file-atomic "^1.1.4" +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -1627,7 +1760,7 @@ compress-commons@^1.2.0: normalize-path "^2.0.0" readable-stream "^2.0.0" -compressible@~2.0.11: +compressible@^2.0.12, compressible@~2.0.11: version "2.0.12" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66" dependencies: @@ -1925,6 +2058,10 @@ copy-props@^1.4.1: each-props "^1.2.1" is-plain-object "^2.0.1" +core-js@^2.0.0: + version "2.5.3" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + core-js@^2.2.0, core-js@^2.4.0: version "2.5.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" @@ -2373,6 +2510,10 @@ didyoumean@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" +diff-match-patch@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048" + diff@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" @@ -2389,6 +2530,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + dmg@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/dmg/-/dmg-0.1.0.tgz#b38ea2107f6f0b070442bbf799bfc4f2aedaa5f8" @@ -2450,7 +2598,7 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" -dot-prop@^4.1.0: +dot-prop@^4.1.0, dot-prop@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" dependencies: @@ -2485,6 +2633,15 @@ duplexify@^3.1.2, duplexify@^3.2.0, duplexify@^3.5.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +duplexify@^3.5.1: + version "3.5.3" + resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + each-props@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.1.tgz#fc138f51e3a2774286d4858e02d6e7de462de158" @@ -2492,6 +2649,10 @@ each-props@^1.2.1: is-plain-object "^2.0.1" object.defaults "^1.1.0" +eastasianwidth@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.1.1.tgz#44d656de9da415694467335365fb3147b8572b7c" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -2529,6 +2690,20 @@ emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" +empower-core@^0.6.2: + version "0.6.2" + resolved "https://registry.npmjs.org/empower-core/-/empower-core-0.6.2.tgz#5adef566088e31fba80ba0a36df47d7094169144" + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +empower@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/empower/-/empower-1.2.3.tgz#6f0da73447f4edd838fec5c60313a88ba5cb852b" + dependencies: + core-js "^2.0.0" + empower-core "^0.6.2" + encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" @@ -2789,6 +2964,12 @@ esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" +espurify@^1.6.0: + version "1.7.0" + resolved "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" + dependencies: + core-js "^2.0.0" + esquery@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" @@ -2806,7 +2987,7 @@ estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: +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" @@ -2984,7 +3165,7 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" -extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: +extend@3, extend@^3.0.0, extend@^3.0.1, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -3058,6 +3239,12 @@ faye-websocket@0.11.1, faye-websocket@>=0.6.0, faye-websocket@~0.11.0: dependencies: websocket-driver ">=0.5.1" +faye-websocket@0.9.3: + version "0.9.3" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.9.3.tgz#482a505b0df0ae626b969866d3bd740cdb962e83" + dependencies: + websocket-driver ">=0.5.1" + faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -3205,6 +3392,20 @@ fined@^1.0.1: object.pick "^1.2.0" parse-filepath "^1.0.1" +firebase-admin@5.8.0: + version "5.8.0" + resolved "https://registry.npmjs.org/firebase-admin/-/firebase-admin-5.8.0.tgz#2363599ad44a495f3673ef5876e18cbed6b33385" + dependencies: + "@firebase/app" "^0.1.1" + "@firebase/database" "^0.1.3" + "@google-cloud/firestore" "^0.10.0" + "@google-cloud/storage" "^1.2.1" + "@types/google-cloud__storage" "^1.1.1" + "@types/node" "^8.0.53" + faye-websocket "0.9.3" + jsonwebtoken "8.1.0" + node-forge "0.7.1" + firebase-tools@^3.10.1: version "3.15.1" resolved "https://registry.yarnpkg.com/firebase-tools/-/firebase-tools-3.15.1.tgz#cbb0b569365e6fa545ffd8e4c9d45988a3008ae5" @@ -3460,6 +3661,13 @@ gcp-metadata@^0.3.0: extend "^3.0.0" retry-request "^3.0.0" +gcp-metadata@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.4.1.tgz#64623b84175357cc119ad7a6aec759392a90a58b" + dependencies: + extend "^3.0.0" + retry-request "^3.1.0" + gcs-resumable-upload@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/gcs-resumable-upload/-/gcs-resumable-upload-0.8.2.tgz#37df02470430395a789a637e72cabc80677ae964" @@ -3472,6 +3680,18 @@ gcs-resumable-upload@^0.8.2: stream-events "^1.0.1" through2 "^2.0.0" +gcs-resumable-upload@^0.9.0: + version "0.9.0" + resolved "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-0.9.0.tgz#644202149696ad114358bc1e0cf43a60b5ec0454" + dependencies: + buffer-equal "^1.0.0" + configstore "^3.0.0" + google-auto-auth "^0.9.0" + pumpify "^1.3.3" + request "^2.81.0" + stream-events "^1.0.1" + through2 "^2.0.0" + geckodriver@^1.8.0: version "1.10.0" resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.10.0.tgz#73e2f785666521d0d3a9ddc9fd5a0a5e3bf47845" @@ -3732,6 +3952,17 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + globule@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" @@ -3755,6 +3986,16 @@ google-auth-library@^0.10.0, google-auth-library@~0.10.0: lodash.noop "^3.0.1" request "^2.74.0" +google-auth-library@^0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-0.12.0.tgz#a3fc6c296d00bb54e4d877ef581a05947330d07f" + dependencies: + gtoken "^1.2.3" + jws "^3.1.4" + lodash.isstring "^4.0.1" + lodash.merge "^4.6.0" + request "^2.81.0" + google-auto-auth@^0.7.1, google-auto-auth@^0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/google-auto-auth/-/google-auto-auth-0.7.2.tgz#bf9352d5c4a0897bf31fd9c491028b765fbea71e" @@ -3764,6 +4005,24 @@ google-auto-auth@^0.7.1, google-auto-auth@^0.7.2: google-auth-library "^0.10.0" request "^2.79.0" +google-auto-auth@^0.8.0: + version "0.8.2" + resolved "https://registry.npmjs.org/google-auto-auth/-/google-auto-auth-0.8.2.tgz#928ee8954514a2ea179de8dd4e97f04d40d13d0a" + dependencies: + async "^2.3.0" + gcp-metadata "^0.3.0" + google-auth-library "^0.12.0" + request "^2.79.0" + +google-auto-auth@^0.9.0: + version "0.9.3" + resolved "https://registry.npmjs.org/google-auto-auth/-/google-auto-auth-0.9.3.tgz#544c36da639890cf56040b0246859060f140715a" + dependencies: + async "^2.3.0" + gcp-metadata "^0.4.1" + google-auth-library "^0.12.0" + request "^2.79.0" + google-closure-compiler-js@^20180204.0.0: version "20180204.0.0" resolved "https://registry.npmjs.org/google-closure-compiler-js/-/google-closure-compiler-js-20180204.0.0.tgz#05920e0c2e743702a0c293898caf3b49af7a88bb" @@ -3793,6 +4052,21 @@ google-closure-library@^20170910.0.0: version "20170910.0.0" resolved "https://registry.yarnpkg.com/google-closure-library/-/google-closure-library-20170910.0.0.tgz#d6122ec24472672ee1347b19e8c4a43d18f57bef" +google-gax@^0.14.1: + version "0.14.5" + resolved "https://registry.npmjs.org/google-gax/-/google-gax-0.14.5.tgz#b2c73c61df6cead94f90421d17f44ff161f623c7" + dependencies: + extend "^3.0.0" + globby "^7.1.1" + google-auto-auth "^0.9.0" + google-proto-files "^0.14.1" + grpc "~1.7.2" + is-stream-ended "^0.1.0" + lodash "^4.17.2" + protobufjs "^6.8.0" + readable-stream "^2.2.2" + through2 "^2.0.3" + google-p12-pem@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177" @@ -3806,6 +4080,15 @@ google-proto-files@0.14.1: globby "^6.1.0" protobufjs "^6.8.0" +google-proto-files@^0.14.1: + version "0.14.2" + resolved "https://registry.npmjs.org/google-proto-files/-/google-proto-files-0.14.2.tgz#958cffea7e8888e00b9a6c55ed1362c06b426f4c" + dependencies: + globby "^7.1.1" + power-assert "^1.4.4" + prettier "^1.10.2" + protobufjs "^6.8.0" + googleapis@22.2.0: version "22.2.0" resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-22.2.0.tgz#fd79c3c26e7e71a4f5a2ec1a7da5fb115d8853d2" @@ -3937,7 +4220,17 @@ grpc@1.7.1, grpc@^1.7.1: node-pre-gyp "^0.6.39" protobufjs "^5.0.0" -gtoken@^1.2.1: +grpc@~1.7.2: + version "1.7.3" + resolved "https://registry.npmjs.org/grpc/-/grpc-1.7.3.tgz#c9d034324e2ec8a06cfaa577a044a116f96c8c90" + dependencies: + arguejs "^0.2.3" + lodash "^4.15.0" + nan "^2.0.0" + node-pre-gyp "^0.6.39" + protobufjs "^5.0.0" + +gtoken@^1.2.1, gtoken@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8" dependencies: @@ -4392,7 +4685,7 @@ ieee754@^1.1.4, ieee754@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ignore@^3.3.3: +ignore@^3.3.3, ignore@^3.3.5: version "3.3.7" resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" @@ -5091,6 +5384,21 @@ jsonschema@^1.0.2: version "1.2.0" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.0.tgz#d6ebaf70798db7b3a20c544f6c9ef9319b077de2" +jsonwebtoken@8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz#c6397cd2e5fd583d65c007a83dc7bb78e6982b83" + dependencies: + jws "^3.1.4" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.0.0" + xtend "^4.0.1" + jsonwebtoken@^7.4.1: version "7.4.3" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz#77f5021de058b605a1783fa1283e99812e645638" @@ -5634,6 +5942,10 @@ lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + lodash.isarguments@2.4.x: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-2.4.1.tgz#4931a9c08253adf091ae7ca192258a973876ecca" @@ -5646,6 +5958,10 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + lodash.isequal@^4.0.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -5654,6 +5970,14 @@ lodash.isfunction@^3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.8.tgz#4db709fc81bc4a8fd7127a458a5346c5cdce2c6b" +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + lodash.isobject@^2.4.1, lodash.isobject@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" @@ -5664,7 +5988,7 @@ lodash.isobject@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" -lodash.isplainobject@^4.0.4: +lodash.isplainobject@^4.0.4, lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -5696,6 +6020,10 @@ lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" +lodash.merge@^4.6.0: + version "4.6.1" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" + lodash.noop@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" @@ -5772,11 +6100,15 @@ lodash@^3.10.0, lodash@^3.10.1, lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" +lodash@^4.13.1: + version "4.17.5" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + lodash@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" -log-driver@^1.2.5: +log-driver@1.2.5, log-driver@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" @@ -6058,6 +6390,10 @@ mime@1.4.1, mime@^1.3.4, mime@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +mime@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" + mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" @@ -6343,7 +6679,7 @@ node-forge@0.6.33: version "0.6.33" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.33.tgz#463811879f573d45155ad6a9f43dc296e8e85ebc" -node-forge@^0.7.1: +node-forge@0.7.1, node-forge@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.1.tgz#9da611ea08982f4b94206b3beb4cc9665f20c300" @@ -6542,7 +6878,7 @@ object-component@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" -object-keys@^1.0.8: +object-keys@^1.0.0, object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -7036,6 +7372,94 @@ portfinder@^1.0.9: debug "^2.2.0" mkdirp "0.5.x" +power-assert-context-formatter@^1.0.7: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz#edba352d3ed8a603114d667265acce60d689ccdf" + dependencies: + core-js "^2.0.0" + power-assert-context-traversal "^1.1.1" + +power-assert-context-reducer-ast@^1.0.7: + version "1.1.2" + resolved "https://registry.npmjs.org/power-assert-context-reducer-ast/-/power-assert-context-reducer-ast-1.1.2.tgz#484a99e26f4973ff8832e5c5cc756702e6094174" + dependencies: + acorn "^4.0.0" + acorn-es7-plugin "^1.0.12" + core-js "^2.0.0" + espurify "^1.6.0" + estraverse "^4.2.0" + +power-assert-context-traversal@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-context-traversal/-/power-assert-context-traversal-1.1.1.tgz#88cabca0d13b6359f07d3d3e8afa699264577ed9" + dependencies: + core-js "^2.0.0" + estraverse "^4.1.0" + +power-assert-formatter@^1.3.1: + version "1.4.1" + resolved "https://registry.npmjs.org/power-assert-formatter/-/power-assert-formatter-1.4.1.tgz#5dc125ed50a3dfb1dda26c19347f3bf58ec2884a" + dependencies: + core-js "^2.0.0" + power-assert-context-formatter "^1.0.7" + power-assert-context-reducer-ast "^1.0.7" + power-assert-renderer-assertion "^1.0.7" + power-assert-renderer-comparison "^1.0.7" + power-assert-renderer-diagram "^1.0.7" + power-assert-renderer-file "^1.0.7" + +power-assert-renderer-assertion@^1.0.7: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-renderer-assertion/-/power-assert-renderer-assertion-1.1.1.tgz#cbfc0e77e0086a8f96af3f1d8e67b9ee7e28ce98" + dependencies: + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.1.1" + +power-assert-renderer-base@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-renderer-base/-/power-assert-renderer-base-1.1.1.tgz#96a650c6fd05ee1bc1f66b54ad61442c8b3f63eb" + +power-assert-renderer-comparison@^1.0.7: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-renderer-comparison/-/power-assert-renderer-comparison-1.1.1.tgz#d7439d97d85156be4e30a00f2fb5a72514ce3c08" + dependencies: + core-js "^2.0.0" + diff-match-patch "^1.0.0" + power-assert-renderer-base "^1.1.1" + stringifier "^1.3.0" + type-name "^2.0.1" + +power-assert-renderer-diagram@^1.0.7: + version "1.1.2" + resolved "https://registry.npmjs.org/power-assert-renderer-diagram/-/power-assert-renderer-diagram-1.1.2.tgz#655f8f711935a9b6d541b86327654717c637a986" + dependencies: + core-js "^2.0.0" + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.1.1" + stringifier "^1.3.0" + +power-assert-renderer-file@^1.0.7: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-renderer-file/-/power-assert-renderer-file-1.1.1.tgz#a37e2bbd178ccacd04e78dbb79c92fe34933c5e7" + dependencies: + power-assert-renderer-base "^1.1.1" + +power-assert-util-string-width@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/power-assert-util-string-width/-/power-assert-util-string-width-1.1.1.tgz#be659eb7937fdd2e6c9a77268daaf64bd5b7c592" + dependencies: + eastasianwidth "^0.1.1" + +power-assert@^1.4.4: + version "1.4.4" + resolved "https://registry.npmjs.org/power-assert/-/power-assert-1.4.4.tgz#9295ea7437196f5a601fde420f042631186d7517" + dependencies: + define-properties "^1.1.2" + empower "^1.2.3" + power-assert-formatter "^1.3.1" + universal-deep-strict-equal "^1.2.1" + xtend "^4.0.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -7048,6 +7472,10 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" +prettier@^1.10.2: + version "1.10.2" + resolved "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93" + prettier@^1.7.0: version "1.8.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" @@ -7333,7 +7761,7 @@ read@1.0.x: dependencies: mute-stream "~0.0.4" -"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.2: +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.2, readable-stream@~1.0.32: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: @@ -7481,6 +7909,21 @@ replacestream@^4.0.0: object-assign "^4.0.1" readable-stream "^2.0.2" +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise@^4.2.2: + version "4.2.2" + resolved "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + request@2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" @@ -7639,6 +8082,13 @@ retry-request@^3.0.0: request "^2.81.0" through2 "^2.0.0" +retry-request@^3.1.0, retry-request@^3.3.1: + version "3.3.1" + resolved "https://registry.npmjs.org/retry-request/-/retry-request-3.3.1.tgz#fb71276235a617e97551e9be737ab5b91591fb9e" + dependencies: + request "^2.81.0" + through2 "^2.0.0" + revalidator@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" @@ -7990,6 +8440,10 @@ sinon@^4.1.3: supports-color "^5.1.0" type-detect "^4.0.5" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -8270,6 +8724,10 @@ statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + stream-browserify@^2.0.0, stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -8393,6 +8851,14 @@ string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" +stringifier@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/stringifier/-/stringifier-1.3.0.tgz#def18342f6933db0f2dbfc9aa02175b448c17959" + dependencies: + core-js "^2.0.0" + traverse "^0.6.6" + type-name "^2.0.1" + stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -8844,7 +9310,7 @@ touch@3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@~2.3.0, tough-cookie@~2.3.3: +tough-cookie@>=2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" dependencies: @@ -8856,6 +9322,10 @@ toxic@^1.0.0: dependencies: lodash "^2.4.1" +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -8992,6 +9462,10 @@ type-is@~1.6.15: media-typer "0.3.0" mime-types "~2.1.15" +type-name@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/type-name/-/type-name-2.0.2.tgz#efe7d4123d8ac52afff7f40c7e4dec5266008fb4" + typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -9099,6 +9573,14 @@ universal-analytics@^0.3.9: request "2.x" underscore "1.x" +universal-deep-strict-equal@^1.2.1: + version "1.2.2" + resolved "https://registry.npmjs.org/universal-deep-strict-equal/-/universal-deep-strict-equal-1.2.2.tgz#0da4ac2f73cff7924c81fa4de018ca562ca2b0a7" + dependencies: + array-filter "^1.0.0" + indexof "0.0.1" + object-keys "^1.0.0" + universalify@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" From e78411043f424c42505f768d3b8b5890fb5124b8 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Tue, 20 Feb 2018 16:12:51 -0800 Subject: [PATCH 04/34] Version Patch for Firebase Admin (#524) * Patch the version info and the firebase.SDK_VERSION * [AUTOMATED]: Prettier Code Styling --- packages/database/index.node.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/database/index.node.ts b/packages/database/index.node.ts index 06fed094c08..896737ef550 100644 --- a/packages/database/index.node.ts +++ b/packages/database/index.node.ts @@ -15,6 +15,7 @@ */ import firebase from '@firebase/app'; +import { CONSTANTS, isNodeSdk } from '@firebase/util'; import { FirebaseApp, FirebaseNamespace } from '@firebase/app-types'; import { _FirebaseNamespace } from '@firebase/app-types/private'; import { Database } from './src/api/Database'; @@ -24,7 +25,6 @@ import { enableLogging } from './src/core/util/util'; import { RepoManager } from './src/core/RepoManager'; import * as INTERNAL from './src/api/internal'; import * as TEST_ACCESS from './src/api/test_access'; -import { isNodeSdk } from '@firebase/util'; import './src/nodePatches'; import * as types from '@firebase/database-types'; @@ -38,7 +38,16 @@ import * as types from '@firebase/database-types'; const ServerValue = Database.ServerValue; -export function initStandalone(app, url) { +export function initStandalone(app, url, version?: string) { + /** + * This should allow the firebase-admin package to provide a custom version + * to the backend + */ + CONSTANTS.NODE_ADMIN = true; + if (version) { + firebase.SDK_VERSION = version; + } + return { instance: RepoManager.getInstance().databaseFromApp(app, url), namespace: { From dbe5fff5039ec09da651c724bb12d3a1da30bed2 Mon Sep 17 00:00:00 2001 From: Matt Gaunt Date: Tue, 20 Feb 2018 16:16:00 -0800 Subject: [PATCH 05/34] Messaging - IDB Cleanup (#523) * Goes through and deletes old IDB entries * [AUTOMATED]: Prettier Code Styling * Fixing tests with db name differences * Altering some logic / logs --- .../src/models/clean-v1-undefined.ts | 84 +++++++++++++++++++ packages/messaging/src/models/db-interface.ts | 4 +- .../src/models/token-details-model.ts | 43 +++++----- .../src/models/vapid-details-model.ts | 7 +- .../test/controller-delete-token.test.ts | 2 +- .../tokenDetailsModel-deleteToken.test.ts | 2 +- .../test/tokenDetailsModel-getToken.test.ts | 2 +- .../test/tokenDetailsModel-saveToken.test.ts | 2 +- .../test/vapid-details-model-delete.test.ts | 2 +- .../test/vapid-details-model-get.test.ts | 2 +- .../test/vapid-details-model-save.test.ts | 2 +- 11 files changed, 119 insertions(+), 33 deletions(-) create mode 100644 packages/messaging/src/models/clean-v1-undefined.ts diff --git a/packages/messaging/src/models/clean-v1-undefined.ts b/packages/messaging/src/models/clean-v1-undefined.ts new file mode 100644 index 00000000000..2adc6e80010 --- /dev/null +++ b/packages/messaging/src/models/clean-v1-undefined.ts @@ -0,0 +1,84 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * There seems to have been a bug in the messaging SDK versions <= 4.9.x + * where the IndexedDB model was using a database name of 'undefined'. + * + * In 4.10.x we changed the model implementation, but kept the database + * name as it should have been. This however introduced an issue where + * two tokens were pointing to the same underlying PushSubscription. + * + * This code will look for the undefined database and delete any of the + * underlying tokens. + */ + +import IIDModel from '../models/iid-model'; + +const OLD_DB_NAME = 'undefined'; +const OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store'; + +function handleDb(db: IDBDatabase) { + if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) { + // We found a database with the name 'undefined', but our expected object + // store isn't defined. + return; + } + + const transaction = db.transaction(OLD_OBJECT_STORE_NAME); + const objectStore = transaction.objectStore(OLD_OBJECT_STORE_NAME); + + const iidModel = new IIDModel(); + + const openCursorRequest: IDBRequest = objectStore.openCursor(); + openCursorRequest.onerror = event => { + // NOOP - Nothing we can do. + console.warn('Unable to cleanup old IDB.', event); + }; + + openCursorRequest.onsuccess = () => { + const cursor = openCursorRequest.result; + if (cursor) { + // cursor.value contains the current record being iterated through + // this is where you'd do something with the result + const tokenDetails = cursor.value; + + iidModel.deleteToken( + tokenDetails.fcmSenderId, + tokenDetails.fcmToken, + tokenDetails.fcmPushSet + ); + + cursor.continue(); + } else { + db.close(); + indexedDB.deleteDatabase(OLD_DB_NAME); + } + }; +} + +function cleanV1() { + const request: IDBOpenDBRequest = indexedDB.open(OLD_DB_NAME); + request.onerror = function(event) { + // NOOP - Nothing we can do. + }; + request.onsuccess = function(event) { + const db = request.result; + handleDb(db); + }; +} + +export { cleanV1 }; diff --git a/packages/messaging/src/models/db-interface.ts b/packages/messaging/src/models/db-interface.ts index 5dfb6f4e5a0..fa712e20711 100644 --- a/packages/messaging/src/models/db-interface.ts +++ b/packages/messaging/src/models/db-interface.ts @@ -59,7 +59,7 @@ export default class DBInterface { request.onupgradeneeded = event => { try { var db = (event.target).result; - this.onDBUpgrade(db); + this.onDBUpgrade(db, event); } catch (err) { // close the database as it can't be used. db.close(); @@ -90,7 +90,7 @@ export default class DBInterface { * @protected * @param {!IDBDatabase} db */ - onDBUpgrade(db) { + onDBUpgrade(db: IDBDatabase, event: IDBVersionChangeEvent) { throw this.errorFactory_.create(Errors.codes.SHOULD_BE_INHERITED); } } diff --git a/packages/messaging/src/models/token-details-model.ts b/packages/messaging/src/models/token-details-model.ts index b074999fe4e..a3182ce6554 100644 --- a/packages/messaging/src/models/token-details-model.ts +++ b/packages/messaging/src/models/token-details-model.ts @@ -18,9 +18,11 @@ import DBInterface from './db-interface'; import Errors from './errors'; import arrayBufferToBase64 from '../helpers/array-buffer-to-base64'; +import { cleanV1 } from './clean-v1-undefined'; const FCM_TOKEN_OBJ_STORE = 'fcm_token_object_Store'; -const DB_VERSION = 1; +const DB_NAME = 'fcm_token_details_db'; +const DB_VERSION = 2; /** @record */ function ValidateInput() {} @@ -39,29 +41,32 @@ ValidateInput.prototype.fcmPushSet; export default class TokenDetailsModel extends DBInterface { constructor() { - super(TokenDetailsModel.DB_NAME, DB_VERSION); + super(DB_NAME, DB_VERSION); } - static get DB_NAME() { - return 'fcm_token_details_db'; - } + onDBUpgrade(db: IDBDatabase, evt: IDBVersionChangeEvent) { + if (evt.oldVersion < 1) { + // New IDB instance + var objectStore = db.createObjectStore(FCM_TOKEN_OBJ_STORE, { + keyPath: 'swScope' + }); - /** - * @override - */ - onDBUpgrade(db) { - var objectStore = db.createObjectStore(FCM_TOKEN_OBJ_STORE, { - keyPath: 'swScope' - }); + // Make sure the sender ID can be searched + objectStore.createIndex('fcmSenderId', 'fcmSenderId', { + unique: false + }); - // Make sure the sender ID can be searched - objectStore.createIndex('fcmSenderId', 'fcmSenderId', { - unique: false - }); + objectStore.createIndex('fcmToken', 'fcmToken', { + unique: true + }); + } - objectStore.createIndex('fcmToken', 'fcmToken', { - unique: true - }); + if (evt.oldVersion < 2) { + // Prior to version 2, we were using either 'fcm_token_details_db' + // or 'undefined' as the database name due to bug in the SDK + // So remove the old tokens and databases. + cleanV1(); + } } /** diff --git a/packages/messaging/src/models/vapid-details-model.ts b/packages/messaging/src/models/vapid-details-model.ts index 490aebe7393..a734480485c 100644 --- a/packages/messaging/src/models/vapid-details-model.ts +++ b/packages/messaging/src/models/vapid-details-model.ts @@ -19,16 +19,13 @@ import DBInterface from './db-interface'; import Errors from './errors'; const FCM_VAPID_OBJ_STORE = 'fcm_vapid_object_Store'; +const DB_NAME = 'fcm_vapid_details_db'; const DB_VERSION = 1; const UNCOMPRESSED_PUBLIC_KEY_SIZE = 65; export default class VapidDetailsModel extends DBInterface { constructor() { - super(VapidDetailsModel.DB_NAME, DB_VERSION); - } - - static get DB_NAME() { - return 'fcm_vapid_details_db'; + super(DB_NAME, DB_VERSION); } /** diff --git a/packages/messaging/test/controller-delete-token.test.ts b/packages/messaging/test/controller-delete-token.test.ts index 7513ff54bae..f5c1480b831 100644 --- a/packages/messaging/test/controller-delete-token.test.ts +++ b/packages/messaging/test/controller-delete-token.test.ts @@ -71,7 +71,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { deletePromises.push(globalMessagingService.delete()); } return Promise.all(deletePromises) - .then(() => deleteDatabase(TokenDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_token_details_db')) .then(() => (globalMessagingService = null)); }; diff --git a/packages/messaging/test/tokenDetailsModel-deleteToken.test.ts b/packages/messaging/test/tokenDetailsModel-deleteToken.test.ts index 15e3a56aef1..0ae278cbaad 100644 --- a/packages/messaging/test/tokenDetailsModel-deleteToken.test.ts +++ b/packages/messaging/test/tokenDetailsModel-deleteToken.test.ts @@ -46,7 +46,7 @@ describe('Firebase Messaging > TokenDetailsModel.deleteToken()', function() { } return Promise.all(promises) - .then(() => deleteDatabase(TokenDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_token_details_db')) .then(() => (globalTokenModel = null)); }; diff --git a/packages/messaging/test/tokenDetailsModel-getToken.test.ts b/packages/messaging/test/tokenDetailsModel-getToken.test.ts index 4f34e34a914..b87fcb65e81 100644 --- a/packages/messaging/test/tokenDetailsModel-getToken.test.ts +++ b/packages/messaging/test/tokenDetailsModel-getToken.test.ts @@ -45,7 +45,7 @@ describe('Firebase Messaging > TokenDetailsModel.getTokenDetailsFromToken()', fu } return Promise.all(promises) - .then(() => deleteDatabase(TokenDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_token_details_db')) .then(() => (globalTokenModel = null)); }; diff --git a/packages/messaging/test/tokenDetailsModel-saveToken.test.ts b/packages/messaging/test/tokenDetailsModel-saveToken.test.ts index cc1bb0fffa8..10066356c83 100644 --- a/packages/messaging/test/tokenDetailsModel-saveToken.test.ts +++ b/packages/messaging/test/tokenDetailsModel-saveToken.test.ts @@ -42,7 +42,7 @@ describe('Firebase Messaging > TokenDetailsModel.saveToken()', function() { } return Promise.all(promises) - .then(() => deleteDatabase(TokenDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_token_details_db')) .then(() => (globalTokenModel = null)); }; diff --git a/packages/messaging/test/vapid-details-model-delete.test.ts b/packages/messaging/test/vapid-details-model-delete.test.ts index 5973011194a..74fb8572ace 100644 --- a/packages/messaging/test/vapid-details-model-delete.test.ts +++ b/packages/messaging/test/vapid-details-model-delete.test.ts @@ -35,7 +35,7 @@ describe('Firebase Messaging > VapidDetailsModel.deleteToken()', function() { } return promiseChain - .then(() => deleteDatabase(VapidDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_vapid_details_db')) .then(() => (vapidModel = null)); }; diff --git a/packages/messaging/test/vapid-details-model-get.test.ts b/packages/messaging/test/vapid-details-model-get.test.ts index 519b7049da3..bed2d390f22 100644 --- a/packages/messaging/test/vapid-details-model-get.test.ts +++ b/packages/messaging/test/vapid-details-model-get.test.ts @@ -35,7 +35,7 @@ describe('Firebase Messaging > VapidDetailsModel.getVapidFromSWScope()', functio } return promiseChain - .then(() => deleteDatabase(VapidDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_vapid_details_db')) .then(() => (vapidModel = null)); }; diff --git a/packages/messaging/test/vapid-details-model-save.test.ts b/packages/messaging/test/vapid-details-model-save.test.ts index c0f964ec577..a234c24401b 100644 --- a/packages/messaging/test/vapid-details-model-save.test.ts +++ b/packages/messaging/test/vapid-details-model-save.test.ts @@ -35,7 +35,7 @@ describe('Firebase Messaging > VapidDetailsModel.saveVapidDetails()', function() } return promiseChain - .then(() => deleteDatabase(VapidDetailsModel.DB_NAME)) + .then(() => deleteDatabase('fcm_vapid_details_db')) .then(() => (vapidModel = null)); }; From 3aec5ac28d0439599af77184b1ffe86e0e16d790 Mon Sep 17 00:00:00 2001 From: Matt Gaunt Date: Wed, 21 Feb 2018 10:14:50 -0800 Subject: [PATCH 06/34] Updating API surface (#527) --- packages/messaging-types/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/messaging-types/index.d.ts b/packages/messaging-types/index.d.ts index 147942e2774..a4d5da954b9 100644 --- a/packages/messaging-types/index.d.ts +++ b/packages/messaging-types/index.d.ts @@ -34,4 +34,5 @@ export class FirebaseMessaging { requestPermission(): Promise | null; setBackgroundMessageHandler(callback: (a: Object) => any): any; useServiceWorker(registration: any): any; + usePublicVapidKey(b64PublicKey: string): void; } From 3ee5bdfde8ea59e884d4551c216646e41f44c2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Natan=20S=C4=85gol?= Date: Wed, 21 Feb 2018 22:34:55 +0100 Subject: [PATCH 07/34] Remove `return Promise.resolve()` statements from the codebase (#422) * Remove `return Promise.resolve()` statements from the codebase. * Fix compilation errors. * Fix more compiler errors. * Use `tslib` module and `importHelpers` Typescript compiler option. It reduces the size of TypeScript packages (namely `firebase-database`, `firebase-firestore`, `firebase-messaging` and the combined `firebase`) be reusing TypeScript helper methods (e.g. `__awaiter`) which were included in every single file relying on features not available in ES5 (emitted during transpilation process). * [AUTOMATED]: Prettier Code Styling * Regenerate top-level yarn.lock * Add `tslib` as a dependency to app, polyfill, storage, template and util packages. Since we set `importHelpers` compiler option to `true` in the base config, we need to add `tslib` to all packages. `*-types` packages are omitted since they do not contain any executable code. * Revert unnecessary change in comment formatting. * Revert moving comments out of empty else block to make the context more clear. Addresses @mikelehen review https://github.com/firebase/firebase-js-sdk/pull/422#pullrequestreview-98041340 --- config/tsconfig.base.json | 1 + .../messaging/test/utils/test-server.js | 16 +++---- packages/app/package.json | 3 +- packages/database/package.json | 3 +- packages/database/src/api/Database.ts | 3 +- packages/firestore/package.json | 3 +- packages/firestore/src/api/database.ts | 8 +--- packages/firestore/src/core/event_manager.ts | 4 +- .../firestore/src/core/firestore_client.ts | 8 +--- .../firestore/src/local/memory_persistence.ts | 8 ++-- .../firestore/src/remote/persistent_stream.ts | 20 +++------ packages/firestore/src/remote/remote_store.ts | 44 +++++++------------ .../test/integration/api/database.test.ts | 39 +++++----------- .../integration/api/server_timestamp.test.ts | 9 ++-- .../test/integration/api/transactions.test.ts | 17 +++---- .../test/integration/api/validation.test.ts | 16 +++---- .../test/integration/remote/stream.test.ts | 3 +- .../test/unit/specs/spec_test_runner.ts | 19 +++----- packages/messaging/package.json | 3 +- .../src/controllers/sw-controller.ts | 3 +- .../src/controllers/window-controller.ts | 5 +-- .../src/models/token-details-model.ts | 4 +- .../test/controller-delete-token.test.ts | 24 +++------- .../test/controller-get-token.test.ts | 22 ++++------ packages/messaging/test/sw-controller.test.ts | 10 ++--- .../messaging/test/window-controller.test.ts | 2 +- packages/polyfill/package.json | 3 +- packages/storage/package.json | 3 +- packages/template/package.json | 3 +- packages/util/package.json | 3 ++ yarn.lock | 6 +-- 31 files changed, 114 insertions(+), 201 deletions(-) diff --git a/config/tsconfig.base.json b/config/tsconfig.base.json index 99e890f5944..7682c9d62bc 100644 --- a/config/tsconfig.base.json +++ b/config/tsconfig.base.json @@ -2,6 +2,7 @@ "compileOnSave": false, "compilerOptions": { "declaration": true, + "importHelpers": true, "lib": [ "es5", "es2015", diff --git a/integration/messaging/test/utils/test-server.js b/integration/messaging/test/utils/test-server.js index 80f55538ae9..44b5062430d 100644 --- a/integration/messaging/test/utils/test-server.js +++ b/integration/messaging/test/utils/test-server.js @@ -42,9 +42,9 @@ class MessagingTestServer { return `http://localhost:${PORT_NUMBER}`; } - start() { + async start() { if (this._server) { - return Promise.resolve(); + return; } return new Promise((resolve, reject) => { @@ -56,15 +56,11 @@ class MessagingTestServer { // Sometimes the server doesn't trigger the callback due to // currently open sockets. So call `closethis._server - stop() { - if (!this._server) { - return Promise.resolve(); + async stop() { + if (this._server) { + this._server.close(); + this._server = null; } - - this._server.close(); - this._server = null; - - return Promise.resolve(); } } module.exports = new MessagingTestServer(); diff --git a/packages/app/package.json b/packages/app/package.json index 66d75be6c4e..27d5757fcaf 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -16,7 +16,8 @@ "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.1.1", - "@firebase/util": "0.1.9" + "@firebase/util": "0.1.9", + "tslib": "^1.9.0" }, "devDependencies": { "@types/chai": "^4.0.4", diff --git a/packages/database/package.json b/packages/database/package.json index 1d662bcb1a3..d3306e94c90 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -21,7 +21,8 @@ "dependencies": { "@firebase/database-types": "0.1.1", "@firebase/util": "0.1.9", - "faye-websocket": "0.11.1" + "faye-websocket": "0.11.1", + "tslib": "^1.9.0" }, "devDependencies": { "@types/chai": "^4.0.4", diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts index 95d8430495c..d237867c4a2 100644 --- a/packages/database/src/api/Database.ts +++ b/packages/database/src/api/Database.ts @@ -132,7 +132,7 @@ export class DatabaseInternals { constructor(public database: Database) {} /** @return {Promise} */ - delete(): Promise { + async delete(): Promise { (this.database as any).checkDeleted_('delete'); RepoManager.getInstance().deleteRepo((this.database as any).repo_ as Repo); @@ -140,6 +140,5 @@ export class DatabaseInternals { (this.database as any).root_ = null; this.database.INTERNAL = null; this.database = null; - return Promise.resolve(); } } diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 4ec7e39aca9..fb565549585 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -24,7 +24,8 @@ "dependencies": { "@firebase/firestore-types": "0.2.1", "@firebase/webchannel-wrapper": "0.2.6", - "grpc": "^1.7.1" + "grpc": "^1.7.1", + "tslib": "^1.9.0" }, "peerDependencies": { "@firebase/app": "^0.1.0", diff --git a/packages/firestore/src/api/database.ts b/packages/firestore/src/api/database.ts index f7eff250257..42965a476f8 100644 --- a/packages/firestore/src/api/database.ts +++ b/packages/firestore/src/api/database.ts @@ -383,11 +383,9 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService { } INTERNAL = { - delete: (): Promise => { + delete: async (): Promise => { if (this._firestoreClient) { return this._firestoreClient.shutdown(); - } else { - return Promise.resolve(); } } }; @@ -685,13 +683,11 @@ export class WriteBatch implements firestore.WriteBatch { return this; } - commit(): Promise { + async commit(): Promise { this.verifyNotCommitted(); this._committed = true; if (this._mutations.length > 0) { return this._firestore.ensureClientConfigured().write(this._mutations); - } else { - return Promise.resolve(); } } diff --git a/packages/firestore/src/core/event_manager.ts b/packages/firestore/src/core/event_manager.ts index 26ce5dbd1b6..12e07e48e32 100644 --- a/packages/firestore/src/core/event_manager.ts +++ b/packages/firestore/src/core/event_manager.ts @@ -87,7 +87,7 @@ export class EventManager { } } - unlisten(listener: QueryListener): Promise { + async unlisten(listener: QueryListener): Promise { const query = listener.query; let lastListen = false; @@ -103,8 +103,6 @@ export class EventManager { if (lastListen) { this.queries.delete(query); return this.syncEngine.unlisten(query); - } else { - return Promise.resolve(); } } diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts index a344a7546ed..63e349a5fd1 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -371,11 +371,7 @@ export class FirestoreClient { ): Promise { // We have to wait for the async queue to be sure syncEngine is initialized. return this.asyncQueue - .enqueue(() => { - return Promise.resolve(); - }) - .then(() => { - return this.syncEngine.runTransaction(updateFunction); - }); + .enqueue(async () => {}) + .then(() => this.syncEngine.runTransaction(updateFunction)); } } diff --git a/packages/firestore/src/local/memory_persistence.ts b/packages/firestore/src/local/memory_persistence.ts index f496ce5f522..e99468ff245 100644 --- a/packages/firestore/src/local/memory_persistence.ts +++ b/packages/firestore/src/local/memory_persistence.ts @@ -47,18 +47,16 @@ export class MemoryPersistence implements Persistence { private started = false; - start(): Promise { + async start(): Promise { + // No durable state to read on startup. assert(!this.started, 'MemoryPersistence double-started!'); this.started = true; - // No durable state to read on startup. - return Promise.resolve(); } - shutdown(): Promise { + async shutdown(): Promise { // No durable state to ensure is closed on shutdown. assert(this.started, 'MemoryPersistence shutdown without start!'); this.started = false; - return Promise.resolve(); } getMutationQueue(user: User): MutationQueue { diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index 2155e23ba1a..e563d084c7b 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -288,13 +288,12 @@ export abstract class PersistentStream< } /** Called by the idle timer when the stream should close due to inactivity. */ - private handleIdleCloseTimer(): Promise { + private async handleIdleCloseTimer(): Promise { if (this.isOpen()) { // When timing out an idle stream there's no reason to force the stream into backoff when // it restarts so set the stream state to Initial instead of Error. return this.close(PersistentStreamState.Initial); } - return Promise.resolve(); } /** Marks the stream as active again. */ @@ -319,7 +318,7 @@ export abstract class PersistentStream< * @param finalState the intended state of the stream after closing. * @param error the error the connection was closed with. */ - private close( + private async close( finalState: PersistentStreamState, error?: FirestoreError ): Promise { @@ -361,8 +360,6 @@ export abstract class PersistentStream< // could trigger undesirable recovery logic, etc.). if (finalState !== PersistentStreamState.Stopped) { return listener.onClose(error); - } else { - return Promise.resolve(); } } @@ -403,7 +400,7 @@ export abstract class PersistentStream< this.startStream(token); }, (error: Error) => { - this.queue.enqueue(() => { + this.queue.enqueue(async () => { if (this.state !== PersistentStreamState.Stopped) { // Stream can be stopped while waiting for authorization. const rpcError = new FirestoreError( @@ -411,8 +408,6 @@ export abstract class PersistentStream< 'Fetching auth token failed: ' + error.message ); return this.handleStreamClose(rpcError); - } else { - return Promise.resolve(); } }); } @@ -436,12 +431,10 @@ export abstract class PersistentStream< stream: Stream, fn: () => Promise ) => { - this.queue.enqueue(() => { + this.queue.enqueue(async () => { // Only raise events if the stream instance has not changed if (this.stream === stream) { return fn(); - } else { - return Promise.resolve(); } }); }; @@ -480,16 +473,15 @@ export abstract class PersistentStream< ); this.state = PersistentStreamState.Backoff; - this.backoff.backoffAndRun(() => { + this.backoff.backoffAndRun(async () => { if (this.state === PersistentStreamState.Stopped) { // Stream can be stopped while waiting for backoff to complete. - return Promise.resolve(); + return; } this.state = PersistentStreamState.Initial; this.start(listener); assert(this.isStarted(), 'PersistentStream should have started'); - return Promise.resolve(); }); } diff --git a/packages/firestore/src/remote/remote_store.ts b/packages/firestore/src/remote/remote_store.ts index 9dba21b9901..e65f11f075f 100644 --- a/packages/firestore/src/remote/remote_store.ts +++ b/packages/firestore/src/remote/remote_store.ts @@ -232,11 +232,10 @@ export class RemoteStore { * Temporarily disables the network. The network can be re-enabled using * enableNetwork(). */ - disableNetwork(): Promise { + async disableNetwork(): Promise { this.disableNetworkInternal(); // Set the OnlineState to failed so get()'s return from cache, etc. this.updateOnlineState(OnlineState.Failed); - return Promise.resolve(); } /** @@ -360,16 +359,17 @@ export class RemoteStore { this.pendingTargetResponses = {}; } - private onWatchStreamOpen(): Promise { + private async onWatchStreamOpen(): Promise { // TODO(b/35852690): close the stream again (with some timeout?) if no watch // targets are active objUtils.forEachNumber(this.listenTargets, (targetId, queryData) => { this.sendWatchRequest(queryData); }); - return Promise.resolve(); } - private onWatchStreamClose(error: FirestoreError | null): Promise { + private async onWatchStreamClose( + error: FirestoreError | null + ): Promise { assert( this.isNetworkEnabled(), 'onWatchStreamClose() should only be called when the network is enabled' @@ -387,10 +387,9 @@ export class RemoteStore { // at establishing a connection this.updateOnlineState(OnlineState.Unknown); } - return Promise.resolve(); } - private onWatchStreamChange( + private async onWatchStreamChange( watchChange: WatchChange, snapshotVersion: SnapshotVersion ): Promise { @@ -419,8 +418,6 @@ export class RemoteStore { const changes = this.accumulatedWatchChanges; this.accumulatedWatchChanges = []; return this.handleWatchChangeBatch(snapshotVersion, changes); - } else { - return Promise.resolve(); } } @@ -558,13 +555,11 @@ export class RemoteStore { const error = watchChange.cause!; let promiseChain = Promise.resolve(); watchChange.targetIds.forEach(targetId => { - promiseChain = promiseChain.then(() => { + promiseChain = promiseChain.then(async () => { + // A watched target might have been removed already. if (objUtils.contains(this.listenTargets, targetId)) { delete this.listenTargets[targetId]; return this.syncEngine.rejectListen(targetId, error); - } else { - // A watched target might have been removed already. - return Promise.resolve(); } }); }); @@ -586,10 +581,8 @@ export class RemoteStore { * Notifies that there are new mutations to process in the queue. This is * typically called by SyncEngine after it has sent mutations to LocalStore. */ - fillWritePipeline(): Promise { - if (!this.canWriteMutations()) { - return Promise.resolve(); - } else { + async fillWritePipeline(): Promise { + if (this.canWriteMutations()) { return this.localStore .nextMutationBatch(this.lastBatchSeen) .then(batch => { @@ -597,7 +590,6 @@ export class RemoteStore { if (this.pendingWrites.length === 0) { this.writeStream.markIdle(); } - return Promise.resolve(); } else { this.commit(batch); return this.fillWritePipeline(); @@ -669,10 +661,8 @@ export class RemoteStore { }); } - private onWriteStreamOpen(): Promise { + private async onWriteStreamOpen(): Promise { this.writeStream.writeHandshake(); - - return Promise.resolve(); } private onWriteHandshakeComplete(): Promise { @@ -723,7 +713,7 @@ export class RemoteStore { }); } - private onWriteStreamClose(error?: FirestoreError): Promise { + private async onWriteStreamClose(error?: FirestoreError): Promise { assert( this.isNetworkEnabled(), 'onWriteStreamClose() should only be called when the network is enabled' @@ -755,13 +745,11 @@ export class RemoteStore { this.startWriteStream(); } }); - } else { - // No pending writes, nothing to do - return Promise.resolve(); } + // No pending writes, nothing to do } - private handleHandshakeError(error: FirestoreError): Promise { + private async handleHandshakeError(error: FirestoreError): Promise { // Reset the token if it's a permanent error or the error code is // ABORTED, signaling the write stream is no longer valid. if (isPermanentError(error.code) || error.code === Code.ABORTED) { @@ -776,11 +764,10 @@ export class RemoteStore { } else { // Some other error, don't reset stream token. Our stream logic will // just retry with exponential backoff. - return Promise.resolve(); } } - private handleWriteError(error: FirestoreError): Promise { + private async handleWriteError(error: FirestoreError): Promise { if (isPermanentError(error.code)) { // This was a permanent error, the request itself was the problem // so it's not going to succeed if we resend it. @@ -800,7 +787,6 @@ export class RemoteStore { }); } else { // Transient error, just let the retry logic kick in. - return Promise.resolve(); } } diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index afe103b49ec..9ce80ebb8b7 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -40,11 +40,10 @@ apiDescribe('Database', persistence => { }); it('doc() will auto generate an ID', () => { - return withTestDb(persistence, db => { + return withTestDb(persistence, async db => { const ref = db.collection('foo').doc(); // Auto IDs are 20 characters long expect(ref.id.length).to.equal(20); - return Promise.resolve(); }); }); @@ -281,12 +280,11 @@ apiDescribe('Database', persistence => { const invalidDocValues = [undefined, null, 0, 'foo', ['a'], new Date()]; for (const val of invalidDocValues) { it('set/update should reject: ' + val, () => { - return withTestDoc(persistence, doc => { + return withTestDoc(persistence, async doc => { // tslint:disable-next-line:no-any Intentionally passing bad types. expect(() => doc.set(val as any)).to.throw(); // tslint:disable-next-line:no-any Intentionally passing bad types. expect(() => doc.update(val as any)).to.throw(); - return Promise.resolve(); }); }); } @@ -307,33 +305,30 @@ apiDescribe('Database', persistence => { // NOTE: Failure cases are validated in validation_test.ts it('same inequality fields works', () => { - return withTestCollection(persistence, {}, coll => { + return withTestCollection(persistence, {}, async coll => { expect(() => coll.where('x', '>=', 32).where('x', '<=', 'cat') ).not.to.throw(); - return Promise.resolve(); }); }); it('inequality and equality on different fields works', () => { - return withTestCollection(persistence, {}, coll => { + return withTestCollection(persistence, {}, async coll => { expect(() => coll.where('x', '>=', 32).where('y', '==', 'cat') ).not.to.throw(); - return Promise.resolve(); }); }); it('inequality same as orderBy works.', () => { - return withTestCollection(persistence, {}, coll => { + return withTestCollection(persistence, {}, async coll => { expect(() => coll.where('x', '>', 32).orderBy('x')).not.to.throw(); expect(() => coll.orderBy('x').where('x', '>', 32)).not.to.throw(); - return Promise.resolve(); }); }); it('inequality same as first orderBy works.', () => { - return withTestCollection(persistence, {}, coll => { + return withTestCollection(persistence, {}, async coll => { expect(() => coll .where('x', '>', 32) @@ -346,7 +341,6 @@ apiDescribe('Database', persistence => { .where('x', '>', 32) .orderBy('y') ).not.to.throw(); - return Promise.resolve(); }); }); }); @@ -496,22 +490,20 @@ apiDescribe('Database', persistence => { }); it('exposes "firestore" on document references.', () => { - return withTestDb(persistence, db => { + return withTestDb(persistence, async db => { expect(db.doc('foo/bar').firestore).to.equal(db); - return Promise.resolve(); }); }); it('exposes "firestore" on query references.', () => { - return withTestDb(persistence, db => { + return withTestDb(persistence, async db => { expect(db.collection('foo').limit(5).firestore).to.equal(db); - return Promise.resolve(); }); }); it('can compare DocumentReference instances with isEqual().', () => { return withTestDb(persistence, firestore => { - return withTestDb(persistence, otherFirestore => { + return withTestDb(persistence, async otherFirestore => { const docRef = firestore.doc('foo/bar'); expect(docRef.isEqual(firestore.doc('foo/bar'))).to.be.true; expect(docRef.collection('baz').parent.isEqual(docRef)).to.be.true; @@ -519,15 +511,13 @@ apiDescribe('Database', persistence => { expect(firestore.doc('foo/BAR').isEqual(docRef)).to.be.false; expect(otherFirestore.doc('foo/bar').isEqual(docRef)).to.be.false; - - return Promise.resolve(); }); }); }); it('can compare Query instances with isEqual().', () => { return withTestDb(persistence, firestore => { - return withTestDb(persistence, otherFirestore => { + return withTestDb(persistence, async otherFirestore => { const query = firestore .collection('foo') .orderBy('bar') @@ -549,14 +539,12 @@ apiDescribe('Database', persistence => { .orderBy('bar') .where('baz', '==', 42); expect(query4.isEqual(query)).to.be.false; - - return Promise.resolve(); }); }); }); it('can traverse collections and documents.', () => { - return withTestDb(persistence, db => { + return withTestDb(persistence, async db => { const expected = 'a/b/c/d'; // doc path from root Firestore. expect(db.doc('a/b/c/d').path).to.deep.equal(expected); @@ -568,12 +556,11 @@ apiDescribe('Database', persistence => { expect(db.doc('a/b').collection('c/d/e').path).to.deep.equal( expected + '/e' ); - return Promise.resolve(); }); }); it('can traverse collection and document parents.', () => { - return withTestDb(persistence, db => { + return withTestDb(persistence, async db => { let collection = db.collection('a/b/c'); expect(collection.path).to.deep.equal('a/b/c'); @@ -585,7 +572,6 @@ apiDescribe('Database', persistence => { const nullDoc = collection.parent; expect(nullDoc).to.equal(null); - return Promise.resolve(); }); }); @@ -640,7 +626,6 @@ apiDescribe('Database', persistence => { await db.disableNetwork(); await db.disableNetwork(); await db.enableNetwork(); - return Promise.resolve(); }); }); }); diff --git a/packages/firestore/test/integration/api/server_timestamp.test.ts b/packages/firestore/test/integration/api/server_timestamp.test.ts index d71d59a82a0..237947f9c44 100644 --- a/packages/firestore/test/integration/api/server_timestamp.test.ts +++ b/packages/firestore/test/integration/api/server_timestamp.test.ts @@ -202,9 +202,8 @@ apiDescribe('Server Timestamps', persistence => { it('work via transaction set()', () => { return withTestSetup(() => { return docRef.firestore - .runTransaction(txn => { + .runTransaction(async txn => { txn.set(docRef, setData); - return Promise.resolve(); }) .then(waitForRemoteEvent) .then(snapshot => verifyTimestampsAreResolved(snapshot)); @@ -215,9 +214,8 @@ apiDescribe('Server Timestamps', persistence => { return withTestSetup(() => { return writeInitialData() .then(() => - docRef.firestore.runTransaction(txn => { + docRef.firestore.runTransaction(async txn => { txn.update(docRef, updateData); - return Promise.resolve(); }) ) .then(waitForRemoteEvent) @@ -333,9 +331,8 @@ apiDescribe('Server Timestamps', persistence => { it('fail via transaction update() on nonexistent document.', () => { return withTestSetup(() => { return docRef.firestore - .runTransaction(txn => { + .runTransaction(async txn => { txn.update(docRef, updateData); - return Promise.resolve(); }) .then( () => { diff --git a/packages/firestore/test/integration/api/transactions.test.ts b/packages/firestore/test/integration/api/transactions.test.ts index 3ed53be5532..bfb8e4711fc 100644 --- a/packages/firestore/test/integration/api/transactions.test.ts +++ b/packages/firestore/test/integration/api/transactions.test.ts @@ -72,9 +72,8 @@ apiDescribe('Database transactions', persistence => { .then(snapshot => { expect(snapshot).to.exist; expect(snapshot.data()['foo']).to.equal('bar'); - return db.runTransaction(transaction => { + return db.runTransaction(async transaction => { transaction.delete(doc); - return Promise.resolve(); }); }) .then(() => { @@ -82,7 +81,6 @@ apiDescribe('Database transactions', persistence => { }) .then(snapshot => { expect(snapshot.exists).to.equal(false); - return Promise.resolve(); }); }); }); @@ -186,9 +184,8 @@ apiDescribe('Database transactions', persistence => { return integrationHelpers.withTestDb(persistence, db => { const doc = db.collection('towns').doc(); return db - .runTransaction(transaction => { + .runTransaction(async transaction => { transaction.set(doc, { a: 'b' }).set(doc, { c: 'd' }); - return Promise.resolve(); }) .then(() => { return doc.get(); @@ -204,7 +201,7 @@ apiDescribe('Database transactions', persistence => { return integrationHelpers.withTestDb(persistence, db => { const doc = db.collection('towns').doc(); return db - .runTransaction(transaction => { + .runTransaction(async transaction => { transaction.set(doc, { a: 'b', nested: { a: 'b' } }).set( doc, { c: 'd', nested: { c: 'd' } }, @@ -212,7 +209,6 @@ apiDescribe('Database transactions', persistence => { merge: true } ); - return Promise.resolve(); }) .then(() => { return doc.get(); @@ -357,7 +353,7 @@ apiDescribe('Database transactions', persistence => { return integrationHelpers.withTestDb(persistence, db => { const doc = db.collection('counters').doc(); return db - .runTransaction(transaction => { + .runTransaction(async transaction => { transaction.set(doc, initialData); transaction.update( doc, @@ -366,7 +362,6 @@ apiDescribe('Database transactions', persistence => { new firebase.firestore.FieldPath('is.admin'), true ); - return Promise.resolve(); }) .then(() => doc.get()) .then(docSnapshot => { @@ -537,9 +532,7 @@ apiDescribe('Database transactions', persistence => { it('are successful with no transaction operations', () => { return integrationHelpers.withTestDb(persistence, db => { - return db.runTransaction(txn => { - return Promise.resolve(); - }); + return db.runTransaction(async txn => {}); }); }); diff --git a/packages/firestore/test/integration/api/validation.test.ts b/packages/firestore/test/integration/api/validation.test.ts index 2051e8514db..8bab7ff59fa 100644 --- a/packages/firestore/test/integration/api/validation.test.ts +++ b/packages/firestore/test/integration/api/validation.test.ts @@ -38,12 +38,10 @@ function validationIt( testFunction: (db: firestore.FirebaseFirestore) => void | Promise ) { it(message, () => { - return withTestDb(persistence, db => { + return withTestDb(persistence, async db => { const maybePromise = testFunction(db); if (maybePromise) { return maybePromise; - } else { - return Promise.resolve(); } }); }); @@ -363,11 +361,10 @@ apiDescribe('Validation:', persistence => { .commit(); }) .then(() => { - return ref.firestore.runTransaction(txn => { + return ref.firestore.runTransaction(async txn => { // Note ref2 does not exist at this point so set that and update ref. txn.update(ref, data); txn.set(ref2, data); - return Promise.resolve(); }); }); }); @@ -465,7 +462,7 @@ apiDescribe('Validation:', persistence => { persistence, 'Batch writes require correct Document References', db => { - return withAlternateTestDb(persistence, db2 => { + return withAlternateTestDb(persistence, async db2 => { const badRef = db2.doc('foo/bar'); const reason = 'Provided document reference is from a different Firestore instance.'; @@ -474,7 +471,6 @@ apiDescribe('Validation:', persistence => { expect(() => batch.set(badRef, data)).to.throw(reason); expect(() => batch.update(badRef, data)).to.throw(reason); expect(() => batch.delete(badRef)).to.throw(reason); - return Promise.resolve(); }); } ); @@ -488,12 +484,11 @@ apiDescribe('Validation:', persistence => { const reason = 'Provided document reference is from a different Firestore instance.'; const data = { foo: 1 }; - return db.runTransaction(txn => { + return db.runTransaction(async txn => { expect(() => txn.get(badRef)).to.throw(reason); expect(() => txn.set(badRef, data)).to.throw(reason); expect(() => txn.update(badRef, data)).to.throw(reason); expect(() => txn.delete(badRef)).to.throw(reason); - return Promise.resolve(); }); }); } @@ -777,7 +772,7 @@ function expectWriteToFail( ); } - return docRef.firestore.runTransaction(txn => { + return docRef.firestore.runTransaction(async txn => { if (includeSets) { expect(() => txn.set(docRef, data)).to.throw(error('Transaction.set')); } @@ -787,7 +782,6 @@ function expectWriteToFail( error('Transaction.update') ); } - return Promise.resolve(); }); } diff --git a/packages/firestore/test/integration/remote/stream.test.ts b/packages/firestore/test/integration/remote/stream.test.ts index ef23ba3d004..0b778e223b5 100644 --- a/packages/firestore/test/integration/remote/stream.test.ts +++ b/packages/firestore/test/integration/remote/stream.test.ts @@ -112,14 +112,13 @@ class StreamStatusListener implements WatchStreamListener, WriteStreamListener { return this.resolvePending('close'); } - private resolvePending(actualCallback: StreamEventType): Promise { + private async resolvePending(actualCallback: StreamEventType): Promise { if (this.pendingPromises.length > 0) { let pendingPromise = this.pendingPromises.shift(); pendingPromise.resolve(actualCallback); } else { this.pendingCallbacks.push(actualCallback); } - return Promise.resolve(); } } diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index 261870162c6..2c202b0c772 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -232,11 +232,10 @@ class MockConnection implements Connection { this.resetAndCloseWriteStream(); } }); - this.queue.enqueue(() => { + this.queue.enqueue(async () => { if (this.writeStream === writeStream) { writeStream.callOnOpen(); } - return Promise.resolve(); }); this.writeStream = writeStream; return writeStream; @@ -265,12 +264,11 @@ class MockConnection implements Connection { } }); // Call on open immediately after returning - this.queue.enqueue(() => { + this.queue.enqueue(async () => { if (this.watchStream === watchStream) { watchStream.callOnOpen(); this.watchOpen.resolve(); } - return Promise.resolve(); }); this.watchStream = watchStream; return this.watchStream; @@ -688,9 +686,7 @@ abstract class TestRunner { } // Put a no-op in the queue so that we know when any outstanding RemoteStore // writes on the network are complete. - return this.queue.enqueue(() => { - return Promise.resolve(); - }); + return this.queue.enqueue(async () => {}); } private async doWatchStreamClose(spec: SpecWatchStreamClose): Promise { @@ -731,13 +727,11 @@ abstract class TestRunner { this.connection.ackWrite(updateTime, [{ updateTime }]); if (writeAck.expectUserCallback) { return nextWrite.userCallback.promise; - } else { - return Promise.resolve(); } }); } - private doFailWrite(writeFailure: SpecWriteFailure): Promise { + private async doFailWrite(writeFailure: SpecWriteFailure): Promise { const specError: SpecError = writeFailure.error; const error = new FirestoreError( mapCodeFromRpcCode(specError.code), @@ -761,8 +755,6 @@ abstract class TestRunner { expect(err).not.to.be.null; } ); - } else { - return Promise.resolve(); } }); } @@ -999,9 +991,8 @@ class MemoryTestRunner extends TestRunner { return new MemoryPersistence(); } - protected destroyPersistence(): Promise { + protected async destroyPersistence(): Promise { // Nothing to do. - return Promise.resolve(); } } diff --git a/packages/messaging/package.json b/packages/messaging/package.json index c61eb369576..1b40958b1f5 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -18,7 +18,8 @@ "dependencies": { "@firebase/messaging-types": "0.1.1", "@firebase/util": "0.1.9", - "lcov-result-merger": "^1.2.0" + "lcov-result-merger": "^1.2.0", + "tslib": "^1.9.0" }, "devDependencies": { "@types/chai": "^4.0.4", diff --git a/packages/messaging/src/controllers/sw-controller.ts b/packages/messaging/src/controllers/sw-controller.ts index 8b0d2649d18..68911414d18 100644 --- a/packages/messaging/src/controllers/sw-controller.ts +++ b/packages/messaging/src/controllers/sw-controller.ts @@ -296,7 +296,7 @@ export default class SWController extends ControllerInterface { * message. This does not guarantee that the message was successfully * received. */ - attemptToMessageClient_(client, message) { + async attemptToMessageClient_(client, message) { // NOTE: This returns a promise in case this API is abstracted later on to // do additional work if (!client) { @@ -306,7 +306,6 @@ export default class SWController extends ControllerInterface { } client.postMessage(message); - return Promise.resolve(); } /** diff --git a/packages/messaging/src/controllers/window-controller.ts b/packages/messaging/src/controllers/window-controller.ts index cf7d8590a1c..09a0178d7a2 100644 --- a/packages/messaging/src/controllers/window-controller.ts +++ b/packages/messaging/src/controllers/window-controller.ts @@ -133,7 +133,6 @@ export default class WindowController extends ControllerInterface .catch(() => { // If the download or parsing fails allow check. // We only want to error if we KNOW that the gcm_sender_id is incorrect. - return Promise.resolve(); }) .then(manifestContent => { if (!manifestContent) { @@ -161,9 +160,9 @@ export default class WindowController extends ControllerInterface * @returns {Promise} Resolves if the permission was granted, otherwise * rejects */ - requestPermission() { + async requestPermission() { if ((Notification as any).permission === NOTIFICATION_PERMISSION.granted) { - return Promise.resolve(); + return; } return new Promise((resolve, reject) => { diff --git a/packages/messaging/src/models/token-details-model.ts b/packages/messaging/src/models/token-details-model.ts index a3182ce6554..21ddc6a5c94 100644 --- a/packages/messaging/src/models/token-details-model.ts +++ b/packages/messaging/src/models/token-details-model.ts @@ -77,7 +77,7 @@ export default class TokenDetailsModel extends DBInterface { * @return {!Promise} Returns promise that resolves if input is valid, * rejects otherwise. */ - validateInputs_(input) { + async validateInputs_(input) { if (input.fcmToken) { if (typeof input.fcmToken !== 'string' || input.fcmToken.length === 0) { return Promise.reject( @@ -134,8 +134,6 @@ export default class TokenDetailsModel extends DBInterface { ); } } - - return Promise.resolve(); } /** diff --git a/packages/messaging/test/controller-delete-token.test.ts b/packages/messaging/test/controller-delete-token.test.ts index f5c1480b831..72021beddc6 100644 --- a/packages/messaging/test/controller-delete-token.test.ts +++ b/packages/messaging/test/controller-delete-token.test.ts @@ -108,9 +108,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { return Promise.resolve(EXAMPLE_TOKEN_SAVE); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); globalMessagingService = new WindowController(app); return globalMessagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken); @@ -129,9 +127,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { return Promise.resolve(EXAMPLE_TOKEN_SAVE); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); globalMessagingService = new WindowController(app); return globalMessagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken).then( @@ -158,9 +154,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { return Promise.resolve(EXAMPLE_TOKEN_SAVE); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); globalMessagingService = new ServiceClass(app); return globalMessagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken); @@ -185,9 +179,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { return Promise.resolve(EXAMPLE_TOKEN_SAVE); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); globalMessagingService = new ServiceClass(app); return globalMessagingService @@ -205,7 +197,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { it(`should handle error on deleteToken ${ServiceClass.name}`, function() { const fakeSubscription = { endpoint: EXAMPLE_TOKEN_SAVE.endpoint, - unsubscribe: () => Promise.resolve() + unsubscribe: async () => {} }; configureRegistrationMocks( @@ -241,7 +233,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { it(`should delete with valid unsubscribe ${ServiceClass.name}`, function() { const fakeSubscription = { endpoint: EXAMPLE_TOKEN_SAVE.endpoint, - unsubscribe: () => Promise.resolve() + unsubscribe: async () => {} }; configureRegistrationMocks( @@ -256,9 +248,7 @@ describe('Firebase Messaging > *Controller.deleteToken()', function() { return Promise.resolve(EXAMPLE_TOKEN_SAVE); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); globalMessagingService = new ServiceClass(app); return globalMessagingService.deleteToken(EXAMPLE_TOKEN_SAVE.fcmToken); diff --git a/packages/messaging/test/controller-get-token.test.ts b/packages/messaging/test/controller-get-token.test.ts index b5551f0b0be..1a6695dad80 100644 --- a/packages/messaging/test/controller-get-token.test.ts +++ b/packages/messaging/test/controller-get-token.test.ts @@ -307,11 +307,11 @@ describe('Firebase Messaging > *Controller.getToken()', function() { sandbox .stub(TokenDetailsModel.prototype, 'saveTokenDetails') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); sandbox .stub(VapidDetailsModel.prototype, 'saveVapidDetails') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); const serviceInstance = new ServiceClass(app); return serviceInstance.getToken().then(token => { @@ -350,7 +350,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { sandbox .stub(VapidDetailsModel.prototype, 'saveVapidDetails') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); sandbox .stub(IIDModel.prototype, 'getToken') @@ -362,7 +362,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { sandbox .stub(TokenDetailsModel.prototype, 'saveTokenDetails') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); const serviceInstance = new ServiceClass(app); return serviceInstance.getToken().then(token => { @@ -430,7 +430,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { sandbox .stub(VapidDetailsModel.prototype, 'saveVapidDetails') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); sandbox .stub(TokenDetailsModel.prototype, 'getTokenDetailsFromSWScope') @@ -461,7 +461,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { TokenDetailsModel.prototype, 'saveTokenDetails' ); - saveTokenDetailsStub.callsFake(() => Promise.resolve()); + saveTokenDetailsStub.callsFake(async () => {}); const deleteTokenStub = sandbox.stub( TokenDetailsModel.prototype, @@ -472,9 +472,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { return Promise.resolve(EXAMPLE_TOKEN_DETAILS_DEFAULT_VAPID); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); sandbox .stub(IIDModel.prototype, 'getToken') @@ -521,7 +519,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { sandbox .stub(VapidDetailsModel.prototype, 'saveVapidDetails') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); sandbox .stub(IIDModel.prototype, 'updateToken') @@ -536,9 +534,7 @@ describe('Firebase Messaging > *Controller.getToken()', function() { return Promise.resolve(EXAMPLE_EXPIRED_TOKEN_DETAILS); }); - sandbox - .stub(IIDModel.prototype, 'deleteToken') - .callsFake(() => Promise.resolve()); + sandbox.stub(IIDModel.prototype, 'deleteToken').callsFake(async () => {}); const serviceInstance = new ServiceClass(app); try { diff --git a/packages/messaging/test/sw-controller.test.ts b/packages/messaging/test/sw-controller.test.ts index cb391f2fd8d..ea186e3c51e 100644 --- a/packages/messaging/test/sw-controller.test.ts +++ b/packages/messaging/test/sw-controller.test.ts @@ -612,7 +612,7 @@ describe('Firebase Messaging > *SWController', function() { .callsFake(() => Promise.resolve(null)); sandbox .stub(swController, 'attemptToMessageClient_') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); swController.onNotificationClick_(event); @@ -671,7 +671,7 @@ describe('Firebase Messaging > *SWController', function() { .callsFake(() => Promise.resolve(fakeWindowClient)); sandbox .stub(swController, 'attemptToMessageClient_') - .callsFake(() => Promise.resolve()); + .callsFake(async () => {}); swController.onNotificationClick_(event); @@ -758,9 +758,9 @@ describe('Firebase Messaging > *SWController', function() { }; const swController = new SWController(app); - sandbox.stub(swController, 'attemptToMessageClient_').callsFake(() => { - return Promise.resolve(); - }); + sandbox + .stub(swController, 'attemptToMessageClient_') + .callsFake(async () => {}); const payload = { example: 'test' diff --git a/packages/messaging/test/window-controller.test.ts b/packages/messaging/test/window-controller.test.ts index 8447bd97135..1505822ca5e 100644 --- a/packages/messaging/test/window-controller.test.ts +++ b/packages/messaging/test/window-controller.test.ts @@ -386,7 +386,7 @@ describe('Firebase Messaging > *WindowController', function() { const exampleSubscription = {}; const reg = makeFakeSWReg(); sandbox.stub(reg, 'pushManager').value({ - getSubscription: () => Promise.resolve(), + getSubscription: async () => {}, subscribe: options => { expect(options).to.deep.equal({ userVisibleOnly: true, diff --git a/packages/polyfill/package.json b/packages/polyfill/package.json index 4e5634d4c55..d35fd6df44d 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -12,7 +12,8 @@ }, "license": "Apache-2.0", "dependencies": { - "promise-polyfill": "^6.0.2" + "promise-polyfill": "^6.0.2", + "tslib": "^1.9.0" }, "devDependencies": { "@types/node": "^8.0.47", diff --git a/packages/storage/package.json b/packages/storage/package.json index 7e61b79409c..5ab033a5afe 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -13,7 +13,8 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/storage-types": "0.1.1" + "@firebase/storage-types": "0.1.1", + "tslib": "^1.9.0" }, "peerDependencies": { "@firebase/app": "^0.1.0", diff --git a/packages/template/package.json b/packages/template/package.json index d50e28b0dfc..580e2f74ced 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -19,7 +19,8 @@ "@firebase/app-types": "0.1.1" }, "dependencies": { - "@firebase/template-types": "0.1.0" + "@firebase/template-types": "0.1.0", + "tslib": "^1.9.0" }, "license": "Apache-2.0", "devDependencies": { diff --git a/packages/util/package.json b/packages/util/package.json index 1c76d0c44b9..a8d74456670 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -14,6 +14,9 @@ "prepare": "gulp build" }, "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, "devDependencies": { "@types/chai": "^4.0.4", "@types/mocha": "^2.2.44", diff --git a/yarn.lock b/yarn.lock index e9c9495a984..0f5a2499ffc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9397,9 +9397,9 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.7.1, tslib@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac" +tslib@^1.7.1, tslib@^1.8.1, tslib@^1.9.0: + version "1.9.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" tslint@^5.8.0: version "5.8.0" From 1b44b4d6166ccd523a3beefda89349c9e4162609 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 21 Feb 2018 15:58:16 -0800 Subject: [PATCH 08/34] Fixing fork testing issues --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2170d596802..ef04aa47a1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_install: # Yarn defaults to an old version, make sure we # get an up to date version - npm install -g yarn - - echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > $HOME/.npmrc + - '[ "${NPM_TOKEN+x}" ] && { echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > $HOME/.npmrc } || echo "Skipping .npmrc creation";' before_script: - cp config/ci.config.json config/project.json script: @@ -37,4 +37,5 @@ deploy: provider: script script: yarn release --canary on: + repo: firebase/firebase-js-sdk branch: master From 0226ed23128f4a0a9fbc5896c207d3157c9d06de Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 21 Feb 2018 16:03:26 -0800 Subject: [PATCH 09/34] Remove bash grouping --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ef04aa47a1c..6158e44d5d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_install: # Yarn defaults to an old version, make sure we # get an up to date version - npm install -g yarn - - '[ "${NPM_TOKEN+x}" ] && { echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > $HOME/.npmrc } || echo "Skipping .npmrc creation";' + - '[ "${NPM_TOKEN+x}" ] && echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > $HOME/.npmrc || echo "Skipping .npmrc creation";' before_script: - cp config/ci.config.json config/project.json script: From cde4e44a2e552791d9c0249a20e435e2ec15929d Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 21 Feb 2018 16:25:56 -0800 Subject: [PATCH 10/34] Dependencies Update (#528) * Run "yarn upgrade-interactive --latest" * Update gulp to a proper NPM dep * Regen yarn.lock * Fix typescript generics issues * [AUTOMATED]: Prettier Code Styling --- integration/browserify/package.json | 8 +- integration/firebase-typings/package.json | 2 +- integration/firestore/package.json | 22 +- integration/messaging/package.json | 10 +- integration/typescript/package.json | 16 +- integration/webpack/package.json | 8 +- package.json | 24 +- packages/app-types/package.json | 2 +- packages/app/package.json | 32 +- packages/auth-types/package.json | 2 +- packages/auth/package.json | 10 +- packages/database-types/package.json | 2 +- packages/database/package.json | 30 +- packages/database/test/order_by.test.ts | 4 +- packages/database/test/query.test.ts | 28 +- packages/database/test/transaction.test.ts | 48 +- packages/firebase/package.json | 14 +- packages/firestore-types/package.json | 2 +- packages/firestore/package.json | 34 +- .../src/platform_node/grpc_connection.ts | 16 +- .../firestore/src/remote/persistent_stream.ts | 4 +- .../firestore/src/util/input_validation.ts | 8 +- .../test/integration/api/validation.test.ts | 4 +- packages/messaging-types/package.json | 2 +- packages/messaging/package.json | 24 +- packages/polyfill/package.json | 4 +- packages/storage-types/package.json | 2 +- packages/storage/package.json | 22 +- packages/template-types/package.json | 2 +- packages/template/package.json | 26 +- packages/testing/package.json | 8 +- packages/util/package.json | 26 +- yarn.lock | 6225 ++++++++++------- 33 files changed, 4008 insertions(+), 2663 deletions(-) diff --git a/integration/browserify/package.json b/integration/browserify/package.json index ffe283105af..87eccfb7127 100644 --- a/integration/browserify/package.json +++ b/integration/browserify/package.json @@ -10,14 +10,14 @@ "firebase": "4.10.0" }, "devDependencies": { - "browserify": "^14.5.0", + "browserify": "^16.1.0", "chai": "^4.1.1", - "karma": "^1.7.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", - "karma-spec-reporter": "0.0.31", + "karma-spec-reporter": "0.0.32", "mkdirp": "^0.5.1", - "mocha": "^4.0.1" + "mocha": "^5.0.1" } } diff --git a/integration/firebase-typings/package.json b/integration/firebase-typings/package.json index 46752ce6218..3ec28b02098 100644 --- a/integration/firebase-typings/package.json +++ b/integration/firebase-typings/package.json @@ -9,6 +9,6 @@ "firebase": "4.10.0" }, "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" } } diff --git a/integration/firestore/package.json b/integration/firestore/package.json index 77fd45b1b3f..6da0390fdc9 100644 --- a/integration/firestore/package.json +++ b/integration/firestore/package.json @@ -11,19 +11,19 @@ "test:debug": "karma start --auto-watch --browsers Chrome" }, "devDependencies": { - "@types/mocha": "^2.2.44", - "@types/node": "^8.0.47", - "gulp": "gulpjs/gulp#4.0", - "gulp-filter": "^5.0.1", + "@types/mocha": "^2.2.48", + "@types/node": "^9.4.6", + "gulp": "^4.0.0", + "gulp-filter": "^5.1.0", "gulp-replace": "^0.6.1", - "karma": "^1.7.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", - "karma-spec-reporter": "0.0.31", - "mocha": "^4.0.1", - "ts-loader": "^3.1.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1", - "webpack-stream": "^4.0.0" + "karma-spec-reporter": "0.0.32", + "mocha": "^5.0.1", + "ts-loader": "^3.5.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0", + "webpack-stream": "^4.0.2" } } diff --git a/integration/messaging/package.json b/integration/messaging/package.json index 33610590e5e..bb7aa5860dd 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -12,12 +12,12 @@ }, "devDependencies": { "chai": "^4.1.1", - "chromedriver": "^2.31.0", + "chromedriver": "^2.35.0", "express": "^4.15.4", "geckodriver": "^1.8.0", - "mocha": "^4.0.1", - "node-fetch": "^1.7.2", - "selenium-assistant": "^5.2.0", - "sinon": "^4.1.3" + "mocha": "^5.0.1", + "node-fetch": "^2.0.0", + "selenium-assistant": "^5.3.0", + "sinon": "^4.3.0" } } diff --git a/integration/typescript/package.json b/integration/typescript/package.json index d030dfe4f13..5c24c7b7d7a 100644 --- a/integration/typescript/package.json +++ b/integration/typescript/package.json @@ -9,18 +9,18 @@ "firebase": "4.10.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/node": "^8.0.47", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/node": "^9.4.6", "chai": "^4.1.1", - "karma": "^1.7.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", - "karma-spec-reporter": "0.0.31", - "karma-typescript": "^3.0.8", - "mocha": "^4.0.1", + "karma-spec-reporter": "0.0.32", + "karma-typescript": "^3.0.12", + "mocha": "^5.0.1", "npm-run-all": "^4.1.1", - "typescript": "^2.4.2" + "typescript": "^2.7.2" } } diff --git a/integration/webpack/package.json b/integration/webpack/package.json index 5a235a1f812..860727d4ae8 100644 --- a/integration/webpack/package.json +++ b/integration/webpack/package.json @@ -11,12 +11,12 @@ }, "devDependencies": { "chai": "^4.1.1", - "karma": "^1.7.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", - "karma-spec-reporter": "0.0.31", - "mocha": "^4.0.1", - "webpack": "^3.8.1" + "karma-spec-reporter": "0.0.32", + "mocha": "^5.0.1", + "webpack": "^3.11.0" } } diff --git a/package.json b/package.json index 9e9048876a0..41ccca6850a 100644 --- a/package.json +++ b/package.json @@ -37,29 +37,29 @@ "integration/*" ], "devDependencies": { - "chalk": "^2.3.0", + "chalk": "^2.3.1", "child-process-promise": "^2.2.1", "clone": "^2.1.1", "coveralls": "^3.0.0", "dependency-graph": "^0.7.0", - "firebase-tools": "^3.10.1", + "firebase-tools": "^3.17.4", "glob": "^7.1.2", - "gulp-sourcemaps": "^2.6.1", - "gulp-typescript": "^3.2.3", + "gulp-sourcemaps": "^2.6.4", + "gulp-typescript": "^4.0.1", "husky": "^0.14.3", - "inquirer": "^5.0.0", + "inquirer": "^5.1.0", "istanbul-instrumenter-loader": "^3.0.0", - "lcov-result-merger": "^1.2.0", - "lerna": "^2.1.0", + "lcov-result-merger": "^2.0.0", + "lerna": "^2.9.0", "listr": "^0.13.0", - "merge2": "^1.2.0", + "merge2": "^1.2.1", "mkdirp": "^0.5.1", "mz": "^2.7.0", "npm-run-path": "^2.0.2", - "ora": "^1.3.0", - "prettier": "^1.7.0", + "ora": "^2.0.0", + "prettier": "^1.10.2", "semver": "^5.5.0", - "simple-git": "^1.80.1", - "yargs": "^10.0.3" + "simple-git": "^1.91.0", + "yargs": "^11.0.0" } } diff --git a/packages/app-types/package.json b/packages/app-types/package.json index f79b34bcc0b..73abc0675f5 100644 --- a/packages/app-types/package.json +++ b/packages/app-types/package.json @@ -12,7 +12,7 @@ "private.d.ts" ], "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/app/package.json b/packages/app/package.json index 27d5757fcaf..86a9a7120f8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -20,31 +20,31 @@ "tslib": "^1.9.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", + "gulp": "^4.0.0", "gulp-replace": "^0.6.1", - "gulp-sourcemaps": "^2.6.1", - "karma": "^1.7.0", + "gulp-sourcemaps": "^2.6.4", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", - "karma-coverage-istanbul-reporter": "^1.3.0", + "karma-coverage-istanbul-reporter": "^1.4.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", "karma-sourcemap-loader": "^0.3.7", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", - "mocha": "^4.0.1", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", + "mocha": "^5.0.1", "npm-run-all": "^4.1.1", - "nyc": "^11.2.1", - "sinon": "^4.0.2", + "nyc": "^11.4.1", + "sinon": "^4.3.0", "source-map-loader": "^0.2.3", - "ts-loader": "^3.1.0", - "ts-node": "^4.1.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1" + "ts-loader": "^3.5.0", + "ts-node": "^5.0.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" }, "repository": { "type": "git", diff --git a/packages/auth-types/package.json b/packages/auth-types/package.json index 1ce00901bca..4fc4f4fad61 100644 --- a/packages/auth-types/package.json +++ b/packages/auth-types/package.json @@ -14,7 +14,7 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/auth/package.json b/packages/auth/package.json index 3d49714c26d..be4b6dcdf6b 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -25,14 +25,14 @@ }, "devDependencies": { "closure-builder": "^2.0.17", - "del": "^2.2.2", + "del": "^3.0.0", "express": "^4.16.2", - "firebase-tools": "^3.10.1", - "google-closure-compiler": "^20170910.0.0", - "google-closure-library": "^20170910.0.0", + "firebase-tools": "^3.17.4", + "google-closure-compiler": "^20180204.0.0", + "google-closure-library": "^20180204.0.0", "gulp": "^3.9.1", "gulp-closure-compiler": "^0.4.0", - "protractor": "^5.1.2" + "protractor": "^5.3.0" }, "repository": { "type": "git", diff --git a/packages/database-types/package.json b/packages/database-types/package.json index 54f46d4f7bb..0bd4a1255b9 100644 --- a/packages/database-types/package.json +++ b/packages/database-types/package.json @@ -14,7 +14,7 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/database/package.json b/packages/database/package.json index d3306e94c90..540a58dcb11 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -25,29 +25,29 @@ "tslib": "^1.9.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/node": "^8.0.47", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/node": "^9.4.6", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "karma": "^1.7.0", + "gulp": "^4.0.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", "karma-sourcemap-loader": "^0.3.7", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", - "mocha": "^4.0.1", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", + "mocha": "^5.0.1", "npm-run-all": "^4.1.1", - "nyc": "^11.2.1", - "sinon": "^4.0.2", + "nyc": "^11.4.1", + "sinon": "^4.3.0", "source-map-loader": "^0.2.3", - "ts-loader": "^3.1.0", - "ts-node": "^4.1.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1" + "ts-loader": "^3.5.0", + "ts-node": "^5.0.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" }, "repository": { "type": "git", diff --git a/packages/database/test/order_by.test.ts b/packages/database/test/order_by.test.ts index 70495f2fd60..b821de62138 100644 --- a/packages/database/test/order_by.test.ts +++ b/packages/database/test/order_by.test.ts @@ -363,9 +363,7 @@ describe('.orderBy tests', function() { expect(addedPrevNames).to.deep.equal(expectedPrevNames); }); - it('Removing default listener removes non-default listener that loads all data', function( - done - ) { + it('Removing default listener removes non-default listener that loads all data', function(done) { const ref = getRandomNode() as Reference; const initial = { key: 'value' }; diff --git a/packages/database/test/query.test.ts b/packages/database/test/query.test.ts index 499748d3edd..bda21cdbb0b 100644 --- a/packages/database/test/query.test.ts +++ b/packages/database/test/query.test.ts @@ -1971,9 +1971,7 @@ describe('Query Tests', function() { expect(val).to.equal(2); }); - it('.startAt() with two arguments works properly (case 1169).', function( - done - ) { + it('.startAt() with two arguments works properly (case 1169).', function(done) { const ref = getRandomNode() as Reference; const data = { Walker: { @@ -2110,9 +2108,7 @@ describe('Query Tests', function() { }); }); - it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", function( - done - ) { + it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", function(done) { const ref = getRandomNode() as Reference; ref.set( { a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f', g: 'g', h: 'h' }, @@ -2134,9 +2130,7 @@ describe('Query Tests', function() { ); }); - it('complex update() at query root raises correct value event', function( - done - ) { + it('complex update() at query root raises correct value event', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2241,9 +2235,7 @@ describe('Query Tests', function() { }); }); - it('listen for child_added events with limit and different types fires properly', function( - done - ) { + it('listen for child_added events with limit and different types fires properly', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2285,9 +2277,7 @@ describe('Query Tests', function() { }); }); - it('listen for child_changed events with limit and different types fires properly', function( - done - ) { + it('listen for child_changed events with limit and different types fires properly', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2338,9 +2328,7 @@ describe('Query Tests', function() { }); }); - it('listen for child_remove events with limit and different types fires properly', function( - done - ) { + it('listen for child_remove events with limit and different types fires properly', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2442,9 +2430,7 @@ describe('Query Tests', function() { ); }); - it('listen for child_remove events when parent set to scalar', function( - done - ) { + it('listen for child_remove events when parent set to scalar', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; diff --git a/packages/database/test/transaction.test.ts b/packages/database/test/transaction.test.ts index e603105ebc0..d0f44f5accc 100644 --- a/packages/database/test/transaction.test.ts +++ b/packages/database/test/transaction.test.ts @@ -86,9 +86,7 @@ describe('Transaction Tests', function() { }); }); - it('Non-aborted transaction sets committed to true in callback.', function( - done - ) { + it('Non-aborted transaction sets committed to true in callback.', function(done) { const node = getRandomNode() as Reference; node.transaction( @@ -104,9 +102,7 @@ describe('Transaction Tests', function() { ); }); - it('Aborted transaction sets committed to false in callback.', function( - done - ) { + it('Aborted transaction sets committed to false in callback.', function(done) { const node = getRandomNode() as Reference; node.transaction( @@ -236,9 +232,7 @@ describe('Transaction Tests', function() { return ea.promise; }); - it('Second transaction gets run immediately on previous output and only runs once.', function( - done - ) { + it('Second transaction gets run immediately on previous output and only runs once.', function(done) { const nodePair = getRandomNode(2) as Reference[]; let firstRun = false, firstDone = false, @@ -512,9 +506,7 @@ describe('Transaction Tests', function() { ); }); - it('Set should cancel already sent transactions that come back as datastale.', function( - done - ) { + it('Set should cancel already sent transactions that come back as datastale.', function(done) { const nodePair = getRandomNode(2) as Reference[]; let transactionCalls = 0; nodePair[0].set(5, function() { @@ -688,9 +680,7 @@ describe('Transaction Tests', function() { return Promise.all([tx1, tx2]); }); - it('Doing set() in successful transaction callback works. Case 870.', function( - done - ) { + it('Doing set() in successful transaction callback works. Case 870.', function(done) { const node = getRandomNode() as Reference; let transactionCalled = false; let callbackCalled = false; @@ -710,9 +700,7 @@ describe('Transaction Tests', function() { ); }); - it('Doing set() in aborted transaction callback works. Case 870.', function( - done - ) { + it('Doing set() in aborted transaction callback works. Case 870.', function(done) { const nodePair = getRandomNode(2) as Reference[], node1 = nodePair[0], node2 = nodePair[1]; @@ -1028,9 +1016,7 @@ describe('Transaction Tests', function() { ); }); - it('Transaction properly reverts data when you add a deeper listen.', function( - done - ) { + it('Transaction properly reverts data when you add a deeper listen.', function(done) { const refPair = getRandomNode(2) as Reference[], ref1 = refPair[0], ref2 = refPair[1]; @@ -1200,9 +1186,7 @@ describe('Transaction Tests', function() { }); }); - it("transaction() doesn't pick up cached data from previous once().", function( - done - ) { + it("transaction() doesn't pick up cached data from previous once().", function(done) { const refPair = getRandomNode(2) as Reference[]; const me = refPair[0], other = refPair[1]; @@ -1229,9 +1213,7 @@ describe('Transaction Tests', function() { }); }); - it("transaction() doesn't pick up cached data from previous transaction.", function( - done - ) { + it("transaction() doesn't pick up cached data from previous transaction.", function(done) { const refPair = getRandomNode(2) as Reference[]; const me = refPair[0], other = refPair[1]; @@ -1263,9 +1245,7 @@ describe('Transaction Tests', function() { ); }); - it('server values: local timestamp should eventually (but not immediately) match the server with txns', function( - done - ) { + it('server values: local timestamp should eventually (but not immediately) match the server with txns', function(done) { const refPair = getRandomNode(2) as Reference[], writer = refPair[0], reader = refPair[1], @@ -1357,9 +1337,7 @@ describe('Transaction Tests', function() { ); }); - it("transaction() on queried location doesn't run initially on null (firebase-worker-queue depends on this).", function( - done - ) { + it("transaction() on queried location doesn't run initially on null (firebase-worker-queue depends on this).", function(done) { const ref = getRandomNode() as Reference; ref.push({ a: 1, b: 2 }, function() { ref @@ -1437,9 +1415,7 @@ describe('Transaction Tests', function() { ); }); - it('transactions works with merges without the transaction path', function( - done - ) { + it('transactions works with merges without the transaction path', function(done) { const ref = getRandomNode() as Reference; ref.update({ foo: 'bar' }); diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 8fa17ae9dd9..40a63bbba61 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -38,15 +38,15 @@ "xmlhttprequest": "^1.8.0" }, "devDependencies": { - "compression-webpack-plugin": "^1.0.0", - "git-rev-sync": "^1.9.1", - "gulp": "gulpjs/gulp#4.0", + "compression-webpack-plugin": "^1.1.7", + "git-rev-sync": "^1.10.0", + "gulp": "^4.0.0", "gulp-concat": "^2.6.1", - "gulp-sourcemaps": "^2.6.1", + "gulp-sourcemaps": "^2.6.4", "npm-run-all": "^4.1.1", - "webpack": "^3.5.6", - "webpack-dev-server": "^2.8.1", - "webpack-stream": "^4.0.0", + "webpack": "^3.11.0", + "webpack-dev-server": "^2.11.1", + "webpack-stream": "^4.0.2", "wrapper-webpack-plugin": "^1.0.0" }, "typings": "index.d.ts" diff --git a/packages/firestore-types/package.json b/packages/firestore-types/package.json index e78beb5c5ab..c1c22cc2731 100644 --- a/packages/firestore-types/package.json +++ b/packages/firestore-types/package.json @@ -14,7 +14,7 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/firestore/package.json b/packages/firestore/package.json index fb565549585..6cd0d693715 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -24,7 +24,7 @@ "dependencies": { "@firebase/firestore-types": "0.2.1", "@firebase/webchannel-wrapper": "0.2.6", - "grpc": "^1.7.1", + "grpc": "^1.9.1", "tslib": "^1.9.0" }, "peerDependencies": { @@ -32,31 +32,31 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "karma": "^1.7.0", + "gulp": "^4.0.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", "karma-sourcemap-loader": "^0.3.7", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", "mkdirp": "^0.5.1", - "mocha": "^4.0.1", + "mocha": "^5.0.1", "npm-run-all": "^4.1.1", - "nyc": "^11.2.1", - "sinon": "^4.0.2", + "nyc": "^11.4.1", + "sinon": "^4.3.0", "source-map-loader": "^0.2.3", - "ts-loader": "^3.1.0", - "ts-node": "^4.1.0", - "tslint": "^5.8.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1", - "yargs": "^10.0.3" + "ts-loader": "^3.5.0", + "ts-node": "^5.0.0", + "tslint": "^5.9.1", + "typescript": "^2.7.2", + "webpack": "^3.11.0", + "yargs": "^11.0.0" }, "repository": { "type": "git", diff --git a/packages/firestore/src/platform_node/grpc_connection.ts b/packages/firestore/src/platform_node/grpc_connection.ts index 21027183103..639c8c3b831 100644 --- a/packages/firestore/src/platform_node/grpc_connection.ts +++ b/packages/firestore/src/platform_node/grpc_connection.ts @@ -37,12 +37,12 @@ const LOG_TAG = 'Connection'; // TODO(b/38203344): The SDK_VERSION is set independently from Firebase because // we are doing out-of-band releases. Once we release as part of Firebase, we // should use the Firebase version instead. -const X_GOOG_API_CLIENT_VALUE = `gl-node/${process.versions.node} fire/${ - SDK_VERSION -} grpc/${grpcVersion}`; +const X_GOOG_API_CLIENT_VALUE = `gl-node/${ + process.versions.node +} fire/${SDK_VERSION} grpc/${grpcVersion}`; -type DuplexRpc = () => grpc.ClientDuplexStream; -type ReadableRpc = (req: Req) => grpc.ClientReadableStream; +type DuplexRpc = () => grpc.ClientDuplexStream; +type ReadableRpc = (req: Req) => grpc.ClientReadableStream; type UnaryRpc = ( req: Req, callback: (err?: grpc.ServiceError, resp?: Resp) => void @@ -135,7 +135,7 @@ export class GrpcConnection implements Connection { private getRpcCallable( rpcName: string, token: Token | null - ): UnaryRpc | ReadableRpc | DuplexRpc { + ): UnaryRpc | ReadableRpc | DuplexRpc { // RPC Methods have the first character lower-cased // (e.g. Listen => listen(), BatchGetDocuments => batchGetDocuments()). const rpcMethod = rpcName.charAt(0).toLowerCase() + rpcName.slice(1); @@ -182,7 +182,7 @@ export class GrpcConnection implements Connection { request: Req, token: Token | null ): Promise { - const rpc = this.getRpcCallable(rpcName, token) as ReadableRpc; + const rpc = this.getRpcCallable(rpcName, token) as ReadableRpc; const results = []; const responseDeferred = new Deferred(); @@ -214,7 +214,7 @@ export class GrpcConnection implements Connection { rpcName: string, token: Token | null ): Stream { - const rpc = this.getRpcCallable(rpcName, token) as DuplexRpc; + const rpc = this.getRpcCallable(rpcName, token) as DuplexRpc; const grpcStream = rpc(); let closed = false; diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index e563d084c7b..0fd3c6573fc 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -273,9 +273,7 @@ export abstract class PersistentStream< // rejections are not considered unhandled. assert( err.code === Code.CANCELLED, - `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${ - err - }` + `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${err}` ); }); } diff --git a/packages/firestore/src/util/input_validation.ts b/packages/firestore/src/util/input_validation.ts index 6d7701c760c..7ad47b8b078 100644 --- a/packages/firestore/src/util/input_validation.ts +++ b/packages/firestore/src/util/input_validation.ts @@ -191,11 +191,9 @@ export function validateNamedPropertyEquals( const actualDescription = valueDescription(input); throw new FirestoreError( Code.INVALID_ARGUMENT, - `Invalid value ${actualDescription} provided to function ${ - functionName - }() for option "${ - optionName - }". Acceptable values: ${expectedDescription.join(', ')}` + `Invalid value ${actualDescription} provided to function ${functionName}() for option "${optionName}". Acceptable values: ${expectedDescription.join( + ', ' + )}` ); } diff --git a/packages/firestore/test/integration/api/validation.test.ts b/packages/firestore/test/integration/api/validation.test.ts index 8bab7ff59fa..a9820691496 100644 --- a/packages/firestore/test/integration/api/validation.test.ts +++ b/packages/firestore/test/integration/api/validation.test.ts @@ -170,9 +170,7 @@ apiDescribe('Validation:', persistence => { const collection = db.collection('test-collection'); const doc = collection.doc('test-document'); for (const path of badPaths) { - const reason = `Invalid path (${ - path - }). Paths must not contain // in them.`; + const reason = `Invalid path (${path}). Paths must not contain // in them.`; expect(() => db.collection(path)).to.throw(reason); expect(() => db.doc(path)).to.throw(reason); expect(() => collection.doc(path)).to.throw(reason); diff --git a/packages/messaging-types/package.json b/packages/messaging-types/package.json index 2ebfabfb620..3fd6ab00c20 100644 --- a/packages/messaging-types/package.json +++ b/packages/messaging-types/package.json @@ -14,7 +14,7 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 1b40958b1f5..100dae7d4f9 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -18,29 +18,29 @@ "dependencies": { "@firebase/messaging-types": "0.1.1", "@firebase/util": "0.1.9", - "lcov-result-merger": "^1.2.0", + "lcov-result-merger": "^2.0.0", "tslib": "^1.9.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "karma": "^1.7.0", + "gulp": "^4.0.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", "karma-sourcemap-loader": "^0.3.7", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", "npm-run-all": "^4.1.1", - "sinon": "^4.0.2", + "sinon": "^4.3.0", "source-map-loader": "^0.2.3", - "ts-loader": "^3.1.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1" + "ts-loader": "^3.5.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" }, "repository": { "type": "git", diff --git a/packages/polyfill/package.json b/packages/polyfill/package.json index d35fd6df44d..14db9c43d5c 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -12,11 +12,11 @@ }, "license": "Apache-2.0", "dependencies": { - "promise-polyfill": "^6.0.2", + "promise-polyfill": "^7.1.0", "tslib": "^1.9.0" }, "devDependencies": { - "@types/node": "^8.0.47", + "@types/node": "^9.4.6", "gulp": "gulpjs/gulp#4.0" }, "repository": { diff --git a/packages/storage-types/package.json b/packages/storage-types/package.json index b71dfd10b3d..f3e49b7d400 100644 --- a/packages/storage-types/package.json +++ b/packages/storage-types/package.json @@ -14,7 +14,7 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/storage/package.json b/packages/storage/package.json index 5ab033a5afe..cb8b08316a6 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -21,25 +21,25 @@ "@firebase/app-types": "^0.1.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "karma": "^1.7.0", + "gulp": "^4.0.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", "karma-sourcemap-loader": "^0.3.7", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", "npm-run-all": "^4.1.1", - "sinon": "^4.0.2", + "sinon": "^4.3.0", "source-map-loader": "^0.2.3", - "ts-loader": "^3.1.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1" + "ts-loader": "^3.5.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" }, "repository": { "type": "git", diff --git a/packages/template-types/package.json b/packages/template-types/package.json index b93309c4856..da89c530245 100644 --- a/packages/template-types/package.json +++ b/packages/template-types/package.json @@ -12,7 +12,7 @@ "index.d.ts" ], "devDependencies": { - "typescript": "^2.4.2" + "typescript": "^2.7.2" }, "repository": { "type": "git", diff --git a/packages/template/package.json b/packages/template/package.json index 580e2f74ced..46c372c806a 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -24,25 +24,25 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "karma": "^1.7.0", + "gulp": "^4.0.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", - "mocha": "^4.0.1", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", + "mocha": "^5.0.1", "npm-run-all": "^4.1.1", - "nyc": "^11.2.1", - "ts-loader": "^3.1.0", - "ts-node": "^3.3.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1" + "nyc": "^11.4.1", + "ts-loader": "^3.5.0", + "ts-node": "^5.0.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" }, "repository": { "type": "git", diff --git a/packages/testing/package.json b/packages/testing/package.json index daaf16e214c..aa4c5a72256 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -14,14 +14,14 @@ }, "license": "Apache-2.0", "dependencies": { - "firebase-admin": "5.8.0", + "firebase-admin": "5.9.0", "request-promise": "^4.2.2" }, "devDependencies": { "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "mocha": "^4.0.1", - "nyc": "^11.2.1" + "gulp": "^4.0.0", + "mocha": "^5.0.1", + "nyc": "^11.4.1" }, "peerDependencies": { "@firebase/app": "^0.1.0", diff --git a/packages/util/package.json b/packages/util/package.json index a8d74456670..eb93061b41f 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -18,25 +18,25 @@ "tslib": "^1.9.0" }, "devDependencies": { - "@types/chai": "^4.0.4", - "@types/mocha": "^2.2.44", - "@types/sinon": "^2.3.7", + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", "chai": "^4.1.1", - "gulp": "gulpjs/gulp#4.0", - "karma": "^1.7.0", + "gulp": "^4.0.0", + "karma": "^2.0.0", "karma-chrome-launcher": "^2.2.0", "karma-cli": "^1.0.1", "karma-mocha": "^1.3.0", "karma-sauce-launcher": "^1.2.0", - "karma-spec-reporter": "^0.0.31", - "karma-webpack": "^2.0.4", - "mocha": "^4.0.1", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", + "mocha": "^5.0.1", "npm-run-all": "^4.1.1", - "nyc": "^11.2.1", - "ts-loader": "^3.1.0", - "ts-node": "^4.1.0", - "typescript": "^2.4.2", - "webpack": "^3.8.1" + "nyc": "^11.4.1", + "ts-loader": "^3.5.0", + "ts-node": "^5.0.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" }, "repository": { "type": "git", diff --git a/yarn.lock b/yarn.lock index 0f5a2499ffc..9bdd54e04b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,7 +8,7 @@ dependencies: acorn "^5.2.1" -"@google-cloud/common-grpc@^0.5.0": +"@google-cloud/common-grpc@^0.5.3": version "0.5.5" resolved "https://registry.npmjs.org/@google-cloud/common-grpc/-/common-grpc-0.5.5.tgz#ca805d7bbbcf47bbd82cf603e0386e963d6f5804" dependencies: @@ -24,7 +24,7 @@ "@google-cloud/common@^0.13.0": version "0.13.6" - resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.13.6.tgz#a9d8e137bc429a44aba9689fe6a0e4331784f853" + resolved "https://registry.npmjs.org/@google-cloud/common/-/common-0.13.6.tgz#a9d8e137bc429a44aba9689fe6a0e4331784f853" dependencies: array-uniq "^1.0.3" arrify "^1.0.1" @@ -45,7 +45,7 @@ string-format-obj "^1.1.0" through2 "^2.0.3" -"@google-cloud/common@^0.15.0": +"@google-cloud/common@^0.15.1": version "0.15.2" resolved "https://registry.npmjs.org/@google-cloud/common/-/common-0.15.2.tgz#d8b5ba80f16b60a0ca53fc80ead4ae8b2c2e5b4a" dependencies: @@ -91,51 +91,50 @@ string-format-obj "^1.1.0" through2 "^2.0.3" -"@google-cloud/firestore@^0.10.0": - version "0.10.2" - resolved "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-0.10.2.tgz#1b045064d5b061e83bdb1e4cfe8b2a96d0f9d64a" +"@google-cloud/firestore@^0.11.2": + version "0.11.2" + resolved "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-0.11.2.tgz#b511a1ec7a3b9df5cc453034b24391b0ccff9b1d" dependencies: - "@google-cloud/common" "^0.15.0" - "@google-cloud/common-grpc" "^0.5.0" + "@google-cloud/common" "^0.15.1" + "@google-cloud/common-grpc" "^0.5.3" bun "^0.0.12" extend "^3.0.1" functional-red-black-tree "^1.0.1" - google-gax "^0.14.1" - grpc "1.7.1" - is "^3.2.0" + google-gax "^0.14.3" + is "^3.2.1" safe-buffer "^5.1.1" through2 "^2.0.3" -"@google-cloud/functions-emulator@^1.0.0-alpha.23": - version "1.0.0-alpha.27" - resolved "https://registry.yarnpkg.com/@google-cloud/functions-emulator/-/functions-emulator-1.0.0-alpha.27.tgz#d2210a02bb4a09037de63a512e7d5a98c28123e7" +"@google-cloud/functions-emulator@1.0.0-alpha.23": + version "1.0.0-alpha.23" + resolved "https://registry.npmjs.org/@google-cloud/functions-emulator/-/functions-emulator-1.0.0-alpha.23.tgz#5f2916934a31369318dc81c23eb917a0400f6ead" dependencies: - "@google-cloud/storage" "1.4.0" + "@google-cloud/storage" "1.2.1" adm-zip "0.4.7" - ajv "5.3.0" - body-parser "1.18.2" + ajv "5.2.2" + body-parser "1.17.2" cli-table2 "0.2.0" colors "1.1.2" configstore "3.1.1" - express "4.16.2" - google-proto-files "0.14.1" - googleapis "22.2.0" + express "4.15.4" + google-proto-files "0.12.1" + googleapis "20.1.0" got "7.1.0" - grpc "1.7.1" + grpc "1.4.1" http-proxy "1.16.2" lodash "4.17.4" prompt "1.0.0" - rimraf "2.6.2" + rimraf "2.6.1" semver "5.4.1" serializerr "1.0.3" - tmp "0.0.33" + tmp "0.0.31" uuid "3.1.0" - winston "2.4.0" - yargs "10.0.3" + winston "2.3.1" + yargs "8.0.2" -"@google-cloud/storage@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-1.4.0.tgz#af5bcac2a986989c46f352b1ca1833be7b383ddb" +"@google-cloud/storage@1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@google-cloud/storage/-/storage-1.2.1.tgz#a0f2e20871b862f0ea64a90ac48fc08845cf9505" dependencies: "@google-cloud/common" "^0.13.0" arrify "^1.0.0" @@ -144,14 +143,12 @@ create-error-class "^3.0.2" duplexify "^3.5.0" extend "^3.0.0" - gcs-resumable-upload "^0.8.2" + gcs-resumable-upload "^0.8.0" hash-stream-validation "^0.2.1" is "^3.0.1" mime-types "^2.0.8" once "^1.3.1" pumpify "^1.3.3" - safe-buffer "^5.1.1" - snakeize "^0.1.0" stream-events "^1.0.1" string-format-obj "^1.0.0" through2 "^2.0.0" @@ -184,7 +181,7 @@ "@gulp-sourcemaps/identity-map@1.X": version "1.0.1" - resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz#cfa23bc5840f9104ce32a65e74db7e7a974bbee1" + resolved "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz#cfa23bc5840f9104ce32a65e74db7e7a974bbee1" dependencies: acorn "^5.0.3" css "^2.2.1" @@ -194,57 +191,63 @@ "@gulp-sourcemaps/map-sources@1.X": version "1.0.0" - resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" + resolved "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" dependencies: normalize-path "^2.0.1" through2 "^2.0.3" "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" "@protobufjs/base64@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" "@protobufjs/codegen@^2.0.4": version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" "@protobufjs/eventemitter@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" "@protobufjs/fetch@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" dependencies: "@protobufjs/aspromise" "^1.1.1" "@protobufjs/inquire" "^1.1.0" "@protobufjs/float@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" "@protobufjs/inquire@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" "@protobufjs/path@^1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" "@protobufjs/pool@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" "@protobufjs/utf8@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + +"@sinonjs/formatio@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" + dependencies: + samsam "1.3.0" -"@types/chai@^4.0.4": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.5.tgz#b6e250e281b47e0192e236619e9b1afe62fd345c" +"@types/chai@^4.1.2": + version "4.1.2" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21" "@types/google-cloud__storage@^1.1.1": version "1.1.7" @@ -252,86 +255,63 @@ dependencies: "@types/node" "*" -"@types/long@^3.0.31": +"@types/long@^3.0.32": version "3.0.32" - resolved "https://registry.yarnpkg.com/@types/long/-/long-3.0.32.tgz#f4e5af31e9e9b196d8e5fca8a5e2e20aa3d60b69" + resolved "https://registry.npmjs.org/@types/long/-/long-3.0.32.tgz#f4e5af31e9e9b196d8e5fca8a5e2e20aa3d60b69" -"@types/mocha@^2.2.44": - version "2.2.44" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e" +"@types/mocha@^2.2.48": + version "2.2.48" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab" -"@types/node@*": +"@types/node@*", "@types/node@^9.4.6": version "9.4.6" resolved "https://registry.npmjs.org/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e" "@types/node@^6.0.46": - version "6.0.92" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.92.tgz#e7f721ae282772e12ba2579968c00d9cce422c5d" - -"@types/node@^7.0.29": - version "7.0.48" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.48.tgz#24bfdc0aa82e8f6dbd017159c58094a2e06d0abb" + version "6.0.101" + resolved "https://registry.npmjs.org/@types/node/-/node-6.0.101.tgz#0c5911cfb434af4a51c0a499931fe6423207d921" -"@types/node@^8.0.47": - version "8.0.53" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" - -"@types/node@^8.0.53": +"@types/node@^8.0.53", "@types/node@^8.9.4": version "8.9.4" resolved "https://registry.npmjs.org/@types/node/-/node-8.9.4.tgz#dfd327582a06c114eb6e0441fa3d6fab35edad48" "@types/q@^0.0.32": version "0.0.32" - resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" + resolved "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" "@types/selenium-webdriver@^2.53.35", "@types/selenium-webdriver@~2.53.39": version "2.53.43" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz#2de3d718819bc20165754c4a59afb7e9833f6707" - -"@types/sinon@^2.3.7": - version "2.3.7" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-2.3.7.tgz#e92c2fed3297eae078d78d1da032b26788b4af86" + resolved "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz#2de3d718819bc20165754c4a59afb7e9833f6707" -"@types/strip-bom@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" - -"@types/strip-json-comments@0.0.30": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" +"@types/sinon@^4.1.3": + version "4.1.3" + resolved "https://registry.npmjs.org/@types/sinon/-/sinon-4.1.3.tgz#2ee25e0e302f31e78a945650a60029e08878eaf8" JSONStream@^1.0.3, JSONStream@^1.0.4, JSONStream@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" + version "1.3.2" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" 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" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" abbrev@1.0.x: version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - -accepts@1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" - dependencies: - mime-types "~2.1.11" - negotiator "0.6.1" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" -accepts@~1.3.4: +accepts@~1.3.3, accepts@~1.3.4: version "1.3.4" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" dependencies: mime-types "~2.1.16" negotiator "0.6.1" acorn-dynamic-import@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + resolved "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" dependencies: acorn "^4.0.3" @@ -345,66 +325,77 @@ acorn-jsx@^3.0.0: dependencies: acorn "^3.0.4" -acorn@4.X, acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" +acorn-node@^1.2.0: + version "1.3.0" + resolved "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz#5f86d73346743810ef1269b901dbcbded020861b" + dependencies: + acorn "^5.4.1" + xtend "^4.0.1" + +acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.2.1, acorn@^5.4.0, acorn@^5.4.1: + version "5.4.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz#fdc58d9d17f4a4e98d102ded826a9b9759125102" acorn@^3.0.4: version "3.3.0" resolved "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^5.0.0, acorn@^5.0.3: - version "5.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" - -acorn@^5.2.1, acorn@^5.4.0: - version "5.4.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz#fdc58d9d17f4a4e98d102ded826a9b9759125102" +acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4: + version "4.0.13" + resolved "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" add-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + +addressparser@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746" adm-zip@0.4.4: version "0.4.4" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.4.tgz#a61ed5ae6905c3aea58b3a657d25033091052736" + resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz#a61ed5ae6905c3aea58b3a657d25033091052736" adm-zip@0.4.7, adm-zip@^0.4.7, adm-zip@~0.4.3: version "0.4.7" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1" + resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1" after@0.8.2: version "0.8.2" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + resolved "https://registry.npmjs.org/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" agent-base@2: version "2.1.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" dependencies: extend "~3.0.0" semver "~5.0.1" -ajv-keywords@^2.0.0, ajv-keywords@^2.1.0: +ajv-keywords@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" -ajv@5.3.0, ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" +ajv-keywords@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" + +ajv@5.2.2: + version "5.2.2" + resolved "https://registry.npmjs.org/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" ajv@^4.9.1: version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + resolved "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.2.3, ajv@^5.3.0: +ajv@^5.0.0, ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -413,86 +404,141 @@ ajv@^5.2.3, ajv@^5.3.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^6.1.0: + version "6.1.1" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz#978d597fbc2b7d0e5a5c3ddeb149a682f2abfa0e" + dependencies: + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + 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" + resolved "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" dependencies: kind-of "^3.0.2" longest "^1.0.1" repeat-string "^1.5.2" -amdefine@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.0.tgz#fd17474700cb5cc9c2b709f0be9d23ce3c198c33" - amdefine@>=0.0.4, amdefine@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +amqplib@^0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz#d2d7313c7ffaa4d10bcf1e6252de4591b6cc7b63" + dependencies: + bitsyntax "~0.0.4" + bluebird "^3.4.6" + buffer-more-ints "0.0.2" + readable-stream "1.x >=1.1.9" + safe-buffer "^5.0.1" ansi-align@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-1.1.0.tgz#2f0c1658829739add5ebb15e6b0c6e3423f016ba" + resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz#2f0c1658829739add5ebb15e6b0c6e3423f016ba" dependencies: string-width "^1.0.1" +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + dependencies: + ansi-wrap "^0.1.0" + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + dependencies: + ansi-wrap "0.1.0" + ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" ansi-escapes@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + dependencies: + ansi-wrap "0.1.0" ansi-html@0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + resolved "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + dependencies: + ansi-wrap "0.1.0" ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" ansi-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" ansi-styles@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.1.0, ansi-styles@^3.2.0: +ansi-styles@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" dependencies: color-convert "^1.9.0" +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + any-observable@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" any-promise@^1.0.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" anymatch@^1.3.0: version "1.3.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" dependencies: micromatch "^2.1.5" normalize-path "^2.0.0" +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + dependencies: + buffer-equal "^1.0.0" + append-transform@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + resolved "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" dependencies: default-require-extensions "^1.0.0" -aproba@^1.0.3: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" archiver-utils@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" + resolved "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" dependencies: glob "^7.0.0" graceful-fs "^4.1.0" @@ -503,7 +549,7 @@ archiver-utils@^1.3.0: archiver@1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-1.3.0.tgz#4f2194d6d8f99df3f531e6881f14f15d55faaf22" + resolved "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz#4f2194d6d8f99df3f531e6881f14f15d55faaf22" dependencies: archiver-utils "^1.3.0" async "^2.0.0" @@ -515,9 +561,9 @@ archiver@1.3.0: walkdir "^0.0.11" zip-stream "^1.1.0" -archiver@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-2.1.0.tgz#d2df2e8d5773a82c1dcce925ccc41450ea999afd" +archiver@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz#ff662b4a78201494a3ee544d3a33fe7496509ebc" dependencies: archiver-utils "^1.3.0" async "^2.0.0" @@ -530,54 +576,73 @@ archiver@^2.1.0: archy@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + resolved "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" are-we-there-yet@~1.1.2: version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" dependencies: delegates "^1.0.0" readable-stream "^2.0.6" argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" dependencies: sprintf-js "~1.0.2" arguejs@^0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/arguejs/-/arguejs-0.2.3.tgz#b6f939f5fe0e3cd1f3f93e2aa9262424bf312af7" + resolved "https://registry.npmjs.org/arguejs/-/arguejs-0.2.3.tgz#b6f939f5fe0e3cd1f3f93e2aa9262424bf312af7" + +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" arr-diff@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" dependencies: arr-flatten "^1.0.1" +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + arr-filter@^1.1.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + resolved "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" dependencies: make-iterator "^1.0.0" -arr-flatten@^1.0.1: +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" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" arr-map@^2.0.0, arr-map@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + resolved "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" dependencies: make-iterator "^1.0.0" +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + array-differ@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + resolved "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" array-each@^1.0.0, array-each@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + resolved "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" array-filter@^1.0.0: version "1.0.0" @@ -585,85 +650,97 @@ array-filter@^1.0.0: array-filter@~0.0.0: version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + resolved "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" 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" + resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" array-flatten@1.1.1, array-flatten@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" array-flatten@2.1.1, array-flatten@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" array-ify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + resolved "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" array-includes@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" dependencies: define-properties "^1.1.2" es-abstract "^1.7.0" array-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.0.1.tgz#86122222a29c1ed42347f6334111afa40f8b20ec" + version "1.1.0" + resolved "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" dependencies: array-slice "^1.0.0" - is-number "^3.0.0" + is-number "^4.0.0" array-last@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.2.0.tgz#0884a67ec2ac2a08133fc00f66779cfedb010986" + version "1.3.0" + resolved "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" dependencies: - is-number "^3.0.0" + is-number "^4.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" + resolved "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" array-reduce@~0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + resolved "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" array-slice@^0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + resolved "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + +array-sort@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.0.0.tgz#e73034f00dcc1f40876008fd20feae77bd4b7c2f" + resolved "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" array-union@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" dependencies: array-uniq "^1.0.1" array-uniq@^1.0.1, array-uniq@^1.0.2, array-uniq@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" array-unique@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" -arraybuffer.slice@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" as-array@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/as-array/-/as-array-1.0.0.tgz#28a6eeeaa5729f1f4eca2047df5e9de1abda0ed1" + resolved "https://registry.npmjs.org/as-array/-/as-array-1.0.0.tgz#28a6eeeaa5729f1f4eca2047df5e9de1abda0ed1" dependencies: lodash.isarguments "2.4.x" lodash.isobject "^2.4.1" @@ -671,18 +748,18 @@ as-array@^1.0.0: as-array@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/as-array/-/as-array-2.0.0.tgz#4f04805d87f8fce8e511bc2108f8e5e3a287d547" + resolved "https://registry.npmjs.org/as-array/-/as-array-2.0.0.tgz#4f04805d87f8fce8e511bc2108f8e5e3a287d547" ascli@~1: version "1.0.1" - resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc" + resolved "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc" dependencies: colour "~0.7.1" optjs "~3.2.2" asn1.js@^4.0.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a" + version "4.10.1" + resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" dependencies: bn.js "^4.0.0" inherits "^2.0.1" @@ -690,35 +767,43 @@ asn1.js@^4.0.0: asn1@~0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" 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" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" assert-plus@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" assert@^1.1.1, assert@^1.4.0, assert@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + resolved "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" dependencies: util "0.10.3" assertion-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + version "1.1.0" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +ast-types@0.x.x: + version "0.11.1" + resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.11.1.tgz#5bb3a8d5ba292c3f4ae94d46df37afc30300b990" astw@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/astw/-/astw-2.2.0.tgz#7bd41784d32493987aeb239b6b4e1c57a873b917" + resolved "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz#7bd41784d32493987aeb239b6b4e1c57a873b917" dependencies: acorn "^4.0.3" async-done@^1.2.0, async-done@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.2.3.tgz#6c7abc7d61ca27fe6f1f2ba3206ea9ae60a43983" + version "1.2.4" + resolved "https://registry.npmjs.org/async-done/-/async-done-1.2.4.tgz#17b0fcefb9a33cb9de63daa8904c0a65bd535fa0" dependencies: end-of-stream "^1.1.0" once "^1.3.2" @@ -727,89 +812,110 @@ async-done@^1.2.0, async-done@^1.2.2: async-each@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" async-settle@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + resolved "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" dependencies: async-done "^1.2.2" async@0.2.x: version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" async@0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" + resolved "https://registry.npmjs.org/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" async@1.x, async@^1.3.0, async@^1.4.0, async@^1.5.0, async@^1.5.2: version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + resolved "https://registry.npmjs.org/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" async@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.0.1.tgz#b709cc0280a9c36f09f4536be823c838a9049e25" + resolved "https://registry.npmjs.org/async/-/async-2.0.1.tgz#b709cc0280a9c36f09f4536be823c838a9049e25" dependencies: lodash "^4.8.0" -async@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" - dependencies: - lodash "^4.14.0" - -async@^2.0.0, async@^2.0.1, async@^2.1.2, async@^2.1.4, async@^2.3.0, async@^2.4.0, async@^2.5.0: +async@^2.0.0, async@^2.0.1, async@^2.1.2, async@^2.1.4, async@^2.3.0, async@^2.4.0, async@^2.4.1, async@^2.5.0: version "2.6.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + resolved "https://registry.npmjs.org/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" dependencies: lodash "^4.14.0" async@~0.9.0: version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + resolved "https://registry.npmjs.org/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" + resolved "https://registry.npmjs.org/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + +async@~2.1.2: + version "2.1.5" + resolved "https://registry.npmjs.org/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + dependencies: + lodash "^4.14.0" async@~2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" + resolved "https://registry.npmjs.org/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9" dependencies: lodash "^4.14.0" asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +atob@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d" atob@~1.1.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773" + resolved "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773" aws-sign2@~0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" aws-sign2@~0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +axios@^0.15.3: + version "0.15.3" + resolved "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053" + dependencies: + follow-redirects "1.0.0" + +axios@^0.17.1: + version "0.17.1" + resolved "https://registry.npmjs.org/axios/-/axios-0.17.1.tgz#2d8e3e5d0bdbd7327f91bc814f5c57660f81824d" + dependencies: + follow-redirects "^1.2.5" + is-buffer "^1.1.5" babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: chalk "^1.1.3" esutils "^2.0.2" js-tokens "^3.0.2" babel-generator@^6.18.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + version "6.26.1" + resolved "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" dependencies: babel-messages "^6.23.0" babel-runtime "^6.26.0" @@ -817,25 +923,25 @@ babel-generator@^6.18.0: detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.17.4" - source-map "^0.5.6" + source-map "^0.5.7" trim-right "^1.0.1" babel-messages@^6.23.0: version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" dependencies: babel-runtime "^6.22.0" babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" babel-template@^6.16.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" dependencies: babel-runtime "^6.26.0" babel-traverse "^6.26.0" @@ -845,7 +951,7 @@ babel-template@^6.16.0: babel-traverse@^6.18.0, babel-traverse@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" dependencies: babel-code-frame "^6.26.0" babel-messages "^6.23.0" @@ -859,7 +965,7 @@ babel-traverse@^6.18.0, babel-traverse@^6.26.0: babel-types@^6.18.0, babel-types@^6.26.0: version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" dependencies: babel-runtime "^6.26.0" esutils "^2.0.2" @@ -868,11 +974,11 @@ babel-types@^6.18.0, babel-types@^6.26.0: babylon@^6.18.0: version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" bach@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + resolved "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" dependencies: arr-filter "^1.1.1" arr-flatten "^1.0.1" @@ -886,111 +992,150 @@ bach@^1.0.0: backo2@1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + resolved "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" balanced-match@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" base64-arraybuffer@0.1.5: version "0.1.5" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" base64-js@0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" -base64-js@^1.0.2, base64-js@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" +base64-js@^1.0.2: + version "1.2.3" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801" base64id@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + resolved "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" base64url@2.0.0, base64url@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb" + resolved "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + 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" + resolved "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz#fdb0b43962ca7b40456a7c2bb48fe173da2d2122" basic-auth@~2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba" + resolved "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz#015db3f353e02e56377755f962742e8981e7bbba" dependencies: safe-buffer "5.1.1" batch@0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" bcrypt-pbkdf@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" dependencies: tweetnacl "^0.14.3" beeper@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + resolved "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" better-assert@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + resolved "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" dependencies: callsite "1.0.0" big.js@^3.1.3: version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + resolved "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" binary-extensions@^1.0.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0" + version "1.11.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" binaryextensions@~1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-1.0.1.tgz#1e637488b35b58bda5f4774bf96a5212a8c90755" + resolved "https://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz#1e637488b35b58bda5f4774bf96a5212a8c90755" + +bitsyntax@~0.0.4: + version "0.0.4" + resolved "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz#eb10cc6f82b8c490e3e85698f07e83d46e0cba82" + dependencies: + buffer-more-ints "0.0.2" bl@^1.0.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" + resolved "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" dependencies: readable-stream "^2.0.5" +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + dependencies: + readable-stream "~2.0.5" + blob@0.0.4: version "0.0.4" - resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" + resolved "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" block-stream@*: version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + resolved "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" dependencies: inherits "~2.0.0" -blocking-proxy@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/blocking-proxy/-/blocking-proxy-0.0.5.tgz#462905e0dcfbea970f41aa37223dda9c07b1912b" +blocking-proxy@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz#81d6fd1fe13a4c0d6957df7f91b75e98dac40cb2" dependencies: minimist "^1.2.0" bluebird@3.4.6: version "3.4.6" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" -bluebird@^3.3.0, bluebird@^3.5.0: +bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1: version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 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" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + +body-parser@1.17.2: + version "1.17.2" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" + dependencies: + bytes "2.4.0" + content-type "~1.0.2" + debug "2.6.7" + depd "~1.1.0" + http-errors "~1.6.1" + iconv-lite "0.4.15" + on-finished "~2.3.0" + qs "6.4.0" + raw-body "~2.2.0" + type-is "~1.6.15" body-parser@1.18.2, body-parser@^1.16.1: version "1.18.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" dependencies: bytes "3.0.0" content-type "~1.0.4" @@ -1005,7 +1150,7 @@ body-parser@1.18.2, body-parser@^1.16.1: bonjour@^3.5.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + resolved "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" dependencies: array-flatten "^2.1.0" deep-equal "^1.0.1" @@ -1016,25 +1161,25 @@ bonjour@^3.5.0: boom@2.x.x: version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + resolved "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" dependencies: hoek "2.x.x" boom@4.x.x: version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + resolved "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" dependencies: hoek "4.x.x" boom@5.x.x: version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + resolved "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" dependencies: hoek "4.x.x" boxen@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.6.0.tgz#8364d4248ac34ff0ef1b2f2bf49a6c60ce0d81b6" + resolved "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz#8364d4248ac34ff0ef1b2f2bf49a6c60ce0d81b6" dependencies: ansi-align "^1.1.0" camelcase "^2.1.0" @@ -1047,53 +1192,71 @@ boxen@^0.6.0: widest-line "^1.0.0" brace-expansion@^1.0.0, brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" braces@^0.1.2: version "0.1.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" + resolved "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" dependencies: expand-range "^0.1.0" braces@^1.8.2: version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + resolved "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" dependencies: expand-range "^1.8.1" preserve "^0.2.0" repeat-element "^1.1.2" +braces@^2.3.0, braces@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + define-property "^1.0.0" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + kind-of "^6.0.2" + 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" + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" browser-pack@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531" + version "6.0.4" + resolved "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz#9a73beb3b48f9e36868be007b64400102c04a99f" dependencies: JSONStream "^1.0.3" - combine-source-map "~0.7.1" + combine-source-map "~0.8.0" defined "^1.0.0" + safe-buffer "^5.1.1" through2 "^2.0.0" umd "^3.0.0" browser-resolve@^1.11.0, browser-resolve@^1.7.0: version "1.11.2" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + resolved "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" 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" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.1.1" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" + resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" dependencies: buffer-xor "^1.0.3" cipher-base "^1.0.0" @@ -1104,7 +1267,7 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: browserify-cipher@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" + resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" dependencies: browserify-aes "^1.0.4" browserify-des "^1.0.0" @@ -1112,7 +1275,7 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" + resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" dependencies: cipher-base "^1.0.1" des.js "^1.0.0" @@ -1120,14 +1283,14 @@ browserify-des@^1.0.0: browserify-rsa@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" 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" + resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" dependencies: bn.js "^4.1.1" browserify-rsa "^4.0.0" @@ -1139,13 +1302,13 @@ browserify-sign@^4.0.0: browserify-zlib@^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" + resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" dependencies: pako "~1.0.5" browserify@^14.5.0: version "14.5.0" - resolved "https://registry.yarnpkg.com/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" + resolved "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz#0bbbce521acd6e4d1d54d8e9365008efb85a9cc5" dependencies: JSONStream "^1.0.3" assert "^1.4.0" @@ -1195,7 +1358,7 @@ browserify@^14.5.0: vm-browserify "~0.0.1" xtend "^4.0.0" -browserify@^16.0.0: +browserify@^16.0.0, browserify@^16.1.0: version "16.1.0" resolved "https://registry.npmjs.org/browserify/-/browserify-16.1.0.tgz#00b86844f89482bbd0d5d1b584b324762ef3f698" dependencies: @@ -1250,27 +1413,31 @@ browserify@^16.0.0: buffer-crc32@^0.2.1, buffer-crc32@~0.2.3: version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" buffer-equal-constant-time@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" buffer-equal@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" buffer-indexof@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + resolved "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + +buffer-more-ints@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz#26b3885d10fa13db7fc01aae3aab870199e0124c" buffer-xor@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" buffer@^3.0.1: version "3.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb" + resolved "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz#a72c936f77b96bf52f5f7e7b467180628551defb" dependencies: base64-js "0.0.8" ieee754 "^1.1.4" @@ -1278,26 +1445,38 @@ buffer@^3.0.1: buffer@^4.3.0: version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" isarray "^1.0.0" buffer@^5.0.2, buffer@^5.0.6: - version "5.0.8" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.8.tgz#84daa52e7cf2fa8ce4195bc5cf0f7809e0930b24" + version "5.1.0" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe" dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" +buildmail@4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz#877f7738b78729871c9a105e3b837d2be11a7a72" + dependencies: + addressparser "1.0.1" + libbase64 "0.1.0" + libmime "3.0.0" + libqp "1.1.0" + nodemailer-fetch "1.6.0" + nodemailer-shared "1.1.0" + punycode "1.4.1" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 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" + resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" bun@^0.0.12: version "0.0.12" @@ -1307,25 +1486,61 @@ bun@^0.0.12: byline@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + resolved "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" bytebuffer@~5: version "5.0.1" - resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" + resolved "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" dependencies: long "~3" +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + bytes@3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + +cacache@^10.0.1: + version "10.0.4" + resolved "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + 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.1" - resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7" + resolved "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7" caching-transform@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + resolved "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" dependencies: md5-hex "^1.2.0" mkdirp "^0.5.1" @@ -1343,7 +1558,7 @@ caller-path@^0.1.0: callsite@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + resolved "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" callsites@^0.2.0: version "0.2.0" @@ -1351,49 +1566,49 @@ callsites@^0.2.0: camelcase-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" dependencies: camelcase "^2.0.0" map-obj "^1.0.0" camelcase@^1.0.2: version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" camelcase@^2.0.0, camelcase@^2.0.1, camelcase@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" camelcase@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" camelcase@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" capture-stack-trace@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + resolved "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" caseless@~0.11.0: version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" caseless@~0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" center-align@^0.1.1: version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + resolved "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" dependencies: align-text "^0.1.3" lazy-cache "^1.0.3" chai@^4.1.1: version "4.1.2" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + resolved "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" dependencies: assertion-error "^1.0.1" check-error "^1.0.1" @@ -1404,7 +1619,7 @@ chai@^4.1.1: chalk@^1.0.0, 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" + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1412,17 +1627,17 @@ 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.0, chalk@^2.1.0, chalk@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" dependencies: - ansi-styles "^3.1.0" + ansi-styles "^3.2.0" escape-string-regexp "^1.0.5" - supports-color "^4.0.0" + supports-color "^5.2.0" char-spinner@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081" + resolved "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081" chardet@^0.4.0: version "0.4.2" @@ -1430,19 +1645,19 @@ chardet@^0.4.0: check-error@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" child-process-promise@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" + resolved "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" dependencies: cross-spawn "^4.0.2" node-version "^1.0.0" promise-polyfill "^6.0.1" -chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.0, chokidar@^1.7.0: +chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: anymatch "^1.3.0" async-each "^1.0.0" @@ -1455,13 +1670,31 @@ chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.0, chokidar@^1.7.0: optionalDependencies: fsevents "^1.0.0" +chokidar@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.0" + optionalDependencies: + fsevents "^1.0.0" + chownr@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" -chromedriver@^2.31.0: - version "2.33.2" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.33.2.tgz#8fc779d54b6e45bef55d264a1eceed52427a9b49" +chromedriver@^2.35.0: + version "2.35.0" + resolved "https://registry.npmjs.org/chromedriver/-/chromedriver-2.35.0.tgz#c103ba2fb3d1671f666058159f5cbaa816902e4d" dependencies: del "^3.0.0" extract-zip "^1.6.5" @@ -1470,12 +1703,12 @@ chromedriver@^2.31.0: request "^2.83.0" ci-info@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.1.tgz#47b44df118c48d2597b56d342e7e25791060171a" + version "1.1.2" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" 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" + resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" @@ -1484,45 +1717,58 @@ circular-json@^0.3.1: version "0.3.3" resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" +circular-json@^0.5.1: + version "0.5.1" + resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.5.1.tgz#b8942a09e535863dc21b04417a91971e1d9cd91f" + cjson@^0.3.1: version "0.3.3" - resolved "https://registry.yarnpkg.com/cjson/-/cjson-0.3.3.tgz#a92d9c786e5bf9b930806329ee05d5d3261b4afa" + resolved "https://registry.npmjs.org/cjson/-/cjson-0.3.3.tgz#a92d9c786e5bf9b930806329ee05d5d3261b4afa" dependencies: json-parse-helpfulerror "^1.0.3" +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + clean-css@^4.1.9: version "4.1.9" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.9.tgz#35cee8ae7687a49b98034f70de00c4edd3826301" + resolved "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz#35cee8ae7687a49b98034f70de00c4edd3826301" dependencies: source-map "0.5.x" cli-boxes@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" cli-cursor@^1.0.1, cli-cursor@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" dependencies: restore-cursor "^1.0.1" cli-cursor@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: restore-cursor "^2.0.0" cli-spinners@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" -cli-spinners@^1.0.0: +cli-spinners@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06" cli-table2@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97" + resolved "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz#2d1ef7f218a0e786e214540562d4bd177fe32d97" dependencies: lodash "^3.10.1" string-width "^1.0.1" @@ -1531,7 +1777,7 @@ cli-table2@0.2.0: cli-table@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + resolved "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" dependencies: colors "1.0.3" @@ -1544,11 +1790,11 @@ cli-truncate@^0.2.1: cli-width@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" cliui@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + resolved "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" dependencies: center-align "^0.1.1" right-align "^0.1.1" @@ -1556,39 +1802,47 @@ cliui@^2.1.0: cliui@^3.0.3, cliui@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + resolved "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + clone-buffer@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + resolved "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" clone-stats@^0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + resolved "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" clone-stats@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + resolved "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" clone@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + resolved "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" clone@^1.0.0, clone@^1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + resolved "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" clone@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + resolved "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" cloneable-readable@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" + resolved "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" dependencies: inherits "^2.0.1" process-nextick-args "^1.0.6" @@ -1620,69 +1874,80 @@ closure-builder@^2.0.17, closure-builder@^2.2.29: cmd-shim@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" dependencies: graceful-fs "^4.1.2" mkdirp "~0.5.0" co@^4.6.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +co@~3.0.6: + version "3.0.6" + resolved "https://registry.npmjs.org/co/-/co-3.0.6.tgz#1445f226c5eb956138e68c9ac30167ea7d2e6bda" 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" - -coffee-script@^1.12.7: - version "1.12.7" - resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" collection-map@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + resolved "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" dependencies: arr-map "^2.0.2" for-own "^1.0.0" make-iterator "^1.0.0" +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + color-convert@^1.9.0: version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" dependencies: color-name "^1.1.1" color-name@^1.1.1: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" colors@1.0.3, colors@1.0.x: version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" colors@1.1.2, colors@^1.1.0, colors@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + resolved "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" colour@~0.7.1: version "0.7.1" - resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" + resolved "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" columnify@^1.5.4: version "1.5.4" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + resolved "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" dependencies: strip-ansi "^3.0.0" wcwidth "^1.0.0" combine-lists@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" + resolved "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" dependencies: lodash "^4.5.0" -combine-source-map@^0.8.0: +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" + resolved "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b" dependencies: convert-source-map "~1.1.0" inline-source-map "~0.6.0" @@ -1691,95 +1956,98 @@ combine-source-map@^0.8.0: combine-source-map@~0.7.1: version "0.7.2" - resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e" + resolved "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e" dependencies: convert-source-map "~1.1.0" inline-source-map "~0.6.0" lodash.memoize "~3.0.3" source-map "~0.5.3" -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" +combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.6" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" dependencies: delayed-stream "~1.0.0" command-join@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf" + resolved "https://registry.npmjs.org/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf" -commander@2.11.0, commander@^2.8.1, commander@^2.9.0: +commander@2.11.0: version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + resolved "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +commander@^2.12.1, commander@^2.8.1, commander@^2.9.0: + version "2.14.1" + resolved "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" commander@~2.8.1: version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + resolved "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" dependencies: graceful-readlink ">= 1.0.0" commondir@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" compare-func@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + resolved "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" dependencies: array-ify "^1.0.0" dot-prop "^3.0.0" compare-semver@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/compare-semver/-/compare-semver-1.1.0.tgz#7c0a79a27bb80b6c6994445f82958259d3d02153" + resolved "https://registry.npmjs.org/compare-semver/-/compare-semver-1.1.0.tgz#7c0a79a27bb80b6c6994445f82958259d3d02153" dependencies: semver "^5.0.1" component-bind@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + resolved "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" -component-emitter@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3" - -component-emitter@1.2.1: +component-emitter@1.2.1, component-emitter@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" component-inherit@0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + resolved "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" compress-commons@^1.2.0: version "1.2.2" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" + resolved "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" dependencies: buffer-crc32 "^0.2.1" crc32-stream "^2.0.0" normalize-path "^2.0.0" readable-stream "^2.0.0" -compressible@^2.0.12, compressible@~2.0.11: - version "2.0.12" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66" +compressible@^2.0.12, compressible@~2.0.13: + version "2.0.13" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9" dependencies: - mime-db ">= 1.30.0 < 2" + mime-db ">= 1.33.0 < 2" -compression-webpack-plugin@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-1.0.1.tgz#7f0a2af9f642b4f87b5989516a3b9e9b41bb4b3f" +compression-webpack-plugin@^1.1.7: + version "1.1.7" + resolved "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-1.1.7.tgz#b0dfb97cf1d26baab997b584b8c36fe91872abe2" dependencies: - async "2.4.1" + async "^2.4.1" + cacache "^10.0.1" + find-cache-dir "^1.0.0" + serialize-javascript "^1.4.0" webpack-sources "^1.0.1" compression@^1.5.2, compression@^1.7.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.1.tgz#eff2603efc2e22cf86f35d2eb93589f9875373db" + version "1.7.2" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.2.tgz#aaffbcd6aaf854b44ebb280353d5ad1651f59a69" dependencies: accepts "~1.3.4" bytes "3.0.0" - compressible "~2.0.11" + compressible "~2.0.13" debug "2.6.9" on-headers "~1.0.1" safe-buffer "5.1.1" @@ -1787,11 +2055,11 @@ compression@^1.5.2, compression@^1.7.0: concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" concat-stream@1.6.0, concat-stream@^1.4.10, concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@~1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: inherits "^2.0.3" readable-stream "^2.2.2" @@ -1799,21 +2067,21 @@ concat-stream@1.6.0, concat-stream@^1.4.10, concat-stream@^1.5.0, concat-stream@ 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" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" dependencies: inherits "~2.0.1" readable-stream "~2.0.0" typedarray "~0.0.5" concat-with-sourcemaps@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz#f55b3be2aeb47601b10a2d5259ccfb70fd2f1dd6" + version "1.0.5" + resolved "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.5.tgz#8964bc2347d05819b63798104d87d6e001bed8d0" dependencies: - source-map "^0.5.1" + source-map "^0.6.1" configstore@3.1.1, configstore@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" + resolved "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" dependencies: dot-prop "^4.1.0" graceful-fs "^4.1.2" @@ -1824,7 +2092,7 @@ configstore@3.1.1, configstore@^3.0.0: configstore@^1.0.0, configstore@^1.2.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021" + resolved "https://registry.npmjs.org/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021" dependencies: graceful-fs "^4.1.2" mkdirp "^0.5.0" @@ -1837,7 +2105,7 @@ configstore@^1.0.0, configstore@^1.2.0: configstore@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" + resolved "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" dependencies: dot-prop "^3.0.0" graceful-fs "^4.1.2" @@ -1851,85 +2119,85 @@ configstore@^2.0.0: connect-history-api-fallback@^1.3.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a" + resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a" connect-query@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/connect-query/-/connect-query-1.0.0.tgz#de44f577209da2404d1fc04692d1a4118e582119" + resolved "https://registry.npmjs.org/connect-query/-/connect-query-1.0.0.tgz#de44f577209da2404d1fc04692d1a4118e582119" dependencies: qs "~6.4.0" connect@^3.6.0, connect@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.5.tgz#fb8dde7ba0763877d0ec9df9dac0b4b40e72c7da" + version "3.6.6" + resolved "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" dependencies: debug "2.6.9" - finalhandler "1.0.6" + finalhandler "1.1.0" parseurl "~1.3.2" utils-merge "1.0.1" console-browserify@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" 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" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" constants-browserify@^1.0.0, constants-browserify@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" content-disposition@0.5.2: version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" -content-type@~1.0.4: +content-type@~1.0.2, content-type@~1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" -conventional-changelog-angular@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.5.2.tgz#2b38f665fe9c5920af1a2f82f547f4babe6de57c" +conventional-changelog-angular@^1.6.5: + version "1.6.5" + resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.5.tgz#936249e897501affdffc6043da45cab59d6f0907" dependencies: compare-func "^1.3.1" q "^1.4.1" -conventional-changelog-atom@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-0.1.2.tgz#12595ad5267a6937c34cf900281b1c65198a4c63" +conventional-changelog-atom@^0.2.3: + version "0.2.3" + resolved "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.2.3.tgz#117d024e5cf9e28dcbd0575981105395be1bca74" dependencies: q "^1.4.1" -conventional-changelog-cli@^1.3.2: - version "1.3.5" - resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-1.3.5.tgz#46c51496216b7406588883defa6fac589e9bb31e" +conventional-changelog-cli@^1.3.13: + version "1.3.14" + resolved "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.14.tgz#2560f640929baf97bb65457f77a12a57d5322852" dependencies: add-stream "^1.0.0" - conventional-changelog "^1.1.7" + conventional-changelog "^1.1.16" lodash "^4.1.0" meow "^3.7.0" tempfile "^1.1.1" -conventional-changelog-codemirror@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.2.1.tgz#299a4f7147baf350e6c8158fc54954a291c5cc09" +conventional-changelog-codemirror@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.3.tgz#e1ec78e77e7fe26a2bd18e32f02523527916a07b" dependencies: q "^1.4.1" -conventional-changelog-core@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-1.9.3.tgz#2899fe779389a329f0ec4b2746c36ddefb98da2d" +conventional-changelog-core@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.4.tgz#bbc476109c6b28ba6328b0b417f5ab5bfc7ca28a" dependencies: - conventional-changelog-writer "^2.0.2" - conventional-commits-parser "^2.0.1" + conventional-changelog-writer "^3.0.3" + conventional-commits-parser "^2.1.4" dateformat "^1.0.12" get-pkg-repo "^1.0.0" - git-raw-commits "^1.3.0" + git-raw-commits "^1.3.3" git-remote-origin-url "^2.0.0" - git-semver-tags "^1.2.3" + git-semver-tags "^1.3.3" lodash "^4.0.0" normalize-package-data "^2.3.5" q "^1.4.1" @@ -1937,49 +2205,53 @@ conventional-changelog-core@^1.9.3: read-pkg-up "^1.0.1" through2 "^2.0.0" -conventional-changelog-ember@^0.2.9: - version "0.2.9" - resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-0.2.9.tgz#8ec73cc054e3ab064667fb1feb52fe8ef1b16438" +conventional-changelog-ember@^0.3.5: + version "0.3.5" + resolved "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.5.tgz#db9a23f01103c6a0446ed2077ed5c87656d0571a" dependencies: q "^1.4.1" -conventional-changelog-eslint@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-0.2.1.tgz#2c2a11beb216f80649ba72834180293b687c0662" +conventional-changelog-eslint@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.3.tgz#023002a3f776266c501e4d4def7b0bb24130f29d" dependencies: q "^1.4.1" -conventional-changelog-express@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-0.2.1.tgz#838d9e1e6c9099703b150b9c19aa2d781742bd6c" +conventional-changelog-express@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.3.3.tgz#25aef42a30b5457f97681a94f2ac9b0ee515484a" dependencies: q "^1.4.1" conventional-changelog-jquery@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510" + resolved "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510" dependencies: q "^1.4.1" conventional-changelog-jscs@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c" + resolved "https://registry.npmjs.org/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c" dependencies: q "^1.4.1" -conventional-changelog-jshint@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-0.2.1.tgz#86139bb3ac99899f2b177e9617e09b37d99bcf3a" +conventional-changelog-jshint@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.3.tgz#28b6fe4d41fb945f38c6c31cd195fe37594f0007" dependencies: compare-func "^1.3.1" q "^1.4.1" -conventional-changelog-writer@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-2.0.2.tgz#b5857ded1b001daf9a78b9cd40926f45c134949b" +conventional-changelog-preset-loader@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.5.tgz#d5af525d7ad81179d9b54137284d74d665997fa7" + +conventional-changelog-writer@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-3.0.3.tgz#2faa65739370769639fff1c0008722162936d46c" dependencies: compare-func "^1.3.1" - conventional-commits-filter "^1.1.0" + conventional-commits-filter "^1.1.4" dateformat "^1.0.11" handlebars "^4.0.2" json-stringify-safe "^5.0.1" @@ -1989,31 +2261,32 @@ conventional-changelog-writer@^2.0.2: split "^1.0.0" through2 "^2.0.0" -conventional-changelog@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.7.tgz#9151a62b1d8edb2d82711dabf5b7cf71041f82b1" - dependencies: - conventional-changelog-angular "^1.5.2" - conventional-changelog-atom "^0.1.2" - conventional-changelog-codemirror "^0.2.1" - conventional-changelog-core "^1.9.3" - conventional-changelog-ember "^0.2.9" - conventional-changelog-eslint "^0.2.1" - conventional-changelog-express "^0.2.1" +conventional-changelog@^1.1.16: + version "1.1.16" + resolved "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.16.tgz#fa78386c831f5b1ae45f60391ef015c2a4a400b9" + dependencies: + conventional-changelog-angular "^1.6.5" + conventional-changelog-atom "^0.2.3" + conventional-changelog-codemirror "^0.3.3" + conventional-changelog-core "^2.0.4" + conventional-changelog-ember "^0.3.5" + conventional-changelog-eslint "^1.0.3" + conventional-changelog-express "^0.3.3" conventional-changelog-jquery "^0.1.0" conventional-changelog-jscs "^0.1.0" - conventional-changelog-jshint "^0.2.1" + conventional-changelog-jshint "^0.3.3" + conventional-changelog-preset-loader "^1.1.5" -conventional-commits-filter@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-1.1.0.tgz#1fc29af30b5edab76f54e229c411b0c663d0f9eb" +conventional-commits-filter@^1.1.1, conventional-commits-filter@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.4.tgz#8b5be3979c372e4f7440180d5c655a94ac5a134a" dependencies: is-subset "^0.1.1" modify-values "^1.0.0" -conventional-commits-parser@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.0.1.tgz#1f15ce6b844f7ca41495c8190c0833c30b8b1693" +conventional-commits-parser@^2.1.1, conventional-commits-parser@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.4.tgz#86d2c21029268d99543c4ebda37d76fe5c44d8d1" dependencies: JSONStream "^1.0.4" is-text-path "^1.0.0" @@ -2023,60 +2296,71 @@ conventional-commits-parser@^2.0.1: through2 "^2.0.0" trim-off-newlines "^1.0.0" -conventional-recommended-bump@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-1.0.3.tgz#472b69b1b8f09c5c4ed40fe28a41e63cc04bd736" +conventional-recommended-bump@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-1.2.1.tgz#1b7137efb5091f99fe009e2fe9ddb7cc490e9375" dependencies: concat-stream "^1.4.10" - conventional-commits-filter "^1.1.0" - conventional-commits-parser "^2.0.1" + conventional-commits-filter "^1.1.1" + conventional-commits-parser "^2.1.1" git-raw-commits "^1.3.0" - git-semver-tags "^1.2.3" + git-semver-tags "^1.3.0" meow "^3.3.0" object-assign "^4.0.1" convert-source-map@1.X, convert-source-map@^1.1.1, convert-source-map@^1.3.0, convert-source-map@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + version "1.5.1" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" 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" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" cookie@0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" -copy-props@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-1.6.0.tgz#f0324bbee99771101e7b3ada112f313c393db8ed" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" dependencies: - each-props "^1.2.1" + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +copy-props@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/copy-props/-/copy-props-2.0.1.tgz#665fc32046ca84a898abaa3c5945e7f248ccba00" + dependencies: + each-props "^1.3.0" is-plain-object "^2.0.1" -core-js@^2.0.0: +core-js@^2.0.0, core-js@^2.2.0, core-js@^2.4.0: version "2.5.3" resolved "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" -core-js@^2.2.0, core-js@^2.4.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" - core-js@~2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" core-util-is@1.0.2, 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" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" coveralls@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.0.tgz#22ef730330538080d29b8c151dc9146afde88a99" + resolved "https://registry.npmjs.org/coveralls/-/coveralls-3.0.0.tgz#22ef730330538080d29b8c151dc9146afde88a99" dependencies: js-yaml "^3.6.1" lcov-parse "^0.0.10" @@ -2086,31 +2370,31 @@ coveralls@^3.0.0: crc32-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" + resolved "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" dependencies: crc "^3.4.4" readable-stream "^2.0.0" crc@^3.4.4: version "3.5.0" - resolved "https://registry.yarnpkg.com/crc/-/crc-3.5.0.tgz#98b8ba7d489665ba3979f59b21381374101a1964" + resolved "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz#98b8ba7d489665ba3979f59b21381374101a1964" create-ecdh@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" + resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" dependencies: bn.js "^4.1.0" elliptic "^6.0.0" create-error-class@^3.0.0, create-error-class@^3.0.1, create-error-class@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + resolved "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" dependencies: capture-stack-trace "^1.0.0" create-hash@^1.1.0, create-hash@^1.1.2: version "1.1.3" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" + resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" dependencies: cipher-base "^1.0.1" inherits "^2.0.1" @@ -2119,7 +2403,7 @@ create-hash@^1.1.0, create-hash@^1.1.2: create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: version "1.1.6" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" + resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" dependencies: cipher-base "^1.0.3" create-hash "^1.1.0" @@ -2130,14 +2414,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: cross-spawn@^4, cross-spawn@^4.0.0, cross-spawn@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" dependencies: lru-cache "^4.0.1" which "^1.2.9" 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" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" @@ -2145,19 +2429,19 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: cryptiles@2.x.x: version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + resolved "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" dependencies: boom "2.x.x" cryptiles@3.x.x: version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + resolved "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" dependencies: boom "5.x.x" crypto-browserify@^3.0.0, crypto-browserify@^3.11.0, crypto-browserify@^3.11.1: version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" dependencies: browserify-cipher "^1.0.0" browserify-sign "^4.0.0" @@ -2173,11 +2457,11 @@ crypto-browserify@^3.0.0, crypto-browserify@^3.11.0, crypto-browserify@^3.11.1: 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" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" css@2.X, css@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/css/-/css-2.2.1.tgz#73a4c81de85db664d4ee674f7d47085e3b2d55dc" + resolved "https://registry.npmjs.org/css/-/css-2.2.1.tgz#73a4c81de85db664d4ee674f7d47085e3b2d55dc" dependencies: inherits "^2.0.1" source-map "^0.1.38" @@ -2186,68 +2470,80 @@ css@2.X, css@^2.2.1: csv-streamify@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/csv-streamify/-/csv-streamify-3.0.4.tgz#4cb614c57e3f299cca17b63fdcb4ad167777f47a" + resolved "https://registry.npmjs.org/csv-streamify/-/csv-streamify-3.0.4.tgz#4cb614c57e3f299cca17b63fdcb4ad167777f47a" dependencies: through2 "2.0.1" currently-unhandled@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" dependencies: array-find-index "^1.0.1" custom-event@~1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + resolved "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" cycle@1.0.x: version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + resolved "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" d@1: version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + resolved "https://registry.npmjs.org/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" 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" + resolved "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" dependencies: number-is-nan "^1.0.0" dashdash@^1.12.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" dependencies: assert-plus "^1.0.0" +data-uri-to-buffer@1: + version "1.2.0" + resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" + date-fns@^1.27.2: version "1.29.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" date-format@^0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-0.0.0.tgz#09206863ab070eb459acea5542cbd856b11966b3" + resolved "https://registry.npmjs.org/date-format/-/date-format-0.0.0.tgz#09206863ab070eb459acea5542cbd856b11966b3" + +date-format@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8" date-now@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + resolved "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" dateformat@^1.0.11, dateformat@^1.0.12, dateformat@^1.0.6: version "1.0.12" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + resolved "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" dependencies: get-stdin "^4.0.1" meow "^3.3.0" dateformat@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + resolved "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" -debug-fabulous@>=0.1.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-0.2.1.tgz#57e1164ba0e9ad6d9a65f20075ff3c2bd6bde0dc" +debug-fabulous@1.X: + version "1.0.0" + resolved "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.0.0.tgz#57f6648646097b1b0849dcda0017362c1ec00f8b" dependencies: debug "3.X" memoizee "0.4.X" @@ -2255,49 +2551,59 @@ debug-fabulous@>=0.1.1: debug-log@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + resolved "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -debug@2, debug@2.6.9, debug@^2, debug@^2.2.0, debug@^2.6.6, debug@^2.6.8: +debug@2, debug@2.6.9, debug@^2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.8, debug@~2.6.4, debug@~2.6.6: version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" -debug@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" +debug@2.6.7: + version "2.6.7" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" dependencies: - ms "0.7.1" + ms "2.0.0" -debug@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" +debug@2.6.8: + version "2.6.8" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: - ms "0.7.2" + ms "2.0.0" -debug@3.1.0, debug@3.X, debug@^3.1.0: +debug@3.1.0, debug@3.X, debug@^3.1.0, debug@~3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: ms "2.0.0" debug@^0.7.2: version "0.7.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" + resolved "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" decompress-response@^3.2.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" dependencies: mimic-response "^1.0.0" decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + resolved "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" dependencies: file-type "^5.2.0" is-stream "^1.1.0" @@ -2305,7 +2611,7 @@ decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: decompress-tarbz2@^4.0.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + resolved "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" dependencies: decompress-tar "^4.1.0" file-type "^6.1.0" @@ -2315,7 +2621,7 @@ decompress-tarbz2@^4.0.0: decompress-targz@^4.0.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + resolved "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" dependencies: decompress-tar "^4.1.1" file-type "^5.2.0" @@ -2323,7 +2629,7 @@ decompress-targz@^4.0.0: decompress-unzip@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + resolved "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" dependencies: file-type "^3.8.0" get-stream "^2.2.0" @@ -2332,7 +2638,7 @@ decompress-unzip@^4.0.1: decompress@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" + resolved "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" dependencies: decompress-tar "^4.0.0" decompress-tarbz2 "^4.0.0" @@ -2345,60 +2651,93 @@ decompress@^4.2.0: dedent@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" deep-eql@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" dependencies: type-detect "^4.0.0" deep-equal@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" deep-equal@~0.2.1: version "0.2.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" deep-extend@~0.4.0: version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" deep-is@~0.1.3: version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + dependencies: + kind-of "^5.0.2" default-require-extensions@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + resolved "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" dependencies: strip-bom "^2.0.0" default-resolution@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + resolved "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" defaults@^1.0.0, defaults@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" dependencies: clone "^1.0.2" define-properties@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" dependencies: foreach "^2.0.5" object-keys "^1.0.8" +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + 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" + resolved "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +degenerator@~1.0.2: + version "1.0.4" + resolved "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" + dependencies: + ast-types "0.x.x" + escodegen "1.x.x" + esprima "3.x.x" -del@^2.0.2, del@^2.2.0, del@^2.2.2: +del@^2.0.2, del@^2.2.0: version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + resolved "https://registry.npmjs.org/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" dependencies: globby "^5.0.0" is-path-cwd "^1.0.0" @@ -2410,7 +2749,7 @@ del@^2.0.2, del@^2.2.0, del@^2.2.2: del@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + resolved "https://registry.npmjs.org/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" dependencies: globby "^6.1.0" is-path-cwd "^1.0.0" @@ -2421,15 +2760,19 @@ del@^3.0.0: delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" delegates@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depd@1.1.1, depd@~1.1.1: +depd@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +depd@~1.1.0, depd@~1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" dependency-graph@^0.7.0: version "0.7.0" @@ -2437,11 +2780,11 @@ dependency-graph@^0.7.0: deprecated@^0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" + resolved "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" deps-sort@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5" + resolved "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz#091724902e84658260eb910748cccd1af6e21fb5" dependencies: JSONStream "^1.0.3" shasum "^1.0.0" @@ -2450,48 +2793,46 @@ deps-sort@^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" + resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" destroy@^1.0.4, destroy@~1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" -detect-file@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" - dependencies: - fs-exists-sync "^0.1.0" +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" detect-indent@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" dependencies: repeating "^2.0.0" detect-indent@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" detect-libc@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1" + version "1.0.3" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" detect-newline@2.X: version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" detect-node@^2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" detective@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" + version "4.7.1" + resolved "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" dependencies: - acorn "^4.0.3" + acorn "^5.2.1" defined "^1.0.0" detective@^5.0.2: @@ -2504,11 +2845,11 @@ detective@^5.0.2: di@^0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + resolved "https://registry.npmjs.org/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" didyoumean@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" + resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" diff-match-patch@^1.0.0: version "1.0.0" @@ -2516,15 +2857,15 @@ diff-match-patch@^1.0.0: diff@3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" + resolved "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" diff@^3.1.0, diff@^3.2.0: version "3.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" + resolved "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" diffie-hellman@^5.0.0: version "5.0.2" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" + resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" dependencies: bn.js "^4.1.0" miller-rabin "^4.0.0" @@ -2539,15 +2880,15 @@ dir-glob@^2.0.0: dmg@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/dmg/-/dmg-0.1.0.tgz#b38ea2107f6f0b070442bbf799bfc4f2aedaa5f8" + resolved "https://registry.npmjs.org/dmg/-/dmg-0.1.0.tgz#b38ea2107f6f0b070442bbf799bfc4f2aedaa5f8" dns-equal@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" -dns-packet@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.2.2.tgz#a8a26bec7646438963fc86e06f8f8b16d6c8bf7a" +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" dependencies: ip "^1.1.0" safe-buffer "^5.0.1" @@ -2561,7 +2902,7 @@ dns-sync@^0.1.3: dns-txt@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + resolved "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" dependencies: buffer-indexof "^1.0.0" @@ -2573,7 +2914,7 @@ doctrine@^2.1.0: dom-serialize@^2.2.0: version "2.2.1" - resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + resolved "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" dependencies: custom-event "~1.0.0" ent "~2.2.0" @@ -2582,58 +2923,53 @@ dom-serialize@^2.2.0: dom-storage@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/dom-storage/-/dom-storage-2.0.2.tgz#ed17cbf68abd10e0aef8182713e297c5e4b500b0" - -domain-browser@^1.1.1, domain-browser@^1.1.7, domain-browser@~1.1.0: - version "1.1.7" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + resolved "https://registry.npmjs.org/dom-storage/-/dom-storage-2.0.2.tgz#ed17cbf68abd10e0aef8182713e297c5e4b500b0" -domain-browser@^1.2.0: +domain-browser@^1.1.1, domain-browser@^1.1.7, domain-browser@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" +domain-browser@~1.1.0: + version "1.1.7" + resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + dot-prop@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" dependencies: is-obj "^1.0.0" dot-prop@^4.1.0, dot-prop@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" dependencies: is-obj "^1.0.0" +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + duplexer2@0.0.2: version "0.0.2" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + resolved "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" dependencies: readable-stream "~1.1.9" duplexer2@^0.1.2, duplexer2@^0.1.4, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + resolved "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" 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" + resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - -duplexify@^3.1.2, duplexify@^3.2.0, duplexify@^3.5.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" + resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" -duplexify@^3.5.1: +duplexify@^3.2.0, duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.5.1, duplexify@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" dependencies: @@ -2642,9 +2978,9 @@ duplexify@^3.5.1: readable-stream "^2.0.0" stream-shift "^1.0.0" -each-props@^1.2.1: +each-props@^1.3.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.1.tgz#fc138f51e3a2774286d4858e02d6e7de462de158" + resolved "https://registry.npmjs.org/each-props/-/each-props-1.3.1.tgz#fc138f51e3a2774286d4858e02d6e7de462de158" dependencies: is-plain-object "^2.0.1" object.defaults "^1.1.0" @@ -2655,20 +2991,20 @@ eastasianwidth@^0.1.1: ecc-jsbn@~0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" dependencies: jsbn "~0.1.0" ecdsa-sig-formatter@1.0.9: version "1.0.9" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1" + resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1" dependencies: base64url "^2.0.0" safe-buffer "^5.0.1" ee-first@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" elegant-spinner@^1.0.1: version "1.0.1" @@ -2676,7 +3012,7 @@ elegant-spinner@^1.0.1: elliptic@^6.0.0: version "6.4.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2688,7 +3024,7 @@ elliptic@^6.0.0: emojis-list@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" empower-core@^0.6.2: version "0.6.2" @@ -2705,69 +3041,63 @@ empower@^1.2.3: empower-core "^0.6.2" encodeurl@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - dependencies: - iconv-lite "~0.4.13" + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + version "1.4.1" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" dependencies: once "^1.4.0" end-of-stream@~0.1.5: version "0.1.5" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" dependencies: once "~1.3.0" -engine.io-client@1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.3.tgz#1798ed93451246453d4c6f635d7a201fe940d5ab" +engine.io-client@~3.1.0: + version "3.1.5" + resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.5.tgz#85de17666560327ef1817978f6e3f8101ded2c47" dependencies: component-emitter "1.2.1" component-inherit "0.0.3" - debug "2.3.3" - engine.io-parser "1.3.2" + debug "~3.1.0" + engine.io-parser "~2.1.1" has-cors "1.1.0" indexof "0.0.1" - parsejson "0.0.3" parseqs "0.0.5" parseuri "0.0.5" - ws "1.1.2" - xmlhttprequest-ssl "1.5.3" + ws "~3.3.1" + xmlhttprequest-ssl "~1.5.4" yeast "0.1.2" -engine.io-parser@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a" +engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz#4c0f4cff79aaeecbbdcfdea66a823c6085409196" dependencies: after "0.8.2" - arraybuffer.slice "0.0.6" + arraybuffer.slice "~0.0.7" base64-arraybuffer "0.1.5" blob "0.0.4" - has-binary "0.1.7" - wtf-8 "1.0.0" + has-binary2 "~1.0.2" -engine.io@1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4" +engine.io@~3.1.0: + version "3.1.5" + resolved "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz#0e7ef9d690eb0b35597f1d4ad02a26ca2dba3845" dependencies: - accepts "1.3.3" + accepts "~1.3.4" base64id "1.0.0" cookie "0.3.1" - debug "2.3.3" - engine.io-parser "1.3.2" - ws "1.1.2" + debug "~3.1.0" + engine.io-parser "~2.1.0" + ws "~3.3.1" + optionalDependencies: + uws "~9.14.0" enhanced-resolve@^3.0.0, enhanced-resolve@^3.4.0: version "3.4.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" dependencies: graceful-fs "^4.1.2" memory-fs "^0.4.0" @@ -2776,23 +3106,23 @@ enhanced-resolve@^3.0.0, enhanced-resolve@^3.4.0: ent@^2.2.0, ent@~2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + resolved "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" errno@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + version "0.1.7" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: - prr "~0.0.0" + prr "~1.0.1" error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: is-arrayish "^0.2.1" es-abstract@^1.4.3, es-abstract@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" + version "1.10.0" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" dependencies: es-to-primitive "^1.1.1" function-bind "^1.1.1" @@ -2802,22 +3132,22 @@ es-abstract@^1.4.3, es-abstract@^1.7.0: es-to-primitive@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" dependencies: is-callable "^1.1.1" is-date-object "^1.0.1" is-symbol "^1.0.1" es5-ext@^0.10.14, es5-ext@^0.10.30, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2: - version "0.10.35" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f" + version "0.10.39" + resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz#fca21b67559277ca4ac1a1ed7048b107b6f76d87" dependencies: - es6-iterator "~2.0.1" + es6-iterator "~2.0.3" es6-symbol "~3.1.1" -es6-iterator@^2.0.1, es6-iterator@~2.0.1: +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" + resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" dependencies: d "1" es5-ext "^0.10.35" @@ -2825,7 +3155,7 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.1: es6-map@^0.1.3: version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + resolved "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" dependencies: d "1" es5-ext "~0.10.14" @@ -2834,17 +3164,13 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-promise@^4.0.5: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a" - es6-promise@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" + resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" es6-set@^0.1.4, es6-set@~0.1.5: version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + resolved "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" dependencies: d "1" es5-ext "~0.10.14" @@ -2854,14 +3180,14 @@ es6-set@^0.1.4, es6-set@~0.1.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" + resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" dependencies: d "1" es5-ext "~0.10.14" es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + resolved "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" dependencies: d "1" es5-ext "^0.10.14" @@ -2870,15 +3196,15 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, 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" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" escodegen@1.8.x: version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" dependencies: esprima "^2.7.1" estraverse "^1.9.1" @@ -2887,9 +3213,20 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" +escodegen@1.x.x: + version "1.9.0" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.5.6" + escope@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + resolved "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" dependencies: es6-map "^0.1.3" es6-weak-map "^2.0.1" @@ -2908,8 +3245,8 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" eslint@^4.16.0: - version "4.17.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-4.17.0.tgz#dc24bb51ede48df629be7031c71d9dc0ee4f3ddf" + version "4.18.1" + resolved "https://registry.npmjs.org/eslint/-/eslint-4.18.1.tgz#b9138440cb1e98b2f44a0d578c6ecf8eae6150b0" dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -2958,11 +3295,15 @@ espree@^3.5.2: esprima@2.7.x, esprima@^2.7.1: version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + resolved "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@3.x.x, esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/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" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" espurify@^1.6.0: version "1.7.0" @@ -2978,37 +3319,37 @@ esquery@^1.0.0: esrecurse@^4.1.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" dependencies: estraverse "^4.1.0" object-assign "^4.0.1" estraverse@^1.9.1: version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" 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" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" esutils@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -etag@~1.8.1: +etag@~1.8.0, etag@~1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" event-emitter@^0.3.5, event-emitter@~0.3.5: version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + resolved "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" dependencies: d "1" es5-ext "~0.10.14" event-stream@~3.3.0: version "3.3.4" - resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + resolved "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" dependencies: duplexer "~0.1.1" from "~0" @@ -3020,11 +3361,11 @@ event-stream@~3.3.0: eventemitter3@1.x.x: version "1.2.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" events@^1.0.0, events@^1.1.1, events@~1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + resolved "https://registry.npmjs.org/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" events@^2.0.0: version "2.0.0" @@ -3032,26 +3373,26 @@ events@^2.0.0: eventsource@0.1.6: version "0.1.6" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" + resolved "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" dependencies: original ">=0.0.5" 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" + resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" dependencies: md5.js "^1.3.4" safe-buffer "^5.1.1" exec-sh@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" + resolved "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" dependencies: merge "^1.1.3" execa@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -3063,7 +3404,7 @@ execa@^0.7.0: execa@^0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + resolved "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -3075,19 +3416,19 @@ execa@^0.8.0: exit-code@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/exit-code/-/exit-code-1.0.2.tgz#ce165811c9f117af6a5f882940b96ae7f9aecc34" + resolved "https://registry.npmjs.org/exit-code/-/exit-code-1.0.2.tgz#ce165811c9f117af6a5f882940b96ae7f9aecc34" exit-hook@^1.0.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + resolved "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" exit@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" expand-braces@^0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" + resolved "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" dependencies: array-slice "^0.2.3" array-unique "^0.2.1" @@ -3095,38 +3436,77 @@ expand-braces@^0.1.1: expand-brackets@^0.1.4: version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" dependencies: is-posix-bracket "^0.1.0" +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + 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@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" + resolved "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" dependencies: is-number "^0.1.1" repeat-string "^0.2.2" expand-range@^1.8.1: version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + resolved "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" dependencies: fill-range "^2.1.0" -expand-tilde@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" - dependencies: - os-homedir "^1.0.1" - -expand-tilde@^2.0.2: +expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" dependencies: homedir-polyfill "^1.0.1" -express@4.16.2, express@^4.13.3, express@^4.15.4, express@^4.16.2: +express@4.15.4: + version "4.15.4" + resolved "https://registry.npmjs.org/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1" + dependencies: + accepts "~1.3.3" + array-flatten "1.1.1" + content-disposition "0.5.2" + content-type "~1.0.2" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.8" + depd "~1.1.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.0" + finalhandler "~1.0.4" + fresh "0.5.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.1" + path-to-regexp "0.1.7" + proxy-addr "~1.1.5" + qs "6.5.0" + range-parser "~1.2.0" + send "0.15.4" + serve-static "1.12.4" + setprototypeof "1.0.3" + statuses "~1.3.1" + type-is "~1.6.15" + utils-merge "1.0.0" + vary "~1.1.1" + +express@^4.15.4, express@^4.16.2: version "4.16.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" + resolved "https://registry.npmjs.org/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" dependencies: accepts "~1.3.4" array-flatten "1.1.1" @@ -3159,25 +3539,30 @@ express@4.16.2, express@^4.13.3, express@^4.15.4, express@^4.16.2: utils-merge "1.0.1" vary "~1.1.2" +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + dependencies: + kind-of "^1.1.0" + extend-shallow@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" dependencies: is-extendable "^0.1.0" +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + extend@3, extend@^3.0.0, extend@^3.0.1, extend@~3.0.0, extend@~3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -external-editor@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.5.tgz#52c249a3981b9ba187c7cacf5beb50bf1d91a6bc" - dependencies: - iconv-lite "^0.4.17" - jschardet "^1.4.2" - tmp "^0.0.33" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.1.0: +external-editor@^2.0.4, external-editor@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" dependencies: @@ -3187,55 +3572,73 @@ external-editor@^2.1.0: extglob@^0.3.1: version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + resolved "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" dependencies: is-extglob "^1.0.0" +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + 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" + extract-zip@^1.6.5: version "1.6.6" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" + resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" dependencies: concat-stream "1.6.0" debug "2.6.9" mkdirp "0.5.0" yauzl "2.4.1" -extsprintf@1.3.0, extsprintf@^1.2.0: +extsprintf@1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" eyes@0.1.x: version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" -fancy-log@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" +fancy-log@^1.1.0, fancy-log@^1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1" dependencies: - chalk "^1.1.1" + ansi-gray "^0.1.1" + color-support "^1.1.3" time-stamp "^1.0.0" 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" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" 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" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" fast-levenshtein@~2.0.4: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" fast-url-parser@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + resolved "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" dependencies: punycode "^1.3.2" faye-websocket@0.11.1, faye-websocket@>=0.6.0, faye-websocket@~0.11.0: version "0.11.1" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" dependencies: websocket-driver ">=0.5.1" @@ -3247,26 +3650,26 @@ faye-websocket@0.9.3: faye-websocket@^0.10.0: version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" dependencies: websocket-driver ">=0.5.1" fd-slicer@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" dependencies: pend "~1.2.0" figures@^1.3.5, figures@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" 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" + resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" dependencies: escape-string-regexp "^1.0.5" @@ -3279,34 +3682,38 @@ file-entry-cache@^2.0.0: file-type@^3.8.0: version "3.9.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + resolved "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" file-type@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + resolved "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" file-type@^6.1.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + resolved "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + +file-uri-to-path@1: + version "1.0.0" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" filename-regex@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + resolved "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" fileset@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + resolved "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" dependencies: glob "^7.0.3" minimatch "^3.0.3" filesize@^3.1.3: - version "3.5.11" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.11.tgz#1919326749433bb3cf77368bd158caabcc19e9ee" + version "3.6.0" + resolved "https://registry.npmjs.org/filesize/-/filesize-3.6.0.tgz#22d079615624bb6fd3c04026120628a41b3f4efa" fill-range@^2.1.0: version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" dependencies: is-number "^2.1.0" isobject "^2.0.0" @@ -3314,13 +3721,22 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + filled-array@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" + resolved "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" -finalhandler@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.6.tgz#007aea33d1a4d3e42017f624848ad58d212f814f" +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" dependencies: debug "2.6.9" encodeurl "~1.0.1" @@ -3330,9 +3746,9 @@ finalhandler@1.0.6: statuses "~1.3.1" unpipe "~1.0.0" -finalhandler@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" +finalhandler@~1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz#007aea33d1a4d3e42017f624848ad58d212f814f" dependencies: debug "2.6.9" encodeurl "~1.0.1" @@ -3344,47 +3760,49 @@ finalhandler@1.1.0: find-cache-dir@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" dependencies: commondir "^1.0.1" mkdirp "^0.5.1" pkg-dir "^1.0.0" +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + find-index@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + resolved "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" find-up@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" 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" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: locate-path "^2.0.0" -findup-sync@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" - dependencies: - detect-file "^0.1.0" - is-glob "^2.0.1" - micromatch "^2.3.7" - resolve-dir "^0.1.0" - -findup-sync@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" dependencies: - glob "~5.0.0" + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" fined@^1.0.1: version "1.1.0" - resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476" + resolved "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476" dependencies: expand-tilde "^2.0.2" is-plain-object "^2.0.3" @@ -3392,13 +3810,13 @@ fined@^1.0.1: object.pick "^1.2.0" parse-filepath "^1.0.1" -firebase-admin@5.8.0: - version "5.8.0" - resolved "https://registry.npmjs.org/firebase-admin/-/firebase-admin-5.8.0.tgz#2363599ad44a495f3673ef5876e18cbed6b33385" +firebase-admin@5.9.0: + version "5.9.0" + resolved "https://registry.npmjs.org/firebase-admin/-/firebase-admin-5.9.0.tgz#ef58a6932e4c0c09a0e96917334eef0f43658c44" dependencies: "@firebase/app" "^0.1.1" "@firebase/database" "^0.1.3" - "@google-cloud/firestore" "^0.10.0" + "@google-cloud/firestore" "^0.11.2" "@google-cloud/storage" "^1.2.1" "@types/google-cloud__storage" "^1.1.1" "@types/node" "^8.0.53" @@ -3406,12 +3824,12 @@ firebase-admin@5.8.0: jsonwebtoken "8.1.0" node-forge "0.7.1" -firebase-tools@^3.10.1: - version "3.15.1" - resolved "https://registry.yarnpkg.com/firebase-tools/-/firebase-tools-3.15.1.tgz#cbb0b569365e6fa545ffd8e4c9d45988a3008ae5" +firebase-tools@^3.17.4: + version "3.17.4" + resolved "https://registry.npmjs.org/firebase-tools/-/firebase-tools-3.17.4.tgz#dde15ee12a6fa9930a4142b7dafd12313f6555d8" dependencies: JSONStream "^1.2.1" - archiver "^2.1.0" + archiver "^2.1.1" chalk "^1.1.0" cjson "^0.3.1" cli-table "^0.3.1" @@ -3442,32 +3860,32 @@ firebase-tools@^3.10.1: semver "^5.0.3" superstatic "^5.0.1" tar "^3.1.5" - tmp "0.0.27" + tmp "0.0.33" universal-analytics "^0.3.9" update-notifier "^0.5.0" user-home "^2.0.0" uuid "^3.0.0" winston "^1.0.1" optionalDependencies: - "@google-cloud/functions-emulator" "^1.0.0-alpha.23" + "@google-cloud/functions-emulator" "1.0.0-alpha.23" firebase@2.x.x: version "2.4.2" - resolved "https://registry.yarnpkg.com/firebase/-/firebase-2.4.2.tgz#4e1119ec0396ca561d8a7acbff1630feac6c0a31" + resolved "https://registry.npmjs.org/firebase/-/firebase-2.4.2.tgz#4e1119ec0396ca561d8a7acbff1630feac6c0a31" dependencies: faye-websocket ">=0.6.0" first-chunk-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + resolved "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" -flagged-respawn@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5" +flagged-respawn@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz#4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7" flat-arguments@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/flat-arguments/-/flat-arguments-1.0.2.tgz#9baa780adf0501f282d726c9c6a038dba44ea76f" + resolved "https://registry.npmjs.org/flat-arguments/-/flat-arguments-1.0.2.tgz#9baa780adf0501f282d726c9c6a038dba44ea76f" dependencies: array-flatten "^1.0.0" as-array "^1.0.0" @@ -3483,90 +3901,118 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -follow-redirects@^1.4.1: +flush-write-stream@^1.0.0, flush-write-stream@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +follow-redirects@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz#8e34298cbd2e176f254effec75a1c78cc849fd37" + dependencies: + debug "^2.2.0" + +follow-redirects@^1.2.5, follow-redirects@^1.4.1: version "1.4.1" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa" dependencies: debug "^3.1.0" -for-in@^1.0.1: +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" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" for-own@^0.1.4: version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + resolved "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" dependencies: for-in "^1.0.1" for-own@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + resolved "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" dependencies: for-in "^1.0.1" foreach@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" foreground-child@^1.5.3, foreground-child@^1.5.6: version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" dependencies: cross-spawn "^4" signal-exit "^3.0.0" forever-agent@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.11" form-data@~2.1.1: version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" dependencies: asynckit "^0.4.0" combined-stream "^1.0.5" mime-types "^2.1.12" form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + version "2.3.2" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" dependencies: asynckit "^0.4.0" - combined-stream "^1.0.5" + combined-stream "1.0.6" mime-types "^2.1.12" -formatio@1.2.0, formatio@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" +forwarded@~0.1.0, forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" dependencies: - samsam "1.x" + map-cache "^0.2.2" -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" +fresh@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" fresh@0.5.2: version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" from@~0: version "0.1.7" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + resolved "https://registry.npmjs.org/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" fs-access@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + resolved "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" dependencies: null-check "^1.0.0" -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - fs-extra@^0.23.1: version "0.23.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.23.1.tgz#6611dba6adf2ab8dc9c69fab37cddf8818157e3d" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-0.23.1.tgz#6611dba6adf2ab8dc9c69fab37cddf8818157e3d" dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -3575,7 +4021,7 @@ fs-extra@^0.23.1: fs-extra@^0.30.0: version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" dependencies: graceful-fs "^4.1.2" jsonfile "^2.1.0" @@ -3583,9 +4029,9 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^4.0.1, fs-extra@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" +fs-extra@^4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -3599,20 +4045,36 @@ fs-extra@^5.0.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" fsevents@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" dependencies: nan "^2.3.0" node-pre-gyp "^0.6.39" fstream-ignore@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + resolved "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" dependencies: fstream "^1.0.0" inherits "2" @@ -3620,16 +4082,23 @@ fstream-ignore@^1.0.5: fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" mkdirp ">=0.5 0" rimraf "2" +ftp@~0.3.10: + version "0.3.10" + resolved "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" functional-red-black-tree@^1.0.1: version "1.0.1" @@ -3637,7 +4106,7 @@ functional-red-black-tree@^1.0.1: gauge@~2.7.3: version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" dependencies: aproba "^1.0.3" console-control-strings "^1.0.0" @@ -3650,27 +4119,28 @@ gauge@~2.7.3: gaze@^0.5.1: version "0.5.2" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" + resolved "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" dependencies: globule "~0.1.0" gcp-metadata@^0.3.0: version "0.3.1" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-0.3.1.tgz#313814456e7c3d0eeb8f8b084b33579e886f829a" + resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.3.1.tgz#313814456e7c3d0eeb8f8b084b33579e886f829a" dependencies: extend "^3.0.0" retry-request "^3.0.0" -gcp-metadata@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.4.1.tgz#64623b84175357cc119ad7a6aec759392a90a58b" +gcp-metadata@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.6.1.tgz#62d54871fc6aeeac6a688e094abc886cb7aaacd0" dependencies: - extend "^3.0.0" - retry-request "^3.1.0" + axios "^0.17.1" + extend "^3.0.1" + retry-axios "0.3.0" -gcs-resumable-upload@^0.8.2: +gcs-resumable-upload@^0.8.0: version "0.8.2" - resolved "https://registry.yarnpkg.com/gcs-resumable-upload/-/gcs-resumable-upload-0.8.2.tgz#37df02470430395a789a637e72cabc80677ae964" + resolved "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-0.8.2.tgz#37df02470430395a789a637e72cabc80677ae964" dependencies: buffer-equal "^1.0.0" configstore "^3.0.0" @@ -3694,7 +4164,7 @@ gcs-resumable-upload@^0.9.0: geckodriver@^1.8.0: version "1.10.0" - resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.10.0.tgz#73e2f785666521d0d3a9ddc9fd5a0a5e3bf47845" + resolved "https://registry.npmjs.org/geckodriver/-/geckodriver-1.10.0.tgz#73e2f785666521d0d3a9ddc9fd5a0a5e3bf47845" dependencies: adm-zip "0.4.7" bluebird "3.4.6" @@ -3703,25 +4173,25 @@ geckodriver@^1.8.0: generate-function@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + resolved "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" generate-object-property@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + resolved "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" dependencies: is-property "^1.0.0" get-caller-file@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" 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" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" get-pkg-repo@^1.0.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + resolved "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" dependencies: hosted-git-info "^2.1.4" meow "^3.3.0" @@ -3731,32 +4201,47 @@ get-pkg-repo@^1.0.0: get-port@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + resolved "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" get-stdin@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" get-stream@^2.2.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + resolved "https://registry.npmjs.org/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" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-uri@2: + version "2.0.1" + resolved "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz#dbdcacacd8c608a38316869368117697a1631c59" + dependencies: + data-uri-to-buffer "1" + debug "2" + extend "3" + file-uri-to-path "1" + ftp "~0.3.10" + readable-stream "2" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" getpass@^0.1.1: version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" dependencies: assert-plus "^1.0.0" -git-raw-commits@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.0.tgz#0bc8596e90d5ffe736f7f5546bd2d12f73abaac6" +git-raw-commits@^1.3.0, git-raw-commits@^1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.3.tgz#464f9aa14c4e78235e98654f0da467f3702590f9" dependencies: dargs "^4.0.1" lodash.template "^4.0.2" @@ -3766,59 +4251,59 @@ git-raw-commits@^1.3.0: git-remote-origin-url@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + resolved "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" dependencies: gitconfiglocal "^1.0.0" pify "^2.3.0" -git-rev-sync@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/git-rev-sync/-/git-rev-sync-1.9.1.tgz#a0c2e3dd392abcf6b76962e27fc75fb3223449ce" +git-rev-sync@^1.10.0: + version "1.10.0" + resolved "https://registry.npmjs.org/git-rev-sync/-/git-rev-sync-1.10.0.tgz#e8ac4fd09672449148ff694e2d7c6a6ee35c93a6" dependencies: escape-string-regexp "1.0.5" graceful-fs "4.1.11" shelljs "0.7.7" -git-semver-tags@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-1.2.3.tgz#188b453882bf9d7a23afd31baba537dab7388d5d" +git-semver-tags@^1.3.0, git-semver-tags@^1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.3.3.tgz#0b0416c43285adfdc93a8038ea25502a09319245" dependencies: meow "^3.3.0" semver "^5.0.1" gitconfiglocal@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + resolved "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" dependencies: ini "^1.3.2" glob-base@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + resolved "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 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" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" dependencies: is-glob "^2.0.0" glob-parent@^3.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" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" glob-slash@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/glob-slash/-/glob-slash-1.0.0.tgz#fe52efa433233f74a2fe64c7abb9bc848202ab95" + resolved "https://registry.npmjs.org/glob-slash/-/glob-slash-1.0.0.tgz#fe52efa433233f74a2fe64c7abb9bc848202ab95" glob-slasher@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/glob-slasher/-/glob-slasher-1.0.1.tgz#747a0e5bb222642ee10d3e05443e109493cb0f8e" + resolved "https://registry.npmjs.org/glob-slasher/-/glob-slasher-1.0.1.tgz#747a0e5bb222642ee10d3e05443e109493cb0f8e" dependencies: glob-slash "^1.0.0" lodash.isobject "^2.4.1" @@ -3826,7 +4311,7 @@ glob-slasher@^1.0.1: glob-stream@^3.1.5: version "3.1.18" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" + resolved "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" dependencies: glob "^4.3.1" glob2base "^0.0.12" @@ -3837,7 +4322,7 @@ glob-stream@^3.1.5: glob-stream@^5.3.2: version "5.3.5" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" + resolved "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" dependencies: extend "^3.0.0" glob "^5.0.3" @@ -3848,30 +4333,54 @@ glob-stream@^5.3.2: to-absolute-glob "^0.1.1" unique-stream "^2.0.2" +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + glob-watcher@^0.0.6: version "0.0.6" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" + resolved "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" dependencies: gaze "^0.5.1" -glob-watcher@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-3.2.0.tgz#ffc1a2d3d07783b672f5e21799a4d0b3fed92daf" +glob-watcher@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/glob-watcher/-/glob-watcher-4.0.0.tgz#9e63a8ff6e61e932de6cc2caece5071a6d737329" dependencies: async-done "^1.2.0" chokidar "^1.4.3" - lodash.debounce "^4.0.6" - object.defaults "^1.0.0" + just-debounce "^1.0.0" + object.defaults "^1.1.0" + +glob-watcher@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.1.tgz#239aaa621b6bd843b288fdf6b155f50963c7d7ea" + dependencies: + async-done "^1.2.0" + chokidar "^2.0.0" + just-debounce "^1.0.0" + object.defaults "^1.1.0" glob2base@^0.0.12: version "0.0.12" - resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + resolved "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" dependencies: find-index "^0.1.1" glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2: version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3882,16 +4391,16 @@ glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glo glob@^4.3.1: version "4.5.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + resolved "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" dependencies: inflight "^1.0.4" inherits "2" minimatch "^2.0.1" once "^1.3.0" -glob@^5.0.14, glob@^5.0.15, glob@^5.0.3, glob@~5.0.0: +glob@^5.0.14, glob@^5.0.15, glob@^5.0.3: version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + resolved "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" dependencies: inflight "^1.0.4" inherits "2" @@ -3901,27 +4410,29 @@ glob@^5.0.14, glob@^5.0.15, glob@^5.0.3, glob@~5.0.0: glob@~3.1.21: version "3.1.21" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" + resolved "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" dependencies: graceful-fs "~1.2.0" inherits "1" minimatch "~0.2.11" -global-modules@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" dependencies: - global-prefix "^0.1.4" - is-windows "^0.2.0" + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" -global-prefix@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" dependencies: - homedir-polyfill "^1.0.0" - ini "^1.3.4" - is-windows "^0.2.0" - which "^1.2.12" + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" globals@^11.0.1: version "11.3.0" @@ -3929,11 +4440,11 @@ globals@^11.0.1: globals@^9.18.0: version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" globby@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + resolved "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" dependencies: array-union "^1.0.1" arrify "^1.0.0" @@ -3944,7 +4455,7 @@ globby@^5.0.0: globby@^6.1.0: version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + resolved "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" dependencies: array-union "^1.0.1" glob "^7.0.3" @@ -3965,21 +4476,21 @@ globby@^7.1.1: globule@~0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" + resolved "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" dependencies: glob "~3.1.21" lodash "~1.0.1" minimatch "~0.2.11" glogg@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" + version "1.0.1" + resolved "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz#dcf758e44789cc3f3d32c1f3562a3676e6a34810" dependencies: sparkles "^1.0.0" google-auth-library@^0.10.0, google-auth-library@~0.10.0: version "0.10.0" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e" + resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e" dependencies: gtoken "^1.2.1" jws "^3.1.4" @@ -3998,7 +4509,7 @@ google-auth-library@^0.12.0: google-auto-auth@^0.7.1, google-auto-auth@^0.7.2: version "0.7.2" - resolved "https://registry.yarnpkg.com/google-auto-auth/-/google-auto-auth-0.7.2.tgz#bf9352d5c4a0897bf31fd9c491028b765fbea71e" + resolved "https://registry.npmjs.org/google-auto-auth/-/google-auto-auth-0.7.2.tgz#bf9352d5c4a0897bf31fd9c491028b765fbea71e" dependencies: async "^2.3.0" gcp-metadata "^0.3.0" @@ -4015,11 +4526,11 @@ google-auto-auth@^0.8.0: request "^2.79.0" google-auto-auth@^0.9.0: - version "0.9.3" - resolved "https://registry.npmjs.org/google-auto-auth/-/google-auto-auth-0.9.3.tgz#544c36da639890cf56040b0246859060f140715a" + version "0.9.4" + resolved "https://registry.npmjs.org/google-auto-auth/-/google-auto-auth-0.9.4.tgz#eba19a5f44d5277848591503f821cb9b45da381d" dependencies: async "^2.3.0" - gcp-metadata "^0.4.1" + gcp-metadata "^0.6.1" google-auth-library "^0.12.0" request "^2.79.0" @@ -4033,26 +4544,26 @@ google-closure-compiler-js@^20180204.0.0: google-closure-compiler@^20151015.0.0: version "20151015.7.0" - resolved "https://registry.yarnpkg.com/google-closure-compiler/-/google-closure-compiler-20151015.7.0.tgz#a494909eb33ec5b6aed1ffb712f0557ff596ba6f" + resolved "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20151015.7.0.tgz#a494909eb33ec5b6aed1ffb712f0557ff596ba6f" dependencies: chalk "^1.0.0" gulp-util "^3.0.7" through2 "^2.0.0" vinyl-sourcemaps-apply "^0.2.0" -google-closure-compiler@^20170910.0.0: - version "20170910.0.0" - resolved "https://registry.yarnpkg.com/google-closure-compiler/-/google-closure-compiler-20170910.0.0.tgz#7a7cf5111d7376b376ce7461137e1b039303f1ea" +google-closure-compiler@^20180204.0.0: + version "20180204.0.0" + resolved "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20180204.0.0.tgz#b097ffb750c65ca07a2da469d76c551d3b8e21a3" dependencies: chalk "^1.0.0" vinyl "^2.0.1" vinyl-sourcemaps-apply "^0.2.0" -google-closure-library@^20170910.0.0: - version "20170910.0.0" - resolved "https://registry.yarnpkg.com/google-closure-library/-/google-closure-library-20170910.0.0.tgz#d6122ec24472672ee1347b19e8c4a43d18f57bef" +google-closure-library@^20180204.0.0: + version "20180204.0.0" + resolved "https://registry.npmjs.org/google-closure-library/-/google-closure-library-20180204.0.0.tgz#ad3c5a18dfd731c6149c5220d2991c0c9129718a" -google-gax@^0.14.1: +google-gax@^0.14.3: version "0.14.5" resolved "https://registry.npmjs.org/google-gax/-/google-gax-0.14.5.tgz#b2c73c61df6cead94f90421d17f44ff161f623c7" dependencies: @@ -4069,16 +4580,13 @@ google-gax@^0.14.1: google-p12-pem@^0.1.0: version "0.1.2" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177" + resolved "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177" dependencies: node-forge "^0.7.1" -google-proto-files@0.14.1: - version "0.14.1" - resolved "https://registry.yarnpkg.com/google-proto-files/-/google-proto-files-0.14.1.tgz#6e5f15f8bd6615d73ca3fdd08cdec33363f9af89" - dependencies: - globby "^6.1.0" - protobufjs "^6.8.0" +google-proto-files@0.12.1: + version "0.12.1" + resolved "https://registry.npmjs.org/google-proto-files/-/google-proto-files-0.12.1.tgz#6434dc7e025a0d0c82e5f04e615c737d6a4c4387" google-proto-files@^0.14.1: version "0.14.2" @@ -4089,9 +4597,9 @@ google-proto-files@^0.14.1: prettier "^1.10.2" protobufjs "^6.8.0" -googleapis@22.2.0: - version "22.2.0" - resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-22.2.0.tgz#fd79c3c26e7e71a4f5a2ec1a7da5fb115d8853d2" +googleapis@20.1.0: + version "20.1.0" + resolved "https://registry.npmjs.org/googleapis/-/googleapis-20.1.0.tgz#efb2541f0cab123492bc8ccfe09fa6baaf2b84ca" dependencies: async "~2.3.0" google-auth-library "~0.10.0" @@ -4099,7 +4607,7 @@ googleapis@22.2.0: got@5.6.0: version "5.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf" + resolved "https://registry.npmjs.org/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf" dependencies: create-error-class "^3.0.1" duplexer2 "^0.1.4" @@ -4120,7 +4628,7 @@ got@5.6.0: got@7.1.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + resolved "https://registry.npmjs.org/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" dependencies: decompress-response "^3.2.0" duplexer3 "^0.1.4" @@ -4139,7 +4647,7 @@ got@7.1.0: got@^3.2.0: version "3.3.1" - resolved "https://registry.yarnpkg.com/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca" + resolved "https://registry.npmjs.org/got/-/got-3.3.1.tgz#e5d0ed4af55fc3eef4d56007769d98192bcb2eca" dependencies: duplexify "^3.2.0" infinity-agent "^2.0.0" @@ -4154,7 +4662,7 @@ got@^3.2.0: got@^5.0.0: version "5.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" + resolved "https://registry.npmjs.org/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" dependencies: create-error-class "^3.0.1" duplexer2 "^0.1.4" @@ -4174,7 +4682,7 @@ got@^5.0.0: got@^6.7.1: version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + resolved "https://registry.npmjs.org/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" dependencies: create-error-class "^3.0.0" duplexer3 "^0.1.4" @@ -4190,31 +4698,40 @@ got@^6.7.1: graceful-fs@4.1.11, graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" graceful-fs@^3.0.0: version "3.0.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" dependencies: natives "^1.1.0" graceful-fs@~1.2.0: version "1.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" "graceful-readlink@>= 1.0.0": version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" growl@1.10.3: version "1.10.3" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" -grpc@1.7.1, grpc@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.7.1.tgz#a1eecd074e78ffe5bb3bb64dcc7417d14fdb5cc4" +grpc@1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/grpc/-/grpc-1.4.1.tgz#3ee4a8346a613f2823928c9f8f99081b6368ec7c" dependencies: arguejs "^0.2.3" + lodash "^4.15.0" + nan "^2.0.0" + node-pre-gyp "^0.6.35" + protobufjs "^5.0.0" + +grpc@^1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/grpc/-/grpc-1.9.1.tgz#18d7cfce153ebf952559e62dadbc8bbb85da1eac" + dependencies: lodash "^4.15.0" nan "^2.0.0" node-pre-gyp "^0.6.39" @@ -4232,39 +4749,39 @@ grpc@~1.7.2: gtoken@^1.2.1, gtoken@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8" + resolved "https://registry.npmjs.org/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8" dependencies: google-p12-pem "^0.1.0" jws "^3.0.0" mime "^1.4.1" request "^2.72.0" -gulp-cli@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-1.4.0.tgz#6f5bbe2cd0bdb4849d12cf9e1246a5861f8b4f88" +gulp-cli@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.0.1.tgz#7847e220cb3662f2be8a6d572bf14e17be5a994b" dependencies: + ansi-colors "^1.0.1" archy "^1.0.0" - chalk "^1.1.0" - copy-props "^1.4.1" - fancy-log "^1.1.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" gulplog "^1.0.0" - interpret "^1.0.0" - liftoff "^2.3.0" - lodash.isfunction "^3.0.8" - lodash.isplainobject "^4.0.4" - lodash.sortby "^4.5.0" - matchdep "^1.0.0" + interpret "^1.1.0" + isobject "^3.0.1" + liftoff "^2.5.0" + matchdep "^2.0.0" mute-stdout "^1.0.0" pretty-hrtime "^1.0.0" - semver-greatest-satisfied-range "^1.0.0" - tildify "^1.0.0" - v8flags "^2.0.9" - wreck "^6.3.0" - yargs "^3.28.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.0.1" + yargs "^7.1.0" gulp-closure-compiler@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/gulp-closure-compiler/-/gulp-closure-compiler-0.4.0.tgz#c4726edb1b44cb758e00d5b1522e1bdcd4e1a49a" + resolved "https://registry.npmjs.org/gulp-closure-compiler/-/gulp-closure-compiler-0.4.0.tgz#c4726edb1b44cb758e00d5b1522e1bdcd4e1a49a" dependencies: glob "^5.0.14" google-closure-compiler "^20151015.0.0" @@ -4277,23 +4794,23 @@ gulp-closure-compiler@^0.4.0: gulp-concat@^2.6.1: version "2.6.1" - resolved "https://registry.yarnpkg.com/gulp-concat/-/gulp-concat-2.6.1.tgz#633d16c95d88504628ad02665663cee5a4793353" + resolved "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz#633d16c95d88504628ad02665663cee5a4793353" dependencies: concat-with-sourcemaps "^1.0.0" through2 "^2.0.0" vinyl "^2.0.0" -gulp-filter@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.0.1.tgz#5d87f662e317e5839ef7650e620e6c9008ff92d0" +gulp-filter@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.1.0.tgz#a05e11affb07cf7dcf41a7de1cb7b63ac3783e73" dependencies: - gulp-util "^3.0.6" multimatch "^2.0.0" + plugin-error "^0.1.2" streamfilter "^1.0.5" gulp-replace@^0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-0.6.1.tgz#11bf8c8fce533e33e2f6a8f2f430b955ba0be066" + resolved "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.6.1.tgz#11bf8c8fce533e33e2f6a8f2f430b955ba0be066" dependencies: istextorbinary "1.0.2" readable-stream "^2.0.1" @@ -4301,7 +4818,7 @@ gulp-replace@^0.6.1: gulp-sourcemaps@1.6.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" + resolved "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" dependencies: convert-source-map "^1.1.1" graceful-fs "^4.1.2" @@ -4309,58 +4826,36 @@ gulp-sourcemaps@1.6.0: through2 "^2.0.0" vinyl "^1.0.0" -gulp-sourcemaps@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz#833a4e28f0b8f4661075032cd782417f7cd8fb0b" +gulp-sourcemaps@^2.6.4: + version "2.6.4" + resolved "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.4.tgz#cbb2008450b1bcce6cd23bf98337be751bf6e30a" dependencies: "@gulp-sourcemaps/identity-map" "1.X" "@gulp-sourcemaps/map-sources" "1.X" - acorn "4.X" + acorn "5.X" convert-source-map "1.X" css "2.X" - debug-fabulous ">=0.1.1" + debug-fabulous "1.X" detect-newline "2.X" graceful-fs "4.X" - source-map "0.X" + source-map "~0.6.0" strip-bom-string "1.X" through2 "2.X" - vinyl "1.X" - -gulp-typescript@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/gulp-typescript/-/gulp-typescript-3.2.3.tgz#32d52ab97b97c4ce070c0419db08ea3af514d720" - dependencies: - gulp-util "~3.0.7" - source-map "~0.5.3" - through2 "~2.0.1" - vinyl-fs "~2.4.3" -gulp-util@3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.7.tgz#78925c4b8f8b49005ac01a011c557e6218941cbb" +gulp-typescript@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-4.0.1.tgz#fd9d2e06a06ea3c1c15885b82ebfb037c07d75b2" dependencies: - array-differ "^1.0.0" - array-uniq "^1.0.2" - beeper "^1.0.0" - chalk "^1.0.0" - dateformat "^1.0.11" - fancy-log "^1.1.0" - gulplog "^1.0.0" - has-gulplog "^0.1.0" - lodash._reescape "^3.0.0" - lodash._reevaluate "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.template "^3.0.0" - minimist "^1.1.0" - multipipe "^0.1.2" - object-assign "^3.0.0" - replace-ext "0.0.1" - through2 "^2.0.0" - vinyl "^0.5.0" + ansi-colors "^1.0.1" + plugin-error "^0.1.2" + source-map "^0.6.1" + through2 "^2.0.3" + vinyl "^2.1.0" + vinyl-fs "^3.0.0" -gulp-util@^3.0.0, gulp-util@^3.0.6, gulp-util@^3.0.7, gulp-util@~3.0.7: +gulp-util@^3.0.0, gulp-util@^3.0.7: version "3.0.8" - resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + resolved "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" dependencies: array-differ "^1.0.0" array-uniq "^1.0.2" @@ -4383,7 +4878,7 @@ gulp-util@^3.0.0, gulp-util@^3.0.6, gulp-util@^3.0.7, gulp-util@~3.0.7: gulp@^3.9.1: version "3.9.1" - resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" + resolved "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" dependencies: archy "^1.0.0" chalk "^1.0.0" @@ -4399,28 +4894,37 @@ gulp@^3.9.1: v8flags "^2.0.2" vinyl-fs "^0.3.0" +gulp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/gulp/-/gulp-4.0.0.tgz#95766c601dade4a77ed3e7b2b6dc03881b596366" + dependencies: + glob-watcher "^5.0.0" + gulp-cli "^2.0.0" + undertaker "^1.0.0" + vinyl-fs "^3.0.0" + gulp@gulpjs/gulp#4.0: - version "4.0.0-alpha.2" - resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/6d71a658c61edb3090221579d8f97dbe086ba2ed" + version "4.0.0-alpha.3" + resolved "https://codeload.github.com/gulpjs/gulp/tar.gz/71c094a51c7972d26f557899ddecab0210ef3776" dependencies: - glob-watcher "^3.0.0" - gulp-cli "^1.0.0" + glob-watcher "^4.0.0" + gulp-cli "^2.0.0" undertaker "^1.0.0" - vinyl-fs "^2.0.0" + vinyl-fs "^3.0.0" gulplog@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + resolved "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" dependencies: glogg "^1.0.0" handle-thing@^1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" + resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" handlebars@^4.0.1, handlebars@^4.0.2, handlebars@^4.0.3: version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" dependencies: async "^1.4.0" optimist "^0.6.1" @@ -4430,15 +4934,15 @@ handlebars@^4.0.1, handlebars@^4.0.2, handlebars@^4.0.3: har-schema@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + resolved "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" har-schema@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" har-validator@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" dependencies: chalk "^1.1.1" commander "^2.9.0" @@ -4447,97 +4951,132 @@ har-validator@~2.0.6: har-validator@~4.2.1: version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" dependencies: ajv "^4.9.1" har-schema "^1.0.5" har-validator@~5.0.3: version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" dependencies: ajv "^5.1.0" har-schema "^2.0.0" has-ansi@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" dependencies: ansi-regex "^2.0.0" -has-binary@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" +has-binary2@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz#e83dba49f0b9be4d026d27365350d9f03f54be98" dependencies: - isarray "0.0.1" + isarray "2.0.1" has-cors@1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + resolved "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" has-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" has-flag@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" has-gulplog@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + resolved "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" dependencies: sparkles "^1.0.0" has-symbol-support-x@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz#66ec2e377e0c7d7ccedb07a3a84d77510ff1bc4c" + resolved "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz#66ec2e377e0c7d7ccedb07a3a84d77510ff1bc4c" + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" has-to-string-tag-x@^1.2.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + resolved "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" dependencies: has-symbol-support-x "^1.4.1" has-unicode@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + 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.npmjs.org/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + 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.npmjs.org/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" has@^1.0.0, has@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + resolved "https://registry.npmjs.org/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" dependencies: function-bind "^1.0.2" hash-base@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" dependencies: inherits "^2.0.1" hash-base@^3.0.0: version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" hash-stream-validation@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/hash-stream-validation/-/hash-stream-validation-0.2.1.tgz#ecc9b997b218be5bb31298628bb807869b73dcd1" + resolved "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.1.tgz#ecc9b997b218be5bb31298628bb807869b73dcd1" dependencies: through2 "^2.0.0" hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.0" hawk@3.1.3, hawk@~3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + resolved "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" dependencies: boom "2.x.x" cryptiles "2.x.x" @@ -4546,7 +5085,7 @@ hawk@3.1.3, hawk@~3.1.3: hawk@~6.0.2: version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + resolved "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" dependencies: boom "4.x.x" cryptiles "3.x.x" @@ -4555,11 +5094,18 @@ hawk@~6.0.2: he@1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + resolved "https://registry.npmjs.org/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + +hipchat-notifier@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz#b6d249755437c191082367799d3ba9a0f23b231e" + dependencies: + lodash "^4.0.0" + request "^2.0.0" hmac-drbg@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" @@ -4567,29 +5113,29 @@ hmac-drbg@^1.0.0: hoek@2.x.x: version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + resolved "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + version "4.2.1" + resolved "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" home-dir@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/home-dir/-/home-dir-1.0.0.tgz#2917eb44bdc9072ceda942579543847e3017fe4e" + resolved "https://registry.npmjs.org/home-dir/-/home-dir-1.0.0.tgz#2917eb44bdc9072ceda942579543847e3017fe4e" -homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: +homedir-polyfill@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" dependencies: parse-passwd "^1.0.0" hosted-git-info@^2.1.4, hosted-git-info@^2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" hpack.js@^2.1.6: version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" dependencies: inherits "^2.0.1" obuf "^1.0.0" @@ -4598,19 +5144,19 @@ hpack.js@^2.1.6: html-entities@^1.2.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + resolved "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" htmlescape@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" + resolved "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" http-deceiver@^1.2.7: version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" -http-errors@1.6.2, http-errors@~1.6.2: +http-errors@1.6.2, http-errors@~1.6.1, http-errors@~1.6.2: version "1.6.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" dependencies: depd "1.1.1" inherits "2.0.3" @@ -4618,12 +5164,20 @@ http-errors@1.6.2, http-errors@~1.6.2: statuses ">= 1.3.1 < 2" http-parser-js@>=0.4.0: - version "0.4.9" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1" + version "0.4.10" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + +http-proxy-agent@1: + version "1.0.0" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz#cc1ce38e453bf984a0f7702d2dd59c73d081284a" + dependencies: + agent-base "2" + debug "2" + extend "3" http-proxy-middleware@~0.17.4: version "0.17.4" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" dependencies: http-proxy "^1.16.2" is-glob "^3.1.0" @@ -4632,14 +5186,14 @@ http-proxy-middleware@~0.17.4: http-proxy@1.16.2, http-proxy@^1.13.0, http-proxy@^1.16.2: version "1.16.2" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" + resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" dependencies: eventemitter3 "1.x.x" requires-port "1.x.x" http-signature@~1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" dependencies: assert-plus "^0.2.0" jsprim "^1.2.2" @@ -4647,19 +5201,30 @@ http-signature@~1.1.0: http-signature@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" sshpk "^1.7.0" +httpntlm@1.6.1: + version "1.6.1" + resolved "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz#ad01527143a2e8773cfae6a96f58656bb52a34b2" + dependencies: + httpreq ">=0.4.22" + underscore "~1.7.0" + +httpreq@>=0.4.22: + version "0.4.24" + resolved "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz#4335ffd82cd969668a39465c929ac61d6393627f" + https-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" -https-proxy-agent@^1.0.0, https-proxy-agent@~1.0.0: +https-proxy-agent@1, https-proxy-agent@^1.0.0, https-proxy-agent@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" dependencies: agent-base "2" debug "2" @@ -4667,7 +5232,7 @@ https-proxy-agent@^1.0.0, https-proxy-agent@~1.0.0: husky@^0.14.3: version "0.14.3" - resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" + resolved "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" dependencies: is-ci "^1.0.10" normalize-path "^1.0.0" @@ -4675,15 +5240,23 @@ husky@^0.14.3: i@0.3.x: version "0.3.6" - resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" + resolved "https://registry.npmjs.org/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" + +iconv-lite@0.4.15: + version "0.4.15" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" -iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13: +iconv-lite@0.4.19, iconv-lite@^0.4.17: version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -ieee754@^1.1.4, ieee754@^1.1.8: +ieee754@^1.1.4: version "1.1.8" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" ignore@^3.3.3, ignore@^3.3.5: version "3.3.7" @@ -4691,22 +5264,22 @@ ignore@^3.3.3, ignore@^3.3.5: immediate@~3.0.5: version "3.0.6" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" -import-local@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8" +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" dependencies: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" indent-string@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" dependencies: repeating "^2.0.0" @@ -4716,44 +5289,52 @@ indent-string@^3.0.0: indexof@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + resolved "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" infinity-agent@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/infinity-agent/-/infinity-agent-2.0.3.tgz#45e0e2ff7a9eb030b27d62b74b3744b7a7ac4216" + resolved "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz#45e0e2ff7a9eb030b27d62b74b3744b7a7ac4216" + +inflection@~1.10.0: + version "1.10.0" + resolved "https://registry.npmjs.org/inflection/-/inflection-1.10.0.tgz#5bffcb1197ad3e81050f8e17e21668087ee9eb2f" + +inflection@~1.3.0: + version "1.3.8" + resolved "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz#cbd160da9f75b14c3cc63578d4f396784bf3014e" inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" dependencies: once "^1.3.0" wrappy "1" inherits@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" + resolved "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" inherits@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + version "1.3.5" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 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" + resolved "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5" dependencies: source-map "~0.5.3" inquirer@^0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" dependencies: ansi-escapes "^1.1.0" ansi-regex "^2.0.0" @@ -4771,7 +5352,7 @@ inquirer@^0.12.0: inquirer@^3.0.6, inquirer@^3.2.2: version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -4788,9 +5369,9 @@ inquirer@^3.0.6, inquirer@^3.2.2: strip-ansi "^4.0.0" through "^2.3.6" -inquirer@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-5.0.1.tgz#5c0396c974fd98df4cab9afd26ed85874b563550" +inquirer@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-5.1.0.tgz#19da508931892328abbbdd4c477f1efc65abfd67" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -4808,7 +5389,7 @@ inquirer@^5.0.0: insert-module-globals@^7.0.0: version "7.0.1" - resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3" + resolved "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3" dependencies: JSONStream "^1.0.3" combine-source-map "~0.7.1" @@ -4821,163 +5402,236 @@ insert-module-globals@^7.0.0: internal-ip@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" + resolved "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" dependencies: meow "^3.3.0" -interpret@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" +interpret@^1.0.0, interpret@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + version "2.2.3" + resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" dependencies: loose-envify "^1.0.0" invert-kv@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +ip@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz#c7e356cdea225ae71b36d70f2e71a92ba4e42590" -ip@^1.1.0, ip@^1.1.5: +ip@^1.1.0, ip@^1.1.2, ip@^1.1.4, ip@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + resolved "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" -ipaddr.js@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" +ipaddr.js@1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" + +ipaddr.js@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" -is-absolute@^0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" dependencies: - is-relative "^0.2.1" - is-windows "^0.2.0" + kind-of "^6.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" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 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" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" 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" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" is-builtin-module@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" dependencies: builtin-modules "^1.0.0" is-callable@^1.1.1, is-callable@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" is-ci@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" + version "1.1.0" + resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" dependencies: ci-info "^1.0.0" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + is-date-object@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + 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.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" is-dotfile@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + resolved "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 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" + resolved "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" dependencies: is-primitive "^2.0.0" 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" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + 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" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" -is-extglob@^2.1.0: +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" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" is-finite@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" dependencies: number-is-nan "^1.0.0" 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" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 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" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 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" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 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" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" dependencies: is-extglob "^2.1.0" +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-my-ip-valid@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" + is-my-json-valid@^2.12.4: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + version "2.17.2" + resolved "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz#6b2103a288e94ef3de5cf15d29dd85fc4b78d65c" dependencies: generate-function "^2.0.0" generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" jsonpointer "^4.0.0" xtend "^4.0.0" is-natural-number@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + resolved "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" is-npm@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" is-number@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" + resolved "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" is-number@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + resolved "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 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" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + is-obj@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" is-object@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + resolved "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" is-observable@^0.2.0: version "0.2.0" @@ -4985,63 +5639,69 @@ is-observable@^0.2.0: dependencies: symbol-observable "^0.2.2" +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + dependencies: + is-number "^4.0.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" + resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" is-path-in-cwd@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + resolved "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" dependencies: is-path-inside "^1.0.0" is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + version "1.0.1" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" 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" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" -is-plain-object@^2.0.1, is-plain-object@^2.0.3: +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" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" 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" + resolved "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" is-primitive@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + resolved "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" is-promise@^2.1, is-promise@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" is-property@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + resolved "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" is-redirect@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + resolved "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" is-regex@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" dependencies: has "^1.0.1" -is-relative@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" dependencies: - is-unc-path "^0.1.1" + is-unc-path "^1.0.0" is-resolvable@^1.0.0: version "1.1.0" @@ -5049,173 +5709,181 @@ is-resolvable@^1.0.0: 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" + resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" is-stream-ended@^0.1.0: version "0.1.3" - resolved "https://registry.yarnpkg.com/is-stream-ended/-/is-stream-ended-0.1.3.tgz#a0473b267c756635486beedc7e3344e549d152ac" + resolved "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.3.tgz#a0473b267c756635486beedc7e3344e549d152ac" 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" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" is-subset@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + resolved "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" is-symbol@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" 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" + resolved "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" dependencies: text-extensions "^1.0.0" is-typedarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" -is-unc-path@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" dependencies: - unc-path-regex "^0.1.0" + unc-path-regex "^0.1.2" is-url@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" + resolved "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" -is-utf8@^0.2.0: +is-utf8@^0.2.0, is-utf8@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" is-valid-glob@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" + resolved "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" -is-windows@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" is-wsl@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" is@^3.0.1, is@^3.2.0, is@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" + resolved "https://registry.npmjs.org/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" isarray@0.0.1, isarray@~0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + resolved "https://registry.npmjs.org/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" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" isbinaryfile@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" isemail@1.x.x: version "1.2.0" - resolved "https://registry.yarnpkg.com/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" + resolved "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" isobject@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 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" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" isstream@0.1.x, isstream@~0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" -istanbul-api@^1.1.8: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620" +istanbul-api@^1.1.14: + version "1.2.2" + resolved "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.2.2.tgz#e17cd519dd5ec4141197f246fdf380b75487f3b1" dependencies: async "^2.1.4" fileset "^2.0.2" - istanbul-lib-coverage "^1.1.1" + istanbul-lib-coverage "^1.1.2" istanbul-lib-hook "^1.1.0" - istanbul-lib-instrument "^1.9.1" - istanbul-lib-report "^1.1.2" - istanbul-lib-source-maps "^1.2.2" - istanbul-reports "^1.1.3" + istanbul-lib-instrument "^1.9.2" + istanbul-lib-report "^1.1.3" + istanbul-lib-source-maps "^1.2.3" + istanbul-reports "^1.1.4" js-yaml "^3.7.0" mkdirp "^0.5.1" once "^1.4.0" istanbul-instrumenter-loader@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.0.tgz#9f553923b22360bac95e617aaba01add1f7db0b2" + resolved "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.0.tgz#9f553923b22360bac95e617aaba01add1f7db0b2" dependencies: convert-source-map "^1.5.0" istanbul-lib-instrument "^1.7.3" loader-utils "^1.1.0" schema-utils "^0.3.0" -istanbul-lib-coverage@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" +istanbul-lib-coverage@^1.1.1, istanbul-lib-coverage@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14" istanbul-lib-hook@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" + resolved "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.7.3, istanbul-lib-instrument@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e" +istanbul-lib-instrument@^1.7.3, istanbul-lib-instrument@^1.9.1, istanbul-lib-instrument@^1.9.2: + version "1.9.2" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.2.tgz#84905bf47f7e0b401d6b840da7bad67086b4aab6" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" babel-traverse "^6.18.0" babel-types "^6.18.0" babylon "^6.18.0" - istanbul-lib-coverage "^1.1.1" + istanbul-lib-coverage "^1.1.2" semver "^5.3.0" -istanbul-lib-report@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" +istanbul-lib-report@^1.1.2, istanbul-lib-report@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz#2df12188c0fa77990c0d2176d2d0ba3394188259" dependencies: - istanbul-lib-coverage "^1.1.1" + istanbul-lib-coverage "^1.1.2" mkdirp "^0.5.1" path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" +istanbul-lib-source-maps@^1.2.2, istanbul-lib-source-maps@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz#20fb54b14e14b3fb6edb6aca3571fd2143db44e6" dependencies: debug "^3.1.0" - istanbul-lib-coverage "^1.1.1" + istanbul-lib-coverage "^1.1.2" mkdirp "^0.5.1" rimraf "^2.6.1" source-map "^0.5.3" -istanbul-reports@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" +istanbul-reports@^1.1.3, istanbul-reports@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.4.tgz#5ccba5e22b7b5a5d91d5e0a830f89be334bf97bd" dependencies: handlebars "^4.0.3" istanbul@0.4.5, istanbul@^0.4.0: version "0.4.5" - resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + resolved "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" dependencies: abbrev "1.0.x" async "1.x" @@ -5234,25 +5902,25 @@ istanbul@0.4.5, istanbul@^0.4.0: istextorbinary@1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-1.0.2.tgz#ace19354d1a9a0173efeb1084ce0f87b0ad7decf" + resolved "https://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz#ace19354d1a9a0173efeb1084ce0f87b0ad7decf" dependencies: binaryextensions "~1.0.0" textextensions "~1.0.0" isurl@^1.0.0-alpha5: version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + resolved "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" dependencies: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" jasmine-core@~2.8.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e" + resolved "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e" -jasmine@^2.5.3: +jasmine@2.8.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-2.8.0.tgz#6b089c0a11576b1f16df11b80146d91d4e8b8a3e" + resolved "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz#6b089c0a11576b1f16df11b80146d91d4e8b8a3e" dependencies: exit "^0.1.2" glob "^7.0.6" @@ -5260,15 +5928,15 @@ jasmine@^2.5.3: jasminewd2@^2.1.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" + resolved "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" jju@^1.1.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/jju/-/jju-1.3.0.tgz#dadd9ef01924bc728b03f2f7979bdbd62f7a2aaa" + resolved "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz#dadd9ef01924bc728b03f2f7979bdbd62f7a2aaa" joi@^6.10.1: version "6.10.1" - resolved "https://registry.yarnpkg.com/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" + resolved "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" dependencies: hoek "2.x.x" isemail "1.x.x" @@ -5277,7 +5945,7 @@ joi@^6.10.1: join-path@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/join-path/-/join-path-1.1.1.tgz#10535a126d24cbd65f7ffcdf15ef2e631076b505" + resolved "https://registry.npmjs.org/join-path/-/join-path-1.1.1.tgz#10535a126d24cbd65f7ffcdf15ef2e631076b505" dependencies: as-array "^2.0.0" url-join "0.0.1" @@ -5285,48 +5953,44 @@ join-path@^1.1.1: js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" js-yaml@3.x, js-yaml@^3.6.1, js-yaml@^3.7.0, js-yaml@^3.9.1: version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: argparse "^1.0.7" 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.6.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" jsesc@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" json-loader@^0.5.4: version "0.5.7" - resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + resolved "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" json-parse-better-errors@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" json-parse-helpfulerror@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" + resolved "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" dependencies: jju "^1.1.0" 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" + resolved "https://registry.npmjs.org/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" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -5334,55 +5998,55 @@ json-stable-stringify-without-jsonify@^1.0.1: json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: jsonify "~0.0.0" 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" + resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45" dependencies: jsonify "~0.0.0" -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@5.0.x, 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" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" -json3@3.3.2, json3@^3.3.2: +json3@^3.3.2: version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + resolved "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" json5@^0.5.0, json5@^0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + resolved "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" jsonfile@^2.1.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" optionalDependencies: graceful-fs "^4.1.6" jsonfile@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" optionalDependencies: graceful-fs "^4.1.6" jsonify@~0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + resolved "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" jsonparse@^1.2.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" jsonpointer@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" jsonschema@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.0.tgz#d6ebaf70798db7b3a20c544f6c9ef9319b077de2" + version "1.2.2" + resolved "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.2.tgz#83ab9c63d65bf4d596f91d81195e78772f6452bc" jsonwebtoken@8.1.0: version "8.1.0" @@ -5401,7 +6065,7 @@ jsonwebtoken@8.1.0: jsonwebtoken@^7.4.1: version "7.4.3" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz#77f5021de058b605a1783fa1283e99812e645638" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz#77f5021de058b605a1783fa1283e99812e645638" dependencies: joi "^6.10.1" jws "^3.1.4" @@ -5411,7 +6075,7 @@ jsonwebtoken@^7.4.1: jsprim@^1.2.2: version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" dependencies: assert-plus "1.0.0" extsprintf "1.3.0" @@ -5420,7 +6084,7 @@ jsprim@^1.2.2: jszip@^3.1.3: version "3.1.5" - resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" + resolved "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" dependencies: core-js "~2.3.0" es6-promise "~3.0.2" @@ -5428,13 +6092,17 @@ jszip@^3.1.3: pako "~1.0.2" readable-stream "~2.0.6" -just-extend@^1.1.26: +just-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" + +just-extend@^1.1.27: version "1.1.27" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905" + resolved "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905" jwa@^1.1.4: version "1.1.5" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5" + resolved "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5" dependencies: base64url "2.0.0" buffer-equal-constant-time "1.0.1" @@ -5443,7 +6111,7 @@ jwa@^1.1.4: jws@^3.0.0, jws@^3.1.4: version "3.1.4" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2" + resolved "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2" dependencies: base64url "^2.0.0" jwa "^1.1.4" @@ -5451,27 +6119,27 @@ jws@^3.0.0, jws@^3.1.4: karma-chrome-launcher@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" + resolved "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" dependencies: fs-access "^1.0.0" which "^1.2.1" karma-cli@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/karma-cli/-/karma-cli-1.0.1.tgz#ae6c3c58a313a1d00b45164c455b9b86ce17f960" + resolved "https://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz#ae6c3c58a313a1d00b45164c455b9b86ce17f960" dependencies: resolve "^1.1.6" -karma-coverage-istanbul-reporter@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.3.0.tgz#d142cd9c55731c9e363ef7374e8ef1a31bebfadb" +karma-coverage-istanbul-reporter@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.1.tgz#2b42d145ddbb4868d85d52888c495a21c61d873c" dependencies: - istanbul-api "^1.1.8" + istanbul-api "^1.1.14" minimatch "^3.0.4" karma-coverage@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-1.1.1.tgz#5aff8b39cf6994dc22de4c84362c76001b637cf6" + resolved "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.1.tgz#5aff8b39cf6994dc22de4c84362c76001b637cf6" dependencies: dateformat "^1.0.6" istanbul "^0.4.0" @@ -5481,13 +6149,13 @@ karma-coverage@^1.1.1: karma-mocha@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-1.3.0.tgz#eeaac7ffc0e201eb63c467440d2b69c7cf3778bf" + resolved "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz#eeaac7ffc0e201eb63c467440d2b69c7cf3778bf" dependencies: minimist "1.2.0" karma-sauce-launcher@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/karma-sauce-launcher/-/karma-sauce-launcher-1.2.0.tgz#6f2558ddef3cf56879fa27540c8ae9f8bfd16bca" + resolved "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-1.2.0.tgz#6f2558ddef3cf56879fa27540c8ae9f8bfd16bca" dependencies: q "^1.5.0" sauce-connect-launcher "^1.2.2" @@ -5496,25 +6164,23 @@ karma-sauce-launcher@^1.2.0: karma-sourcemap-loader@^0.3.7: version "0.3.7" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + resolved "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" dependencies: graceful-fs "^4.1.2" -karma-spec-reporter@0.0.31, karma-spec-reporter@^0.0.31: - version "0.0.31" - resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.31.tgz#4830dc7148a155c7d7a186e632339a0d80fadec3" +karma-spec-reporter@0.0.32, karma-spec-reporter@^0.0.32: + version "0.0.32" + resolved "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz#2e9c7207ea726771260259f82becb543209e440a" dependencies: colors "^1.1.2" -karma-typescript@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/karma-typescript/-/karma-typescript-3.0.8.tgz#a1ac86b00da744dc1c03cdc7817a2982e72f1171" +karma-typescript@^3.0.12: + version "3.0.12" + resolved "https://registry.npmjs.org/karma-typescript/-/karma-typescript-3.0.12.tgz#aa2cbdd111442a09c6dbcbaaeaf48499654c6913" dependencies: acorn "^4.0.4" - amdefine "1.0.0" assert "^1.4.1" async "^2.1.4" - base64-js "^1.2.1" browser-resolve "^1.11.0" browserify-zlib "^0.2.0" buffer "^5.0.6" @@ -5525,32 +6191,27 @@ karma-typescript@^3.0.8: crypto-browserify "^3.11.1" diff "^3.2.0" domain-browser "^1.1.7" - es6-promise "^4.0.5" events "^1.1.1" glob "^7.1.1" https-browserify "^1.0.0" - ieee754 "^1.1.8" - isarray "^1.0.0" istanbul "0.4.5" json-stringify-safe "^5.0.1" karma-coverage "^1.1.1" lodash "^4.17.4" log4js "^1.1.1" - magic-string "^0.19.0" minimatch "^3.0.3" os-browserify "^0.3.0" - pad "^1.1.0" + pad "^2.0.0" path-browserify "0.0.0" process "^0.11.10" punycode "^1.4.1" querystring-es3 "^0.2.1" readable-stream "^2.3.3" - remap-istanbul "^0.8.4" - source-map ">=0.5.6" + remap-istanbul "^0.10.1" + source-map "0.6.1" stream-browserify "^2.0.1" stream-http "^2.7.2" string_decoder "^1.0.3" - through2 "2.0.1" timers-browserify "^2.0.2" tmp "0.0.29" tty-browserify "0.0.0" @@ -5558,9 +6219,9 @@ karma-typescript@^3.0.8: util "^0.10.3" vm-browserify "0.0.4" -karma-webpack@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.6.tgz#967918e59750ebe0f40829263435fde7ac81bdb4" +karma-webpack@^2.0.9: + version "2.0.9" + resolved "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.9.tgz#61c88091f7dd910635134c032b266a465affb57f" dependencies: async "~0.9.0" loader-utils "^0.2.5" @@ -5568,12 +6229,13 @@ karma-webpack@^2.0.4: source-map "^0.5.6" webpack-dev-middleware "^1.12.0" -karma@^1.7.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/karma/-/karma-1.7.1.tgz#85cc08e9e0a22d7ce9cca37c4a1be824f6a2b1ae" +karma@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/karma/-/karma-2.0.0.tgz#a02698dd7f0f05ff5eb66ab8f65582490b512e58" dependencies: bluebird "^3.3.0" body-parser "^1.16.1" + browserify "^14.5.0" chokidar "^1.4.1" colors "^1.1.0" combine-lists "^1.0.0" @@ -5586,8 +6248,8 @@ karma@^1.7.0: graceful-fs "^4.1.2" http-proxy "^1.13.0" isbinaryfile "^3.0.0" - lodash "^3.8.0" - log4js "^0.6.31" + lodash "^4.17.4" + log4js "^2.3.9" mime "^1.3.4" minimatch "^3.0.2" optimist "^0.6.1" @@ -5595,40 +6257,52 @@ karma@^1.7.0: range-parser "^1.2.0" rimraf "^2.6.0" safe-buffer "^5.0.1" - socket.io "1.7.3" - source-map "^0.5.3" - tmp "0.0.31" + socket.io "2.0.4" + source-map "^0.6.1" + tmp "0.0.33" useragent "^2.1.12" kew@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" + resolved "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" killable@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b" + resolved "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b" + +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" -kind-of@^3.0.2, kind-of@^3.1.0: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0: version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 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" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" dependencies: is-buffer "^1.1.5" +kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + klaw@^1.0.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + resolved "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" optionalDependencies: graceful-fs "^4.1.9" labeled-stream-splicer@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz#a52e1d138024c00b86b1c0c91f677918b8ae0a59" + resolved "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz#a52e1d138024c00b86b1c0c91f677918b8ae0a59" dependencies: inherits "^2.0.1" isarray "~0.0.1" @@ -5636,66 +6310,78 @@ labeled-stream-splicer@^2.0.0: last-run@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + resolved "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" dependencies: default-resolution "^2.0.0" es6-weak-map "^2.0.1" latest-version@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-1.0.1.tgz#72cfc46e3e8d1be651e1ebb54ea9f6ea96f374bb" + resolved "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz#72cfc46e3e8d1be651e1ebb54ea9f6ea96f374bb" dependencies: package-json "^1.0.0" latest-version@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" + resolved "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" dependencies: package-json "^2.0.0" lazy-cache@^1.0.3: version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + resolved "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lazy-cache@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" + dependencies: + set-getter "^0.1.0" lazy-req@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-1.1.0.tgz#bdaebead30f8d824039ce0ce149d4daa07ba1fac" + resolved "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz#bdaebead30f8d824039ce0ce149d4daa07ba1fac" lazystream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" dependencies: readable-stream "^2.0.5" lcid@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + resolved "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" dependencies: invert-kv "^1.0.0" lcov-parse@^0.0.10: version "0.0.10" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + resolved "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" -lcov-result-merger@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/lcov-result-merger/-/lcov-result-merger-1.2.0.tgz#5de1e6426f885929b77357f014de5fee1dad0553" +lcov-result-merger@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/lcov-result-merger/-/lcov-result-merger-2.0.0.tgz#ba26a3b7d15b40b0efe6e603b1354b1dded28ce1" dependencies: through2 "^2.0.1" - vinyl "^1.1.1" + vinyl "^2.0.0" vinyl-fs "^2.4.3" -lerna@^2.1.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.5.1.tgz#d07099bd3051ee799f98c753328bd69e96c6fab8" +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + dependencies: + flush-write-stream "^1.0.2" + +lerna@^2.9.0: + version "2.9.0" + resolved "https://registry.npmjs.org/lerna/-/lerna-2.9.0.tgz#303f70bc50b1c4541bdcf54eda13c36fe54401f3" dependencies: async "^1.5.0" chalk "^2.1.0" cmd-shim "^2.0.2" columnify "^1.5.4" command-join "^2.0.0" - conventional-changelog-cli "^1.3.2" - conventional-recommended-bump "^1.0.1" + conventional-changelog-cli "^1.3.13" + conventional-recommended-bump "^1.2.1" dedent "^0.7.0" execa "^0.8.0" find-up "^2.1.0" @@ -5708,7 +6394,7 @@ lerna@^2.1.0: hosted-git-info "^2.5.0" inquirer "^3.2.2" is-ci "^1.0.10" - load-json-file "^3.0.0" + load-json-file "^4.0.0" lodash "^4.17.4" minimatch "^3.0.4" npmlog "^4.1.2" @@ -5716,11 +6402,12 @@ lerna@^2.1.0: package-json "^4.0.1" path-exists "^3.0.0" read-cmd-shim "^1.0.1" - read-pkg "^2.0.0" + read-pkg "^3.0.0" rimraf "^2.6.1" safe-buffer "^5.1.1" semver "^5.4.1" signal-exit "^3.0.2" + slash "^1.0.0" strong-log-transformer "^1.0.6" temp-write "^3.3.0" write-file-atomic "^2.3.0" @@ -5730,34 +6417,49 @@ lerna@^2.1.0: levn@^0.3.0, levn@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" lexical-scope@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/lexical-scope/-/lexical-scope-1.2.0.tgz#fcea5edc704a4b3a8796cdca419c3a0afaf22df4" + resolved "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz#fcea5edc704a4b3a8796cdca419c3a0afaf22df4" dependencies: astw "^2.0.0" +libbase64@0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz#62351a839563ac5ff5bd26f12f60e9830bb751e6" + +libmime@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz#51a1a9e7448ecbd32cda54421675bb21bc093da6" + dependencies: + iconv-lite "0.4.15" + libbase64 "0.1.0" + libqp "1.1.0" + +libqp@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz#f5e6e06ad74b794fb5b5b66988bf728ef1dedbe8" + lie@~3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + resolved "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" dependencies: immediate "~3.0.5" -liftoff@^2.1.0, liftoff@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" +liftoff@^2.1.0, liftoff@^2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" dependencies: extend "^3.0.0" - findup-sync "^0.4.2" + findup-sync "^2.0.0" fined "^1.0.1" - flagged-respawn "^0.3.2" - lodash.isplainobject "^4.0.4" - lodash.isstring "^4.0.1" - lodash.mapvalues "^4.4.0" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" rechoir "^0.6.2" resolve "^1.1.7" @@ -5811,7 +6513,7 @@ listr@^0.13.0: load-json-file@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -5821,25 +6523,16 @@ load-json-file@^1.0.0: 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" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" pify "^2.0.0" strip-bom "^3.0.0" -load-json-file@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-3.0.0.tgz#7eb3735d983a7ed2262ade4ff769af5369c5c440" - dependencies: - graceful-fs "^4.1.2" - parse-json "^3.0.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" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" dependencies: graceful-fs "^4.1.2" parse-json "^4.0.0" @@ -5848,11 +6541,11 @@ load-json-file@^4.0.0: loader-runner@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" loader-utils@^0.2.5, loader-utils@~0.2.2: version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: big.js "^3.1.3" emojis-list "^2.0.0" @@ -5861,7 +6554,7 @@ loader-utils@^0.2.5, loader-utils@~0.2.2: loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" dependencies: big.js "^3.1.3" emojis-list "^2.0.0" @@ -5869,78 +6562,78 @@ loader-utils@^1.0.2, loader-utils@^1.1.0: locate-path@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" dependencies: p-locate "^2.0.0" path-exists "^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" + resolved "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" lodash._basetostring@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + resolved "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" lodash._basevalues@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + resolved "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" lodash._getnative@^3.0.0: version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + resolved "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" lodash._isiterateecall@^3.0.0: version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + resolved "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" lodash._isnative@~2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" + resolved "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" lodash._objecttypes@~2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" + resolved "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" lodash._reescape@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + resolved "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" lodash._reevaluate@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + resolved "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" lodash._reinterpolate@^3.0.0, lodash._reinterpolate@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" lodash._root@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + resolved "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" lodash._shimkeys@~2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" + resolved "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" dependencies: lodash._objecttypes "~2.4.1" lodash.clone@^4.3.2: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + resolved "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" -lodash.debounce@^4.0.6: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" +lodash.endswith@^4.2.1: + version "4.2.1" + resolved "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" lodash.escape@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + resolved "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" dependencies: lodash._root "^3.0.0" lodash.get@^4.4.2: version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" lodash.includes@^4.3.0: version "4.3.0" @@ -5948,15 +6641,15 @@ lodash.includes@^4.3.0: lodash.isarguments@2.4.x: version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-2.4.1.tgz#4931a9c08253adf091ae7ca192258a973876ecca" + resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-2.4.1.tgz#4931a9c08253adf091ae7ca192258a973876ecca" lodash.isarguments@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" lodash.isarray@^3.0.0: version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + resolved "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" lodash.isboolean@^3.0.3: version "3.0.3" @@ -5964,11 +6657,11 @@ lodash.isboolean@^3.0.3: lodash.isequal@^4.0.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" lodash.isfunction@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.8.tgz#4db709fc81bc4a8fd7127a458a5346c5cdce2c6b" + version "3.0.9" + resolved "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" lodash.isinteger@^4.0.4: version "4.0.4" @@ -5980,25 +6673,25 @@ lodash.isnumber@^3.0.3: lodash.isobject@^2.4.1, lodash.isobject@~2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" + resolved "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" dependencies: lodash._objecttypes "~2.4.1" lodash.isobject@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" + resolved "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" -lodash.isplainobject@^4.0.4, lodash.isplainobject@^4.0.6: +lodash.isplainobject@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" lodash.isstring@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" lodash.keys@^3.0.0: version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" dependencies: lodash._getnative "^3.0.0" lodash.isarguments "^3.0.0" @@ -6006,19 +6699,15 @@ lodash.keys@^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" + resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" dependencies: lodash._isnative "~2.4.1" lodash._shimkeys "~2.4.1" lodash.isobject "~2.4.1" -lodash.mapvalues@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" - lodash.memoize@~3.0.3: version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" lodash.merge@^4.6.0: version "4.6.1" @@ -6026,27 +6715,27 @@ lodash.merge@^4.6.0: lodash.noop@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" + resolved "https://registry.npmjs.org/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" lodash.once@^4.0.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" lodash.restparam@^3.0.0: version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + resolved "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" lodash.some@^4.2.2: version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + resolved "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -lodash.sortby@^4.5.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" +lodash.startswith@^4.2.1: + version "4.2.1" + resolved "https://registry.npmjs.org/lodash.startswith/-/lodash.startswith-4.2.1.tgz#c598c4adce188a27e53145731cdc6c0e7177600c" lodash.template@^3.0.0: version "3.6.2" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" dependencies: lodash._basecopy "^3.0.0" lodash._basetostring "^3.0.0" @@ -6060,64 +6749,74 @@ lodash.template@^3.0.0: lodash.template@^4.0.2: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" dependencies: lodash._reinterpolate "~3.0.0" lodash.templatesettings "^4.0.0" lodash.templatesettings@^3.0.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" dependencies: lodash._reinterpolate "^3.0.0" lodash.escape "^3.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" + resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" dependencies: lodash._reinterpolate "~3.0.0" lodash.values@^2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" + resolved "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz#abf514436b3cb705001627978cbcf30b1280eea4" dependencies: lodash.keys "~2.4.1" lodash@4.16.2: version "4.16.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.2.tgz#3e626db827048a699281a8a125226326cfc0e652" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.16.2.tgz#3e626db827048a699281a8a125226326cfc0e652" -lodash@4.17.4, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@^4.8.0: +lodash@4.17.4: version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" lodash@^2.4.1: version "2.4.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + resolved "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" lodash@^3.10.0, lodash@^3.10.1, lodash@^3.8.0: version "3.10.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + resolved "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.13.1: +lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@^4.8.0: version "4.17.5" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" lodash@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" + resolved "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" -log-driver@1.2.5, log-driver@^1.2.5: +log-driver@1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + resolved "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + +log-driver@^1.2.5: + version "1.2.7" + resolved "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" log-symbols@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" dependencies: chalk "^1.0.0" +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + dependencies: + chalk "^2.0.1" + log-update@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" @@ -6125,160 +6824,197 @@ log-update@^1.0.2: ansi-escapes "^1.0.0" cli-cursor "^1.0.2" -log4js@^0.6.31: - version "0.6.38" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd" - dependencies: - readable-stream "~1.0.2" - semver "~4.3.3" - log4js@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-1.1.1.tgz#c21d29c7604089e4f255833e7f94b3461de1ff43" + resolved "https://registry.npmjs.org/log4js/-/log4js-1.1.1.tgz#c21d29c7604089e4f255833e7f94b3461de1ff43" dependencies: debug "^2.2.0" semver "^5.3.0" streamroller "^0.4.0" -loglevel@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934" +log4js@^2.3.9: + version "2.5.3" + resolved "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz#38bb7bde5e9c1c181bd75e8bc128c5cd0409caf1" + dependencies: + circular-json "^0.5.1" + date-format "^1.2.0" + debug "^3.1.0" + semver "^5.3.0" + streamroller "^0.7.0" + optionalDependencies: + amqplib "^0.5.2" + axios "^0.15.3" + hipchat-notifier "^1.1.0" + loggly "^1.1.0" + mailgun-js "^0.7.0" + nodemailer "^2.5.0" + redis "^2.7.1" + slack-node "~0.2.0" + +loggly@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz#0a0fc1d3fa3a5ec44fdc7b897beba2a4695cebee" + dependencies: + json-stringify-safe "5.0.x" + request "2.75.x" + timespan "2.3.x" -loglevel@^1.6.1: +loglevel@^1.4.1, loglevel@^1.6.1: version "1.6.1" resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" -lolex@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" +lolex@^2.2.0, lolex@^2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807" -lolex@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.0.tgz#d6bad0f0aa5caebffcfebb09fb2caa89baaff51c" +long@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" -long@^3.2.0, long@~3: +long@~3: version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + resolved "https://registry.npmjs.org/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" longest@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + resolved "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" loose-envify@^1.0.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" dependencies: js-tokens "^3.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" + resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" dependencies: currently-unhandled "^0.4.1" signal-exit "^3.0.0" lowercase-keys@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" lru-cache@2: version "2.7.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" -lru-cache@2.2.x: - version "2.2.4" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" - -lru-cache@^4.0.1: +lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" dependencies: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@~2.6.5: + version "2.6.5" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5" + lru-queue@0.1: version "0.1.0" - resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + resolved "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" dependencies: es5-ext "~0.10.2" -magic-string@^0.19.0: - version "0.19.1" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.19.1.tgz#14d768013caf2ec8fdea16a49af82fc377e75201" +mailcomposer@4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz#0e1c44b2a07cf740ee17dc149ba009f19cadfeb4" + dependencies: + buildmail "4.0.1" + libmime "3.0.0" + +mailgun-js@^0.7.0: + version "0.7.15" + resolved "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.7.15.tgz#ee366a20dac64c3c15c03d6c1b3e0ed795252abb" dependencies: - vlq "^0.2.1" + async "~2.1.2" + debug "~2.2.0" + form-data "~2.1.1" + inflection "~1.10.0" + is-stream "^1.1.0" + path-proxy "~1.0.0" + proxy-agent "~2.0.0" + q "~1.4.0" + tsscmp "~1.0.0" make-dir@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" + version "1.2.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b" dependencies: pify "^3.0.0" make-error@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.0.tgz#52ad3a339ccf10ce62b4040b708fe707244b8b96" + version "1.3.4" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535" make-iterator@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.0.tgz#57bef5dc85d23923ba23767324d8e8f8f3d9694b" + resolved "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz#57bef5dc85d23923ba23767324d8e8f8f3d9694b" dependencies: kind-of "^3.1.0" -map-cache@^0.2.0: +map-cache@^0.2.0, map-cache@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" map-stream@~0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + resolved "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" marked@^0.3.12: - version "0.3.12" - resolved "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz#7cf25ff2252632f3fe2406bde258e94eee927519" + version "0.3.16" + resolved "https://registry.npmjs.org/marked/-/marked-0.3.16.tgz#2f188b7dfcfa6540fe9940adaf0f3b791c9a5cba" -matchdep@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-1.0.1.tgz#a57a33804491fbae208aba8f68380437abc2dca5" +matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" dependencies: - findup-sync "~0.3.0" - micromatch "^2.3.7" - resolve "~1.1.6" - stack-trace "0.0.9" + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" md5-hex@^1.2.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + resolved "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" dependencies: md5-o-matic "^0.1.1" md5-o-matic@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + resolved "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" md5.js@^1.3.4: version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" dependencies: hash-base "^3.0.0" inherits "^2.0.1" media-typer@0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" mem@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + resolved "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" dependencies: mimic-fn "^1.0.0" memoizee@0.4.X: version "0.4.11" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.11.tgz#bde9817663c9e40fdb2a4ea1c367296087ae8c8f" + resolved "https://registry.npmjs.org/memoizee/-/memoizee-0.4.11.tgz#bde9817663c9e40fdb2a4ea1c367296087ae8c8f" dependencies: d "1" es5-ext "^0.10.30" @@ -6291,18 +7027,18 @@ memoizee@0.4.X: memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" dependencies: errno "^0.1.3" readable-stream "^2.0.1" memorystream@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" meow@^3.3.0, meow@^3.7.0: version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: camelcase-keys "^2.0.0" decamelize "^1.1.2" @@ -6317,39 +7053,39 @@ meow@^3.3.0, meow@^3.7.0: merge-descriptors@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" merge-source-map@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" + version "1.1.0" + resolved "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" dependencies: - source-map "^0.5.6" + source-map "^0.6.1" merge-stream@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" dependencies: readable-stream "^2.0.1" -merge2@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.0.tgz#0f882151d988b1f3d0758945404fa73ee5923d3f" +merge2@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.2.1.tgz#271d2516ff52d4af7f7b710b8bf3e16e183fef66" merge@^1.1.3: version "1.2.0" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + resolved "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" methmeth@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/methmeth/-/methmeth-1.1.0.tgz#e80a26618e52f5c4222861bb748510bd10e29089" + resolved "https://registry.npmjs.org/methmeth/-/methmeth-1.1.0.tgz#e80a26618e52f5c4222861bb748510bd10e29089" methods@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" dependencies: arr-diff "^2.0.0" array-unique "^0.2.1" @@ -6365,128 +7101,157 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" +micromatch@^3.0.4, micromatch@^3.1.4: + version "3.1.8" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.8.tgz#5c8caa008de588eebb395e8c0ad12c128f25fff1" + 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.1" + miller-rabin@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" dependencies: bn.js "^4.0.0" brorand "^1.0.1" -"mime-db@>= 1.30.0 < 2": - version "1.31.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.31.0.tgz#a49cd8f3ebf3ed1a482b60561d9105ad40ca74cb" +"mime-db@>= 1.33.0 < 2", mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.0.8, mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" +mime-types@^2.0.8, mime-types@^2.1.11, mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: + version "2.1.18" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: - mime-db "~1.30.0" + mime-db "~1.33.0" + +mime@1.3.4: + version "1.3.4" + resolved "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" -mime@1.4.1, mime@^1.3.4, mime@^1.4.1: +mime@1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + resolved "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +mime@^1.3.4, mime@^1.4.1, mime@^1.5.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" mime@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" mimic-fn@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + version "1.2.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" mimic-response@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" minimalistic-assert@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" 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" + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" "minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: brace-expansion "^1.1.7" minimatch@^2.0.1: version "2.0.10" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" dependencies: brace-expansion "^1.0.0" minimatch@~0.2.11: version "0.2.14" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" dependencies: lru-cache "2" sigmund "~1.0.0" minimist@0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" minimist@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" minimist@~0.0.1: version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" minipass@^2.0.2, minipass@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.1.tgz#5ada97538b1027b4cf7213432428578cb564011f" + resolved "https://registry.npmjs.org/minipass/-/minipass-2.2.1.tgz#5ada97538b1027b4cf7213432428578cb564011f" dependencies: yallist "^3.0.0" minizlib@^1.0.3, minizlib@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.0.4.tgz#8ebb51dd8bbe40b0126b5633dbb36b284a2f523c" + version "1.1.0" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" dependencies: minipass "^2.2.1" +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + mkdirp@0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" dependencies: minimist "0.0.8" mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" -mocha@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.0.1.tgz#0aee5a95cf69a4618820f5e51fa31717117daf1b" - dependencies: - browser-stdout "1.3.0" - commander "2.11.0" - debug "3.1.0" - diff "3.3.1" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.3" - he "1.1.1" - mkdirp "0.5.1" - supports-color "4.4.0" - -mocha@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/mocha/-/mocha-5.0.0.tgz#cccac988b0bc5477119cba0e43de7af6d6ad8f4e" +mocha@^5.0.0, mocha@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/mocha/-/mocha-5.0.1.tgz#759b62c836b0732382a62b6b1fb245ec1bc943ac" dependencies: browser-stdout "1.3.0" commander "2.11.0" @@ -6500,16 +7265,16 @@ mocha@^5.0.0: supports-color "4.4.0" modelo@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/modelo/-/modelo-4.2.0.tgz#3b4b420023a66ca7e32bdba16e710937e14d1b0b" + version "4.2.3" + resolved "https://registry.npmjs.org/modelo/-/modelo-4.2.3.tgz#b278588a4db87fc1e5107ae3a277c0876f38d894" modify-values@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2" + resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2" module-deps@^4.0.8: version "4.1.1" - resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-4.1.1.tgz#23215833f1da13fd606ccb8087b44852dcb821fd" + resolved "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz#23215833f1da13fd606ccb8087b44852dcb821fd" dependencies: JSONStream "^1.0.3" browser-resolve "^1.7.0" @@ -6548,12 +7313,12 @@ module-deps@^6.0.0: xtend "^4.0.0" moment@2.x.x, moment@^2.6.0: - version "2.19.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.2.tgz#8a7f774c95a64550b4c7ebd496683908f9419dbe" + version "2.20.1" + resolved "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" morgan@^1.8.2: version "1.9.0" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051" + resolved "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051" dependencies: basic-auth "~2.0.0" debug "2.6.9" @@ -6561,32 +7326,43 @@ morgan@^1.8.2: on-finished "~2.3.0" on-headers "~1.0.1" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@0.7.1: version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" - -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + resolved "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" -ms@2.0.0, ms@^2.0.0: +ms@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +ms@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" multicast-dns-service-types@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + resolved "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" multicast-dns@^6.0.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.1.1.tgz#6e7de86a570872ab17058adea7160bbeca814dde" + version "6.2.3" + resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" dependencies: - dns-packet "^1.0.1" - thunky "^0.1.0" + dns-packet "^1.3.1" + thunky "^1.0.2" multimatch@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + resolved "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" dependencies: array-differ "^1.0.0" array-union "^1.0.1" @@ -6595,25 +7371,25 @@ multimatch@^2.0.0: multipipe@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + resolved "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" dependencies: duplexer2 "0.0.2" mute-stdout@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.0.tgz#5b32ea07eb43c9ded6130434cf926f46b2a7fd4d" + resolved "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.0.tgz#5b32ea07eb43c9ded6130434cf926f46b2a7fd4d" mute-stream@0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" mute-stream@0.0.7, mute-stream@~0.0.4: version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" mz@^2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" dependencies: any-promise "^1.0.0" object-assign "^4.0.1" @@ -6621,11 +7397,28 @@ mz@^2.7.0: nan@^2.0.0, nan@^2.3.0: version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" + resolved "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" + +nanomatch@^1.2.9: + version "1.2.9" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + 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-odd "^2.0.0" + 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" nash@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/nash/-/nash-2.0.4.tgz#cb964791cefd376d59cfacd80109274616aa15d2" + resolved "https://registry.npmjs.org/nash/-/nash-2.0.4.tgz#cb964791cefd376d59cfacd80109274616aa15d2" dependencies: async "^1.3.0" flat-arguments "^1.0.0" @@ -6633,8 +7426,8 @@ nash@^2.0.4: minimist "^1.1.0" natives@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" + version "1.1.1" + resolved "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz#011acce1f7cbd87f7ba6b3093d6cd9392be1c574" natural-compare@^1.4.0: version "1.4.0" @@ -6642,50 +7435,47 @@ natural-compare@^1.4.0: ncp@1.0.x: version "1.0.1" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" + resolved "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" negotiator@0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" nested-error-stacks@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz#19f619591519f096769a5ba9a86e6eeec823c3cf" + resolved "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz#19f619591519f096769a5ba9a86e6eeec823c3cf" dependencies: inherits "~2.0.1" +netmask@~1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" + next-tick@1: version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" nise@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53" + version "1.2.5" + resolved "https://registry.npmjs.org/nise/-/nise-1.2.5.tgz#a143371b65014b6807d3a6e6b4556063f3a53363" dependencies: - formatio "^1.2.0" - just-extend "^1.1.26" - lolex "^1.6.0" + "@sinonjs/formatio" "^2.0.0" + just-extend "^1.1.27" + lolex "^2.3.2" path-to-regexp "^1.7.0" text-encoding "^0.6.4" -node-fetch@^1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-forge@0.6.33: - version "0.6.33" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.33.tgz#463811879f573d45155ad6a9f43dc296e8e85ebc" +node-fetch@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.0.0.tgz#982bba43ecd4f2922a29cc186a6bbb0bb73fcba6" node-forge@0.7.1, node-forge@^0.7.1: version "0.7.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.1.tgz#9da611ea08982f4b94206b3beb4cc9665f20c300" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz#9da611ea08982f4b94206b3beb4cc9665f20c300" node-libs-browser@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" dependencies: assert "^1.1.1" browserify-zlib "^0.2.0" @@ -6713,13 +7503,13 @@ node-libs-browser@^2.0.0: node-localstorage@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/node-localstorage/-/node-localstorage-1.3.0.tgz#2e436aae8dcc9ace97b43c65c16c0d577be0a55c" + resolved "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.0.tgz#2e436aae8dcc9ace97b43c65c16c0d577be0a55c" dependencies: write-file-atomic "^1.1.4" -node-pre-gyp@^0.6.39: +node-pre-gyp@^0.6.35, node-pre-gyp@^0.6.39: version "0.6.39" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" + resolved "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" dependencies: detect-libc "^1.0.2" hawk "3.1.3" @@ -6735,38 +7525,87 @@ node-pre-gyp@^0.6.39: node-status-codes@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" + resolved "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" -node-uuid@1.x: +node-uuid@1.x, node-uuid@~1.4.7: version "1.4.8" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + resolved "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" node-version@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.1.0.tgz#f437d7ba407e65e2c4eaef8887b1718ba523d4f0" + resolved "https://registry.npmjs.org/node-version/-/node-version-1.1.0.tgz#f437d7ba407e65e2c4eaef8887b1718ba523d4f0" + +nodemailer-direct-transport@3.3.2: + version "3.3.2" + resolved "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz#e96fafb90358560947e569017d97e60738a50a86" + dependencies: + nodemailer-shared "1.1.0" + smtp-connection "2.12.0" + +nodemailer-fetch@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz#79c4908a1c0f5f375b73fe888da9828f6dc963a4" + +nodemailer-shared@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz#cf5994e2fd268d00f5cf0fa767a08169edb07ec0" + dependencies: + nodemailer-fetch "1.6.0" + +nodemailer-smtp-pool@2.8.2: + version "2.8.2" + resolved "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz#2eb94d6cf85780b1b4725ce853b9cbd5e8da8c72" + dependencies: + nodemailer-shared "1.1.0" + nodemailer-wellknown "0.1.10" + smtp-connection "2.12.0" + +nodemailer-smtp-transport@2.7.2: + version "2.7.2" + resolved "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz#03d71c76314f14ac7dbc7bf033a6a6d16d67fb77" + dependencies: + nodemailer-shared "1.1.0" + nodemailer-wellknown "0.1.10" + smtp-connection "2.12.0" + +nodemailer-wellknown@0.1.10: + version "0.1.10" + resolved "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz#586db8101db30cb4438eb546737a41aad0cf13d5" + +nodemailer@^2.5.0: + version "2.7.2" + resolved "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz#f242e649aeeae39b6c7ed740ef7b061c404d30f9" + dependencies: + libmime "3.0.0" + mailcomposer "4.0.1" + nodemailer-direct-transport "3.3.2" + nodemailer-shared "1.1.0" + nodemailer-smtp-pool "2.8.2" + nodemailer-smtp-transport "2.7.2" + socks "1.1.9" nopt@3.x: version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" dependencies: abbrev "1" nopt@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" dependencies: abbrev "1" osenv "^0.1.4" nopt@~1.0.10: version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + resolved "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" dependencies: abbrev "1" normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -6775,23 +7614,23 @@ normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package- normalize-path@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" 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" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" dependencies: remove-trailing-separator "^1.0.1" now-and-later@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" + resolved "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" dependencies: once "^1.3.2" npm-run-all@^4.1.1: version "4.1.2" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.2.tgz#90d62d078792d20669139e718621186656cea056" + resolved "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz#90d62d078792d20669139e718621186656cea056" dependencies: ansi-styles "^3.2.0" chalk "^2.1.0" @@ -6805,13 +7644,13 @@ npm-run-all@^4.1.1: npm-run-path@^2.0.0, npm-run-path@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" dependencies: path-key "^2.0.0" npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -6820,15 +7659,15 @@ npmlog@^4.0.2, npmlog@^4.1.2: null-check@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + resolved "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" 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" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -nyc@^11.2.1: - version "11.3.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.3.0.tgz#a42bc17b3cfa41f7b15eb602bc98b2633ddd76f0" +nyc@^11.4.1: + version "11.4.1" + resolved "https://registry.npmjs.org/nyc/-/nyc-11.4.1.tgz#13fdf7e7ef22d027c61d174758f6978a68f4f5e5" dependencies: archy "^1.0.0" arrify "^1.0.1" @@ -6853,120 +7692,146 @@ nyc@^11.2.1: resolve-from "^2.0.0" rimraf "^2.5.4" signal-exit "^3.0.1" - spawn-wrap "=1.3.8" + spawn-wrap "^1.4.2" test-exclude "^4.1.1" yargs "^10.0.3" yargs-parser "^8.0.0" oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" + resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" object-assign@4.X, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" object-assign@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" object-component@0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + resolved "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" -object-keys@^1.0.0, object-keys@^1.0.8: +object-keys@^1.0.0, object-keys@^1.0.11, object-keys@^1.0.8: version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4: + version "4.1.0" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" object.defaults@^1.0.0, object.defaults@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + resolved "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" dependencies: array-each "^1.0.1" array-slice "^1.0.0" for-own "^1.0.0" isobject "^3.0.0" +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + dependencies: + for-own "^1.0.0" + make-iterator "^1.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" + resolved "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" dependencies: for-own "^0.1.4" is-extendable "^0.1.1" -object.pick@^1.2.0: +object.pick@^1.2.0, object.pick@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" dependencies: isobject "^3.0.1" object.reduce@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + resolved "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" dependencies: for-own "^1.0.0" make-iterator "^1.0.0" obuf@^1.0.0, obuf@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" on-finished@^2.2.0, on-finished@~2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" dependencies: ee-first "1.1.1" on-headers@^1.0.0, on-headers@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" once@~1.3.0: version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + resolved "https://registry.npmjs.org/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" dependencies: wrappy "1" onetime@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + resolved "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" onetime@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" dependencies: mimic-fn "^1.0.0" open@^0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" + resolved "https://registry.npmjs.org/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" opn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519" + version "5.2.0" + resolved "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz#71fdf934d6827d676cecbea1531f95d354641225" dependencies: is-wsl "^1.1.0" optimist@^0.6.1, optimist@~0.6.0: version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + resolved "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" dependencies: minimist "~0.0.1" 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" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: deep-is "~0.1.3" fast-levenshtein "~2.0.4" @@ -6977,33 +7842,35 @@ optionator@^0.8.1, optionator@^0.8.2: options@>=0.0.5: version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + resolved "https://registry.npmjs.org/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" optjs@~3.2.2: version "3.2.2" - resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" + resolved "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" ora@0.2.3, ora@^0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + resolved "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" dependencies: chalk "^1.1.1" cli-cursor "^1.0.2" cli-spinners "^0.1.2" object-assign "^4.0.1" -ora@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-1.3.0.tgz#80078dd2b92a934af66a3ad72a5b910694ede51a" +ora@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ora/-/ora-2.0.0.tgz#8ec3a37fa7bffb54a3a0c188a1f6798e7e1827cd" dependencies: - chalk "^1.1.1" + chalk "^2.3.1" cli-cursor "^2.1.0" - cli-spinners "^1.0.0" - log-symbols "^1.0.2" + cli-spinners "^1.1.0" + log-symbols "^2.2.0" + strip-ansi "^4.0.0" + wcwidth "^1.0.1" orchestrator@^0.3.0: version "0.3.8" - resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" + resolved "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" dependencies: end-of-stream "~0.1.5" sequencify "~0.0.7" @@ -7011,92 +7878,128 @@ orchestrator@^0.3.0: ordered-read-streams@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" + resolved "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" ordered-read-streams@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" + resolved "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" dependencies: is-stream "^1.0.1" readable-stream "^2.0.1" +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + dependencies: + readable-stream "^2.0.1" + original@>=0.0.5: version "1.0.0" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" + resolved "https://registry.npmjs.org/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" dependencies: url-parse "1.0.x" os-browserify@^0.3.0, os-browserify@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" 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" + resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" os-locale@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + resolved "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" dependencies: lcid "^1.0.0" os-locale@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + resolved "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" dependencies: execa "^0.7.0" lcid "^1.0.0" mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@~1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" osenv@^0.1.0, osenv@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + version "0.1.5" + resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" p-cancelable@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" p-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + version "1.2.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.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" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" dependencies: p-limit "^1.1.0" p-map@^1.1.1: version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + resolved "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" p-timeout@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.0.tgz#9820f99434c5817868b4f34809ee5291660d5b6c" + version "1.2.1" + resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" dependencies: p-finally "^1.0.0" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +pac-proxy-agent@1: + version "1.1.0" + resolved "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d" + dependencies: + agent-base "2" + debug "2" + extend "3" + get-uri "2" + http-proxy-agent "1" + https-proxy-agent "1" + pac-resolver "~2.0.0" + raw-body "2" + socks-proxy-agent "2" + +pac-resolver@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/pac-resolver/-/pac-resolver-2.0.0.tgz#99b88d2f193fbdeefc1c9a529c1f3260ab5277cd" + dependencies: + co "~3.0.6" + degenerator "~1.0.2" + ip "1.0.1" + netmask "~1.0.4" + thunkify "~2.1.1" + package-json@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-1.2.0.tgz#c8ecac094227cdf76a316874ed05e27cc939a0e0" + resolved "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz#c8ecac094227cdf76a316874ed05e27cc939a0e0" dependencies: got "^3.2.0" registry-url "^3.0.0" package-json@^2.0.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" + resolved "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" dependencies: got "^5.0.0" registry-auth-token "^3.0.1" @@ -7105,33 +8008,40 @@ package-json@^2.0.0: package-json@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" dependencies: got "^6.7.1" registry-auth-token "^3.0.1" registry-url "^3.0.3" semver "^5.1.0" -pad@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pad/-/pad-1.2.1.tgz#c656342f14ab8605e9ed159b9b2f516577dfc872" +pad@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/pad/-/pad-2.0.3.tgz#e2b877496c5576c299ee3df93bee95b76532dffb" dependencies: - coffee-script "^1.12.7" wcwidth "^1.0.1" pako@~1.0.2, pako@~1.0.5: version "1.0.6" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" parents@^1.0.0, parents@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" + resolved "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" dependencies: path-platform "~0.11.15" parse-asn1@^5.0.0: version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" + resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -7140,20 +8050,20 @@ parse-asn1@^5.0.0: pbkdf2 "^3.0.3" parse-filepath@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" + version "1.0.2" + resolved "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" dependencies: - is-absolute "^0.2.3" + is-absolute "^1.0.0" map-cache "^0.2.0" path-root "^0.1.1" parse-github-repo-url@^1.3.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + resolved "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" parse-glob@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + resolved "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" dependencies: glob-base "^0.3.0" is-dotfile "^1.0.0" @@ -7162,110 +8072,108 @@ parse-glob@^3.0.4: parse-json@^2.1.0, parse-json@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" dependencies: error-ex "^1.2.0" -parse-json@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13" - dependencies: - error-ex "^1.3.1" - parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" parse-passwd@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - -parsejson@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" - dependencies: - better-assert "~1.0.0" + resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" parseqs@0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + resolved "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" dependencies: better-assert "~1.0.0" parseuri@0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + resolved "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" dependencies: better-assert "~1.0.0" -parseurl@~1.3.2: +parseurl@~1.3.1, parseurl@~1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" path-browserify@0.0.0, path-browserify@~0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" path-dirname@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" path-exists@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" dependencies: pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 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" + resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" path-key@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" path-parse@1.0.5, path-parse@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" path-platform@~0.11.15: version "0.11.15" - resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + resolved "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" + +path-proxy@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz#18e8a36859fc9d2f1a53b48dee138543c020de5e" + dependencies: + inflection "~1.3.0" path-root-regex@^0.1.0: version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + resolved "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" path-root@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + resolved "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" dependencies: path-root-regex "^0.1.0" 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" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" path-to-regexp@^1.7.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" dependencies: isarray "0.0.1" path-type@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" dependencies: graceful-fs "^4.1.2" pify "^2.0.0" @@ -7273,29 +8181,29 @@ path-type@^1.0.0: path-type@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" 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" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" dependencies: pify "^3.0.0" pathval@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" pause-stream@0.0.11: version "0.0.11" - resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + resolved "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" dependencies: through "~2.3" pbkdf2@^3.0.3: version "3.0.14" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" + resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -7305,53 +8213,72 @@ pbkdf2@^3.0.3: pend@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" performance-now@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" -pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" pify@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" pinkie-promise@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 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" + resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" pkg-dir@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" dependencies: find-up "^1.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" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" dependencies: find-up "^2.1.0" pkginfo@0.3.x: version "0.3.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" + resolved "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" pkginfo@0.x.x: version "0.4.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" + resolved "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff" + +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + +plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" pluralize@^7.0.0: version "7.0.0" @@ -7359,19 +8286,23 @@ pluralize@^7.0.0: portfinder@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-0.4.0.tgz#a3ffadffafe4fb98e0601a85eda27c27ce84ca1e" + resolved "https://registry.npmjs.org/portfinder/-/portfinder-0.4.0.tgz#a3ffadffafe4fb98e0601a85eda27c27ce84ca1e" dependencies: async "0.9.0" mkdirp "0.5.x" portfinder@^1.0.9: version "1.0.13" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" + resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" dependencies: async "^1.5.2" debug "^2.2.0" mkdirp "0.5.x" +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + power-assert-context-formatter@^1.0.7: version "1.1.1" resolved "https://registry.npmjs.org/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz#edba352d3ed8a603114d667265acce60d689ccdf" @@ -7462,47 +8393,55 @@ power-assert@^1.4.4: prelude-ls@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" prepend-http@^1.0.0, prepend-http@^1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" preserve@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + resolved "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" prettier@^1.10.2: version "1.10.2" resolved "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93" -prettier@^1.7.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" - pretty-hrtime@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" process-nextick-args@^1.0.6, process-nextick-args@^1.0.7, 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" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" process@^0.11.10, process@~0.11.0: version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" progress@2.0.0, progress@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" -promise-polyfill@^6.0.1, promise-polyfill@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.0.2.tgz#d9c86d3dc4dc2df9016e88946defd69b49b41162" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + +promise-polyfill@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" + +promise-polyfill@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.0.tgz#4d749485b44577c14137591c6f36e5d7e2dd3378" prompt@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe" + resolved "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe" dependencies: colors "^1.1.2" pkginfo "0.x.x" @@ -7513,7 +8452,7 @@ prompt@1.0.0: protobufjs@^5.0.0: version "5.0.2" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.2.tgz#59748d7dcf03d2db22c13da9feb024e16ab80c91" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.2.tgz#59748d7dcf03d2db22c13da9feb024e16ab80c91" dependencies: ascli "~1" bytebuffer "~5" @@ -7521,8 +8460,8 @@ protobufjs@^5.0.0: yargs "^3.10.0" protobufjs@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.0.tgz#04e85493c4e1653878ec283f18bc78b1e7c5d5a2" + version "6.8.5" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.5.tgz#ca064d0b1b52327b3ff9e3bb74de3624e08e5fe2" dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -7534,25 +8473,25 @@ protobufjs@^6.8.0: "@protobufjs/path" "^1.1.2" "@protobufjs/pool" "^1.1.0" "@protobufjs/utf8" "^1.1.0" - "@types/long" "^3.0.31" - "@types/node" "^7.0.29" - long "^3.2.0" + "@types/long" "^3.0.32" + "@types/node" "^8.9.4" + long "^4.0.0" protochain@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/protochain/-/protochain-1.0.5.tgz#991c407e99de264aadf8f81504b5e7faf7bfa260" + resolved "https://registry.npmjs.org/protochain/-/protochain-1.0.5.tgz#991c407e99de264aadf8f81504b5e7faf7bfa260" -protractor@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.2.0.tgz#d3f39b195e85f3539ad9d8cb6560a9d2b63297c4" +protractor@^5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/protractor/-/protractor-5.3.0.tgz#5df98201cbdaeb50826af6d05630ef1945bf9c32" dependencies: "@types/node" "^6.0.46" "@types/q" "^0.0.32" "@types/selenium-webdriver" "~2.53.39" - blocking-proxy "0.0.5" + blocking-proxy "^1.0.0" chalk "^1.1.3" glob "^7.0.3" - jasmine "^2.5.3" + jasmine "2.8.0" jasminewd2 "^2.1.0" optimist "~0.6.0" q "1.4.1" @@ -7562,30 +8501,50 @@ protractor@^5.1.2: webdriver-js-extender "^1.0.0" webdriver-manager "^12.0.6" +proxy-addr@~1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" + dependencies: + forwarded "~0.1.0" + ipaddr.js "1.4.0" + proxy-addr@~2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" + version "2.0.3" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" dependencies: forwarded "~0.1.2" - ipaddr.js "1.5.2" + ipaddr.js "1.6.0" -prr@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" +proxy-agent@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.0.0.tgz#57eb5347aa805d74ec681cb25649dba39c933499" + dependencies: + agent-base "2" + debug "2" + extend "3" + http-proxy-agent "1" + https-proxy-agent "1" + lru-cache "~2.6.5" + pac-proxy-agent "1" + socks-proxy-agent "2" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" ps-tree@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + resolved "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" dependencies: event-stream "~3.3.0" pseudomap@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" public-encrypt@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" + resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" dependencies: bn.js "^4.1.0" browserify-rsa "^4.0.0" @@ -7593,105 +8552,121 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" -pump@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" dependencies: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^1.3.3: - version "1.3.5" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b" +pumpify@^1.3.3, pumpify@^1.3.5: + version "1.4.0" + resolved "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" dependencies: - duplexify "^3.1.2" - inherits "^2.0.1" - pump "^1.0.0" + duplexify "^3.5.3" + inherits "^2.0.3" + pump "^2.0.0" punycode@1.3.2: version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" -punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: +punycode@1.4.1, punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -q@1.4.1: +q@1.4.1, q@~1.4.0: version "1.4.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + resolved "https://registry.npmjs.org/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" q@^1.4.1, q@^1.5.0: version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" qjobs@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73" + version "1.2.0" + resolved "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + +qs@6.4.0, qs@~6.4.0: + version "6.4.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +qs@6.5.0: + version "6.5.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49" qs@6.5.1, qs@~6.5.1: version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +qs@~6.2.0: + version "6.2.3" + resolved "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" qs@~6.3.0: version "6.3.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" - -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + resolved "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" querystring-es3@^0.2.0, querystring-es3@^0.2.1, querystring-es3@~0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" querystring@0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" querystringify@0.0.x: version "0.0.4" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" querystringify@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" randomatic@^1.1.3: version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + resolved "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" dependencies: is-number "^3.0.0" kind-of "^4.0.0" randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" + version "2.0.6" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.3.tgz#b96b7df587f01dd91726c418f30553b1418e3d62" + version "1.0.4" + resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" dependencies: randombytes "^2.0.5" safe-buffer "^5.1.0" range-parser@^1.0.3, range-parser@^1.2.0, range-parser@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" -raw-body@2.3.2: +raw-body@2, raw-body@2.3.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" dependencies: bytes "3.0.0" http-errors "1.6.2" iconv-lite "0.4.19" unpipe "1.0.0" +raw-body@~2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.15" + unpipe "1.0.0" + rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: - version "1.2.2" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077" + version "1.2.5" + resolved "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" dependencies: deep-extend "~0.4.0" ini "~1.3.0" @@ -7700,40 +8675,40 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: read-all-stream@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" + resolved "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" dependencies: pinkie-promise "^2.0.0" readable-stream "^2.0.0" read-cmd-shim@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" dependencies: graceful-fs "^4.1.2" 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" + resolved "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0" dependencies: readable-stream "^2.0.2" read-pkg-up@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" dependencies: find-up "^1.0.0" read-pkg "^1.0.0" 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" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" dependencies: find-up "^2.0.0" read-pkg "^2.0.0" read-pkg@^1.0.0, read-pkg@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" dependencies: load-json-file "^1.0.0" normalize-package-data "^2.3.2" @@ -7741,7 +8716,7 @@ read-pkg@^1.0.0, read-pkg@^1.1.0: read-pkg@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" dependencies: load-json-file "^2.0.0" normalize-package-data "^2.3.2" @@ -7749,7 +8724,7 @@ read-pkg@^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" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" dependencies: load-json-file "^4.0.0" normalize-package-data "^2.3.2" @@ -7757,46 +8732,46 @@ read-pkg@^3.0.0: read@1.0.x: version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" dependencies: mute-stream "~0.0.4" -"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.2, readable-stream@~1.0.32: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" +"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3: + version "2.3.4" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071" + 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.0.3" + util-deprecate "~1.0.1" + +readable-stream@1.1.x, "readable-stream@1.x >=1.1.9", readable-stream@^1.1.7, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^1.1.7, readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.32: + version "1.0.34" + resolved "https://registry.npmjs.org/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" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" +readable-stream@~2.0.0, readable-stream@~2.0.5, readable-stream@~2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" dependencies: core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -readable-stream@~2.0.0, readable-stream@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" + inherits "~2.0.1" isarray "~1.0.0" process-nextick-args "~1.0.6" string_decoder "~0.10.x" @@ -7804,7 +8779,7 @@ readable-stream@~2.0.0, readable-stream@~2.0.6: readdirp@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" dependencies: graceful-fs "^4.1.2" minimatch "^3.0.2" @@ -7813,7 +8788,7 @@ readdirp@^2.0.0: readline2@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + resolved "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -7821,89 +8796,136 @@ readline2@^1.0.1: rechoir@^0.6.2: version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" dependencies: resolve "^1.1.6" redent@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + resolved "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" dependencies: indent-string "^2.1.0" strip-indent "^1.0.1" +redis-commands@^1.2.0: + version "1.3.1" + resolved "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b" + +redis-parser@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" + +redis@^2.7.1: + version "2.8.0" + resolved "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" + dependencies: + double-ended-queue "^2.1.0-0" + redis-commands "^1.2.0" + redis-parser "^2.6.0" + regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" + version "0.11.1" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" regex-cache@^0.4.2: version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + resolved "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" dependencies: is-equal-shallow "^0.1.3" +regex-not@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + registry-auth-token@^3.0.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + version "3.3.2" + resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" dependencies: rc "^1.1.6" safe-buffer "^5.0.1" registry-url@^3.0.0, registry-url@^3.0.3: version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" dependencies: rc "^1.0.1" -remap-istanbul@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/remap-istanbul/-/remap-istanbul-0.8.4.tgz#b4bfdfdbc90efa635e9a28b1f4a116e22c8c2697" +remap-istanbul@^0.10.1: + version "0.10.1" + resolved "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.10.1.tgz#3aa58dd5021d499f336d3ba5bf3bbb91c1b88e37" dependencies: amdefine "^1.0.0" - gulp-util "3.0.7" istanbul "0.4.5" - source-map ">=0.5.6" + minimatch "^3.0.3" + plugin-error "^0.1.2" + source-map "^0.6.1" through2 "2.0.1" -remove-trailing-separator@^1.0.1: +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" repeat-element@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" repeat-string@^0.2.2: version "0.2.2" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" -repeat-string@^1.5.2: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" repeating@^1.1.2: version "1.1.3" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" + resolved "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" dependencies: is-finite "^1.0.0" repeating@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" dependencies: is-finite "^1.0.0" replace-ext@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" replace-ext@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + +replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" replacestream@^4.0.0: version "4.0.3" - resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" + resolved "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" dependencies: escape-string-regexp "^1.0.3" object-assign "^4.0.1" @@ -7924,9 +8946,35 @@ request-promise@^4.2.2: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" +request@2.75.x: + version "2.75.0" + resolved "https://registry.npmjs.org/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.0.0" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + request@2.79.0: version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + resolved "https://registry.npmjs.org/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" @@ -7951,7 +8999,7 @@ request@2.79.0: request@2.81.0: version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + resolved "https://registry.npmjs.org/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" @@ -7976,9 +9024,9 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@2.x, request@^2.58.0, request@^2.72.0, request@^2.74.0, request@^2.78.0, request@^2.79.0, request@^2.81.0, request@^2.83.0: +request@2.x, request@^2.0.0, request@^2.58.0, request@^2.72.0, request@^2.74.0, request@^2.78.0, request@^2.79.0, request@^2.81.0, request@^2.83.0: version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + resolved "https://registry.npmjs.org/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: aws-sign2 "~0.7.0" aws4 "^1.6.0" @@ -8003,13 +9051,22 @@ request@2.x, request@^2.58.0, request@^2.72.0, request@^2.74.0, request@^2.78.0, tunnel-agent "^0.6.0" uuid "^3.1.0" +requestretry@^1.2.2: + version "1.13.0" + resolved "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz#213ec1006eeb750e8b8ce54176283d15a8d55d94" + dependencies: + extend "^3.0.0" + lodash "^4.15.0" + request "^2.74.0" + when "^3.7.7" + require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 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" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" require-uncached@^1.0.3: version "1.0.3" @@ -8020,20 +9077,20 @@ require-uncached@^1.0.3: requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" resolve-cwd@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" dependencies: resolve-from "^3.0.0" -resolve-dir@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" dependencies: - expand-tilde "^1.2.2" - global-modules "^0.2.3" + expand-tilde "^2.0.0" + global-modules "^1.0.0" resolve-from@^1.0.0: version "1.0.1" @@ -8041,48 +9098,55 @@ resolve-from@^1.0.0: resolve-from@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" resolve-from@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + dependencies: + value-or-function "^3.0.0" -resolve-url@~0.2.1: +resolve-url@^0.2.1, resolve-url@~0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" -resolve@1.1.7, resolve@1.1.x, resolve@~1.1.6: +resolve@1.1.7, resolve@1.1.x: version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2, resolve@^1.4.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" dependencies: path-parse "^1.0.5" restore-cursor@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" dependencies: exit-hook "^1.0.0" onetime "^1.0.0" restore-cursor@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" dependencies: onetime "^2.0.0" signal-exit "^3.0.2" -retry-request@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-3.1.1.tgz#0c6ec046253f2f8475e9465c4eb58c802675014c" - dependencies: - request "^2.81.0" - through2 "^2.0.0" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" -retry-request@^3.1.0, retry-request@^3.3.1: +retry-axios@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.0.tgz#7858ad369872d6acaf05fd97b0490969c9c35ee2" + +retry-request@^3.0.0, retry-request@^3.3.1: version "3.3.1" resolved "https://registry.npmjs.org/retry-request/-/retry-request-3.3.1.tgz#fb71276235a617e97551e9be737ab5b91591fb9e" dependencies: @@ -8091,23 +9155,29 @@ retry-request@^3.1.0, retry-request@^3.3.1: revalidator@0.1.x: version "0.1.8" - resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" + resolved "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" right-align@^0.1.1: version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + resolved "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" dependencies: align-text "^0.1.1" -rimraf@2, rimraf@2.6.2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rimraf@2.6.1: + version "2.6.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: glob "^7.0.5" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" + resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" dependencies: hash-base "^2.0.0" inherits "^2.0.1" @@ -8118,7 +9188,7 @@ rollup@^0.55.3: router@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/router/-/router-1.3.2.tgz#bfaa16888a5283d5ee40d999da7a9fa15296a60c" + resolved "https://registry.npmjs.org/router/-/router-1.3.2.tgz#bfaa16888a5283d5ee40d999da7a9fa15296a60c" dependencies: array-flatten "2.1.1" debug "2.6.9" @@ -8130,33 +9200,39 @@ router@^1.3.1: rsvp@^3.0.18, rsvp@^3.6.2: version "3.6.2" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" run-async@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + resolved "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" dependencies: once "^1.3.0" run-async@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" dependencies: is-promise "^2.1.0" +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + rx-lite-aggregates@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + resolved "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" dependencies: rx-lite "*" rx-lite@*, rx-lite@^4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" rx-lite@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" rxjs@^5.4.2, rxjs@^5.5.2: version "5.5.6" @@ -8166,15 +9242,21 @@ rxjs@^5.4.2, rxjs@^5.5.2: safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" -samsam@1.x: +samsam@1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" + resolved "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" sauce-connect-launcher@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/sauce-connect-launcher/-/sauce-connect-launcher-1.2.3.tgz#d2f931ad7ae8fdabf1968a440e7b20417aca7f86" + resolved "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.3.tgz#d2f931ad7ae8fdabf1968a440e7b20417aca7f86" dependencies: adm-zip "~0.4.3" async "^2.1.2" @@ -8184,48 +9266,47 @@ sauce-connect-launcher@^1.2.2: saucelabs@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.4.0.tgz#b934a9af9da2874b3f40aae1fcde50a4466f5f38" + resolved "https://registry.npmjs.org/saucelabs/-/saucelabs-1.4.0.tgz#b934a9af9da2874b3f40aae1fcde50a4466f5f38" dependencies: https-proxy-agent "^1.0.0" saucelabs@~1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.3.0.tgz#d240e8009df7fa87306ec4578a69ba3b5c424fee" + resolved "https://registry.npmjs.org/saucelabs/-/saucelabs-1.3.0.tgz#d240e8009df7fa87306ec4578a69ba3b5c424fee" dependencies: https-proxy-agent "^1.0.0" sax@0.6.x: version "0.6.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-0.6.1.tgz#563b19c7c1de892e09bfc4f2fc30e3c27f0952b9" + resolved "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz#563b19c7c1de892e09bfc4f2fc30e3c27f0952b9" sax@>=0.6.0: version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" schema-utils@^0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" dependencies: ajv "^5.0.0" seek-bzip@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + resolved "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" dependencies: commander "~2.8.1" select-hose@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" -selenium-assistant@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/selenium-assistant/-/selenium-assistant-5.2.0.tgz#5bb5b863da70419578ebcf3993781ec6eb0327f7" +selenium-assistant@^5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/selenium-assistant/-/selenium-assistant-5.3.0.tgz#0583a77fbfbc339334cb6a4efe33a5cec5dfe30a" dependencies: chalk "^2.1.0" - del "^3.0.0" dmg "^0.1.0" - fs-extra "^4.0.2" + fs-extra "^5.0.0" mkdirp "^0.5.1" node-localstorage "^1.3.0" request "^2.83.0" @@ -8237,7 +9318,7 @@ selenium-assistant@^5.2.0: selenium-webdriver@3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" + resolved "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" dependencies: jszip "^3.1.3" rimraf "^2.5.4" @@ -8246,7 +9327,7 @@ selenium-webdriver@3.6.0: selenium-webdriver@^2.53.2: version "2.53.3" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz#d29ff5a957dff1a1b49dc457756e4e4bfbdce085" + resolved "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz#d29ff5a957dff1a1b49dc457756e4e4bfbdce085" dependencies: adm-zip "0.4.4" rimraf "^2.2.8" @@ -8255,42 +9336,60 @@ selenium-webdriver@^2.53.2: xml2js "0.4.4" selfsigned@^1.9.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.1.tgz#bf8cb7b83256c4551e31347c6311778db99eec52" + version "1.10.2" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.2.tgz#b4449580d99929b65b10a48389301a6592088758" dependencies: - node-forge "0.6.33" + node-forge "0.7.1" semver-diff@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" dependencies: semver "^5.0.3" -semver-greatest-satisfied-range@^1.0.0: +semver-greatest-satisfied-range@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + resolved "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" dependencies: sver-compat "^1.5.0" -"semver@2 || 3 || 4 || 5", semver@5.4.1, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: + version "5.5.0" + resolved "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +semver@5.4.1: version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + resolved "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" -semver@^4.1.0, semver@~4.3.3: +semver@^4.1.0: version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - -semver@^5.5.0: - version "5.5.0" - resolved "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + resolved "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" semver@~5.0.1: version "5.0.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + resolved "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + +send@0.15.4: + version "0.15.4" + resolved "https://registry.npmjs.org/send/-/send-0.15.4.tgz#985faa3e284b0273c793364a35c6737bd93905b9" + dependencies: + debug "2.6.8" + depd "~1.1.1" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.0" + fresh "0.5.0" + http-errors "~1.6.2" + mime "1.3.4" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.1" send@0.16.1: version "0.16.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" + resolved "https://registry.npmjs.org/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" dependencies: debug "2.6.9" depd "~1.1.1" @@ -8308,17 +9407,21 @@ send@0.16.1: sequencify@~0.0.7: version "0.0.7" - resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" + resolved "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" + +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" serializerr@1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/serializerr/-/serializerr-1.0.3.tgz#12d4c5aa1c3ffb8f6d1dc5f395aa9455569c3f91" + resolved "https://registry.npmjs.org/serializerr/-/serializerr-1.0.3.tgz#12d4c5aa1c3ffb8f6d1dc5f395aa9455569c3f91" dependencies: protochain "^1.0.5" serve-index@^1.7.2: version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" dependencies: accepts "~1.3.4" batch "0.6.1" @@ -8328,9 +9431,18 @@ serve-index@^1.7.2: mime-types "~2.1.17" parseurl "~1.3.2" +serve-static@1.12.4: + version "1.12.4" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz#9b6aa98eeb7253c4eedc4c1f6fdbca609901a961" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.15.4" + serve-static@1.13.1: version "1.13.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" dependencies: encodeurl "~1.0.1" escape-html "~1.0.3" @@ -8339,51 +9451,75 @@ serve-static@1.13.1: 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" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-getter@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" + dependencies: + to-object-path "^0.3.0" set-immediate-shim@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + resolved "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + 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.npmjs.org/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" setimmediate@^1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" setprototypeof@1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" setprototypeof@1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4: - version "2.4.9" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d" + version "2.4.10" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b" dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" shasum@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f" + resolved "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f" 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" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 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" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" shell-quote@^1.6.1: version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" dependencies: array-filter "~0.0.0" array-map "~0.0.0" @@ -8392,7 +9528,7 @@ shell-quote@^1.6.1: shelljs@0.7.7: version "0.7.7" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" + resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -8404,42 +9540,36 @@ shelljs@~0.5: sigmund@~1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + resolved "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -simple-git@^1.80.1: - version "1.82.0" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.82.0.tgz#5fd0efe9c4ee78e5d942f276ac492b32e041a01a" +simple-git@^1.91.0: + version "1.91.0" + resolved "https://registry.npmjs.org/simple-git/-/simple-git-1.91.0.tgz#842db6c2ba08328e93c17391a895b850518cd13a" dependencies: debug "^3.1.0" -sinon@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.1.2.tgz#65610521d926fb53742dd84cd599f0b89a82f440" - dependencies: - diff "^3.1.0" - formatio "1.2.0" - lodash.get "^4.4.2" - lolex "^2.2.0" - nise "^1.2.0" - supports-color "^4.4.0" - type-detect "^4.0.0" - -sinon@^4.1.3: - version "4.2.2" - resolved "https://registry.npmjs.org/sinon/-/sinon-4.2.2.tgz#e039ab27bdb426fc61363c380726e996a2e2c620" +sinon@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/sinon/-/sinon-4.3.0.tgz#cec9b27d5f4e2c63c1a79c9dc1c05d34bb088234" dependencies: + "@sinonjs/formatio" "^2.0.0" diff "^3.1.0" - formatio "1.2.0" lodash.get "^4.4.2" lolex "^2.2.0" nise "^1.2.0" supports-color "^5.1.0" type-detect "^4.0.5" +slack-node@~0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz#de4b8dddaa8b793f61dbd2938104fdabf37dfa30" + dependencies: + requestretry "^1.2.2" + slash@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -8456,71 +9586,106 @@ slice-ansi@1.0.0: slide@^1.1.5: version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + resolved "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +smart-buffer@^1.0.13, smart-buffer@^1.0.4: + version "1.1.15" + resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" + +smtp-connection@2.12.0: + version "2.12.0" + resolved "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz#d76ef9127cb23c2259edb1e8349c2e8d5e2d74c1" + dependencies: + httpntlm "1.6.1" + nodemailer-shared "1.1.0" snakeize@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/snakeize/-/snakeize-0.1.0.tgz#10c088d8b58eb076b3229bb5a04e232ce126422d" + resolved "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz#10c088d8b58eb076b3229bb5a04e232ce126422d" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + 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.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.1" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370" + 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 "^2.0.0" sntp@1.x.x: version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + resolved "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" dependencies: hoek "2.x.x" sntp@2.x.x: version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + resolved "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" dependencies: hoek "4.x.x" -socket.io-adapter@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b" - dependencies: - debug "2.3.3" - socket.io-parser "2.3.1" +socket.io-adapter@~1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b" -socket.io-client@1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377" +socket.io-client@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz#0918a552406dc5e540b380dcd97afc4a64332f8e" dependencies: backo2 "1.0.2" + base64-arraybuffer "0.1.5" component-bind "1.0.0" component-emitter "1.2.1" - debug "2.3.3" - engine.io-client "1.8.3" - has-binary "0.1.7" + debug "~2.6.4" + engine.io-client "~3.1.0" + has-cors "1.1.0" indexof "0.0.1" object-component "0.0.3" + parseqs "0.0.5" parseuri "0.0.5" - socket.io-parser "2.3.1" + socket.io-parser "~3.1.1" to-array "0.1.4" -socket.io-parser@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0" +socket.io-parser@~3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.2.tgz#dbc2282151fc4faebbe40aeedc0772eba619f7f2" dependencies: - component-emitter "1.1.2" - debug "2.2.0" - isarray "0.0.1" - json3 "3.3.2" + component-emitter "1.2.1" + debug "~2.6.4" + has-binary2 "~1.0.2" + isarray "2.0.1" -socket.io@1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b" +socket.io@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz#c1a4590ceff87ecf13c72652f046f716b29e6014" dependencies: - debug "2.3.3" - engine.io "1.8.3" - has-binary "0.1.7" - object-assign "4.1.0" - socket.io-adapter "0.5.0" - socket.io-client "1.7.3" - socket.io-parser "2.3.1" + debug "~2.6.6" + engine.io "~3.1.0" + socket.io-adapter "~1.1.0" + socket.io-client "2.0.4" + socket.io-parser "~3.1.1" sockjs-client@1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" + resolved "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" dependencies: debug "^2.6.6" eventsource "0.1.6" @@ -8529,22 +9694,44 @@ sockjs-client@1.1.4: json3 "^3.3.2" url-parse "^1.1.8" -sockjs@0.3.18: - version "0.3.18" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.18.tgz#d9b289316ca7df77595ef299e075f0f937eb4207" +sockjs@0.3.19: + version "0.3.19" + resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d" dependencies: faye-websocket "^0.10.0" - uuid "^2.0.2" + uuid "^3.0.1" + +socks-proxy-agent@2: + version "2.1.1" + resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3" + dependencies: + agent-base "2" + extend "3" + socks "~1.1.5" + +socks@1.1.9: + version "1.1.9" + resolved "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz#628d7e4d04912435445ac0b6e459376cb3e6d691" + dependencies: + ip "^1.1.2" + smart-buffer "^1.0.4" + +socks@~1.1.5: + version "1.1.10" + resolved "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" + dependencies: + ip "^1.1.4" + smart-buffer "^1.0.13" sort-keys@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" dependencies: is-plain-obj "^1.0.0" source-list-map@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" source-list-map@~0.1.7: version "0.1.8" @@ -8552,7 +9739,7 @@ source-list-map@~0.1.7: source-map-loader@^0.2.3: version "0.2.3" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-0.2.3.tgz#d4b0c8cd47d54edce3e6bfa0f523f452b5b0e521" + resolved "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.3.tgz#d4b0c8cd47d54edce3e6bfa0f523f452b5b0e521" dependencies: async "^2.5.0" loader-utils "~0.2.2" @@ -8560,87 +9747,101 @@ source-map-loader@^0.2.3: source-map-resolve@^0.3.0: version "0.3.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" dependencies: atob "~1.1.0" resolve-url "~0.2.1" source-map-url "~0.3.0" urix "~0.1.0" -source-map-support@^0.4.0, source-map-support@~0.4.0: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" +source-map-resolve@^0.5.0: + version "0.5.1" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" dependencies: - source-map "^0.5.6" + atob "^2.0.0" + 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.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab" +source-map-support@^0.5.3: + version "0.5.3" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.3.tgz#2b3d5fff298cfa4d1afd7d4352d569e9a0158e76" dependencies: source-map "^0.6.0" +source-map-support@~0.4.0: + version "0.4.18" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + source-map-url@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" -source-map@0.5.x, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: +source-map@0.5.x, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6: version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@0.X, source-map@>=0.5.6, source-map@^0.6.0, source-map@~0.6.1: +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" source-map@^0.1.38: version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" dependencies: amdefine ">=0.0.4" source-map@^0.4.4, source-map@~0.4.1: version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: amdefine ">=0.0.4" source-map@~0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" dependencies: amdefine ">=0.0.4" sparkles@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + resolved "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" -spawn-wrap@=1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" dependencies: foreground-child "^1.5.6" mkdirp "^0.5.0" os-homedir "^1.0.1" - rimraf "^2.3.3" + rimraf "^2.6.2" signal-exit "^3.0.2" - which "^1.2.4" + which "^1.3.0" spdx-correct@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" dependencies: spdx-license-ids "^1.0.2" spdx-expression-parse@~1.0.0: version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" spdx-license-ids@^1.0.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" spdy-transport@^2.0.18: version "2.0.20" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.20.tgz#735e72054c486b2354fe89e702256004a39ace4d" + resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz#735e72054c486b2354fe89e702256004a39ace4d" dependencies: debug "^2.6.8" detect-node "^2.0.3" @@ -8652,7 +9853,7 @@ spdy-transport@^2.0.18: spdy@^3.4.1: version "3.4.7" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc" + resolved "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc" dependencies: debug "^2.6.8" handle-thing "^1.2.5" @@ -8663,40 +9864,46 @@ spdy@^3.4.1: split-array-stream@^1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/split-array-stream/-/split-array-stream-1.0.3.tgz#d2b75a8e5e0d824d52fdec8b8225839dc2e35dfa" + resolved "https://registry.npmjs.org/split-array-stream/-/split-array-stream-1.0.3.tgz#d2b75a8e5e0d824d52fdec8b8225839dc2e35dfa" dependencies: async "^2.4.0" is-stream-ended "^0.1.0" +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + 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" + resolved "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" dependencies: through2 "^2.0.2" split@0.3: version "0.3.3" - resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + resolved "https://registry.npmjs.org/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" dependencies: through "2" split@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + resolved "https://registry.npmjs.org/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" dependencies: through "2" sprintf-js@^1.0.3: version "1.1.1" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -8708,21 +9915,30 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -stack-trace@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" +ssri@^5.2.4: + version "5.2.4" + resolved "https://registry.npmjs.org/ssri/-/ssri-5.2.4.tgz#9985e14041e65fc397af96542be35724ac11da52" + dependencies: + safe-buffer "^5.1.1" -stack-trace@0.0.x: +stack-trace@0.0.10, stack-trace@0.0.x: version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" "statuses@>= 1.3.1 < 2": version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" statuses@~1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" stealthy-require@^1.1.0: version "1.1.1" @@ -8730,55 +9946,62 @@ stealthy-require@^1.1.0: stream-browserify@^2.0.0, stream-browserify@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" 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" + resolved "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" dependencies: duplexer2 "~0.1.0" readable-stream "^2.0.2" stream-combiner@~0.0.4: version "0.0.4" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + resolved "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" dependencies: duplexer "~0.1.1" stream-consume@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + version "0.1.1" + resolved "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz#d3bdb598c2bd0ae82b8cac7ac50b1107a7996c48" + +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" stream-events@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.2.tgz#abf39f66c0890a4eb795bc8d5e859b2615b590b2" + resolved "https://registry.npmjs.org/stream-events/-/stream-events-1.0.2.tgz#abf39f66c0890a4eb795bc8d5e859b2615b590b2" dependencies: stubs "^3.0.0" stream-exhaust@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + resolved "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" stream-http@^2.0.0, stream-http@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" + version "2.8.0" + resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10" dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" - readable-stream "^2.2.6" + readable-stream "^2.3.3" 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" + resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" stream-splicer@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83" + resolved "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz#1b63be438a133e4b671cc1935197600175910d83" dependencies: inherits "^2.0.1" readable-stream "^2.0.2" @@ -8790,37 +10013,46 @@ stream-to-observable@^0.2.0: any-observable "^0.2.0" streamfilter@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.5.tgz#87507111beb8e298451717b511cfed8f002abf53" + version "1.0.7" + resolved "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.7.tgz#ae3e64522aa5a35c061fd17f67620c7653c643c9" dependencies: readable-stream "^2.0.2" streamroller@^0.4.0: version "0.4.1" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.4.1.tgz#d435bd5974373abd9bd9068359513085106cc05f" + resolved "https://registry.npmjs.org/streamroller/-/streamroller-0.4.1.tgz#d435bd5974373abd9bd9068359513085106cc05f" dependencies: date-format "^0.0.0" debug "^0.7.2" mkdirp "^0.5.1" readable-stream "^1.1.7" +streamroller@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b" + dependencies: + date-format "^1.2.0" + debug "^3.1.0" + mkdirp "^0.5.1" + readable-stream "^2.3.0" + string-format-obj@^1.0.0, string-format-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/string-format-obj/-/string-format-obj-1.1.0.tgz#7635610b1ef397013e8478be98a170e04983d068" + version "1.1.1" + resolved "https://registry.npmjs.org/string-format-obj/-/string-format-obj-1.1.1.tgz#c7612ca4e2ad923812a81db192dc291850aa1f65" string-length@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac" + resolved "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac" dependencies: strip-ansi "^3.0.0" string-template@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96" + resolved "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96" string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -8828,14 +10060,14 @@ string-width@^1.0.1, string-width@^1.0.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" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" string.prototype.padend@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + resolved "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" dependencies: define-properties "^1.1.2" es-abstract "^1.4.3" @@ -8843,13 +10075,13 @@ string.prototype.padend@^3.0.0: string_decoder@^1.0.0, string_decoder@^1.0.3, string_decoder@~1.0.0, string_decoder@~1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: safe-buffer "~5.1.0" string_decoder@~0.10.x: version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" stringifier@^1.3.0: version "1.3.0" @@ -8861,75 +10093,75 @@ stringifier@^1.3.0: stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + resolved "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" 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" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 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" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" dependencies: ansi-regex "^3.0.0" strip-bom-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" + resolved "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" dependencies: first-chunk-stream "^1.0.0" strip-bom "^2.0.0" strip-bom-string@1.X: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + resolved "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" strip-bom@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" dependencies: first-chunk-stream "^1.0.0" is-utf8 "^0.2.0" strip-bom@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" dependencies: is-utf8 "^0.2.0" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" strip-dirs@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + resolved "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" dependencies: is-natural-number "^4.0.1" strip-eof@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" strip-indent@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" dependencies: get-stdin "^4.0.1" strip-indent@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" -strip-json-comments@^2.0.0, 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" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" strong-log-transformer@^1.0.6: version "1.0.6" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz#f7fb93758a69a571140181277eea0c2eb1301fa3" + resolved "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz#f7fb93758a69a571140181277eea0c2eb1301fa3" dependencies: byline "^5.0.0" duplexer "^0.1.1" @@ -8939,17 +10171,17 @@ strong-log-transformer@^1.0.6: stubs@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" + resolved "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" subarg@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" + resolved "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" dependencies: minimist "^1.1.0" superstatic@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/superstatic/-/superstatic-5.0.1.tgz#f0a83942ad8e93c5c53a98341c4a3de229dff94e" + resolved "https://registry.npmjs.org/superstatic/-/superstatic-5.0.1.tgz#f0a83942ad8e93c5c53a98341c4a3de229dff94e" dependencies: as-array "^2.0.0" async "^1.5.2" @@ -8984,35 +10216,35 @@ superstatic@^5.0.1: supports-color@4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" dependencies: has-flag "^2.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" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" supports-color@^3.1.0, supports-color@^3.1.2: version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: has-flag "^1.0.0" -supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0: +supports-color@^4.2.1: version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" dependencies: has-flag "^2.0.0" -supports-color@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5" +supports-color@^5.1.0, supports-color@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a" dependencies: - has-flag "^2.0.0" + has-flag "^3.0.0" sver-compat@^1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + resolved "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" dependencies: es6-iterator "^2.0.1" es6-symbol "^3.1.1" @@ -9026,10 +10258,10 @@ symbol-observable@^0.2.2: resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" syntax-error@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.3.0.tgz#1ed9266c4d40be75dc55bf9bb1cb77062bb96ca1" + version "1.4.0" + resolved "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c" dependencies: - acorn "^4.0.3" + acorn-node "^1.2.0" table@^4.0.1: version "4.0.2" @@ -9044,11 +10276,11 @@ table@^4.0.1: tapable@^0.2.7: version "0.2.8" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" + resolved "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" tar-pack@^3.4.0: version "3.4.1" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" + resolved "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" dependencies: debug "^2.2.0" fstream "^1.0.10" @@ -9061,7 +10293,7 @@ tar-pack@^3.4.0: tar-stream@^1.5.0, tar-stream@^1.5.2: version "1.5.5" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55" + resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz#5cad84779f45c83b1f2508d96b09d88c7218af55" dependencies: bl "^1.0.0" end-of-stream "^1.0.0" @@ -9070,7 +10302,7 @@ tar-stream@^1.5.0, tar-stream@^1.5.2: tar@4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.0.2.tgz#e8e22bf3eec330e5c616d415a698395e294e8fad" + resolved "https://registry.npmjs.org/tar/-/tar-4.0.2.tgz#e8e22bf3eec330e5c616d415a698395e294e8fad" dependencies: chownr "^1.0.1" minipass "^2.2.1" @@ -9080,7 +10312,7 @@ tar@4.0.2: tar@^2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + resolved "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" dependencies: block-stream "*" fstream "^1.0.2" @@ -9088,7 +10320,7 @@ tar@^2.2.1: tar@^3.1.5: version "3.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-3.2.1.tgz#9aa8e41c88f09e76c166075bc71f93d5166e61b1" + resolved "https://registry.npmjs.org/tar/-/tar-3.2.1.tgz#9aa8e41c88f09e76c166075bc71f93d5166e61b1" dependencies: chownr "^1.0.1" minipass "^2.0.2" @@ -9098,11 +10330,11 @@ tar@^3.1.5: temp-dir@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + resolved "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" temp-write@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-1.1.2.tgz#75b57a3cd9f802beaae3762b11e66ab1f4afd947" + resolved "https://registry.npmjs.org/temp-write/-/temp-write-1.1.2.tgz#75b57a3cd9f802beaae3762b11e66ab1f4afd947" dependencies: graceful-fs "^4.1.2" mkdirp "^0.5.0" @@ -9110,26 +10342,26 @@ temp-write@^1.0.0: uuid "^2.0.1" temp-write@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.3.0.tgz#c1a96de2b36061342eae81f44ff001aec8f615a9" + version "3.4.0" + resolved "https://registry.npmjs.org/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492" dependencies: graceful-fs "^4.1.2" is-stream "^1.1.0" make-dir "^1.0.0" - pify "^2.2.0" + pify "^3.0.0" temp-dir "^1.0.0" uuid "^3.0.1" tempfile@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" + resolved "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" dependencies: os-tmpdir "^1.0.0" uuid "^2.0.1" test-exclude@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" + version "4.2.0" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.0.tgz#07e3613609a362c74516a717515e13322ab45b3c" dependencies: arrify "^1.0.1" micromatch "^2.3.11" @@ -9139,11 +10371,11 @@ test-exclude@^4.1.1: text-encoding@^0.6.4: version "0.6.4" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + resolved "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" text-extensions@^1.0.0: version "1.7.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" + resolved "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" text-table@~0.2.0: version "0.2.0" @@ -9151,174 +10383,210 @@ text-table@~0.2.0: textextensions@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-1.0.2.tgz#65486393ee1f2bb039a60cbba05b0b68bd9501d2" + resolved "https://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz#65486393ee1f2bb039a60cbba05b0b68bd9501d2" thenify-all@^1.0.0: version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" dependencies: thenify ">= 3.1.0 < 4" "thenify@>= 3.1.0 < 4": version "3.3.0" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" dependencies: any-promise "^1.0.0" through2-filter@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" + resolved "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" dependencies: through2 "~2.0.0" xtend "~4.0.0" through2@2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9" dependencies: readable-stream "~2.0.0" xtend "~4.0.0" -through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@^2.0.3, through2@~2.0.0, through2@~2.0.1: +through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@^2.0.3, through2@~2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" dependencies: readable-stream "^2.1.5" xtend "~4.0.1" through2@^0.6.0, through2@^0.6.1: version "0.6.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + resolved "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" dependencies: readable-stream ">=1.0.33-1 <1.1.0-0" xtend ">=4.0.0 <4.1.0-0" through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1: version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" -thunky@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-0.1.0.tgz#bf30146824e2b6e67b0f2d7a4ac8beb26908684e" +thunkify@~2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" + +thunky@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz#a862e018e3fb1ea2ec3fce5d55605cf57f247371" tildify@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" + resolved "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" dependencies: os-homedir "^1.0.0" time-stamp@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" time-stamp@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" + resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" timed-out@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" + resolved "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" timed-out@^3.0.0: version "3.1.3" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" + resolved "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" timed-out@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + resolved "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" timers-browserify@^1.0.1: version "1.4.2" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" + resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" dependencies: process "~0.11.0" timers-browserify@^2.0.2, timers-browserify@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6" + version "2.0.6" + resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae" dependencies: setimmediate "^1.0.4" timers-ext@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204" + resolved "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204" dependencies: es5-ext "~0.10.14" next-tick "1" +timespan@2.3.x: + version "2.3.0" + resolved "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz#4902ce040bd13d845c8f59b27e9d59bad6f39929" + tmp@0.0.24: version "0.0.24" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.24.tgz#d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12" - -tmp@0.0.27: - version "0.0.27" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.27.tgz#6aaf42a2d7664150ab528287068ecbc27139a013" - dependencies: - os-tmpdir "~1.0.0" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz#d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12" tmp@0.0.29: version "0.0.29" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" dependencies: os-tmpdir "~1.0.1" tmp@0.0.30: version "0.0.30" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" dependencies: os-tmpdir "~1.0.1" tmp@0.0.31: version "0.0.31" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" dependencies: os-tmpdir "~1.0.1" tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" dependencies: os-tmpdir "~1.0.2" to-absolute-glob@^0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" + resolved "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" dependencies: extend-shallow "^2.0.1" +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + to-array@0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + resolved "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" to-arraybuffer@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" to-fast-properties@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz#15358bee4a2c83bd76377ba1dc049d0f18837aae" + dependencies: + define-property "^0.2.5" + extend-shallow "^2.0.1" + regex-not "^1.0.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + dependencies: + through2 "^2.0.3" topo@1.x.x: version "1.1.0" - resolved "https://registry.yarnpkg.com/topo/-/topo-1.1.0.tgz#e9d751615d1bb87dc865db182fa1ca0a5ef536d5" + resolved "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz#e9d751615d1bb87dc865db182fa1ca0a5ef536d5" dependencies: hoek "2.x.x" touch@3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + resolved "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" dependencies: nopt "~1.0.10" tough-cookie@>=2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" dependencies: punycode "^1.4.1" toxic@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/toxic/-/toxic-1.0.0.tgz#f1154d8b6ac21875ac943a9f7408df2dfe164ea2" + resolved "https://registry.npmjs.org/toxic/-/toxic-1.0.0.tgz#f1154d8b6ac21875ac943a9f7408df2dfe164ea2" dependencies: lodash "^2.4.1" @@ -9328,47 +10596,33 @@ traverse@^0.6.6: trim-newlines@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" 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" + resolved "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" trim-right@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" try-require@^1.0.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/try-require/-/try-require-1.2.1.tgz#34489a2cac0c09c1cc10ed91ba011594d4333be2" + resolved "https://registry.npmjs.org/try-require/-/try-require-1.2.1.tgz#34489a2cac0c09c1cc10ed91ba011594d4333be2" -ts-loader@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-3.1.1.tgz#602d93c12029eaf8fa1ee478a90785d40c5f6658" +ts-loader@^3.5.0: + version "3.5.0" + resolved "https://registry.npmjs.org/ts-loader/-/ts-loader-3.5.0.tgz#151d004dcddb4cf8e381a3bf9d6b74c2d957a9c0" dependencies: chalk "^2.3.0" enhanced-resolve "^3.0.0" loader-utils "^1.0.2" + micromatch "^3.1.4" semver "^5.0.1" -ts-node@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz#c13c6a3024e30be1180dd53038fc209289d4bf69" - dependencies: - arrify "^1.0.0" - chalk "^2.0.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.4.0" - tsconfig "^6.0.0" - v8flags "^3.0.0" - yn "^2.0.0" - -ts-node@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-4.1.0.tgz#36d9529c7b90bb993306c408cd07f7743de20712" +ts-node@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-5.0.0.tgz#9aa573889ad7949411f972981c209e064705e36f" dependencies: arrify "^1.0.0" chalk "^2.3.0" @@ -9376,91 +10630,78 @@ ts-node@^4.1.0: make-error "^1.1.1" minimist "^1.2.0" mkdirp "^0.5.1" - source-map-support "^0.5.0" - tsconfig "^7.0.0" - v8flags "^3.0.0" + source-map-support "^0.5.3" yn "^2.0.0" -tsconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz#6b0e8376003d7af1864f8df8f89dd0059ffcd032" - dependencies: - strip-bom "^3.0.0" - strip-json-comments "^2.0.0" - -tsconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" - dependencies: - "@types/strip-bom" "^3.0.0" - "@types/strip-json-comments" "0.0.30" - strip-bom "^3.0.0" - strip-json-comments "^2.0.0" - -tslib@^1.7.1, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.0" resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" -tslint@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.8.0.tgz#1f49ad5b2e77c76c3af4ddcae552ae4e3612eb13" +tslint@^5.9.1: + version "5.9.1" + resolved "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" dependencies: babel-code-frame "^6.22.0" builtin-modules "^1.1.1" - chalk "^2.1.0" - commander "^2.9.0" + chalk "^2.3.0" + commander "^2.12.1" diff "^3.2.0" glob "^7.1.1" + js-yaml "^3.7.0" minimatch "^3.0.4" resolve "^1.3.2" semver "^5.3.0" - tslib "^1.7.1" + tslib "^1.8.0" tsutils "^2.12.1" +tsscmp@~1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97" + tsutils@^2.12.1: - version "2.15.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.15.0.tgz#90831e5908cca10b28cdaf83a56dcf8156aed7c6" + version "2.21.1" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.21.1.tgz#5b23c263233300ed7442b4217855cbc7547c296a" dependencies: tslib "^1.8.1" -tty-browserify@0.0.0, tty-browserify@~0.0.0: +tty-browserify@0.0.0: version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" -tty-browserify@0.0.1: +tty-browserify@0.0.1, tty-browserify@~0.0.0: version "0.0.1" resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" tunnel-agent@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" dependencies: safe-buffer "^5.0.1" tunnel-agent@~0.4.1: version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" type-check@~0.3.2: version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" dependencies: prelude-ls "~1.1.2" type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2" + version "4.0.8" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" type-is@~1.6.15: - version "1.6.15" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" + version "1.6.16" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" dependencies: media-typer "0.3.0" - mime-types "~2.1.15" + mime-types "~2.1.18" type-name@^2.0.1: version "2.0.2" @@ -9468,15 +10709,15 @@ type-name@^2.0.1: typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^2.4.2: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.1.tgz#ef39cdea27abac0b500242d6726ab90e0c846631" +typescript@^2.7.2: + version "2.7.2" + resolved "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" uglify-js@^2.6, uglify-js@^2.8.29: version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -9485,11 +10726,11 @@ uglify-js@^2.6, uglify-js@^2.8.29: uglify-to-browserify@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + resolved "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" uglifyjs-webpack-plugin@^0.4.6: version "0.4.6" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + resolved "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" dependencies: source-map "^0.5.6" uglify-js "^2.8.29" @@ -9497,45 +10738,53 @@ uglifyjs-webpack-plugin@^0.4.6: uid-number@^0.0.6: version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + resolved "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" ultron@1.0.x: version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + resolved "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" umd@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e" + resolved "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz#8ae556e11011f63c2596708a8837259f01b3d60e" unbzip2-stream@^1.0.9: version "1.2.5" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47" + resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47" dependencies: buffer "^3.0.1" through "^2.3.6" -unc-path-regex@^0.1.0: +unc-path-regex@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + resolved "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" underscore.string@3.3.4: version "3.3.4" - resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.4.tgz#2c2a3f9f83e64762fdc45e6ceac65142864213db" + resolved "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz#2c2a3f9f83e64762fdc45e6ceac65142864213db" dependencies: sprintf-js "^1.0.3" util-deprecate "^1.0.2" underscore@1.x: version "1.8.3" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + +underscore@~1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" undertaker-registry@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + resolved "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" undertaker@^1.0.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.0.tgz#339da4646252d082dc378e708067299750e11b49" + resolved "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz#339da4646252d082dc378e708067299750e11b49" dependencies: arr-flatten "^1.0.1" arr-map "^2.0.0" @@ -9547,26 +10796,47 @@ undertaker@^1.0.0: object.reduce "^1.0.0" undertaker-registry "^1.0.0" +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + unique-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" + resolved "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" unique-stream@^2.0.2: version "2.2.1" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" + resolved "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" dependencies: json-stable-stringify "^1.0.0" through2-filter "^2.0.0" unique-string@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" dependencies: crypto-random-string "^1.0.0" universal-analytics@^0.3.9: version "0.3.11" - resolved "https://registry.yarnpkg.com/universal-analytics/-/universal-analytics-0.3.11.tgz#512879193a12a66dcbd9185121389bab913cd4b6" + resolved "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.3.11.tgz#512879193a12a66dcbd9185121389bab913cd4b6" dependencies: async "0.2.x" node-uuid "1.x" @@ -9583,23 +10853,39 @@ universal-deep-strict-equal@^1.2.1: universalify@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" unzip-response@^1.0.0, unzip-response@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" unzip-response@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + resolved "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + +upath@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/upath/-/upath-1.0.2.tgz#80aaae5395abc5fd402933ae2f58694f0860204c" + dependencies: + lodash.endswith "^4.2.1" + lodash.isfunction "^3.0.8" + lodash.isstring "^4.0.1" + lodash.startswith "^4.2.1" update-notifier@^0.5.0: version "0.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.5.0.tgz#07b5dc2066b3627ab3b4f530130f7eddda07a4cc" + resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-0.5.0.tgz#07b5dc2066b3627ab3b4f530130f7eddda07a4cc" dependencies: chalk "^1.0.0" configstore "^1.0.0" @@ -9611,7 +10897,7 @@ update-notifier@^0.5.0: update-notifier@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-1.0.3.tgz#8f92c515482bd6831b7c93013e70f87552c7cf5a" + resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz#8f92c515482bd6831b7c93013e70f87552c7cf5a" dependencies: boxen "^0.6.0" chalk "^1.0.0" @@ -9624,73 +10910,81 @@ update-notifier@^1.0.3: urix@^0.1.0, urix@~0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" url-join@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-0.0.1.tgz#1db48ad422d3402469a87f7d97bdebfe4fb1e3c8" + resolved "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz#1db48ad422d3402469a87f7d97bdebfe4fb1e3c8" 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" + resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" dependencies: prepend-http "^1.0.1" url-parse@1.0.x: version "1.0.5" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" dependencies: querystringify "0.0.x" requires-port "1.0.x" url-parse@^1.1.8: version "1.2.0" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" dependencies: querystringify "~1.0.0" requires-port "~1.0.0" url-to-options@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + resolved "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" url@^0.11.0, url@~0.11.0: version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" dependencies: punycode "1.3.2" querystring "0.2.0" +use@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8" + dependencies: + define-property "^0.2.5" + isobject "^3.0.0" + lazy-cache "^2.0.2" + user-home@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + resolved "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" user-home@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + resolved "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" dependencies: os-homedir "^1.0.0" useragent@^2.1.12: - version "2.2.1" - resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e" + version "2.3.0" + resolved "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" dependencies: - lru-cache "2.2.x" + lru-cache "4.1.x" tmp "0.0.x" util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" util@0.10.3, util@^0.10.3, util@~0.10.1: version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + resolved "https://registry.npmjs.org/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" dependencies: inherits "2.0.1" utile@0.3.x: version "0.3.0" - resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" + resolved "https://registry.npmjs.org/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" dependencies: async "~0.9.0" deep-equal "~0.2.1" @@ -9699,60 +10993,76 @@ utile@0.3.x: ncp "1.0.x" rimraf "2.x.x" +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" -uuid@3.1.0, uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: +uuid@3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -uuid@^2.0.1, uuid@^2.0.2: +uuid@^2.0.1: version "2.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + resolved "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" -v8flags@^2.0.2, v8flags@^2.0.9: +uws@~9.14.0: + version "9.14.0" + resolved "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95" + +v8flags@^2.0.2: version "2.1.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + resolved "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" dependencies: user-home "^1.1.1" -v8flags@^3.0.0: +v8flags@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.1.tgz#dce8fc379c17d9f2c9e9ed78d89ce00052b1b76b" + resolved "https://registry.npmjs.org/v8flags/-/v8flags-3.0.1.tgz#dce8fc379c17d9f2c9e9ed78d89ce00052b1b76b" dependencies: homedir-polyfill "^1.0.1" vali-date@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" + resolved "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" valid-url@^1: version "1.0.9" - resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + resolved "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" validate-npm-package-license@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" dependencies: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" validator@^9.4.0: - version "9.4.0" - resolved "https://registry.npmjs.org/validator/-/validator-9.4.0.tgz#c503ef88f7e6b8fb7688599267b309482d81ae60" + version "9.4.1" + resolved "https://registry.npmjs.org/validator/-/validator-9.4.1.tgz#abf466d398b561cd243050112c6ff1de6cc12663" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" vargs@0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" + resolved "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" -vary@~1.1.2: +vary@~1.1.1, vary@~1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" verror@1.10.0: version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -9760,7 +11070,7 @@ verror@1.10.0: vinyl-fs@^0.3.0: version "0.3.14" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" + resolved "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" dependencies: defaults "^1.0.0" glob-stream "^3.1.5" @@ -9771,9 +11081,9 @@ vinyl-fs@^0.3.0: through2 "^0.6.1" vinyl "^0.4.0" -vinyl-fs@^2.0.0, vinyl-fs@^2.4.3, vinyl-fs@~2.4.3: +vinyl-fs@^2.4.3: version "2.4.4" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" + resolved "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" dependencies: duplexify "^3.2.0" glob-stream "^5.3.2" @@ -9793,30 +11103,64 @@ vinyl-fs@^2.0.0, vinyl-fs@^2.4.3, vinyl-fs@~2.4.3: vali-date "^1.0.0" vinyl "^1.0.0" +vinyl-fs@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.2.tgz#1b86258844383f57581fcaac081fe09ef6d6d752" + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemaps-apply@^0.2.0: version "0.2.1" - resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + resolved "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" dependencies: source-map "^0.5.1" -vinyl@1.X, vinyl@^1.0.0, vinyl@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - vinyl@^0.4.0: version "0.4.6" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + resolved "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" dependencies: clone "^0.2.0" clone-stats "^0.0.1" vinyl@^0.5.0: version "0.5.3" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + resolved "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" dependencies: clone "^1.0.0" clone-stats "^0.0.1" @@ -9824,7 +11168,7 @@ vinyl@^0.5.0: vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" + resolved "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" dependencies: clone "^2.1.1" clone-buffer "^1.0.0" @@ -9833,34 +11177,30 @@ vinyl@^2.0.0, vinyl@^2.0.1, vinyl@^2.1.0: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vlq@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" - vm-browserify@0.0.4, vm-browserify@~0.0.1: version "0.0.4" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" dependencies: indexof "0.0.1" void-elements@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + resolved "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" walkdir@^0.0.11: version "0.0.11" - resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" + resolved "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" watch@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c" + resolved "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c" dependencies: exec-sh "^0.2.0" minimist "^1.2.0" watchpack@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" dependencies: async "^2.1.2" chokidar "^1.7.0" @@ -9868,19 +11208,19 @@ watchpack@^1.4.0: wbuf@^1.1.0, wbuf@^1.7.2: version "1.7.2" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe" + resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe" dependencies: minimalistic-assert "^1.0.0" wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" dependencies: defaults "^1.0.3" wd@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/wd/-/wd-1.4.1.tgz#6b1ab39aab1728ee276c1a2b6d7321da68b16e8c" + version "1.5.0" + resolved "https://registry.npmjs.org/wd/-/wd-1.5.0.tgz#45c96a16ff9f8c0f9e7ca90f806a8b48bd0034d6" dependencies: archiver "1.3.0" async "2.0.1" @@ -9893,14 +11233,14 @@ wd@^1.4.0: webdriver-js-extender@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515" + resolved "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515" dependencies: "@types/selenium-webdriver" "^2.53.35" selenium-webdriver "^2.53.2" webdriver-manager@^12.0.6: version "12.0.6" - resolved "https://registry.yarnpkg.com/webdriver-manager/-/webdriver-manager-12.0.6.tgz#3df1a481977010b4cbf8c9d85c7a577828c0e70b" + resolved "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.0.6.tgz#3df1a481977010b4cbf8c9d85c7a577828c0e70b" dependencies: adm-zip "^0.4.7" chalk "^1.1.1" @@ -9921,32 +11261,32 @@ webpack-core@^0.6.8: source-list-map "~0.1.7" source-map "~0.4.1" -webpack-dev-middleware@^1.11.0, webpack-dev-middleware@^1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz#d34efefb2edda7e1d3b5dbe07289513219651709" +webpack-dev-middleware@1.12.2, webpack-dev-middleware@^1.12.0: + version "1.12.2" + resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e" dependencies: memory-fs "~0.4.1" - mime "^1.3.4" + mime "^1.5.0" path-is-absolute "^1.0.0" range-parser "^1.0.3" time-stamp "^2.0.0" -webpack-dev-server@^2.8.1: - version "2.9.4" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz#7883e61759c6a4b33e9b19ec4037bd4ab61428d1" +webpack-dev-server@^2.11.1: + version "2.11.1" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.1.tgz#6f9358a002db8403f016e336816f4485384e5ec0" dependencies: ansi-html "0.0.7" array-includes "^3.0.3" bonjour "^3.5.0" - chokidar "^1.6.0" + chokidar "^2.0.0" compression "^1.5.2" connect-history-api-fallback "^1.3.0" debug "^3.1.0" del "^3.0.0" - express "^4.13.3" + express "^4.16.2" html-entities "^1.2.0" http-proxy-middleware "~0.17.4" - import-local "^0.1.1" + import-local "^1.0.0" internal-ip "1.2.0" ip "^1.1.5" killable "^1.0.0" @@ -9955,41 +11295,43 @@ webpack-dev-server@^2.8.1: portfinder "^1.0.9" selfsigned "^1.9.1" serve-index "^1.7.2" - sockjs "0.3.18" + sockjs "0.3.19" sockjs-client "1.1.4" spdy "^3.4.1" - strip-ansi "^3.0.1" - supports-color "^4.2.1" - webpack-dev-middleware "^1.11.0" - yargs "^6.6.0" + strip-ansi "^3.0.0" + supports-color "^5.1.0" + webpack-dev-middleware "1.12.2" + yargs "6.6.0" webpack-sources@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.2.tgz#d0148ec083b3b5ccef1035a6b3ec16442983b27a" + version "1.1.0" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" dependencies: source-list-map "^2.0.0" source-map "~0.6.1" -webpack-stream@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-4.0.0.tgz#f3673dd907d6d9b1ea7bf51fcd1db85b5fd9e0f2" +webpack-stream@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/webpack-stream/-/webpack-stream-4.0.2.tgz#7b90aec71d45c8a4519ff8b5a4d59e039cfd02c0" dependencies: - gulp-util "^3.0.7" + fancy-log "^1.3.2" lodash.clone "^4.3.2" lodash.some "^4.2.2" memory-fs "^0.4.1" + plugin-error "^1.0.1" + supports-color "^5.2.0" through "^2.3.8" vinyl "^2.1.0" webpack "^3.4.1" -webpack@^3.4.1, webpack@^3.5.6, webpack@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83" +webpack@^3.11.0, webpack@^3.4.1: + version "3.11.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz#77da451b1d7b4b117adaf41a1a93b5742f24d894" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" - ajv "^5.1.5" - ajv-keywords "^2.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" async "^2.1.2" enhanced-resolve "^3.4.0" escope "^3.6.0" @@ -10011,52 +11353,56 @@ webpack@^3.4.1, webpack@^3.5.6, webpack@^3.8.1: websocket-driver@>=0.5.1: version "0.7.0" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" dependencies: http-parser-js ">=0.4.0" websocket-extensions ">=0.1.1" websocket-extensions@>=0.1.1: version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + +when@^3.7.7: + version "3.7.8" + resolved "https://registry.npmjs.org/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" which-module@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + resolved "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" which-module@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.4, which@^1.2.9, which@^1.3.0: +which@^1.1.1, which@^1.2.1, which@^1.2.14, which@^1.2.9, which@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + resolved "https://registry.npmjs.org/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" dependencies: string-width "^1.0.2" widest-line@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + resolved "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" dependencies: string-width "^1.0.1" window-size@0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + resolved "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" window-size@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" + resolved "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" winston@2.1.x: version "2.1.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e" + resolved "https://registry.npmjs.org/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e" dependencies: async "~1.0.0" colors "1.0.x" @@ -10066,9 +11412,9 @@ winston@2.1.x: pkginfo "0.3.x" stack-trace "0.0.x" -winston@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee" +winston@2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/winston/-/winston-2.3.1.tgz#0b48420d978c01804cf0230b648861598225a119" dependencies: async "~1.0.0" colors "1.0.x" @@ -10079,7 +11425,7 @@ winston@2.4.0: winston@^1.0.1: version "1.1.2" - resolved "https://registry.yarnpkg.com/winston/-/winston-1.1.2.tgz#68edd769ff79d4f9528cf0e5d80021aade67480c" + resolved "https://registry.npmjs.org/winston/-/winston-1.1.2.tgz#68edd769ff79d4f9528cf0e5d80021aade67480c" dependencies: async "~1.0.0" colors "1.0.x" @@ -10091,43 +11437,36 @@ winston@^1.0.1: wordwrap@0.0.2: version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" wordwrap@~0.0.2: version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" wrap-ansi@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" wrapper-webpack-plugin@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/wrapper-webpack-plugin/-/wrapper-webpack-plugin-1.0.0.tgz#55c11647f8ca990ff6f04b41d8fa4af096c31bbb" + resolved "https://registry.npmjs.org/wrapper-webpack-plugin/-/wrapper-webpack-plugin-1.0.0.tgz#55c11647f8ca990ff6f04b41d8fa4af096c31bbb" dependencies: webpack-sources "^1.0.1" wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -wreck@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/wreck/-/wreck-6.3.0.tgz#a1369769f07bbb62d6a378336a7871fc773c740b" - dependencies: - boom "2.x.x" - hoek "2.x.x" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" write-file-atomic@^1.1.2, write-file-atomic@^1.1.4: version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -10135,7 +11474,7 @@ write-file-atomic@^1.1.2, write-file-atomic@^1.1.4: write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -10143,7 +11482,7 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: 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" + resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" dependencies: detect-indent "^5.0.0" graceful-fs "^4.1.2" @@ -10154,7 +11493,7 @@ write-json-file@^2.2.0: write-pkg@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9" + resolved "https://registry.npmjs.org/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9" dependencies: sort-keys "^2.0.0" write-json-file "^2.2.0" @@ -10165,100 +11504,153 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.2.tgz#8a244fa052401e08c9886cf44a85189e1fd4067f" - dependencies: - options ">=0.0.5" - ultron "1.0.x" - ws@^1.0.1: version "1.1.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" + resolved "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" dependencies: options ">=0.0.5" ultron "1.0.x" -wtf-8@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" +ws@~3.3.1: + version "3.3.3" + resolved "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" xdg-basedir@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" + resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" dependencies: os-homedir "^1.0.0" xdg-basedir@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" xml2js@0.4.4: version "0.4.4" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.4.tgz#3111010003008ae19240eba17497b57c729c555d" + resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz#3111010003008ae19240eba17497b57c729c555d" dependencies: sax "0.6.x" xmlbuilder ">=1.0.0" xml2js@^0.4.17: version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" dependencies: sax ">=0.6.0" xmlbuilder "~9.0.1" xmlbuilder@>=1.0.0, xmlbuilder@~9.0.1: - version "9.0.4" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.4.tgz#519cb4ca686d005a8420d3496f3f0caeecca580f" + version "9.0.7" + resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" -xmlhttprequest-ssl@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" xmlhttprequest@^1.8.0: version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + resolved "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" y18n@^3.2.0, y18n@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" yallist@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" yargs-parser@^4.2.0: version "4.2.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" dependencies: camelcase "^3.0.0" yargs-parser@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + +yargs-parser@^8.0.0, yargs-parser@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" dependencies: camelcase "^4.1.0" -yargs-parser@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" dependencies: camelcase "^4.1.0" -yargs@10.0.3, yargs@^10.0.3: - version "10.0.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae" +yargs@6.6.0: + version "6.6.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" dependencies: + camelcase "^3.0.0" cliui "^3.2.0" decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@8.0.2, yargs@^8.0.2: + version "8.0.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.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" + yargs-parser "^7.0.0" + +yargs@^10.0.3: + version "10.1.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" find-up "^2.1.0" get-caller-file "^1.0.1" os-locale "^2.0.0" @@ -10268,11 +11660,28 @@ yargs@10.0.3, yargs@^10.0.3: string-width "^2.0.0" which-module "^2.0.0" y18n "^3.2.1" - yargs-parser "^8.0.0" + yargs-parser "^8.1.0" -yargs@^3.10.0, yargs@^3.28.0: +yargs@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.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" + yargs-parser "^9.0.2" + +yargs@^3.10.0: version "3.32.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + resolved "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" dependencies: camelcase "^2.0.1" cliui "^3.0.3" @@ -10282,9 +11691,9 @@ yargs@^3.10.0, yargs@^3.28.0: window-size "^0.1.4" y18n "^3.2.0" -yargs@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" +yargs@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" dependencies: camelcase "^3.0.0" cliui "^3.2.0" @@ -10298,29 +11707,11 @@ yargs@^6.6.0: string-width "^1.0.2" which-module "^1.0.0" y18n "^3.2.1" - yargs-parser "^4.2.0" - -yargs@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.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" - yargs-parser "^7.0.0" + yargs-parser "^5.0.0" yargs@~3.10.0: version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + resolved "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" dependencies: camelcase "^1.0.2" cliui "^2.1.0" @@ -10329,28 +11720,28 @@ yargs@~3.10.0: yauzl@2.4.1: version "2.4.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" dependencies: fd-slicer "~1.0.1" yauzl@^2.4.2, yauzl@^2.8.0: version "2.9.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.0.1" yeast@0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + resolved "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" yn@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" zip-stream@^1.1.0, zip-stream@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04" + resolved "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04" dependencies: archiver-utils "^1.3.0" compress-commons "^1.2.0" From e70ef379c6cf2d4e00c72ff2feda82d6dda44bd1 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Thu, 22 Feb 2018 14:21:38 -0800 Subject: [PATCH 11/34] Publish firebase@4.10.1 --- integration/browserify/package.json | 2 +- integration/firebase-typings/package.json | 2 +- integration/messaging/package.json | 2 +- integration/typescript/package.json | 2 +- integration/webpack/package.json | 2 +- packages/app-types/package.json | 2 +- packages/app/package.json | 6 +++--- packages/auth-types/package.json | 2 +- packages/auth/package.json | 4 ++-- packages/database-types/package.json | 2 +- packages/database/package.json | 6 +++--- packages/firebase/package.json | 16 ++++++++-------- packages/firestore-types/package.json | 2 +- packages/firestore/package.json | 4 ++-- packages/messaging-types/package.json | 2 +- packages/messaging/package.json | 6 +++--- packages/polyfill/package.json | 2 +- packages/storage-types/package.json | 2 +- packages/storage/package.json | 4 ++-- packages/util/package.json | 2 +- 20 files changed, 36 insertions(+), 36 deletions(-) diff --git a/integration/browserify/package.json b/integration/browserify/package.json index 87eccfb7127..7513bab3a4e 100644 --- a/integration/browserify/package.json +++ b/integration/browserify/package.json @@ -7,7 +7,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.10.0" + "firebase": "4.10.1" }, "devDependencies": { "browserify": "^16.1.0", diff --git a/integration/firebase-typings/package.json b/integration/firebase-typings/package.json index 3ec28b02098..4125929c44b 100644 --- a/integration/firebase-typings/package.json +++ b/integration/firebase-typings/package.json @@ -6,7 +6,7 @@ "test": "tsc index.ts --outDir dist" }, "dependencies": { - "firebase": "4.10.0" + "firebase": "4.10.1" }, "devDependencies": { "typescript": "^2.7.2" diff --git a/integration/messaging/package.json b/integration/messaging/package.json index bb7aa5860dd..443a4ba5771 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -8,7 +8,7 @@ "test:manual": "mocha --exit" }, "dependencies": { - "firebase": "4.10.0" + "firebase": "4.10.1" }, "devDependencies": { "chai": "^4.1.1", diff --git a/integration/typescript/package.json b/integration/typescript/package.json index 5c24c7b7d7a..27739a960b4 100644 --- a/integration/typescript/package.json +++ b/integration/typescript/package.json @@ -6,7 +6,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.10.0" + "firebase": "4.10.1" }, "devDependencies": { "@types/chai": "^4.1.2", diff --git a/integration/webpack/package.json b/integration/webpack/package.json index 860727d4ae8..896015613ca 100644 --- a/integration/webpack/package.json +++ b/integration/webpack/package.json @@ -7,7 +7,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.10.0" + "firebase": "4.10.1" }, "devDependencies": { "chai": "^4.1.1", diff --git a/packages/app-types/package.json b/packages/app-types/package.json index 73abc0675f5..9542582ad74 100644 --- a/packages/app-types/package.json +++ b/packages/app-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app-types", - "version": "0.1.1", + "version": "0.1.2", "description": "@firebase/app Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/app/package.json b/packages/app/package.json index 86a9a7120f8..8b3efc66af3 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/app", - "version": "0.1.9", + "version": "0.1.10", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -15,8 +15,8 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/app-types": "0.1.1", - "@firebase/util": "0.1.9", + "@firebase/app-types": "0.1.2", + "@firebase/util": "0.1.10", "tslib": "^1.9.0" }, "devDependencies": { diff --git a/packages/auth-types/package.json b/packages/auth-types/package.json index 4fc4f4fad61..0ebca7447bb 100644 --- a/packages/auth-types/package.json +++ b/packages/auth-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/auth-types", - "version": "0.1.1", + "version": "0.1.2", "description": "@firebase/auth Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/auth/package.json b/packages/auth/package.json index be4b6dcdf6b..b7e3eb6bb53 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/auth", - "version": "0.3.3", + "version": "0.3.4", "main": "dist/auth.js", "description": "Javascript library for Firebase Auth SDK", "author": "Firebase (https://firebase.google.com/)", @@ -21,7 +21,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/auth-types": "0.1.1" + "@firebase/auth-types": "0.1.2" }, "devDependencies": { "closure-builder": "^2.0.17", diff --git a/packages/database-types/package.json b/packages/database-types/package.json index 0bd4a1255b9..0c2d9cbff64 100644 --- a/packages/database-types/package.json +++ b/packages/database-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/database-types", - "version": "0.1.1", + "version": "0.1.2", "description": "@firebase/database Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/database/package.json b/packages/database/package.json index 540a58dcb11..f4b84eed31b 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/database", - "version": "0.1.10", + "version": "0.1.11", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", @@ -19,8 +19,8 @@ "@firebase/app-types": "^0.1.0" }, "dependencies": { - "@firebase/database-types": "0.1.1", - "@firebase/util": "0.1.9", + "@firebase/database-types": "0.1.2", + "@firebase/util": "0.1.10", "faye-websocket": "0.11.1", "tslib": "^1.9.0" }, diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 40a63bbba61..cfd08f18b69 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "firebase", - "version": "4.10.0", + "version": "4.10.1", "description": "Firebase JavaScript library for web and Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -27,13 +27,13 @@ "browser": "index.js", "react-native": "index.react-native.js", "dependencies": { - "@firebase/app": "0.1.9", - "@firebase/auth": "0.3.3", - "@firebase/database": "0.1.10", - "@firebase/firestore": "0.3.3", - "@firebase/messaging": "0.2.0", - "@firebase/polyfill": "0.1.5", - "@firebase/storage": "0.1.7", + "@firebase/app": "0.1.10", + "@firebase/auth": "0.3.4", + "@firebase/database": "0.1.11", + "@firebase/firestore": "0.3.4", + "@firebase/messaging": "0.2.1", + "@firebase/polyfill": "0.1.6", + "@firebase/storage": "0.1.8", "dom-storage": "^2.0.2", "xmlhttprequest": "^1.8.0" }, diff --git a/packages/firestore-types/package.json b/packages/firestore-types/package.json index c1c22cc2731..efa015bf5f6 100644 --- a/packages/firestore-types/package.json +++ b/packages/firestore-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore-types", - "version": "0.2.1", + "version": "0.2.2", "description": "@firebase/firestore Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 6cd0d693715..96fb38ef60d 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore", - "version": "0.3.3", + "version": "0.3.4", "description": "", "author": "Firebase (https://firebase.google.com/)", "scripts": { @@ -22,7 +22,7 @@ "module": "dist/esm/index.js", "license": "Apache-2.0", "dependencies": { - "@firebase/firestore-types": "0.2.1", + "@firebase/firestore-types": "0.2.2", "@firebase/webchannel-wrapper": "0.2.6", "grpc": "^1.9.1", "tslib": "^1.9.0" diff --git a/packages/messaging-types/package.json b/packages/messaging-types/package.json index 3fd6ab00c20..b5d05910ddb 100644 --- a/packages/messaging-types/package.json +++ b/packages/messaging-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/messaging-types", - "version": "0.1.1", + "version": "0.1.2", "description": "@firebase/messaging Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 100dae7d4f9..415c7447ecc 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/messaging", - "version": "0.2.0", + "version": "0.2.1", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -16,8 +16,8 @@ "@firebase/app": "^0.1.0" }, "dependencies": { - "@firebase/messaging-types": "0.1.1", - "@firebase/util": "0.1.9", + "@firebase/messaging-types": "0.1.2", + "@firebase/util": "0.1.10", "lcov-result-merger": "^2.0.0", "tslib": "^1.9.0" }, diff --git a/packages/polyfill/package.json b/packages/polyfill/package.json index 14db9c43d5c..1cdc4aa93ff 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/polyfill", - "version": "0.1.5", + "version": "0.1.6", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", diff --git a/packages/storage-types/package.json b/packages/storage-types/package.json index f3e49b7d400..a37bfe6f781 100644 --- a/packages/storage-types/package.json +++ b/packages/storage-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/storage-types", - "version": "0.1.1", + "version": "0.1.2", "description": "@firebase/storage Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/storage/package.json b/packages/storage/package.json index cb8b08316a6..121b0d8997c 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/storage", - "version": "0.1.7", + "version": "0.1.8", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -13,7 +13,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/storage-types": "0.1.1", + "@firebase/storage-types": "0.1.2", "tslib": "^1.9.0" }, "peerDependencies": { diff --git a/packages/util/package.json b/packages/util/package.json index eb93061b41f..153fec501ff 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/util", - "version": "0.1.9", + "version": "0.1.10", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", From 9cda9c927bfd2b19eff13357beac6646ec9f1413 Mon Sep 17 00:00:00 2001 From: Greg Soltis Date: Tue, 27 Feb 2018 09:48:07 -0800 Subject: [PATCH 12/34] Keep track of number of queries in the query cache (#510) * Adding Schema Migration * Pseudocode for Schema Migration * [AUTOMATED]: Prettier Code Styling * IndexedDb Schema Migration * Lint cleanup * Removing unused import * Removing user ID from instance row * [AUTOMATED]: Prettier Code Styling * Review comments * Lint fixes * Review * [AUTOMATED]: Prettier Code Styling * Fixing the tests * Closing the Database in the Schema tests * [AUTOMATED]: Prettier Code Styling * Changing test helper to close the DB * [AUTOMATED]: Prettier Code Styling * Making v2 the default version * [AUTOMATED]: Prettier Code Styling * Addressing comment * [AUTOMATED]: Prettier Code Styling * Renamed to ALL_STORES * Start work on adding query counts * Implement target count * [AUTOMATED]: Prettier Code Styling * Separate out add and update for the query cache * [AUTOMATED]: Prettier Code Styling * Comments and formatting * Comments and restructuring * [AUTOMATED]: Prettier Code Styling * Use SimpleDb, shorten iOS-y name * [AUTOMATED]: Prettier Code Styling * addTargetCount -> saveTargetCount * Fix lint warnings * Comment fixes * Rename test file * Add expectation for 0 targets if none were added * [AUTOMATED]: Prettier Code Styling * Switch to PersistenceTransaction for schema upgrade * Fix the other tests * [AUTOMATED]: Prettier Code Styling * Update comment * Add some asserts, revert to PersistencePromise * Add assert * [AUTOMATED]: Prettier Code Styling * helpers moved * Review feedback * Switch to just using fail() * Rename updateMetadata * Renaming and thread metadata through schema upgrade * Use the proper assert * Review feedback * [AUTOMATED]: Prettier Code Styling * Drop note re running time, initialize metadata to null * Fix tests that weren't calling start * [AUTOMATED]: Prettier Code Styling --- packages/database/test/order_by.test.ts | 4 +- packages/database/test/query.test.ts | 28 ++- packages/database/test/transaction.test.ts | 48 +++-- .../src/local/indexeddb_persistence.ts | 9 +- .../src/local/indexeddb_query_cache.ts | 104 +++++++--- .../firestore/src/local/indexeddb_schema.ts | 186 +++++++++++++----- packages/firestore/src/local/local_store.ts | 2 +- .../firestore/src/local/memory_query_cache.ts | 40 +++- packages/firestore/src/local/query_cache.ts | 27 ++- packages/firestore/src/local/simple_db.ts | 56 ++++-- .../src/platform_node/grpc_connection.ts | 6 +- .../firestore/src/remote/persistent_stream.ts | 4 +- .../firestore/src/util/input_validation.ts | 8 +- .../test/integration/api/validation.test.ts | 4 +- .../unit/local/encoded_resource_path.test.ts | 1 + .../test/unit/local/indexeddb_schema.test.ts | 136 +++++++++++++ .../test/unit/local/query_cache.test.ts | 31 +-- .../test/unit/local/simple_db.test.ts | 1 + .../test/unit/local/test_query_cache.ts | 10 + 19 files changed, 559 insertions(+), 146 deletions(-) create mode 100644 packages/firestore/test/unit/local/indexeddb_schema.test.ts diff --git a/packages/database/test/order_by.test.ts b/packages/database/test/order_by.test.ts index b821de62138..70495f2fd60 100644 --- a/packages/database/test/order_by.test.ts +++ b/packages/database/test/order_by.test.ts @@ -363,7 +363,9 @@ describe('.orderBy tests', function() { expect(addedPrevNames).to.deep.equal(expectedPrevNames); }); - it('Removing default listener removes non-default listener that loads all data', function(done) { + it('Removing default listener removes non-default listener that loads all data', function( + done + ) { const ref = getRandomNode() as Reference; const initial = { key: 'value' }; diff --git a/packages/database/test/query.test.ts b/packages/database/test/query.test.ts index bda21cdbb0b..499748d3edd 100644 --- a/packages/database/test/query.test.ts +++ b/packages/database/test/query.test.ts @@ -1971,7 +1971,9 @@ describe('Query Tests', function() { expect(val).to.equal(2); }); - it('.startAt() with two arguments works properly (case 1169).', function(done) { + it('.startAt() with two arguments works properly (case 1169).', function( + done + ) { const ref = getRandomNode() as Reference; const data = { Walker: { @@ -2108,7 +2110,9 @@ describe('Query Tests', function() { }); }); - it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", function(done) { + it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", function( + done + ) { const ref = getRandomNode() as Reference; ref.set( { a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f', g: 'g', h: 'h' }, @@ -2130,7 +2134,9 @@ describe('Query Tests', function() { ); }); - it('complex update() at query root raises correct value event', function(done) { + it('complex update() at query root raises correct value event', function( + done + ) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2235,7 +2241,9 @@ describe('Query Tests', function() { }); }); - it('listen for child_added events with limit and different types fires properly', function(done) { + it('listen for child_added events with limit and different types fires properly', function( + done + ) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2277,7 +2285,9 @@ describe('Query Tests', function() { }); }); - it('listen for child_changed events with limit and different types fires properly', function(done) { + it('listen for child_changed events with limit and different types fires properly', function( + done + ) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2328,7 +2338,9 @@ describe('Query Tests', function() { }); }); - it('listen for child_remove events with limit and different types fires properly', function(done) { + it('listen for child_remove events with limit and different types fires properly', function( + done + ) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2430,7 +2442,9 @@ describe('Query Tests', function() { ); }); - it('listen for child_remove events when parent set to scalar', function(done) { + it('listen for child_remove events when parent set to scalar', function( + done + ) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; diff --git a/packages/database/test/transaction.test.ts b/packages/database/test/transaction.test.ts index d0f44f5accc..e603105ebc0 100644 --- a/packages/database/test/transaction.test.ts +++ b/packages/database/test/transaction.test.ts @@ -86,7 +86,9 @@ describe('Transaction Tests', function() { }); }); - it('Non-aborted transaction sets committed to true in callback.', function(done) { + it('Non-aborted transaction sets committed to true in callback.', function( + done + ) { const node = getRandomNode() as Reference; node.transaction( @@ -102,7 +104,9 @@ describe('Transaction Tests', function() { ); }); - it('Aborted transaction sets committed to false in callback.', function(done) { + it('Aborted transaction sets committed to false in callback.', function( + done + ) { const node = getRandomNode() as Reference; node.transaction( @@ -232,7 +236,9 @@ describe('Transaction Tests', function() { return ea.promise; }); - it('Second transaction gets run immediately on previous output and only runs once.', function(done) { + it('Second transaction gets run immediately on previous output and only runs once.', function( + done + ) { const nodePair = getRandomNode(2) as Reference[]; let firstRun = false, firstDone = false, @@ -506,7 +512,9 @@ describe('Transaction Tests', function() { ); }); - it('Set should cancel already sent transactions that come back as datastale.', function(done) { + it('Set should cancel already sent transactions that come back as datastale.', function( + done + ) { const nodePair = getRandomNode(2) as Reference[]; let transactionCalls = 0; nodePair[0].set(5, function() { @@ -680,7 +688,9 @@ describe('Transaction Tests', function() { return Promise.all([tx1, tx2]); }); - it('Doing set() in successful transaction callback works. Case 870.', function(done) { + it('Doing set() in successful transaction callback works. Case 870.', function( + done + ) { const node = getRandomNode() as Reference; let transactionCalled = false; let callbackCalled = false; @@ -700,7 +710,9 @@ describe('Transaction Tests', function() { ); }); - it('Doing set() in aborted transaction callback works. Case 870.', function(done) { + it('Doing set() in aborted transaction callback works. Case 870.', function( + done + ) { const nodePair = getRandomNode(2) as Reference[], node1 = nodePair[0], node2 = nodePair[1]; @@ -1016,7 +1028,9 @@ describe('Transaction Tests', function() { ); }); - it('Transaction properly reverts data when you add a deeper listen.', function(done) { + it('Transaction properly reverts data when you add a deeper listen.', function( + done + ) { const refPair = getRandomNode(2) as Reference[], ref1 = refPair[0], ref2 = refPair[1]; @@ -1186,7 +1200,9 @@ describe('Transaction Tests', function() { }); }); - it("transaction() doesn't pick up cached data from previous once().", function(done) { + it("transaction() doesn't pick up cached data from previous once().", function( + done + ) { const refPair = getRandomNode(2) as Reference[]; const me = refPair[0], other = refPair[1]; @@ -1213,7 +1229,9 @@ describe('Transaction Tests', function() { }); }); - it("transaction() doesn't pick up cached data from previous transaction.", function(done) { + it("transaction() doesn't pick up cached data from previous transaction.", function( + done + ) { const refPair = getRandomNode(2) as Reference[]; const me = refPair[0], other = refPair[1]; @@ -1245,7 +1263,9 @@ describe('Transaction Tests', function() { ); }); - it('server values: local timestamp should eventually (but not immediately) match the server with txns', function(done) { + it('server values: local timestamp should eventually (but not immediately) match the server with txns', function( + done + ) { const refPair = getRandomNode(2) as Reference[], writer = refPair[0], reader = refPair[1], @@ -1337,7 +1357,9 @@ describe('Transaction Tests', function() { ); }); - it("transaction() on queried location doesn't run initially on null (firebase-worker-queue depends on this).", function(done) { + it("transaction() on queried location doesn't run initially on null (firebase-worker-queue depends on this).", function( + done + ) { const ref = getRandomNode() as Reference; ref.push({ a: 1, b: 2 }, function() { ref @@ -1415,7 +1437,9 @@ describe('Transaction Tests', function() { ); }); - it('transactions works with merges without the transaction path', function(done) { + it('transactions works with merges without the transaction path', function( + done + ) { const ref = getRandomNode() as Reference; ref.update({ foo: 'bar' }); diff --git a/packages/firestore/src/local/indexeddb_persistence.ts b/packages/firestore/src/local/indexeddb_persistence.ts index c4bcd5c8634..b09548e5e2b 100644 --- a/packages/firestore/src/local/indexeddb_persistence.ts +++ b/packages/firestore/src/local/indexeddb_persistence.ts @@ -25,8 +25,13 @@ import { AutoId } from '../util/misc'; import { IndexedDbMutationQueue } from './indexeddb_mutation_queue'; import { IndexedDbQueryCache } from './indexeddb_query_cache'; import { IndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache'; -import { ALL_STORES, DbOwner, DbOwnerKey } from './indexeddb_schema'; -import { createOrUpgradeDb, SCHEMA_VERSION } from './indexeddb_schema'; +import { + ALL_STORES, + createOrUpgradeDb, + DbOwner, + DbOwnerKey, + SCHEMA_VERSION +} from './indexeddb_schema'; import { LocalSerializer } from './local_serializer'; import { MutationQueue } from './mutation_queue'; import { Persistence } from './persistence'; diff --git a/packages/firestore/src/local/indexeddb_query_cache.ts b/packages/firestore/src/local/indexeddb_query_cache.ts index 285a4f02bfe..9f9ca5cb616 100644 --- a/packages/firestore/src/local/indexeddb_query_cache.ts +++ b/packages/firestore/src/local/indexeddb_query_cache.ts @@ -31,8 +31,7 @@ import { DbTargetDocumentKey, DbTargetGlobal, DbTargetGlobalKey, - DbTargetKey, - DbTimestamp + DbTargetKey } from './indexeddb_schema'; import { LocalSerializer } from './local_serializer'; import { PersistenceTransaction } from './persistence'; @@ -53,11 +52,7 @@ export class IndexedDbQueryCache implements QueryCache { /** * A cached copy of the metadata for the query cache. */ - private metadata = new DbTargetGlobal( - /*highestTargetId=*/ 0, - /*lastListenSequenceNumber=*/ 0, - SnapshotVersion.MIN.toTimestamp() - ); + private metadata = null; /** The garbage collector to notify about potential garbage keys. */ private garbageCollector: GarbageCollector | null = null; @@ -66,13 +61,15 @@ export class IndexedDbQueryCache implements QueryCache { return globalTargetStore(transaction) .get(DbTargetGlobal.key) .next(metadata => { - if (metadata !== null) { - this.metadata = metadata; - const lastSavedVersion = metadata.lastRemoteSnapshotVersion; - this.lastRemoteSnapshotVersion = SnapshotVersion.fromTimestamp( - new Timestamp(lastSavedVersion.seconds, lastSavedVersion.nanos) - ); - } + assert( + metadata !== null, + 'Missing metadata row that should be added by schema migration.' + ); + this.metadata = metadata; + const lastSavedVersion = metadata.lastRemoteSnapshotVersion; + this.lastRemoteSnapshotVersion = SnapshotVersion.fromTimestamp( + new Timestamp(lastSavedVersion.seconds, lastSavedVersion.nanos) + ); return PersistencePromise.resolve(); }); } @@ -101,32 +98,75 @@ export class IndexedDbQueryCache implements QueryCache { transaction: PersistenceTransaction, queryData: QueryData ): PersistencePromise { - const targetId = queryData.targetId; - const addedQueryPromise = targetsStore(transaction).put( - this.serializer.toDbTarget(queryData) - ); - if (targetId > this.metadata.highestTargetId) { - this.metadata.highestTargetId = targetId; - return addedQueryPromise.next(() => - globalTargetStore(transaction).put(DbTargetGlobal.key, this.metadata) - ); - } else { - return addedQueryPromise; - } + return this.saveQueryData(transaction, queryData).next(() => { + this.metadata.targetCount += 1; + this.updateMetadataFromQueryData(queryData); + return this.saveMetadata(transaction); + }); } - removeQueryData( + updateQueryData( transaction: PersistenceTransaction, queryData: QueryData ): PersistencePromise { - return this.removeMatchingKeysForTargetId( - transaction, - queryData.targetId - ).next(() => { - targetsStore(transaction).delete(queryData.targetId); + return this.saveQueryData(transaction, queryData).next(() => { + if (this.updateMetadataFromQueryData(queryData)) { + return this.saveMetadata(transaction); + } else { + return PersistencePromise.resolve(); + } }); } + removeQueryData( + transaction: PersistenceTransaction, + queryData: QueryData + ): PersistencePromise { + assert(this.metadata.targetCount > 0, 'Removing from an empty query cache'); + return this.removeMatchingKeysForTargetId(transaction, queryData.targetId) + .next(() => targetsStore(transaction).delete(queryData.targetId)) + .next(() => { + this.metadata.targetCount -= 1; + return this.saveMetadata(transaction); + }); + } + + private saveMetadata( + transaction: PersistenceTransaction + ): PersistencePromise { + return globalTargetStore(transaction).put( + DbTargetGlobal.key, + this.metadata + ); + } + + private saveQueryData( + transaction: PersistenceTransaction, + queryData: QueryData + ): PersistencePromise { + return targetsStore(transaction).put(this.serializer.toDbTarget(queryData)); + } + + /** + * Updates the in-memory version of the metadata to account for values in the + * given QueryData. Saving is done separately. Returns true if there were any + * changes to the metadata. + */ + private updateMetadataFromQueryData(queryData: QueryData): boolean { + let needsUpdate = false; + if (queryData.targetId > this.metadata.highestTargetId) { + this.metadata.highestTargetId = queryData.targetId; + needsUpdate = true; + } + + // TODO(GC): add sequence number check + return needsUpdate; + } + + get count(): number { + return this.metadata.targetCount; + } + getQueryData( transaction: PersistenceTransaction, query: Query diff --git a/packages/firestore/src/local/indexeddb_schema.ts b/packages/firestore/src/local/indexeddb_schema.ts index 88bfb484371..5064606978c 100644 --- a/packages/firestore/src/local/indexeddb_schema.ts +++ b/packages/firestore/src/local/indexeddb_schema.ts @@ -21,54 +21,59 @@ import { ResourcePath } from '../model/path'; import { assert } from '../util/assert'; import { encode, EncodedResourcePath } from './encoded_resource_path'; +import { SimpleDbTransaction } from './simple_db'; +import { PersistencePromise } from './persistence_promise'; +import { SnapshotVersion } from '../core/snapshot_version'; -export const SCHEMA_VERSION = 1; - -/** Performs database creation and (in the future) upgrades between versions. */ -export function createOrUpgradeDb(db: IDBDatabase, oldVersion: number): void { - assert(oldVersion === 0, 'Unexpected upgrade from version ' + oldVersion); - - db.createObjectStore(DbMutationQueue.store, { - keyPath: DbMutationQueue.keyPath - }); - - // TODO(mikelehen): Get rid of "as any" if/when TypeScript fixes their - // types. https://github.com/Microsoft/TypeScript/issues/14322 - db.createObjectStore( - DbMutationBatch.store, - // tslint:disable-next-line:no-any - { keyPath: DbMutationBatch.keyPath as any } - ); +/** + * Schema Version for the Web client: + * 1. Initial version including Mutation Queue, Query Cache, and Remote Document + * Cache + * 2. Added targetCount to targetGlobal row. + */ +export const SCHEMA_VERSION = 2; - const targetDocumentsStore = db.createObjectStore( - DbTargetDocument.store, - // tslint:disable-next-line:no-any - { keyPath: DbTargetDocument.keyPath as any } - ); - targetDocumentsStore.createIndex( - DbTargetDocument.documentTargetsIndex, - DbTargetDocument.documentTargetsKeyPath, - { unique: true } +/** + * Performs database creation and schema upgrades. + * + * Note that in production, this method is only ever used to upgrade the schema + * to SCHEMA_VERSION. Different values of toVersion are only used for testing + * and local feature development. + */ +export function createOrUpgradeDb( + db: IDBDatabase, + txn: SimpleDbTransaction, + fromVersion: number, + toVersion: number +): PersistencePromise { + // This function currently supports migrating to schema version 1 (Mutation + // Queue, Query and Remote Document Cache) and schema version 2 (Query + // counting). + assert( + fromVersion < toVersion && fromVersion >= 0 && toVersion <= 2, + 'Unexpected schema upgrade from v${fromVersion} to v{toVersion}.' ); - const targetStore = db.createObjectStore(DbTarget.store, { - keyPath: DbTarget.keyPath - }); - // NOTE: This is unique only because the TargetId is the suffix. - targetStore.createIndex( - DbTarget.queryTargetsIndexName, - DbTarget.queryTargetsKeyPath, - { unique: true } - ); + if (fromVersion < 1 && toVersion >= 1) { + createOwnerStore(db); + createMutationQueue(db); + createQueryCache(db); + createRemoteDocumentCache(db); + } - // NOTE: keys for these stores are specified explicitly rather than using a - // keyPath. - db.createObjectStore(DbDocumentMutation.store); - db.createObjectStore(DbRemoteDocument.store); - db.createObjectStore(DbOwner.store); - db.createObjectStore(DbTargetGlobal.store); + let p = PersistencePromise.resolve(); + if (fromVersion < 2 && toVersion >= 2) { + p = ensureTargetGlobalExists(txn).next(targetGlobal => + saveTargetCount(txn, targetGlobal) + ); + } + return p; } +// TODO(mikelehen): Get rid of "as any" if/when TypeScript fixes their types. +// https://github.com/Microsoft/TypeScript/issues/14322 +type KeyPath = any; // tslint:disable-line:no-any + /** * Wrapper class to store timestamps (seconds and nanos) in IndexedDb objects. */ @@ -94,6 +99,10 @@ export class DbOwner { constructor(public ownerId: string, public leaseTimestampMs: number) {} } +function createOwnerStore(db: IDBDatabase): void { + db.createObjectStore(DbOwner.store); +} + /** Object keys in the 'mutationQueues' store are userId strings. */ export type DbMutationQueueKey = string; @@ -183,6 +192,18 @@ export class DbMutationBatch { */ export type DbDocumentMutationKey = [string, EncodedResourcePath, BatchId]; +function createMutationQueue(db: IDBDatabase): void { + db.createObjectStore(DbMutationQueue.store, { + keyPath: DbMutationQueue.keyPath + }); + + db.createObjectStore(DbMutationBatch.store, { + keyPath: DbMutationBatch.keyPath as KeyPath + }); + + db.createObjectStore(DbDocumentMutation.store); +} + /** * An object to be stored in the 'documentMutations' store in IndexedDb. * @@ -241,6 +262,10 @@ export class DbDocumentMutation { */ export type DbRemoteDocumentKey = string[]; +function createRemoteDocumentCache(db: IDBDatabase): void { + db.createObjectStore(DbRemoteDocument.store); +} + /** * Represents the known absence of a document at a particular version. * Stored in IndexedDb as part of a DbRemoteDocument object. @@ -451,13 +476,86 @@ export class DbTargetGlobal { * until the backend has caught up to this snapshot version again. This * prevents our cache from ever going backwards in time. */ - public lastRemoteSnapshotVersion: DbTimestamp + public lastRemoteSnapshotVersion: DbTimestamp, + /** + * The number of targets persisted. + */ + public targetCount: number ) {} } +function createQueryCache(db: IDBDatabase): void { + const targetDocumentsStore = db.createObjectStore(DbTargetDocument.store, { + keyPath: DbTargetDocument.keyPath as KeyPath + }); + targetDocumentsStore.createIndex( + DbTargetDocument.documentTargetsIndex, + DbTargetDocument.documentTargetsKeyPath, + { unique: true } + ); + + const targetStore = db.createObjectStore(DbTarget.store, { + keyPath: DbTarget.keyPath + }); + + // NOTE: This is unique only because the TargetId is the suffix. + targetStore.createIndex( + DbTarget.queryTargetsIndexName, + DbTarget.queryTargetsKeyPath, + { unique: true } + ); + db.createObjectStore(DbTargetGlobal.store); +} + +/** + * Counts the number of targets persisted and adds that value to the target + * global singleton. + */ +function saveTargetCount( + txn: SimpleDbTransaction, + metadata: DbTargetGlobal +): PersistencePromise { + const globalStore = txn.store( + DbTargetGlobal.store + ); + const targetStore = txn.store(DbTarget.store); + return targetStore.count().next(count => { + metadata.targetCount = count; + return globalStore.put(DbTargetGlobal.key, metadata); + }); +} + +/** + * Ensures that the target global singleton row exists by adding it if it's + * missing. + * + * @param {IDBTransaction} txn The version upgrade transaction for indexeddb + */ +function ensureTargetGlobalExists( + txn: SimpleDbTransaction +): PersistencePromise { + const globalStore = txn.store( + DbTargetGlobal.store + ); + return globalStore.get(DbTargetGlobal.key).next(metadata => { + if (metadata != null) { + return PersistencePromise.resolve(metadata); + } else { + metadata = new DbTargetGlobal( + /*highestTargetId=*/ 0, + /*lastListenSequenceNumber=*/ 0, + SnapshotVersion.MIN.toTimestamp(), + /*targetCount=*/ 0 + ); + return globalStore.put(DbTargetGlobal.key, metadata).next(() => metadata); + } + }); +} + /** - * The list of all IndexedDB stored used by the SDK. This is used when creating - * transactions so that access across all stores is done atomically. + * The list of all default IndexedDB stores used throughout the SDK. This is + * used when creating transactions so that access across all stores is done + * atomically. */ export const ALL_STORES = [ DbMutationQueue.store, diff --git a/packages/firestore/src/local/local_store.ts b/packages/firestore/src/local/local_store.ts index d8f1b84e16c..fac1e77b028 100644 --- a/packages/firestore/src/local/local_store.ts +++ b/packages/firestore/src/local/local_store.ts @@ -478,7 +478,7 @@ export class LocalStore { snapshotVersion: change.snapshotVersion }); this.targetIds[targetId] = queryData; - promises.push(this.queryCache.addQueryData(txn, queryData)); + promises.push(this.queryCache.updateQueryData(txn, queryData)); } } ); diff --git a/packages/firestore/src/local/memory_query_cache.ts b/packages/firestore/src/local/memory_query_cache.ts index feda7988ddc..9bf31739c33 100644 --- a/packages/firestore/src/local/memory_query_cache.ts +++ b/packages/firestore/src/local/memory_query_cache.ts @@ -27,6 +27,7 @@ import { PersistencePromise } from './persistence_promise'; import { QueryCache } from './query_cache'; import { QueryData } from './query_data'; import { ReferenceSet } from './reference_set'; +import { assert } from '../util/assert'; export class MemoryQueryCache implements QueryCache { /** @@ -44,6 +45,8 @@ export class MemoryQueryCache implements QueryCache { */ private references = new ReferenceSet(); + private targetCount = 0; + start(transaction: PersistenceTransaction): PersistencePromise { // Nothing to do. return PersistencePromise.resolve(); @@ -65,15 +68,34 @@ export class MemoryQueryCache implements QueryCache { return PersistencePromise.resolve(); } - addQueryData( - transaction: PersistenceTransaction, - queryData: QueryData - ): PersistencePromise { + private saveQueryData(queryData: QueryData) { this.queries.set(queryData.query, queryData); const targetId = queryData.targetId; if (targetId > this.highestTargetId) { this.highestTargetId = targetId; } + // TODO(GC): track sequence number + } + + addQueryData( + transaction: PersistenceTransaction, + queryData: QueryData + ): PersistencePromise { + assert( + !this.queries.has(queryData.query), + 'Adding a query that already exists' + ); + this.saveQueryData(queryData); + this.targetCount += 1; + return PersistencePromise.resolve(); + } + + updateQueryData( + transaction: PersistenceTransaction, + queryData: QueryData + ): PersistencePromise { + assert(this.queries.has(queryData.query), 'Updating a non-existent query'); + this.saveQueryData(queryData); return PersistencePromise.resolve(); } @@ -81,11 +103,21 @@ export class MemoryQueryCache implements QueryCache { transaction: PersistenceTransaction, queryData: QueryData ): PersistencePromise { + assert(this.targetCount > 0, 'Removing a target from an empty cache'); + assert( + this.queries.has(queryData.query), + 'Removing a non-existent target from the cache' + ); this.queries.delete(queryData.query); this.references.removeReferencesForId(queryData.targetId); + this.targetCount -= 1; return PersistencePromise.resolve(); } + get count(): number { + return this.targetCount; + } + getQueryData( transaction: PersistenceTransaction, query: Query diff --git a/packages/firestore/src/local/query_cache.ts b/packages/firestore/src/local/query_cache.ts index 60d095dc879..47b3c410242 100644 --- a/packages/firestore/src/local/query_cache.ts +++ b/packages/firestore/src/local/query_cache.ts @@ -67,10 +67,10 @@ export interface QueryCache extends GarbageSource { ): PersistencePromise; /** - * Adds or replaces an entry in the cache. + * Adds an entry in the cache. * - * The cache key is extracted from `queryData.query`. If there is already a - * cache entry for the key, it will be replaced. + * The cache key is extracted from `queryData.query`. The key must not already + * exist in the cache. * * @param queryData A QueryData instance to put in the cache. */ @@ -80,14 +80,31 @@ export interface QueryCache extends GarbageSource { ): PersistencePromise; /** - * Removes the cached entry for the given query data (no-op if no entry - * exists). + * Updates an entry in the cache. + * + * The cache key is extracted from `queryData.query`. The entry must already + * exist in the cache, and it will be replaced. + * @param {QueryData} queryData The QueryData to be replaced into the cache. + */ + updateQueryData( + transaction: PersistenceTransaction, + queryData: QueryData + ): PersistencePromise; + + /** + * Removes the cached entry for the given query data. It is an error to remove + * a query data that does not exist. */ removeQueryData( transaction: PersistenceTransaction, queryData: QueryData ): PersistencePromise; + /** + * The number of targets currently in the cache. + */ + readonly count: number; + /** * Looks up a QueryData entry in the cache. * diff --git a/packages/firestore/src/local/simple_db.ts b/packages/firestore/src/local/simple_db.ts index cfaa6bb9767..5be70f9cced 100644 --- a/packages/firestore/src/local/simple_db.ts +++ b/packages/firestore/src/local/simple_db.ts @@ -19,6 +19,7 @@ import { debug } from '../util/log'; import { AnyDuringMigration } from '../util/misc'; import { PersistencePromise } from './persistence_promise'; +import { SCHEMA_VERSION } from './indexeddb_schema'; const LOG_TAG = 'SimpleDb'; @@ -34,7 +35,12 @@ export class SimpleDb { static openOrCreate( name: string, version: number, - runUpgrade: (db: IDBDatabase, oldVersion: number) => void + runUpgrade: ( + db: IDBDatabase, + txn: SimpleDbTransaction, + fromVersion: number, + toVersion: number + ) => PersistencePromise ): Promise { assert( SimpleDb.isAvailable(), @@ -45,7 +51,8 @@ export class SimpleDb { // TODO(mikelehen): Investigate browser compatibility. // https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB // suggests IE9 and older WebKit browsers handle upgrade - // differently. + // differently. They expect setVersion, as described here: + // https://developer.mozilla.org/en-US/docs/Web/API/IDBVersionChangeRequest/setVersion const request = window.indexedDB.open(name, version); request.onsuccess = (event: Event) => { @@ -63,14 +70,17 @@ export class SimpleDb { 'Database "' + name + '" requires upgrade from version:', event.oldVersion ); - // TODO(mikelehen): If/when we need to do an actual data - // migration, we'll want to wrap db in a SimpleDb and have the - // runUpgrade function return a PersistencePromise, since we'll - // likely need to do async reads and writes. For now we're - // cheating and just passing the raw IndexedDB in, since - // createObjectStore(), etc. are synchronous. const db = (event.target as IDBOpenDBRequest).result; - runUpgrade(db, event.oldVersion); + // We are provided a version upgrade transaction from the request, so + // we wrap that in a SimpleDbTransaction to allow use of our friendlier + // API for schema migration operations. + const txn = new SimpleDbTransaction(request.transaction); + runUpgrade(db, txn, event.oldVersion, SCHEMA_VERSION).next(() => { + debug( + LOG_TAG, + 'Database upgrade to version ' + SCHEMA_VERSION + ' complete' + ); + }); }; }).toPromise(); } @@ -124,7 +134,7 @@ export class SimpleDb { objectStores: string[], transactionFn: (transaction: SimpleDbTransaction) => PersistencePromise ): Promise { - const transaction = new SimpleDbTransaction(this.db, mode, objectStores); + const transaction = SimpleDbTransaction.open(this.db, mode, objectStores); const transactionFnResult = transactionFn(transaction) .catch(error => { // Abort the transaction if there was an @@ -224,7 +234,6 @@ export interface IterateOptions { * specific object store. */ export class SimpleDbTransaction { - private transaction: IDBTransaction; private aborted = false; /** @@ -235,12 +244,17 @@ export class SimpleDbTransaction { */ readonly completionPromise: Promise; - constructor(db: IDBDatabase, mode: string, objectStoresNames: string[]) { - this.transaction = db.transaction( - objectStoresNames, - mode as AnyDuringMigration + static open( + db: IDBDatabase, + mode: string, + objectStoreNames: string[] + ): SimpleDbTransaction { + return new SimpleDbTransaction( + db.transaction(objectStoreNames, mode as AnyDuringMigration) ); + } + constructor(private readonly transaction: IDBTransaction) { this.completionPromise = new Promise((resolve, reject) => { // We consider aborting to be "normal" and just resolve the promise. // May need to revisit if/when we actually need to abort transactions. @@ -342,6 +356,18 @@ export class SimpleDbStore { return wrapRequest(request); } + /** + * If we ever need more of the count variants, we can add overloads. For now, + * all we need is to count everything in a store. + * + * Returns the number of rows in the store. + */ + count(): PersistencePromise { + debug(LOG_TAG, 'COUNT', this.store.name); + const request = this.store.count(); + return wrapRequest(request); + } + loadAll(): PersistencePromise; loadAll(range: IDBKeyRange): PersistencePromise; loadAll(index: string, range: IDBKeyRange): PersistencePromise; diff --git a/packages/firestore/src/platform_node/grpc_connection.ts b/packages/firestore/src/platform_node/grpc_connection.ts index 639c8c3b831..f6780ead440 100644 --- a/packages/firestore/src/platform_node/grpc_connection.ts +++ b/packages/firestore/src/platform_node/grpc_connection.ts @@ -37,9 +37,9 @@ const LOG_TAG = 'Connection'; // TODO(b/38203344): The SDK_VERSION is set independently from Firebase because // we are doing out-of-band releases. Once we release as part of Firebase, we // should use the Firebase version instead. -const X_GOOG_API_CLIENT_VALUE = `gl-node/${ - process.versions.node -} fire/${SDK_VERSION} grpc/${grpcVersion}`; +const X_GOOG_API_CLIENT_VALUE = `gl-node/${process.versions.node} fire/${ + SDK_VERSION +} grpc/${grpcVersion}`; type DuplexRpc = () => grpc.ClientDuplexStream; type ReadableRpc = (req: Req) => grpc.ClientReadableStream; diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index 0fd3c6573fc..e563d084c7b 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -273,7 +273,9 @@ export abstract class PersistentStream< // rejections are not considered unhandled. assert( err.code === Code.CANCELLED, - `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${err}` + `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${ + err + }` ); }); } diff --git a/packages/firestore/src/util/input_validation.ts b/packages/firestore/src/util/input_validation.ts index 7ad47b8b078..6d7701c760c 100644 --- a/packages/firestore/src/util/input_validation.ts +++ b/packages/firestore/src/util/input_validation.ts @@ -191,9 +191,11 @@ export function validateNamedPropertyEquals( const actualDescription = valueDescription(input); throw new FirestoreError( Code.INVALID_ARGUMENT, - `Invalid value ${actualDescription} provided to function ${functionName}() for option "${optionName}". Acceptable values: ${expectedDescription.join( - ', ' - )}` + `Invalid value ${actualDescription} provided to function ${ + functionName + }() for option "${ + optionName + }". Acceptable values: ${expectedDescription.join(', ')}` ); } diff --git a/packages/firestore/test/integration/api/validation.test.ts b/packages/firestore/test/integration/api/validation.test.ts index a9820691496..8bab7ff59fa 100644 --- a/packages/firestore/test/integration/api/validation.test.ts +++ b/packages/firestore/test/integration/api/validation.test.ts @@ -170,7 +170,9 @@ apiDescribe('Validation:', persistence => { const collection = db.collection('test-collection'); const doc = collection.doc('test-document'); for (const path of badPaths) { - const reason = `Invalid path (${path}). Paths must not contain // in them.`; + const reason = `Invalid path (${ + path + }). Paths must not contain // in them.`; expect(() => db.collection(path)).to.throw(reason); expect(() => db.doc(path)).to.throw(reason); expect(() => collection.doc(path)).to.throw(reason); diff --git a/packages/firestore/test/unit/local/encoded_resource_path.test.ts b/packages/firestore/test/unit/local/encoded_resource_path.test.ts index 05eb6cec579..a738fed2a89 100644 --- a/packages/firestore/test/unit/local/encoded_resource_path.test.ts +++ b/packages/firestore/test/unit/local/encoded_resource_path.test.ts @@ -45,6 +45,7 @@ describe('EncodedResourcePath', () => { .then(() => { return SimpleDb.openOrCreate(dbName, 1, db => { db.createObjectStore('test'); + return PersistencePromise.resolve(); }); }) .then(simpleDb => { diff --git a/packages/firestore/test/unit/local/indexeddb_schema.test.ts b/packages/firestore/test/unit/local/indexeddb_schema.test.ts new file mode 100644 index 00000000000..50ad0212645 --- /dev/null +++ b/packages/firestore/test/unit/local/indexeddb_schema.test.ts @@ -0,0 +1,136 @@ +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence'; +import { + ALL_STORES, + createOrUpgradeDb, + DbTarget, + DbTargetGlobal, + DbTargetGlobalKey +} from '../../../src/local/indexeddb_schema'; +import { SimpleDb, SimpleDbTransaction } from '../../../src/local/simple_db'; +import { PersistencePromise } from '../../../src/local/persistence_promise'; + +const INDEXEDDB_TEST_DATABASE = 'schemaTest'; + +function withDb( + schemaVersion, + fn: (db: IDBDatabase) => Promise +): Promise { + return new Promise((resolve, reject) => { + const request = window.indexedDB.open( + INDEXEDDB_TEST_DATABASE, + schemaVersion + ); + request.onupgradeneeded = (event: IDBVersionChangeEvent) => { + const db = (event.target as IDBOpenDBRequest).result; + createOrUpgradeDb( + db, + new SimpleDbTransaction(request.transaction), + event.oldVersion, + schemaVersion + ); + }; + request.onsuccess = (event: Event) => { + resolve((event.target as IDBOpenDBRequest).result); + }; + request.onerror = (event: ErrorEvent) => { + reject((event.target as IDBOpenDBRequest).error); + }; + }) + .then(db => fn(db).then(() => db)) + .then(db => { + db.close(); + }); +} + +function getAllObjectStores(db: IDBDatabase): String[] { + const objectStores: String[] = []; + for (let i = 0; i < db.objectStoreNames.length; ++i) { + objectStores.push(db.objectStoreNames.item(i)); + } + objectStores.sort(); + return objectStores; +} + +function getTargetCount(db: IDBDatabase): Promise { + const sdb = new SimpleDb(db); + return sdb + .runTransaction('readonly', [DbTargetGlobal.store], txn => + txn + .store(DbTargetGlobal.store) + .get(DbTargetGlobal.key) + ) + .then(metadata => metadata.targetCount); +} + +describe('IndexedDbSchema: createOrUpgradeDb', () => { + if (!IndexedDbPersistence.isAvailable()) { + console.warn('No IndexedDB. Skipping createOrUpgradeDb() tests.'); + return; + } + + beforeEach(() => SimpleDb.delete(INDEXEDDB_TEST_DATABASE)); + + it('can install schema version 1', () => { + return withDb(1, db => { + expect(db.version).to.equal(1); + // Version 1 adds all of the stores so far. + expect(getAllObjectStores(db)).to.have.members(ALL_STORES); + return Promise.resolve(); + }); + }); + + it('can install schema version 2', () => { + return withDb(2, db => { + expect(db.version).to.equal(2); + // We should have all of the stores, we should have the target global row + // and we should not have any targets counted, because there are none. + expect(getAllObjectStores(db)).to.have.members(ALL_STORES); + // Check the target count. We haven't added any targets, so we expect 0. + return getTargetCount(db).then(targetCount => { + expect(targetCount).to.equal(0); + }); + }); + }); + + it('can upgrade from schema version 1 to 2', () => { + const expectedTargetCount = 5; + return withDb(1, db => { + const sdb = new SimpleDb(db); + // Now that we have all of the stores, add some targets so the next + // migration can count them. + return sdb.runTransaction('readwrite', [DbTarget.store], txn => { + const store = txn.store(DbTarget.store); + let p = PersistencePromise.resolve(); + for (let i = 0; i < expectedTargetCount; i++) { + p = p.next(() => store.put({ targetId: i })); + } + return p; + }); + }).then(() => + withDb(2, db => { + expect(db.version).to.equal(2); + expect(getAllObjectStores(db)).to.have.members(ALL_STORES); + return getTargetCount(db).then(targetCount => { + expect(targetCount).to.equal(expectedTargetCount); + }); + }) + ); + }); +}); diff --git a/packages/firestore/test/unit/local/query_cache.test.ts b/packages/firestore/test/unit/local/query_cache.test.ts index 903e60c0533..c4dcd03df51 100644 --- a/packages/firestore/test/unit/local/query_cache.test.ts +++ b/packages/firestore/test/unit/local/query_cache.test.ts @@ -35,6 +35,7 @@ import { import * as persistenceHelpers from './persistence_test_helpers'; import { TestGarbageCollector } from './test_garbage_collector'; import { TestQueryCache } from './test_query_cache'; +import { fail } from '../../../src/util/assert'; let persistence: Persistence; let cache: TestQueryCache; @@ -97,14 +98,9 @@ function genericQueryCacheTests() { ); } - async function setAndReadQuery(queryData: QueryData): Promise { - await cache.addQueryData(queryData); - const read = await cache.getQueryData(queryData.query); - expect(read).to.deep.equal(queryData); - } - - beforeEach(() => { + beforeEach(async () => { cache = new TestQueryCache(persistence, persistence.getQueryCache()); + await cache.start(); }); it('returns null for query not in cache', () => { @@ -113,8 +109,11 @@ function genericQueryCacheTests() { }); }); - it('can set and read a query', () => { - return setAndReadQuery(testQueryData(QUERY_ROOMS, 1, 1)); + it('can set and read a query', async () => { + const queryData = testQueryData(QUERY_ROOMS, 1, 1); + await cache.addQueryData(queryData); + const read = await cache.getQueryData(queryData.query); + expect(read).to.deep.equal(queryData); }); it('handles canonical ID collisions', async () => { @@ -131,9 +130,11 @@ function genericQueryCacheTests() { // equal canonicalIDs. expect(await cache.getQueryData(q2)).to.equal(null); expect(await cache.getQueryData(q1)).to.deep.equal(data1); + expect(cache.count()).to.equal(1); const data2 = testQueryData(q2, 2, 1); await cache.addQueryData(data2); + expect(cache.count()).to.equal(2); expect(await cache.getQueryData(q1)).to.deep.equal(data1); expect(await cache.getQueryData(q2)).to.deep.equal(data2); @@ -141,15 +142,20 @@ function genericQueryCacheTests() { await cache.removeQueryData(data1); expect(await cache.getQueryData(q1)).to.equal(null); expect(await cache.getQueryData(q2)).to.deep.equal(data2); + expect(cache.count()).to.equal(1); await cache.removeQueryData(data2); expect(await cache.getQueryData(q1)).to.equal(null); expect(await cache.getQueryData(q2)).to.equal(null); + expect(cache.count()).to.equal(0); }); it('can set query to new value', async () => { await cache.addQueryData(testQueryData(QUERY_ROOMS, 1, 1)); - await setAndReadQuery(testQueryData(QUERY_ROOMS, 1, 2)); + const updated = testQueryData(QUERY_ROOMS, 1, 2); + await cache.updateQueryData(updated); + const retrieved = await cache.getQueryData(updated.query); + expect(retrieved).to.deep.equal(updated); }); it('can remove a query', async () => { @@ -160,11 +166,6 @@ function genericQueryCacheTests() { expect(read).to.equal(null); }); - it('can remove nonexistent query', () => { - // no-op, but make sure it doesn't fail. - return cache.removeQueryData(testQueryData(QUERY_ROOMS, 1, 1)); - }); - it('can remove matching keys when a query is removed', async () => { const rooms = testQueryData(QUERY_ROOMS, 1, 1); await cache.addQueryData(rooms); diff --git a/packages/firestore/test/unit/local/simple_db.test.ts b/packages/firestore/test/unit/local/simple_db.test.ts index 038f9a6b729..33c7aa95c09 100644 --- a/packages/firestore/test/unit/local/simple_db.test.ts +++ b/packages/firestore/test/unit/local/simple_db.test.ts @@ -84,6 +84,7 @@ describe('SimpleDb', () => { // A store that uses arrays as keys. db.createObjectStore('docs'); + return PersistencePromise.resolve(); }); }) .then(simpleDb => { diff --git a/packages/firestore/test/unit/local/test_query_cache.ts b/packages/firestore/test/unit/local/test_query_cache.ts index eefe0032cdb..17d484fc743 100644 --- a/packages/firestore/test/unit/local/test_query_cache.ts +++ b/packages/firestore/test/unit/local/test_query_cache.ts @@ -42,6 +42,16 @@ export class TestQueryCache { }); } + updateQueryData(queryData: QueryData): Promise { + return this.persistence.runTransaction('updateQueryData', txn => { + return this.cache.updateQueryData(txn, queryData); + }); + } + + count(): number { + return this.cache.count; + } + removeQueryData(queryData: QueryData): Promise { return this.persistence.runTransaction('addQueryData', txn => { return this.cache.removeQueryData(txn, queryData); From 3d6289dd7853240a09887cbf2fea06b0a33ac357 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 28 Feb 2018 10:49:47 -0800 Subject: [PATCH 13/34] @firebase/logger (#473) * Start work on @firebase/logger package * Refactor to remove debug dep * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: License Headers * Expose a LogHandler type * Allow users to "silence" our logging * Adding some comments * Do @firebase/firestore integration * Do @firebase/database integration * [AUTOMATED]: Prettier Code Styling * Refactor to propagate the default level if changed * Add some basic tests * [AUTOMATED]: Prettier Code Styling * Feedback from @mikelehen and @schmidt-sebastian Refactor to also log fatal issues Refactor to not attempt to log if the level is invalid Adding docs and more feedback * [AUTOMATED]: Prettier Code Styling * Fixing an error message * Updating yarn.lock * Address @mikelehen feedback * [AUTOMATED]: Prettier Code Styling * Refactor logClient.log -> logClient.debug * Update deps * More @mikelehen feedback * Fixing comment * Feedback from @schmidt-sebastian --- packages/database/package.json | 1 + .../database/src/core/PersistentConnection.ts | 2 +- packages/database/src/core/util/util.ts | 39 ++--- packages/firestore/package.json | 1 + packages/firestore/src/util/log.ts | 42 +++-- packages/logger/.npmignore | 1 + packages/logger/README.md | 40 +++++ packages/logger/gulpfile.js | 31 ++++ packages/logger/index.ts | 25 +++ packages/logger/karma.conf.js | 31 ++++ packages/logger/package.json | 54 ++++++ packages/logger/src/logger.ts | 156 ++++++++++++++++++ packages/logger/test/logger.test.ts | 99 +++++++++++ packages/logger/tsconfig.json | 9 + packages/template/index.ts | 7 - 15 files changed, 492 insertions(+), 46 deletions(-) create mode 100644 packages/logger/.npmignore create mode 100644 packages/logger/README.md create mode 100644 packages/logger/gulpfile.js create mode 100644 packages/logger/index.ts create mode 100644 packages/logger/karma.conf.js create mode 100644 packages/logger/package.json create mode 100644 packages/logger/src/logger.ts create mode 100644 packages/logger/test/logger.test.ts create mode 100644 packages/logger/tsconfig.json diff --git a/packages/database/package.json b/packages/database/package.json index f4b84eed31b..73a9d081f2a 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@firebase/database-types": "0.1.2", + "@firebase/logger": "0.1.0", "@firebase/util": "0.1.10", "faye-websocket": "0.11.1", "tslib": "^1.9.0" diff --git a/packages/database/src/core/PersistentConnection.ts b/packages/database/src/core/PersistentConnection.ts index 541e8a8868d..6f595c29b82 100644 --- a/packages/database/src/core/PersistentConnection.ts +++ b/packages/database/src/core/PersistentConnection.ts @@ -935,7 +935,7 @@ export class PersistentConnection extends ServerActions { if (this.securityDebugCallback_) { this.securityDebugCallback_(body); } else { - if ('msg' in body && typeof console !== 'undefined') { + if ('msg' in body) { console.log('FIREBASE: ' + body['msg'].replace('\n', '\nFIREBASE: ')); } } diff --git a/packages/database/src/core/util/util.ts b/packages/database/src/core/util/util.ts index bd501505ea9..72b25e04811 100644 --- a/packages/database/src/core/util/util.ts +++ b/packages/database/src/core/util/util.ts @@ -27,6 +27,9 @@ import { stringToByteArray } from '@firebase/util'; import { stringify } from '@firebase/util'; import { SessionStorage } from '../storage/storage'; import { isNodeSdk } from '@firebase/util'; +import { Logger } from '@firebase/logger'; + +const logClient = new Logger('@firebase/database'); /** * Returns a locally-unique ID (generated by just incrementing up from 0 each time its called). @@ -105,16 +108,7 @@ export const enableLogging = function( "Can't turn on custom loggers persistently." ); if (logger_ === true) { - if (typeof console !== 'undefined') { - if (typeof console.log === 'function') { - logger = console.log.bind(console); - } else if (typeof console.log === 'object') { - // IE does this. - logger = function(message) { - console.log(message); - }; - } - } + logger = logClient.log.bind(logClient); if (persistent) SessionStorage.set('logging_enabled', true); } else if (typeof logger_ === 'function') { logger = logger_; @@ -157,36 +151,25 @@ export const logWrapper = function( * @param {...string} var_args */ export const error = function(...var_args: string[]) { - if (typeof console !== 'undefined') { - const message = 'FIREBASE INTERNAL ERROR: ' + buildLogMessage_(...var_args); - if (typeof console.error !== 'undefined') { - console.error(message); - } else { - console.log(message); - } - } + const message = 'FIREBASE INTERNAL ERROR: ' + buildLogMessage_(...var_args); + logClient.error(message); }; /** * @param {...string} var_args */ export const fatal = function(...var_args: string[]) { - const message = buildLogMessage_(...var_args); - throw new Error('FIREBASE FATAL ERROR: ' + message); + const message = `FIREBASE FATAL ERROR: ${buildLogMessage_(...var_args)}`; + logClient.error(message); + throw new Error(message); }; /** * @param {...*} var_args */ export const warn = function(...var_args: any[]) { - if (typeof console !== 'undefined') { - const message = 'FIREBASE WARNING: ' + buildLogMessage_(...var_args); - if (typeof console.warn !== 'undefined') { - console.warn(message); - } else { - console.log(message); - } - } + const message = 'FIREBASE WARNING: ' + buildLogMessage_(...var_args); + logClient.warn(message); }; /** diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 96fb38ef60d..bd291401261 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -23,6 +23,7 @@ "license": "Apache-2.0", "dependencies": { "@firebase/firestore-types": "0.2.2", + "@firebase/logger": "0.1.0", "@firebase/webchannel-wrapper": "0.2.6", "grpc": "^1.9.1", "tslib": "^1.9.0" diff --git a/packages/firestore/src/util/log.ts b/packages/firestore/src/util/log.ts index 579d76743c2..bca80685b90 100644 --- a/packages/firestore/src/util/log.ts +++ b/packages/firestore/src/util/log.ts @@ -19,6 +19,9 @@ import { SDK_VERSION } from '../core/version'; import { AnyJs } from './misc'; import { PlatformSupport } from '../platform/platform'; +import { Logger, LogLevel as FirebaseLogLevel } from '@firebase/logger'; + +const logClient = new Logger('@firebase/firestore'); export enum LogLevel { DEBUG, @@ -26,29 +29,48 @@ export enum LogLevel { SILENT } -let logLevel = LogLevel.ERROR; - // Helper methods are needed because variables can't be exported as read/write export function getLogLevel(): LogLevel { - return logLevel; + if (logClient.logLevel === FirebaseLogLevel.DEBUG) { + return LogLevel.DEBUG; + } else if (logClient.logLevel === FirebaseLogLevel.SILENT) { + return LogLevel.SILENT; + } else { + return LogLevel.ERROR; + } } export function setLogLevel(newLevel: LogLevel): void { - logLevel = newLevel; + /** + * Map the new log level to the associated Firebase Log Level + */ + switch (newLevel) { + case LogLevel.DEBUG: + logClient.logLevel = FirebaseLogLevel.DEBUG; + break; + case LogLevel.ERROR: + logClient.logLevel = FirebaseLogLevel.ERROR; + break; + case LogLevel.SILENT: + logClient.logLevel = FirebaseLogLevel.SILENT; + break; + default: + logClient.error( + `Firestore (${SDK_VERSION}): Invalid value passed to \`setLogLevel\`` + ); + } } export function debug(tag: string, msg: string, ...obj: AnyJs[]): void { - if (logLevel <= LogLevel.DEBUG) { - const time = new Date().toISOString(); + if (logClient.logLevel <= FirebaseLogLevel.DEBUG) { const args = obj.map(argToString); - console.log(`Firestore (${SDK_VERSION}) ${time} [${tag}]: ${msg}`, ...args); + logClient.debug(`Firestore (${SDK_VERSION}) [${tag}]: ${msg}`, ...args); } } export function error(msg: string, ...obj: AnyJs[]): void { - if (logLevel <= LogLevel.ERROR) { - const time = new Date().toISOString(); + if (logClient.logLevel <= FirebaseLogLevel.ERROR) { const args = obj.map(argToString); - console.error(`Firestore (${SDK_VERSION}) ${time}: ${msg}`, ...args); + logClient.error(`Firestore (${SDK_VERSION}): ${msg}`, ...args); } } diff --git a/packages/logger/.npmignore b/packages/logger/.npmignore new file mode 100644 index 00000000000..6de0b6d2896 --- /dev/null +++ b/packages/logger/.npmignore @@ -0,0 +1 @@ +# This file is left intentionally blank \ No newline at end of file diff --git a/packages/logger/README.md b/packages/logger/README.md new file mode 100644 index 00000000000..69c1642e2ae --- /dev/null +++ b/packages/logger/README.md @@ -0,0 +1,40 @@ +# @firebase/logger + +This package serves as the base of all logging in the JS SDK. Any logging that +is intended to be visible to Firebase end developers should go through this +module. + +## Basic Usage + +Firebase components should import the `Logger` class and instantiate a new +instance by passing a component name (e.g. `@firebase/`) to the +constructor. + +_e.g._ + +```typescript +import { Logger } from '@firebase/logger'; + +const logClient = new Logger(`@firebase/`); +``` + +Each `Logger` instance supports 5 log functions each to be used in a specific +instance: + +- `debug`: Internal logs; use this to allow developers to send us their debug + logs for us to be able to diagnose an issue. +- `log`: Use to inform your user about things they may need to know. +- `info`: Use if you have to inform the user about something that they need to + take a concrete action on. Once they take that action, the log should go away. +- `warn`: Use when a product feature may stop functioning correctly; unexpected + scenario. +- `error`: Only use when user App would stop functioning correctly - super rare! + +## Log Format + +Each log will be formatted in the following manner: + +```typescript +`[${new Date()}] ${COMPONENT_NAME}: ${...args}` +``` + diff --git a/packages/logger/gulpfile.js b/packages/logger/gulpfile.js new file mode 100644 index 00000000000..dc8ec17b593 --- /dev/null +++ b/packages/logger/gulpfile.js @@ -0,0 +1,31 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const gulp = require('gulp'); +const tools = require('../../tools/build'); + +const buildModule = gulp.parallel([ + tools.buildCjs(__dirname), + tools.buildEsm(__dirname) +]); + +const setupWatcher = () => { + gulp.watch(['index.ts', 'src/**/*'], buildModule); +}; + +gulp.task('build', buildModule); + +gulp.task('dev', gulp.parallel([setupWatcher])); diff --git a/packages/logger/index.ts b/packages/logger/index.ts new file mode 100644 index 00000000000..9abb0eacb28 --- /dev/null +++ b/packages/logger/index.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { instances, LogLevel } from './src/logger'; + +export function setLogLevel(level: LogLevel) { + instances.forEach(inst => { + inst.logLevel = level; + }); +} + +export { Logger, LogLevel, LogHandler } from './src/logger'; diff --git a/packages/logger/karma.conf.js b/packages/logger/karma.conf.js new file mode 100644 index 00000000000..9a064313342 --- /dev/null +++ b/packages/logger/karma.conf.js @@ -0,0 +1,31 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const karma = require('karma'); +const path = require('path'); +const karmaBase = require('../../config/karma.base'); + +module.exports = function(config) { + const karmaConfig = Object.assign({}, karmaBase, { + // files to load into karma + files: [{ pattern: `test/**/*` }], + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['mocha'] + }); + + config.set(karmaConfig); +}; diff --git a/packages/logger/package.json b/packages/logger/package.json new file mode 100644 index 00000000000..fa20ae34233 --- /dev/null +++ b/packages/logger/package.json @@ -0,0 +1,54 @@ +{ + "name": "@firebase/logger", + "version": "0.1.0", + "private": true, + "description": "A logger package for use in the Firebase JS SDK", + "author": "Firebase (https://firebase.google.com/)", + "main": "dist/cjs/index.js", + "module": "dist/esm/index.js", + "scripts": { + "dev": "gulp dev", + "test": "run-p test:browser test:node", + "test:browser": "karma start --single-run", + "test:browser:debug": "karma start --browsers Chrome --auto-watch", + "test:node": "nyc --reporter lcovonly -- mocha test/**/*.test.* --compilers ts:ts-node/register --exit", + "prepare": "gulp build" + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/chai": "^4.1.2", + "@types/mocha": "^2.2.48", + "@types/sinon": "^4.1.3", + "chai": "^4.1.1", + "gulp": "^4.0.0", + "karma": "^2.0.0", + "karma-chrome-launcher": "^2.2.0", + "karma-cli": "^1.0.1", + "karma-mocha": "^1.3.0", + "karma-sauce-launcher": "^1.2.0", + "karma-spec-reporter": "^0.0.32", + "karma-webpack": "^2.0.9", + "mocha": "^5.0.1", + "npm-run-all": "^4.1.1", + "nyc": "^11.4.1", + "ts-loader": "^3.5.0", + "ts-node": "^5.0.0", + "typescript": "^2.7.2", + "webpack": "^3.11.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/firebase/firebase-js-sdk/tree/master/packages/logger" + }, + "bugs": { + "url": "https://github.com/firebase/firebase-js-sdk/issues" + }, + "typings": "dist/esm/index.d.ts", + "nyc": { + "extension": [ + ".ts" + ], + "reportDir": "./coverage/node" + }, + "dependencies": {} +} diff --git a/packages/logger/src/logger.ts b/packages/logger/src/logger.ts new file mode 100644 index 00000000000..8b162f816f8 --- /dev/null +++ b/packages/logger/src/logger.ts @@ -0,0 +1,156 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A container for all of the Logger instances + */ +export const instances: Logger[] = []; + +/** + * The JS SDK supports 5 log levels and also allows a user the ability to + * silence the logs altogether. + * + * The order is a follows: + * DEBUG < VERBOSE < INFO < WARN < ERROR + * + * All of the log types above the current log level will be captured (i.e. if + * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and + * `VERBOSE` logs will not) + */ +export enum LogLevel { + DEBUG, + VERBOSE, + INFO, + WARN, + ERROR, + SILENT +} + +/** + * The default log level + */ +const defaultLogLevel: LogLevel = LogLevel.INFO; + +/** + * We allow users the ability to pass their own log handler. We will pass the + * type of log, the current log level, and any other arguments passed (i.e. the + * messages that the user wants to log) to this function. + */ +export type LogHandler = ( + loggerInstance: Logger, + logType: LogLevel, + ...args: any[] +) => void; + +/** + * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR + * messages on to their corresponding console counterparts (if the log method + * is supported by the current log level) + */ +const defaultLogHandler: LogHandler = (instance, logType, ...args) => { + if (logType < instance.logLevel) return; + const now = new Date().toISOString(); + switch (logType) { + /** + * By default, `console.debug` is not displayed in the developer console (in + * chrome). To avoid forcing users to have to opt-in to these logs twice + * (i.e. once for firebase, and once in the console), we are sending `DEBUG` + * logs to the `console.log` function. + */ + case LogLevel.DEBUG: + console.log(`[${now}] ${instance.name}:`, ...args); + break; + case LogLevel.VERBOSE: + console.log(`[${now}] ${instance.name}:`, ...args); + break; + case LogLevel.INFO: + console.info(`[${now}] ${instance.name}:`, ...args); + break; + case LogLevel.WARN: + console.warn(`[${now}] ${instance.name}:`, ...args); + break; + case LogLevel.ERROR: + console.error(`[${now}] ${instance.name}:`, ...args); + break; + default: + throw new Error( + `Attempted to log a message with an invalid logType (value: ${logType})` + ); + } +}; + +export class Logger { + /** + * Gives you an instance of a Logger to capture messages according to + * Firebase's logging scheme. + * + * @param name The name that the logs will be associated with + */ + constructor(public name: string) { + /** + * Capture the current instance for later use + */ + instances.push(this); + } + + /** + * The log level of the given Logger instance. + */ + private _logLevel = defaultLogLevel; + get logLevel(): LogLevel { + return this._logLevel; + } + set logLevel(val: LogLevel) { + if (!(val in LogLevel)) { + throw new TypeError('Invalid value assigned to `logLevel`'); + } + this._logLevel = val; + } + + /** + * The log handler for the Logger instance. + */ + private _logHandler: LogHandler = defaultLogHandler; + get logHandler(): LogHandler { + return this._logHandler; + } + set logHandler(val: LogHandler) { + if (typeof val !== 'function') { + throw new TypeError('Value assigned to `logHandler` must be a function'); + } + this._logHandler = val; + } + + /** + * The functions below are all based on the `console` interface + */ + + debug(...args) { + this._logHandler(this, LogLevel.DEBUG, ...args); + } + log(...args) { + this._logHandler(this, LogLevel.VERBOSE, ...args); + } + info(...args) { + this._logHandler(this, LogLevel.INFO, ...args); + } + warn(...args) { + this._logHandler(this, LogLevel.WARN, ...args); + } + error(...args) { + this._logHandler(this, LogLevel.ERROR, ...args); + } +} diff --git a/packages/logger/test/logger.test.ts b/packages/logger/test/logger.test.ts new file mode 100644 index 00000000000..900880e83a0 --- /dev/null +++ b/packages/logger/test/logger.test.ts @@ -0,0 +1,99 @@ +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import { spy as Spy } from 'sinon'; +import { Logger, LogLevel } from '../src/logger'; +import { setLogLevel } from '../index'; +import { debug } from 'util'; + +describe('@firebase/logger', () => { + const message = 'Hello there!'; + let client: Logger; + const spies = { + logSpy: null, + infoSpy: null, + warnSpy: null, + errorSpy: null + }; + /** + * Before each test, instantiate a new instance of Logger and establish spies + * on all of the console methods so we can assert against them as needed + */ + beforeEach(() => { + client = new Logger('@firebase/test-logger'); + + spies.logSpy = Spy(console, 'log'); + spies.infoSpy = Spy(console, 'info'); + spies.warnSpy = Spy(console, 'warn'); + spies.errorSpy = Spy(console, 'error'); + }); + + afterEach(() => { + spies.logSpy.restore(); + spies.infoSpy.restore(); + spies.warnSpy.restore(); + spies.errorSpy.restore(); + }); + + function testLog(message, channel, shouldLog) { + /** + * Ensure that `debug` logs assert against the `console.log` function. The + * rationale here is explained in `logger.ts`. + */ + channel = channel === 'debug' ? 'log' : channel; + + it(`Should ${ + shouldLog ? '' : 'not' + } call \`console.${channel}\` if \`.${channel}\` is called`, () => { + client[channel](message); + expect( + spies[`${channel}Spy`] && spies[`${channel}Spy`].called, + `Expected ${channel} to ${shouldLog ? '' : 'not'} log` + ).to.be[shouldLog ? 'true' : 'false']; + }); + } + + describe('Class instance methods', () => { + beforeEach(() => { + setLogLevel(LogLevel.DEBUG); + }); + testLog(message, 'debug', true); + testLog(message, 'log', true); + testLog(message, 'info', true); + testLog(message, 'warn', true); + testLog(message, 'error', true); + }); + + describe('Defaults to LogLevel.NOTICE', () => { + testLog(message, 'debug', false); + testLog(message, 'log', false); + testLog(message, 'info', true); + testLog(message, 'warn', true); + testLog(message, 'error', true); + }); + + describe(`Doesn't log if LogLevel.SILENT is set`, () => { + beforeEach(() => { + setLogLevel(LogLevel.SILENT); + }); + testLog(message, 'debug', false); + testLog(message, 'log', false); + testLog(message, 'info', false); + testLog(message, 'warn', false); + testLog(message, 'error', false); + }); +}); diff --git a/packages/logger/tsconfig.json b/packages/logger/tsconfig.json new file mode 100644 index 00000000000..a06ed9a374c --- /dev/null +++ b/packages/logger/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../config/tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "exclude": [ + "dist/**/*" + ] +} \ No newline at end of file diff --git a/packages/template/index.ts b/packages/template/index.ts index d362d85d4eb..907a7b0e607 100644 --- a/packages/template/index.ts +++ b/packages/template/index.ts @@ -14,13 +14,6 @@ * limitations under the License. */ -/** - * This is the file that people using Node.js will actually import. You should - * only include this file if you have something specific about your - * implementation that mandates having a separate entrypoint. Otherwise you can - * just use index.ts - */ - import { testFxn } from './src'; testFxn(); From c1a07da3d4607e175f7952c7bff8205359164336 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 28 Feb 2018 11:36:36 -0800 Subject: [PATCH 14/34] Refactor npm publish command (#536) --- scripts/release/utils/npm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release/utils/npm.js b/scripts/release/utils/npm.js index 83dcfffcef9..2e009efa81c 100644 --- a/scripts/release/utils/npm.js +++ b/scripts/release/utils/npm.js @@ -39,7 +39,7 @@ async function publishPackage(pkg, releaseType) { * Default publish args */ - let args = ['publish']; + let args = ['publish', '--access', 'public']; /** * Ensure prereleases are tagged with the `next` tag From fbb2aabe2527cafce4dca1d56bd34f8e0e0a0d65 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 28 Feb 2018 11:41:40 -0800 Subject: [PATCH 15/34] Remove the "private" flag from the @firebase/logger package (#537) --- packages/logger/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/logger/package.json b/packages/logger/package.json index fa20ae34233..ade24b85035 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -1,7 +1,6 @@ { "name": "@firebase/logger", "version": "0.1.0", - "private": true, "description": "A logger package for use in the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", From dbed6899923aceedb87860a1381b478d8d9880c4 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 1 Mar 2018 09:45:46 -0800 Subject: [PATCH 16/34] Database API: Ref from Ref (#534) --- packages/database-types/index.d.ts | 2 +- packages/database/src/api/Database.ts | 21 ++++++++++++++++----- packages/database/test/database.test.ts | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/database-types/index.d.ts b/packages/database-types/index.d.ts index f47dae548b5..35e89d4fc15 100644 --- a/packages/database-types/index.d.ts +++ b/packages/database-types/index.d.ts @@ -37,7 +37,7 @@ export class FirebaseDatabase { app: FirebaseApp; goOffline(): void; goOnline(): void; - ref(path?: string): Reference; + ref(path?: string | Reference): Reference; refFromURL(url: string): Reference; } diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts index d237867c4a2..54b206503ca 100644 --- a/packages/database/src/api/Database.ts +++ b/packages/database/src/api/Database.ts @@ -62,15 +62,26 @@ export class Database implements FirebaseService { } /** - * Returns a reference to the root or the path specified in opt_pathString. - * @param {string=} pathString + * Returns a reference to the root or to the path specified in the provided + * argument. + + * @param {string|Reference=} path The relative string path or an existing + * Reference to a database location. + * @throws If a Reference is provided, throws if it does not belong to the + * same project. * @return {!Reference} Firebase reference. - */ - ref(pathString?: string): Reference { + **/ + ref(path?: string): Reference; + ref(path?: Reference): Reference; + ref(path?: string | Reference): Reference { this.checkDeleted_('ref'); validateArgCount('database.ref', 0, 1, arguments.length); - return pathString !== undefined ? this.root_.child(pathString) : this.root_; + if (path instanceof Reference) { + return this.refFromURL(path.toString()); + } + + return path !== undefined ? this.root_.child(path) : this.root_; } /** diff --git a/packages/database/test/database.test.ts b/packages/database/test/database.test.ts index 227e84decac..2514bf2c020 100644 --- a/packages/database/test/database.test.ts +++ b/packages/database/test/database.test.ts @@ -149,6 +149,17 @@ describe('Database Tests', function() { expect(ref.key).to.equal('grand-child'); }); + it('Can get ref from ref', function() { + const db1 = (firebase as any).database(); + const db2 = (firebase as any).database(); + + const ref1 = db1.ref('child'); + const ref2 = db2.ref(ref1); + + expect(ref1.key).to.equal('child'); + expect(ref2.key).to.equal('child'); + }); + it('ref() validates arguments', function() { const db = (firebase as any).database(); expect(function() { @@ -156,6 +167,17 @@ describe('Database Tests', function() { }).to.throw(/Expects no more than 1/); }); + it('ref() validates project', function() { + const db1 = defaultApp.database('http://bar.foo.com'); + const db2 = defaultApp.database('http://foo.bar.com'); + + const ref1 = db1.ref('child'); + + expect(function() { + db2.ref(ref1); + }).to.throw(/does not match.*database/i); + }); + it('Can get refFromURL()', function() { const db = (firebase as any).database(); const ref = db.refFromURL(TEST_PROJECT.databaseURL + '/path/to/data'); From aba869cf779b32da2901ac1502577e240ec2efbb Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Fri, 2 Mar 2018 14:05:47 -0800 Subject: [PATCH 17/34] [AUTOMATED]: Prettier Code Styling --- packages/database/test/order_by.test.ts | 4 +- packages/database/test/query.test.ts | 28 +++-------- packages/database/test/transaction.test.ts | 48 +++++-------------- .../src/platform_node/grpc_connection.ts | 6 +-- .../firestore/src/remote/persistent_stream.ts | 4 +- .../firestore/src/util/input_validation.ts | 8 ++-- .../test/integration/api/validation.test.ts | 4 +- 7 files changed, 28 insertions(+), 74 deletions(-) diff --git a/packages/database/test/order_by.test.ts b/packages/database/test/order_by.test.ts index 70495f2fd60..b821de62138 100644 --- a/packages/database/test/order_by.test.ts +++ b/packages/database/test/order_by.test.ts @@ -363,9 +363,7 @@ describe('.orderBy tests', function() { expect(addedPrevNames).to.deep.equal(expectedPrevNames); }); - it('Removing default listener removes non-default listener that loads all data', function( - done - ) { + it('Removing default listener removes non-default listener that loads all data', function(done) { const ref = getRandomNode() as Reference; const initial = { key: 'value' }; diff --git a/packages/database/test/query.test.ts b/packages/database/test/query.test.ts index 499748d3edd..bda21cdbb0b 100644 --- a/packages/database/test/query.test.ts +++ b/packages/database/test/query.test.ts @@ -1971,9 +1971,7 @@ describe('Query Tests', function() { expect(val).to.equal(2); }); - it('.startAt() with two arguments works properly (case 1169).', function( - done - ) { + it('.startAt() with two arguments works properly (case 1169).', function(done) { const ref = getRandomNode() as Reference; const data = { Walker: { @@ -2110,9 +2108,7 @@ describe('Query Tests', function() { }); }); - it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", function( - done - ) { + it(".endAt(null, 'f').limitToLast(5) returns the right set of children.", function(done) { const ref = getRandomNode() as Reference; ref.set( { a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f', g: 'g', h: 'h' }, @@ -2134,9 +2130,7 @@ describe('Query Tests', function() { ); }); - it('complex update() at query root raises correct value event', function( - done - ) { + it('complex update() at query root raises correct value event', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2241,9 +2235,7 @@ describe('Query Tests', function() { }); }); - it('listen for child_added events with limit and different types fires properly', function( - done - ) { + it('listen for child_added events with limit and different types fires properly', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2285,9 +2277,7 @@ describe('Query Tests', function() { }); }); - it('listen for child_changed events with limit and different types fires properly', function( - done - ) { + it('listen for child_changed events with limit and different types fires properly', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2338,9 +2328,7 @@ describe('Query Tests', function() { }); }); - it('listen for child_remove events with limit and different types fires properly', function( - done - ) { + it('listen for child_remove events with limit and different types fires properly', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; @@ -2442,9 +2430,7 @@ describe('Query Tests', function() { ); }); - it('listen for child_remove events when parent set to scalar', function( - done - ) { + it('listen for child_remove events when parent set to scalar', function(done) { const nodePair = getRandomNode(2); const writer = nodePair[0]; const reader = nodePair[1]; diff --git a/packages/database/test/transaction.test.ts b/packages/database/test/transaction.test.ts index e603105ebc0..d0f44f5accc 100644 --- a/packages/database/test/transaction.test.ts +++ b/packages/database/test/transaction.test.ts @@ -86,9 +86,7 @@ describe('Transaction Tests', function() { }); }); - it('Non-aborted transaction sets committed to true in callback.', function( - done - ) { + it('Non-aborted transaction sets committed to true in callback.', function(done) { const node = getRandomNode() as Reference; node.transaction( @@ -104,9 +102,7 @@ describe('Transaction Tests', function() { ); }); - it('Aborted transaction sets committed to false in callback.', function( - done - ) { + it('Aborted transaction sets committed to false in callback.', function(done) { const node = getRandomNode() as Reference; node.transaction( @@ -236,9 +232,7 @@ describe('Transaction Tests', function() { return ea.promise; }); - it('Second transaction gets run immediately on previous output and only runs once.', function( - done - ) { + it('Second transaction gets run immediately on previous output and only runs once.', function(done) { const nodePair = getRandomNode(2) as Reference[]; let firstRun = false, firstDone = false, @@ -512,9 +506,7 @@ describe('Transaction Tests', function() { ); }); - it('Set should cancel already sent transactions that come back as datastale.', function( - done - ) { + it('Set should cancel already sent transactions that come back as datastale.', function(done) { const nodePair = getRandomNode(2) as Reference[]; let transactionCalls = 0; nodePair[0].set(5, function() { @@ -688,9 +680,7 @@ describe('Transaction Tests', function() { return Promise.all([tx1, tx2]); }); - it('Doing set() in successful transaction callback works. Case 870.', function( - done - ) { + it('Doing set() in successful transaction callback works. Case 870.', function(done) { const node = getRandomNode() as Reference; let transactionCalled = false; let callbackCalled = false; @@ -710,9 +700,7 @@ describe('Transaction Tests', function() { ); }); - it('Doing set() in aborted transaction callback works. Case 870.', function( - done - ) { + it('Doing set() in aborted transaction callback works. Case 870.', function(done) { const nodePair = getRandomNode(2) as Reference[], node1 = nodePair[0], node2 = nodePair[1]; @@ -1028,9 +1016,7 @@ describe('Transaction Tests', function() { ); }); - it('Transaction properly reverts data when you add a deeper listen.', function( - done - ) { + it('Transaction properly reverts data when you add a deeper listen.', function(done) { const refPair = getRandomNode(2) as Reference[], ref1 = refPair[0], ref2 = refPair[1]; @@ -1200,9 +1186,7 @@ describe('Transaction Tests', function() { }); }); - it("transaction() doesn't pick up cached data from previous once().", function( - done - ) { + it("transaction() doesn't pick up cached data from previous once().", function(done) { const refPair = getRandomNode(2) as Reference[]; const me = refPair[0], other = refPair[1]; @@ -1229,9 +1213,7 @@ describe('Transaction Tests', function() { }); }); - it("transaction() doesn't pick up cached data from previous transaction.", function( - done - ) { + it("transaction() doesn't pick up cached data from previous transaction.", function(done) { const refPair = getRandomNode(2) as Reference[]; const me = refPair[0], other = refPair[1]; @@ -1263,9 +1245,7 @@ describe('Transaction Tests', function() { ); }); - it('server values: local timestamp should eventually (but not immediately) match the server with txns', function( - done - ) { + it('server values: local timestamp should eventually (but not immediately) match the server with txns', function(done) { const refPair = getRandomNode(2) as Reference[], writer = refPair[0], reader = refPair[1], @@ -1357,9 +1337,7 @@ describe('Transaction Tests', function() { ); }); - it("transaction() on queried location doesn't run initially on null (firebase-worker-queue depends on this).", function( - done - ) { + it("transaction() on queried location doesn't run initially on null (firebase-worker-queue depends on this).", function(done) { const ref = getRandomNode() as Reference; ref.push({ a: 1, b: 2 }, function() { ref @@ -1437,9 +1415,7 @@ describe('Transaction Tests', function() { ); }); - it('transactions works with merges without the transaction path', function( - done - ) { + it('transactions works with merges without the transaction path', function(done) { const ref = getRandomNode() as Reference; ref.update({ foo: 'bar' }); diff --git a/packages/firestore/src/platform_node/grpc_connection.ts b/packages/firestore/src/platform_node/grpc_connection.ts index f6780ead440..639c8c3b831 100644 --- a/packages/firestore/src/platform_node/grpc_connection.ts +++ b/packages/firestore/src/platform_node/grpc_connection.ts @@ -37,9 +37,9 @@ const LOG_TAG = 'Connection'; // TODO(b/38203344): The SDK_VERSION is set independently from Firebase because // we are doing out-of-band releases. Once we release as part of Firebase, we // should use the Firebase version instead. -const X_GOOG_API_CLIENT_VALUE = `gl-node/${process.versions.node} fire/${ - SDK_VERSION -} grpc/${grpcVersion}`; +const X_GOOG_API_CLIENT_VALUE = `gl-node/${ + process.versions.node +} fire/${SDK_VERSION} grpc/${grpcVersion}`; type DuplexRpc = () => grpc.ClientDuplexStream; type ReadableRpc = (req: Req) => grpc.ClientReadableStream; diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index e563d084c7b..0fd3c6573fc 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -273,9 +273,7 @@ export abstract class PersistentStream< // rejections are not considered unhandled. assert( err.code === Code.CANCELLED, - `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${ - err - }` + `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${err}` ); }); } diff --git a/packages/firestore/src/util/input_validation.ts b/packages/firestore/src/util/input_validation.ts index 6d7701c760c..7ad47b8b078 100644 --- a/packages/firestore/src/util/input_validation.ts +++ b/packages/firestore/src/util/input_validation.ts @@ -191,11 +191,9 @@ export function validateNamedPropertyEquals( const actualDescription = valueDescription(input); throw new FirestoreError( Code.INVALID_ARGUMENT, - `Invalid value ${actualDescription} provided to function ${ - functionName - }() for option "${ - optionName - }". Acceptable values: ${expectedDescription.join(', ')}` + `Invalid value ${actualDescription} provided to function ${functionName}() for option "${optionName}". Acceptable values: ${expectedDescription.join( + ', ' + )}` ); } diff --git a/packages/firestore/test/integration/api/validation.test.ts b/packages/firestore/test/integration/api/validation.test.ts index 8bab7ff59fa..a9820691496 100644 --- a/packages/firestore/test/integration/api/validation.test.ts +++ b/packages/firestore/test/integration/api/validation.test.ts @@ -170,9 +170,7 @@ apiDescribe('Validation:', persistence => { const collection = db.collection('test-collection'); const doc = collection.doc('test-document'); for (const path of badPaths) { - const reason = `Invalid path (${ - path - }). Paths must not contain // in them.`; + const reason = `Invalid path (${path}). Paths must not contain // in them.`; expect(() => db.collection(path)).to.throw(reason); expect(() => db.doc(path)).to.throw(reason); expect(() => collection.doc(path)).to.throw(reason); From 0fa319e5e019dd0d40ab441d2ff9f8f6d4724e43 Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Fri, 2 Mar 2018 17:23:26 -0800 Subject: [PATCH 18/34] Add 10 second timeout waiting for connection before client behaves as-if offline. * Refactored OnlineState tracking out of RemoteStore and into new OnlineStateTracker component. * Added a 10 second timeout to transition from OnlineState.Unknown to OnlineState.Offline rather than waiting indefinitely for the stream to succeed or fail. * Added a SpecTest to verify OnlineState timeout behavior. * Misc cleanup: * Renamed OnlineState states: Failed => Offline, Healthy => Online * Renamed TimerIds (ListenStreamConnection => ListenStreamConnectionBackoff) * Added a dummy .catch() handler to the CancelablePromises returned by AsyncQueue.enqueueAfterDelay() to avoid UnhandledPromiseRejection log spam due to canceled timers. * Added ability to run timers from spec tests (including assigning string names to TimerId enum values) * Added TimerId.All to match iOS and make it easier to run all timers from spec tests. --- packages/firestore/CHANGELOG.md | 6 + packages/firestore/src/core/event_manager.ts | 6 +- .../firestore/src/core/firestore_client.ts | 1 + packages/firestore/src/core/types.ts | 4 +- packages/firestore/src/core/view.ts | 2 +- .../src/remote/online_state_tracker.ts | 172 ++++++++++++++++++ .../firestore/src/remote/persistent_stream.ts | 15 +- packages/firestore/src/remote/remote_store.ts | 104 +++-------- packages/firestore/src/util/async_queue.ts | 50 +++-- .../test/integration/remote/stream.test.ts | 2 +- .../test/unit/core/event_manager.test.ts | 22 +-- .../test/unit/specs/offline_spec.test.ts | 35 ++++ .../firestore/test/unit/specs/spec_builder.ts | 7 + .../test/unit/specs/spec_test_runner.ts | 27 ++- .../test/unit/util/async_queue.test.ts | 8 +- 15 files changed, 328 insertions(+), 133 deletions(-) create mode 100644 packages/firestore/src/remote/online_state_tracker.ts diff --git a/packages/firestore/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 322bb768de3..354a8050718 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -1,4 +1,10 @@ # Unreleased +- [changed] If the SDK's attempt to connect to the Cloud Firestore backend + neither succeeds nor fails within 10 seconds, the SDK will consider itself + "offline", causing get() calls to resolve with cached results, rather than + continuing to wait. + +# 0.3.2 - [fixed] Fixed a regression in Firebase JS release 4.9.0 that could in certain cases result in an "OnlineState should not affect limbo documents." assertion crash when the client loses its network connection. diff --git a/packages/firestore/src/core/event_manager.ts b/packages/firestore/src/core/event_manager.ts index 12e07e48e32..2b4311886c0 100644 --- a/packages/firestore/src/core/event_manager.ts +++ b/packages/firestore/src/core/event_manager.ts @@ -248,9 +248,9 @@ export class QueryListener { return true; } - // NOTE: We consider OnlineState.Unknown as online (it should become Failed + // NOTE: We consider OnlineState.Unknown as online (it should become Offline // or Online if we wait long enough). - const maybeOnline = onlineState !== OnlineState.Failed; + const maybeOnline = onlineState !== OnlineState.Offline; // Don't raise the event if we're online, aren't synced yet (checked // above) and are waiting for a sync. if (this.options.waitForSyncWhenOnline && maybeOnline) { @@ -262,7 +262,7 @@ export class QueryListener { } // Raise data from cache if we have any documents or we are offline - return !snap.docs.isEmpty() || onlineState === OnlineState.Failed; + return !snap.docs.isEmpty() || onlineState === OnlineState.Offline; } private shouldRaiseEvent(snap: ViewSnapshot): boolean { diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts index 63e349a5fd1..7829d07eabb 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -288,6 +288,7 @@ export class FirestoreClient { this.remoteStore = new RemoteStore( this.localStore, datastore, + this.asyncQueue, onlineStateChangedHandler ); diff --git a/packages/firestore/src/core/types.ts b/packages/firestore/src/core/types.ts index 49693083a76..c5ef83a76bc 100644 --- a/packages/firestore/src/core/types.ts +++ b/packages/firestore/src/core/types.ts @@ -51,12 +51,12 @@ export enum OnlineState { * reached after a successful connection and there has been at least one * successful message received from the backends. */ - Healthy, + Online, /** * The client is either trying to establish a connection but failing, or it * has been explicitly marked offline via a call to disableNetwork(). * Higher-level components should operate in offline mode. */ - Failed + Offline } diff --git a/packages/firestore/src/core/view.ts b/packages/firestore/src/core/view.ts index 8da76d74faa..b7d811fa6af 100644 --- a/packages/firestore/src/core/view.ts +++ b/packages/firestore/src/core/view.ts @@ -276,7 +276,7 @@ export class View { * ViewChange if the view's syncState changes as a result. */ applyOnlineStateChange(onlineState: OnlineState): ViewChange { - if (this.current && onlineState === OnlineState.Failed) { + if (this.current && onlineState === OnlineState.Offline) { // If we're offline, set `current` to false and then call applyChanges() // to refresh our syncState and generate a ViewChange as appropriate. We // are guaranteed to get a new TargetChange that sets `current` back to diff --git a/packages/firestore/src/remote/online_state_tracker.ts b/packages/firestore/src/remote/online_state_tracker.ts new file mode 100644 index 00000000000..147f8d49323 --- /dev/null +++ b/packages/firestore/src/remote/online_state_tracker.ts @@ -0,0 +1,172 @@ +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { OnlineState } from '../core/types'; +import * as log from '../util/log'; +import { assert } from '../util/assert'; +import { AsyncQueue, TimerId } from '../util/async_queue'; +import { CancelablePromise } from '../util/promise'; + +const LOG_TAG = 'OnlineStateTracker'; + +// To deal with transient failures, we allow multiple stream attempts before +// giving up and transitioning from OnlineState.Unknown to Offline. +const MAX_WATCH_STREAM_FAILURES = 2; + +// To deal with stream attempts that don't succeed or fail in a timely manner, +// we have a timeout for OnlineState to reach Online or Offline. +// If the timeout is reached, we transition to Offline rather than waiting +// indefinitely. +const ONLINE_STATE_TIMEOUT_MS = 10 * 1000; + +/** + * A component used by the RemoteStore to track the OnlineState (that is, + * whether or not the client as a whole should be considered to be online or + * offline), implementing the appropriate heuristics. + * + * In particular, when the client is trying to connect to the backend, we + * allow up to MAX_WATCH_STREAM_FAILURES within ONLINE_STATE_TIMEOUT_MS for + * a connection to succeed. If we have too many failures or the timeout elapses, + * then we set the OnlineState to Offline, and the client will behave as if + * it is offline (get()s will return cached data, etc.). + */ +export class OnlineStateTracker { + /** The current OnlineState. */ + private state = OnlineState.Unknown; + + /** + * A count of consecutive failures to open the stream. If it reaches the + * maximum defined by MAX_WATCH_STREAM_FAILURES, we'll set the OnlineState to + * Offline. + */ + private watchStreamFailures = 0; + + /** + * A timer that elapses after ONLINE_STATE_TIMEOUT_MS, at which point we + * transition from OnlineState.Unknown to OnlineState.Offline without waiting + * for the stream to actually fail (MAX_WATCH_STREAM_FAILURES times). + */ + private onlineStateTimer: CancelablePromise | null = null; + + /** + * Whether the client should log a warning message if it fails to connect to + * the backend (initially true, cleared after a successful stream, or if we've + * logged the message already). + */ + private shouldWarnClientIsOffline = true; + + constructor( + private asyncQueue: AsyncQueue, + private onlineStateHandler: (onlineState: OnlineState) => void + ) {} + + /** + * Called by RemoteStore when a watch stream is started. + * + * It sets the OnlineState to Unknown and starts the onlineStateTimer + * if necessary. + */ + handleWatchStreamStart(): void { + this.setAndBroadcast(OnlineState.Unknown); + + if (this.onlineStateTimer === null) { + this.onlineStateTimer = this.asyncQueue.enqueueAfterDelay( + TimerId.OnlineStateTimeout, + ONLINE_STATE_TIMEOUT_MS, + () => { + this.onlineStateTimer = null; + assert( + this.state === OnlineState.Unknown, + 'Timer should be canceled if we transitioned to a different state.' + ); + log.debug( + LOG_TAG, + `Watch stream didn't reach online or offline within ` + + `${ONLINE_STATE_TIMEOUT_MS}ms. Considering client offline.` + ); + this.logClientOfflineWarningIfNecessary(); + this.setAndBroadcast(OnlineState.Offline); + + // NOTE: handleWatchStreamFailure() will continue to increment + // watchStreamFailures even though we are already marked Offline, + // but this is non-harmful. + + return Promise.resolve(); + } + ); + } + } + + /** + * Updates our OnlineState as appropriate after the watch stream reports a + * failure. The first failure moves us to the 'Unknown' state. We then may + * allow multiple failures (based on MAX_WATCH_STREAM_FAILURES) before we + * actually transition to the 'Offline' state. + */ + handleWatchStreamFailure(): void { + if (this.state === OnlineState.Online) { + this.setAndBroadcast(OnlineState.Unknown); + } else { + this.watchStreamFailures++; + if (this.watchStreamFailures >= MAX_WATCH_STREAM_FAILURES) { + this.clearOnlineStateTimer(); + this.logClientOfflineWarningIfNecessary(); + this.setAndBroadcast(OnlineState.Offline); + } + } + } + + /** + * Explicitly sets the OnlineState to the specified state. + * + * Note that this resets our timers / failure counters, etc. used by our + * Offline heuristics, so must not be used in place of + * handleWatchStreamStart() and handleWatchStreamFailure(). + */ + set(newState: OnlineState): void { + this.clearOnlineStateTimer(); + this.watchStreamFailures = 0; + + if (newState === OnlineState.Online) { + // We've connected to watch at least once. Don't warn the developer + // about being offline going forward. + this.shouldWarnClientIsOffline = false; + } + + this.setAndBroadcast(newState); + } + + private setAndBroadcast(newState: OnlineState): void { + if (newState !== this.state) { + this.state = newState; + this.onlineStateHandler(newState); + } + } + + private logClientOfflineWarningIfNecessary(): void { + if (this.shouldWarnClientIsOffline) { + log.error('Could not reach Firestore backend.'); + this.shouldWarnClientIsOffline = false; + } + } + + private clearOnlineStateTimer(): void { + if (this.onlineStateTimer !== null) { + this.onlineStateTimer.cancel(); + this.onlineStateTimer = null; + } + } +} diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index 0fd3c6573fc..df573a763b0 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -265,17 +265,6 @@ export abstract class PersistentStream< IDLE_TIMEOUT_MS, () => this.handleIdleCloseTimer() ); - - this.inactivityTimerPromise.catch((err: FirestoreError) => { - // When the AsyncQueue gets drained during testing, pending Promises - // (including these idle checks) will get rejected. We special-case - // these cancelled idle checks to make sure that these specific Promise - // rejections are not considered unhandled. - assert( - err.code === Code.CANCELLED, - `Received unexpected error in idle timeout closure. Expected CANCELLED, but was: ${err}` - ); - }); } } @@ -529,7 +518,7 @@ export class PersistentListenStream extends PersistentStream< ) { super( queue, - TimerId.ListenStreamConnection, + TimerId.ListenStreamConnectionBackoff, TimerId.ListenStreamIdle, connection, credentials @@ -637,7 +626,7 @@ export class PersistentWriteStream extends PersistentStream< ) { super( queue, - TimerId.WriteStreamConnection, + TimerId.WriteStreamConnectionBackoff, TimerId.WriteStreamIdle, connection, credentials diff --git a/packages/firestore/src/remote/remote_store.ts b/packages/firestore/src/remote/remote_store.ts index e65f11f075f..060edbae56b 100644 --- a/packages/firestore/src/remote/remote_store.ts +++ b/packages/firestore/src/remote/remote_store.ts @@ -49,19 +49,14 @@ import { WatchTargetChange, WatchTargetChangeState } from './watch_change'; +import { OnlineStateTracker } from './online_state_tracker'; +import { AsyncQueue } from '../util/async_queue'; const LOG_TAG = 'RemoteStore'; // TODO(b/35853402): Negotiate this with the stream. const MAX_PENDING_WRITES = 10; -// The RemoteStore notifies an onlineStateHandler with OnlineState.Failed if we -// fail to connect to the backend. This subsequently triggers get() requests to -// fail or use cached data, etc. Unfortunately, our connections have -// historically been subject to various transient failures. So we wait for -// multiple failures before notifying the onlineStateHandler. -const ONLINE_ATTEMPTS_BEFORE_FAILURE = 2; - /** * RemoteStore - An interface to remotely stored data, basically providing a * wrapper around the Datastore that is more reliable for the rest of the @@ -117,17 +112,7 @@ export class RemoteStore { private watchStream: PersistentListenStream = null; private writeStream: PersistentWriteStream = null; - /** - * The online state of the watch stream. The state is set to healthy if and - * only if there are messages received by the backend. - */ - private watchStreamOnlineState = OnlineState.Unknown; - - /** A count of consecutive failures to open the stream. */ - private watchStreamFailures = 0; - - /** Whether the client should fire offline warning. */ - private shouldWarnOffline = true; + private onlineStateTracker: OnlineStateTracker; constructor( /** @@ -137,8 +122,14 @@ export class RemoteStore { private localStore: LocalStore, /** The client-side proxy for interacting with the backend. */ private datastore: Datastore, - private onlineStateHandler: (onlineState: OnlineState) => void - ) {} + asyncQueue: AsyncQueue, + onlineStateHandler: (onlineState: OnlineState) => void + ) { + this.onlineStateTracker = new OnlineStateTracker( + asyncQueue, + onlineStateHandler + ); + } /** SyncEngine to notify of watch and write events. */ syncEngine: RemoteSyncer; @@ -151,51 +142,6 @@ export class RemoteStore { return this.enableNetwork(); } - /** - * Updates our OnlineState to the new state, updating local state - * and notifying the onlineStateHandler as appropriate. Idempotent. - */ - private updateOnlineState(newState: OnlineState): void { - if (newState !== this.watchStreamOnlineState) { - if (newState === OnlineState.Healthy) { - // We've connected to watch at least once. Don't warn the developer about - // being offline going forward. - this.shouldWarnOffline = false; - } else if (newState === OnlineState.Unknown) { - // The state is set to unknown when a healthy stream is closed (e.g. due to - // a token timeout) or when we have no active listens and therefore there's - // no need to start the stream. Assuming there is (possibly in the future) - // an active listen, then we will eventually move to state Online or Failed, - // but we always want to make at least ONLINE_ATTEMPTS_BEFORE_FAILURE - // attempts before failing, so we reset the count here. - this.watchStreamFailures = 0; - } - this.watchStreamOnlineState = newState; - this.onlineStateHandler(newState); - } - } - - /** - * Updates our OnlineState as appropriate after the watch stream reports a - * failure. The first failure moves us to the 'Unknown' state. We then may - * allow multiple failures (based on ONLINE_ATTEMPTS_BEFORE_FAILURE) before we - * actually transition to OnlineState.Failed. - */ - private updateOnlineStateAfterFailure(): void { - if (this.watchStreamOnlineState === OnlineState.Healthy) { - this.updateOnlineState(OnlineState.Unknown); - } else { - this.watchStreamFailures++; - if (this.watchStreamFailures >= ONLINE_ATTEMPTS_BEFORE_FAILURE) { - if (this.shouldWarnOffline) { - log.error('Could not reach Firestore backend.'); - this.shouldWarnOffline = false; - } - this.updateOnlineState(OnlineState.Failed); - } - } - } - private isNetworkEnabled(): boolean { assert( (this.watchStream == null) === (this.writeStream == null), @@ -220,10 +166,10 @@ export class RemoteStore { if (this.shouldStartWatchStream()) { this.startWatchStream(); + } else { + this.onlineStateTracker.set(OnlineState.Unknown); } - this.updateOnlineState(OnlineState.Unknown); - return this.fillWritePipeline(); // This may start the writeStream. }); } @@ -234,8 +180,8 @@ export class RemoteStore { */ async disableNetwork(): Promise { this.disableNetworkInternal(); - // Set the OnlineState to failed so get()'s return from cache, etc. - this.updateOnlineState(OnlineState.Failed); + // Set the OnlineState to Offline so get()s return from cache, etc. + this.onlineStateTracker.set(OnlineState.Offline); } /** @@ -259,9 +205,9 @@ export class RemoteStore { shutdown(): Promise { log.debug(LOG_TAG, 'RemoteStore shutting down.'); this.disableNetworkInternal(); - // Set the OnlineState to Unknown (rather than Failed) to avoid potentially + // Set the OnlineState to Unknown (rather than Offline) to avoid potentially // triggering spurious listener events with cached data, etc. - this.updateOnlineState(OnlineState.Unknown); + this.onlineStateTracker.set(OnlineState.Unknown); return Promise.resolve(); } @@ -336,11 +282,13 @@ export class RemoteStore { onClose: this.onWatchStreamClose.bind(this), onWatchChange: this.onWatchStreamChange.bind(this) }); + + this.onlineStateTracker.handleWatchStreamStart(); } /** - * Returns whether the watch stream should be started because there are - * active targets trying to be listened too + * Returns whether the watch stream should be started because it's necessary + * and has not yet been started. */ private shouldStartWatchStream(): boolean { return ( @@ -376,16 +324,16 @@ export class RemoteStore { ); this.cleanUpWatchStreamState(); + this.onlineStateTracker.handleWatchStreamFailure(); // If there was an error, retry the connection. if (this.shouldStartWatchStream()) { - this.updateOnlineStateAfterFailure(); this.startWatchStream(); } else { // No need to restart watch stream because there are no active targets. // The online state is set to unknown because there is no active attempt // at establishing a connection - this.updateOnlineState(OnlineState.Unknown); + this.onlineStateTracker.set(OnlineState.Unknown); } } @@ -393,8 +341,8 @@ export class RemoteStore { watchChange: WatchChange, snapshotVersion: SnapshotVersion ): Promise { - // Mark the connection as healthy because we got a message from the server - this.updateOnlineState(OnlineState.Healthy); + // Mark the client as online since we got a message from the server + this.onlineStateTracker.set(OnlineState.Online); if ( watchChange instanceof WatchTargetChange && @@ -804,7 +752,7 @@ export class RemoteStore { // for the new user and re-fill the write pipeline with new mutations from the LocalStore // (since mutations are per-user). this.disableNetworkInternal(); - this.updateOnlineState(OnlineState.Unknown); + this.onlineStateTracker.set(OnlineState.Unknown); return this.enableNetwork(); } } diff --git a/packages/firestore/src/util/async_queue.ts b/packages/firestore/src/util/async_queue.ts index 453e720c373..29440d72a50 100644 --- a/packages/firestore/src/util/async_queue.ts +++ b/packages/firestore/src/util/async_queue.ts @@ -27,12 +27,30 @@ type TimerHandle = any; * Wellknown "timer" IDs used when scheduling delayed operations on the * AsyncQueue. These IDs can then be used from tests to check for the presence * of operations or to run them early. + * + * The string values are used when encoding these timer IDs in JSON spec tests. */ export enum TimerId { - ListenStreamIdle, - ListenStreamConnection, - WriteStreamIdle, - WriteStreamConnection + /** All can be used with runDelayedOperationsEarly() to run all timers. */ + All = 'all', + + /** + * The following 4 timers are used in persistent_stream.ts for the listen and + * write streams. The "Idle" timer is used to close the stream due to + * inactivity. The "ConnectionBackoff" timer is used to restart a stream once + * the appropriate backoff delay has elapsed. + */ + ListenStreamIdle = 'listen_stream_idle', + ListenStreamConnectionBackoff = 'listen_stream_connection_backoff', + WriteStreamIdle = 'write_stream_idle', + WriteStreamConnectionBackoff = 'write_stream_connection_backoff', + + /** + * A timer used in online_state_tracker.ts to transition from + * OnlineState.Unknown to Offline after a set timeout, rather than waiting + * indefinitely for success or failure. + */ + OnlineStateTimeout = 'online_state_timeout' } /** @@ -55,7 +73,12 @@ class DelayedOperation implements CancelablePromise { readonly targetTimeMs: number, private readonly op: () => Promise, private readonly removalCallback: (op: DelayedOperation) => void - ) {} + ) { + // It's normal for the deferred promise to be canceled (due to cancellation) + // and so we attach a dummy catch callback to avoid + // 'UnhandledPromiseRejectionWarning' log spam. + this.deferred.promise.catch(err => {}); + } /** * Creates and returns a DelayedOperation that has been scheduled to be @@ -221,9 +244,7 @@ export class AsyncQueue { // ops with the same timer id in the queue, so defensively reject them. assert( !this.containsDelayedOperation(timerId), - `Attempted to schedule multiple operations with timer id ${ - TimerId[timerId] - }.` + `Attempted to schedule multiple operations with timer id ${timerId}.` ); const delayedOp = DelayedOperation.createAndSchedule( @@ -279,16 +300,17 @@ export class AsyncQueue { /** * For Tests: Runs some or all delayed operations early. * - * @param lastTimerId If specified, only delayed operations up to and - * including this TimerId will be drained. Throws if no such operation - * exists. + * @param lastTimerId Delayed operations up to and including this TimerId will + * be drained. Throws if no such operation exists. Pass TimerId.All to run + * all delayed operations. * @returns a Promise that resolves once all operations have been run. */ - runDelayedOperationsEarly(lastTimerId?: TimerId): Promise { + runDelayedOperationsEarly(lastTimerId: TimerId): Promise { // Note that draining may generate more delayed ops, so we do that first. return this.drain().then(() => { assert( - lastTimerId === undefined || this.containsDelayedOperation(lastTimerId), + lastTimerId === TimerId.All || + this.containsDelayedOperation(lastTimerId), `Attempted to drain to missing operation ${lastTimerId}` ); @@ -297,7 +319,7 @@ export class AsyncQueue { for (const op of this.delayedOperations) { op.skipDelay(); - if (lastTimerId !== undefined && op.timerId === lastTimerId) { + if (lastTimerId !== TimerId.All && op.timerId === lastTimerId) { break; } } diff --git a/packages/firestore/test/integration/remote/stream.test.ts b/packages/firestore/test/integration/remote/stream.test.ts index 0b778e223b5..8faabc26763 100644 --- a/packages/firestore/test/integration/remote/stream.test.ts +++ b/packages/firestore/test/integration/remote/stream.test.ts @@ -259,7 +259,7 @@ describe('Write Stream', () => { writeStream.writeMutations(SINGLE_MUTATION); return streamListener.awaitCallback('mutationResult'); }) - .then(() => queue.runDelayedOperationsEarly()) + .then(() => queue.runDelayedOperationsEarly(TimerId.All)) .then(() => { expect(writeStream.isOpen()).to.be.true; }); diff --git a/packages/firestore/test/unit/core/event_manager.test.ts b/packages/firestore/test/unit/core/event_manager.test.ts index 1e41dd1e778..34d69418d9d 100644 --- a/packages/firestore/test/unit/core/event_manager.test.ts +++ b/packages/firestore/test/unit/core/event_manager.test.ts @@ -139,8 +139,8 @@ describe('EventManager', () => { eventManager.listen(fakeListener1); expect(events).to.deep.equal([OnlineState.Unknown]); - eventManager.applyOnlineStateChange(OnlineState.Healthy); - expect(events).to.deep.equal([OnlineState.Unknown, OnlineState.Healthy]); + eventManager.applyOnlineStateChange(OnlineState.Online); + expect(events).to.deep.equal([OnlineState.Unknown, OnlineState.Online]); }); }); @@ -423,10 +423,10 @@ describe('QueryListener', () => { const changes3 = view.computeDocChanges(documentUpdates()); const snap3 = view.applyChanges(changes3, ackTarget(doc1, doc2)).snapshot!; - listener.applyOnlineStateChange(OnlineState.Healthy); // no event + listener.applyOnlineStateChange(OnlineState.Online); // no event listener.onViewSnapshot(snap1); // no event listener.applyOnlineStateChange(OnlineState.Unknown); // no event - listener.applyOnlineStateChange(OnlineState.Healthy); // no event + listener.applyOnlineStateChange(OnlineState.Online); // no event listener.onViewSnapshot(snap2); // no event listener.onViewSnapshot(snap3); // event because synced @@ -461,11 +461,11 @@ describe('QueryListener', () => { const changes2 = view.computeDocChanges(documentUpdates(doc2)); const snap2 = view.applyChanges(changes2).snapshot!; - listener.applyOnlineStateChange(OnlineState.Healthy); // no event + listener.applyOnlineStateChange(OnlineState.Online); // no event listener.onViewSnapshot(snap1); // no event - listener.applyOnlineStateChange(OnlineState.Failed); // event - listener.applyOnlineStateChange(OnlineState.Healthy); // no event - listener.applyOnlineStateChange(OnlineState.Failed); // no event + listener.applyOnlineStateChange(OnlineState.Offline); // event + listener.applyOnlineStateChange(OnlineState.Online); // no event + listener.applyOnlineStateChange(OnlineState.Offline); // no event listener.onViewSnapshot(snap2); // another event const expectedSnap1 = { @@ -499,9 +499,9 @@ describe('QueryListener', () => { const changes1 = view.computeDocChanges(documentUpdates()); const snap1 = view.applyChanges(changes1).snapshot!; - listener.applyOnlineStateChange(OnlineState.Healthy); // no event + listener.applyOnlineStateChange(OnlineState.Online); // no event listener.onViewSnapshot(snap1); // no event - listener.applyOnlineStateChange(OnlineState.Failed); // event + listener.applyOnlineStateChange(OnlineState.Offline); // event const expectedSnap = { query, @@ -525,7 +525,7 @@ describe('QueryListener', () => { const changes1 = view.computeDocChanges(documentUpdates()); const snap1 = view.applyChanges(changes1).snapshot!; - listener.applyOnlineStateChange(OnlineState.Failed); + listener.applyOnlineStateChange(OnlineState.Offline); listener.onViewSnapshot(snap1); const expectedSnap = { diff --git a/packages/firestore/test/unit/specs/offline_spec.test.ts b/packages/firestore/test/unit/specs/offline_spec.test.ts index d832400e034..af23a2ba614 100644 --- a/packages/firestore/test/unit/specs/offline_spec.test.ts +++ b/packages/firestore/test/unit/specs/offline_spec.test.ts @@ -21,6 +21,7 @@ import { doc, path } from '../../util/helpers'; import { describeSpec, specTest } from './describe_spec'; import { spec } from './spec_builder'; +import { TimerId } from '../../../src/util/async_queue'; describeSpec('Offline:', [], () => { specTest('Empty queries are resolved if client goes offline', [], () => { @@ -146,4 +147,38 @@ describeSpec('Offline:', [], () => { .expectLimboDocs() ); }); + + specTest('OnlineState timeout triggers offline behavior', [], () => { + const query = Query.atPath(path('collection')); + const docA = doc('collection/a', 1000, { key: 'a' }); + return ( + spec() + .userListens(query) + + // OnlineState timer should trigger offline behavior (fromCache=true). + .runTimer(TimerId.OnlineStateTimeout) + .expectEvents(query, { + fromCache: true + }) + + // We should get no further events for failed connection attempts. + .watchStreamCloses(Code.UNAVAILABLE) + .watchStreamCloses(Code.UNAVAILABLE) + + // We should get events after a successful connection. + .watchAcksFull(query, 1000, docA) + .expectEvents(query, { added: [docA], fromCache: false }) + + // Running timers should have no effect now. + .runTimer(TimerId.All) + + // After a disconnect, the timer should become active again. + .watchStreamCloses(Code.UNAVAILABLE) + .restoreListen(query, 'resume-token-1000') + .runTimer(TimerId.OnlineStateTimeout) + .expectEvents(query, { + fromCache: true + }) + ); + }); }); diff --git a/packages/firestore/test/unit/specs/spec_builder.ts b/packages/firestore/test/unit/specs/spec_builder.ts index c59434b0f4e..b13afa61a33 100644 --- a/packages/firestore/test/unit/specs/spec_builder.ts +++ b/packages/firestore/test/unit/specs/spec_builder.ts @@ -41,6 +41,7 @@ import { SpecStep, SpecWatchFilter } from './spec_test_runner'; +import { TimerId } from '../../../src/util/async_queue'; /** * Provides a high-level language to construct spec tests that can be exported @@ -194,6 +195,12 @@ export class SpecBuilder { return this; } + runTimer(timerId: TimerId) { + this.nextStep(); + this.currentStep = { runTimer: timerId }; + return this; + } + changeUser(uid: string | null): SpecBuilder { this.nextStep(); this.currentStep = { changeUser: uid }; diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index 2c202b0c772..b5e5c9f54ec 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -384,6 +384,7 @@ abstract class TestRunner { this.remoteStore = new RemoteStore( this.localStore, this.datastore, + this.queue, onlineStateChangedHandler ); @@ -463,6 +464,8 @@ abstract class TestRunner { return this.doWriteAck(step.writeAck!); } else if ('failWrite' in step) { return this.doFailWrite(step.failWrite!); + } else if ('runTimer' in step) { + return this.doRunTimer(step.runTimer!); } else if ('enableNetwork' in step) { return step.enableNetwork! ? this.doEnableNetwork() @@ -699,7 +702,7 @@ abstract class TestRunner { // The watch stream should re-open if we have active listeners. if (!this.queryListeners.isEmpty()) { await this.queue.runDelayedOperationsEarly( - TimerId.ListenStreamConnection + TimerId.ListenStreamConnectionBackoff ); await this.connection.waitForWatchOpen(); } @@ -759,6 +762,14 @@ abstract class TestRunner { }); } + private async doRunTimer(timer: string): Promise { + // We assume the timer string is a valid TimerID enum value, but if it's + // not, then there won't be a matching item on the queue and + // runDelayedOperationsEarly() will throw. + const timerId = timer as TimerId; + await this.queue.runDelayedOperationsEarly(timerId); + } + private async doDisableNetwork(): Promise { // Make sure to execute all writes that are currently queued. This allows us // to assert on the total number of requests sent before shutdown. @@ -888,11 +899,9 @@ abstract class TestRunner { ) ); expect(actualTarget.query).to.deep.equal(expectedTarget.query); - expect(actualTarget.targetId).to.deep.equal(expectedTarget.targetId); - expect(actualTarget.readTime).to.deep.equal(expectedTarget.readTime); - expect(actualTarget.resumeToken).to.deep.equal( - expectedTarget.resumeToken - ); + expect(actualTarget.targetId).to.equal(expectedTarget.targetId); + expect(actualTarget.readTime).to.equal(expectedTarget.readTime); + expect(actualTarget.resumeToken).to.equal(expectedTarget.resumeToken); delete actualTargets[targetId]; }); expect(obj.size(actualTargets)).to.equal( @@ -1089,6 +1098,12 @@ export interface SpecStep { /** Fail a write */ failWrite?: SpecWriteFailure; + /** + * Run a queued timer task (without waiting for the delay to expire). See + * TimerId enum definition for possible values). + */ + runTimer?: string; + /** Enable or disable RemoteStore's network connection. */ enableNetwork?: boolean; diff --git a/packages/firestore/test/unit/util/async_queue.test.ts b/packages/firestore/test/unit/util/async_queue.test.ts index f1c49f66251..c089a56917c 100644 --- a/packages/firestore/test/unit/util/async_queue.test.ts +++ b/packages/firestore/test/unit/util/async_queue.test.ts @@ -23,9 +23,9 @@ import { Code } from '../../../src/util/error'; describe('AsyncQueue', () => { // We reuse these TimerIds for generic testing. - const timerId1 = TimerId.ListenStreamConnection; + const timerId1 = TimerId.ListenStreamConnectionBackoff; const timerId2 = TimerId.ListenStreamIdle; - const timerId3 = TimerId.WriteStreamConnection; + const timerId3 = TimerId.WriteStreamConnectionBackoff; it('schedules ops in right order', () => { const queue = new AsyncQueue(); @@ -161,7 +161,7 @@ describe('AsyncQueue', () => { err => expect(err.code === Code.CANCELLED) ); - await queue.runDelayedOperationsEarly(); + await queue.runDelayedOperationsEarly(TimerId.All); expect(completedSteps).to.deep.equal([1]); }); @@ -174,7 +174,7 @@ describe('AsyncQueue', () => { queue.enqueueAfterDelay(timerId2, 10000, () => doStep(3)); queue.enqueue(() => doStep(2)); - await queue.runDelayedOperationsEarly(); + await queue.runDelayedOperationsEarly(TimerId.All); expect(completedSteps).to.deep.equal([1, 2, 3, 4]); }); From a0583f76d975c8183c0a1f46468688d8ffc1f060 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Mon, 5 Mar 2018 10:45:15 -0800 Subject: [PATCH 19/34] Shim refactor (#550) * Refactor to organize shims by Object * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: License Headers --- packages/polyfill/index.ts | 4 +- .../src/shims/{findIndex.ts => Array.ts} | 49 ++++++++++++++ packages/polyfill/src/shims/String.ts | 25 ++++++++ packages/polyfill/src/shims/find.ts | 64 ------------------- 4 files changed, 76 insertions(+), 66 deletions(-) rename packages/polyfill/src/shims/{findIndex.ts => Array.ts} (58%) create mode 100644 packages/polyfill/src/shims/String.ts delete mode 100644 packages/polyfill/src/shims/find.ts diff --git a/packages/polyfill/index.ts b/packages/polyfill/index.ts index 21b16b16ee6..f3714ae33fa 100644 --- a/packages/polyfill/index.ts +++ b/packages/polyfill/index.ts @@ -15,5 +15,5 @@ */ import './src/polyfills/promise'; -import './src/shims/find'; -import './src/shims/findIndex'; +import './src/shims/Array'; +import './src/shims/String'; diff --git a/packages/polyfill/src/shims/findIndex.ts b/packages/polyfill/src/shims/Array.ts similarity index 58% rename from packages/polyfill/src/shims/findIndex.ts rename to packages/polyfill/src/shims/Array.ts index 325c7f0d59d..798a4f3a343 100644 --- a/packages/polyfill/src/shims/findIndex.ts +++ b/packages/polyfill/src/shims/Array.ts @@ -14,6 +14,55 @@ * limitations under the License. */ +/** + * This is the Array.prototype.find polyfill from MDN + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find + * https://tc39.github.io/ecma262/#sec-array.prototype.find + */ +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function(predicate) { + // 1. Let O be ? ToObject(this value). + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this); + + // 2. Let len be ? ToLength(? Get(O, "length")). + var len = o.length >>> 0; + + // 3. If IsCallable(predicate) is false, throw a TypeError exception. + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + + // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. + var thisArg = arguments[1]; + + // 5. Let k be 0. + var k = 0; + + // 6. Repeat, while k < len + while (k < len) { + // a. Let Pk be ! ToString(k). + // b. Let kValue be ? Get(O, Pk). + // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). + // d. If testResult is true, return kValue. + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return kValue; + } + // e. Increase k by 1. + k++; + } + + // 7. Return undefined. + return undefined; + } + }); +} + /** * This is the Array.prototype.findIndex polyfill from MDN * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex diff --git a/packages/polyfill/src/shims/String.ts b/packages/polyfill/src/shims/String.ts new file mode 100644 index 00000000000..c8c006f7c15 --- /dev/null +++ b/packages/polyfill/src/shims/String.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This is the String.prototype.startsWith polyfill from MDN + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith + */ +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + }; +} diff --git a/packages/polyfill/src/shims/find.ts b/packages/polyfill/src/shims/find.ts deleted file mode 100644 index 587e23ddb67..00000000000 --- a/packages/polyfill/src/shims/find.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2017 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This is the Array.prototype.find polyfill from MDN - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find - * https://tc39.github.io/ecma262/#sec-array.prototype.find - */ -if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - value: function(predicate) { - // 1. Let O be ? ToObject(this value). - if (this == null) { - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this); - - // 2. Let len be ? ToLength(? Get(O, "length")). - var len = o.length >>> 0; - - // 3. If IsCallable(predicate) is false, throw a TypeError exception. - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - - // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. - var thisArg = arguments[1]; - - // 5. Let k be 0. - var k = 0; - - // 6. Repeat, while k < len - while (k < len) { - // a. Let Pk be ! ToString(k). - // b. Let kValue be ? Get(O, Pk). - // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). - // d. If testResult is true, return kValue. - var kValue = o[k]; - if (predicate.call(thisArg, kValue, k, o)) { - return kValue; - } - // e. Increase k by 1. - k++; - } - - // 7. Return undefined. - return undefined; - } - }); -} From 2b20a14bdce1004a7f6f0fd0dac134bb13ef7837 Mon Sep 17 00:00:00 2001 From: Zev Goldstein Date: Tue, 6 Mar 2018 11:59:02 -0500 Subject: [PATCH 20/34] removes unecessary lcov-result-merger dependency (#547) --- packages/messaging/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 415c7447ecc..1796360a4c1 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -18,7 +18,6 @@ "dependencies": { "@firebase/messaging-types": "0.1.2", "@firebase/util": "0.1.10", - "lcov-result-merger": "^2.0.0", "tslib": "^1.9.0" }, "devDependencies": { From 03d224f08b7267a4ceb57ec12ed62fb215a62d83 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Tue, 6 Mar 2018 12:19:32 -0800 Subject: [PATCH 21/34] Release Fixes (#551) * Fix some issues w/ the release process. This commit addresses two issues: - The banner text not correctly displaying on macOS due to the changed emoji spacing - The release CLI throwing errors when trying to stage an unpublished package * [AUTOMATED]: Prettier Code Styling * Refactor to handle production initial releases * [AUTOMATED]: Prettier Code Styling --- scripts/release/utils/banner.js | 3 -- scripts/release/utils/inquirer.js | 47 +++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/scripts/release/utils/banner.js b/scripts/release/utils/banner.js index 4b77a7543e9..93684fd4b68 100644 --- a/scripts/release/utils/banner.js +++ b/scripts/release/utils/banner.js @@ -21,8 +21,5 @@ const readFile = promisify(_readFile); exports.bannerText = async () => { let BANNER_TEXT = await readFile(resolve(__dirname, 'banner.txt'), 'utf8'); - if (process.platform === 'darwin') { - BANNER_TEXT = BANNER_TEXT.replace(/#/g, '🔥'); - } console.log(BANNER_TEXT); }; diff --git a/scripts/release/utils/inquirer.js b/scripts/release/utils/inquirer.js index 5094d659f2a..7efa46a2216 100644 --- a/scripts/release/utils/inquirer.js +++ b/scripts/release/utils/inquirer.js @@ -33,6 +33,16 @@ exports.packageVersionUpdate = async (package, releaseType) => { /** * Check and see if we are trying to publish a prerelease */ + let isPublished = await (async isStaging => { + if (isStaging) { + let { stdout } = await exec(`npm info ${package}@next version`); + return !!stdout.trim(); + } else { + let { stdout } = await exec(`npm info ${package} version`); + return !stdout.includes('canary'); + } + })(releaseType === 'Staging'); + if (releaseType === 'Staging' && !private) { let { stdout: nextVersion } = await exec( `npm info ${package}@next version` @@ -42,12 +52,11 @@ exports.packageVersionUpdate = async (package, releaseType) => { * will break the `semver` module parsing */ nextVersion = nextVersion.trim(); - /** * If we are currently in a prerelease cycle, fast-forward the version * to the prereleased version instead of the current version */ - if (gt(nextVersion, version)) { + if (isPublished && gt(nextVersion, version)) { version = nextVersion; } } @@ -69,6 +78,32 @@ exports.packageVersionUpdate = async (package, releaseType) => { ? prereleaseVersions : ['patch', 'minor', 'major']; + let choices; + + if (isPublished) { + /** + * Will hit this codepath if we are publishing a module that has already been + * published once + */ + choices = increments.map(increment => { + const newVersion = inc(version, increment); + return { + name: chalk`${capitalize(increment)} {gray ${newVersion}}`, + value: newVersion + }; + }); + } else { + /** + * Will hit this codepath if this is the first prerelease of the component + */ + choices = [ + { + name: chalk`Initial Release {gray ${version}}`, + value: version + } + ]; + } + /** * Create prompts */ @@ -76,13 +111,7 @@ exports.packageVersionUpdate = async (package, releaseType) => { type: 'list', name: `${package}`, message: `Select semver increment for ${package}`, - choices: increments.map(increment => { - const newVersion = inc(version, increment); - return { - name: chalk`${capitalize(increment)} {gray ${newVersion}}`, - value: newVersion - }; - }) + choices }; }; From 121c1674a998e03e44b8509da27fd1710d5898a1 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Tue, 6 Mar 2018 14:56:46 -0800 Subject: [PATCH 22/34] Fixes an issue with staged release version (#552) * Refactor so staging releases use a staging version * [AUTOMATED]: Prettier Code Styling --- scripts/release/utils/inquirer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/release/utils/inquirer.js b/scripts/release/utils/inquirer.js index 7efa46a2216..9fce4c959b3 100644 --- a/scripts/release/utils/inquirer.js +++ b/scripts/release/utils/inquirer.js @@ -93,6 +93,7 @@ exports.packageVersionUpdate = async (package, releaseType) => { }; }); } else { + version = releaseType === 'Staging' ? inc(version, 'pre') : version; /** * Will hit this codepath if this is the first prerelease of the component */ From 7681d0355f632f420e833e40dc2c627d07dd845a Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Wed, 7 Mar 2018 14:28:12 -0800 Subject: [PATCH 23/34] Remove "google-cloud-resource-prefix" header in favor of "database" url parameter in WebChannel requests. (#554) I verified that the client still works against prod and that the ?database=... paremeter was included in every WebChannel network request. NOTE that prior to this change we were including the "google-cloud-resource-prefix" header on non-streaming RPC requests, but with this change we will not include the header or use the "database" url parameter. --- .../src/platform_browser/webchannel_connection.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/firestore/src/platform_browser/webchannel_connection.ts b/packages/firestore/src/platform_browser/webchannel_connection.ts index 398cc2ac729..dc676c0ce42 100644 --- a/packages/firestore/src/platform_browser/webchannel_connection.ts +++ b/packages/firestore/src/platform_browser/webchannel_connection.ts @@ -80,11 +80,6 @@ export class WebChannelConnection implements Connection { } } headers['X-Goog-Api-Client'] = X_GOOG_API_CLIENT_VALUE; - // This header is used to improve routing and project isolation by the - // backend. - headers['google-cloud-resource-prefix'] = - `projects/${this.databaseId.projectId}/` + - `databases/${this.databaseId.database}`; } invokeRPC( @@ -207,6 +202,13 @@ export class WebChannelConnection implements Connection { // preflight round-trip. This is formally defined here: // https://github.com/google/closure-library/blob/b0e1815b13fb92a46d7c9b3c30de5d6a396a3245/closure/goog/net/rpc/httpcors.js#L40 httpHeadersOverwriteParam: '$httpHeaders', + messageUrlParams: { + // This param is used to improve routing and project isolation by the + // backend and must be included in every request. + database: `projects/${this.databaseId.projectId}/databases/${ + this.databaseId.database + }` + }, sendRawJson: true, supportsCrossDomainXhr: true }; From 98ab8e5d76fd1b37205bca175fba79bbbb4c34e1 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Thu, 8 Mar 2018 14:41:44 -0800 Subject: [PATCH 24/34] Publish firebase@4.11.0 --- integration/browserify/package.json | 2 +- integration/firebase-typings/package.json | 2 +- integration/messaging/package.json | 2 +- integration/typescript/package.json | 2 +- integration/webpack/package.json | 2 +- packages/database-types/package.json | 2 +- packages/database/package.json | 6 +++--- packages/firebase/package.json | 10 +++++----- packages/firestore/package.json | 2 +- packages/messaging/package.json | 2 +- packages/polyfill/package.json | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/integration/browserify/package.json b/integration/browserify/package.json index 7513bab3a4e..f0bae00439c 100644 --- a/integration/browserify/package.json +++ b/integration/browserify/package.json @@ -7,7 +7,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.10.1" + "firebase": "4.11.0" }, "devDependencies": { "browserify": "^16.1.0", diff --git a/integration/firebase-typings/package.json b/integration/firebase-typings/package.json index 4125929c44b..9ec96a60940 100644 --- a/integration/firebase-typings/package.json +++ b/integration/firebase-typings/package.json @@ -6,7 +6,7 @@ "test": "tsc index.ts --outDir dist" }, "dependencies": { - "firebase": "4.10.1" + "firebase": "4.11.0" }, "devDependencies": { "typescript": "^2.7.2" diff --git a/integration/messaging/package.json b/integration/messaging/package.json index 443a4ba5771..a0b74e0e028 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -8,7 +8,7 @@ "test:manual": "mocha --exit" }, "dependencies": { - "firebase": "4.10.1" + "firebase": "4.11.0" }, "devDependencies": { "chai": "^4.1.1", diff --git a/integration/typescript/package.json b/integration/typescript/package.json index 27739a960b4..25eb9345c5f 100644 --- a/integration/typescript/package.json +++ b/integration/typescript/package.json @@ -6,7 +6,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.10.1" + "firebase": "4.11.0" }, "devDependencies": { "@types/chai": "^4.1.2", diff --git a/integration/webpack/package.json b/integration/webpack/package.json index 896015613ca..d3fd988ebe8 100644 --- a/integration/webpack/package.json +++ b/integration/webpack/package.json @@ -7,7 +7,7 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.10.1" + "firebase": "4.11.0" }, "devDependencies": { "chai": "^4.1.1", diff --git a/packages/database-types/package.json b/packages/database-types/package.json index 0c2d9cbff64..328cab49394 100644 --- a/packages/database-types/package.json +++ b/packages/database-types/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/database-types", - "version": "0.1.2", + "version": "0.2.0", "description": "@firebase/database Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", diff --git a/packages/database/package.json b/packages/database/package.json index 73a9d081f2a..f7b8e41f419 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/database", - "version": "0.1.11", + "version": "0.2.0", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", @@ -19,8 +19,8 @@ "@firebase/app-types": "^0.1.0" }, "dependencies": { - "@firebase/database-types": "0.1.2", - "@firebase/logger": "0.1.0", + "@firebase/database-types": "0.2.0", + "@firebase/logger": "0.1.0", "@firebase/util": "0.1.10", "faye-websocket": "0.11.1", "tslib": "^1.9.0" diff --git a/packages/firebase/package.json b/packages/firebase/package.json index cfd08f18b69..da296300ce6 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "firebase", - "version": "4.10.1", + "version": "4.11.0", "description": "Firebase JavaScript library for web and Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -29,10 +29,10 @@ "dependencies": { "@firebase/app": "0.1.10", "@firebase/auth": "0.3.4", - "@firebase/database": "0.1.11", - "@firebase/firestore": "0.3.4", - "@firebase/messaging": "0.2.1", - "@firebase/polyfill": "0.1.6", + "@firebase/database": "0.2.0", + "@firebase/firestore": "0.3.5", + "@firebase/messaging": "0.2.2", + "@firebase/polyfill": "0.2.0", "@firebase/storage": "0.1.8", "dom-storage": "^2.0.2", "xmlhttprequest": "^1.8.0" diff --git a/packages/firestore/package.json b/packages/firestore/package.json index bd291401261..2f74a41096e 100644 --- a/packages/firestore/package.json +++ b/packages/firestore/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/firestore", - "version": "0.3.4", + "version": "0.3.5", "description": "", "author": "Firebase (https://firebase.google.com/)", "scripts": { diff --git a/packages/messaging/package.json b/packages/messaging/package.json index 1796360a4c1..5d1ee6e912d 100644 --- a/packages/messaging/package.json +++ b/packages/messaging/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/messaging", - "version": "0.2.1", + "version": "0.2.2", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", diff --git a/packages/polyfill/package.json b/packages/polyfill/package.json index 1cdc4aa93ff..5658a01093c 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/polyfill", - "version": "0.1.6", + "version": "0.2.0", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", From 6aed77a501ae66f42ea61323cc67b1f1c8ff6954 Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Thu, 8 Mar 2018 14:46:53 -0800 Subject: [PATCH 25/34] Update yarn.lock --- yarn.lock | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/yarn.lock b/yarn.lock index 9bdd54e04b4..eab6683407b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,6 +8,19 @@ dependencies: acorn "^5.2.1" +"@firebase/database-types@0.1.2": + version "0.1.2" + resolved "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.1.2.tgz#c6a23b8aa721ca16951c752430167ee764659916" + +"@firebase/database@^0.1.3": + version "0.1.11" + resolved "https://registry.npmjs.org/@firebase/database/-/database-0.1.11.tgz#652731bfd844bb858ab616e3dc8a3d5b8181101c" + dependencies: + "@firebase/database-types" "0.1.2" + "@firebase/util" "0.1.10" + faye-websocket "0.11.1" + tslib "^1.9.0" + "@google-cloud/common-grpc@^0.5.3": version "0.5.5" resolved "https://registry.npmjs.org/@google-cloud/common-grpc/-/common-grpc-0.5.5.tgz#ca805d7bbbcf47bbd82cf603e0386e963d6f5804" From 69c9a971fa4e48bf965369744559e4c9a2fab12b Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Thu, 8 Mar 2018 15:00:44 -0800 Subject: [PATCH 26/34] Fix issues that arose in latest release flow --- scripts/release/utils/git.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/release/utils/git.js b/scripts/release/utils/git.js index 94371f2ea26..99e2ca5aec0 100644 --- a/scripts/release/utils/git.js +++ b/scripts/release/utils/git.js @@ -37,7 +37,7 @@ exports.cleanTree = async () => { * Returns the tagged commits */ exports.commitAndTag = async updatedVersions => { - await exec('git add */package.json'); + await exec('git add */package.json yarn.lock'); let result = await exec( `git commit -m "Publish firebase@${updatedVersions.firebase}"` @@ -63,7 +63,7 @@ exports.pushUpdatesToGithub = async tags => { currentBranch = currentBranch.trim(); await exec(`git push origin ${currentBranch} --no-verify -u`, { cwd: root }); - await exec(`git push origin ${tags.join(' ')}`); + await exec(`git push origin ${tags.join(' ')} --no-verify`, { cwd: root }); }; exports.resetWorkingTree = async () => { From 786082d542a5d80611c110e9c9ff3592d129cd3b Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Mon, 12 Mar 2018 11:30:13 -0700 Subject: [PATCH 27/34] Fix MutationQueue issue resulting in re-sending acknowledged writes. (#559) getNextMutationBatchAfterBatchId() was not respecting highestAcknowledgedBatchId and therefore we were resending writes if they had been acknowledged but not removed (aka the held write acks case). This showed up when a user disabled / enabled the network as reported here and I've included a spec test to emulate that case: firebase/firebase-ios-sdk#772 --- packages/firestore/CHANGELOG.md | 3 ++ .../src/local/indexeddb_mutation_queue.ts | 12 +++-- .../src/local/memory_mutation_queue.ts | 4 +- .../test/unit/local/mutation_queue.test.ts | 21 ++++++++ .../test/unit/specs/spec_test_runner.ts | 6 +-- .../test/unit/specs/write_spec.test.ts | 53 +++++++++++++++++++ 6 files changed, 91 insertions(+), 8 deletions(-) diff --git a/packages/firestore/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 354a8050718..4d602c741b2 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -3,6 +3,9 @@ neither succeeds nor fails within 10 seconds, the SDK will consider itself "offline", causing get() calls to resolve with cached results, rather than continuing to wait. +- [fixed] Fixed a potential race condition after calling `enableNetwork()` that + could result in a "Mutation batchIDs must be acknowledged in order" assertion + crash. # 0.3.2 - [fixed] Fixed a regression in Firebase JS release 4.9.0 that could in certain diff --git a/packages/firestore/src/local/indexeddb_mutation_queue.ts b/packages/firestore/src/local/indexeddb_mutation_queue.ts index 3df5652ad83..548c73561ca 100644 --- a/packages/firestore/src/local/indexeddb_mutation_queue.ts +++ b/packages/firestore/src/local/indexeddb_mutation_queue.ts @@ -255,14 +255,20 @@ export class IndexedDbMutationQueue implements MutationQueue { transaction: PersistenceTransaction, batchId: BatchId ): PersistencePromise { - const range = IDBKeyRange.lowerBound(this.keyForBatchId(batchId + 1)); + // All batches with batchId <= this.metadata.lastAcknowledgedBatchId have + // been acknowledged so the first unacknowledged batch after batchID will + // have a batchID larger than both of these values. + const nextBatchId = + Math.max(batchId, this.metadata.lastAcknowledgedBatchId) + 1; + + const range = IDBKeyRange.lowerBound(this.keyForBatchId(nextBatchId)); let foundBatch: MutationBatch | null = null; return mutationsStore(transaction) .iterate({ range }, (key, dbBatch, control) => { if (dbBatch.userId === this.userId) { assert( - dbBatch.batchId > batchId, - 'Should have found mutation after ' + batchId + dbBatch.batchId >= nextBatchId, + 'Should have found mutation after ' + nextBatchId ); foundBatch = this.serializer.fromDbMutationBatch(dbBatch); } diff --git a/packages/firestore/src/local/memory_mutation_queue.ts b/packages/firestore/src/local/memory_mutation_queue.ts index c6aff8f3d83..9858d811480 100644 --- a/packages/firestore/src/local/memory_mutation_queue.ts +++ b/packages/firestore/src/local/memory_mutation_queue.ts @@ -182,11 +182,11 @@ export class MemoryMutationQueue implements MutationQueue { // All batches with batchId <= this.highestAcknowledgedBatchId have been // acknowledged so the first unacknowledged batch after batchID will have a // batchID larger than both of these values. - batchId = Math.max(batchId + 1, this.highestAcknowledgedBatchId); + const nextBatchId = Math.max(batchId, this.highestAcknowledgedBatchId) + 1; // The requested batchId may still be out of range so normalize it to the // start of the queue. - const rawIndex = this.indexOfBatchId(batchId); + const rawIndex = this.indexOfBatchId(nextBatchId); let index = rawIndex < 0 ? 0 : rawIndex; // Finally return the first non-tombstone batch. diff --git a/packages/firestore/test/unit/local/mutation_queue.test.ts b/packages/firestore/test/unit/local/mutation_queue.test.ts index 98efa331ac0..d57ebd9a5c7 100644 --- a/packages/firestore/test/unit/local/mutation_queue.test.ts +++ b/packages/firestore/test/unit/local/mutation_queue.test.ts @@ -40,6 +40,7 @@ import { import * as persistenceHelpers from './persistence_test_helpers'; import { TestMutationQueue } from './test_mutation_queue'; +import { addEqualityMatcher } from '../../util/equality_matcher'; let persistence: Persistence; let mutationQueue: TestMutationQueue; @@ -120,6 +121,8 @@ describe('IndexedDbMutationQueue', () => { * implementations. */ function genericMutationQueueTests() { + addEqualityMatcher(); + beforeEach(() => { mutationQueue = new TestMutationQueue( persistence, @@ -324,6 +327,24 @@ function genericMutationQueueTests() { expect(notFound).to.be.null; }); + it('getNextMutationBatchAfterBatchId() skips acknowledged batches', async () => { + const batches = await createBatches(3); + expect( + await mutationQueue.getNextMutationBatchAfterBatchId(BATCHID_UNKNOWN) + ).to.deep.equal(batches[0]); + + await mutationQueue.acknowledgeBatch(batches[0], emptyByteString()); + expect( + await mutationQueue.getNextMutationBatchAfterBatchId(BATCHID_UNKNOWN) + ).to.deep.equal(batches[1]); + expect( + await mutationQueue.getNextMutationBatchAfterBatchId(batches[0].batchId) + ).to.deep.equal(batches[1]); + expect( + await mutationQueue.getNextMutationBatchAfterBatchId(batches[1].batchId) + ).to.deep.equal(batches[2]); + }); + it('can getAllMutationBatchesThroughBatchId()', async () => { const batches = await createBatches(10); await makeHolesInBatches([2, 6, 7], batches); diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index b5e5c9f54ec..d1985b7db14 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -825,17 +825,17 @@ abstract class TestRunner { private validateStateExpectations(expectation: StateExpectation): void { if (expectation) { if ('numOutstandingWrites' in expectation) { - expect(this.remoteStore.outstandingWrites()).to.deep.equal( + expect(this.remoteStore.outstandingWrites()).to.equal( expectation.numOutstandingWrites ); } if ('writeStreamRequestCount' in expectation) { - expect(this.connection.writeStreamRequestCount).to.deep.equal( + expect(this.connection.writeStreamRequestCount).to.equal( expectation.writeStreamRequestCount ); } if ('watchStreamRequestCount' in expectation) { - expect(this.connection.watchStreamRequestCount).to.deep.equal( + expect(this.connection.watchStreamRequestCount).to.equal( expectation.watchStreamRequestCount ); } diff --git a/packages/firestore/test/unit/specs/write_spec.test.ts b/packages/firestore/test/unit/specs/write_spec.test.ts index b3df25f88c9..bfb22d9aae9 100644 --- a/packages/firestore/test/unit/specs/write_spec.test.ts +++ b/packages/firestore/test/unit/specs/write_spec.test.ts @@ -394,6 +394,59 @@ describeSpec('Writes:', [], () => { ); }); + specTest( + 'Held writes are not re-sent after disable/enable network.', + [], + () => { + const query = Query.atPath(path('collection')); + const docALocal = doc( + 'collection/a', + 0, + { v: 1 }, + { hasLocalMutations: true } + ); + const docA = doc('collection/a', 1000, { v: 1 }); + + return ( + spec() + .userListens(query) + .watchAcksFull(query, 500) + .expectEvents(query, {}) + .userSets('collection/a', { v: 1 }) + .expectEvents(query, { + hasPendingWrites: true, + added: [docALocal] + }) + // ack write but without a watch event. + .writeAcks(1000) + + // handshake + write = 2 requests + .expectWriteStreamRequestCount(2) + + .disableNetwork() + .expectEvents(query, { + hasPendingWrites: true, + fromCache: true + }) + + // handshake + write + close = 3 requests + .expectWriteStreamRequestCount(3) + + .enableNetwork() + .expectActiveTargets({ query, resumeToken: 'resume-token-500' }) + + // acked write should /not/ have been resent, so count should still be 3 + .expectWriteStreamRequestCount(3) + + // Finally watch catches up. + .watchAcksFull(query, 2000, docA) + .expectEvents(query, { + metadata: [docA] + }) + ); + } + ); + specTest( 'Held writes are released when there are no queries left.', [], From 0c5cbe038968fcedf55d123f47bf3db4a0b6dfde Mon Sep 17 00:00:00 2001 From: Abe Haskins Date: Wed, 14 Mar 2018 14:09:11 -0700 Subject: [PATCH 28/34] Fixes #562, Adds usePublicVapidKey to firebase/index.d.ts (#563) --- packages/firebase/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/firebase/index.d.ts b/packages/firebase/index.d.ts index 1076c273052..12318f100ad 100644 --- a/packages/firebase/index.d.ts +++ b/packages/firebase/index.d.ts @@ -474,6 +474,7 @@ declare namespace firebase.messaging { requestPermission(): Promise | null; setBackgroundMessageHandler(callback: (a: Object) => any): any; useServiceWorker(registration: any): any; + usePublicVapidKey(b64PublicKey: string): void; } } From bf7a221e905a2d50ef0773d7528b25aaedf8ff6a Mon Sep 17 00:00:00 2001 From: Josh Crowther Date: Wed, 14 Mar 2018 14:23:45 -0700 Subject: [PATCH 29/34] Set log level to VERBOSE if enableLogging(true) is passed (#561) --- packages/database/src/core/util/util.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/database/src/core/util/util.ts b/packages/database/src/core/util/util.ts index 72b25e04811..efb003161ee 100644 --- a/packages/database/src/core/util/util.ts +++ b/packages/database/src/core/util/util.ts @@ -27,7 +27,7 @@ import { stringToByteArray } from '@firebase/util'; import { stringify } from '@firebase/util'; import { SessionStorage } from '../storage/storage'; import { isNodeSdk } from '@firebase/util'; -import { Logger } from '@firebase/logger'; +import { Logger, LogLevel } from '@firebase/logger'; const logClient = new Logger('@firebase/database'); @@ -108,6 +108,7 @@ export const enableLogging = function( "Can't turn on custom loggers persistently." ); if (logger_ === true) { + logClient.logLevel = LogLevel.VERBOSE; logger = logClient.log.bind(logClient); if (persistent) SessionStorage.set('logging_enabled', true); } else if (typeof logger_ === 'function') { From b949d81363e664f7be651c6a4a94265470e042ce Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Wed, 14 Mar 2018 16:22:47 -0700 Subject: [PATCH 30/34] Fix for b/74749605: Cancel pending backoff operations when closing streams. (#564) --- packages/firestore/CHANGELOG.md | 6 ++++ packages/firestore/src/remote/backoff.ts | 12 +++++-- .../firestore/src/remote/persistent_stream.ts | 13 ++++++- .../test/unit/specs/remote_store_spec.test.ts | 34 ++++++++++++++++++- .../firestore/test/unit/specs/spec_builder.ts | 12 +++++-- .../test/unit/specs/spec_test_runner.ts | 3 +- 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/packages/firestore/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 4d602c741b2..13899391aa2 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -1,4 +1,10 @@ # Unreleased +- [fixed] Fixed a regression in the Firebase JS release 4.11.0 that could + cause a crash if a user signs out while the client is offline, resulting in + an error of "Attempted to schedule multiple operations with timer id + listen_stream_connection_backoff". + +# 0.3.5 - [changed] If the SDK's attempt to connect to the Cloud Firestore backend neither succeeds nor fails within 10 seconds, the SDK will consider itself "offline", causing get() calls to resolve with cached results, rather than diff --git a/packages/firestore/src/remote/backoff.ts b/packages/firestore/src/remote/backoff.ts index 38262358289..6a1ced7c794 100644 --- a/packages/firestore/src/remote/backoff.ts +++ b/packages/firestore/src/remote/backoff.ts @@ -87,9 +87,8 @@ export class ExponentialBackoff { * already, it will be canceled. */ backoffAndRun(op: () => Promise): void { - if (this.timerPromise !== null) { - this.timerPromise.cancel(); - } + // Cancel any pending backoff operation. + this.cancel(); // First schedule using the current base (which may be 0 and should be // honored as such). @@ -118,6 +117,13 @@ export class ExponentialBackoff { } } + cancel(): void { + if (this.timerPromise !== null) { + this.timerPromise.cancel(); + this.timerPromise = null; + } + } + /** Returns a random value in the range [-currentBaseMs/2, currentBaseMs/2] */ private jitterDelayMs(): number { return (Math.random() - 0.5) * this.currentBaseMs; diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index df573a763b0..0a8468d50e8 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -314,8 +314,13 @@ export abstract class PersistentStream< "Can't provide an error when not in an error state." ); + // The stream will be closed so we don't need our idle close timer anymore. this.cancelIdleCheck(); + // Ensure we don't leave a pending backoff operation queued (in case close() + // was called while we were waiting to reconnect). + this.backoff.cancel(); + if (finalState !== PersistentStreamState.Error) { // If this is an intentional close ensure we don't delay our next connection attempt. this.backoff.reset(); @@ -462,10 +467,16 @@ export abstract class PersistentStream< this.backoff.backoffAndRun(async () => { if (this.state === PersistentStreamState.Stopped) { - // Stream can be stopped while waiting for backoff to complete. + // We should have canceled the backoff timer when the stream was + // closed, but just in case we make this a no-op. return; } + assert( + this.state === PersistentStreamState.Backoff, + 'Backoff should have been canceled if we left the Backoff state.' + ); + this.state = PersistentStreamState.Initial; this.start(listener); assert(this.isStarted(), 'PersistentStream should have started'); diff --git a/packages/firestore/test/unit/specs/remote_store_spec.test.ts b/packages/firestore/test/unit/specs/remote_store_spec.test.ts index 3b5183eb940..4cfbc0732e1 100644 --- a/packages/firestore/test/unit/specs/remote_store_spec.test.ts +++ b/packages/firestore/test/unit/specs/remote_store_spec.test.ts @@ -17,7 +17,7 @@ import { expect } from 'chai'; import { Query } from '../../../src/core/query'; import { Code } from '../../../src/util/error'; -import { doc, path } from '../../util/helpers'; +import { doc, path, resumeTokenForSnapshot } from '../../util/helpers'; import { describeSpec, specTest } from './describe_spec'; import { spec } from './spec_builder'; @@ -83,4 +83,36 @@ describeSpec('Remote store:', [], () => { .expectEvents(query, { added: [doc1] }) ); }); + + // TODO(b/72313632): This test is web-only because the Android / iOS spec + // tests exclude backoff entirely. + specTest( + 'Handles user changes while offline (b/74749605).', + ['no-android', 'no-ios'], + () => { + const query = Query.atPath(path('collection')); + const docA = doc('collection/a', 1000, { key: 'a' }); + return ( + spec() + .userListens(query) + + // close the stream (this should trigger retry with backoff; but don't + // run it in an attempt to reproduce b/74749605). + .watchStreamCloses(Code.UNAVAILABLE, { runBackoffTimer: false }) + + // Because we didn't let the backoff timer run and restart the watch + // stream, there will be no active targets. + .expectActiveTargets() + + // Change user (will shut down existing streams and start new ones). + .changeUser('abc') + // Our query should be sent to the new stream. + .expectActiveTargets({ query, resumeToken: '' }) + + // Close the (newly-created) stream as if it too failed (should trigger + // retry with backoff, potentially reproducing the crash in b/74749605). + .watchStreamCloses(Code.UNAVAILABLE) + ); + } + ); }); diff --git a/packages/firestore/test/unit/specs/spec_builder.ts b/packages/firestore/test/unit/specs/spec_builder.ts index b13afa61a33..b225c57283b 100644 --- a/packages/firestore/test/unit/specs/spec_builder.ts +++ b/packages/firestore/test/unit/specs/spec_builder.ts @@ -496,14 +496,22 @@ export class SpecBuilder { return this; } - watchStreamCloses(error: Code): SpecBuilder { + watchStreamCloses( + error: Code, + opts?: { runBackoffTimer: boolean } + ): SpecBuilder { + if (!opts) { + opts = { runBackoffTimer: true }; + } + this.nextStep(); this.currentStep = { watchStreamClose: { error: { code: mapRpcCodeFromCode(error), message: 'Simulated Backend Error' - } + }, + runBackoffTimer: opts.runBackoffTimer } }; return this; diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index d1985b7db14..a03f87f2ac0 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -700,7 +700,7 @@ abstract class TestRunner { ) ); // The watch stream should re-open if we have active listeners. - if (!this.queryListeners.isEmpty()) { + if (spec.runBackoffTimer && !this.queryListeners.isEmpty()) { await this.queue.runDelayedOperationsEarly( TimerId.ListenStreamConnectionBackoff ); @@ -1167,6 +1167,7 @@ export type SpecSnapshotVersion = TestSnapshotVersion; export type SpecWatchStreamClose = { error: SpecError; + runBackoffTimer: boolean; }; export type SpecWriteAck = { From 2cb9ef50c0894fa0d154e5cd1ae1784105c1744b Mon Sep 17 00:00:00 2001 From: wti806 <32399754+wti806@users.noreply.github.com> Date: Thu, 15 Mar 2018 10:17:49 -0700 Subject: [PATCH 31/34] Passwordless (#529) * passwordless signin added new files for passwordless signin added licence exported function * updated externs and types * [AUTOMATED]: Prettier Code Styling * added passwordless sign in in demo and fixed type * remove email in localstorage after used for passwordless sign in --- packages/auth-types/index.d.ts | 16 + packages/auth/demo/public/index.html | 52 ++ packages/auth/demo/public/script.js | 165 ++++++ packages/auth/src/actioncodeinfo.js | 19 +- packages/auth/src/actioncodesettings.js | 16 +- packages/auth/src/actioncodeurl.js | 92 +++ packages/auth/src/auth.js | 75 +++ packages/auth/src/authcredential.js | 100 +++- packages/auth/src/exports_auth.js | 27 + packages/auth/src/idp.js | 16 + packages/auth/src/rpchandler.js | 123 +++- packages/auth/test/actioncodeinfo_test.js | 25 + packages/auth/test/actioncodesettings_test.js | 21 +- packages/auth/test/actioncodeurl_test.js | 66 +++ packages/auth/test/auth_test.js | 306 ++++++++++ packages/auth/test/authcredential_test.js | 262 +++++++-- packages/auth/test/error_test.js | 23 +- packages/auth/test/rpchandler_test.js | 535 ++++++++++++++++++ .../firebase/externs/firebase-auth-externs.js | 227 ++++++++ 19 files changed, 2099 insertions(+), 67 deletions(-) create mode 100644 packages/auth/src/actioncodeurl.js create mode 100644 packages/auth/test/actioncodeurl_test.js diff --git a/packages/auth-types/index.d.ts b/packages/auth-types/index.d.ts index cda41850b8a..7e085efee5b 100644 --- a/packages/auth-types/index.d.ts +++ b/packages/auth-types/index.d.ts @@ -96,6 +96,7 @@ export interface ApplicationVerifier { export interface AuthCredential { providerId: string; + signInMethod: string; } export interface AuthProvider { @@ -109,7 +110,10 @@ export interface ConfirmationResult { export class EmailAuthProvider extends EmailAuthProvider_Instance { static PROVIDER_ID: string; + static EMAIL_PASSWORD_SIGN_IN_METHOD: string; + static EMAIL_LINK_SIGN_IN_METHOD: string; static credential(email: string, password: string): AuthCredential; + static credentialWithLink(email: string, emailLink: string): AuthCredential; } export class EmailAuthProvider_Instance implements AuthProvider { providerId: string; @@ -122,6 +126,7 @@ export interface Error { export class FacebookAuthProvider extends FacebookAuthProvider_Instance { static PROVIDER_ID: string; + static FACEBOOK_SIGN_IN_METHOD: string; static credential(token: string): AuthCredential; } export class FacebookAuthProvider_Instance implements AuthProvider { @@ -132,6 +137,7 @@ export class FacebookAuthProvider_Instance implements AuthProvider { export class GithubAuthProvider extends GithubAuthProvider_Instance { static PROVIDER_ID: string; + static GITHUB_SIGN_IN_METHOD: string; static credential(token: string): AuthCredential; } export class GithubAuthProvider_Instance implements AuthProvider { @@ -142,6 +148,7 @@ export class GithubAuthProvider_Instance implements AuthProvider { export class GoogleAuthProvider extends GoogleAuthProvider_Instance { static PROVIDER_ID: string; + static GOOGLE_SIGN_IN_METHOD: string; static credential( idToken?: string | null, accessToken?: string | null @@ -162,6 +169,7 @@ export class OAuthProvider implements AuthProvider { export class PhoneAuthProvider extends PhoneAuthProvider_Instance { static PROVIDER_ID: string; + static PHONE_SIGN_IN_METHOD: string; static credential( verificationId: string, verificationCode: string @@ -191,6 +199,7 @@ export class RecaptchaVerifier_Instance implements ApplicationVerifier { export class TwitterAuthProvider extends TwitterAuthProvider_Instance { static PROVIDER_ID: string; + static TWITTER_SIGN_IN_METHOD: string; static credential(token: string, secret: string): AuthCredential; } export class TwitterAuthProvider_Instance implements AuthProvider { @@ -238,6 +247,8 @@ export class FirebaseAuth { ): Promise; currentUser: User | null; fetchProvidersForEmail(email: string): Promise; + fetchSignInMethodsForEmail(email: string): Promise; + isSignInWithEmailLink(emailLink: string): boolean; getRedirectResult(): Promise; languageCode: string | null; onAuthStateChanged( @@ -250,6 +261,10 @@ export class FirebaseAuth { error?: (a: Error) => any, completed?: Unsubscribe ): Unsubscribe; + sendSignInLinkToEmail( + email: string, + actionCodeSettings: ActionCodeSettings + ): Promise; sendPasswordResetEmail( email: string, actionCodeSettings?: ActionCodeSettings | null @@ -266,6 +281,7 @@ export class FirebaseAuth { email: string, password: string ): Promise; + signInWithEmailLink(email: string, emailLink?: string): Promise; signInWithPhoneNumber( phoneNumber: string, applicationVerifier: ApplicationVerifier diff --git a/packages/auth/demo/public/index.html b/packages/auth/demo/public/index.html index d9f4199ce9c..2818ba17de3 100644 --- a/packages/auth/demo/public/index.html +++ b/packages/auth/demo/public/index.html @@ -254,6 +254,29 @@ + +
Sign In with Email Link
+
+ + + +
+
+ + +
+
Password Reset
@@ -280,6 +303,20 @@ Confirm Password Change
+ +
Fetch Sign In Methods/Providers
+
+ + + +
@@ -359,6 +396,21 @@ +
+ + + + + +
+
diff --git a/packages/auth/demo/public/script.js b/packages/auth/demo/public/script.js index 55c7bea41e0..c62c2408a92 100644 --- a/packages/auth/demo/public/script.js +++ b/packages/auth/demo/public/script.js @@ -312,6 +312,49 @@ function onSignInWithEmailAndPassword() { } +/** + * Signs in a user with an email link. + */ +function onSignInWithEmailLink() { + var email = $('#sign-in-with-email-link-email').val(); + var link = $('#sign-in-with-email-link-link').val() || undefined; + if (auth.isSignInWithEmailLink(link)) { + auth.signInWithEmailLink(email, link).then(onAuthSuccess, onAuthError); + } else { + alertError('Sign in link is invalid'); + } +} + +/** + * Links a user with an email link. + */ +function onLinkWithEmailLink() { + var email = $('#link-with-email-link-email').val(); + var link = $('#link-with-email-link-link').val() || undefined; + var credential = firebase.auth.EmailAuthProvider + .credentialWithLink(email, link); + activeUser().linkAndRetrieveDataWithCredential(credential) + .then(onAuthUserCredentialSuccess, onAuthError); +} + + +/** + * Re-authenticate a user with email link credential. + */ +function onReauthenticateWithEmailLink() { + var email = $('#link-with-email-link-email').val(); + var link = $('#link-with-email-link-link').val() || undefined; + var credential = firebase.auth.EmailAuthProvider + .credentialWithLink(email, link); + activeUser().reauthenticateAndRetrieveDataWithCredential(credential) + .then(function(result) { + logAdditionalUserInfo(result); + refreshUserData(); + alertSuccess('User reauthenticated!'); + }, onAuthError); +} + + /** * Signs in with a custom token. * @param {DOMEvent} event HTML DOM event returned by the listener. @@ -581,6 +624,52 @@ function onUpdateProfile() { } +/** + * Sends sign in with email link to the user. + */ +function onSendSignInLinkToEmail() { + var email = $('#sign-in-with-email-link-email').val(); + auth.sendSignInLinkToEmail(email, getActionCodeSettings()).then(function() { + alertSuccess('Email sent!'); + }, onAuthError); +} + +/** + * Sends sign in with email link to the user and pass in current url. + */ +function onSendSignInLinkToEmailCurrentUrl() { + var email = $('#sign-in-with-email-link-email').val(); + var actionCodeSettings = { + 'url': window.location.href, + 'handleCodeInApp': true + }; + + auth.sendSignInLinkToEmail(email, actionCodeSettings).then(function() { + if ('localStorage' in window && window['localStorage'] !== null) { + window.localStorage.setItem( + 'emailForSignIn', + // Save the email and the timestamp. + JSON.stringify({ + email: email, + timestamp: new Date().getTime() + })); + } + alertSuccess('Email sent!'); + }, onAuthError); +} + + +/** + * Sends email link to link the user. + */ +function onSendLinkEmailLink() { + var email = $('#link-with-email-link-email').val(); + auth.sendSignInLinkToEmail(email, getActionCodeSettings()).then(function() { + alertSuccess('Email sent!'); + }, onAuthError); +} + + /** * Sends password reset email to the user. */ @@ -615,6 +704,41 @@ function onConfirmPasswordReset() { } +/** + * Gets the list of IDPs that can be used to log in for the given email address. + */ +function onFetchProvidersForEmail() { + var email = $('#fetch-providers-email').val(); + auth.fetchProvidersForEmail(email).then(function(providers) { + log('Providers for ' + email + ' :'); + log(providers); + if (providers.length == 0) { + alertSuccess('Providers for ' + email + ': N/A'); + } else { + alertSuccess('Providers for ' + email +': ' + providers.join(', ')); + } + }, onAuthError); +} + + +/** + * Gets the list of possible sign in methods for the given email address. + */ +function onFetchSignInMethodsForEmail() { + var email = $('#fetch-providers-email').val(); + auth.fetchSignInMethodsForEmail(email).then(function(signInMethods) { + log('Sign in methods for ' + email + ' :'); + log(signInMethods); + if (signInMethods.length == 0) { + alertSuccess('Sign In Methods for ' + email + ': N/A'); + } else { + alertSuccess( + 'Sign In Methods for ' + email +': ' + signInMethods.join(', ')); + } + }, onAuthError); +} + + /** * Fetches and logs the user's providers data. */ @@ -966,6 +1090,28 @@ function getParameterByName(name) { * the input field for the confirm email verification process. */ function populateActionCodes() { + var emailForSignIn = null; + var signInTime = 0; + if ('localStorage' in window && window['localStorage'] !== null) { + try { + // Try to parse as JSON first using new storage format. + var emailForSignInData = + JSON.parse(window.localStorage.getItem('emailForSignIn')); + emailForSignIn = emailForSignInData['email'] || null; + signInTime = emailForSignInData['timestamp'] || 0; + } catch (e) { + // JSON parsing failed. This means the email is stored in the old string + // format. + emailForSignIn = window.localStorage.getItem('emailForSignIn'); + } + if (emailForSignIn) { + // Clear old codes. Old format codes should be cleared immediately. + if (new Date().getTime() - signInTime >= 1 * 24 * 3600 * 1000) { + // Remove email from storage. + window.localStorage.removeItem('emailForSignIn'); + } + } + } var actionCode = getParameterByName('oobCode'); if (actionCode != null) { var mode = getParameterByName('mode'); @@ -973,6 +1119,14 @@ function populateActionCodes() { $('#email-verification-code').val(actionCode); } else if (mode == 'resetPassword') { $('#password-reset-code').val(actionCode); + } else if (mode == 'signIn') { + if (emailForSignIn) { + $('#sign-in-with-email-link-email').val(emailForSignIn); + $('#sign-in-with-email-link-link').val(window.location.href); + onSignInWithEmailLink(); + // Remove email from storage as the code is only usable once. + window.localStorage.removeItem('emailForSignIn'); + } } else { $('#email-verification-code').val(actionCode); $('#password-reset-code').val(actionCode); @@ -1153,11 +1307,19 @@ function initApp(){ e.preventDefault(); } }); + $('#sign-in-with-email-link').click(onSignInWithEmailLink); + $('#link-with-email-link').click(onLinkWithEmailLink); + $('#reauth-with-email-link').click(onReauthenticateWithEmailLink); $('#change-email').click(onChangeEmail); $('#change-password').click(onChangePassword); $('#update-profile').click(onUpdateProfile); + $('#send-sign-in-link-to-email').click(onSendSignInLinkToEmail); + $('#send-sign-in-link-to-email-current-url') + .click(onSendSignInLinkToEmailCurrentUrl); + $('#send-link-email-link').click(onSendLinkEmailLink); + $('#send-password-reset-email').click(onSendPasswordResetEmail); $('#verify-password-reset-code').click(onVerifyPasswordResetCode); $('#confirm-password-reset').click(onConfirmPasswordReset); @@ -1202,6 +1364,9 @@ function initApp(){ $('#set-language-code').click(onSetLanguageCode); $('#use-device-language').click(onUseDeviceLanguage); + + $('#fetch-providers-for-email').click(onFetchProvidersForEmail); + $('#fetch-sign-in-methods-for-email').click(onFetchSignInMethodsForEmail); } $(initApp); diff --git a/packages/auth/src/actioncodeinfo.js b/packages/auth/src/actioncodeinfo.js index 58529cd6f6c..34a5a66a529 100644 --- a/packages/auth/src/actioncodeinfo.js +++ b/packages/auth/src/actioncodeinfo.js @@ -41,12 +41,15 @@ fireauth.ActionCodeInfo = function(response) { var newEmail = response[fireauth.ActionCodeInfo.ServerFieldName.NEW_EMAIL]; var operation = response[fireauth.ActionCodeInfo.ServerFieldName.REQUEST_TYPE]; - if (!email || !operation) { + // Email could be empty only if the request type is EMAIL_SIGNIN. + if (!operation || + (operation != fireauth.ActionCodeInfo.RequestType.EMAIL_SIGNIN && + !email)) { // This is internal only. throw new Error('Invalid provider user info!'); } data[fireauth.ActionCodeInfo.DataField.FROM_EMAIL] = newEmail || null; - data[fireauth.ActionCodeInfo.DataField.EMAIL] = email; + data[fireauth.ActionCodeInfo.DataField.EMAIL] = email || null; fireauth.object.setReadonlyProperty( this, fireauth.ActionCodeInfo.PropertyName.OPERATION, @@ -58,6 +61,18 @@ fireauth.ActionCodeInfo = function(response) { }; +/** + * Firebase Auth Action Code Info requestType possible values. + * @enum {string} + */ +fireauth.ActionCodeInfo.RequestType = { + PASSWORD_RESET: 'PASSWORD_RESET', + RECOVER_EMAIL: 'RECOVER_EMAIL', + EMAIL_SIGNIN: 'EMAIL_SIGNIN', + VERIFY_EMAIL: 'VERIFY_EMAIL' +}; + + /** * The checkActionCode endpoint server response field names. * @enum {string} diff --git a/packages/auth/src/actioncodesettings.js b/packages/auth/src/actioncodesettings.js index 7099273ba16..f9af91b80ff 100644 --- a/packages/auth/src/actioncodesettings.js +++ b/packages/auth/src/actioncodesettings.js @@ -142,13 +142,6 @@ fireauth.ActionCodeSettings.prototype.initialize_ = function(settingsObj) { } /** @private {boolean} Whether the code can be handled in app. */ this.canHandleCodeInApp_ = !!canHandleCodeInApp; - // canHandleCodeInApp can't be true when no mobile application is provided. - if (this.canHandleCodeInApp_ && !this.ibi_ && !this.apn_) { - throw new fireauth.AuthError( - fireauth.authenum.Error.ARGUMENT_ERROR, - fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP + - ' property can\'t be true when no mobile application is provided.'); - } }; @@ -227,3 +220,12 @@ fireauth.ActionCodeSettings.prototype.buildRequest = function() { } return request; }; + + +/** + * Returns the canHandleCodeInApp setting of ActionCodeSettings. + * @return {boolean} Whether the code can be handled in app. + */ +fireauth.ActionCodeSettings.prototype.canHandleCodeInApp = function() { + return this.canHandleCodeInApp_; +}; diff --git a/packages/auth/src/actioncodeurl.js b/packages/auth/src/actioncodeurl.js new file mode 100644 index 00000000000..10bca61d481 --- /dev/null +++ b/packages/auth/src/actioncodeurl.js @@ -0,0 +1,92 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Defines firebase.auth.ActionCodeUrl class which is the utility + * to parse action code URLs. + */ + +goog.provide('fireauth.ActionCodeUrl'); + +goog.require('goog.Uri'); + + +/** + * The utility class to help parse action code URLs used for out of band email + * flows such as password reset, email verification, email link sign in, etc. + * @param {string} actionCodeUrl The action code URL. + * @constructor + */ +fireauth.ActionCodeUrl = function(actionCodeUrl) { + /** @private {!goog.Uri} The action code URL components.*/ + this.uri_ = goog.Uri.parse(actionCodeUrl); +}; + + +/** + * Enums for fields in URL query string. + * @enum {string} + */ +fireauth.ActionCodeUrl.QueryField = { + API_KEY: 'apiKey', + CODE: 'oobCode', + MODE: 'mode' +}; + + +/** + * Enums for action code modes. + * @enum {string} + */ +fireauth.ActionCodeUrl.Mode = { + RESET_PASSWORD: 'resetPassword', + REVOKE_EMAIL: 'recoverEmail', + SIGN_IN: 'signIn', + VERIFY_EMAIL: 'verifyEmail' +}; + + +/** + * Returns the API key parameter of action code URL. + * @return {?string} The first API key value in action code URL or + * undefined if apiKey does not appear in the URL. + */ +fireauth.ActionCodeUrl.prototype.getApiKey = function() { + return this.uri_.getParameterValue( + fireauth.ActionCodeUrl.QueryField.API_KEY) || null; +}; + + +/** + * Returns the action code parameter of action code URL. + * @return {?string} The first oobCode value in action code URL or + * undefined if oobCode does not appear in the URL. + */ +fireauth.ActionCodeUrl.prototype.getCode = function() { + return this.uri_.getParameterValue( + fireauth.ActionCodeUrl.QueryField.CODE) || null; +}; + + +/** + * Returns the mode parameter of action code URL. + * @return {?string} The first mode value in action code URL or + * undefined if mode does not appear in the URL. + */ +fireauth.ActionCodeUrl.prototype.getMode = function() { + return this.uri_.getParameterValue( + fireauth.ActionCodeUrl.QueryField.MODE) || null; +}; diff --git a/packages/auth/src/auth.js b/packages/auth/src/auth.js index 7585b5b757d..75cdeff3d15 100644 --- a/packages/auth/src/auth.js +++ b/packages/auth/src/auth.js @@ -31,6 +31,7 @@ goog.require('fireauth.AuthEventManager'); goog.require('fireauth.AuthProvider'); goog.require('fireauth.AuthUser'); goog.require('fireauth.ConfirmationResult'); +goog.require('fireauth.EmailAuthProvider'); goog.require('fireauth.RpcHandler'); goog.require('fireauth.UserEventType'); goog.require('fireauth.authenum.Error'); @@ -1823,6 +1824,60 @@ fireauth.Auth.prototype.fetchProvidersForEmail = function(email) { }; +/** + * Gets the list of possible sign in methods for the given email address. + * @param {string} email The email address. + * @return {!goog.Promise>} + */ +fireauth.Auth.prototype.fetchSignInMethodsForEmail = function(email) { + return /** @type {!goog.Promise>} */ ( + this.registerPendingPromise_( + this.getRpcHandler().fetchSignInMethodsForIdentifier(email))); +}; + + +/** + * @param {string} emailLink The email link. + * @return {boolean} Whether the link is a sign in with email link. + */ +fireauth.Auth.prototype.isSignInWithEmailLink = function(emailLink) { + return !!fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink); +}; + + +/** + * Sends the sign-in with email link for the email account provided. + * @param {string} email The email account to sign in with. + * @param {!Object} actionCodeSettings The action code settings object. + * @return {!goog.Promise} + */ +fireauth.Auth.prototype.sendSignInLinkToEmail = function( + email, actionCodeSettings) { + var self = this; + return this.registerPendingPromise_( + // Wrap in promise as ActionCodeSettings constructor could throw a + // synchronous error if invalid arguments are specified. + goog.Promise.resolve() + .then(function() { + var actionCodeSettingsBuilder = + new fireauth.ActionCodeSettings(actionCodeSettings); + if (!actionCodeSettingsBuilder.canHandleCodeInApp()) { + throw new fireauth.AuthError( + fireauth.authenum.Error.ARGUMENT_ERROR, + fireauth.ActionCodeSettings.RawField.HANDLE_CODE_IN_APP + + ' must be true when sending sign in link to email'); + } + return actionCodeSettingsBuilder.buildRequest(); + }).then(function(additionalRequestData) { + return self.getRpcHandler().sendSignInLinkToEmail( + email, additionalRequestData); + }).then(function(email) { + // Do not return the email. + })); +}; + + /** * Verifies an email action code for password reset and returns a promise * that resolves with the associated email if verified. @@ -1930,3 +1985,23 @@ fireauth.Auth.prototype.signInWithPhoneNumber = // This will wait for redirectStateIsReady to resolve first. goog.bind(this.signInAndRetrieveDataWithCredential, this)))); }; + + +/** + * Signs in a Firebase User with the provided email and the passwordless + * sign-in email link. + * @param {string} email The email account to sign in with. + * @param {?string=} opt_link The optional link which contains the OTP needed + * to complete the sign in with email link. If not specified, the current + * URL is used instead. + * @return {!goog.Promise} + */ +fireauth.Auth.prototype.signInWithEmailLink = function(email, opt_link) { + var self = this; + return this.registerPendingPromise_( + goog.Promise.resolve().then(function() { + var credential = fireauth.EmailAuthProvider.credentialWithLink( + email, opt_link || fireauth.util.getCurrentUrl()); + return self.signInAndRetrieveDataWithCredential(credential); + })); +}; diff --git a/packages/auth/src/authcredential.js b/packages/auth/src/authcredential.js index 38fb56cc3d3..c5cffb50fa6 100644 --- a/packages/auth/src/authcredential.js +++ b/packages/auth/src/authcredential.js @@ -33,6 +33,7 @@ goog.provide('fireauth.PhoneAuthCredential'); goog.provide('fireauth.PhoneAuthProvider'); goog.provide('fireauth.TwitterAuthProvider'); +goog.require('fireauth.ActionCodeUrl'); goog.require('fireauth.AuthError'); goog.require('fireauth.IdToken'); goog.require('fireauth.authenum.Error'); @@ -159,10 +160,11 @@ fireauth.OAuthResponse; * @param {!fireauth.idp.ProviderId} providerId The provider ID. * @param {!fireauth.OAuthResponse} oauthResponse The OAuth * response object containing token information. + * @param {!fireauth.idp.SignInMethod} signInMethod The sign in method. * @constructor * @implements {fireauth.AuthCredential} */ -fireauth.OAuthCredential = function(providerId, oauthResponse) { +fireauth.OAuthCredential = function(providerId, oauthResponse, signInMethod) { if (oauthResponse['idToken'] || oauthResponse['accessToken']) { // OAuth 2 and either ID token or access token. if (oauthResponse['idToken']) { @@ -186,6 +188,7 @@ fireauth.OAuthCredential = function(providerId, oauthResponse) { } fireauth.object.setReadonlyProperty(this, 'providerId', providerId); + fireauth.object.setReadonlyProperty(this, 'signInMethod', signInMethod); }; @@ -272,7 +275,8 @@ fireauth.OAuthCredential.prototype.makeVerifyAssertionRequest_ = function() { */ fireauth.OAuthCredential.prototype.toPlainObject = function() { var obj = { - 'providerId': this['providerId'] + 'providerId': this['providerId'], + 'signInMethod': this['signInMethod'] }; if (this['idToken']) { obj['oauthIdToken'] = this['idToken']; @@ -422,7 +426,10 @@ fireauth.OAuthProvider.prototype.credential = function(opt_idToken, 'idToken': opt_idToken || null, 'accessToken': opt_accessToken || null }; - return new fireauth.OAuthCredential(this['providerId'], oauthResponse); + // For OAuthCredential, sign in method is same as providerId. + return new fireauth.OAuthCredential(this['providerId'], + oauthResponse, + this['providerId']); }; @@ -441,6 +448,9 @@ goog.inherits(fireauth.FacebookAuthProvider, fireauth.OAuthProvider); fireauth.object.setReadonlyProperty(fireauth.FacebookAuthProvider, 'PROVIDER_ID', fireauth.idp.ProviderId.FACEBOOK); +fireauth.object.setReadonlyProperty(fireauth.FacebookAuthProvider, + 'FACEBOOK_SIGN_IN_METHOD', fireauth.idp.SignInMethod.FACEBOOK); + /** * Initializes a Facebook AuthCredential. @@ -478,6 +488,9 @@ goog.inherits(fireauth.GithubAuthProvider, fireauth.OAuthProvider); fireauth.object.setReadonlyProperty(fireauth.GithubAuthProvider, 'PROVIDER_ID', fireauth.idp.ProviderId.GITHUB); +fireauth.object.setReadonlyProperty(fireauth.GithubAuthProvider, + 'GITHUB_SIGN_IN_METHOD', fireauth.idp.SignInMethod.GITHUB); + /** * Initializes a GitHub AuthCredential. @@ -519,6 +532,9 @@ goog.inherits(fireauth.GoogleAuthProvider, fireauth.OAuthProvider); fireauth.object.setReadonlyProperty(fireauth.GoogleAuthProvider, 'PROVIDER_ID', fireauth.idp.ProviderId.GOOGLE); +fireauth.object.setReadonlyProperty(fireauth.GoogleAuthProvider, + 'GOOGLE_SIGN_IN_METHOD', fireauth.idp.SignInMethod.GOOGLE); + /** * Initializes a Google AuthCredential. @@ -558,6 +574,9 @@ goog.inherits(fireauth.TwitterAuthProvider, fireauth.FederatedProvider); fireauth.object.setReadonlyProperty(fireauth.TwitterAuthProvider, 'PROVIDER_ID', fireauth.idp.ProviderId.TWITTER); +fireauth.object.setReadonlyProperty(fireauth.TwitterAuthProvider, + 'TWITTER_SIGN_IN_METHOD', fireauth.idp.SignInMethod.TWITTER); + /** * Initializes a Twitter AuthCredential. @@ -583,7 +602,8 @@ fireauth.TwitterAuthProvider.credential = function(tokenOrObject, secret) { } return new fireauth.OAuthCredential(fireauth.idp.ProviderId.TWITTER, - /** @type {!fireauth.OAuthResponse} */ (tokenObject)); + /** @type {!fireauth.OAuthResponse} */ (tokenObject), + fireauth.idp.SignInMethod.TWITTER); }; @@ -591,14 +611,21 @@ fireauth.TwitterAuthProvider.credential = function(tokenOrObject, secret) { * The email and password credential class. * @param {string} email The credential email. * @param {string} password The credential password. + * @param {string=} opt_signInMethod The credential sign in method can be either + * 'password' or 'emailLink' * @constructor * @implements {fireauth.AuthCredential} */ -fireauth.EmailAuthCredential = function(email, password) { +fireauth.EmailAuthCredential = function(email, password, opt_signInMethod) { this.email_ = email; this.password_ = password; fireauth.object.setReadonlyProperty(this, 'providerId', fireauth.idp.ProviderId.PASSWORD); + var signInMethod = opt_signInMethod === + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD'] ? + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD'] : + fireauth.EmailAuthProvider['EMAIL_PASSWORD_SIGN_IN_METHOD']; + fireauth.object.setReadonlyProperty(this, 'signInMethod', signInMethod); }; @@ -613,6 +640,10 @@ fireauth.EmailAuthCredential = function(email, password) { */ fireauth.EmailAuthCredential.prototype.getIdTokenProvider = function(rpcHandler) { + if (this['signInMethod'] == + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']) { + return rpcHandler.emailLinkSignIn(this.email_, this.password_); + } return rpcHandler.verifyPassword(this.email_, this.password_); }; @@ -628,6 +659,11 @@ fireauth.EmailAuthCredential.prototype.getIdTokenProvider = */ fireauth.EmailAuthCredential.prototype.linkToIdToken = function(rpcHandler, idToken) { + if (this['signInMethod'] == + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']) { + return rpcHandler.emailLinkSignInForLinking( + idToken, this.email_, this.password_); + } return rpcHandler.updateEmailAndPassword( idToken, this.email_, this.password_); }; @@ -658,7 +694,8 @@ fireauth.EmailAuthCredential.prototype.matchIdTokenWithUid = fireauth.EmailAuthCredential.prototype.toPlainObject = function() { return { 'email': this.email_, - 'password': this.password_ + 'password': this.password_, + 'signInMethod': this['signInMethod'] }; }; @@ -690,11 +727,53 @@ fireauth.EmailAuthProvider.credential = function(email, password) { }; +/** + * @param {string} email The credential email. + * @param {string} emailLink The credential email link. + * @return {!fireauth.EmailAuthCredential} The Auth credential object. + */ +fireauth.EmailAuthProvider.credentialWithLink = function(email, emailLink) { + var code = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink); + if (!code) { + throw new fireauth.AuthError( + fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!'); + } + return new fireauth.EmailAuthCredential(email, code, + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']); +}; + + +/** + * @param {string} emailLink The sign in email link to be validated. + * @return {?string} Action code if the email link is valid, otherwise null. + */ +fireauth.EmailAuthProvider.getActionCodeFromSignInEmailLink = + function(emailLink) { + var actionCodeUrl = new fireauth.ActionCodeUrl(emailLink); + var code = actionCodeUrl.getCode(); + if (actionCodeUrl.getMode() === fireauth.ActionCodeUrl.Mode.SIGN_IN && code) { + return code; + } + return null; +}; + + // Set read only PROVIDER_ID property. fireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, { 'PROVIDER_ID': fireauth.idp.ProviderId.PASSWORD }); +// Set read only EMAIL_LINK_SIGN_IN_METHOD property. +fireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, { + 'EMAIL_LINK_SIGN_IN_METHOD': fireauth.idp.SignInMethod.EMAIL_LINK +}); + +// Set read only EMAIL_PASSWORD_SIGN_IN_METHOD property. +fireauth.object.setReadonlyProperties(fireauth.EmailAuthProvider, { + 'EMAIL_PASSWORD_SIGN_IN_METHOD': fireauth.idp.SignInMethod.EMAIL_PASSWORD +}); + /** * A credential for phone number sign-in. @@ -721,6 +800,9 @@ fireauth.PhoneAuthCredential = function(params) { fireauth.object.setReadonlyProperty(this, 'providerId', fireauth.idp.ProviderId.PHONE); + + fireauth.object.setReadonlyProperty( + this, 'signInMethod', fireauth.idp.SignInMethod.PHONE); }; @@ -957,6 +1039,12 @@ fireauth.object.setReadonlyProperties(fireauth.PhoneAuthProvider, { }); +// Set read only PHONE_SIGN_IN_METHOD property. +fireauth.object.setReadonlyProperties(fireauth.PhoneAuthProvider, { + 'PHONE_SIGN_IN_METHOD': fireauth.idp.SignInMethod.PHONE +}); + + /** * Constructs an Auth credential from a backend response. * @param {?Object} response The backend response to build a credential from. diff --git a/packages/auth/src/exports_auth.js b/packages/auth/src/exports_auth.js index 8f93162e404..496cb50fe1a 100644 --- a/packages/auth/src/exports_auth.js +++ b/packages/auth/src/exports_auth.js @@ -66,10 +66,18 @@ fireauth.exportlib.exportPrototypeMethods( name: 'fetchProvidersForEmail', args: [fireauth.args.string('email')] }, + fetchSignInMethodsForEmail: { + name: 'fetchSignInMethodsForEmail', + args: [fireauth.args.string('email')] + }, getRedirectResult: { name: 'getRedirectResult', args: [] }, + isSignInWithEmailLink: { + name: 'isSignInWithEmailLink', + args: [fireauth.args.string('emailLink')] + }, onAuthStateChanged: { name: 'onAuthStateChanged', args: [ @@ -103,6 +111,13 @@ fireauth.exportlib.exportPrototypeMethods( true) ] }, + sendSignInLinkToEmail: { + name: 'sendSignInLinkToEmail', + args: [ + fireauth.args.string('email'), + fireauth.args.object('actionCodeSettings') + ] + }, setPersistence: { name: 'setPersistence', args: [fireauth.args.string('persistence')] @@ -135,6 +150,12 @@ fireauth.exportlib.exportPrototypeMethods( name: 'signInWithEmailAndPassword', args: [fireauth.args.string('email'), fireauth.args.string('password')] }, + signInWithEmailLink: { + name: 'signInWithEmailLink', + args: [ + fireauth.args.string('email'), fireauth.args.string('emailLink', true) + ] + }, signInAndRetrieveDataWithEmailAndPassword: { name: 'signInAndRetrieveDataWithEmailAndPassword', args: [fireauth.args.string('email'), fireauth.args.string('password')] @@ -341,6 +362,12 @@ fireauth.exportlib.exportFunction( fireauth.args.or(fireauth.args.string(), fireauth.args.object(), 'token') ]); +fireauth.exportlib.exportFunction( + fireauth.EmailAuthProvider, 'credentialWithLink', + fireauth.EmailAuthProvider.credentialWithLink, [ + fireauth.args.string('email'), + fireauth.args.string('emailLink') + ]); fireauth.exportlib.exportPrototypeMethods( fireauth.GithubAuthProvider.prototype, { diff --git a/packages/auth/src/idp.js b/packages/auth/src/idp.js index 1391b9a95ee..5df9af2d1de 100644 --- a/packages/auth/src/idp.js +++ b/packages/auth/src/idp.js @@ -22,6 +22,7 @@ goog.provide('fireauth.idp'); goog.provide('fireauth.idp.IdpSettings'); goog.provide('fireauth.idp.ProviderId'); goog.provide('fireauth.idp.Settings'); +goog.provide('fireauth.idp.SignInMethod'); /** @@ -43,6 +44,21 @@ fireauth.idp.ProviderId = { }; +/** + * Enums for supported sign in methods. + * @enum {string} + */ +fireauth.idp.SignInMethod = { + EMAIL_LINK: 'emailLink', + EMAIL_PASSWORD: 'password', + FACEBOOK: 'facebook.com', + GITHUB: 'github.com', + GOOGLE: 'google.com', + PHONE: 'phone', + TWITTER: 'twitter.com' +}; + + /** * The settings of an identity provider. The fields are: *
    diff --git a/packages/auth/src/rpchandler.js b/packages/auth/src/rpchandler.js index a127553d08b..31e7c9213b5 100644 --- a/packages/auth/src/rpchandler.js +++ b/packages/auth/src/rpchandler.js @@ -231,6 +231,7 @@ fireauth.RpcHandler.AuthServerField = { REFRESH_TOKEN: 'refreshToken', SESSION_ID: 'sessionId', SESSION_INFO: 'sessionInfo', + SIGNIN_METHODS: 'signinMethods', TEMPORARY_PROOF: 'temporaryProof' }; @@ -240,6 +241,7 @@ fireauth.RpcHandler.AuthServerField = { * @enum {string} */ fireauth.RpcHandler.GetOobCodeRequestType = { + EMAIL_SIGNIN: 'EMAIL_SIGNIN', NEW_EMAIL_ACCEPT: 'NEW_EMAIL_ACCEPT', PASSWORD_RESET: 'PASSWORD_RESET', VERIFY_EMAIL: 'VERIFY_EMAIL' @@ -883,6 +885,31 @@ fireauth.RpcHandler.prototype.fetchProvidersForIdentifier = }; +/** + * Returns the list of sign in methods for the given identifier. + * @param {string} identifier The identifier, such as an email address. + * @return {!goog.Promise>} + */ +fireauth.RpcHandler.prototype.fetchSignInMethodsForIdentifier = function( + identifier) { + // createAuthUri returns an error if continue URI is not http or https. + // For environments like Cordova, Chrome extensions, native frameworks, file + // systems, etc, use http://localhost as continue URL. + var continueUri = fireauth.util.isHttpOrHttps() ? + fireauth.util.getCurrentUrl() : + 'http://localhost'; + var request = { + 'identifier': identifier, + 'continueUri': continueUri + }; + return this.invokeRpc_(fireauth.RpcHandler.ApiMethod.CREATE_AUTH_URI, request) + .then(function(response) { + return response[fireauth.RpcHandler.AuthServerField.SIGNIN_METHODS] || + []; + }); +}; + + /** * Gets the list of authorized domains for the specified project. * @return {!goog.Promise>} @@ -1056,6 +1083,44 @@ fireauth.RpcHandler.prototype.verifyPassword = function(email, password) { }; +/** + * Verifies an email link OTP for sign-in and returns a Promise that resolves + * with the ID token. + * @param {string} email The email address. + * @param {string} oobCode The email action OTP. + * @return {!goog.Promise} + */ +fireauth.RpcHandler.prototype.emailLinkSignIn = function(email, oobCode) { + var request = { + 'email': email, + 'oobCode': oobCode + }; + return this.invokeRpc_( + fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN, request); +}; + + +/** + * Verifies an email link OTP for linking and returns a Promise that resolves + * with the ID token. + * @param {string} idToken The ID token. + * @param {string} email The email address. + * @param {string} oobCode The email action OTP. + * @return {!goog.Promise} + */ +fireauth.RpcHandler.prototype.emailLinkSignInForLinking = + function(idToken, email, oobCode) { + var request = { + 'idToken': idToken, + 'email': email, + 'oobCode': oobCode + }; + return this.invokeRpc_( + fireauth.RpcHandler.ApiMethod.EMAIL_LINK_SIGNIN_FOR_LINKING, + request); +}; + + /** * Validates a response that should contain an ID token. * @param {?Object} response The server response data. @@ -1304,8 +1369,22 @@ fireauth.RpcHandler.validateOobCodeRequest_ = function(request) { /** - * Validates a request for an email action code for password reset. - * @param {!Object} request The getOobCode request data for password reset. + * Validates a request for an email action for passwordless email sign-in. + * @param {!Object} request The getOobCode request data for email sign-in. + * @private + */ +fireauth.RpcHandler.validateEmailSignInCodeRequest_ = function(request) { + if (request['requestType'] != + fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN) { + throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR); + } + fireauth.RpcHandler.validateRequestHasEmail_(request); +}; + + +/** + * Validates a request for an email action for email verification. + * @param {!Object} request The getOobCode request data for email verification. * @private */ fireauth.RpcHandler.validateEmailVerificationCodeRequest_ = function(request) { @@ -1335,6 +1414,26 @@ fireauth.RpcHandler.prototype.sendPasswordResetEmail = }; +/** + * Requests getOobCode endpoint for passwordless email sign-in, returns promise + * that resolves with user's email. + * @param {string} email The email account to sign in with. + * @param {!Object} additionalRequestData Additional data to add to the request. + * @return {!goog.Promise} + */ +fireauth.RpcHandler.prototype.sendSignInLinkToEmail = function( + email, additionalRequestData) { + var request = { + 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN, + 'email': email + }; + // Extend the original request with the additional data. + goog.object.extend(request, additionalRequestData); + return this.invokeRpc_( + fireauth.RpcHandler.ApiMethod.GET_EMAIL_SIGNIN_CODE, request); +}; + + /** * Requests getOobCode endpoint for email verification, returns promise that * resolves with user's email. @@ -1800,6 +1899,20 @@ fireauth.RpcHandler.ApiMethod = { requestRequiredFields: ['idToken', 'deleteProvider'], requestValidator: fireauth.RpcHandler.validateDeleteLinkedAccountsRequest_ }, + EMAIL_LINK_SIGNIN: { + endpoint: 'emailLinkSignin', + requestRequiredFields: ['email', 'oobCode'], + requestValidator: fireauth.RpcHandler.validateRequestHasEmail_, + responseValidator: fireauth.RpcHandler.validateIdTokenResponse_, + returnSecureToken: true + }, + EMAIL_LINK_SIGNIN_FOR_LINKING: { + endpoint: 'emailLinkSignin', + requestRequiredFields: ['idToken', 'email', 'oobCode'], + requestValidator: fireauth.RpcHandler.validateRequestHasEmail_, + responseValidator: fireauth.RpcHandler.validateIdTokenResponse_, + returnSecureToken: true + }, GET_ACCOUNT_INFO: { endpoint: 'getAccountInfo' }, @@ -1808,6 +1921,12 @@ fireauth.RpcHandler.ApiMethod = { requestRequiredFields: ['continueUri', 'providerId'], responseValidator: fireauth.RpcHandler.validateGetAuthResponse_ }, + GET_EMAIL_SIGNIN_CODE: { + endpoint: 'getOobConfirmationCode', + requestRequiredFields: ['requestType'], + requestValidator: fireauth.RpcHandler.validateEmailSignInCodeRequest_, + responseField: fireauth.RpcHandler.AuthServerField.EMAIL + }, GET_EMAIL_VERIFICATION_CODE: { endpoint: 'getOobConfirmationCode', requestRequiredFields: ['idToken', 'requestType'], diff --git a/packages/auth/test/actioncodeinfo_test.js b/packages/auth/test/actioncodeinfo_test.js index 6ecb1c90fa5..b79a3489f38 100644 --- a/packages/auth/test/actioncodeinfo_test.js +++ b/packages/auth/test/actioncodeinfo_test.js @@ -43,6 +43,10 @@ var recoverEmailServerResponse = { 'newEmail': 'newUser@example.com', 'requestType': 'RECOVER_EMAIL' }; +var signInWithEmailLinkServerResponse = { + 'kind': 'identitytoolkit#ResetPasswordResponse', + 'requestType': 'EMAIL_SIGNIN' +}; function testActionCodeInfo_invalid_missingOperation() { @@ -139,3 +143,24 @@ function testActionCodeInfo_recoverEmail() { expectedData, actionCodeInfo['data']); } + + +function testActionCodeInfo_signInWithEmailLink() { + var expectedData = {email: null, fromEmail: null}; + var actionCodeInfo = + new fireauth.ActionCodeInfo(signInWithEmailLinkServerResponse); + + // Check operation. + assertEquals('EMAIL_SIGNIN', actionCodeInfo['operation']); + // Property should be read-only. + actionCodeInfo['operation'] = 'BLA'; + assertEquals('EMAIL_SIGNIN', actionCodeInfo['operation']); + + // Check data. + assertObjectEquals(expectedData, actionCodeInfo['data']); + // Property should be read-only. + actionCodeInfo['data']['email'] = 'other@example.com'; + assertObjectEquals(expectedData, actionCodeInfo['data']); + actionCodeInfo['data'] = 'BLA'; + assertObjectEquals(expectedData, actionCodeInfo['data']); +} diff --git a/packages/auth/test/actioncodesettings_test.js b/packages/auth/test/actioncodesettings_test.js index 45af297aa7d..fd22a100798 100644 --- a/packages/auth/test/actioncodesettings_test.js +++ b/packages/auth/test/actioncodesettings_test.js @@ -147,14 +147,21 @@ function testActionCodeSettings_error_continueUrl() { } +function testActionCodeSettings_success_urlOnly_canHandleCodeInApp() { + var settings = { + 'url': 'https://www.example.com/?state=abc', + 'handleCodeInApp': true + }; + var expectedRequest = { + 'continueUrl': 'https://www.example.com/?state=abc', + 'canHandleCodeInApp': true + }; + var actionCodeSettings = new fireauth.ActionCodeSettings(settings); + assertObjectEquals(expectedRequest, actionCodeSettings.buildRequest()); +} + + function testActionCodeSettings_error_canHandleCodeInApp() { - // Can handle code in app but no app specified. - assertActionCodeSettingsErrorThrown( - { - 'url': 'https://www.example.com/?state=abc', - 'handleCodeInApp': true - }, - 'auth/argument-error'); // Non-boolean can handle code in app. assertActionCodeSettingsErrorThrown( { diff --git a/packages/auth/test/actioncodeurl_test.js b/packages/auth/test/actioncodeurl_test.js new file mode 100644 index 00000000000..164e43744d9 --- /dev/null +++ b/packages/auth/test/actioncodeurl_test.js @@ -0,0 +1,66 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Tests for actioncodeurl.js. + */ + +goog.provide('fireauth.ActionCodeUrlTest'); + +goog.require('fireauth.ActionCodeUrl'); +goog.require('goog.testing.jsunit'); + +goog.setTestOnly(); + + +function testActionCodeUrl_success() { + var url = 'https://www.example.com/finishSignIn?' + + 'oobCode=CODE&mode=signIn&apiKey=API_KEY&state=bla'; + var actionCodeUrl = new fireauth.ActionCodeUrl(url); + assertEquals('signIn', actionCodeUrl.getMode()); + assertEquals('CODE', actionCodeUrl.getCode()); + assertEquals('API_KEY', actionCodeUrl.getApiKey()); +} + + +function testActionCodeUrl_success_portNumberInUrl() { + var url = 'https://www.example.com:8080/finishSignIn?' + + 'oobCode=CODE&mode=signIn&apiKey=API_KEY&state=bla'; + var actionCodeUrl = new fireauth.ActionCodeUrl(url); + assertEquals('signIn', actionCodeUrl.getMode()); + assertEquals('CODE', actionCodeUrl.getCode()); + assertEquals('API_KEY', actionCodeUrl.getApiKey()); +} + + +function testActionCodeUrl_success_hashParameters() { + var url = 'https://www.example.com/finishSignIn?' + + 'oobCode=CODE1&mode=signIn&apiKey=API_KEY1&state=bla' + + '#oobCode=CODE2&mode=signIn&apiKey=API_KEY2&state=bla'; + var actionCodeUrl = new fireauth.ActionCodeUrl(url); + assertEquals('signIn', actionCodeUrl.getMode()); + assertEquals('CODE1', actionCodeUrl.getCode()); + assertEquals('API_KEY1', actionCodeUrl.getApiKey()); +} + + +function testActionCodeUrl_emptyParameter() { + var url = 'https://www.example.com/finishSignIn'; + var actionCodeUrl = new fireauth.ActionCodeUrl(url); + assertNull(actionCodeUrl.getMode()); + assertNull(actionCodeUrl.getCode()); + assertNull(actionCodeUrl.getApiKey()); +} diff --git a/packages/auth/test/auth_test.js b/packages/auth/test/auth_test.js index 516d09ea30a..9c3b4eac0a8 100644 --- a/packages/auth/test/auth_test.js +++ b/packages/auth/test/auth_test.js @@ -1349,6 +1349,73 @@ function testFetchProvidersForEmail() { } +function testFetchSignInMethodsForEmail() { + var email = 'foo@bar.com'; + var expectedSignInMethods = ['password', 'google.com']; + + asyncTestCase.waitForSignals(1); + + // Simulate successful RpcHandler fetchSignInMethodsForIdentifier. + stubs.replace( + fireauth.RpcHandler.prototype, 'fetchSignInMethodsForIdentifier', + function(data) { + assertObjectEquals(email, data); + return goog.Promise.resolve(expectedSignInMethods); + }); + + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + auth1.fetchSignInMethodsForEmail(email).then(function(signInMethods) { + assertArrayEquals(expectedSignInMethods, signInMethods); + asyncTestCase.signal(); + }); + assertAuthTokenListenerCalledOnce(auth1); +} + + +function testFetchSignInMethodsForEmail_error() { + var email = 'foo@bar.com'; + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.INTERNAL_ERROR); + + asyncTestCase.waitForSignals(1); + + stubs.replace( + fireauth.RpcHandler.prototype, 'fetchSignInMethodsForIdentifier', + function(data) { + assertObjectEquals(email, data); + return goog.Promise.reject(expectedError); + }); + + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + auth1.fetchSignInMethodsForEmail(email) + .then(function(signInMethods) { + fail('fetchSignInMethodsForEmail should not resolve!'); + }).thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + asyncTestCase.signal(); + }); + assertAuthTokenListenerCalledOnce(auth1); +} + + +function testIsSignInWithEmailLink() { + var emailLink1 = 'https://www.example.com/action?mode=signIn&oobCode=oobCode'; + var emailLink2 = 'https://www.example.com/action?mode=verifyEmail&' + + 'oobCode=oobCode'; + var emailLink3 = 'https://www.example.com/action?mode=signIn'; + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + var isSignInLink1 = auth1.isSignInWithEmailLink(emailLink1); + assertEquals(true, isSignInLink1); + var isSignInLink2 = auth1.isSignInWithEmailLink(emailLink2); + assertEquals(false, isSignInLink2); + var isSignInLink3 = auth1.isSignInWithEmailLink(emailLink3); + assertEquals(false, isSignInLink3); +} + + function testAuth_pendingPromises() { asyncTestCase.waitForSignals(1); // Simulate available token. @@ -1433,6 +1500,116 @@ function testAuth_delete() { } +/** + * Tests sendSignInLinkToEmail successful operation with action code settings. + */ +function testSendSignInLinkToEmail_success() { + var expectedEmail = 'user@example.com'; + // Simulate successful RpcHandler sendSignInLinkToEmail. + stubs.replace( + fireauth.RpcHandler.prototype, + 'sendSignInLinkToEmail', + function(email, actualActionCodeSettings) { + assertObjectEquals( + new fireauth.ActionCodeSettings(actionCodeSettings).buildRequest(), + actualActionCodeSettings); + assertEquals(expectedEmail, email); + return goog.Promise.resolve(expectedEmail); + }); + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + assertAuthTokenListenerCalledOnce(auth1); + auth1.sendSignInLinkToEmail(expectedEmail, actionCodeSettings) + .then(function() { + asyncTestCase.signal(); + }); + asyncTestCase.waitForSignals(1); +} + + +/** + * Tests sendSignInLinkToEmail failing operation due to backend error. + */ +function testSendSignInLinkToEmail_error() { + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.INTERNAL_ERROR); + var expectedEmail = 'user@example.com'; + // Simulate unsuccessful RpcHandler sendSignInLinkToEmail. + stubs.replace( + fireauth.RpcHandler.prototype, + 'sendSignInLinkToEmail', + function(email, actualActionCodeSettings) { + assertObjectEquals( + new fireauth.ActionCodeSettings(actionCodeSettings).buildRequest(), + actualActionCodeSettings); + return goog.Promise.reject(expectedError); + }); + asyncTestCase.waitForSignals(1); + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + assertAuthTokenListenerCalledOnce(auth1); + auth1.sendSignInLinkToEmail(expectedEmail, actionCodeSettings) + .then(function() { + fail('sendSignInLinkToEmail should not resolve!'); + }).thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + asyncTestCase.signal(); + }); +} + + +/** + * Tests sendSignInLinkToEmail empty continue URL in action code settings. + */ +function testSendSignInLinkToEmail_emptyContinueUrl_error() { + var settings = { + 'url': '', + 'handleCodeInApp': true + }; + var expectedError = + new fireauth.AuthError(fireauth.authenum.Error.INVALID_CONTINUE_URI); + + var expectedEmail = 'user@example.com'; + asyncTestCase.waitForSignals(1); + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + assertAuthTokenListenerCalledOnce(auth1); + auth1.sendSignInLinkToEmail(expectedEmail, settings) + .then(function() { + fail('sendSignInLinkToEmail should not resolve!'); + }).thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + asyncTestCase.signal(); + }); +} + + +/** + * Tests sendSignInLinkToEmail invalid handleCodeInApp settings. + */ +function testSendSignInLinkToEmail_handleCodeInApp_error() { + var settings = { + 'url': 'https://www.example.com/?state=abc', + 'handleCodeInApp': false + }; + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.ARGUMENT_ERROR, + 'handleCodeInApp must be true when sending sign in link to email'); + var expectedEmail = 'user@example.com'; + asyncTestCase.waitForSignals(1); + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + assertAuthTokenListenerCalledOnce(auth1); + auth1.sendSignInLinkToEmail(expectedEmail, settings) + .then(function() { + fail('sendSignInLinkToEmail should not resolve!'); + }).thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + asyncTestCase.signal(); + }); +} + + /** * Tests sendPasswordResetEmail successful operation with no action code * settings. @@ -3733,6 +3910,135 @@ function testAuth_signInAndRetrieveDataWithCustomToken_error() { } +function testAuth_signInWithEmailLink_success() { + // Tests successful signInWithEmailLink. + fireauth.AuthEventManager.ENABLED = true; + // Expected email and link. + var expectedEmail = 'user@example.com'; + var expectedLink = 'https://www.example.com?mode=signIn&oobCode=code'; + var expectedOobCode = 'code'; + var expectedIdToken = 'HEAD.ew0KICAiaXNzIjogImh0dHBzOi8vc2VjdXJldG9rZW4uZ2' + + '9vZ2xlLmNvbS8xMjM0NTY3OCIsDQogICJwaWN0dXJlIjogImh0dHBzOi8vcGx1cy5nb29' + + 'nbGUuY29tL2FiY2RlZmdoaWprbG1ub3BxcnN0dSIsDQogICJhdWQiOiAiMTIzNDU2Nzgi' + + 'LA0KICAiYXV0aF90aW1lIjogMTUxMDM1NzYyMiwNCiAgInVzZXJfaWQiOiAiYWJjZGVmZ' + + '2hpamtsbW5vcHFyc3R1IiwNCiAgInN1YiI6ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHUiLA' + + '0KICAiaWF0IjogMTUxMDM1NzYyMiwNCiAgImV4cCI6IDE1MTAzNjEyMjIsDQogICJlbWF' + + 'pbCI6ICJ1c2VyQGV4YW1wbGUuY29tIiwNCiAgImVtYWlsX3ZlcmlmaWVkIjogdHJ1ZSwN' + + 'CiAgImZpcmViYXNlIjogew0KICAgICJpZGVudGl0aWVzIjogew0KICAgICAgImVtYWlsI' + + 'jogWw0KICAgICAgICAidXNlckBleGFtcGxlLmNvbSINCiAgICAgIF0NCiAgICB9LA0KIC' + + 'AgICJzaWduX2luX3Byb3ZpZGVyIjogInBhc3N3b3JkIg0KICB9DQp9.SIGNATURE'; + expectedTokenResponse['idToken'] = expectedIdToken; + + // Stub OAuth sign in handler. + fakeOAuthSignInHandler(); + // signInWithIdTokenResponse should initialize a user using the expected + // token response generated by RPC response. + stubs.replace( + fireauth.Auth.prototype, + 'signInWithIdTokenResponse', + function(tokenResponse) { + // Token response should match rpcHandler response. + assertObjectEquals(expectedTokenResponse, tokenResponse); + // Simulate user sign in completed and returned. + auth1.setCurrentUser_(user1); + asyncTestCase.signal(); + return goog.Promise.resolve(); + }); + // emailLinkSignIn should be called with expected parameters and resolved + // with expected token response. + stubs.replace( + fireauth.RpcHandler.prototype, + 'emailLinkSignIn', + function(email, oobCode) { + assertEquals(expectedEmail, email); + assertEquals(expectedOobCode, oobCode); + asyncTestCase.signal(); + return goog.Promise.resolve(expectedTokenResponse); + }); + asyncTestCase.waitForSignals(3); + // Initialize expected user. + var user1 = new fireauth.AuthUser( + config3, expectedTokenResponse, accountInfo); + var expectedResult = { + 'user': user1, + 'credential': null, + 'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}, + 'operationType': fireauth.constants.OperationType.SIGN_IN + }; + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + // Sign in with email and password. + auth1.signInWithEmailLink(expectedEmail, expectedLink) + .then(function(result) { + assertObjectEquals(expectedResult, result); + asyncTestCase.signal(); + }); +} + + +function testAuth_signInWithEmailLink_error() { + // Tests successful signInWithEmailLink. + fireauth.AuthEventManager.ENABLED = true; + // Expected email and link. + var expectedEmail = 'user@example.com'; + var expectedLink = 'https://www.example.com?mode=signIn&oobCode=code'; + var expectedOobCode = 'code'; + // Expected RPC error. + var expectedError = + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR); + // Stub OAuth sign in handler. + fakeOAuthSignInHandler(); + // signInWithIdTokenResponse should initialize a user using the expected + // token response generated by RPC response. + stubs.replace( + fireauth.Auth.prototype, + 'signInWithIdTokenResponse', + function(tokenResponse) { + fail('signInWithIdTokenResponse should not be called!'); + }); + // emailLinkSignIn should be called with expected parameters and resolved + // with expected error. + stubs.replace( + fireauth.RpcHandler.prototype, + 'emailLinkSignIn', + function(email, oobCode) { + assertEquals(expectedEmail, email); + assertEquals(expectedOobCode, oobCode); + asyncTestCase.signal(); + return goog.Promise.reject(expectedError); + }); + asyncTestCase.waitForSignals(2); + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + // Sign in with email and password should throw expected error. + auth1.signInWithEmailLink(expectedEmail, expectedLink) + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + asyncTestCase.signal(); + }); +} + + +function testAuth_signInWithEmailLink_invalidLink_error() { + // Tests signInWithEmailLink when an invalid link is provided. + fireauth.AuthEventManager.ENABLED = true; + // Expected email and link. + var expectedEmail = 'user@example.com'; + var expectedLink = 'https://www.example.com?mode=signIn'; + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!'); + asyncTestCase.waitForSignals(1); + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + // Sign in with email and password should throw expected error. + auth1.signInWithEmailLink(expectedEmail, expectedLink) + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + asyncTestCase.signal(); + }); +} + + function testAuth_signInWithEmailAndPassword_success() { // Tests successful signInWithEmailAndPassword. fireauth.AuthEventManager.ENABLED = true; diff --git a/packages/auth/test/authcredential_test.js b/packages/auth/test/authcredential_test.js index abdc18de6b4..2a1d53a8707 100644 --- a/packages/auth/test/authcredential_test.js +++ b/packages/auth/test/authcredential_test.js @@ -39,6 +39,7 @@ goog.require('fireauth.authenum.Error'); goog.require('fireauth.common.testHelper'); goog.require('fireauth.deprecation'); goog.require('fireauth.idp.ProviderId'); +goog.require('fireauth.idp.SignInMethod'); goog.require('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.testing.MockControl'); @@ -83,6 +84,16 @@ function setUp() { goog.testing.recordFunction(function(request) { return goog.Promise.resolve(responseForIdToken); })); + stubs.replace( + fireauth.RpcHandler.prototype, 'emailLinkSignIn', + goog.testing.recordFunction(function(request) { + return goog.Promise.resolve(responseForIdToken); + })); + stubs.replace( + fireauth.RpcHandler.prototype, 'emailLinkSignInForLinking', + goog.testing.recordFunction(function(request) { + return goog.Promise.resolve(responseForIdToken); + })); stubs.replace( fireauth.RpcHandler.prototype, 'verifyAssertionForLinking', @@ -157,9 +168,9 @@ function assertRpcHandlerVerifyAssertion(request) { /** - * Assert that the correct request is sent to RPC handler verifyPassword. - * @param {!string} email The email in verifyPassword request. - * @param {!string} password The password in verifyPassword request. + * Asserts that the correct request is sent to RPC handler verifyPassword. + * @param {string} email The email in verifyPassword request. + * @param {string} password The password in verifyPassword request. */ function assertRpcHandlerVerifyPassword(email, password) { assertEquals( @@ -178,6 +189,46 @@ function assertRpcHandlerVerifyPassword(email, password) { } +/** + * Asserts that the correct request is sent to RPC handler emailLinkSignIn. + * @param {string} email The email in emailLinkSignIn request. + * @param {string} oobCode The oobCode in emailLinkSignIn request. + */ +function assertRpcHandlerEmailLinkSignIn(email, oobCode) { + assertEquals(1, fireauth.RpcHandler.prototype.emailLinkSignIn.getCallCount()); + assertObjectEquals( + email, + fireauth.RpcHandler.prototype.emailLinkSignIn.getLastCall().getArgument( + 0)); + assertObjectEquals( + oobCode, + fireauth.RpcHandler.prototype.emailLinkSignIn.getLastCall().getArgument( + 1)); +} + + +/** + * Asserts that the correct request is sent to RPC handler + * emailLinkSignInForLinking. + * @param {string} idToken The idToken in emailLinkSignInForLinking request. + * @param {string} email The email in emailLinkSignInForLinking request. + * @param {string} oobCode The oobCode in emailLinkSignInForLinking request. + */ +function assertRpcHandlerEmailLinkSignInForLinking(idToken, email, oobCode) { + assertEquals(1, fireauth.RpcHandler.prototype.emailLinkSignInForLinking + .getCallCount()); + assertObjectEquals( + idToken, fireauth.RpcHandler.prototype.emailLinkSignInForLinking + .getLastCall().getArgument(0)); + assertObjectEquals( + email, fireauth.RpcHandler.prototype.emailLinkSignInForLinking + .getLastCall().getArgument(1)); + assertObjectEquals( + oobCode, fireauth.RpcHandler.prototype.emailLinkSignInForLinking + .getLastCall().getArgument(2)); +} + + /** * Assert that the correct request is sent to RPC handler * verifyAssertionForLinking. @@ -306,12 +357,14 @@ function testOAuthCredential() { assertEquals('exampleIdToken', authCredential['idToken']); assertEquals('exampleAccessToken', authCredential['accessToken']); assertEquals('example.com', authCredential['providerId']); + assertEquals('example.com', authCredential['signInMethod']); authCredential.getIdTokenProvider(rpcHandler); assertObjectEquals( { 'oauthAccessToken': 'exampleAccessToken', 'oauthIdToken': 'exampleIdToken', - 'providerId': 'example.com' + 'providerId': 'example.com', + 'signInMethod': 'example.com' }, authCredential.toPlainObject()); assertRpcHandlerVerifyAssertion({ @@ -419,7 +472,8 @@ function testOAuthProvider_getCredentialFromResponse() { fireauth.AuthProvider.getCredentialFromResponse({ 'oauthAccessToken': 'exampleAccessToken', 'oauthIdToken': 'exampleIdToken', - 'providerId': 'example.com' + 'providerId': 'example.com', + 'signInMethod': 'example.com' }).toPlainObject()); } @@ -433,7 +487,8 @@ function testOAuthProvider_getCredentialFromResponse_accessTokenOnly() { authCredential.toPlainObject(), fireauth.AuthProvider.getCredentialFromResponse({ 'oauthAccessToken': 'exampleAccessToken', - 'providerId': 'example.com' + 'providerId': 'example.com', + 'signInMethod': 'example.com' }).toPlainObject()); } @@ -446,7 +501,8 @@ function testOAuthProvider_getCredentialFromResponse_idTokenOnly() { authCredential.toPlainObject(), fireauth.AuthProvider.getCredentialFromResponse({ 'oauthIdToken': 'exampleIdToken', - 'providerId': 'example.com' + 'providerId': 'example.com', + 'signInMethod': 'example.com' }).toPlainObject()); } @@ -491,15 +547,21 @@ function testFacebookAuthCredential() { assertEquals( fireauth.idp.ProviderId.FACEBOOK, fireauth.FacebookAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.FACEBOOK, + fireauth.FacebookAuthProvider['FACEBOOK_SIGN_IN_METHOD']); var authCredential = fireauth.FacebookAuthProvider.credential( 'facebookAccessToken'); assertEquals('facebookAccessToken', authCredential['accessToken']); assertEquals(fireauth.idp.ProviderId.FACEBOOK, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.FACEBOOK, authCredential['signInMethod']); authCredential.getIdTokenProvider(rpcHandler); assertObjectEquals( { 'oauthAccessToken': 'facebookAccessToken', - 'providerId': fireauth.idp.ProviderId.FACEBOOK + 'providerId': fireauth.idp.ProviderId.FACEBOOK, + 'signInMethod': fireauth.idp.SignInMethod.FACEBOOK }, authCredential.toPlainObject()); assertRpcHandlerVerifyAssertion({ @@ -614,10 +676,13 @@ function testFacebookAuthCredential_alternateConstructor() { {'accessToken': 'facebookAccessToken'}); assertEquals('facebookAccessToken', authCredential['accessToken']); assertEquals(fireauth.idp.ProviderId.FACEBOOK, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.FACEBOOK, authCredential['signInMethod']); assertObjectEquals( { 'oauthAccessToken': 'facebookAccessToken', - 'providerId': fireauth.idp.ProviderId.FACEBOOK + 'providerId': fireauth.idp.ProviderId.FACEBOOK, + 'signInMethod': fireauth.idp.SignInMethod.FACEBOOK }, authCredential.toPlainObject()); @@ -667,11 +732,14 @@ function testFacebookAuthCredential_nonHttp() { 'facebookAccessToken'); assertEquals('facebookAccessToken', authCredential['accessToken']); assertEquals(fireauth.idp.ProviderId.FACEBOOK, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.FACEBOOK, authCredential['signInMethod']); authCredential.getIdTokenProvider(rpcHandler); assertObjectEquals( { 'oauthAccessToken': 'facebookAccessToken', - 'providerId': fireauth.idp.ProviderId.FACEBOOK + 'providerId': fireauth.idp.ProviderId.FACEBOOK, + 'signInMethod': fireauth.idp.SignInMethod.FACEBOOK }, authCredential.toPlainObject()); // http://localhost should be used instead of the real current URL. @@ -691,15 +759,21 @@ function testGithubAuthCredential() { assertEquals( fireauth.idp.ProviderId.GITHUB, fireauth.GithubAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.GITHUB, + fireauth.GithubAuthProvider['GITHUB_SIGN_IN_METHOD']); var authCredential = fireauth.GithubAuthProvider.credential( 'githubAccessToken'); assertEquals('githubAccessToken', authCredential['accessToken']); assertEquals(fireauth.idp.ProviderId.GITHUB, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.GITHUB, authCredential['signInMethod']); authCredential.getIdTokenProvider(rpcHandler); assertObjectEquals( { 'oauthAccessToken': 'githubAccessToken', - 'providerId': fireauth.idp.ProviderId.GITHUB + 'providerId': fireauth.idp.ProviderId.GITHUB, + 'signInMethod':fireauth.idp.SignInMethod.GITHUB }, authCredential.toPlainObject()); assertRpcHandlerVerifyAssertion({ @@ -805,7 +879,8 @@ function testGithubAuthCredential_alternateConstructor() { assertObjectEquals( { 'oauthAccessToken': 'githubAccessToken', - 'providerId': fireauth.idp.ProviderId.GITHUB + 'providerId': fireauth.idp.ProviderId.GITHUB, + 'signInMethod':fireauth.idp.SignInMethod.GITHUB }, authCredential.toPlainObject()); @@ -873,17 +948,23 @@ function testGoogleAuthCredential() { assertEquals( fireauth.idp.ProviderId.GOOGLE, fireauth.GoogleAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.GOOGLE, + fireauth.GoogleAuthProvider['GOOGLE_SIGN_IN_METHOD']); var authCredential = fireauth.GoogleAuthProvider.credential( 'googleIdToken', 'googleAccessToken'); assertEquals('googleIdToken', authCredential['idToken']); assertEquals('googleAccessToken', authCredential['accessToken']); assertEquals(fireauth.idp.ProviderId.GOOGLE, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.GOOGLE, authCredential['signInMethod']); authCredential.getIdTokenProvider(rpcHandler); assertObjectEquals( { 'oauthAccessToken': 'googleAccessToken', 'oauthIdToken': 'googleIdToken', - 'providerId': fireauth.idp.ProviderId.GOOGLE + 'providerId': fireauth.idp.ProviderId.GOOGLE, + 'signInMethod': fireauth.idp.SignInMethod.GOOGLE }, authCredential.toPlainObject()); assertRpcHandlerVerifyAssertion({ @@ -1059,31 +1140,39 @@ function testGoogleAuthCredential_alternateConstructor() { {'idToken': 'googleIdToken'}); assertEquals('googleIdToken', authCredentialIdToken['idToken']); assertUndefined(authCredentialIdToken['accessToken']); - assertObjectEquals({ - 'oauthIdToken': 'googleIdToken', - 'providerId': fireauth.idp.ProviderId.GOOGLE - }, authCredentialIdToken.toPlainObject()); + assertObjectEquals( + { + 'oauthIdToken': 'googleIdToken', + 'providerId': fireauth.idp.ProviderId.GOOGLE, + 'signInMethod': fireauth.idp.SignInMethod.GOOGLE + }, + authCredentialIdToken.toPlainObject()); // Only access token. var authCredentialAccessToken = fireauth.GoogleAuthProvider.credential( {'accessToken': 'googleAccessToken'}); assertEquals('googleAccessToken', authCredentialAccessToken['accessToken']); assertUndefined(authCredentialAccessToken['idToken']); - assertObjectEquals({ - 'oauthAccessToken': 'googleAccessToken', - 'providerId': fireauth.idp.ProviderId.GOOGLE - }, authCredentialAccessToken.toPlainObject()); + assertObjectEquals( + { + 'oauthIdToken': 'googleIdToken', + 'providerId': fireauth.idp.ProviderId.GOOGLE, + 'signInMethod': fireauth.idp.SignInMethod.GOOGLE + }, + authCredentialIdToken.toPlainObject()); // Both tokens. var authCredentialBoth = fireauth.GoogleAuthProvider.credential( {'idToken': 'googleIdToken', 'accessToken': 'googleAccessToken'}); assertEquals('googleAccessToken', authCredentialBoth['accessToken']); assertEquals('googleIdToken', authCredentialBoth['idToken']); - assertObjectEquals({ - 'oauthAccessToken': 'googleAccessToken', - 'oauthIdToken': 'googleIdToken', - 'providerId': fireauth.idp.ProviderId.GOOGLE - }, authCredentialBoth.toPlainObject()); + assertObjectEquals( + { + 'oauthIdToken': 'googleIdToken', + 'providerId': fireauth.idp.ProviderId.GOOGLE, + 'signInMethod': fireauth.idp.SignInMethod.GOOGLE + }, + authCredentialIdToken.toPlainObject()); // Neither token. var expectedError = new fireauth.AuthError( @@ -1133,16 +1222,22 @@ function testTwitterAuthCredential() { assertEquals( fireauth.idp.ProviderId.TWITTER, fireauth.TwitterAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.TWITTER, + fireauth.TwitterAuthProvider['TWITTER_SIGN_IN_METHOD']); var authCredential = fireauth.TwitterAuthProvider.credential( 'twitterOauthToken', 'twitterOauthTokenSecret'); assertEquals('twitterOauthToken', authCredential['accessToken']); assertEquals('twitterOauthTokenSecret', authCredential['secret']); assertEquals(fireauth.idp.ProviderId.TWITTER, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.TWITTER, authCredential['signInMethod']); assertObjectEquals( { 'oauthAccessToken': 'twitterOauthToken', 'oauthTokenSecret': 'twitterOauthTokenSecret', - 'providerId': fireauth.idp.ProviderId.TWITTER + 'providerId': fireauth.idp.ProviderId.TWITTER, + 'signInMethod': fireauth.idp.SignInMethod.TWITTER }, authCredential.toPlainObject()); authCredential.getIdTokenProvider(rpcHandler); @@ -1275,12 +1370,14 @@ function testTwitterAuthCredential_alternateConstructor() { assertEquals('twitterOauthToken', authCredential['accessToken']); assertEquals('twitterOauthTokenSecret', authCredential['secret']); assertEquals(fireauth.idp.ProviderId.TWITTER, authCredential['providerId']); - assertObjectEquals({ - 'oauthAccessToken': 'twitterOauthToken', - 'oauthTokenSecret': 'twitterOauthTokenSecret', - 'providerId': fireauth.idp.ProviderId.TWITTER - }, - authCredential.toPlainObject()); + assertObjectEquals( + { + 'oauthAccessToken': 'twitterOauthToken', + 'oauthTokenSecret': 'twitterOauthTokenSecret', + 'providerId': fireauth.idp.ProviderId.TWITTER, + 'signInMethod':fireauth.idp.SignInMethod.TWITTER + }, + authCredential.toPlainObject()); // Missing token or secret should be an error. var expectedError = new fireauth.AuthError( @@ -1308,12 +1405,16 @@ function testEmailAuthCredential() { assertEquals( fireauth.idp.ProviderId.PASSWORD, fireauth.EmailAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.EMAIL_PASSWORD, + fireauth.EmailAuthProvider['EMAIL_PASSWORD_SIGN_IN_METHOD']); var authCredential = fireauth.EmailAuthProvider.credential( 'user@example.com', 'password'); assertObjectEquals( { 'email': 'user@example.com', - 'password': 'password' + 'password': 'password', + 'signInMethod': 'password' }, authCredential.toPlainObject()); assertEquals(fireauth.idp.ProviderId.PASSWORD, authCredential['providerId']); @@ -1341,6 +1442,15 @@ function testEmailAuthCredential_linkToIdToken() { } +function testEmailAuthCredentialWithEmailLink_linkToIdToken() { + var authCredential = fireauth.EmailAuthProvider.credentialWithLink( + 'user@example.com', 'https://www.example.com?mode=signIn&oobCode=code'); + authCredential.linkToIdToken(rpcHandler, 'myIdToken'); + assertRpcHandlerEmailLinkSignInForLinking( + 'myIdToken', 'user@example.com', 'code'); +} + + function testEmailAuthCredential_matchIdTokenWithUid() { // Mock idToken parsing. initializeIdTokenMocks('ID_TOKEN', '1234'); @@ -1352,6 +1462,82 @@ function testEmailAuthCredential_matchIdTokenWithUid() { } +function testEmailAuthCredentialWithEmailLink_matchIdTokenWithUid() { + // Mock idToken parsing. + initializeIdTokenMocks('ID_TOKEN', '1234'); + var authCredential = fireauth.EmailAuthProvider.credentialWithLink( + 'user@example.com', 'https://www.example.com?mode=signIn&oobCode=code'); + var p = authCredential.matchIdTokenWithUid(rpcHandler, '1234'); + assertRpcHandlerEmailLinkSignIn('user@example.com', 'code'); + return p; +} + + +/** + * Test Email Link Auth credential. + */ +function testEmailAuthCredentialWithLink() { + assertEquals( + fireauth.idp.ProviderId.PASSWORD, + fireauth.EmailAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.EMAIL_LINK, + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']); + var authCredential = fireauth.EmailAuthProvider.credentialWithLink( + 'user@example.com', 'https://www.example.com?mode=signIn&oobCode=code'); + assertObjectEquals( + { + 'email': 'user@example.com', + 'password': 'code', + 'signInMethod': 'emailLink' + }, + authCredential.toPlainObject()); + assertEquals(fireauth.idp.ProviderId.PASSWORD, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.EMAIL_LINK, authCredential['signInMethod']); + authCredential.getIdTokenProvider(rpcHandler); + assertRpcHandlerEmailLinkSignIn('user@example.com', 'code'); + var provider = new fireauth.EmailAuthProvider(); + // Should throw an invalid OAuth provider error. + var error = assertThrows(function() { + fireauth.AuthProvider.checkIfOAuthSupported(provider); + }); + var expectedError = + new fireauth.AuthError(fireauth.authenum.Error.INVALID_OAUTH_PROVIDER); + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + assertEquals(fireauth.idp.ProviderId.PASSWORD, provider['providerId']); + assertFalse(provider['isOAuthProvider']); +} + + +function testEmailAuthCredentialWithLink_invalidLink_error() { + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!'); + var error = assertThrows(function() { + fireauth.EmailAuthProvider.credentialWithLink( + 'user@example.com', 'invalidLink'); + }); + fireauth.common.testHelper.assertErrorEquals(expectedError, error); +} + + +function testEmailAuthProvider_getActionCodeFromSignInEmailLink() { + var emailLink1 = 'https://www.example.com/action?mode=signIn&oobCode=oobCode'; + var emailLink2 = 'https://www.example.com/action?mode=verifyEmail&' + + 'oobCode=oobCode'; + var emailLink3 = 'https://www.example.com/action?mode=signIn'; + var oobCode1 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink1); + assertEquals('oobCode', oobCode1); + var oobCode2 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink2); + assertNull(oobCode2); + var oobCode3 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink3); + assertNull(oobCode3); +} + + function testPhoneAuthProvider() { assertEquals(fireauth.PhoneAuthProvider['PROVIDER_ID'], fireauth.idp.ProviderId.PHONE); @@ -1632,6 +1818,10 @@ function testPhoneAuthCredential() { var credential = fireauth.PhoneAuthProvider.credential( verificationId, verificationCode); assertEquals(fireauth.idp.ProviderId.PHONE, credential['providerId']); + assertEquals(fireauth.idp.SignInMethod.PHONE, credential['signInMethod']); + assertEquals( + fireauth.idp.SignInMethod.PHONE, + fireauth.PhoneAuthProvider['PHONE_SIGN_IN_METHOD']); assertObjectEquals({ 'providerId': fireauth.idp.ProviderId.PHONE, 'verificationId': verificationId, @@ -1819,6 +2009,10 @@ function testPhoneAuthCredential_temporaryProof() { }); assertEquals(fireauth.idp.ProviderId.PHONE, credential['providerId']); + assertEquals(fireauth.idp.SignInMethod.PHONE, credential['signInMethod']); + assertEquals( + fireauth.idp.SignInMethod.PHONE, + fireauth.PhoneAuthProvider['PHONE_SIGN_IN_METHOD']); assertObjectEquals({ 'providerId': fireauth.idp.ProviderId.PHONE, 'temporaryProof': temporaryProof, diff --git a/packages/auth/test/error_test.js b/packages/auth/test/error_test.js index 0a901b27a91..eca90841c33 100644 --- a/packages/auth/test/error_test.js +++ b/packages/auth/test/error_test.js @@ -92,13 +92,16 @@ function testAuthErrorWithCredential() { assertEquals( 'Account already exists, please confirm and link.', error['message']); // Test toJSON(). - assertObjectEquals({ - code: error['code'], - message: error['message'], - email: 'user@example.com', - providerId: 'facebook.com', - oauthAccessToken: 'ACCESS_TOKEN' - }, error.toJSON()); + assertObjectEquals( + { + code: error['code'], + message: error['message'], + email: 'user@example.com', + providerId: 'facebook.com', + oauthAccessToken: 'ACCESS_TOKEN', + signInMethod: fireauth.FacebookAuthProvider['FACEBOOK_SIGN_IN_METHOD'] + }, + error.toJSON()); assertEquals(JSON.stringify(error), JSON.stringify(error.toJSON())); } @@ -202,7 +205,8 @@ function testAuthErrorWithCredential_toPlainObject() { 'email': 'user@example.com', 'message': 'Account already exists, please confirm and link.', 'providerId': 'facebook.com', - 'oauthAccessToken': 'ACCESS_TOKEN' + 'oauthAccessToken': 'ACCESS_TOKEN', + 'signInMethod': fireauth.FacebookAuthProvider['FACEBOOK_SIGN_IN_METHOD'] }; assertObjectEquals( errorObject, @@ -240,7 +244,8 @@ function testAuthErrorWithCredential_toPlainObject() { 'email': 'user@example.com', 'message': 'The email address is already in use by another account.', 'providerId': 'google.com', - 'oauthIdToken': 'ID_TOKEN' + 'oauthIdToken': 'ID_TOKEN', + 'signInMethod': fireauth.GoogleAuthProvider['GOOGLE_SIGN_IN_METHOD'] }; assertObjectEquals( errorObject3, diff --git a/packages/auth/test/rpchandler_test.js b/packages/auth/test/rpchandler_test.js index 61683157519..aaf8f7dbc16 100644 --- a/packages/auth/test/rpchandler_test.js +++ b/packages/auth/test/rpchandler_test.js @@ -1641,6 +1641,132 @@ function testIsOAuthClientIdValid_error() { } +function testFetchSignInMethodsForIdentifier() { + var expectedResponse = ['google.com', 'emailLink']; + var serverResponse = { + 'kind': 'identitytoolkit#CreateAuthUriResponse', + 'allProviders': [ + 'google.com', + "password" + ], + 'signinMethods': [ + 'google.com', + 'emailLink' + ], + 'registered': true, + 'sessionId': 'AXT8iKR2x89y2o7zRnroApio_uo' + }; + var identifier = 'user@example.com'; + + asyncTestCase.waitForSignals(1); + var request = {'identifier': identifier, 'continueUri': CURRENT_URL}; + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/' + + 'createAuthUri?key=apiKey', + 'POST', + goog.json.serialize(request), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + serverResponse); + rpcHandler.fetchSignInMethodsForIdentifier(identifier) + .then(function(response) { + assertArrayEquals(expectedResponse, response); + asyncTestCase.signal(); + }); +} + + +function testFetchSignInMethodsForIdentifier_noSignInMethodsReturned() { + var expectedResponse = []; + var serverResponse = { + 'kind': 'identitytoolkit#CreateAuthUriResponse', + 'registered': true, + 'sessionId': 'AXT8iKR2x89y2o7zRnroApio_uo' + }; + var identifier = 'user@example.com'; + + asyncTestCase.waitForSignals(1); + var request = {'identifier': identifier, 'continueUri': CURRENT_URL}; + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/' + + 'createAuthUri?key=apiKey', + 'POST', + goog.json.serialize(request), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + serverResponse); + rpcHandler.fetchSignInMethodsForIdentifier(identifier) + .then(function(response) { + assertArrayEquals(expectedResponse, response); + asyncTestCase.signal(); + }); +} + + +function testFetchSignInMethodsForIdentifier_nonHttpOrHttps() { + // Simulate non http or https current URL. + stubs.replace(fireauth.util, 'getCurrentUrl', function() { + return 'chrome-extension://234567890/index.html'; + }); + stubs.replace(fireauth.util, 'getCurrentScheme', function() { + return 'chrome-extension:'; + }); + var expectedResponse = ['google.com', 'emailLink']; + var serverResponse = { + 'kind': 'identitytoolkit#CreateAuthUriResponse', + 'allProviders': [ + 'google.com', + 'password' + ], + 'signinMethods': [ + 'google.com', + 'emailLink' + ], + 'registered': true, + 'sessionId': 'AXT8iKR2x89y2o7zRnroApio_uo' + }; + var identifier = 'user@example.com'; + + asyncTestCase.waitForSignals(1); + var request = { + 'identifier': identifier, + // A fallback HTTP URL should be used. + 'continueUri': 'http://localhost' + }; + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/' + + 'createAuthUri?key=apiKey', + 'POST', + goog.json.serialize(request), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + serverResponse); + rpcHandler.fetchSignInMethodsForIdentifier(identifier) + .then(function(response) { + assertArrayEquals(expectedResponse, response); + asyncTestCase.signal(); + }); +} + + +function testFetchSignInMethodsForIdentifier_serverCaughtError() { + var identifier = 'user@example.com'; + var requestBody = {'identifier': identifier, 'continueUri': CURRENT_URL}; + var expectedUrl = 'https://www.googleapis.com/identitytoolkit/v3/' + + 'relyingparty/createAuthUri?key=apiKey'; + + var errorMap = {}; + errorMap[fireauth.RpcHandler.ServerError.INVALID_IDENTIFIER] = + fireauth.authenum.Error.INVALID_EMAIL; + errorMap[fireauth.RpcHandler.ServerError.MISSING_CONTINUE_URI] = + fireauth.authenum.Error.INTERNAL_ERROR; + + assertServerErrorsAreHandled(function() { + return rpcHandler.fetchSignInMethodsForIdentifier(identifier); + }, errorMap, expectedUrl, requestBody); +} + + function testFetchProvidersForIdentifier() { var expectedResponse = [ 'google.com', @@ -2088,6 +2214,107 @@ function testVerifyCustomToken_unknownServerResponse() { } +function testEmailLinkSignIn_success() { + var expectedResponse = {'idToken': 'ID_TOKEN'}; + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/emailLinkSi' + + 'gnin?key=apiKey', + 'POST', + goog.json.serialize({ + 'email': 'user@example.com', + 'oobCode': 'OTP_CODE', + 'returnSecureToken': true + }), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + expectedResponse); + rpcHandler.emailLinkSignIn('user@example.com', 'OTP_CODE') + .then(function(response) { + assertObjectEquals(expectedResponse, response); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignIn_serverCaughtError() { + var expectedUrl = 'https://www.googleapis.com/identitytoolkit/v3/' + + 'relyingparty/emailLinkSignin?key=apiKey'; + var email = 'user@example.com'; + var oobCode = 'OTP_CODE'; + var requestBody = { + 'email': email, + 'oobCode': oobCode, + 'returnSecureToken': true + }; + var errorMap = {}; + errorMap[fireauth.RpcHandler.ServerError.INVALID_EMAIL] = + fireauth.authenum.Error.INVALID_EMAIL; + errorMap[fireauth.RpcHandler.ServerError.TOO_MANY_ATTEMPTS_TRY_LATER] = + fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER; + errorMap[fireauth.RpcHandler.ServerError.USER_DISABLED] = + fireauth.authenum.Error.USER_DISABLED; + + assertServerErrorsAreHandled(function() { + return rpcHandler.emailLinkSignIn(email, oobCode); + }, errorMap, expectedUrl, requestBody); +} + + +/** + * Tests invalid server response emailLinkSignIn error. + */ +function testEmailLinkSignIn_unknownServerResponse() { + // Test when server returns unexpected response with no error message. + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/emailLinkSi' + + 'gnin?key=apiKey', + 'POST', + goog.json.serialize({ + 'email': 'user@example.com', + 'oobCode': 'OTP_CODE', + 'returnSecureToken': true + }), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + {}); + rpcHandler.emailLinkSignIn('user@example.com', 'OTP_CODE') + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + error); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignIn_emptyActionCodeError() { + // Test when empty action code is passed in emailLinkSignIn request. + asyncTestCase.waitForSignals(1); + // Test when request is invalid. + rpcHandler.emailLinkSignIn('user@example.com', '').thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), error); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignIn_invalidEmailError() { + // Test when invalid email is passed in emailLinkSignIn request. + asyncTestCase.waitForSignals(1); + // Test when request is invalid. + rpcHandler.emailLinkSignIn('user@invalid', 'OTP_CODE') + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INVALID_EMAIL), + error); + asyncTestCase.signal(); + }); +} + + function testVerifyPassword_success() { var expectedResponse = { 'idToken': 'ID_TOKEN' @@ -3093,6 +3320,189 @@ function testVerifyAssertionForExisting_serverCaughtError() { } +/** + * Tests successful sendSignInLinkToEmail RPC call with action code settings. + */ +function testSendSignInLinkToEmail_success_actionCodeSettings() { + var userEmail = 'user@example.com'; + var additionalRequestData = { + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }; + var expectedResponse = {'email': userEmail}; + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobCon' + + 'firmationCode?key=apiKey', + 'POST', + goog.json.serialize({ + 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN, + 'email': userEmail, + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + expectedResponse); + rpcHandler.sendSignInLinkToEmail('user@example.com', additionalRequestData) + .then(function(email) { + assertEquals(userEmail, email); + asyncTestCase.signal(); + }); +} + + +/** + * Tests successful sendSignInLinkToEmail RPC call with custom locale. + */ +function testSendSignInLinkToEmail_success_customLocale() { + var userEmail = 'user@example.com'; + var additionalRequestData = { + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }; + var expectedResponse = {'email': userEmail}; + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobCon' + + 'firmationCode?key=apiKey', + 'POST', + goog.json.serialize({ + 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN, + 'email': userEmail, + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }), + {'Content-Type': 'application/json', 'X-Firebase-Locale': 'es'}, + delay, + expectedResponse); + rpcHandler.updateCustomLocaleHeader('es'); + rpcHandler.sendSignInLinkToEmail('user@example.com', additionalRequestData) + .then(function(email) { + assertEquals(userEmail, email); + asyncTestCase.signal(); + }); +} + + +/** + * Tests invalid email sendSignInLinkToEmail error. + */ +function testSendSignInLinkToEmail_invalidEmailError() { + // Test when invalid email is passed in getOobCode request. + var additionalRequestData = { + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }; + asyncTestCase.waitForSignals(1); + // Test when request is invalid. + rpcHandler.sendSignInLinkToEmail('user@invalid', additionalRequestData) + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INVALID_EMAIL), + error); + asyncTestCase.signal(); + }); +} + + +/** + * Tests invalid response sendSignInLinkToEmail error. + */ +function testSendSignInLinkToEmail_unknownServerResponse() { + var userEmail = 'user@example.com'; + var additionalRequestData = { + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }; + var expectedResponse = {}; + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobCon' + + 'firmationCode?key=apiKey', + 'POST', + goog.json.serialize({ + 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN, + 'email': userEmail, + 'continueUrl': 'https://www.example.com/?state=abc', + 'iOSBundleId': 'com.example.ios', + 'androidPackageName': 'com.example.android', + 'androidInstallApp': true, + 'androidMinimumVersion': '12', + 'canHandleCodeInApp': true + }), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + expectedResponse); + rpcHandler.sendSignInLinkToEmail(userEmail, additionalRequestData) + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + error); + asyncTestCase.signal(); + }); +} + + +/** + * Tests server side sendSignInLinkToEmail error. + */ +function testSendSignInLinkToEmail_serverCaughtError() { + var userEmail = 'user@example.com'; + var expectedUrl = 'https://www.googleapis.com/identitytoolkit/v3/relyin' + + 'gparty/getOobConfirmationCode?key=apiKey'; + var requestBody = { + 'requestType': fireauth.RpcHandler.GetOobCodeRequestType.EMAIL_SIGNIN, + 'email': userEmail + }; + var errorMap = {}; + errorMap[fireauth.RpcHandler.ServerError.INVALID_RECIPIENT_EMAIL] = + fireauth.authenum.Error.INVALID_RECIPIENT_EMAIL; + errorMap[fireauth.RpcHandler.ServerError.INVALID_SENDER] = + fireauth.authenum.Error.INVALID_SENDER; + errorMap[fireauth.RpcHandler.ServerError.INVALID_MESSAGE_PAYLOAD] = + fireauth.authenum.Error.INVALID_MESSAGE_PAYLOAD; + + // Action code settings related errors. + errorMap[fireauth.RpcHandler.ServerError.INVALID_CONTINUE_URI] = + fireauth.authenum.Error.INVALID_CONTINUE_URI; + errorMap[fireauth.RpcHandler.ServerError.MISSING_ANDROID_PACKAGE_NAME] = + fireauth.authenum.Error.MISSING_ANDROID_PACKAGE_NAME; + errorMap[fireauth.RpcHandler.ServerError.MISSING_IOS_BUNDLE_ID] = + fireauth.authenum.Error.MISSING_IOS_BUNDLE_ID; + errorMap[fireauth.RpcHandler.ServerError.UNAUTHORIZED_DOMAIN] = + fireauth.authenum.Error.UNAUTHORIZED_DOMAIN; + + assertServerErrorsAreHandled(function() { + return rpcHandler.sendSignInLinkToEmail(userEmail, {}); + }, errorMap, expectedUrl, requestBody); +} + + /** * Tests successful sendPasswordResetEmail RPC call with action code settings. */ @@ -4151,6 +4561,131 @@ function testUpdateEmailAndPassword_noPassword() { } +function testEmailLinkSignInForLinking_success() { + var expectedResponse = {'idToken': 'ID_TOKEN'}; + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/emailLinkSi' + + 'gnin?key=apiKey', + 'POST', + goog.json.serialize({ + 'idToken': 'ID_TOKEN', + 'email': 'user@example.com', + 'oobCode': 'OTP_CODE', + 'returnSecureToken': true + }), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + expectedResponse); + rpcHandler.emailLinkSignInForLinking( + 'ID_TOKEN', 'user@example.com', 'OTP_CODE') + .then(function(response) { + assertEquals('ID_TOKEN', response['idToken']); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignInForLinking_serverCaughtError() { + var expectedUrl = 'https://www.googleapis.com/identitytoolkit/v3/' + + 'relyingparty/emailLinkSignin?key=apiKey'; + var email = 'user@example.com'; + var oobCode = 'OTP_CODE'; + var id_token = 'ID_TOKEN'; + var requestBody = { + 'idToken': 'ID_TOKEN', + 'email': email, + 'oobCode': oobCode, + 'returnSecureToken': true + }; + var errorMap = {}; + errorMap[fireauth.RpcHandler.ServerError.INVALID_EMAIL] = + fireauth.authenum.Error.INVALID_EMAIL; + errorMap[fireauth.RpcHandler.ServerError.TOO_MANY_ATTEMPTS_TRY_LATER] = + fireauth.authenum.Error.TOO_MANY_ATTEMPTS_TRY_LATER; + errorMap[fireauth.RpcHandler.ServerError.USER_DISABLED] = + fireauth.authenum.Error.USER_DISABLED; + + assertServerErrorsAreHandled(function() { + return rpcHandler.emailLinkSignInForLinking(id_token, email, oobCode); + }, errorMap, expectedUrl, requestBody); +} + + +/** + * Tests invalid server response emailLinkSignInForLinking error. + */ +function testEmailLinkSignInForLinking_unknownServerResponse() { + // Test when server returns unexpected response with no error message. + asyncTestCase.waitForSignals(1); + assertSendXhrAndRunCallback( + 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/emailLinkSi' + + 'gnin?key=apiKey', + 'POST', + goog.json.serialize({ + 'idToken': 'ID_TOKEN', + 'email': 'user@example.com', + 'oobCode': 'OTP_CODE', + 'returnSecureToken': true + }), + fireauth.RpcHandler.DEFAULT_FIREBASE_HEADERS_, + delay, + {}); + rpcHandler.emailLinkSignInForLinking( + 'ID_TOKEN', 'user@example.com', 'OTP_CODE') + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + error); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignInForLinking_emptyActionCodeError() { + // Test when empty action code is passed in emailLinkSignInForLinking request. + asyncTestCase.waitForSignals(1); + // Test when request is invalid. + rpcHandler.emailLinkSignInForLinking('ID_TOKEN', 'user@example.com', '') + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + error); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignInForLinking_invalidEmailError() { + // Test when invalid email is passed in emailLinkSignInForLinking request. + asyncTestCase.waitForSignals(1); + // Test when request is invalid. + rpcHandler.emailLinkSignInForLinking( + 'ID_TOKEN', 'user@invalid', 'OTP_CODE') + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INVALID_EMAIL), + error); + asyncTestCase.signal(); + }); +} + + +function testEmailLinkSignInForLinking_emptyIdTokenError() { + // Test when empty ID token is passed in emailLinkSignInForLinking request. + asyncTestCase.waitForSignals(1); + // Test when request is invalid. + rpcHandler.emailLinkSignInForLinking( + '', 'user@example.com', 'OTP_CODE') + .thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals( + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + error); + asyncTestCase.signal(); + }); +} + + function testInvokeRpc() { asyncTestCase.waitForSignals(3); var request = { diff --git a/packages/firebase/externs/firebase-auth-externs.js b/packages/firebase/externs/firebase-auth-externs.js index 4cd37997a16..d6ec6295af0 100644 --- a/packages/firebase/externs/firebase-auth-externs.js +++ b/packages/firebase/externs/firebase-auth-externs.js @@ -75,6 +75,16 @@ firebase.auth.AuthCredential = function() {}; */ firebase.auth.AuthCredential.prototype.providerId; +/** + * The authentication sign in method for the credential. + * For example, 'password', or 'emailLink. This corresponds to the sign-in + * method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.AuthCredential.prototype.signInMethod; + /** * Interface that represents the OAuth credentials returned by an OAuth * provider. Implementations specify the details about each auth provider's @@ -843,6 +853,8 @@ firebase.auth.ActionCodeInfo.prototype.data; * {@link firebase.User#sendEmailVerification}. *
  • `RECOVER_EMAIL`: email change revocation code generated via * {@link firebase.User#updateEmail}.
  • + *
  • `EMAIL_SIGNIN`: email sign in code generated via + * {@link firebase.auth.Auth#sendSignInLinkToEmail}.
  • *
* * @type {string} @@ -1165,6 +1177,31 @@ firebase.auth.Auth.prototype.createUserWithEmailAndPassword = function( */ firebase.auth.Auth.prototype.fetchProvidersForEmail = function(email) {}; +/** + * Gets the list of possible sign in methods for the given email address. This + * is useful to differentiate methods of sign-in for the same provider, + * eg. `EmailAuthProvider` which has 2 methods of sign-in, email/password and + * email/link. + * + *

Error Codes

+ *
+ *
auth/invalid-email
+ *
Thrown if the email address is not valid.
+ *
+ * + * @param {string} email An email address. + * @return {!firebase.Promise>} + */ +firebase.auth.Auth.prototype.fetchSignInMethodsForEmail = function(email) {}; + +/** + * Checks if an incoming link is a sign-in with email link. + * + * @param {string} emailLink Sign-in email link. + * @return {boolean} Whether the link is a sign-in with email link. + */ +firebase.auth.Auth.prototype.isSignInWithEmailLink = function(emailLink) {}; + /** * Adds an observer for changes to the user's sign-in state. * @@ -1222,6 +1259,82 @@ firebase.auth.Auth.prototype.onIdTokenChanged = function( completed ) {}; +/** + * Sends a sign-in email link to the user with the specified email. + * + * The sign-in operation has to always be completed in the app unlike other out + * of band email actions (password reset and email verifications). This is + * because, at the end of the flow, the user is expected to be signed in and + * their Auth state persisted within the app. + * + * To complete sign in with the email link, call + * {@link firebase.auth.Auth#signInWithEmailLink} with the email address and + * the email link supplied in the email sent to the user. + * + *

Error Codes

+ *
+ *
auth/argument-error
+ *
Thrown if handleCodeInApp is false.
+ *
auth/invalid-email
+ *
Thrown if the email address is not valid.
+ *
auth/missing-android-pkg-name
+ *
An Android package name must be provided if the Android app is required + * to be installed.
+ *
auth/missing-continue-uri
+ *
A continue URL must be provided in the request.
+ *
auth/missing-ios-bundle-id
+ *
An iOS Bundle ID must be provided if an App Store ID is provided.
+ *
auth/invalid-continue-uri
+ *
The continue URL provided in the request is invalid.
+ *
auth/unauthorized-continue-uri
+ *
The domain of the continue URL is not whitelisted. Whitelist + * the domain in the Firebase console.
+ *
+ * + * @example + * var actionCodeSettings = { + * // The URL to redirect to for sign-in completion. This is also the deep + * // link for mobile redirects. The domain (www.example.com) for this URL + * // must be whitelisted in the Firebase Console. + * url: 'https://www.example.com/finishSignUp?cartId=1234', + * iOS: { + * bundleId: 'com.example.ios' + * }, + * android: { + * packageName: 'com.example.android', + * installApp: true, + * minimumVersion: '12' + * }, + * // This must be true. + * handleCodeInApp: true + * }; + * firebase.auth().sendSignInLinkToEmail('user@example.com', actionCodeSettings) + * .then(function() { + * // The link was successfully sent. Inform the user. Save the email + * // locally so you don't need to ask the user for it again if they open + * // the link on the same device. + * }) + * .catch(function(error) { + * // Some error occurred, you can inspect the code: error.code + * }); + * + * @param {string} email The email account to sign in with. + * @param {!firebase.auth.ActionCodeSettings} actionCodeSettings The action + * code settings. The action code settings which provides Firebase with + * instructions on how to construct the email link. This includes the + * sign in completion URL or the deep link for mobile redirects, the mobile + * apps to use when the sign-in link is opened on an Android or iOS device. + * Mobile app redirects will only be applicable if the developer configures + * and accepts the Firebase Dynamic Links terms of condition. + * The Android package name and iOS bundle ID will be respected only if they + * are configured in the same Firebase Auth project used. + * @return {!firebase.Promise} + */ +firebase.auth.Auth.prototype.sendSignInLinkToEmail = function( + email, + actionCodeSettings +) {}; + /** * Sends a password reset email to the given email address. * @@ -1623,6 +1736,45 @@ firebase.auth.Auth.prototype.signInWithEmailAndPassword = function( password ) {}; +/** + * Asynchronously signs in using an email and sign-in email link. If no link + * is passed, the link is inferred from the current URL. + * + * Fails with an error if the email address is invalid or OTP in email link + * expires. + * + * Note: Confirm the link is a sign-in email link before calling this method + * {@link firebase.auth.Auth#isSignInWithEmailLink}. + * + *

Error Codes

+ *
+ *
auth/expired-action-code
+ *
Thrown if OTP in email link expires.
+ *
auth/invalid-email
+ *
Thrown if the email address is not valid.
+ *
auth/user-disabled
+ *
Thrown if the user corresponding to the given email has been + * disabled.
+ *
+ * + * @example + * firebase.auth().signInWithEmailLink(email, emailLink) + * .catch(function(error) { + * // Some error occurred, you can inspect the code: error.code + * // Common errors could be invalid email and invalid or expired OTPs. + * }); + * + * @param {string} email The email account to sign in with. + * @param {?string=} emailLink The optional link which contains the OTP needed + * to complete the sign in with email link. If not specified, the current + * URL is used instead. + * @return {!firebase.Promise} + */ +firebase.auth.Auth.prototype.signInWithEmailLink = function( + email, + emailLink +) {}; + /** * Asynchronously signs in using a phone number. This method sends a code via * SMS to the given phone number, and returns a @@ -2025,6 +2177,14 @@ firebase.auth.FacebookAuthProvider = function() {}; /** @type {string} */ firebase.auth.FacebookAuthProvider.PROVIDER_ID; +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD; + /** * @example * var cred = firebase.auth.FacebookAuthProvider.credential( @@ -2133,6 +2293,14 @@ firebase.auth.GithubAuthProvider = function() {}; /** @type {string} */ firebase.auth.GithubAuthProvider.PROVIDER_ID; +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.GithubAuthProvider.GITHUB_SIGN_IN_METHOD; + /** * @example * var cred = firebase.auth.FacebookAuthProvider.credential( @@ -2211,6 +2379,14 @@ firebase.auth.GoogleAuthProvider = function() {}; /** @type {string} */ firebase.auth.GoogleAuthProvider.PROVIDER_ID; +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD; + /** * Creates a credential for Google. At least one of ID token and access token * is required. @@ -2293,6 +2469,14 @@ firebase.auth.TwitterAuthProvider = function() {}; /** @type {string} */ firebase.auth.TwitterAuthProvider.PROVIDER_ID; +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.TwitterAuthProvider.TWITTER_SIGN_IN_METHOD; + /** * @param {string} token Twitter access token. * @param {string} secret Twitter secret. @@ -2331,6 +2515,22 @@ firebase.auth.EmailAuthProvider = function() {}; /** @type {string} */ firebase.auth.EmailAuthProvider.PROVIDER_ID; +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD; + +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD; + /** * @example * var cred = firebase.auth.EmailAuthProvider.credential( @@ -2344,6 +2544,25 @@ firebase.auth.EmailAuthProvider.PROVIDER_ID; */ firebase.auth.EmailAuthProvider.credential = function(email, password) {}; +/** + * Initialize an `EmailAuthProvider` credential using an email and an email link + * after a sign in with email link operation. + * + * @example + * var cred = firebase.auth.EmailAuthProvider.credentialWithLink( + * email, + * emailLink + * ); + * + * @param {string} email Email address. + * @param {string} emailLink Sign-in email link. + * @return {!firebase.auth.AuthCredential} The auth provider credential. + */ +firebase.auth.EmailAuthProvider.credentialWithLink = function( + email, + emailLink +) {}; + /** @type {string} */ firebase.auth.EmailAuthProvider.prototype.providerId; @@ -2376,6 +2595,14 @@ firebase.auth.PhoneAuthProvider = function(auth) {}; /** @type {string} */ firebase.auth.PhoneAuthProvider.PROVIDER_ID; +/** + * This corresponds to the sign-in method identifier as returned in + * {@link firebase.auth.Auth#fetchSignInMethodsForEmail}. + * + * @type {string} + */ +firebase.auth.PhoneAuthProvider.PHONE_SIGN_IN_METHOD; + /** * Creates a phone auth credential, given the verification ID from * {@link firebase.auth.PhoneAuthProvider#verifyPhoneNumber} and the code From 1b3ba41f7c5207907a32601e552168e29281948e Mon Sep 17 00:00:00 2001 From: wti806 <32399754+wti806@users.noreply.github.com> Date: Thu, 15 Mar 2018 10:18:10 -0700 Subject: [PATCH 32/34] Refactor Auth storage test (#530) * refactored storage test * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: Prettier Code Styling * migrate storage from localstorage to indexedDb * added worker compatibility, exposed finally, updated error message * appended photo size for google hosted image --- packages/auth/demo/public/script.js | 10 +- packages/auth/src/authstorage.js | 62 +++- packages/auth/src/error_auth.js | 4 +- packages/auth/src/exports_auth.js | 3 + .../auth/src/iframeclient/iframewrapper.js | 15 +- .../recaptchaverifier/recaptchaverifier.js | 12 +- packages/auth/src/rpchandler.js | 62 ++-- packages/auth/src/storage/asyncstorage.js | 2 + packages/auth/src/storage/factory.js | 11 +- packages/auth/src/storage/indexeddb.js | 2 + packages/auth/src/storage/inmemorystorage.js | 20 +- packages/auth/src/storage/localstorage.js | 2 + packages/auth/src/storage/mockstorage.js | 101 +++++++ packages/auth/src/storage/nullstorage.js | 3 + packages/auth/src/storage/sessionstorage.js | 2 + packages/auth/src/storage/storage.js | 19 ++ packages/auth/src/storageusermanager.js | 13 +- packages/auth/src/utils.js | 108 +++++-- packages/auth/test/auth_test.js | 151 ++++------ packages/auth/test/autheventmanager_test.js | 20 +- packages/auth/test/authstorage_test.js | 281 +++++++++++++++--- packages/auth/test/cordovahandler_test.js | 22 +- .../recaptchaverifier_test.js | 45 +++ packages/auth/test/rpchandler_test.js | 137 ++++++++- .../auth/test/storage/asyncstorage_test.js | 2 + packages/auth/test/storage/factory_test.js | 61 +++- packages/auth/test/storage/indexeddb_test.js | 2 + .../auth/test/storage/inmemorystorage_test.js | 2 + .../auth/test/storage/localstorage_test.js | 2 + .../auth/test/storage/mockstorage_test.js | 128 ++++++++ .../auth/test/storage/nullstorage_test.js | 2 + .../auth/test/storage/sessionstorage_test.js | 2 + .../auth/test/storageautheventmanager_test.js | 108 ++++--- .../test/storageoauthhandlermanager_test.js | 57 ++-- .../storagependingredirectmanager_test.js | 28 +- .../test/storageredirectusermanager_test.js | 30 +- packages/auth/test/storageusermanager_test.js | 222 +++++++++----- packages/auth/test/testhelper.js | 36 ++- packages/auth/test/utils_test.js | 219 ++++++++++++++ 39 files changed, 1625 insertions(+), 383 deletions(-) create mode 100644 packages/auth/src/storage/mockstorage.js create mode 100644 packages/auth/test/storage/mockstorage_test.js diff --git a/packages/auth/demo/public/script.js b/packages/auth/demo/public/script.js index c62c2408a92..d44c88f1ceb 100644 --- a/packages/auth/demo/public/script.js +++ b/packages/auth/demo/public/script.js @@ -153,7 +153,15 @@ function refreshUserData() { $('input.profile-name').val(user.displayName); $('input.photo-url').val(user.photoURL); if (user.photoURL != null) { - $('img.profile-image').attr('src', user.photoURL).show(); + var photoURL = user.photoURL; + // Append size to the photo URL for Google hosted images to avoid requesting + // the image with its original resolution (using more bandwidth than needed) + // when it is going to be presented in smaller size. + if ((photoURL.indexOf('googleusercontent.com') != -1) || + (photoURL.indexOf('ggpht.com') != -1)) { + photoURL = photoURL + '?sz=' + $('img.profile-image').height(); + } + $('img.profile-image').attr('src', photoURL).show(); } else { $('img.profile-image').hide(); } diff --git a/packages/auth/src/authstorage.js b/packages/auth/src/authstorage.js index 405b7b8e276..ef187dcce22 100644 --- a/packages/auth/src/authstorage.js +++ b/packages/auth/src/authstorage.js @@ -26,6 +26,7 @@ goog.provide('fireauth.authStorage.Persistence'); goog.require('fireauth.AuthError'); goog.require('fireauth.authenum.Error'); goog.require('fireauth.storage.Factory'); +goog.require('fireauth.storage.Storage'); goog.require('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.array'); @@ -235,6 +236,12 @@ fireauth.authStorage.Manager.getInstance = function() { }; +/** Clears storage manager instances. This is used for testing. */ +fireauth.authStorage.Manager.clear = function() { + fireauth.authStorage.Manager.instance_ = null; +}; + + /** * Returns the storage corresponding to the specified persistence. * @param {!fireauth.authStorage.Persistence} persistent The type of storage @@ -270,6 +277,55 @@ fireauth.authStorage.Manager.prototype.getKeyName_ = function(dataKey, opt_id) { }; +/** + * Migrates window.localStorage to the provided persistent storage. + * @param {fireauth.authStorage.Key} dataKey The key under which the persistent + * value is supposed to be stored. + * @param {?string=} opt_id When operating in multiple app mode, this ID + * associates storage values with specific apps. + * @return {!goog.Promise} A promise that resolves when the data stored + * in window.localStorage is migrated to the provided persistent storage + * identified by the provided data key. + */ +fireauth.authStorage.Manager.prototype.migrateFromLocalStorage = + function(dataKey, opt_id) { + var self = this; + var key = this.getKeyName_(dataKey, opt_id); + var storage = this.getStorage_(dataKey.persistent); + // Get data stored in the default persistent storage identified by dataKey. + return this.get(dataKey, opt_id).then(function(response) { + // Get the stored value in window.localStorage if available. + var oldStorageValue = null; + try { + oldStorageValue = fireauth.util.parseJSON( + goog.global['localStorage']['getItem'](key)); + } catch (e) { + // Set value as null. This will resolve the promise immediately. + } + // If data is stored in window.localStorage but no data is available in + // default persistent storage, migrate data from window.localStorage to + // default persistent storage. + if (oldStorageValue && !response) { + // This condition may fail in situations where a user opens a tab with + // an old version while using a tab with a new version, or when a + // developer switches back and forth between and old and new version of + // the library. + goog.global['localStorage']['removeItem'](key); + // Migrate the value to new default persistent storage. + return self.set(dataKey, oldStorageValue, opt_id); + } else if (oldStorageValue && + response && + storage.type != fireauth.storage.Storage.Type.LOCAL_STORAGE) { + // Data stored in both localStorage and new persistent storage (eg. + // indexedDB) for some reason. + // This could happen if the developer is migrating back and forth. + // The new default persistent storage (eg. indexedDB) takes precedence. + goog.global['localStorage']['removeItem'](key); + } + }); +}; + + /** * Gets the stored value from the corresponding storage. * @param {fireauth.authStorage.Key} dataKey The key under which the value is @@ -404,9 +460,9 @@ fireauth.authStorage.Manager.prototype.startListeners_ = function() { // TODO: refactor this implementation to be handled by the underlying // storage mechanism. if (!this.runsInBackground_ && - // Add an exception for IE11 and Edge browsers, we should stick to - // indexedDB in that case. - !fireauth.util.isLocalStorageNotSynchronized() && + // Add an exception for browsers that persist storage with indexedDB, we + // should stick with indexedDB listener implementation in that case. + !fireauth.util.persistsStorageWithIndexedDB() && // Confirm browser web storage is supported as polling relies on it. this.webStorageSupported_) { this.startManualListeners_(); diff --git a/packages/auth/src/error_auth.js b/packages/auth/src/error_auth.js index 0af4a05abf9..25dc4f096e3 100644 --- a/packages/auth/src/error_auth.js +++ b/packages/auth/src/error_auth.js @@ -240,7 +240,9 @@ fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_APP_CREDENTIAL] = fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_APP_ID] = 'The mobile app identifier is not registed for the current project.'; fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_AUTH] = - 'The user\'s credential is no longer valid. The user must sign in again.'; + 'This user\'s credential isn\'t valid for this project. This can happen ' + + 'if the user\'s token has been tampered with, or if the user isn\'t for ' + + 'the project associated with this API key.'; fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_AUTH_EVENT] = 'An internal error has occurred.'; fireauth.AuthError.MESSAGES_[fireauth.authenum.Error.INVALID_CODE] = diff --git a/packages/auth/src/exports_auth.js b/packages/auth/src/exports_auth.js index 496cb50fe1a..ebaa755de77 100644 --- a/packages/auth/src/exports_auth.js +++ b/packages/auth/src/exports_auth.js @@ -320,6 +320,9 @@ fireauth.exportlib.exportPrototypeMethods( fireauth.exportlib.exportPrototypeMethods( goog.Promise.prototype, { + thenAlways: { + name: 'finally' + }, thenCatch: { name: 'catch' }, diff --git a/packages/auth/src/iframeclient/iframewrapper.js b/packages/auth/src/iframeclient/iframewrapper.js index c92d289b617..25298bff318 100644 --- a/packages/auth/src/iframeclient/iframewrapper.js +++ b/packages/auth/src/iframeclient/iframewrapper.js @@ -174,10 +174,12 @@ fireauth.iframeclient.IframeWrapper.prototype.registerEvent = this.onIframeOpen_.then(function() { self.iframe_.register( eventName, - handler, + /** @type {function(this:gapi.iframes.Iframe, + * *, gapi.iframes.Iframe): *} + */ (handler), /** @type {!gapi.iframes.IframesFilter} */ ( - fireauth.util.getObjectRef( - 'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER'))); + fireauth.util.getObjectRef( + 'gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER'))); }); }; @@ -191,12 +193,15 @@ fireauth.iframeclient.IframeWrapper.prototype.unregisterEvent = function(eventName, handler) { var self = this; this.onIframeOpen_.then(function() { - self.iframe_.unregister(eventName, handler); + self.iframe_.unregister( + eventName, + /** @type {(function(this:gapi.iframes.Iframe, + * *, gapi.iframes.Iframe): *|undefined)} + */ (handler)); }); }; - /** @private @const {!goog.string.Const} The GApi loader URL. */ fireauth.iframeclient.IframeWrapper.GAPI_LOADER_SRC_ = goog.string.Const.from( 'https://apis.google.com/js/api.js?onload=%{onload}'); diff --git a/packages/auth/src/recaptchaverifier/recaptchaverifier.js b/packages/auth/src/recaptchaverifier/recaptchaverifier.js index 058d569a490..5ccd1b65a48 100644 --- a/packages/auth/src/recaptchaverifier/recaptchaverifier.js +++ b/packages/auth/src/recaptchaverifier/recaptchaverifier.js @@ -94,6 +94,13 @@ fireauth.BaseRecaptchaVerifier = function(apiKey, container, opt_parameters, this.isInvisible_ = this.parameters_[fireauth.BaseRecaptchaVerifier.ParamName.SIZE] === 'invisible'; + // Check if DOM is supported. + if (!fireauth.util.isDOMSupported()) { + throw new fireauth.AuthError( + fireauth.authenum.Error.OPERATION_NOT_SUPPORTED, + 'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' + + 'environment with DOM support.'); + } // reCAPTCHA container must be valid and if visible, not empty. // An invisible reCAPTCHA will not render in its container. That container // will execute the reCAPTCHA when it is clicked. @@ -257,9 +264,8 @@ fireauth.BaseRecaptchaVerifier.prototype.isReady_ = function() { this.cachedReadyPromise_ = this.registerPendingPromise_(goog.Promise.resolve() .then(function() { // Verify environment first. - // This is actually not enough as this could be triggered from a worker - // environment, but DOM ready should theoretically not resolve. - if (fireauth.util.isHttpOrHttps()) { + // Fail quickly from a worker environment or non-HTTP/HTTPS environment. + if (fireauth.util.isHttpOrHttps() && !fireauth.util.isWorker()) { // Wait for DOM to be ready as this feature depends on that. return fireauth.util.onDomReady(); } else { diff --git a/packages/auth/src/rpchandler.js b/packages/auth/src/rpchandler.js index 31e7c9213b5..41ec70105f9 100644 --- a/packages/auth/src/rpchandler.js +++ b/packages/auth/src/rpchandler.js @@ -35,6 +35,7 @@ goog.require('goog.html.TrustedResourceUrl'); goog.require('goog.json'); goog.require('goog.net.CorsXmlHttpFactory'); goog.require('goog.net.EventType'); +goog.require('goog.net.FetchXmlHttpFactory'); goog.require('goog.net.XhrIo'); goog.require('goog.net.XmlHttpFactory'); goog.require('goog.net.jsloader'); @@ -93,13 +94,6 @@ fireauth.XmlHttpFactory.prototype.internalGetOptions = function() { * @constructor */ fireauth.RpcHandler = function(apiKey, opt_config, opt_firebaseClientVersion) { - // Get XMLHttpRequest reference. - var XMLHttpRequest = fireauth.util.getXMLHttpRequest(); - if (!XMLHttpRequest) { - // In a Node.js environment, xmlhttprequest module needs to be required. - throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR, - 'The XMLHttpRequest compatibility library was not found.'); - } this.apiKey_ = apiKey; var config = opt_config || {}; this.secureTokenEndpoint_ = config['secureTokenEndpoint'] || @@ -131,10 +125,46 @@ fireauth.RpcHandler = function(apiKey, opt_config, opt_firebaseClientVersion) { // Log client version for securetoken server. this.secureTokenHeaders_['X-Client-Version'] = opt_firebaseClientVersion; } - /** @const @private {!goog.net.CorsXmlHttpFactory} The CORS XHR factory. */ - this.corsXhrFactory_ = new goog.net.CorsXmlHttpFactory(); - /** @const @private {!goog.net.XmlHttpFactory} The XHR factory. */ - this.xhrFactory_ = new fireauth.XmlHttpFactory(XMLHttpRequest); + + // Get XMLHttpRequest reference. + var XMLHttpRequest = fireauth.RpcHandler.getXMLHttpRequest(); + if (!XMLHttpRequest && !fireauth.util.isWorker()) { + // In a Node.js environment, xmlhttprequest module needs to be required. + throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR, + 'The XMLHttpRequest compatibility library was not found.'); + } + /** @private {!goog.net.XmlHttpFactory|undefined} The XHR factory. */ + this.rpcHandlerXhrFactory_ = undefined; + // Initialize XHR factory. CORS does not apply in native environments or + // workers so don't use CorsXmlHttpFactory in those cases. + if (fireauth.util.isWorker()) { + // For worker environment use FetchXmlHttpFactory. + this.rpcHandlerXhrFactory_ = new goog.net.FetchXmlHttpFactory( + /** @type {!WorkerGlobalScope} */ (self)); + } else if (fireauth.util.isNativeEnvironment()) { + // For Node.js, this is the polyfill library. For other environments, + // this is the native global XMLHttpRequest. + this.rpcHandlerXhrFactory_ = new fireauth.XmlHttpFactory( + /** @type {function(new:XMLHttpRequest)} */ (XMLHttpRequest)); + } else { + // CORS Browser environment. + this.rpcHandlerXhrFactory_ = new goog.net.CorsXmlHttpFactory(); + } +}; + + +/** + * @return {?function(new:XMLHttpRequest)|undefined} The current environment + * XMLHttpRequest. This is undefined for worker environment. + */ +fireauth.RpcHandler.getXMLHttpRequest = function() { + // In Node.js XMLHttpRequest is polyfilled. + var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE; + var XMLHttpRequest = goog.global['XMLHttpRequest'] || + (isNode && + firebase.INTERNAL['node'] && + firebase.INTERNAL['node']['XMLHttpRequest']); + return XMLHttpRequest; }; @@ -394,7 +424,7 @@ fireauth.RpcHandler.prototype.sendXhr_ = function( return; } var sendXhr; - if (fireauth.util.supportsCors()) { + if (fireauth.util.supportsCors() || fireauth.util.isWorker()) { // If supports CORS use goog.net.XhrIo. sendXhr = goog.bind(this.sendXhrUsingXhrIo_, this); } else { @@ -432,13 +462,7 @@ fireauth.RpcHandler.prototype.sendXhrUsingXhrIo_ = function( opt_data, opt_headers, opt_timeout) { - // Send XHR request. CORS does not apply in native environments so don't use - // CorsXmlHttpFactory in those cases. - // For a Node.js environment use the fireauth.XmlHttpFactory instance. - var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE; - var xhrIo = fireauth.util.isNativeEnvironment() ? - (isNode ? new goog.net.XhrIo(this.xhrFactory_) : new goog.net.XhrIo()) : - new goog.net.XhrIo(this.corsXhrFactory_); + var xhrIo = new goog.net.XhrIo(this.rpcHandlerXhrFactory_); // xhrIo.setTimeoutInterval not working in IE10 and IE11, handle manually. var requestTimeout; diff --git a/packages/auth/src/storage/asyncstorage.js b/packages/auth/src/storage/asyncstorage.js index e5cb678e20e..fc01b141b59 100644 --- a/packages/auth/src/storage/asyncstorage.js +++ b/packages/auth/src/storage/asyncstorage.js @@ -45,6 +45,8 @@ fireauth.storage.AsyncStorage = function(opt_asyncStorage) { throw new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR, 'The React Native compatibility library was not found.'); } + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.ASYNC_STORAGE; }; diff --git a/packages/auth/src/storage/factory.js b/packages/auth/src/storage/factory.js index bc5e9884c92..a8ee5b4996e 100644 --- a/packages/auth/src/storage/factory.js +++ b/packages/auth/src/storage/factory.js @@ -78,6 +78,10 @@ fireauth.storage.Factory.EnvConfig = { REACT_NATIVE: { persistent: fireauth.storage.AsyncStorage, temporary: fireauth.storage.NullStorage + }, + WORKER: { + persistent: fireauth.storage.LocalStorage, + temporary: fireauth.storage.NullStorage } }; @@ -95,6 +99,8 @@ fireauth.storage.Factory.getEnvConfig = function() { fireauth.storage.Factory.EnvConfig.NODE; envMap[fireauth.util.Env.REACT_NATIVE] = fireauth.storage.Factory.EnvConfig.REACT_NATIVE; + envMap[fireauth.util.Env.WORKER] = + fireauth.storage.Factory.EnvConfig.WORKER; return envMap[fireauth.util.getEnvironment()]; }; @@ -103,9 +109,8 @@ fireauth.storage.Factory.getEnvConfig = function() { * @return {!fireauth.storage.Storage} The persistent storage instance. */ fireauth.storage.Factory.prototype.makePersistentStorage = function() { - if (fireauth.util.isLocalStorageNotSynchronized()) { - // In a browser environment, when an iframe and a popup web storage are not - // synchronized, use the indexedDB fireauth.storage.Storage implementation. + if (fireauth.util.persistsStorageWithIndexedDB()) { + // If persistent storage is implemented using indexedDB, use indexedDB. return fireauth.storage.IndexedDB.getFireauthManager(); } return new this.env_.persistent(); diff --git a/packages/auth/src/storage/indexeddb.js b/packages/auth/src/storage/indexeddb.js index cd5176ef171..d333e79dd12 100644 --- a/packages/auth/src/storage/indexeddb.js +++ b/packages/auth/src/storage/indexeddb.js @@ -94,6 +94,8 @@ fireauth.storage.IndexedDB = function( /** @private {!IDBFactory} The indexedDB factory object. */ this.indexedDB_ = /** @type {!IDBFactory} */ ( opt_indexedDB || goog.global.indexedDB); + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.INDEXEDDB; }; diff --git a/packages/auth/src/storage/inmemorystorage.js b/packages/auth/src/storage/inmemorystorage.js index 5b751576dac..58d9f3c1b39 100644 --- a/packages/auth/src/storage/inmemorystorage.js +++ b/packages/auth/src/storage/inmemorystorage.js @@ -31,8 +31,10 @@ goog.require('goog.Promise'); * @implements {fireauth.storage.Storage} */ fireauth.storage.InMemoryStorage = function() { - /** @private {!Object} The object where we store values. */ - this.storage_ = {}; + /** @protected {!Object} The object where we store values. */ + this.storage = {}; + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.IN_MEMORY; }; @@ -42,7 +44,7 @@ fireauth.storage.InMemoryStorage = function() { * @override */ fireauth.storage.InMemoryStorage.prototype.get = function(key) { - return goog.Promise.resolve(/** @type {*} */ (this.storage_[key])); + return goog.Promise.resolve(/** @type {*} */ (this.storage[key])); }; @@ -53,7 +55,7 @@ fireauth.storage.InMemoryStorage.prototype.get = function(key) { * @override */ fireauth.storage.InMemoryStorage.prototype.set = function(key, value) { - this.storage_[key] = value; + this.storage[key] = value; return goog.Promise.resolve(); }; @@ -64,14 +66,14 @@ fireauth.storage.InMemoryStorage.prototype.set = function(key, value) { * @override */ fireauth.storage.InMemoryStorage.prototype.remove = function(key) { - delete this.storage_[key]; + delete this.storage[key]; return goog.Promise.resolve(); }; /** - * @param {function(!goog.events.BrowserEvent)} listener The storage event - * listener. + * @param {function((!goog.events.BrowserEvent|!Array))} listener The + * storage event listener. * @override */ fireauth.storage.InMemoryStorage.prototype.addStorageListener = @@ -80,8 +82,8 @@ fireauth.storage.InMemoryStorage.prototype.addStorageListener = /** - * @param {function(!goog.events.BrowserEvent)} listener The storage event - * listener. + * @param {function((!goog.events.BrowserEvent|!Array))} listener The + * storage event listener. * @override */ fireauth.storage.InMemoryStorage.prototype.removeStorageListener = function( diff --git a/packages/auth/src/storage/localstorage.js b/packages/auth/src/storage/localstorage.js index 61bf55cea12..ddfca2cafe1 100644 --- a/packages/auth/src/storage/localstorage.js +++ b/packages/auth/src/storage/localstorage.js @@ -50,6 +50,8 @@ fireauth.storage.LocalStorage = function() { this.storage_ = /** @type {!Storage} */ ( fireauth.storage.LocalStorage.getGlobalStorage() || firebase.INTERNAL['node']['localStorage']); + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.LOCAL_STORAGE; }; diff --git a/packages/auth/src/storage/mockstorage.js b/packages/auth/src/storage/mockstorage.js new file mode 100644 index 00000000000..8d6c46dafc3 --- /dev/null +++ b/packages/auth/src/storage/mockstorage.js @@ -0,0 +1,101 @@ +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +goog.provide('fireauth.storage.MockStorage'); + +goog.require('fireauth.storage.InMemoryStorage'); +goog.require('fireauth.storage.Storage'); +goog.require('fireauth.util'); +goog.require('goog.array'); + + +/** + * Mock storage structure useful for testing and mocking local storage and other + * types of storage without depending on any native type of storage. + * @constructor + * @implements {fireauth.storage.Storage} + * @extends {fireauth.storage.InMemoryStorage} + */ +fireauth.storage.MockStorage = function() { + /** + * @private {!Array))>} The + * storage listeners. + */ + this.storageListeners_ = []; + fireauth.storage.MockStorage.base(this, 'constructor'); + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.MOCK_STORAGE; +}; +goog.inherits(fireauth.storage.MockStorage, fireauth.storage.InMemoryStorage); + + +/** + * @param {function((!goog.events.BrowserEvent|!Array))} listener The + * storage event listener. + * @override + */ +fireauth.storage.MockStorage.prototype.addStorageListener = function(listener) { + this.storageListeners_.push(listener); +}; + + +/** + * @param {function((!goog.events.BrowserEvent|!Array))} listener The + * storage event listener. + * @override + */ +fireauth.storage.MockStorage.prototype.removeStorageListener = function( + listener) { + goog.array.removeAllIf(this.storageListeners_, function(ele) { + return ele == listener; + }); +}; + + +/** + * Simulates a storage event getting triggered which would trigger any attached + * listener. Any fired event would also update the underlying storage map. + * @param {!Event} storageEvent The storage event triggered. + */ +fireauth.storage.MockStorage.prototype.fireBrowserEvent = + function(storageEvent) { + // Get key of storage event. + var key = storageEvent.key; + if (key != null) { + // If key available, get newValue. + var newValue = storageEvent.newValue; + if (newValue != null) { + // newValue available, update corresponding value. + this.storage[key] = fireauth.util.parseJSON(newValue); + } else { + // newValue not available, delete the corresponding key's entry. + delete this.storage[key]; + } + } else { + // If key not available, clear storage. + this.clear(); + } + // Trigger all attached storage listeners. + goog.array.forEach(this.storageListeners_, function(listener) { + listener([key]); + }); +}; + + +/** Clears all stored data. */ +fireauth.storage.MockStorage.prototype.clear = function() { + this.storage = {}; +}; diff --git a/packages/auth/src/storage/nullstorage.js b/packages/auth/src/storage/nullstorage.js index 9070dbc0cc7..c3b9cdfc789 100644 --- a/packages/auth/src/storage/nullstorage.js +++ b/packages/auth/src/storage/nullstorage.js @@ -16,6 +16,7 @@ goog.provide('fireauth.storage.NullStorage'); +goog.require('fireauth.storage.Storage'); goog.require('goog.Promise'); @@ -29,6 +30,8 @@ goog.require('goog.Promise'); fireauth.storage.NullStorage = function() { /** @private {!Object} The object where we store values. */ this.storage_ = {}; + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.NULL_STORAGE; }; diff --git a/packages/auth/src/storage/sessionstorage.js b/packages/auth/src/storage/sessionstorage.js index c566e55c5ae..af770bac338 100644 --- a/packages/auth/src/storage/sessionstorage.js +++ b/packages/auth/src/storage/sessionstorage.js @@ -49,6 +49,8 @@ fireauth.storage.SessionStorage = function() { this.storage_ = /** @type {!Storage} */ ( fireauth.storage.SessionStorage.getGlobalStorage() || firebase.INTERNAL['node']['sessionStorage']); + /** @protected {string} The storage type identifier. */ + this.type = fireauth.storage.Storage.Type.SESSION_STORAGE; }; diff --git a/packages/auth/src/storage/storage.js b/packages/auth/src/storage/storage.js index 3a61342e647..d59c0ac7f89 100644 --- a/packages/auth/src/storage/storage.js +++ b/packages/auth/src/storage/storage.js @@ -65,3 +65,22 @@ fireauth.storage.Storage.prototype.addStorageListener = function(listener) {}; */ fireauth.storage.Storage.prototype.removeStorageListener = function(listener) { }; + + +/** @type {string} The storage type identifier. */ +fireauth.storage.Storage.prototype.type; + + +/** + * Enum for the identifier of the type of underlying storage. + * @enum {string} + */ +fireauth.storage.Storage.Type = { + ASYNC_STORAGE: 'asyncStorage', + IN_MEMORY: 'inMemory', + INDEXEDDB: 'indexedDB', + LOCAL_STORAGE: 'localStorage', + MOCK_STORAGE: 'mockStorage', + NULL_STORAGE: 'nullStorage', + SESSION_STORAGE: 'sessionStorage' +}; diff --git a/packages/auth/src/storageusermanager.js b/packages/auth/src/storageusermanager.js index bb05eee0612..8c0bd52003d 100644 --- a/packages/auth/src/storageusermanager.js +++ b/packages/auth/src/storageusermanager.js @@ -66,6 +66,7 @@ goog.provide('fireauth.storage.UserManager'); goog.require('fireauth.AuthUser'); goog.require('fireauth.authStorage'); +goog.require('goog.Promise'); /** @@ -127,7 +128,7 @@ fireauth.storage.UserManager.prototype.switchToLocalOnExternalEvent_ = // local. this.waitForReady_(function() { return goog.Promise.resolve().then(function() { - // In current persistence is not already local. + // If current persistence is not already local. if (self.currentAuthUserKey_ && self.currentAuthUserKey_.persistent != fireauth.authStorage.Persistence.LOCAL) { @@ -205,8 +206,14 @@ fireauth.storage.UserManager.prototype.initialize_ = function() { // In memory key. This is unlikely to contain anything on load. var inMemoryKey = fireauth.storage.UserManager.getAuthUserKey_( fireauth.authStorage.Persistence.NONE); - // Check if state is stored in session storage. - return this.manager_.get(sessionKey, this.appId_).then(function(response) { + // Migrate any old currentUser from localStorage to indexedDB. + // This keeps any user signed in without the need for reauthentication and + // minimizes risks of dangling Auth states. + return this.manager_.migrateFromLocalStorage( + localKey, this.appId_).then(function() { + // Check if state is stored in session storage. + return self.manager_.get(sessionKey, self.appId_); + }).then(function(response) { if (response) { // Session storage is being used. return sessionKey; diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js index c311559a0d8..c1a388a1542 100644 --- a/packages/auth/src/utils.js +++ b/packages/auth/src/utils.js @@ -23,6 +23,7 @@ goog.provide('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.Timer'); goog.require('goog.Uri'); +goog.require('goog.dom'); goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('goog.html.SafeUrl'); @@ -82,7 +83,8 @@ fireauth.util.isLocalStorageNotSynchronized = function(opt_userAgent) { /** @return {string} The current URL. */ fireauth.util.getCurrentUrl = function() { return (goog.global['window'] && goog.global['window']['location']['href']) || - ''; + // Check for worker environments. + (self && self['location'] && self['location']['href']) || ''; }; @@ -495,6 +497,12 @@ fireauth.util.onDomReady = function() { }; +/** @return {boolean} Whether environment supports DOM. */ +fireauth.util.isDOMSupported = function() { + return !!goog.global.document; +}; + + /** * The default ondeviceready Cordova timeout in ms. * @const {number} @@ -610,6 +618,17 @@ fireauth.util.isOpenerAnIframe = function(opt_win) { }; +/** + * @param {?Object=} opt_global The optional global scope. + * @return {boolean} Whether current environment is a worker. + */ +fireauth.util.isWorker = function(opt_global) { + var scope = opt_global || goog.global; + return typeof scope['window'] !== 'object' && + typeof scope['importScripts'] === 'function'; +}; + + /** * Enum for the runtime environment. * @enum {string} @@ -617,7 +636,8 @@ fireauth.util.isOpenerAnIframe = function(opt_win) { fireauth.util.Env = { BROWSER: 'Browser', NODE: 'Node', - REACT_NATIVE: 'ReactNative' + REACT_NATIVE: 'ReactNative', + WORKER: 'Worker' }; @@ -632,6 +652,9 @@ fireauth.util.getEnvironment = function() { // the library is browser only. Use this check instead to reliably detect // a Node.js environment. return fireauth.util.Env.NODE; + } else if (fireauth.util.isWorker()) { + // Worker environment. + return fireauth.util.Env.WORKER; } // The default is a browser environment. return fireauth.util.Env.BROWSER; @@ -815,6 +838,13 @@ fireauth.util.getClientVersion = function(clientImplementation, clientVersion, // In a browser environment, report the browser name. var userAgent = opt_userAgent || fireauth.util.getUserAgentString(); reportedEnvironment = fireauth.util.getBrowserName(userAgent); + } else if (environment === fireauth.util.Env.WORKER) { + // Technically a worker runs from a browser but we need to differentiate a + // worker from a browser. + // For example: Chrome-Worker/JsCore/4.9.1/FirebaseCore-web. + var userAgent = opt_userAgent || fireauth.util.getUserAgentString(); + reportedEnvironment = fireauth.util.getBrowserName(userAgent) + '-' + + environment; } else { // Otherwise, just report the environment name. reportedEnvironment = environment; @@ -882,7 +912,11 @@ fireauth.util.isWebStorageSupported = function() { } return true; } - } catch (e) {} + } catch (e) { + // localStorage is not available from a worker. Test availability of + // indexedDB. + return fireauth.util.isWorker() && !!goog.global['indexedDB']; + } return false; }; @@ -913,7 +947,9 @@ fireauth.util.isPopupRedirectSupported = function() { !fireauth.util.isNativeEnvironment() && // Local storage has to be supported for browser popup and redirect // operations to work. - fireauth.util.isWebStorageSupported(); + fireauth.util.isWebStorageSupported() && + // DOM, popups and redirects are not supported within a worker. + !fireauth.util.isWorker(); }; @@ -1066,21 +1102,6 @@ fireauth.util.parseJSON = function(json) { }; -/** - * @return {?function(new:XMLHttpRequest)|undefined} The current environment - * XMLHttpRequest. - */ -fireauth.util.getXMLHttpRequest = function() { - // In Node.js XMLHttpRequest is polyfilled. - var isNode = fireauth.util.getEnvironment() == fireauth.util.Env.NODE; - var XMLHttpRequest = goog.global['XMLHttpRequest'] || - (isNode && - firebase.INTERNAL['node'] && - firebase.INTERNAL['node']['XMLHttpRequest']); - return XMLHttpRequest; -}; - - /** * @param {?string=} opt_prefix An optional prefix string to prepend to ID. * @return {string} The generated event ID used to identify a generic event. @@ -1335,3 +1356,52 @@ fireauth.util.utcTimestampToDateString = function(utcTimestamp) { } return null; }; + + +/** @return {boolean} Whether indexedDB is available. */ +fireauth.util.isIndexedDBAvailable = function() { + return !!goog.global['indexedDB']; +}; + + +/** @return {boolean} Whether current mode is Auth handler or iframe. */ +fireauth.util.isAuthHandlerOrIframe = function() { + return !!(fireauth.util.getObjectRef('fireauth.oauthhelper', goog.global) || + fireauth.util.getObjectRef('fireauth.iframe', goog.global)); +}; + + +/** @return {boolean} Whether indexedDB is used to persist storage. */ +fireauth.util.persistsStorageWithIndexedDB = function() { + // This will cover: + // IE11, Edge when indexedDB is available (this is unavailable in InPrivate + // mode). (SDK, OAuth handler and iframe) + // Any environment where indexedDB is available (SDK only). + + // In a browser environment, when an iframe and a popup web storage are not + // synchronized, use the indexedDB fireauth.storage.Storage implementation. + return (fireauth.util.isLocalStorageNotSynchronized() || + !fireauth.util.isAuthHandlerOrIframe()) && + fireauth.util.isIndexedDBAvailable(); +}; + + +/** Sets the no-referrer meta tag in the document head if applicable. */ +fireauth.util.setNoReferrer = function() { + var doc = goog.global.document; + if (doc) { + try { + var meta = goog.dom.createDom(goog.dom.TagName.META, { + 'name': 'referrer', + 'content': 'no-referrer' + }); + var headCollection = goog.dom.getElementsByTagName(goog.dom.TagName.HEAD); + // Append meta tag to head. + if (headCollection.length) { + headCollection[0].appendChild(meta); + } + } catch (e) { + // Best effort approach. + } + } +}; diff --git a/packages/auth/test/auth_test.js b/packages/auth/test/auth_test.js index 9c3b4eac0a8..28a73f20e19 100644 --- a/packages/auth/test/auth_test.js +++ b/packages/auth/test/auth_test.js @@ -43,6 +43,7 @@ goog.require('fireauth.exports'); goog.require('fireauth.idp'); goog.require('fireauth.iframeclient.IfcHandler'); goog.require('fireauth.object'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.PendingRedirectManager'); goog.require('fireauth.storage.RedirectUserManager'); goog.require('fireauth.storage.UserManager'); @@ -147,9 +148,15 @@ var actionCodeSettings = { }, 'handleCodeInApp': true }; +var mockLocalStorage; +var mockSessionStorage; function setUp() { + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); // Disable Auth event manager for testing unless needed. fireauth.AuthEventManager.ENABLED = false; // Assume origin is a valid one. @@ -185,8 +192,7 @@ function setUp() { fireauth.util, 'getCurrentUrl', function() {return 'http://localhost';}); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Initialize App and Auth instances. config1 = { apiKey: 'apiKey1' @@ -323,7 +329,7 @@ function tearDown() { } finally { mockControl.$tearDown(); } - delete fireauth.authStorage.Manager.instance_; + fireauth.authStorage.Manager.clear(); currentUserStorageManager = null; redirectUserStorageManager = null; } @@ -361,16 +367,8 @@ function assertAuthTokenListenerCalledOnce(auth) { } -/** Simulates that local storage synchronizes across tabs. */ -function simulateLocalStorageSynchronized() { - stubs.replace( - fireauth.util, - 'isIe11', - function() {return false;}); - stubs.replace( - fireauth.util, - 'isEdge', - function() {return false;}); +/** Initializes mock storages. */ +function initializeMockStorage() { // Simulate tab can run in background. stubs.replace( fireauth.util, @@ -378,6 +376,8 @@ function simulateLocalStorageSynchronized() { function() { return true; }); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); } @@ -452,8 +452,7 @@ function testToJson_withUser() { // Test toJSON with a user signed in. stubs.reset(); fireauth.AuthEventManager.ENABLED = false; - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate available token. stubs.replace( fireauth.AuthUser.prototype, @@ -755,8 +754,7 @@ function testAddAuthTokenListener_initialNullState() { function() { return goog.Promise.resolve(null); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Suppress addStateChangeListener. stubs.replace( fireauth.storage.UserManager.prototype, @@ -829,8 +827,7 @@ function testAddAuthTokenListener_initialValidState() { function() { return goog.Promise.resolve(user); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Suppress addStateChangeListener. stubs.replace( fireauth.storage.UserManager.prototype, @@ -1126,8 +1123,7 @@ function testNotifyAuthStateObservers() { function() { return goog.Promise.resolve(user); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Suppress addStateChangeListener. stubs.replace( fireauth.storage.UserManager.prototype, @@ -1219,8 +1215,7 @@ function testAuth_onAuthStateChanged() { function() { return goog.Promise.resolve(user); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Suppress addStateChangeListener. stubs.replace( fireauth.storage.UserManager.prototype, @@ -1939,8 +1934,7 @@ function testAuth_authEventManager() { // Test Auth event manager. fireauth.AuthEventManager.ENABLED = true; stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); var expectedManager = { 'subscribe': goog.testing.recordFunction(), 'unsubscribe': goog.testing.recordFunction() @@ -2077,8 +2071,7 @@ function testAuth_initState_signedInStatus() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // New loaded user should be reloaded before being set as current user. @@ -2176,8 +2169,7 @@ function testAuth_initState_signedInStatus() { function testAuth_initState_reloadUpdate_previousSignedInUser() { asyncTestCase.waitForSignals(2); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate reload introduced external changes to user. stubs.replace( fireauth.AuthUser.prototype, @@ -2240,8 +2232,7 @@ function testAuth_initState_signedInStatus_differentAuthDomain() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // New loaded user should be reloaded before being set as current user. @@ -2305,8 +2296,7 @@ function testAuth_initState_signedInStatus_withRedirectUser() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Return new token on each request. @@ -2437,8 +2427,7 @@ function testAuth_initState_signedInStatus_withRedirectUser_sameEventId() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Return new token on each request. @@ -2569,8 +2558,7 @@ function testAuth_initState_signedInStatus_deletedUser() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // New loaded user should be reloaded. In this case throw an error. @@ -2642,8 +2630,7 @@ function testAuth_initState_signedInStatus_offline() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // New loaded user should be reloaded. In this case throw an error. @@ -2734,8 +2721,7 @@ function testAuth_initState_signedOutStatus() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Current user change listener should be added. @@ -2796,8 +2782,7 @@ function testAuth_syncAuthChanges_sameUser() { function() { return goog.Promise.resolve(); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Save sync listener. @@ -2933,8 +2918,7 @@ function testAuth_syncAuthChanges_newSignIn() { function() { return goog.Promise.resolve(); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Save sync listener. @@ -3054,8 +3038,7 @@ function testAuth_syncAuthChanges_newSignIn_differentAuthDomain() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); asyncTestCase.waitForSignals(1); @@ -3105,7 +3088,7 @@ function testAuth_syncAuthChanges_newSignIn_differentAuthDomain() { asyncTestCase.signal(); }); // This should force localstorage sync. - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.fireBrowserEvent(storageEvent); }); }); } @@ -3129,8 +3112,7 @@ function testAuth_syncAuthChanges_newSignOut() { function() { return goog.Promise.resolve(); }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Save sync listener. @@ -3238,8 +3220,7 @@ function testAuth_signInWithIdTokenResponse_newUser() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Initialize from ID token response should be called and resolved with the @@ -3328,8 +3309,7 @@ function testAuth_signInWithIdTokenResponse_sameUser() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Initialize from ID token response should be called and resolved with the @@ -3462,8 +3442,7 @@ function testAuth_signInWithIdTokenResponse_newUserDifferentFromCurrent() { function() { return now; }); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Stub OAuth sign in handler. fakeOAuthSignInHandler(); // Initialize from ID token response should be called and resolved with the @@ -6871,8 +6850,7 @@ function testAuth_returnFromSignInWithRedirect_withExistingUser() { null, 'http://www.example.com/#response', 'SESSION_ID'); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate user loaded from storage. stubs.replace( fireauth.AuthUser.prototype, @@ -7185,8 +7163,7 @@ function testAuth_returnFromLinkWithRedirect_success() { var expectedCred = fireauth.GoogleAuthProvider.credential(null, 'ACCESS_TOKEN'); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Expected link via redirect successful Auth event. var expectedAuthEvent = new fireauth.AuthEvent( fireauth.AuthEvent.Type.LINK_VIA_REDIRECT, @@ -7293,8 +7270,7 @@ function testAuth_returnFromLinkWithRedirect_redirectedLoggedOutUser_success() { 'http://www.example.com/#response', 'SESSION_ID'); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate user loaded from storage. stubs.replace( fireauth.AuthUser.prototype, @@ -7429,8 +7405,7 @@ function testAuth_redirectedLoggedOutUser_differentAuthDomain() { stubs.reset(); // Simulate current origin is whitelisted. simulateWhitelistedOrigin(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); stubs.replace( goog, 'now', @@ -7548,8 +7523,7 @@ function testAuth_returnFromLinkWithRedirect_noCurrentUser_redirectUser() { 'http://www.example.com/#response', 'SESSION_ID'); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate redirect user loaded from storage. stubs.replace( fireauth.storage.RedirectUserManager.prototype, @@ -7746,8 +7720,7 @@ function testAuth_returnFromLinkWithRedirect_redirectedLoggedInUser_success() { 'http://www.example.com/#response', 'SESSION_ID'); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate user loaded from storage. stubs.replace( fireauth.AuthUser.prototype, @@ -7874,8 +7847,7 @@ function testAuth_returnFromLinkWithRedirect_invalidUser() { 'http://www.example.com/#response', 'SESSION_ID'); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate user loaded from storage. stubs.replace( fireauth.AuthUser.prototype, @@ -7969,8 +7941,7 @@ function testAuth_returnFromLinkWithRedirect_error() { null, expectedError); stubs.reset(); - // Simulate local storage change synchronized. - simulateLocalStorageSynchronized(); + initializeMockStorage(); // Simulate user loaded from storage. stubs.replace( fireauth.AuthUser.prototype, @@ -8878,7 +8849,8 @@ function testAuth_setPersistence_noExistingAuthState() { // Confirm first user saved in session storage. assertUserEquals(user1, user); return fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'session', user1); + auth1.getStorageKey(), 'session', user1, + fireauth.authStorage.Manager.getInstance()); }).then(function() { // Sign in with custom token. return auth1.signInWithCustomToken('CUSTOM_TOKEN'); @@ -8886,7 +8858,8 @@ function testAuth_setPersistence_noExistingAuthState() { // Confirm second user saved in session storage. clock.tick(1); return fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'session', user2); + auth1.getStorageKey(), 'session', user2, + fireauth.authStorage.Manager.getInstance()); }).then(function() { asyncTestCase.signal(); }); @@ -8928,13 +8901,15 @@ function testAuth_setPersistence_existingAuthState() { // When this is first triggered, the previously signed in user should be // switched to session storage. fireauth.common.testHelper.assertUserStorage( - config3['apiKey'] + ':' + appId1, 'session', user1).then(function() { + config3['apiKey'] + ':' + appId1, 'session', user1, + fireauth.authStorage.Manager.getInstance()).then(function() { // Sign in a new user. return auth1.signInAnonymously(); }).then(function() { // Second user should be also persistence in session storage. return fireauth.common.testHelper.assertUserStorage( - config3['apiKey'] + ':' + appId1, 'session', user2); + config3['apiKey'] + ':' + appId1, 'session', user2, + fireauth.authStorage.Manager.getInstance()); }).then(function() { asyncTestCase.signal(); }); @@ -8982,8 +8957,7 @@ function testAuth_temporaryPersistence_externalChange() { var storageEvent = new goog.testing.events.Event( goog.events.EventType.STORAGE, window); // Simulate existing user stored in session storage. - window.sessionStorage.setItem( - storageKey, JSON.stringify(user1.toPlainObject())); + mockSessionStorage.set(storageKey, user1.toPlainObject()); app1 = firebase.initializeApp(config3, appId1); auth1 = app1.auth(); storageEvent.key = 'firebase:authUser:' + auth1.getStorageKey(); @@ -8997,18 +8971,20 @@ function testAuth_temporaryPersistence_externalChange() { // On first call, the first user should be stored in session storage. assertUserEquals(user1, user); fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'session', user1).then(function() { + auth1.getStorageKey(), 'session', user1, + fireauth.authStorage.Manager.getInstance()).then(function() { // Simulate external user signed in on another tab. - window.localStorage.setItem( - storageKey, JSON.stringify(user2.toPlainObject())); - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.set( + storageKey, user2.toPlainObject()); + mockLocalStorage.fireBrowserEvent(storageEvent); }); } else if (calls == 2) { // On second call, the second user detected from external event should // be detected and stored in local storage. assertUserEquals(user2, user); fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'local', user2).then(function() { + auth1.getStorageKey(), 'local', user2, + fireauth.authStorage.Manager.getInstance()).then(function() { // Sign in anonymously. auth1.signInAnonymously(); }); @@ -9016,7 +8992,8 @@ function testAuth_temporaryPersistence_externalChange() { // Third anonymous user detected and should be stored in local storage. assertUserEquals(user3, user); fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'local', user3).then(function() { + auth1.getStorageKey(), 'local', user3, + fireauth.authStorage.Manager.getInstance()).then(function() { asyncTestCase.signal(); }); } @@ -9098,7 +9075,8 @@ function testAuth_storedPersistence_returnFromRedirect() { // savePersistenceForRedirect was previously called with session // persistence. return fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'session', user1); + auth1.getStorageKey(), 'session', user1, + fireauth.authStorage.Manager.getInstance()); }).then(function() { asyncTestCase.signal(); }); @@ -9203,7 +9181,8 @@ function testAuth_changedPersistence_returnFromRedirect() { // was session, it will be overriddent by the local persistence // explicitly called after Auth instance is initialized. return fireauth.common.testHelper.assertUserStorage( - auth1.getStorageKey(), 'local', user1); + auth1.getStorageKey(), 'local', user1, + fireauth.authStorage.Manager.getInstance()); }).then(function() { asyncTestCase.signal(); }); diff --git a/packages/auth/test/autheventmanager_test.js b/packages/auth/test/autheventmanager_test.js index d68299608d0..2dce3d1d066 100644 --- a/packages/auth/test/autheventmanager_test.js +++ b/packages/auth/test/autheventmanager_test.js @@ -32,8 +32,10 @@ goog.require('fireauth.RedirectAuthEventProcessor'); goog.require('fireauth.RpcHandler'); goog.require('fireauth.UniversalLinkSubscriber'); goog.require('fireauth.authenum.Error'); +goog.require('fireauth.common.testHelper'); goog.require('fireauth.constants'); goog.require('fireauth.iframeclient.IfcHandler'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.OAuthHandlerManager'); goog.require('fireauth.storage.PendingRedirectManager'); goog.require('fireauth.util'); @@ -76,8 +78,14 @@ var savePartialEventManager; var timeoutDelay = 30000; var mockControl; var ignoreArgument; +var mockLocalStorage; +var mockSessionStorage; function setUp() { + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); mockControl = new goog.testing.MockControl(); ignoreArgument = goog.testing.mockmatchers.ignoreArgument; mockControl.$resetAll(); @@ -86,7 +94,8 @@ function setUp() { 'resolvePendingPopupEvent': goog.testing.recordFunction(), 'getAuthEventHandlerFinisher': goog.testing.recordFunction() }; - simulateLocalStorageSynchronized(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); // Default OAuth sign in handler is IfcHandler. setOAuthSignInHandlerEnvironment(false); } @@ -162,15 +171,6 @@ function initializePlugins( } -/** Simulates that local storage synchronizes across tabs. */ -function simulateLocalStorageSynchronized() { - stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', - function() {return false;}); -} - - /** * Helper function to set the current OAuth sign in handler. * @param {boolean} isCordova Whether to simulate a Cordova environment. diff --git a/packages/auth/test/authstorage_test.js b/packages/auth/test/authstorage_test.js index 683a6f1ae84..3739a7e70f8 100644 --- a/packages/auth/test/authstorage_test.js +++ b/packages/auth/test/authstorage_test.js @@ -28,6 +28,7 @@ goog.require('fireauth.common.testHelper'); goog.require('fireauth.exports'); goog.require('fireauth.storage.IndexedDB'); goog.require('fireauth.storage.LocalStorage'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.SessionStorage'); goog.require('fireauth.util'); goog.require('goog.Promise'); @@ -50,16 +51,17 @@ var config = { var stubs = new goog.testing.PropertyReplacer(); var appId = 'appId1'; var clock; +var mockLocalStorage; +var mockSessionStorage; function setUp() { - // Simulate browser that synchronizes between and iframe and a popup. - stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', - function() { - return false; - }); + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); clock = new goog.testing.MockClock(true); window.localStorage.clear(); window.sessionStorage.clear(); @@ -209,6 +211,13 @@ function testValidatePersistenceArgument_browser() { function testWebStorageNotSupported() { // Test when web storage not supported. In memory storage should be used // instead. + stubs.reset(); + stubs.replace( + fireauth.storage.IndexedDB, + 'isAvailable', + function() { + return false; + }); stubs.replace( fireauth.storage.LocalStorage, 'isAvailable', @@ -271,7 +280,6 @@ function testWebStorageNotSupported() { .then(function(value) { assertUndefined(value); }); - } @@ -288,10 +296,14 @@ function testGetSet_temporaryStorage() { return manager.get(key, appId); }) .then(function(value) { - assertNull(window.localStorage.getItem(storageKey)); - assertEquals( - window.sessionStorage.getItem(storageKey), - JSON.stringify(expectedValue)); + assertObjectEquals(expectedValue, value); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { assertObjectEquals(expectedValue, value); }) .then(function() { @@ -301,8 +313,14 @@ function testGetSet_temporaryStorage() { return manager.get(key, appId); }) .then(function(value) { - assertNull(window.sessionStorage.getItem(storageKey)); - assertNull(window.localStorage.getItem(storageKey)); + assertUndefined(value); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { assertUndefined(value); }); } @@ -321,19 +339,29 @@ function testGetSet_inMemoryStorage() { return manager.get(key, appId); }) .then(function(value) { - assertNull(window.sessionStorage.getItem(storageKey)); - assertNull(window.localStorage.getItem(storageKey)); assertObjectEquals(expectedValue, value); + return mockLocalStorage.get(storageKey); }) - .then(function() { + .then(function(value) { + assertUndefined(value); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); return manager.remove(key, appId); }) .then(function() { return manager.get(key, appId); }) .then(function(value) { - assertNull(window.sessionStorage.getItem(storageKey)); - assertNull(window.localStorage.getItem(storageKey)); + assertUndefined(value); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { assertUndefined(value); }); } @@ -352,22 +380,71 @@ function testGetSet_persistentStorage() { return manager.get(key, appId); }) .then(function(value) { - assertEquals( - window.localStorage.getItem(storageKey), - JSON.stringify(expectedValue)); - assertNull(window.sessionStorage.getItem(storageKey)); assertObjectEquals(expectedValue, value); + return mockSessionStorage.get(storageKey); }) - .then(function() { + .then(function(value) { + assertUndefined(value); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { + assertObjectEquals(expectedValue, value); return manager.remove(key, appId); }) .then(function() { return manager.get(key, appId); }) .then(function(value) { - assertNull(window.localStorage.getItem(storageKey)); - assertNull(window.sessionStorage.getItem(storageKey)); assertUndefined(value); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); + }); +} + + +function testMigrateFromLocalStorage_previouslyPersistedWithLocalStorage() { + var manager = getDefaultManagerInstance(); + var key = {name: 'persistent', persistent: 'local'}; + var expectedValue = 'something'; + var storageKey = 'firebase:persistent:appId1'; + // Save expected value to window.localStorage initially. + window.localStorage.setItem(storageKey, JSON.stringify(expectedValue)); + return manager.migrateFromLocalStorage(key, appId) + .then(function() { + return manager.get(key, appId); + }) + .then(function(value) { + // Data should be migrated from window.localStorage to mockLocalStorage. + assertEquals(expectedValue, value); + assertNull(window.localStorage.getItem(storageKey)); + }); +} + + +function testMigrateFromLocalStorage_multiplePersistentStorage() { + var manager = getDefaultManagerInstance(); + var key = {name: 'persistent', persistent: 'local'}; + var expectedValue = 'something'; + var expectedValue2 = 'somethingElse'; + var storageKey = 'firebase:persistent:appId1'; + // Save expected value to mockLocalStorage. + mockLocalStorage.set(storageKey, expectedValue); + // Save second expected value to window.localStorage. + window.localStorage.setItem(storageKey, JSON.stringify(expectedValue2)); + return manager.migrateFromLocalStorage(key, appId) + .then(function() { + return manager.get(key, appId); + }) + .then(function(value) { + // mockLocalStorage will take precedence over window.localStorage. + assertEquals(expectedValue, value); + assertNull(window.localStorage.getItem(storageKey)); }); } @@ -385,25 +462,103 @@ function testGetSet_persistentStorage_noId() { return manager.get(key); }) .then(function(value) { - assertEquals( - window.localStorage.getItem(storageKey), - JSON.stringify(expectedValue)); assertObjectEquals(expectedValue, value); + return mockLocalStorage.get(storageKey); }) - .then(function() { + .then(function(value) { + assertObjectEquals(expectedValue, value); return manager.remove(key); }) .then(function() { return manager.get(key); }) .then(function(value) { - assertNull(window.localStorage.getItem(storageKey)); + assertUndefined(value); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { assertUndefined(value); }); } +function testAddRemoveListeners_persistentStorage() { + var manager = + new fireauth.authStorage.Manager('name', ':', false, true, true); + var listener1 = goog.testing.recordFunction(); + var listener2 = goog.testing.recordFunction(); + var listener3 = goog.testing.recordFunction(); + var key1 = {'name': 'authUser', 'persistent': true}; + var key2 = {'name': 'authEvent', 'persistent': true}; + return goog.Promise.resolve() + .then(function() { + return mockLocalStorage.set('name:authUser:appId1', {'foo': 'bar'}); + }) + .then(function() { + return mockLocalStorage.set('name:authEvent:appId1', {'foo': 'bar'}); + }) + .then(function() { + // Add listeners for 2 events. + manager.addListener(key1, 'appId1', listener1); + manager.addListener(key2, 'appId1', listener2); + manager.addListener(key1, 'appId1', listener3); + var storageEvent = new goog.testing.events.Event( + goog.events.EventType.STORAGE, window); + // Trigger user event. + storageEvent.key = 'name:authUser:appId1'; + storageEvent.newValue = null; + mockLocalStorage.fireBrowserEvent(storageEvent); + // Listener 1 and 3 should trigger. + assertEquals(1, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(0, listener2.getCallCount()); + storageEvent = new goog.testing.events.Event( + goog.events.EventType.STORAGE, window); + // Trigger second event. + storageEvent.key = 'name:authEvent:appId1'; + storageEvent.newValue = null; + mockLocalStorage.fireBrowserEvent(storageEvent); + // Only second listener should trigger. + assertEquals(1, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(1, listener2.getCallCount()); + storageEvent = new goog.testing.events.Event( + goog.events.EventType.STORAGE, window); + // Some unknown event. + storageEvent.key = 'key3'; + storageEvent.newValue = null; + mockLocalStorage.fireBrowserEvent(storageEvent); + // No listeners should trigger. + assertEquals(1, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(1, listener2.getCallCount()); + // Remove all listeners. + manager.removeListener(key1, 'appId1', listener1); + manager.removeListener(key2, 'appId1', listener2); + manager.removeListener(key1, 'appId1', listener3); + // Trigger first event. + storageEvent = new goog.testing.events.Event( + goog.events.EventType.STORAGE, window); + storageEvent.key = 'name:authUser:appId1'; + storageEvent.newValue = JSON.stringify({'foo': 'bar'}); + mockLocalStorage.fireBrowserEvent(storageEvent); + // No change. + assertEquals(1, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(1, listener2.getCallCount()); + }); +} + + function testAddRemoveListeners_localStorage() { + stubs.reset(); + // localStorage is used when service workers are not supported. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() { + return false; + }); var manager = new fireauth.authStorage.Manager('name', ':', false, true, true); var listener1 = goog.testing.recordFunction(); @@ -471,6 +626,12 @@ function testAddRemoveListeners_localStorage() { function testAddRemoveListeners_localStorage_nullKey() { + stubs.reset(); + // Simulate localStorage is used for persistent storage. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); var manager = new fireauth.authStorage.Manager('name', ':', false, true, true); var listener1 = goog.testing.recordFunction(); @@ -515,6 +676,14 @@ function testAddRemoveListeners_localStorage_nullKey() { function testAddRemoveListeners_localStorage_ie10() { + stubs.reset(); + // Simulate localStorage is used for persistent storage. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() { + return false; + }); // Simulate IE 10 with localStorage events not synchronized. // event.newValue will not be immediately equal to // localStorage.getItem(event.key). @@ -609,6 +778,7 @@ function testAddRemoveListeners_localStorage_ie10() { function testAddRemoveListeners_indexeddb() { + stubs.reset(); // Mock indexedDB local storage manager. var mockIndexeddb = { handlers: [], @@ -626,10 +796,10 @@ function testAddRemoveListeners_indexeddb() { } } }; - // Simulate browser that does not synchronize between and iframe and a popup. + // Simulate indexedDB is used for persistent storage. stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', + fireauth.util, + 'persistsStorageWithIndexedDB', function() { return true; }); @@ -687,6 +857,7 @@ function testAddRemoveListeners_indexeddb_cannotRunInBackground() { // between iframe and popup, polling web storage function should not be used. // indexedDB should be used. // Mock indexedDB local storage manager. + stubs.reset(); var mockIndexeddb = { handlers: [], addStorageListener: function(indexeddbHandler) { @@ -703,10 +874,10 @@ function testAddRemoveListeners_indexeddb_cannotRunInBackground() { } } }; - // Simulate browser that does not synchronize between and iframe and a popup. + // Simulate indexedDB is used for persistent storage. stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', + fireauth.util, + 'persistsStorageWithIndexedDB', function() { return true; }); @@ -761,6 +932,12 @@ function testAddRemoveListeners_indexeddb_cannotRunInBackground() { function testSafariLocalStorageSync_newEvent() { + stubs.reset(); + // Simulate persistent state implemented through localStorage for Safari. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); var manager = new fireauth.authStorage.Manager('firebase', ':', true, true, true); // Simulate Safari bug. @@ -798,6 +975,12 @@ function testSafariLocalStorageSync_newEvent() { function testSafariLocalStorageSync_cannotRunInBackground() { + stubs.reset(); + // Simulate persistent state implemented through localStorage for Safari. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); // This simulates iframe embedded in a cross origin domain. // Realistically only storage event should trigger here. // Test when new data is added to storage. @@ -838,6 +1021,12 @@ function testSafariLocalStorageSync_cannotRunInBackground() { function testSafariLocalStorageSync_deletedEvent() { + stubs.reset(); + // Simulate persistent state implemented through localStorage for Safari. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); // This simulates iframe embedded in a cross origin domain. // Realistically only storage event should trigger here. // Test when old data is deleted from storage. @@ -881,6 +1070,12 @@ function testRunsInBackground_storageEventMode() { // foreground. // Test when storage event is first detected. Polling should be disabled to // prevent duplicate storage detection. + stubs.reset(); + // Simulate localStorage is used for persistent storage. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); var key = {name: 'authEvent', persistent: 'local'}; var storageKey = 'firebase:authEvent:appId1'; var manager = new fireauth.authStorage.Manager( @@ -972,6 +1167,12 @@ function testRunsInBackground_webStorageNotSupported() { function testRunsInBackground_pollingMode() { + stubs.reset(); + // Simulate localStorage is used for persistent storage. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); // Test when browser does not run in the background while another tab is in // foreground. // Test when storage polling first detects a storage notification. @@ -1025,6 +1226,12 @@ function testRunsInBackground_pollingMode() { function testRunsInBackground_currentTabChangesIgnored() { + stubs.reset(); + // Simulate localStorage is used for persistent storage. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() {return false;}); // Test when browser does not run in the background while another tab is in // foreground. // This tests that only other tab changes are detected and current tab changes diff --git a/packages/auth/test/cordovahandler_test.js b/packages/auth/test/cordovahandler_test.js index a2b17f0c79c..0dd935c6ec1 100644 --- a/packages/auth/test/cordovahandler_test.js +++ b/packages/auth/test/cordovahandler_test.js @@ -27,9 +27,11 @@ goog.require('fireauth.EmailAuthProvider'); goog.require('fireauth.GoogleAuthProvider'); goog.require('fireauth.UniversalLinkSubscriber'); goog.require('fireauth.authenum.Error'); +goog.require('fireauth.common.testHelper'); goog.require('fireauth.constants'); goog.require('fireauth.iframeclient.IfcHandler'); goog.require('fireauth.storage.AuthEventManager'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.OAuthHandlerManager'); goog.require('fireauth.util'); goog.require('goog.Promise'); @@ -66,6 +68,8 @@ var iOS8iPhoneUA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) A' + var iOS9iPhoneUA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) A' + 'ppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13C75 Safar' + 'i/601.1'; +var mockLocalStorage; +var mockSessionStorage; /** @@ -140,9 +144,12 @@ function initializePlugins( function setUp() { - // This would never run in IE environment anyway. - // Simulate localStorage synchronized. - simulateLocalStorageSynchronized(); + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); // Initialize plugins. initializePlugins( function(eventName, cb) { @@ -188,15 +195,6 @@ function tearDown() { } -/** Simulates that local storage synchronizes across tabs. */ -function simulateLocalStorageSynchronized() { - stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', - function() {return false;}); -} - - /** * Install the test to run and runs it. * @param {string} id The test identifier. diff --git a/packages/auth/test/recaptchaverifier/recaptchaverifier_test.js b/packages/auth/test/recaptchaverifier/recaptchaverifier_test.js index 82d1bc1c82d..381a09a1314 100644 --- a/packages/auth/test/recaptchaverifier/recaptchaverifier_test.js +++ b/packages/auth/test/recaptchaverifier/recaptchaverifier_test.js @@ -349,6 +349,24 @@ function installAndRunTest(id, func) { } +function testBaseRecaptchaVerifier_noDOM() { + return installAndRunTest('testBaseAppVerifier_noHttpOrHttps', function() { + var isDOMSupported = mockControl.createMethodMock( + fireauth.util, 'isDOMSupported'); + isDOMSupported().$returns(false).$once(); + mockControl.$replayAll(); + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.OPERATION_NOT_SUPPORTED, + 'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' + + 'environment with DOM support.'); + var error = assertThrows(function() { + new fireauth.BaseRecaptchaVerifier('API_KEY', 'id'); + }); + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + }); +} + + function testBaseRecaptchaVerifier_noHttpOrHttps() { return installAndRunTest('testBaseAppVerifier_noHttpOrHttps', function() { var isHttpOrHttps = mockControl.createMethodMock( @@ -368,6 +386,33 @@ function testBaseRecaptchaVerifier_noHttpOrHttps() { } +function testBaseRecaptchaVerifier_worker() { + return installAndRunTest('testBaseAppVerifier_noHttpOrHttps', function() { + // This gets called in some underlying dependencies at various points. + // It is not feasible counting the exact number of calls and the sequence + // they get called. It is better to use property replacer to stub this + // utility. + stubs.replace( + fireauth.util, + 'isWorker', + function() {return true;}); + var isHttpOrHttps = mockControl.createMethodMock( + fireauth.util, 'isHttpOrHttps'); + isHttpOrHttps().$returns(true).$once(); + mockControl.$replayAll(); + var expectedError = new fireauth.AuthError( + fireauth.authenum.Error.OPERATION_NOT_SUPPORTED, + 'RecaptchaVerifier is only supported in a browser HTTP/HTTPS ' + + 'environment.'); + var recaptchaVerifier = new fireauth.BaseRecaptchaVerifier( + 'API_KEY', myElement); + return recaptchaVerifier.render().thenCatch(function(error) { + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + }); + }); +} + + function testBaseRecaptchaVerifier_withSitekey() { return installAndRunTest('testBaseAppVerifier_withSitekey', function() { var options = { diff --git a/packages/auth/test/rpchandler_test.js b/packages/auth/test/rpchandler_test.js index aaf8f7dbc16..105510569b5 100644 --- a/packages/auth/test/rpchandler_test.js +++ b/packages/auth/test/rpchandler_test.js @@ -31,6 +31,8 @@ goog.require('fireauth.common.testHelper'); goog.require('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.json'); +goog.require('goog.net.CorsXmlHttpFactory'); +goog.require('goog.net.FetchXmlHttpFactory'); goog.require('goog.net.XhrIo'); goog.require('goog.net.XhrLike'); goog.require('goog.object'); @@ -169,6 +171,7 @@ function tearDown() { } finally { mockControl.$tearDown(); } + delete goog.global['self']; } @@ -179,7 +182,7 @@ function testGetApiKey() { function testRpcHandler_XMLHttpRequest_notSupported() { stubs.replace( - fireauth.util, + fireauth.RpcHandler, 'getXMLHttpRequest', function() {return undefined;}); var expectedError = new fireauth.AuthError( @@ -190,6 +193,136 @@ function testRpcHandler_XMLHttpRequest_notSupported() { } +function testRpcHandler_XMLHttpRequest_worker() { + // Test worker environment that FetchXmlHttpFactory is used in initialization + // of goog.net.XhrIo. + // Install mock clock. + clock = new goog.testing.MockClock(true); + // Simulates global self in a worker environment. + goog.global['self'] = {}; + var xhrInstance = mockControl.createStrictMock(goog.net.XhrLike); + var createInstance = mockControl.createMethodMock( + goog.net.FetchXmlHttpFactory.prototype, 'createInstance'); + stubs.reset(); + // Simulate worker environment. + stubs.replace( + fireauth.util, + 'isWorker', + function() {return true;}); + // No XMLHttpRequest available. + stubs.replace( + fireauth.RpcHandler, + 'getXMLHttpRequest', + function() {return undefined;}); + // Confirm RPC handler calls XHR instance from FetchXmlHttpFactory XHR. + createInstance().$returns(xhrInstance); + xhrInstance.open(ignoreArgument, ignoreArgument, ignoreArgument).$once(); + xhrInstance.setRequestHeader(ignoreArgument, ignoreArgument).$once(); + xhrInstance.send(ignoreArgument).$once(); + xhrInstance.abort().$once(); + asyncTestCase.waitForSignals(1); + mockControl.$replayAll(); + rpcHandler = new fireauth.RpcHandler('apiKey'); + // Simulate RPC and then timeout. + rpcHandler.fetchProvidersForIdentifier('user@example.com') + .thenCatch(function(error) { + asyncTestCase.signal(); + }); + // Timeout XHR request. + clock.tick(delay * 2); +} + + +function testRpcHandler_XMLHttpRequest_corsBrowser() { + // Test CORS browser environment that CorsXmlHttpFactory is used in + // initialization of goog.net.XhrIo. + // Install mock clock. + clock = new goog.testing.MockClock(true); + var xhrInstance = mockControl.createStrictMock(goog.net.XhrLike); + var createInstance = mockControl.createMethodMock( + goog.net.CorsXmlHttpFactory.prototype, 'createInstance'); + stubs.reset(); + // Non-worker environment. + stubs.replace( + fireauth.util, + 'isWorker', + function() {return false;}); + // CORS supporting browser. + stubs.replace( + fireauth.util, + 'supportsCors', + function() {return true;}); + // Non-native environment. + stubs.replace( + fireauth.util, + 'isNativeEnvironment', + function() {return false;}); + // Confirm RPC handler calls XHR instance from CorsXmlHttpFactory XHR. + createInstance().$returns(xhrInstance); + xhrInstance.open(ignoreArgument, ignoreArgument, ignoreArgument).$once(); + xhrInstance.setRequestHeader(ignoreArgument, ignoreArgument).$once(); + xhrInstance.send(ignoreArgument).$once(); + xhrInstance.abort().$once(); + asyncTestCase.waitForSignals(1); + mockControl.$replayAll(); + rpcHandler = new fireauth.RpcHandler('apiKey'); + // Simulate RPC and then timeout. + rpcHandler.fetchProvidersForIdentifier('user@example.com') + .thenCatch(function(error) { + asyncTestCase.signal(); + }); + // Timeout XHR request. + clock.tick(delay * 2); +} + + +function testRpcHandler_XMLHttpRequest_reactNative() { + // Test react-native environment that built-in XMLHttpRequest is used in + // xhrFactory. + // Install mock clock. + clock = new goog.testing.MockClock(true); + var xhrInstance = mockControl.createStrictMock(goog.net.XhrLike); + var xhrConstructor = mockControl.createConstructorMock( + goog.net, 'XhrLike'); + stubs.reset(); + // CORS supporting environment. + stubs.replace( + fireauth.util, + 'supportsCors', + function() {return true;}); + // Return native XMLHttpRequest.. + stubs.replace( + fireauth.RpcHandler, + 'getXMLHttpRequest', + function() {return xhrConstructor;}); + // React-native environment. + stubs.replace( + fireauth.util, + 'isNativeEnvironment', + function() {return true;}); + stubs.replace( + fireauth.util, + 'getEnvironment', + function() {return fireauth.util.Env.REACT_NATIVE;}); + // Confirm RPC handler calls XHR instance from factory XHR. + xhrConstructor().$returns(xhrInstance); + xhrInstance.open(ignoreArgument, ignoreArgument, ignoreArgument).$once(); + xhrInstance.setRequestHeader(ignoreArgument, ignoreArgument).$once(); + xhrInstance.send(ignoreArgument).$once(); + xhrInstance.abort().$once(); + asyncTestCase.waitForSignals(1); + mockControl.$replayAll(); + rpcHandler = new fireauth.RpcHandler('apiKey'); + // Simulate RPC and then timeout. + rpcHandler.fetchProvidersForIdentifier('user@example.com') + .thenCatch(function(error) { + asyncTestCase.signal(); + }); + // Timeout XHR request. + clock.tick(delay * 2); +} + + function testRpcHandler_XMLHttpRequest_node() { // Test node environment that Node.js implementation is used in xhrfactory. // Install mock clock. @@ -205,7 +338,7 @@ function testRpcHandler_XMLHttpRequest_node() { // Return mock XHR constructor. In a Node.js environment the polyfill library // would be used. stubs.replace( - fireauth.util, + fireauth.RpcHandler, 'getXMLHttpRequest', function() {return xhrConstructor;}); // Node.js environment. diff --git a/packages/auth/test/storage/asyncstorage_test.js b/packages/auth/test/storage/asyncstorage_test.js index ac3f8d200dd..9e8afb72dd3 100644 --- a/packages/auth/test/storage/asyncstorage_test.js +++ b/packages/auth/test/storage/asyncstorage_test.js @@ -17,6 +17,7 @@ goog.provide('fireauth.storage.AsyncStorageTest'); goog.require('fireauth.storage.AsyncStorage'); +goog.require('fireauth.storage.Storage'); /** @suppress {extraRequire} */ goog.require('fireauth.storage.testHelper'); goog.require('fireauth.storage.testHelper.FakeAsyncStorage'); @@ -43,6 +44,7 @@ function tearDown() { function testBasicStorageOperations() { + assertEquals(fireauth.storage.Storage.Type.ASYNC_STORAGE, storage.type); return assertBasicStorageOperations(storage); } diff --git a/packages/auth/test/storage/factory_test.js b/packages/auth/test/storage/factory_test.js index 2a441a12232..69ce48835ae 100644 --- a/packages/auth/test/storage/factory_test.js +++ b/packages/auth/test/storage/factory_test.js @@ -36,10 +36,10 @@ var stubs = new goog.testing.PropertyReplacer(); function setUp() { - // Simulate browser that synchronizes between and iframe and a popup. + // Simulate storage not persisted with indexedDB. stubs.replace( fireauth.util, - 'isLocalStorageNotSynchronized', + 'persistsStorageWithIndexedDB', function() { return false; }); @@ -59,7 +59,13 @@ function testGetStorage_browser_temporary() { } -function testGetStorage_browser_persistent() { +function testGetStorage_browser_persistent_localStorage() { + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() { + return false; + }); var factory = new fireauth.storage.Factory( fireauth.storage.Factory.EnvConfig.BROWSER); assertTrue(factory.makePersistentStorage() instanceof @@ -67,14 +73,14 @@ function testGetStorage_browser_persistent() { } -function testGetStorage_browser_persistent_isLocalStorageNotSynchronized() { +function testGetStorage_browser_persistent_indexedDB() { // Simulate browser to force usage of indexedDB storage. var mock = { type: 'indexedDB' }; stubs.replace( fireauth.util, - 'isLocalStorageNotSynchronized', + 'persistsStorageWithIndexedDB', function() { return true; }); @@ -99,6 +105,12 @@ function testGetStorage_node_temporary() { function testGetStorage_node_persistent() { + stubs.replace( + fireauth.storage.IndexedDB, + 'isAvailable', + function() { + return false; + }); var factory = new fireauth.storage.Factory( fireauth.storage.Factory.EnvConfig.NODE); assertTrue(factory.makePersistentStorage() instanceof @@ -115,6 +127,12 @@ function testGetStorage_reactnative_temporary() { function testGetStorage_reactnative_persistent() { + stubs.replace( + fireauth.storage.IndexedDB, + 'isAvailable', + function() { + return false; + }); var factory = new fireauth.storage.Factory( fireauth.storage.Factory.EnvConfig.REACT_NATIVE); assertTrue(factory.makePersistentStorage() instanceof @@ -122,6 +140,39 @@ function testGetStorage_reactnative_persistent() { } +function testGetStorage_worker_persistent() { + var mock = { + type: 'indexedDB' + }; + // persistsStorageWithIndexedDB is true in a worker environment. + stubs.replace( + fireauth.util, + 'persistsStorageWithIndexedDB', + function() { + return true; + }); + // Return a mock indexeDB instance to assert the expected result of the test + // below. + stubs.replace( + fireauth.storage.IndexedDB, + 'getFireauthManager', + function() { + return mock; + }); + var factory = new fireauth.storage.Factory( + fireauth.storage.Factory.EnvConfig.WORKER); + assertEquals('indexedDB', factory.makePersistentStorage().type); +} + + +function testGetStorage_worker_temporary() { + var factory = new fireauth.storage.Factory( + fireauth.storage.Factory.EnvConfig.WORKER); + assertTrue(factory.makeTemporaryStorage() instanceof + fireauth.storage.NullStorage); +} + + function testGetStorage_inMemory() { var factory = new fireauth.storage.Factory( fireauth.storage.Factory.EnvConfig.BROWSER); diff --git a/packages/auth/test/storage/indexeddb_test.js b/packages/auth/test/storage/indexeddb_test.js index 9f0e1958f2f..863d9b7a571 100644 --- a/packages/auth/test/storage/indexeddb_test.js +++ b/packages/auth/test/storage/indexeddb_test.js @@ -19,6 +19,7 @@ goog.provide('fireauth.storage.IndexedDBTest'); goog.require('fireauth.AuthError'); goog.require('fireauth.authenum.Error'); goog.require('fireauth.storage.IndexedDB'); +goog.require('fireauth.storage.Storage'); goog.require('goog.Promise'); goog.require('goog.testing.MockClock'); goog.require('goog.testing.PropertyReplacer'); @@ -240,6 +241,7 @@ function testIndexedDb_notSupported() { function testIndexedDb_null() { manager = getDefaultFireauthManager(); + assertEquals(fireauth.storage.Storage.Type.INDEXEDDB, manager.type); return manager.get('key1') .then(function(data) { assertNull(data); diff --git a/packages/auth/test/storage/inmemorystorage_test.js b/packages/auth/test/storage/inmemorystorage_test.js index 348f678dd6a..a18b7ae91b3 100644 --- a/packages/auth/test/storage/inmemorystorage_test.js +++ b/packages/auth/test/storage/inmemorystorage_test.js @@ -17,6 +17,7 @@ goog.provide('fireauth.storage.InMemoryStorageTest'); goog.require('fireauth.storage.InMemoryStorage'); +goog.require('fireauth.storage.Storage'); /** @suppress {extraRequire} */ goog.require('fireauth.storage.testHelper'); goog.require('goog.testing.jsunit'); @@ -38,6 +39,7 @@ function tearDown() { function testBasicStorageOperations() { + assertEquals(fireauth.storage.Storage.Type.IN_MEMORY, storage.type); return assertBasicStorageOperations(storage); } diff --git a/packages/auth/test/storage/localstorage_test.js b/packages/auth/test/storage/localstorage_test.js index c050117bb56..a50820187a9 100644 --- a/packages/auth/test/storage/localstorage_test.js +++ b/packages/auth/test/storage/localstorage_test.js @@ -19,6 +19,7 @@ goog.provide('fireauth.storage.LocalStorageTest'); goog.require('fireauth.AuthError'); goog.require('fireauth.authenum.Error'); goog.require('fireauth.storage.LocalStorage'); +goog.require('fireauth.storage.Storage'); /** @suppress {extraRequire} */ goog.require('fireauth.storage.testHelper'); goog.require('fireauth.util'); @@ -64,6 +65,7 @@ function simulateNodeEnvironment() { function testBasicStorageOperations() { + assertEquals(fireauth.storage.Storage.Type.LOCAL_STORAGE, storage.type); return assertBasicStorageOperations(storage); } diff --git a/packages/auth/test/storage/mockstorage_test.js b/packages/auth/test/storage/mockstorage_test.js new file mode 100644 index 00000000000..e959239b965 --- /dev/null +++ b/packages/auth/test/storage/mockstorage_test.js @@ -0,0 +1,128 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +goog.provide('fireauth.storage.MockStorageTest'); + +goog.require('fireauth.storage.MockStorage'); +goog.require('fireauth.storage.Storage'); +/** @suppress {extraRequire} */ +goog.require('fireauth.storage.testHelper'); +goog.require('goog.events.EventType'); +goog.require('goog.testing.events'); +goog.require('goog.testing.events.Event'); +goog.require('goog.testing.jsunit'); +goog.require('goog.testing.recordFunction'); + +goog.setTestOnly('fireauth.storage.MockStorageTest'); + + +var storage; + + +function setUp() { + storage = new fireauth.storage.MockStorage(); +} + + +function tearDown() { + storage = null; +} + + +function testBasicStorageOperations() { + assertEquals(fireauth.storage.Storage.Type.MOCK_STORAGE, storage.type); + return assertBasicStorageOperations(storage); +} + + +function testDifferentTypes() { + return assertDifferentTypes(storage); +} + + +function testListeners() { + var storageEvent; + + var listener1 = goog.testing.recordFunction(); + var listener2 = goog.testing.recordFunction(); + var listener3 = goog.testing.recordFunction(); + + storage.addStorageListener(listener1); + storage.addStorageListener(listener3); + + storageEvent = + new goog.testing.events.Event(goog.events.EventType.STORAGE, window); + storageEvent.key = 'myKey1'; + storageEvent.newValue = JSON.stringify('value1'); + storage.fireBrowserEvent(storageEvent); + + assertEquals(1, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(0, listener2.getCallCount()); + return storage.get('myKey1').then(function(value) { + assertEquals('value1', value); + + storage.removeStorageListener(listener3); + + storageEvent.key = 'myKey2'; + storageEvent.newValue = JSON.stringify('value2'); + storage.fireBrowserEvent(storageEvent); + + assertEquals(2, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(0, listener2.getCallCount()); + return storage.get('myKey2'); + }).then(function(value) { + assertEquals('value2', value); + storageEvent.key = 'myKey1'; + storageEvent.newValue = null; + storage.fireBrowserEvent(storageEvent); + + assertEquals(3, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(0, listener2.getCallCount()); + + return storage.get('myKey1'); + }).then(function(value) { + assertUndefined(value); + + storage.removeStorageListener(listener1); + + storageEvent.key = null; + storage.fireBrowserEvent(storageEvent); + + assertEquals(3, listener1.getCallCount()); + assertEquals(1, listener3.getCallCount()); + assertEquals(0, listener2.getCallCount()); + + return storage.get('myKey2'); + }).then(function(value) { + assertUndefined(value); + }); +} + + +function testClear() { + storage.set('myKey1', 'value1'); + storage.set('myKey2', 'value2'); + storage.clear(); + return storage.get('myKey1').then(function(value) { + assertUndefined(value); + return storage.get('myKey2'); + }).then(function(value) { + assertUndefined(value); + }); +} diff --git a/packages/auth/test/storage/nullstorage_test.js b/packages/auth/test/storage/nullstorage_test.js index 84f1bd3486c..d47e2f71d7d 100644 --- a/packages/auth/test/storage/nullstorage_test.js +++ b/packages/auth/test/storage/nullstorage_test.js @@ -17,6 +17,7 @@ goog.provide('fireauth.storage.NullStorageTest'); goog.require('fireauth.storage.NullStorage'); +goog.require('fireauth.storage.Storage'); goog.require('goog.Promise'); goog.require('goog.testing.jsunit'); @@ -27,6 +28,7 @@ goog.setTestOnly('fireauth.storage.NullStorageTest'); function testNullStorage() { var storage = new fireauth.storage.NullStorage(); var listener = function() {}; + assertEquals(fireauth.storage.Storage.Type.NULL_STORAGE, storage.type); storage.addStorageListener(listener); storage.removeStorageListener(listener); return goog.Promise.resolve() diff --git a/packages/auth/test/storage/sessionstorage_test.js b/packages/auth/test/storage/sessionstorage_test.js index 061c39d02b2..5660f5f2c09 100644 --- a/packages/auth/test/storage/sessionstorage_test.js +++ b/packages/auth/test/storage/sessionstorage_test.js @@ -19,6 +19,7 @@ goog.provide('fireauth.storage.SessionStorageTest'); goog.require('fireauth.AuthError'); goog.require('fireauth.authenum.Error'); goog.require('fireauth.storage.SessionStorage'); +goog.require('fireauth.storage.Storage'); /** @suppress {extraRequire} */ goog.require('fireauth.storage.testHelper'); goog.require('fireauth.util'); @@ -60,6 +61,7 @@ function simulateNodeEnvironment() { function testBasicStorageOperations() { + assertEquals(fireauth.storage.Storage.Type.SESSION_STORAGE, storage.type); return assertBasicStorageOperations(storage); } diff --git a/packages/auth/test/storageautheventmanager_test.js b/packages/auth/test/storageautheventmanager_test.js index 323b9b1b7c9..39bdab127d7 100644 --- a/packages/auth/test/storageautheventmanager_test.js +++ b/packages/auth/test/storageautheventmanager_test.js @@ -22,7 +22,9 @@ goog.provide('fireauth.storage.AuthEventManagerTest'); goog.require('fireauth.AuthEvent'); goog.require('fireauth.authStorage'); +goog.require('fireauth.common.testHelper'); goog.require('fireauth.storage.AuthEventManager'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.events'); @@ -38,9 +40,17 @@ goog.setTestOnly('fireauth.storage.AuthEventManagerTest'); var appId = 'appId1'; var stubs = new goog.testing.PropertyReplacer(); +var mockLocalStorage; +var mockSessionStorage; function setUp() { + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); // Simulate browser that synchronizes between and iframe and a popup. stubs.replace( fireauth.util, @@ -53,6 +63,11 @@ function setUp() { } +function tearDown() { + stubs.reset(); +} + + /** * @return {!fireauth.authStorage.Manager} The default local storage * synchronized manager instance used for testing. @@ -71,12 +86,13 @@ function testGetSetRemoveAuthEvent() { '1234', 'http://www.example.com/#oauthResponse', 'SESSION_ID'); - // Set expected Auth event in localStorage. - window.localStorage.setItem( - 'firebase:authEvent:appId1', - JSON.stringify(expectedAuthEvent.toPlainObject())); var storageKey = 'firebase:authEvent:appId1'; return goog.Promise.resolve() + .then(function() { + // Set expected Auth event in localStorage. + return mockLocalStorage.set( + storageKey, expectedAuthEvent.toPlainObject()); + }) .then(function() { return authEventManager.getAuthEvent(); }) @@ -87,7 +103,10 @@ function testGetSetRemoveAuthEvent() { return authEventManager.removeAuthEvent(); }) .then(function() { - assertNull(window.localStorage.getItem(storageKey)); + return mockLocalStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); return authEventManager.getAuthEvent(); }) .then(function(authEvent) { @@ -106,9 +125,9 @@ function testGetSetRemoveRedirectEvent() { 'http://www.example.com/#oauthResponse', 'SESSION_ID'); // Set expected Auth event in sessionStorage. - window.sessionStorage.setItem( + mockSessionStorage.set( 'firebase:redirectEvent:appId1', - JSON.stringify(expectedAuthEvent.toPlainObject())); + expectedAuthEvent.toPlainObject()); var storageKey = 'firebase:redirectEvent:appId1'; return goog.Promise.resolve() .then(function() { @@ -121,7 +140,10 @@ function testGetSetRemoveRedirectEvent() { return authEventManager.removeRedirectEvent(); }) .then(function() { - assertNull(window.sessionStorage.getItem(storageKey)); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); return authEventManager.getRedirectEvent(); }) .then(function(authEvent) { @@ -141,38 +163,40 @@ function testAddRemoveAuthEventListener() { new fireauth.storage.AuthEventManager('appId1', storageManager); var listener = goog.testing.recordFunction(); // Save existing Auth events for appId1 and appId2. - window.localStorage.setItem( - 'firebase:authEvent:appId1', - JSON.stringify(expectedAuthEvent.toPlainObject())); - window.localStorage.setItem( - 'firebase:authEvent:appId2', - JSON.stringify(expectedAuthEvent.toPlainObject())); - authEventManager.addAuthEventListener(listener); - // Simulate appId1 event deletion. - storageEvent = - new goog.testing.events.Event(goog.events.EventType.STORAGE, window); - storageEvent.key = 'firebase:authEvent:appId1'; - storageEvent.newValue = null; - window.localStorage.removeItem('firebase:authEvent:appId1'); - // This should trigger listener. - goog.testing.events.fireBrowserEvent(storageEvent); - assertEquals(1, listener.getCallCount()); - // Simulate appId2 event deletion. - storageEvent.key = 'firebase:authEvent:appId2'; - window.localStorage.removeItem('firebase:authEvent:appId2'); - // This should not trigger listener. - goog.testing.events.fireBrowserEvent(storageEvent); - assertEquals(1, listener.getCallCount()); - // Remove listener. - authEventManager.removeAuthEventListener(listener); - // Simulate new event saved for appId1. - // This should not trigger listener anymore. - storageEvent.key = 'firebase:authEvent:appId1'; - storageEvent.oldValue = null; - storageEvent.newValue = JSON.stringify(expectedAuthEvent.toPlainObject()); - window.localStorage.setItem( - 'firebase:authEvent:appId1', - JSON.stringify(expectedAuthEvent.toPlainObject())); - goog.testing.events.fireBrowserEvent(storageEvent); - assertEquals(1, listener.getCallCount()); + return goog.Promise.resolve() + .then(function() { + return mockLocalStorage.set( + 'firebase:authEvent:appId1', expectedAuthEvent.toPlainObject()); + }) + .then(function() { + // Set expected Auth event in localStorage. + return mockLocalStorage.set( + 'firebase:authEvent:appId2', expectedAuthEvent.toPlainObject()); + }) + .then(function() { + authEventManager.addAuthEventListener(listener); + // Simulate appId1 event deletion. + storageEvent = new goog.testing.events.Event( + goog.events.EventType.STORAGE, window); + storageEvent.key = 'firebase:authEvent:appId1'; + storageEvent.newValue = null; + // This should trigger listener. + mockLocalStorage.fireBrowserEvent(storageEvent); + assertEquals(1, listener.getCallCount()); + // Simulate appId2 event deletion. + storageEvent.key = 'firebase:authEvent:appId2'; + // This should not trigger listener. + mockLocalStorage.fireBrowserEvent(storageEvent); + assertEquals(1, listener.getCallCount()); + // Remove listener. + authEventManager.removeAuthEventListener(listener); + // Simulate new event saved for appId1. + // This should not trigger listener anymore. + storageEvent.key = 'firebase:authEvent:appId1'; + storageEvent.oldValue = null; + storageEvent.newValue = + JSON.stringify(expectedAuthEvent.toPlainObject()); + mockLocalStorage.fireBrowserEvent(storageEvent); + assertEquals(1, listener.getCallCount()); + }); } diff --git a/packages/auth/test/storageoauthhandlermanager_test.js b/packages/auth/test/storageoauthhandlermanager_test.js index d8552c19077..1559d0bd2f0 100644 --- a/packages/auth/test/storageoauthhandlermanager_test.js +++ b/packages/auth/test/storageoauthhandlermanager_test.js @@ -23,6 +23,8 @@ goog.provide('fireauth.storage.OAuthHandlerManagerTest'); goog.require('fireauth.AuthEvent'); goog.require('fireauth.OAuthHelperState'); goog.require('fireauth.authStorage'); +goog.require('fireauth.common.testHelper'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.OAuthHandlerManager'); goog.require('fireauth.util'); goog.require('goog.Promise'); @@ -34,9 +36,17 @@ goog.setTestOnly('fireauth.storage.OAuthHandlerManagerTest'); var appId = 'appId1'; var stubs = new goog.testing.PropertyReplacer(); +var mockLocalStorage; +var mockSessionStorage; function setUp() { + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); // Simulate browser that synchronizes between and iframe and a popup. stubs.replace( fireauth.util, @@ -49,6 +59,11 @@ function setUp() { } +function tearDown() { + stubs.reset(); +} + + /** * @return {!fireauth.authStorage.Manager} The default local storage * synchronized manager instance used for testing. @@ -72,16 +87,17 @@ function testGetSetRemoveSessionId() { return oauthHandlerManager.getSessionId(appId); }) .then(function(sessionId) { - assertEquals( - window.sessionStorage.getItem(storageKey), - JSON.stringify(expectedSessionId)); assertObjectEquals(expectedSessionId, sessionId); + return mockSessionStorage.get(storageKey); }) - .then(function() { + .then(function(value) { + assertObjectEquals(expectedSessionId, value); return oauthHandlerManager.removeSessionId(appId); }) .then(function() { - assertNull(window.sessionStorage.getItem(storageKey)); + return mockSessionStorage.get(storageKey); + }).then(function(value) { + assertUndefined(value); return oauthHandlerManager.getSessionId(appId); }) .then(function(sessionId) { @@ -104,10 +120,12 @@ function testSetAuthEvent() { return oauthHandlerManager.setAuthEvent(appId, expectedAuthEvent); }) .then(function() { - assertEquals( - JSON.stringify(expectedAuthEvent.toPlainObject()), - window.localStorage.getItem( - 'firebase:authEvent:appId1')); + return mockLocalStorage.get('firebase:authEvent:appId1'); + }) + .then(function(value) { + assertObjectEquals( + expectedAuthEvent.toPlainObject(), + value); }); } @@ -126,10 +144,11 @@ function testSetRedirectEvent() { return oauthHandlerManager.setRedirectEvent(appId, expectedAuthEvent); }) .then(function() { - assertEquals( - JSON.stringify(expectedAuthEvent.toPlainObject()), - window.sessionStorage.getItem( - 'firebase:redirectEvent:appId1')); + return mockSessionStorage.get('firebase:redirectEvent:appId1'); + }).then(function(value) { + assertObjectEquals( + expectedAuthEvent.toPlainObject(), + value); }); } @@ -152,16 +171,18 @@ function testGetSetRemoveOAuthHelperState() { return oauthHandlerManager.getOAuthHelperState(); }) .then(function(state) { - assertEquals( - window.sessionStorage.getItem(storageKey), - JSON.stringify(expectedState.toPlainObject())); assertObjectEquals(expectedState, state); + return mockSessionStorage.get(storageKey); }) - .then(function() { + .then(function(value) { + assertObjectEquals(expectedState.toPlainObject(), value); return oauthHandlerManager.removeOAuthHelperState(); }) .then(function() { - assertNull(window.sessionStorage.getItem(storageKey)); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); return oauthHandlerManager.getOAuthHelperState(); }) .then(function(state) { diff --git a/packages/auth/test/storagependingredirectmanager_test.js b/packages/auth/test/storagependingredirectmanager_test.js index 8ef41d4dbf5..d2ceb2134e1 100644 --- a/packages/auth/test/storagependingredirectmanager_test.js +++ b/packages/auth/test/storagependingredirectmanager_test.js @@ -21,8 +21,9 @@ goog.provide('fireauth.storage.PendingRedirectManagerTest'); goog.require('fireauth.authStorage'); +goog.require('fireauth.common.testHelper'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.PendingRedirectManager'); -goog.require('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.testing.PropertyReplacer'); goog.require('goog.testing.jsunit'); @@ -32,18 +33,19 @@ goog.setTestOnly('fireauth.storage.PendingRedirectManagerTest'); var appId = 'appId1'; var stubs = new goog.testing.PropertyReplacer(); +var mockLocalStorage; +var mockSessionStorage; function setUp() { - // Simulate browser that synchronizes between and iframe and a popup. - stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', - function() { - return false; - }); + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); window.localStorage.clear(); window.sessionStorage.clear(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); } @@ -69,14 +71,16 @@ function testGetSetPendingStatus() { return pendingRedirectManager.getPendingStatus(); }) .then(function(status) { - assertEquals( - window.sessionStorage.getItem(storageKey), - JSON.stringify('pending')); assertTrue(status); + return mockSessionStorage.get(storageKey); + }).then(function(value) { + assertEquals('pending', value); return pendingRedirectManager.removePendingStatus(); }) .then(function() { - assertNull(window.sessionStorage.getItem(storageKey)); + return mockSessionStorage.get(storageKey); + }).then(function(value) { + assertUndefined(value); return pendingRedirectManager.getPendingStatus(); }) .then(function(status) { diff --git a/packages/auth/test/storageredirectusermanager_test.js b/packages/auth/test/storageredirectusermanager_test.js index 40c0242cd95..5350a829e4d 100644 --- a/packages/auth/test/storageredirectusermanager_test.js +++ b/packages/auth/test/storageredirectusermanager_test.js @@ -22,8 +22,9 @@ goog.provide('fireauth.storage.RedirectUserManagerTest'); goog.require('fireauth.AuthUser'); goog.require('fireauth.authStorage'); +goog.require('fireauth.common.testHelper'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.RedirectUserManager'); -goog.require('fireauth.util'); goog.require('goog.Promise'); goog.require('goog.testing.MockClock'); goog.require('goog.testing.PropertyReplacer'); @@ -40,19 +41,20 @@ var clock; var expectedUser; var expectedUserWithAuthDomain; var stubs = new goog.testing.PropertyReplacer(); +var mockLocalStorage; +var mockSessionStorage; function setUp() { - // Simulate browser that synchronizes between and iframe and a popup. - stubs.replace( - fireauth.util, - 'isLocalStorageNotSynchronized', - function() { - return false; - }); + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); clock = new goog.testing.MockClock(true); window.localStorage.clear(); window.sessionStorage.clear(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); } @@ -116,10 +118,11 @@ function testGetSetRemoveRedirectUser() { return redirectUserManager.getRedirectUser(); }) .then(function(user) { - assertEquals( - window.sessionStorage.getItem(storageKey), - JSON.stringify(expectedUser.toPlainObject())); assertObjectEquals(expectedUser, user); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + assertObjectEquals(expectedUser.toPlainObject(), value); // Get user with authDomain. return redirectUserManager.getRedirectUser('project.firebaseapp.com'); }) @@ -128,7 +131,10 @@ function testGetSetRemoveRedirectUser() { return redirectUserManager.removeRedirectUser(); }) .then(function() { - assertNull(window.sessionStorage.getItem(storageKey)); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + assertUndefined(value); return redirectUserManager.getRedirectUser(); }) .then(function(user) { diff --git a/packages/auth/test/storageusermanager_test.js b/packages/auth/test/storageusermanager_test.js index 9d9998bd692..9e80065bab6 100644 --- a/packages/auth/test/storageusermanager_test.js +++ b/packages/auth/test/storageusermanager_test.js @@ -23,6 +23,7 @@ goog.provide('fireauth.storage.UserManagerTest'); goog.require('fireauth.AuthUser'); goog.require('fireauth.authStorage'); goog.require('fireauth.common.testHelper'); +goog.require('fireauth.storage.MockStorage'); goog.require('fireauth.storage.UserManager'); goog.require('fireauth.util'); goog.require('goog.Promise'); @@ -48,9 +49,17 @@ var expectedUserWithAuthDomain; var stubs = new goog.testing.PropertyReplacer(); var testUser; var testUser2; +var mockLocalStorage; +var mockSessionStorage; function setUp() { + // Create new mock storages for persistent and temporary storage before each + // test. + mockLocalStorage = new fireauth.storage.MockStorage(); + mockSessionStorage = new fireauth.storage.MockStorage(); + fireauth.common.testHelper.installMockStorages( + stubs, mockLocalStorage, mockSessionStorage); // Simulate browser that synchronizes between and iframe and a popup. stubs.replace( fireauth.util, @@ -154,10 +163,11 @@ function testGetSetRemoveCurrentUser() { return userManager.getCurrentUser(); }) .then(function(user) { - assertEquals( - window.localStorage.getItem(storageKey), - JSON.stringify(expectedUser.toPlainObject())); - assertObjectEquals(expectedUser, user); + assertObjectEquals(expectedUser.toPlainObject(), user.toPlainObject()); + return mockLocalStorage.get(storageKey); + }) + .then(function(user) { + assertObjectEquals(expectedUser.toPlainObject(), user); // Get user with authDomain. return userManager.getCurrentUser('project.firebaseapp.com'); }) @@ -166,7 +176,10 @@ function testGetSetRemoveCurrentUser() { return userManager.removeCurrentUser(); }) .then(function() { - assertNull(window.localStorage.getItem(storageKey)); + return mockLocalStorage.get(storageKey); + }) + .then(function(user) { + assertUndefined(user); return userManager.getCurrentUser(); }) .then(function(user) { @@ -186,51 +199,51 @@ function testAddRemoveCurrentUserChangeListener() { } }; // Save existing Auth users for appId1 and appId2. - window.localStorage.setItem( - 'firebase:authUser:appId1', - JSON.stringify(testUser.toPlainObject())); - window.localStorage.setItem( - 'firebase:authUser:appId2', - JSON.stringify(testUser.toPlainObject())); - userManager.addCurrentUserChangeListener(listener); - // Simulate appId1 user deletion. - var storageEvent = - new goog.testing.events.Event(goog.events.EventType.STORAGE, window); - storageEvent.key = 'firebase:authUser:appId1'; - storageEvent.oldValue = JSON.stringify(testUser.toPlainObject()); - storageEvent.newValue = null; - window.localStorage.removeItem('firebase:authUser:appId1'); - // This should trigger listener. - goog.testing.events.fireBrowserEvent(storageEvent); - assertEquals(1, calls); - // Simulate appId2 user deletion. - storageEvent.key = 'firebase:authUser:appId2'; - storageEvent.oldValue = JSON.stringify(testUser.toPlainObject()); - storageEvent.newValue = null; - window.localStorage.removeItem('firebase:authUser:appId2'); - // This should not trigger listener. - goog.testing.events.fireBrowserEvent(storageEvent); - assertEquals(1, calls); - // Remove listener. - userManager.removeCurrentUserChangeListener(listener); - // Simulate new user saved for appId1. - // This should not trigger listener. - storageEvent.key = 'firebase:authUser:appId1'; - storageEvent.newValue = JSON.stringify(testUser.toPlainObject()); - storageEvent.oldValue = null; - window.localStorage.setItem( - 'firebase:authUser:appId1', - JSON.stringify(testUser.toPlainObject())); - goog.testing.events.fireBrowserEvent(storageEvent); - assertEquals(1, calls); + mockLocalStorage.set('firebase:authUser:appId1', testUser.toPlainObject()); + mockLocalStorage.set('firebase:authUser:appId2', testUser.toPlainObject()); + return goog.Promise.resolve().then(function() { + return mockLocalStorage.set( + 'firebase:authUser:appId1', testUser.toPlainObject()); + }) + .then(function() { + return mockLocalStorage.set( + 'firebase:authUser:appId2', testUser.toPlainObject()); + }) + .then(function() { + userManager.addCurrentUserChangeListener(listener); + // Simulate appId1 user deletion. + var storageEvent = + new goog.testing.events.Event(goog.events.EventType.STORAGE, window); + storageEvent.key = 'firebase:authUser:appId1'; + storageEvent.oldValue = JSON.stringify(testUser.toPlainObject()); + storageEvent.newValue = null; + // This should trigger listener. + mockLocalStorage.fireBrowserEvent(storageEvent); + assertEquals(1, calls); + // Simulate appId2 user deletion. + storageEvent.key = 'firebase:authUser:appId2'; + storageEvent.oldValue = JSON.stringify(testUser.toPlainObject()); + storageEvent.newValue = null; + // This should not trigger listener. + mockLocalStorage.fireBrowserEvent(storageEvent); + assertEquals(1, calls); + // Remove listener. + userManager.removeCurrentUserChangeListener(listener); + // Simulate new user saved for appId1. + // This should not trigger listener. + storageEvent.key = 'firebase:authUser:appId1'; + storageEvent.newValue = JSON.stringify(testUser.toPlainObject()); + storageEvent.oldValue = null; + mockLocalStorage.fireBrowserEvent(storageEvent); + assertEquals(1, calls); + }); } function testUserManager_initializedWithSession() { // Save state in session storage. var storageKey = 'firebase:authUser:appId1'; - window.sessionStorage.setItem( - storageKey, JSON.stringify(testUser.toPlainObject())); + mockSessionStorage.set(storageKey, testUser.toPlainObject()); var storageManager = getDefaultStorageManagerInstance(); var userManager = new fireauth.storage.UserManager('appId1', storageManager); return userManager.getCurrentUser() @@ -261,14 +274,12 @@ function testUserManager_initializedWithSession_duplicateStorage() { var userManager; // Save state in session storage. var storageKey = 'firebase:authUser:appId1'; - window.sessionStorage.setItem( - storageKey, JSON.stringify(testUser.toPlainObject())); + mockSessionStorage.set(storageKey, testUser.toPlainObject()); // Add state to other types of storage. - window.localStorage.setItem( - storageKey, JSON.stringify(testUser2.toPlainObject())); + mockLocalStorage.set(storageKey, testUser2.toPlainObject()); // Set redirect persistence to none. - window.sessionStorage.setItem( - 'firebase:persistence:appId1', JSON.stringify('none')); + mockSessionStorage.set( + 'firebase:persistence:appId1', 'none'); // Save state using in memory storage. return storageManager.set( {name: 'authUser', persistent: 'none'}, @@ -336,8 +347,7 @@ function testUserManager_initializedWithInMemory() { function testUserManager_initializedWithLocal() { // Save state in local storage. var storageKey = 'firebase:authUser:appId1'; - window.localStorage.setItem( - storageKey, JSON.stringify(testUser.toPlainObject())); + mockLocalStorage.set(storageKey, testUser.toPlainObject()); var storageManager = getDefaultStorageManagerInstance(); var userManager = new fireauth.storage.UserManager('appId1', storageManager); return userManager.getCurrentUser() @@ -362,6 +372,72 @@ function testUserManager_initializedWithLocal() { } +function testUserManager_initializedWithLocal_migratedFromLocalStorage() { + var storageKey = 'firebase:authUser:appId1'; + // Save Auth state to localStorage. This will be migrated to mockLocalStorage. + window.localStorage.setItem( + storageKey, JSON.stringify(testUser.toPlainObject())); + var storageManager = getDefaultStorageManagerInstance(); + var userManager = new fireauth.storage.UserManager('appId1', storageManager); + return userManager.getCurrentUser() + .then(function(user) { + assertObjectEquals(testUser, user); + // User should be cleared from window.localStorage. + assertNull(window.localStorage.getItem(storageKey)); + // User should be saved in mock local storage only with everything else + // cleared. + return fireauth.common.testHelper.assertUserStorage( + 'appId1', 'local', testUser, storageManager); + }) + .then(function() { + // Should be saved in local storage only. + return userManager.setCurrentUser(testUser2); + }) + .then(function() { + return userManager.getCurrentUser(); + }) + .then(function(user) { + assertObjectEquals(testUser2, user); + return fireauth.common.testHelper.assertUserStorage( + 'appId1', 'local', testUser2, storageManager); + }); +} + + +function testUserManager_initializedWithLocal_multiplePersistentStorage() { + var storageKey = 'firebase:authUser:appId1'; + // Save Auth state to window.localStorage. This will be cleared. + window.localStorage.setItem( + storageKey, JSON.stringify(testUser.toPlainObject())); + // Save another Auth state in mockLocalStorage. This will have precedence over + // window.localStorage. + mockLocalStorage.set(storageKey, testUser2.toPlainObject()); + var storageManager = getDefaultStorageManagerInstance(); + var userManager = new fireauth.storage.UserManager('appId1', storageManager); + return userManager.getCurrentUser() + .then(function(user) { + assertObjectEquals(testUser2, user); + // User should be ignored and cleared from window.localStorage. + assertNull(window.localStorage.getItem(storageKey)); + // Existing user saved in mock local storage persisted with everything + // else cleared. + return fireauth.common.testHelper.assertUserStorage( + 'appId1', 'local', testUser2, storageManager); + }) + .then(function() { + return userManager.setCurrentUser(testUser); + }) + .then(function() { + return userManager.getCurrentUser(); + }) + .then(function(user) { + assertObjectEquals(testUser, user); + return fireauth.common.testHelper.assertUserStorage( + 'appId1', 'local', testUser, storageManager); + }); +} + + function testUserManager_initializedWithDefault() { var storageManager = getDefaultStorageManagerInstance(); var userManager = new fireauth.storage.UserManager('appId1', storageManager); @@ -384,8 +460,7 @@ function testUserManager_initializedWithDefault() { function testUserManager_initializedWithSavedPersistence() { // Save redirect persistence. - window.sessionStorage.setItem( - 'firebase:persistence:appId1', JSON.stringify('session')); + mockSessionStorage.set('firebase:persistence:appId1', 'session'); var storageManager = getDefaultStorageManagerInstance(); var userManager = new fireauth.storage.UserManager('appId1', storageManager); return userManager.getCurrentUser() @@ -414,10 +489,11 @@ function testUserManager_savePersistenceForRedirect_default() { return userManager.savePersistenceForRedirect() .then(function() { // Should store persistence value in session storage. - assertEquals( - window.sessionStorage.getItem(storageKey), - // Should apply the current default persistence. - JSON.stringify('local')); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + // Should apply the current default persistence. + assertEquals('local', value); }); } @@ -431,10 +507,11 @@ function testUserManager_savePersistenceForRedirect_modifed() { return userManager.savePersistenceForRedirect() .then(function() { // Should store persistence value in session storage. - assertEquals( - window.sessionStorage.getItem(storageKey), - // The latest modified persistence value should be used. - JSON.stringify('session')); + return mockSessionStorage.get(storageKey); + }) + .then(function(value) { + // The latest modified persistence value should be used. + assertEquals('session', value); }); } @@ -498,8 +575,7 @@ function testUserManager_existingState_setPersistence() { // Test setPersistence behavior with some initial saved persistence state. var storageKey = 'firebase:authUser:appId1'; // Save initial data in local storage. - window.localStorage.setItem( - storageKey, JSON.stringify(testUser2.toPlainObject())); + mockLocalStorage.set(storageKey, testUser2.toPlainObject()); var storageManager = getDefaultStorageManagerInstance(); // As no existing state, the default is local. var userManager = new fireauth.storage.UserManager('appId1', storageManager); @@ -514,8 +590,7 @@ function testUserManager_existingState_setPersistence() { }) .then(function() { // Simulate some state duplication due to some unexpected error. - window.localStorage.setItem( - storageKey, JSON.stringify(testUser.toPlainObject())); + mockLocalStorage.set(storageKey, testUser.toPlainObject()); // Should switch state from session to none and clear everything else. userManager.setPersistence('none'); return userManager.getCurrentUser(); @@ -546,12 +621,10 @@ function testUserManager_switchToLocalOnExternalEvents_noExistingUser() { return userManager.setPersistence('session') .then(function() { // Simulate user signed in in another tab. - window.localStorage.setItem( - storageKey, JSON.stringify(testUser2.toPlainObject())); storageEvent.newValue = JSON.stringify(testUser2.toPlainObject()); // This should trigger listener and switch storage from session to // local. - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.fireBrowserEvent(storageEvent); // Listener should be called. assertEquals(1, listener.getCallCount()); return userManager.getCurrentUser(); @@ -565,7 +638,7 @@ function testUserManager_switchToLocalOnExternalEvents_noExistingUser() { .then(function() { userManager.removeCurrentUserChangeListener(listener); // This should not trigger listener. - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.fireBrowserEvent(storageEvent); assertEquals(1, listener.getCallCount()); }); } @@ -582,8 +655,7 @@ function testUserManager_switchToLocalOnExternalEvents_existingUser() { storageEvent.key = storageKey; storageEvent.newValue = null; // Existing user in session storage. - window.sessionStorage.setItem( - storageKey, JSON.stringify(testUser.toPlainObject())); + mockSessionStorage.set(storageKey, testUser.toPlainObject()); var storageManager = getDefaultStorageManagerInstance(); // Due to existing state in session storage, the initial state is session. @@ -599,11 +671,9 @@ function testUserManager_switchToLocalOnExternalEvents_existingUser() { }) .then(function(user) { // Simulate user signed in in another tab. - window.localStorage.setItem( - storageKey, JSON.stringify(testUser2.toPlainObject())); storageEvent.newValue = JSON.stringify(testUser2.toPlainObject()); // This should trigger listener and switch storage to local. - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.fireBrowserEvent(storageEvent); assertEquals(1, listener.getCallCount()); return userManager.getCurrentUser(); }) @@ -616,7 +686,7 @@ function testUserManager_switchToLocalOnExternalEvents_existingUser() { .then(function() { userManager.removeCurrentUserChangeListener(listener); // This should not trigger listener. - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.fireBrowserEvent(storageEvent); assertEquals(1, listener.getCallCount()); }); } diff --git a/packages/auth/test/testhelper.js b/packages/auth/test/testhelper.js index 163f005a916..b8de22915b3 100644 --- a/packages/auth/test/testhelper.js +++ b/packages/auth/test/testhelper.js @@ -21,6 +21,9 @@ goog.provide('fireauth.common.testHelper'); +goog.require('fireauth.storage.Factory'); +goog.require('goog.Promise'); + goog.setTestOnly('fireauth.common.testHelper'); @@ -121,21 +124,19 @@ fireauth.common.testHelper.assertDeprecatedUserCredentialResponse = function( * check for existence. If null is passed, the check will ensure no user is * saved in storage. * @param {?fireauth.AuthUser} expectedUser The expected Auth user to test for. - * @param {?fireauth.authStorage.Manager=} opt_manager The underlying storage + * @param {?fireauth.authStorage.Manager} manager The underlying storage * manager to use. If none is provided, the default global instance is used. * @return {!goog.Promise} A promise that resolves when the check completes. */ fireauth.common.testHelper.assertUserStorage = - function(appId, persistence, expectedUser, opt_manager) { - // Get storage manager. - var storage = opt_manager || fireauth.authStorage.Manager.getInstance(); + function(appId, persistence, expectedUser, manager) { var promises = []; // All supported persistence types. var types = ['local', 'session', 'none']; // For each persistence type. for (var i = 0; i < types.length; i++) { // Get the current user if stored in current persistence. - var p = storage.get({name: 'authUser', persistent: types[i]}, appId); + var p = manager.get({name: 'authUser', persistent: types[i]}, appId); if (persistence === types[i]) { // If matching specified persistence, ensure value matches the specified // user. @@ -154,3 +155,28 @@ fireauth.common.testHelper.assertUserStorage = // Wait for all checks to complete before resolving. return goog.Promise.all(promises); }; + + +/** + * Installs different persistent/temporary storage using the provided mocks. + * @param {!goog.testing.PropertyReplacer} stub The property replacer. + * @param {!fireauth.storage.Storage} mockLocalStorage The mock storage + * instance for persistent storage. + * @param {!fireauth.storage.Storage} mockSessionStorage The mock storage + * instance for temporary storage. + */ +fireauth.common.testHelper.installMockStorages = + function(stub, mockLocalStorage, mockSessionStorage) { + stub.replace( + fireauth.storage.Factory.prototype, + 'makePersistentStorage', + function() { + return mockLocalStorage; + }); + stub.replace( + fireauth.storage.Factory.prototype, + 'makeTemporaryStorage', + function() { + return mockSessionStorage; + }); +}; diff --git a/packages/auth/test/utils_test.js b/packages/auth/test/utils_test.js index 0d92f0f6e7d..dc8d1a11419 100644 --- a/packages/auth/test/utils_test.js +++ b/packages/auth/test/utils_test.js @@ -22,6 +22,7 @@ goog.provide('fireauth.utilTest'); goog.require('fireauth.util'); goog.require('goog.Timer'); +goog.require('goog.dom'); goog.require('goog.testing.MockControl'); goog.require('goog.testing.PropertyReplacer'); goog.require('goog.testing.TestCase'); @@ -94,6 +95,7 @@ var parsedJSON = { 'someOtherKeyName': false } }; +var lastMetaTag; function setUp() { @@ -105,6 +107,10 @@ function tearDown() { mockControl.$tearDown(); angular = undefined; stubs.reset(); + if (lastMetaTag) { + goog.dom.removeNode(lastMetaTag); + lastMetaTag = null; + } } @@ -494,6 +500,26 @@ function testGetEnvironment_node() { } +function testGetEnvironment_worker() { + // Simulate worker environment. + stubs.replace( + fireauth.util, + 'isWorker', + function() { + return true; + }); + assertEquals(fireauth.util.Env.WORKER, fireauth.util.getEnvironment()); +} + + +function testIsWorker() { + assertFalse(fireauth.util.isWorker({'window': {}})); + assertTrue(fireauth.util.isWorker({ + 'importScripts': function() {} + })); +} + + function testGetBrowserName_opera() { assertEquals('Opera', fireauth.util.getBrowserName(operaUA)); } @@ -601,6 +627,25 @@ function testGetClientVersion_node() { } +function testGetClientVersion_worker() { + var ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like ' + + 'Gecko) Chrome/50.0.2661.94 Safari/537.36'; + var firebaseSdkVersion = '4.9.1'; + // Simulate worker environment. + stubs.replace( + fireauth.util, + 'isWorker', + function() { + return true; + }); + assertEquals( + 'Chrome-Worker/JsCore/4.9.1/FirebaseCore-web', + fireauth.util.getClientVersion( + fireauth.util.ClientImplementation.JSCORE, firebaseSdkVersion, + null, ua)); +} + + function testGetFrameworkIds() { assertArrayEquals([], fireauth.util.getFrameworkIds([])); assertArrayEquals([], fireauth.util.getFrameworkIds(['bla'])); @@ -902,6 +947,35 @@ function testIsPopupRedirectSupported_unsupportedNativeEnvironment() { } +function testIsPopupRedirectSupported_workerEnvironment() { + fireauth.util.isCordovaEnabled = false; + // Web storage supported via indexedDB within worker. + stubs.replace(fireauth.util, 'isWebStorageSupported', function() { + return true; + }); + // HTTPS scheme. + stubs.replace(fireauth.util, 'getCurrentScheme', function() { + return 'https:'; + }); + // Neither iOS, nor Android file environment. + stubs.replace(fireauth.util, 'isAndroidOrIosFileEnvironment', function() { + return false; + }); + // Non-native environment environment. + stubs.replace(fireauth.util, 'isNativeEnvironment', function() { + return false; + }); + // Popup/redirect should be supported with above conditions (minus worker). + assertTrue(fireauth.util.isPopupRedirectSupported()); + // Simulate worker environment. + stubs.replace(fireauth.util, 'isWorker', function() { + return true; + }); + // Popup/redirect no longer supported. + assertFalse(fireauth.util.isPopupRedirectSupported()); +} + + function testIsChromeExtension() { // Test https environment. stubs.replace( @@ -1196,6 +1270,12 @@ function testIsMobileDevice() { fireauth.util.isMobileDevice(chromeUA, fireauth.util.Env.BROWSER)); assertFalse( fireauth.util.isMobileDevice(null, fireauth.util.Env.NODE)); + // For worker environments, the userAgent is still accessible and should be + // used to determine if the current device is a mobile device. + assertTrue( + fireauth.util.isMobileDevice(chriosUA, fireauth.util.Env.WORKER)); + assertFalse( + fireauth.util.isMobileDevice(chromeUA, fireauth.util.Env.WORKER)); } @@ -1247,6 +1327,32 @@ function testIsMobileDevice_mobileEnv_default() { } +function testIsMobileDevice_mobileWorker_default() { + // Simulate mobile browser. + stubs.replace(fireauth.util, 'isMobileBrowser', function(ua) { + return true; + }); + // Whether this is a worker or a non-worker shouldn't matter. + stubs.replace(fireauth.util, 'getEnvironment', function() { + return fireauth.util.Env.WORKER; + }); + assertTrue(fireauth.util.isMobileDevice()); +} + + +function testIsMobileDevice_desktopWorker_default() { + // Simulate desktop browser. + stubs.replace(fireauth.util, 'isMobileBrowser', function(ua) { + return false; + }); + // Whether this is a worker or a non-worker shouldn't matter. + stubs.replace(fireauth.util, 'getEnvironment', function() { + return fireauth.util.Env.WORKER; + }); + assertFalse(fireauth.util.isMobileDevice()); +} + + function testIsOnline_httpOrHttps_online() { // HTTP/HTTPS environment. stubs.replace(fireauth.util, 'isHttpOrHttps', function(ua) { @@ -1394,6 +1500,24 @@ function testDelay_mobileBrowser() { } +function testDelay_desktopBrowser() { + // Whether this is a worker or a non-worker shouldn't matter. + // The userAgent is the authority on how the delay is determined. + var delay = + new fireauth.util.Delay(10, 50, chromeUA, fireauth.util.Env.WORKER); + assertEquals(10, delay.get()); +} + + +function testDelay_mobileBrowser() { + // Whether this is a worker or a non-worker shouldn't matter. + // The userAgent is the authority on how the delay is determined. + var delay = + new fireauth.util.Delay(10, 50, chriosUA, fireauth.util.Env.WORKER); + assertEquals(50, delay.get()); +} + + function testDelay_node() { var delay = new fireauth.util.Delay(10, 50, null, fireauth.util.Env.NODE); assertEquals(10, delay.get()); @@ -1610,3 +1734,98 @@ function testUtcTimestampToDateString() { new Date(1506046529000).toUTCString(), fireauth.util.utcTimestampToDateString(1506046529000)); } + + +function testPersistsStorageWithIndexedDB() { + // SDK only: localStorage not synchronized and indexedDB available. + stubs.replace( + fireauth.util, + 'isAuthHandlerOrIframe', + function() {return false;}); + stubs.replace( + fireauth.util, + 'isLocalStorageNotSynchronized', + function() {return true;}); + stubs.replace( + fireauth.util, + 'isIndexedDBAvailable', + function() {return true;}); + assertTrue(fireauth.util.persistsStorageWithIndexedDB()); + + // SDK only: localStorage synchronized and indexedDB available. + stubs.replace( + fireauth.util, + 'isLocalStorageNotSynchronized', + function() {return false;}); + stubs.replace( + fireauth.util, + 'isIndexedDBAvailable', + function() {return true;}); + assertTrue(fireauth.util.persistsStorageWithIndexedDB()); + + // indexedDB not available. + stubs.reset(); + stubs.replace( + fireauth.util, + 'isIndexedDBAvailable', + function() {return false;}); + assertFalse(fireauth.util.persistsStorageWithIndexedDB()); + + // Auth handler/iframe: localStorage not synchronized and indexedDB available. + stubs.replace( + fireauth.util, + 'isAuthHandlerOrIframe', + function() {return true;}); + stubs.replace( + fireauth.util, + 'isLocalStorageNotSynchronized', + function() {return true;}); + stubs.replace( + fireauth.util, + 'isIndexedDBAvailable', + function() {return true;}); + assertTrue(fireauth.util.persistsStorageWithIndexedDB()); + + // Auth handler/iframe: localStorage synchronized and indexedDB available. + stubs.replace( + fireauth.util, + 'isAuthHandlerOrIframe', + function() {return true;}); + stubs.replace( + fireauth.util, + 'isLocalStorageNotSynchronized', + function() {return false;}); + stubs.replace( + fireauth.util, + 'isIndexedDBAvailable', + function() {return true;}); + assertFalse(fireauth.util.persistsStorageWithIndexedDB()); +} + + +/** + * @return {?HTMLElement} The last meta element if available in the head + * element. + */ +function getLastMetaTag() { + var collection = goog.dom.getElementsByTagName('head'); + if (collection.length) { + var metaTags = goog.dom.getElementsByTagName('meta', collection[0]); + if (metaTags.length > 0) { + return metaTags[metaTags.length - 1]; + } + } + return null; +} + + +function testSetNoReferrer() { + lastMetaTag = getLastMetaTag(); + if (lastMetaTag) { + assertNotEquals('referrer', lastMetaTag.getAttribute('name')); + } + fireauth.util.setNoReferrer(); + lastMetaTag = getLastMetaTag(); + assertEquals('referrer', lastMetaTag.getAttribute('name')); + assertEquals('no-referrer', lastMetaTag.getAttribute('content')); +} From df183a5ce45c435e9d36dbb1125cd244a2dc044c Mon Sep 17 00:00:00 2001 From: Michael Lehenbauer Date: Thu, 15 Mar 2018 12:04:02 -0700 Subject: [PATCH 33/34] Remove assert I accidentally left in (I meant to remove it when I re-added the defensive check above). (#565) --- packages/firestore/CHANGELOG.md | 6 +++--- packages/firestore/src/remote/persistent_stream.ts | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/firestore/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 13899391aa2..24f75bf6ee2 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -1,7 +1,7 @@ # Unreleased -- [fixed] Fixed a regression in the Firebase JS release 4.11.0 that could - cause a crash if a user signs out while the client is offline, resulting in - an error of "Attempted to schedule multiple operations with timer id +- [fixed] Fixed a regression in the Firebase JS release 4.11.0 that could + cause a crash if a user signs out while the client is offline, resulting in + an error of "Attempted to schedule multiple operations with timer id listen_stream_connection_backoff". # 0.3.5 diff --git a/packages/firestore/src/remote/persistent_stream.ts b/packages/firestore/src/remote/persistent_stream.ts index 0a8468d50e8..8d087c7ba10 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -472,11 +472,6 @@ export abstract class PersistentStream< return; } - assert( - this.state === PersistentStreamState.Backoff, - 'Backoff should have been canceled if we left the Backoff state.' - ); - this.state = PersistentStreamState.Initial; this.start(listener); assert(this.isStarted(), 'PersistentStream should have started'); From 2a5d3f69890108d32daf9c722c7ddfb7ae3c13cc Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 16 Mar 2018 12:37:16 -0700 Subject: [PATCH 34/34] Manual merge --- .../src/local/indexeddb_persistence.ts | 4 +- .../firestore/src/local/indexeddb_schema.ts | 54 ++++++----- .../firestore/src/local/memory_persistence.ts | 4 - packages/firestore/src/util/async_queue.ts | 2 +- .../test/unit/local/indexeddb_schema.test.ts | 31 +++++-- .../test/unit/local/schema_migration.test.ts | 90 ------------------- .../test/unit/local/test_query_cache.ts | 2 +- .../test/unit/specs/persistence_spec.test.ts | 4 +- .../firestore/test/unit/specs/spec_builder.ts | 2 +- 9 files changed, 62 insertions(+), 131 deletions(-) delete mode 100644 packages/firestore/test/unit/local/schema_migration.test.ts diff --git a/packages/firestore/src/local/indexeddb_persistence.ts b/packages/firestore/src/local/indexeddb_persistence.ts index b6368ab96d3..512075c2bdc 100644 --- a/packages/firestore/src/local/indexeddb_persistence.ts +++ b/packages/firestore/src/local/indexeddb_persistence.ts @@ -422,9 +422,7 @@ export class IndexedDbPersistence implements Persistence { return false; } else if (updateTimeMs > maxAcceptable) { log.error( - `Detected an update time that is in the future: ${updateTimeMs} > ${ - maxAcceptable - }` + `Detected an update time that is in the future: ${updateTimeMs} > ${maxAcceptable}` ); return false; } diff --git a/packages/firestore/src/local/indexeddb_schema.ts b/packages/firestore/src/local/indexeddb_schema.ts index ae5f71b3978..34e049f884c 100644 --- a/packages/firestore/src/local/indexeddb_schema.ts +++ b/packages/firestore/src/local/indexeddb_schema.ts @@ -62,13 +62,15 @@ export function createOrUpgradeDb( if (fromVersion < 2 && toVersion >= 2) { p = ensureTargetGlobalExists(txn).next(targetGlobal => - saveTargetCount(txn, targetGlobal) + saveTargetCount(txn, targetGlobal) ); } if (fromVersion < 3 && toVersion >= 3) { - createClientMetadataStore(db); - createTargetChangeStore(db); + p = p.next(() => { + createClientMetadataStore(db); + createTargetChangeStore(db); + }); } return p; } @@ -517,11 +519,11 @@ function createQueryCache(db: IDBDatabase): void { * global singleton. */ function saveTargetCount( - txn: SimpleDbTransaction, - metadata: DbTargetGlobal + txn: SimpleDbTransaction, + metadata: DbTargetGlobal ): PersistencePromise { const globalStore = txn.store( - DbTargetGlobal.store + DbTargetGlobal.store ); const targetStore = txn.store(DbTarget.store); return targetStore.count().next(count => { @@ -537,24 +539,24 @@ function saveTargetCount( * @param {IDBTransaction} txn The version upgrade transaction for indexeddb */ function ensureTargetGlobalExists( - txn: SimpleDbTransaction + txn: SimpleDbTransaction ): PersistencePromise { const globalStore = txn.store( - DbTargetGlobal.store + DbTargetGlobal.store ); return globalStore.get(DbTargetGlobal.key).next(metadata => { - if (metadata != null) { - return PersistencePromise.resolve(metadata); - } else { - metadata = new DbTargetGlobal( - /*highestTargetId=*/ 0, - /*lastListenSequenceNumber=*/ 0, - SnapshotVersion.MIN.toTimestamp(), - /*targetCount=*/ 0 - ); - return globalStore.put(DbTargetGlobal.key, metadata).next(() => metadata); - } - }); + if (metadata != null) { + return PersistencePromise.resolve(metadata); + } else { + metadata = new DbTargetGlobal( + /*highestTargetId=*/ 0, + /*lastListenSequenceNumber=*/ 0, + SnapshotVersion.MIN.toTimestamp(), + /*targetCount=*/ 0 + ); + return globalStore.put(DbTargetGlobal.key, metadata).next(() => metadata); + } + }); } /** @@ -642,11 +644,19 @@ export const V1_STORES = [ DbTargetDocument.store ]; -const V3_STORES = [DbClientMetadata.store, DbTargetChange.store]; +// Visible for testing +export const V2_STORES = V1_STORES; + +// Visible for testing +export const V3_STORES = [ + ...V2_STORES, + DbClientMetadata.store, + DbTargetChange.store +]; /** * The list of all default IndexedDB stores used throughout the SDK. This is * used when creating transactions so that access across all stores is done * atomically. */ -export const ALL_STORES = [...V1_STORES, ...V3_STORES]; +export const ALL_STORES = V3_STORES; diff --git a/packages/firestore/src/local/memory_persistence.ts b/packages/firestore/src/local/memory_persistence.ts index 0f54ad2d29a..32d67743b90 100644 --- a/packages/firestore/src/local/memory_persistence.ts +++ b/packages/firestore/src/local/memory_persistence.ts @@ -52,14 +52,10 @@ export class MemoryPersistence implements Persistence { private started = false; -<<<<<<< HEAD constructor(private readonly queue: AsyncQueue) {} - start(): Promise { -======= async start(): Promise { // No durable state to read on startup. ->>>>>>> master assert(!this.started, 'MemoryPersistence double-started!'); this.started = true; } diff --git a/packages/firestore/src/util/async_queue.ts b/packages/firestore/src/util/async_queue.ts index 57343b73601..e5655291332 100644 --- a/packages/firestore/src/util/async_queue.ts +++ b/packages/firestore/src/util/async_queue.ts @@ -56,7 +56,7 @@ export enum TimerId { * A timer used to update the client metadata in IndexedDb, which is used * to determine the primary leaseholder. */ - ClientMetadataRefresh = 'client_metadata_refresh', + ClientMetadataRefresh = 'client_metadata_refresh' } /** diff --git a/packages/firestore/test/unit/local/indexeddb_schema.test.ts b/packages/firestore/test/unit/local/indexeddb_schema.test.ts index 50ad0212645..019b3c3cbbd 100644 --- a/packages/firestore/test/unit/local/indexeddb_schema.test.ts +++ b/packages/firestore/test/unit/local/indexeddb_schema.test.ts @@ -17,11 +17,13 @@ import { expect } from 'chai'; import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence'; import { - ALL_STORES, createOrUpgradeDb, DbTarget, DbTargetGlobal, - DbTargetGlobalKey + DbTargetGlobalKey, + V1_STORES, + V2_STORES, + V3_STORES } from '../../../src/local/indexeddb_schema'; import { SimpleDb, SimpleDbTransaction } from '../../../src/local/simple_db'; import { PersistencePromise } from '../../../src/local/persistence_promise'; @@ -88,11 +90,10 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => { beforeEach(() => SimpleDb.delete(INDEXEDDB_TEST_DATABASE)); it('can install schema version 1', () => { - return withDb(1, db => { + return withDb(1, async db => { expect(db.version).to.equal(1); // Version 1 adds all of the stores so far. - expect(getAllObjectStores(db)).to.have.members(ALL_STORES); - return Promise.resolve(); + expect(getAllObjectStores(db)).to.have.members(V1_STORES); }); }); @@ -101,7 +102,7 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => { expect(db.version).to.equal(2); // We should have all of the stores, we should have the target global row // and we should not have any targets counted, because there are none. - expect(getAllObjectStores(db)).to.have.members(ALL_STORES); + expect(getAllObjectStores(db)).to.have.members(V2_STORES); // Check the target count. We haven't added any targets, so we expect 0. return getTargetCount(db).then(targetCount => { expect(targetCount).to.equal(0); @@ -109,6 +110,13 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => { }); }); + it('can install schema version 3', () => { + return withDb(3, async db => { + expect(db.version).to.be.equal(3); + expect(getAllObjectStores(db)).to.have.members(V3_STORES); + }); + }); + it('can upgrade from schema version 1 to 2', () => { const expectedTargetCount = 5; return withDb(1, db => { @@ -126,11 +134,20 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => { }).then(() => withDb(2, db => { expect(db.version).to.equal(2); - expect(getAllObjectStores(db)).to.have.members(ALL_STORES); + expect(getAllObjectStores(db)).to.have.members(V2_STORES); return getTargetCount(db).then(targetCount => { expect(targetCount).to.equal(expectedTargetCount); }); }) ); }); + + it('can upgrade from schema version 2 to 3', () => { + return withDb(2, async () => {}).then(() => + withDb(3, async db => { + expect(db.version).to.be.equal(3); + expect(getAllObjectStores(db)).to.have.members(V3_STORES); + }) + ); + }); }); diff --git a/packages/firestore/test/unit/local/schema_migration.test.ts b/packages/firestore/test/unit/local/schema_migration.test.ts deleted file mode 100644 index 3faad875333..00000000000 --- a/packages/firestore/test/unit/local/schema_migration.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright 2018 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { expect } from 'chai'; -import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence'; -import { - ALL_STORES, - createOrUpgradeDb, - V1_STORES -} from '../../../src/local/indexeddb_schema'; -import { Deferred } from '../../../src/util/promise'; -import { SimpleDb } from '../../../src/local/simple_db'; - -const INDEXEDDB_TEST_DATABASE = 'schemaTest'; - -function withDb(schemaVersion, fn: (db: IDBDatabase) => void): Promise { - return new Promise((resolve, reject) => { - const request = window.indexedDB.open( - INDEXEDDB_TEST_DATABASE, - schemaVersion - ); - request.onupgradeneeded = (event: IDBVersionChangeEvent) => { - const db = (event.target as IDBOpenDBRequest).result; - createOrUpgradeDb(db, event.oldVersion, schemaVersion); - }; - request.onsuccess = (event: Event) => { - resolve((event.target as IDBOpenDBRequest).result); - }; - request.onerror = (event: ErrorEvent) => { - reject((event.target as IDBOpenDBRequest).error); - }; - }).then(db => { - fn(db); - db.close(); - }); -} - -function getAllObjectStores(db: IDBDatabase): String[] { - const objectStores: String[] = []; - for (let i = 0; i < db.objectStoreNames.length; ++i) { - objectStores.push(db.objectStoreNames.item(i)); - } - objectStores.sort(); - return objectStores; -} - -describe('IndexedDbSchema: createOrUpgradeDb', () => { - if (!IndexedDbPersistence.isAvailable()) { - console.warn('No IndexedDB. Skipping createOrUpgradeDb() tests.'); - return; - } - - beforeEach(() => SimpleDb.delete(INDEXEDDB_TEST_DATABASE)); - - it('can install schema version 1', () => { - return withDb(1, db => { - expect(db.version).to.be.equal(1); - expect(getAllObjectStores(db)).to.have.members(V1_STORES); - }); - }); - - it('can install schema version 2', () => { - return withDb(2, db => { - expect(db.version).to.be.equal(2); - expect(getAllObjectStores(db)).to.have.members(ALL_STORES); - }); - }); - - it('can upgrade from schema version 1 to 2', () => { - return withDb(1, () => {}).then(() => - withDb(2, db => { - expect(db.version).to.be.equal(2); - expect(getAllObjectStores(db)).to.have.members(ALL_STORES); - }) - ); - }); -}); diff --git a/packages/firestore/test/unit/local/test_query_cache.ts b/packages/firestore/test/unit/local/test_query_cache.ts index 6862057dcab..2e289309e42 100644 --- a/packages/firestore/test/unit/local/test_query_cache.ts +++ b/packages/firestore/test/unit/local/test_query_cache.ts @@ -43,7 +43,7 @@ export class TestQueryCache { } updateQueryData(queryData: QueryData): Promise { - return this.persistence.runTransaction('updateQueryData', txn => { + return this.persistence.runTransaction('updateQueryData', true, txn => { return this.cache.updateQueryData(txn, queryData); }); } diff --git a/packages/firestore/test/unit/specs/persistence_spec.test.ts b/packages/firestore/test/unit/specs/persistence_spec.test.ts index f9ce0311bc7..5e884aa73a0 100644 --- a/packages/firestore/test/unit/specs/persistence_spec.test.ts +++ b/packages/firestore/test/unit/specs/persistence_spec.test.ts @@ -20,7 +20,7 @@ import { doc, path } from '../../util/helpers'; import { describeSpec, specTest } from './describe_spec'; import { client, spec } from './spec_builder'; -import {TimerId} from '../../../src/util/async_queue'; +import { TimerId } from '../../../src/util/async_queue'; describeSpec('Persistence:', [], () => { specTest('Local mutations are persisted and re-sent', [], () => { @@ -223,7 +223,7 @@ describeSpec('Persistence:', [], () => { .runTimer(TimerId.ClientMetadataRefresh) .expectPrimaryState(false) .client(2) - .runTimer(TimerId.ClientMetadataRefresh) + .runTimer(TimerId.ClientMetadataRefresh) .expectPrimaryState(true) ); }); diff --git a/packages/firestore/test/unit/specs/spec_builder.ts b/packages/firestore/test/unit/specs/spec_builder.ts index b308e2f53b7..6b7107b7c20 100644 --- a/packages/firestore/test/unit/specs/spec_builder.ts +++ b/packages/firestore/test/unit/specs/spec_builder.ts @@ -209,7 +209,7 @@ export class SpecBuilder { becomeVisible(): SpecBuilder { this.nextStep(); this.currentStep = { - applyClientState: {visibility: 'visible'} + applyClientState: { visibility: 'visible' } }; return this; }