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/.travis.yml b/.travis.yml index 2170d596802..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 - - 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 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/browserify/package.json b/integration/browserify/package.json index 7588b72c9e4..f0bae00439c 100644 --- a/integration/browserify/package.json +++ b/integration/browserify/package.json @@ -7,17 +7,17 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.11.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 a8e1b0a972a..9ec96a60940 100644 --- a/integration/firebase-typings/package.json +++ b/integration/firebase-typings/package.json @@ -6,9 +6,9 @@ "test": "tsc index.ts --outDir dist" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.11.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 6a16a07f05a..a0b74e0e028 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -8,16 +8,16 @@ "test:manual": "mocha --exit" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.11.0" }, "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/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/integration/typescript/package.json b/integration/typescript/package.json index 94c169910bb..25eb9345c5f 100644 --- a/integration/typescript/package.json +++ b/integration/typescript/package.json @@ -6,21 +6,21 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.11.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 d159273a94a..d3fd988ebe8 100644 --- a/integration/webpack/package.json +++ b/integration/webpack/package.json @@ -7,16 +7,16 @@ "test": "karma start --single-run" }, "dependencies": { - "firebase": "4.9.1" + "firebase": "4.11.0" }, "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..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", @@ -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 309750b3173..8b3efc66af3 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.10", "description": "The primary entrypoint to the Firebase JS SDK", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -15,35 +15,36 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/app-types": "0.1.1", - "@firebase/util": "0.1.8" + "@firebase/app-types": "0.1.2", + "@firebase/util": "0.1.10", + "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/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-types/package.json b/packages/auth-types/package.json index 1ce00901bca..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", @@ -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/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..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(); } @@ -312,6 +320,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 +632,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 +712,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 +1098,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 +1127,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 +1315,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 +1372,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/package.json b/packages/auth/package.json index 3d49714c26d..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,18 +21,18 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/auth-types": "0.1.1" + "@firebase/auth-types": "0.1.2" }, "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/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/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 8f93162e404..ebaa755de77 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')] @@ -299,6 +320,9 @@ fireauth.exportlib.exportPrototypeMethods( fireauth.exportlib.exportPrototypeMethods( goog.Promise.prototype, { + thenAlways: { + name: 'finally' + }, thenCatch: { name: 'catch' }, @@ -341,6 +365,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/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 a127553d08b..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; }; @@ -231,6 +261,7 @@ fireauth.RpcHandler.AuthServerField = { REFRESH_TOKEN: 'refreshToken', SESSION_ID: 'sessionId', SESSION_INFO: 'sessionInfo', + SIGNIN_METHODS: 'signinMethods', TEMPORARY_PROOF: 'temporaryProof' }; @@ -240,6 +271,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' @@ -392,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 { @@ -430,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; @@ -883,6 +909,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 +1107,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 +1393,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 +1438,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 +1923,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 +1945,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/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/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..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, @@ -1349,6 +1344,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 +1495,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. @@ -1762,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() @@ -1900,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. @@ -1999,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, @@ -2063,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. @@ -2128,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. @@ -2260,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. @@ -2392,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. @@ -2465,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. @@ -2557,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. @@ -2619,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. @@ -2756,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. @@ -2877,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); @@ -2928,7 +3088,7 @@ function testAuth_syncAuthChanges_newSignIn_differentAuthDomain() { asyncTestCase.signal(); }); // This should force localstorage sync. - goog.testing.events.fireBrowserEvent(storageEvent); + mockLocalStorage.fireBrowserEvent(storageEvent); }); }); } @@ -2952,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. @@ -3061,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 @@ -3151,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 @@ -3285,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 @@ -3733,6 +3889,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; @@ -6565,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, @@ -6879,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, @@ -6987,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, @@ -7123,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', @@ -7242,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, @@ -7440,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, @@ -7568,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, @@ -7663,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, @@ -8572,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'); @@ -8580,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(); }); @@ -8622,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(); }); @@ -8676,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(); @@ -8691,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(); }); @@ -8710,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(); }); } @@ -8792,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(); }); @@ -8897,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/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/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/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/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 61683157519..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. @@ -1641,6 +1774,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', @@ -2081,7 +2340,108 @@ function testVerifyCustomToken_unknownServerResponse() { rpcHandler.verifyCustomToken('CUSTOM_TOKEN').thenCatch( function(error) { fireauth.common.testHelper.assertErrorEquals( - new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + new fireauth.AuthError(fireauth.authenum.Error.INTERNAL_ERROR), + error); + asyncTestCase.signal(); + }); +} + + +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(); }); @@ -3093,6 +3453,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 +4694,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/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')); +} 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-types/package.json b/packages/database-types/package.json index 54f46d4f7bb..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.1", + "version": "0.2.0", "description": "@firebase/database Types", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -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/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: { diff --git a/packages/database/package.json b/packages/database/package.json index e04cbdd986a..f7b8e41f419 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/database", - "version": "0.1.9", + "version": "0.2.0", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", @@ -19,34 +19,36 @@ "@firebase/app-types": "^0.1.0" }, "dependencies": { - "@firebase/database-types": "0.1.1", - "@firebase/util": "0.1.8", - "faye-websocket": "0.11.1" + "@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" }, "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/src/api/Database.ts b/packages/database/src/api/Database.ts index 95d8430495c..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_; } /** @@ -132,7 +143,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 +151,5 @@ export class DatabaseInternals { (this.database as any).root_ = null; this.database.INTERNAL = null; this.database = null; - return Promise.resolve(); } } 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/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; diff --git a/packages/database/src/core/util/util.ts b/packages/database/src/core/util/util.ts index bd501505ea9..efb003161ee 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, LogLevel } 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,8 @@ 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); - }; - } - } + logClient.logLevel = LogLevel.VERBOSE; + logger = logClient.log.bind(logClient); if (persistent) SessionStorage.set('logging_enabled', true); } else if (typeof logger_ === 'function') { logger = logger_; @@ -157,36 +152,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/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'); 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/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 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; } } diff --git a/packages/firebase/package.json b/packages/firebase/package.json index 2a0e53ce917..da296300ce6 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "firebase", - "version": "4.9.1", + "version": "4.11.0", "description": "Firebase JavaScript library for web and Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", @@ -27,26 +27,26 @@ "browser": "index.js", "react-native": "index.react-native.js", "dependencies": { - "@firebase/app": "0.1.8", - "@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/app": "0.1.10", + "@firebase/auth": "0.3.4", + "@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" }, "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..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", @@ -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/CHANGELOG.md b/packages/firestore/CHANGELOG.md index 322bb768de3..24f75bf6ee2 100644 --- a/packages/firestore/CHANGELOG.md +++ b/packages/firestore/CHANGELOG.md @@ -1,4 +1,19 @@ # 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 + 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 cases result in an "OnlineState should not affect limbo documents." assertion crash when the client loses its network connection. diff --git a/packages/firestore/package.json b/packages/firestore/package.json index 445e4da54bc..2f74a41096e 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.5", "description": "", "author": "Firebase (https://firebase.google.com/)", "scripts": { @@ -22,40 +22,42 @@ "module": "dist/esm/index.js", "license": "Apache-2.0", "dependencies": { - "@firebase/firestore-types": "0.2.1", + "@firebase/firestore-types": "0.2.2", + "@firebase/logger": "0.1.0", "@firebase/webchannel-wrapper": "0.2.6", - "grpc": "^1.7.1" + "grpc": "^1.9.1", + "tslib": "^1.9.0" }, "peerDependencies": { "@firebase/app": "^0.1.0", "@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/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..2b4311886c0 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(); } } @@ -250,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) { @@ -264,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 fe65f132b89..07fe4a7b79d 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -293,6 +293,7 @@ export class FirestoreClient { this.remoteStore = new RemoteStore( this.localStore, datastore, + this.asyncQueue, onlineStateChangedHandler ); @@ -383,11 +384,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/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/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/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_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 1894d209af5..34e049f884c 100644 --- a/packages/firestore/src/local/indexeddb_schema.ts +++ b/packages/firestore/src/local/indexeddb_schema.ts @@ -21,12 +21,18 @@ 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'; /** - * Schema Version for the Web client (containing the Mutation Queue, the Query - * and the Remote Document Cache) and Multi-Tab Support. + * Schema Version for the Web client: + * 1. Initial version including Mutation Queue, Query Cache, and Remote Document + * Cache + * 2. Added targetCount to targetGlobal row. + * 3. Multi-Tab Support. */ -export const SCHEMA_VERSION = 2; +export const SCHEMA_VERSION = 3; /** * Performs database creation and schema upgrades. @@ -37,15 +43,15 @@ export const SCHEMA_VERSION = 2; */ export function createOrUpgradeDb( db: IDBDatabase, + txn: SimpleDbTransaction, fromVersion: number, toVersion: number -): void { - // This function currently supports migrating to schema version 1 (Mutation - // Queue, Query and Remote Document Cache) and schema version 2 (Multi-Tab). +): PersistencePromise { assert( - fromVersion < toVersion && fromVersion >= 0 && toVersion <= 2, + fromVersion < toVersion && fromVersion >= 0 && toVersion <= 3, 'Unexpected schema upgrade from v${fromVersion} to v{toVersion}.' ); + let p = PersistencePromise.resolve(); if (fromVersion < 1 && toVersion >= 1) { createOwnerStore(db); @@ -55,9 +61,18 @@ export function createOrUpgradeDb( } if (fromVersion < 2 && toVersion >= 2) { - createClientMetadataStore(db); - createTargetChangeStore(db); + p = ensureTargetGlobalExists(txn).next(targetGlobal => + saveTargetCount(txn, targetGlobal) + ); } + + if (fromVersion < 3 && toVersion >= 3) { + p = p.next(() => { + createClientMetadataStore(db); + createTargetChangeStore(db); + }); + } + return p; } // TODO(mikelehen): Get rid of "as any" if/when TypeScript fixes their types. @@ -468,7 +483,11 @@ 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 ) {} } @@ -495,6 +514,51 @@ function createQueryCache(db: IDBDatabase): void { 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); + } + }); +} + /** * An object representing the changes at a particular snapshot version for the * given target. This is used to facilitate storing query changelogs in the @@ -580,11 +644,19 @@ export const V1_STORES = [ DbTargetDocument.store ]; -const V2_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, ...V2_STORES]; +export const ALL_STORES = V3_STORES; diff --git a/packages/firestore/src/local/local_store.ts b/packages/firestore/src/local/local_store.ts index 214bf186c6f..e0602e20f5f 100644 --- a/packages/firestore/src/local/local_store.ts +++ b/packages/firestore/src/local/local_store.ts @@ -491,7 +491,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_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/src/local/memory_persistence.ts b/packages/firestore/src/local/memory_persistence.ts index 86e1b43452d..32d67743b90 100644 --- a/packages/firestore/src/local/memory_persistence.ts +++ b/packages/firestore/src/local/memory_persistence.ts @@ -54,18 +54,16 @@ export class MemoryPersistence implements Persistence { constructor(private readonly queue: AsyncQueue) {} - 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(); } setPrimaryStateListener(primaryStateListener: PrimaryStateListener) { 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 8adbcad37d5..5be70f9cced 100644 --- a/packages/firestore/src/local/simple_db.ts +++ b/packages/firestore/src/local/simple_db.ts @@ -37,9 +37,10 @@ export class SimpleDb { version: number, runUpgrade: ( db: IDBDatabase, + txn: SimpleDbTransaction, fromVersion: number, toVersion: number - ) => void + ) => PersistencePromise ): Promise { assert( SimpleDb.isAvailable(), @@ -50,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) => { @@ -68,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, SCHEMA_VERSION); + // 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(); } @@ -129,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 @@ -229,7 +234,6 @@ export interface IterateOptions { * specific object store. */ export class SimpleDbTransaction { - private transaction: IDBTransaction; private aborted = false; /** @@ -240,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. @@ -347,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_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 }; 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/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/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 2155e23ba1a..8d087c7ba10 100644 --- a/packages/firestore/src/remote/persistent_stream.ts +++ b/packages/firestore/src/remote/persistent_stream.ts @@ -265,19 +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 - }` - ); - }); } } @@ -288,13 +275,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 +305,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 { @@ -328,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(); @@ -361,8 +352,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 +392,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 +400,6 @@ export abstract class PersistentStream< 'Fetching auth token failed: ' + error.message ); return this.handleStreamClose(rpcError); - } else { - return Promise.resolve(); } }); } @@ -436,12 +423,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 +465,16 @@ 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(); + // We should have canceled the backoff timer when the stream was + // closed, but just in case we make this a no-op. + return; } this.state = PersistentStreamState.Initial; this.start(listener); assert(this.isStarted(), 'PersistentStream should have started'); - return Promise.resolve(); }); } @@ -539,7 +524,7 @@ export class PersistentListenStream extends PersistentStream< ) { super( queue, - TimerId.ListenStreamConnection, + TimerId.ListenStreamConnectionBackoff, TimerId.ListenStreamIdle, connection, credentials @@ -647,7 +632,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 9dba21b9901..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. }); } @@ -232,11 +178,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(); + // Set the OnlineState to Offline so get()s return from cache, etc. + this.onlineStateTracker.set(OnlineState.Offline); } /** @@ -260,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(); } @@ -337,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 ( @@ -360,42 +307,42 @@ 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' ); 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); } - return Promise.resolve(); } - private onWatchStreamChange( + private async onWatchStreamChange( 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 && @@ -419,8 +366,6 @@ export class RemoteStore { const changes = this.accumulatedWatchChanges; this.accumulatedWatchChanges = []; return this.handleWatchChangeBatch(snapshotVersion, changes); - } else { - return Promise.resolve(); } } @@ -558,13 +503,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 +529,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 +538,6 @@ export class RemoteStore { if (this.pendingWrites.length === 0) { this.writeStream.markIdle(); } - return Promise.resolve(); } else { this.commit(batch); return this.fillWritePipeline(); @@ -669,10 +609,8 @@ export class RemoteStore { }); } - private onWriteStreamOpen(): Promise { + private async onWriteStreamOpen(): Promise { this.writeStream.writeHandshake(); - - return Promise.resolve(); } private onWriteHandshakeComplete(): Promise { @@ -723,7 +661,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 +693,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 +712,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 +735,6 @@ export class RemoteStore { }); } else { // Transient error, just let the retry logic kick in. - return Promise.resolve(); } } @@ -818,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 e4aaab59033..e5655291332 100644 --- a/packages/firestore/src/util/async_queue.ts +++ b/packages/firestore/src/util/async_queue.ts @@ -27,13 +27,36 @@ 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, - ClientMetadataRefresh + /** 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', + + /** + * A timer used to update the client metadata in IndexedDb, which is used + * to determine the primary leaseholder. + */ + ClientMetadataRefresh = 'client_metadata_refresh' } /** @@ -56,7 +79,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 @@ -227,9 +255,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( @@ -285,16 +311,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}` ); @@ -303,7 +330,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/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/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/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..a9820691496 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(); } }); }); @@ -172,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); @@ -363,11 +359,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 +460,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 +469,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 +482,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 +770,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 +780,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..8faabc26763 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(); } } @@ -260,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/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..019b3c3cbbd --- /dev/null +++ b/packages/firestore/test/unit/local/indexeddb_schema.test.ts @@ -0,0 +1,153 @@ +/** + * 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 { + createOrUpgradeDb, + DbTarget, + DbTargetGlobal, + 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'; + +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, async db => { + expect(db.version).to.equal(1); + // Version 1 adds all of the stores so far. + expect(getAllObjectStores(db)).to.have.members(V1_STORES); + }); + }); + + 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(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); + }); + }); + }); + + 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 => { + 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(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/mutation_queue.test.ts b/packages/firestore/test/unit/local/mutation_queue.test.ts index f2ea4bf85e3..51a37daf8e0 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/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/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/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 d4439ca52ea..2e289309e42 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', true, txn => { + return this.cache.updateQueryData(txn, queryData); + }); + } + + count(): number { + return this.cache.count; + } + removeQueryData(queryData: QueryData): Promise { return this.persistence.runTransaction('addQueryData', true, txn => { return this.cache.removeQueryData(txn, queryData); 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/persistence_spec.test.ts b/packages/firestore/test/unit/specs/persistence_spec.test.ts index 1acfb725f79..5e884aa73a0 100644 --- a/packages/firestore/test/unit/specs/persistence_spec.test.ts +++ b/packages/firestore/test/unit/specs/persistence_spec.test.ts @@ -20,6 +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'; describeSpec('Persistence:', [], () => { specTest('Local mutations are persisted and re-sent', [], () => { @@ -196,7 +197,7 @@ describeSpec('Persistence:', [], () => { .client(0) .shutdown() .client(1) - .tryAcquirePrimaryLease() + .runTimer(TimerId.ClientMetadataRefresh) .expectPrimaryState(true); }); @@ -219,10 +220,10 @@ describeSpec('Persistence:', [], () => { .client(1) // Client 1 is in the background and doesn't grab the primary lease as // client 2 is in the foreground. - .tryAcquirePrimaryLease() + .runTimer(TimerId.ClientMetadataRefresh) .expectPrimaryState(false) .client(2) - .tryAcquirePrimaryLease() + .runTimer(TimerId.ClientMetadataRefresh) .expectPrimaryState(true) ); }); 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 58e3b865faf..6b7107b7c20 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 @@ -213,6 +214,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 }; @@ -254,17 +261,6 @@ export class SpecBuilder { return this; } - // TODO: Replace with .runTimer(TimerId.ClientStateRefresh) once #412 is - // merged. - // PORTING NOTE: Only used by web multi-tab tests. - tryAcquirePrimaryLease(): SpecBuilder { - this.nextStep(); - this.currentStep = { - acquirePrimaryLease: true - }; - return this; - } - shutdown(): SpecBuilder { this.nextStep(); this.currentStep = { @@ -537,14 +533,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; @@ -777,6 +781,11 @@ export class MultiClientSpecBuilder extends SpecBuilder { return this; } + runTimer(timerId: TimerId) { + super.runTimer(timerId); + return this; + } + changeUser(uid: string | null): MultiClientSpecBuilder { super.changeUser(uid); return this; @@ -797,11 +806,6 @@ export class MultiClientSpecBuilder extends SpecBuilder { return this; } - tryAcquirePrimaryLease(): MultiClientSpecBuilder { - super.tryAcquirePrimaryLease(); - return this; - } - expectActiveTargets(...targets): MultiClientSpecBuilder { super.expectActiveTargets(...targets); 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 0a049913380..d4d4e8717d8 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -236,11 +236,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; @@ -269,12 +268,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; @@ -395,6 +393,7 @@ abstract class TestRunner { this.remoteStore = new RemoteStore( this.localStore, this.datastore, + this.queue, onlineStateChangedHandler ); @@ -474,13 +473,12 @@ 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() : this.doDisableNetwork(); - } else if ('acquirePrimaryLease' in step) { - // PORTING NOTE: Only used by web multi-tab tests. - return this.doAcquirePrimaryLease(); } else if ('restart' in step) { return this.doRestart(); } else if ('shutdown' in step) { @@ -704,9 +702,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 { @@ -717,9 +713,9 @@ 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.ListenStreamConnection + TimerId.ListenStreamConnectionBackoff ); await this.connection.waitForWatchOpen(); } @@ -747,13 +743,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), @@ -777,12 +771,18 @@ abstract class TestRunner { expect(err).not.to.be.null; } ); - } else { - return Promise.resolve(); } }); } + 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. @@ -794,14 +794,6 @@ abstract class TestRunner { await this.remoteStore.enableNetwork(); } - private async doAcquirePrimaryLease(): Promise { - // We drain the queue after running the client metadata refresh task as the - // refresh might schedule a primary state callback on the queue as well. - return this.queue - .runDelayedOperationsEarly(TimerId.ClientMetadataRefresh) - .then(() => this.queue.drain()); - } - private async doShutdown(): Promise { await this.remoteStore.shutdown(); await this.persistence.shutdown(); @@ -858,17 +850,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 ); } @@ -935,11 +927,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( @@ -1241,6 +1231,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; @@ -1250,9 +1246,6 @@ export interface SpecStep { /** Change to a new active user (specified by uid or null for anonymous). */ changeUser?: string | null; - /** Attempt to acquire the primary lease. */ - acquirePrimaryLease?: true; // PORTING NOTE: Only used by web multi-tab tests - /** * Restarts the SyncEngine from scratch, except re-uses persistence and auth * components. This allows you to queue writes, get documents into cache, @@ -1312,6 +1305,7 @@ export type SpecSnapshotVersion = TestSnapshotVersion; export type SpecWatchStreamClose = { error: SpecError; + runBackoffTimer: boolean; }; export type SpecWriteAck = { 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.', [], 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]); }); 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..ade24b85035 --- /dev/null +++ b/packages/logger/package.json @@ -0,0 +1,53 @@ +{ + "name": "@firebase/logger", + "version": "0.1.0", + "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/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; } diff --git a/packages/messaging-types/package.json b/packages/messaging-types/package.json index 2ebfabfb620..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", @@ -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 4069141c19c..5d1ee6e912d 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.2", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -16,30 +16,30 @@ "@firebase/app": "^0.1.0" }, "dependencies": { - "@firebase/messaging-types": "0.1.1", - "@firebase/util": "0.1.8", - "lcov-result-merger": "^1.2.0" + "@firebase/messaging-types": "0.1.2", + "@firebase/util": "0.1.10", + "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/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/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..21ddc6a5c94 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(); + } } /** @@ -72,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( @@ -129,8 +134,6 @@ export default class TokenDetailsModel extends DBInterface { ); } } - - return Promise.resolve(); } /** 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..72021beddc6 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)); }; @@ -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/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)); }; 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/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/package.json b/packages/polyfill/package.json index eb4eb49b5fe..5658a01093c 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -1,6 +1,6 @@ { "name": "@firebase/polyfill", - "version": "0.1.4", + "version": "0.2.0", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -12,10 +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/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; - } - }); -} diff --git a/packages/storage-types/package.json b/packages/storage-types/package.json index b71dfd10b3d..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", @@ -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 eb511e233b5..121b0d8997c 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.8", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.js", @@ -13,32 +13,33 @@ }, "license": "Apache-2.0", "dependencies": { - "@firebase/storage-types": "0.1.1" + "@firebase/storage-types": "0.1.2", + "tslib": "^1.9.0" }, "peerDependencies": { "@firebase/app": "^0.1.0", "@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/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(); diff --git a/packages/template/package.json b/packages/template/package.json index d50e28b0dfc..46c372c806a 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -19,29 +19,30 @@ "@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": { - "@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/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..aa4c5a72256 --- /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.9.0", + "request-promise": "^4.2.2" + }, + "devDependencies": { + "chai": "^4.1.1", + "gulp": "^4.0.0", + "mocha": "^5.0.1", + "nyc": "^11.4.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/packages/util/package.json b/packages/util/package.json index e31700aae0e..153fec501ff 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.10", "description": "", "author": "Firebase (https://firebase.google.com/)", "main": "dist/cjs/index.node.js", @@ -14,26 +14,29 @@ "prepare": "gulp build" }, "license": "Apache-2.0", + "dependencies": { + "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/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/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 () => { diff --git a/scripts/release/utils/inquirer.js b/scripts/release/utils/inquirer.js index 5094d659f2a..9fce4c959b3 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,33 @@ 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 { + version = releaseType === 'Staging' ? inc(version, 'pre') : version; + /** + * 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 +112,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 }; }; 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 diff --git a/yarn.lock b/yarn.lock index e943b6b50b9..eab6683407b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,9 +8,36 @@ 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" + 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" + resolved "https://registry.npmjs.org/@google-cloud/common/-/common-0.13.6.tgz#a9d8e137bc429a44aba9689fe6a0e4331784f853" dependencies: array-uniq "^1.0.3" arrify "^1.0.1" @@ -31,36 +58,96 @@ string-format-obj "^1.1.0" 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/common@^0.15.1": + 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.11.2": + version "0.11.2" + resolved "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-0.11.2.tgz#b511a1ec7a3b9df5cc453034b24391b0ccff9b1d" dependencies: - "@google-cloud/storage" "1.4.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.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.23" + resolved "https://registry.npmjs.org/@google-cloud/functions-emulator/-/functions-emulator-1.0.0-alpha.23.tgz#5f2916934a31369318dc81c23eb917a0400f6ead" + dependencies: + "@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" @@ -69,12 +156,36 @@ 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" + stream-events "^1.0.1" + 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" @@ -83,7 +194,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" @@ -93,199 +204,211 @@ "@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" + 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": +"@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@^6.0.46": - version "6.0.92" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.92.tgz#e7f721ae282772e12ba2579968c00d9cce422c5d" +"@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@^7.0.29": - version "7.0.48" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.48.tgz#24bfdc0aa82e8f6dbd017159c58094a2e06d0abb" +"@types/node@^6.0.46": + 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.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" - -"@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" + resolved "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz#2de3d718819bc20165754c4a59afb7e9833f6707" -"@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" +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: - 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: @@ -294,86 +417,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" @@ -384,7 +562,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" @@ -396,9 +574,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" @@ -411,136 +589,171 @@ 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" + 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" + 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" @@ -548,18 +761,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" @@ -567,35 +780,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" @@ -604,89 +825,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" @@ -694,25 +936,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" @@ -722,7 +964,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" @@ -736,7 +978,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" @@ -745,11 +987,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" @@ -763,111 +1005,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.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" @@ -882,7 +1163,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" @@ -893,25 +1174,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" @@ -924,53 +1205,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" @@ -981,7 +1280,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" @@ -989,7 +1288,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" @@ -997,14 +1296,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" @@ -1016,13 +1315,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" @@ -1072,7 +1371,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: @@ -1127,27 +1426,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" @@ -1155,53 +1458,111 @@ 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" + 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" + 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" 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" @@ -1210,7 +1571,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" @@ -1218,49 +1579,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" @@ -1271,7 +1632,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" @@ -1279,17 +1640,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" @@ -1297,19 +1658,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" @@ -1322,27 +1683,45 @@ chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.0, chokidar@^1.7.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" - -chromedriver@^2.31.0: - version "2.33.2" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.33.2.tgz#8fc779d54b6e45bef55d264a1eceed52427a9b49" +chokidar@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7" dependencies: - del "^3.0.0" + 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.npmjs.org/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +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" kew "^0.7.0" mkdirp "^0.5.1" 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" @@ -1351,45 +1730,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" @@ -1398,7 +1790,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" @@ -1411,11 +1803,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" @@ -1423,39 +1815,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" @@ -1487,69 +1887,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" @@ -1558,95 +1969,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.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" @@ -1654,11 +2068,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" @@ -1666,21 +2080,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" @@ -1691,7 +2105,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" @@ -1704,7 +2118,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" @@ -1718,85 +2132,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" @@ -1804,49 +2218,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" @@ -1856,31 +2274,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" @@ -1890,56 +2309,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.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.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.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" @@ -1949,31 +2383,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" @@ -1982,7 +2416,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" @@ -1993,14 +2427,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" @@ -2008,19 +2442,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" @@ -2036,11 +2470,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" @@ -2049,68 +2483,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" @@ -2118,49 +2564,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" @@ -2168,7 +2624,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" @@ -2178,7 +2634,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" @@ -2186,7 +2642,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" @@ -2195,7 +2651,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" @@ -2208,60 +2664,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" @@ -2273,7 +2762,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" @@ -2284,15 +2773,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" @@ -2300,11 +2793,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" @@ -2313,48 +2806,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: @@ -2367,39 +2858,50 @@ 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" + 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" + 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" 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" + 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" @@ -2413,7 +2915,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" @@ -2425,7 +2927,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" @@ -2434,80 +2936,88 @@ 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" + resolved "https://registry.npmjs.org/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" - -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.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" + resolved "https://registry.npmjs.org/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" +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: 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: +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" +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" + 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" @@ -2515,7 +3025,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" @@ -2527,72 +3037,80 @@ 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" -encodeurl@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" +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" -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" +empower@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/empower/-/empower-1.2.3.tgz#6f0da73447f4edd838fec5c60313a88ba5cb852b" dependencies: - iconv-lite "~0.4.13" + core-js "^2.0.0" + empower-core "^0.6.2" + +encodeurl@~1.0.1: + 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" @@ -2601,23 +3119,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" @@ -2627,22 +3145,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" @@ -2650,7 +3168,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" @@ -2659,17 +3177,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" @@ -2679,14 +3193,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" @@ -2695,15 +3209,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" @@ -2712,9 +3226,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" @@ -2733,8 +3258,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" @@ -2783,11 +3308,21 @@ 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" + 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" @@ -2797,37 +3332,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.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" @@ -2839,11 +3374,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" @@ -2851,26 +3386,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" @@ -2882,7 +3417,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" @@ -2894,19 +3429,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" @@ -2914,38 +3449,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" @@ -2978,25 +3552,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@3, extend@^3.0.0, 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" +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: - iconv-lite "^0.4.17" - jschardet "^1.4.2" - tmp "^0.0.33" + 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.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: @@ -3006,80 +3585,104 @@ 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" + +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" + 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" @@ -3092,34 +3695,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" @@ -3127,13 +3734,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" @@ -3143,9 +3759,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" @@ -3157,47 +3773,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" +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" 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" - 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" @@ -3205,12 +3823,26 @@ fined@^1.0.1: object.pick "^1.2.0" parse-filepath "^1.0.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-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.11.2" + "@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.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" @@ -3241,32 +3873,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" @@ -3282,90 +3914,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" @@ -3374,7 +4034,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" @@ -3382,9 +4042,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" @@ -3398,20 +4058,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" @@ -3419,16 +4095,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" @@ -3436,7 +4119,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" @@ -3449,20 +4132,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" -gcs-resumable-upload@^0.8.2: +gcp-metadata@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.6.1.tgz#62d54871fc6aeeac6a688e094abc886cb7aaacd0" + dependencies: + axios "^0.17.1" + extend "^3.0.1" + retry-axios "0.3.0" + +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" @@ -3472,9 +4163,21 @@ 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" + resolved "https://registry.npmjs.org/geckodriver/-/geckodriver-1.10.0.tgz#73e2f785666521d0d3a9ddc9fd5a0a5e3bf47845" dependencies: adm-zip "0.4.7" bluebird "3.4.6" @@ -3483,25 +4186,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" @@ -3511,32 +4214,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" @@ -3546,59 +4264,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" @@ -3606,7 +4324,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" @@ -3617,7 +4335,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" @@ -3628,30 +4346,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" @@ -3662,16 +4404,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" @@ -3681,27 +4423,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" + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" ini "^1.3.4" - is-windows "^0.2.0" - which "^1.2.12" + is-windows "^1.0.1" + which "^1.2.14" globals@^11.0.1: version "11.3.0" @@ -3709,11 +4453,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" @@ -3724,7 +4468,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" @@ -3732,38 +4476,77 @@ 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" + 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" 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" + 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" 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.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.6.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" @@ -3774,41 +4557,62 @@ 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.3: + 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" + 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" +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" + resolved "https://registry.npmjs.org/google-proto-files/-/google-proto-files-0.14.2.tgz#958cffea7e8888e00b9a6c55ed1362c06b426f4c" dependencies: - globby "^6.1.0" + 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" +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" @@ -3816,7 +4620,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" @@ -3837,7 +4641,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" @@ -3856,7 +4660,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" @@ -3871,7 +4675,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" @@ -3891,7 +4695,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" @@ -3907,29 +4711,48 @@ 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.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" + protobufjs "^5.0.0" -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.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" @@ -3937,41 +4760,41 @@ grpc@1.7.1, grpc@^1.7.1: node-pre-gyp "^0.6.39" protobufjs "^5.0.0" -gtoken@^1.2.1: +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" @@ -3984,23 +4807,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" @@ -4008,7 +4831,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" @@ -4016,58 +4839,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" @@ -4090,7 +4891,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" @@ -4106,28 +4907,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" @@ -4137,15 +4947,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" @@ -4154,97 +4964,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" @@ -4253,7 +5098,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" @@ -4262,11 +5107,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" @@ -4274,29 +5126,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" @@ -4305,19 +5157,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" @@ -4325,12 +5177,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" @@ -4339,14 +5199,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" @@ -4354,19 +5214,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" @@ -4374,7 +5245,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" @@ -4382,38 +5253,46 @@ 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.3, ignore@^3.3.5: version "3.3.7" resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" 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" @@ -4423,44 +5302,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" @@ -4478,7 +5365,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" @@ -4495,9 +5382,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" @@ -4515,7 +5402,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" @@ -4528,163 +5415,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" -is-absolute@^0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" - dependencies: - is-relative "^0.2.1" - is-windows "^0.2.0" +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@^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: + 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" @@ -4692,63 +5652,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" @@ -4756,173 +5722,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" @@ -4941,25 +5915,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" @@ -4967,15 +5941,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" @@ -4984,7 +5958,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" @@ -4992,48 +5966,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" @@ -5041,59 +6011,74 @@ 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" + 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" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz#77f5021de058b605a1783fa1283e99812e645638" dependencies: joi "^6.10.1" jws "^3.1.4" @@ -5103,7 +6088,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" @@ -5112,7 +6097,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" @@ -5120,13 +6105,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" @@ -5135,7 +6124,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" @@ -5143,27 +6132,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" @@ -5173,13 +6162,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" @@ -5188,25 +6177,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" @@ -5217,32 +6204,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" @@ -5250,9 +6232,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" @@ -5260,12 +6242,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" @@ -5278,8 +6261,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" @@ -5287,40 +6270,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" @@ -5328,66 +6323,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" @@ -5400,7 +6407,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" @@ -5408,11 +6415,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" @@ -5422,34 +6430,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" @@ -5503,7 +6526,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" @@ -5513,25 +6536,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" @@ -5540,11 +6554,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" @@ -5553,7 +6567,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" @@ -5561,120 +6575,136 @@ 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" + 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" + 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" + 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" + 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" + 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" + 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: 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" @@ -5682,43 +6712,43 @@ 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" + 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" + 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" @@ -5732,60 +6762,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.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: 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" @@ -5793,160 +6837,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" @@ -5959,18 +7040,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" @@ -5985,39 +7066,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" @@ -6033,124 +7114,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" @@ -6164,16 +7278,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" @@ -6212,12 +7326,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" @@ -6225,32 +7339,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" @@ -6259,25 +7384,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" @@ -6285,11 +7410,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" @@ -6297,8 +7439,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" @@ -6306,50 +7448,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, 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" @@ -6377,13 +7516,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" @@ -6399,38 +7538,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" -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" +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: - abbrev "1" + nodemailer-shared "1.1.0" + smtp-connection "2.12.0" -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" +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.npmjs.org/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + 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" @@ -6439,23 +7627,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" @@ -6469,13 +7657,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" @@ -6484,15 +7672,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" @@ -6517,120 +7705,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.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" @@ -6641,33 +7855,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" @@ -6675,92 +7891,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" @@ -6769,33 +8021,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" @@ -6804,20 +8063,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" @@ -6826,110 +8085,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" @@ -6937,29 +8194,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" @@ -6969,53 +8226,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" @@ -7023,58 +8299,162 @@ 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" + 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" + 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.7.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" +prettier@^1.10.2: + version "1.10.2" + resolved "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93" 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" @@ -7085,7 +8465,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" @@ -7093,8 +8473,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" @@ -7106,25 +8486,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" @@ -7134,30 +8514,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" @@ -7165,105 +8565,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" @@ -7272,40 +8688,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" @@ -7313,7 +8729,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" @@ -7321,7 +8737,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" @@ -7329,43 +8745,43 @@ 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: - 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.1" - isarray "0.0.1" - string_decoder "~0.10.x" + 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.7, readable-stream@~1.1.9: +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.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + 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@^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@>=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.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" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" -readable-stream@~2.0.0, readable-stream@~2.0.6: +readable-stream@~2.0.0, readable-stream@~2.0.5, readable-stream@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -7376,7 +8792,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" @@ -7385,7 +8801,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" @@ -7393,97 +8809,185 @@ 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" 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.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" @@ -7508,7 +9012,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" @@ -7533,9 +9037,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" @@ -7560,13 +9064,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" @@ -7577,20 +9090,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" @@ -7598,66 +9111,86 @@ 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-url@~0.2.1: +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: 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" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +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: 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" + 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" @@ -7668,7 +9201,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" @@ -7680,33 +9213,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" @@ -7716,15 +9255,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" @@ -7734,48 +9279,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" @@ -7787,7 +9331,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" @@ -7796,7 +9340,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" @@ -7805,42 +9349,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" @@ -7858,17 +9420,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" @@ -7878,9 +9444,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" @@ -7889,51 +9464,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" @@ -7942,7 +9541,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" @@ -7954,42 +9553,40 @@ 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" + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -8002,71 +9599,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" @@ -8075,22 +9707,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" @@ -8098,7 +9752,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" @@ -8106,87 +9760,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" @@ -8198,7 +9866,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" @@ -8209,40 +9877,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" @@ -8254,73 +9928,93 @@ 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" + 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" + 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" @@ -8332,37 +10026,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" + 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" @@ -8370,14 +10073,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" @@ -8385,85 +10088,93 @@ 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" + 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" + 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" @@ -8473,17 +10184,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" @@ -8518,35 +10229,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" @@ -8560,10 +10271,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" @@ -8578,11 +10289,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" @@ -8595,7 +10306,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" @@ -8604,7 +10315,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" @@ -8614,7 +10325,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" @@ -8622,7 +10333,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" @@ -8632,11 +10343,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" @@ -8644,26 +10355,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" @@ -8673,11 +10384,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" @@ -8685,220 +10396,246 @@ 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.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" + 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" +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" + 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" @@ -8906,103 +10643,94 @@ 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: - version "1.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac" +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" + 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" + 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" @@ -9011,11 +10739,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" @@ -9023,45 +10751,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" @@ -9073,51 +10809,96 @@ 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" 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" + 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" @@ -9129,7 +10910,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" @@ -9142,73 +10923,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" @@ -9217,60 +11006,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" + +uws@~9.14.0: + version "9.14.0" + resolved "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95" -v8flags@^2.0.2, v8flags@^2.0.9: +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" @@ -9278,7 +11083,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" @@ -9289,9 +11094,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" @@ -9311,30 +11116,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" @@ -9342,7 +11181,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" @@ -9351,34 +11190,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" @@ -9386,19 +11221,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" @@ -9411,14 +11246,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" @@ -9439,32 +11274,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" @@ -9473,41 +11308,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" @@ -9529,52 +11366,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" @@ -9584,9 +11425,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" @@ -9597,7 +11438,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" @@ -9609,43 +11450,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" @@ -9653,7 +11487,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" @@ -9661,7 +11495,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" @@ -9672,7 +11506,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" @@ -9683,100 +11517,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" @@ -9786,11 +11673,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@^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, yargs@^3.28.0: +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" @@ -9800,9 +11704,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" @@ -9816,29 +11720,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" @@ -9847,28 +11733,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"