@@ -87,4 +89,11 @@ class Comment extends React.Component {
}
}
+Comment.propTypes = {
+ viewComment: PropTypes.func,
+ comment: PropTypes.object,
+ asset: PropTypes.object,
+ root: PropTypes.object,
+};
+
export default Comment;
diff --git a/plugins/talk-plugin-notifications-category-reply/index.js b/plugins/talk-plugin-notifications-category-reply/index.js
index e214975ac..cce258daa 100644
--- a/plugins/talk-plugin-notifications-category-reply/index.js
+++ b/plugins/talk-plugin-notifications-category-reply/index.js
@@ -1,4 +1,4 @@
-const { get } = require('lodash');
+const { get, map } = require('lodash');
const path = require('path');
const handle = async (ctx, comment) => {
@@ -23,6 +23,9 @@ const handle = async (ctx, comment) => {
id
user {
id
+ ignoredUsers {
+ id
+ }
notificationSettings {
onReply
}
@@ -53,13 +56,23 @@ const handle = async (ctx, comment) => {
return;
}
+ // Pull out the author of the new comment.
+ const authorID = get(comment, 'author_id');
+
// Check to see if this is yourself replying to yourself, if that's the case
// don't send a notification.
- if (userID === get(comment, 'author_id')) {
+ if (userID === authorID) {
ctx.log.info('user id of parent comment is the same as the new comment');
return;
}
+ // Check to see if this user is ignoring the user who replied to their
+ // comment.
+ if (map(get(comment, 'user.ignoredUsers', []), 'id').indexOf(authorID)) {
+ ctx.log.info('parent user has ignored the author of the new comment');
+ return;
+ }
+
// The user does have notifications for replied comments enabled, queue the
// notification to be sent.
return { userID, date: comment.created_at, context: comment.id };
diff --git a/plugins/talk-plugin-notifications/server/mutators.js b/plugins/talk-plugin-notifications/server/mutators.js
index 5c0db9c8d..46954faa5 100644
--- a/plugins/talk-plugin-notifications/server/mutators.js
+++ b/plugins/talk-plugin-notifications/server/mutators.js
@@ -29,10 +29,11 @@ async function updateNotificationSettings(ctx, settings) {
}
module.exports = ctx => {
+ const { connectors: { errors: ErrNotAuthorized } } = ctx;
+
let mutators = {
User: {
- updateNotificationSettings: () =>
- Promise.reject(ctx.connectors.errors.ErrNotAuthorized),
+ updateNotificationSettings: () => Promise.reject(new ErrNotAuthorized()),
},
};
diff --git a/plugins/talk-plugin-rich-text/client/components/AdminCommentContent.js b/plugins/talk-plugin-rich-text/client/components/AdminCommentContent.js
index 1b7e53ebf..f49d89055 100644
--- a/plugins/talk-plugin-rich-text/client/components/AdminCommentContent.js
+++ b/plugins/talk-plugin-rich-text/client/components/AdminCommentContent.js
@@ -1,12 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
+import Linkify from 'react-linkify';
import styles from './AdminCommentContent.css';
import { AdminCommentContent as Content } from 'plugin-api/beta/client/components';
class AdminCommentContent extends React.Component {
render() {
const { comment, suspectWords, bannedWords } = this.props;
- return (
+ const content = (
);
+
+ if (!!comment.richTextBody) {
+ return content;
+ }
+
+ return
{content};
}
}
diff --git a/plugins/talk-plugin-rich-text/client/components/CommentContent.js b/plugins/talk-plugin-rich-text/client/components/CommentContent.js
index 2cf481830..64aa96c82 100644
--- a/plugins/talk-plugin-rich-text/client/components/CommentContent.js
+++ b/plugins/talk-plugin-rich-text/client/components/CommentContent.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { PLUGIN_NAME } from '../constants';
import cn from 'classnames';
import styles from './CommentContent.css';
+import Linkify from 'react-linkify';
class CommentContent extends React.Component {
render() {
@@ -14,7 +15,9 @@ class CommentContent extends React.Component {
dangerouslySetInnerHTML={{ __html: comment.richTextBody }}
/>
) : (
-
{comment.body}
+
+ {comment.body}
+
);
}
}
diff --git a/plugins/talk-plugin-toxic-comments/server/__mocks__/perspective.js b/plugins/talk-plugin-toxic-comments/server/__mocks__/perspective.js
new file mode 100644
index 000000000..cda3cf841
--- /dev/null
+++ b/plugins/talk-plugin-toxic-comments/server/__mocks__/perspective.js
@@ -0,0 +1,11 @@
+let values = {};
+
+const getScores = () => values.getScores;
+
+const isToxic = () => values.isToxic;
+
+const setValues = newValues => {
+ values = newValues;
+};
+
+module.exports = { getScores, isToxic, setValues };
diff --git a/plugins/talk-plugin-toxic-comments/server/errors.js b/plugins/talk-plugin-toxic-comments/server/errors.js
index 60135a8f8..a60bd549b 100644
--- a/plugins/talk-plugin-toxic-comments/server/errors.js
+++ b/plugins/talk-plugin-toxic-comments/server/errors.js
@@ -1,12 +1,16 @@
-const { APIError } = require('errors');
+const { TalkError } = require('errors');
// ErrToxic is sent during a `CreateComment` mutation where
// `input.checkToxicity` is set to true and the comment contains
// toxic language as determined by the perspective service.
-const ErrToxic = new APIError('Comment is toxic', {
- status: 400,
- translation_key: 'COMMENT_IS_TOXIC',
-});
+class ErrToxic extends TalkError {
+ constructor() {
+ super('Comment is toxic', {
+ status: 400,
+ translation_key: 'COMMENT_IS_TOXIC',
+ });
+ }
+}
module.exports = {
ErrToxic,
diff --git a/plugins/talk-plugin-toxic-comments/server/hooks.js b/plugins/talk-plugin-toxic-comments/server/hooks.js
index 7b9c93dad..d35b5cc20 100644
--- a/plugins/talk-plugin-toxic-comments/server/hooks.js
+++ b/plugins/talk-plugin-toxic-comments/server/hooks.js
@@ -1,11 +1,6 @@
const { getScores, isToxic } = require('./perspective');
const { ErrToxic } = require('./errors');
-// We don't add the hooks during _test_ as the perspective API is not available.
-if (process.env.NODE_ENV === 'test') {
- return null;
-}
-
module.exports = {
RootMutation: {
createComment: {
@@ -16,7 +11,7 @@ module.exports = {
scores = await getScores(input.body);
} catch (err) {
// Warn and let mutation pass.
- console.trace(err);
+ console.trace(err); // TODO: log/handle this differently?
return;
}
@@ -27,7 +22,7 @@ module.exports = {
if (isToxic(scores)) {
if (input.checkToxicity) {
- throw ErrToxic;
+ throw new ErrToxic();
}
input.status = 'SYSTEM_WITHHELD';
diff --git a/plugins/talk-plugin-toxic-comments/server/hooks.spec.js b/plugins/talk-plugin-toxic-comments/server/hooks.spec.js
new file mode 100644
index 000000000..d9fbe67e6
--- /dev/null
+++ b/plugins/talk-plugin-toxic-comments/server/hooks.spec.js
@@ -0,0 +1,31 @@
+const hooks = require('./hooks');
+const { ErrToxic } = require('./errors');
+
+// Mock out the perspective api call.
+jest.mock('./perspective');
+
+describe('talk-plugin-toxic-comments', () => {
+ describe('hooks', () => {
+ beforeEach(() => {
+ require('./perspective').setValues({ isToxic: true });
+ });
+
+ it('sets the correct values for a toxic comment', async () => {
+ let input = { body: 'This is a body.', checkToxicity: false };
+ await hooks.RootMutation.createComment.pre(null, { input }, null, null);
+ expect(input).toHaveProperty('status', 'SYSTEM_WITHHELD');
+ });
+
+ it('throws an error when a toxic comment is sent', async () => {
+ expect.assertions(1);
+ await expect(
+ hooks.RootMutation.createComment.pre(
+ null,
+ { input: { checkToxicity: true } },
+ null,
+ null
+ )
+ ).rejects.toBeInstanceOf(ErrToxic);
+ });
+ });
+});
diff --git a/routes/api/v1/users.js b/routes/api/v1/users.js
index e0de3b5db..481e5650c 100644
--- a/routes/api/v1/users.js
+++ b/routes/api/v1/users.js
@@ -1,7 +1,7 @@
const express = require('express');
const router = express.Router();
const UsersService = require('../../../services/users');
-const errors = require('../../../errors');
+const { ErrMissingEmail, ErrNotFound } = require('../../../errors');
const authorization = require('../../../middleware/authorization');
const Limit = require('../../../services/limit');
@@ -40,17 +40,12 @@ router.post('/resend-verify', async (req, res, next) => {
// Clean up and validate the email.
email = email.toLowerCase().trim();
if (email.length < 5) {
- return next(errors.ErrMissingEmail);
+ return next(new ErrMissingEmail());
}
// Check if we're past the rate limit, if we are, stop now. Otherwise, record
// this as an attempt to send a verification email.
try {
- const tries = await resendRateLimiter.get(email);
- if (tries > 0) {
- throw errors.ErrMaxRateLimit;
- }
-
await resendRateLimiter.test(email);
} catch (err) {
return next(err);
@@ -59,7 +54,7 @@ router.post('/resend-verify', async (req, res, next) => {
try {
const user = await UsersService.findLocalUser(email);
if (!user) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
await UsersService.sendEmailConfirmation(user, email, redirectUri);
@@ -81,13 +76,13 @@ router.post(
try {
let user = await UsersService.findById(user_id);
if (!user) {
- return next(errors.ErrNotFound);
+ return next(new ErrNotFound());
}
// Find the first local profile.
const email = user.firstEmail;
if (!email) {
- return next(errors.ErrMissingEmail);
+ return next(new ErrMissingEmail());
}
// Send the email to the first local profile that was found.
diff --git a/routes/index.js b/routes/index.js
index 489a5e8b5..b6e46791e 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -1,8 +1,8 @@
const SetupService = require('../services/setup');
const authentication = require('../middleware/authentication');
+const logging = require('../middleware/logging');
const cookieParser = require('cookie-parser');
-const enabled = require('debug').enabled;
-const errors = require('../errors');
+const { TalkError, ErrNotFound } = require('../errors');
const express = require('express');
const i18n = require('../middleware/i18n');
const path = require('path');
@@ -149,19 +149,16 @@ router.use(require('./plugins'));
// Catch 404 and forward to error handler.
router.use((req, res, next) => {
- next(errors.ErrNotFound);
+ next(new ErrNotFound());
});
+// Add logging for errors.
+router.use(logging.error);
+
// General API error handler. Respond with the message and error if we have it
// while returning a status code that makes sense.
router.use('/api', (err, req, res, next) => {
- if (err !== errors.ErrNotFound) {
- if (process.env.NODE_ENV !== 'test' || enabled('talk:errors')) {
- console.error(err);
- }
- }
-
- if (err instanceof errors.APIError) {
+ if (err instanceof TalkError) {
res.status(err.status).json({
message: res.locals.t(`error.${err.translation_key}`),
error: err,
@@ -172,11 +169,7 @@ router.use('/api', (err, req, res, next) => {
});
router.use('/', (err, req, res, next) => {
- if (err !== errors.ErrNotFound) {
- console.error(err);
- }
-
- if (err instanceof errors.APIError) {
+ if (err instanceof TalkError) {
res.status(err.status);
res.render('error', {
message: res.locals.t(`error.${err.translation_key}`),
diff --git a/serve.js b/serve.js
index ea06a6342..8b4d4556c 100644
--- a/serve.js
+++ b/serve.js
@@ -1,5 +1,5 @@
const app = require('./app');
-const errors = require('./errors');
+const { ErrSettingsInit, ErrInstallLock } = require('./errors');
const { createServer } = require('http');
const jobs = require('./jobs');
const MigrationService = require('./services/migration');
@@ -95,20 +95,16 @@ async function serve({
await SetupService.isAvailable();
logger.info('Setup is currently available, migrations not being checked');
- } catch (e) {
+ } catch (err) {
// Check the error.
- switch (e) {
- case errors.ErrInstallLock:
- case errors.ErrSettingsInit:
- logger.info(
- 'Setup is not currently available, migrations now being checked'
- );
-
- // The error was expected, just continue.
- break;
- default:
- // The error was not expected, throw the error!
- throw e;
+ if (err instanceof ErrInstallLock || err instanceof ErrSettingsInit) {
+ // The error was expected, just continue.
+ logger.info(
+ 'Setup is not currently available, migrations now being checked'
+ );
+ } else {
+ // The error was not expected, throw the error!
+ throw err;
}
// Now try and check the migration status.
diff --git a/services/assets.js b/services/assets.js
index f229bb353..fbed22287 100644
--- a/services/assets.js
+++ b/services/assets.js
@@ -2,9 +2,12 @@ const CommentModel = require('../models/comment');
const AssetModel = require('../models/asset');
const SettingsService = require('./settings');
const DomainList = require('./domain_list');
-const errors = require('../errors');
-const merge = require('lodash/merge');
-const isEmpty = require('lodash/isEmpty');
+const {
+ ErrAssetURLAlreadyExists,
+ ErrNotFound,
+ ErrInvalidAssetURL,
+} = require('../errors');
+const { merge, isEmpty } = require('lodash');
const { dotize } = require('./utils');
module.exports = class AssetsService {
@@ -73,7 +76,7 @@ module.exports = class AssetsService {
}
if (!whitelisted) {
- return Promise.reject(errors.ErrInvalidAssetURL);
+ throw new ErrInvalidAssetURL(url);
} else {
return AssetModel.findOneAndUpdate({ url }, update, {
// Ensure that if it's new, we return the new object created.
@@ -211,7 +214,7 @@ module.exports = class AssetsService {
// Try to see if an asset already exists with the given url.
let asset = await AssetsService.findByUrl(url);
if (asset !== null) {
- throw errors.ErrAssetURLAlreadyExists;
+ throw new ErrAssetURLAlreadyExists();
}
// Seems that there was no other asset with the same url, try and perform
@@ -227,7 +230,7 @@ module.exports = class AssetsService {
dstAssetID,
]);
if (!srcAsset || !dstAsset) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
// Resolve the merge operation, this invloves moving all resources attached
diff --git a/services/comments.js b/services/comments.js
index a1f59c1e1..b9d73d91c 100644
--- a/services/comments.js
+++ b/services/comments.js
@@ -2,10 +2,13 @@ const CommentModel = require('../models/comment');
const { dotize } = require('./utils');
const debug = require('debug')('talk:services:comments');
const SettingsService = require('./settings');
-
-const cloneDeep = require('lodash/cloneDeep');
-const errors = require('../errors');
-const merge = require('lodash/merge');
+const { merge, cloneDeep } = require('lodash');
+const {
+ ErrParentDoesNotVisible,
+ ErrNotFound,
+ ErrNotAuthorized,
+ ErrEditWindowHasEnded,
+} = require('../errors');
const incrReplyCount = async (comment, value) => {
try {
@@ -40,7 +43,7 @@ module.exports = {
if (parent_id !== null) {
const parent = await CommentModel.findOne({ id: parent_id });
if (parent === null || !parent.visible) {
- throw errors.ErrParentDoesNotVisible;
+ throw new ErrParentDoesNotVisible();
}
}
@@ -126,7 +129,7 @@ module.exports = {
const comment = await CommentModel.findOne({ id });
if (comment == null) {
debug('rejecting comment edit because comment was not found');
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
// Check to see if the user was't allowed to edit it.
@@ -134,7 +137,7 @@ module.exports = {
debug(
'rejecting comment edit because author id does not match editing user'
);
- throw errors.ErrNotAuthorized;
+ throw new ErrNotAuthorized();
}
// Check to see if the comment had a status that was editable.
@@ -142,13 +145,13 @@ module.exports = {
debug(
'rejecting comment edit because original comment has a non-editable status'
);
- throw errors.ErrNotAuthorized;
+ throw new ErrNotAuthorized();
}
// Check to see if the edit window expired.
if (comment.created_at <= lastEditableCommentCreatedAt) {
debug('rejecting comment edit because outside edit time window');
- throw errors.ErrEditWindowHasEnded;
+ throw new ErrEditWindowHasEnded();
}
throw new Error('comment edit failed for an unexpected reason');
@@ -198,7 +201,7 @@ module.exports = {
);
if (originalComment == null) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
const editedComment = new CommentModel(originalComment.toObject());
diff --git a/services/limit.js b/services/limit.js
index 6d46f3715..573d7a815 100644
--- a/services/limit.js
+++ b/services/limit.js
@@ -1,5 +1,5 @@
const ms = require('ms');
-const errors = require('../errors');
+const { ErrMaxRateLimit } = require('../errors');
const { createClientFactory } = require('./redis');
const client = createClientFactory();
@@ -60,7 +60,7 @@ class Limit {
}
if (tries > this.max) {
- throw errors.ErrMaxRateLimit;
+ throw new ErrMaxRateLimit(this.max, tries);
}
return tries;
diff --git a/services/logging.js b/services/logging.js
index 47ef93af8..7ae3654b1 100644
--- a/services/logging.js
+++ b/services/logging.js
@@ -1,18 +1,45 @@
const { version } = require('../package.json');
-const Logger = require('bunyan');
+const path = require('path');
+const { createLogger: createBunyanLogger, stdSerializers } = require('bunyan');
const { LOGGING_LEVEL, REVISION_HASH } = require('../config');
-const logger = new Logger({
+
+// Streams enables the ability for development logs to be readable to a human,
+// but will send JSON logs in production that's parsable by a system like ELK.
+const streams = (() => {
+ // In development, use the debug stream printer.
+ if (process.env.NODE_ENV !== 'production') {
+ const debug = require('bunyan-debug-stream');
+ return [
+ {
+ level: LOGGING_LEVEL,
+ type: 'raw',
+ stream: debug({
+ basepath: path.resolve(__dirname, '..'),
+ forceColor: true,
+ }),
+ },
+ ];
+ }
+
+ // In production, emit JSON.
+ return [{ stream: process.stdout, level: LOGGING_LEVEL }];
+})();
+
+// logger is the base logger used by all logging systems in Talk.
+const logger = createBunyanLogger({
src: true,
name: 'talk',
version,
revision: REVISION_HASH,
- level: LOGGING_LEVEL,
- serializers: Logger.stdSerializers,
+ streams,
+ serializers: stdSerializers,
});
-// Create the logging instance that all logger's are branched from.
-function createLogger(name, traceID) {
- return logger.child({ origin: name, traceID });
-}
+/**
+ *
+ * @param {String} origin the origin name used by the logger
+ * @param {String} traceID the id of the request being made
+ */
+const createLogger = (origin, traceID) => logger.child({ origin, traceID });
module.exports = { logger, createLogger };
diff --git a/services/moderation/index.js b/services/moderation/index.js
index 4d87e190f..530d6f2a6 100644
--- a/services/moderation/index.js
+++ b/services/moderation/index.js
@@ -1,4 +1,4 @@
-const errors = require('../../errors');
+const { ErrNotFound } = require('../../errors');
const get = require('lodash/get');
// Load in the phases to use.
@@ -92,14 +92,14 @@ const fetchOptions = async (ctx, comment) => {
const assetID = get(comment, 'asset_id', null);
if (assetID === null) {
// And leave now if this asset wasn't found.
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
// Load the asset.
const asset = await Assets.getByID.load(assetID);
if (!asset) {
// And leave now if this asset wasn't found.
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
// Combine the asset and the settings to get the asset settings.
diff --git a/services/moderation/phases/commentLength.js b/services/moderation/phases/commentLength.js
index 925115326..e19198ef1 100644
--- a/services/moderation/phases/commentLength.js
+++ b/services/moderation/phases/commentLength.js
@@ -8,7 +8,7 @@ module.exports = (
) => {
// Check to see if the body is too short, if it is, then complain about it!
if (comment.body.length < 2) {
- throw ErrCommentTooShort;
+ throw new ErrCommentTooShort(comment.body.length);
}
// Reject if the comment is too long
diff --git a/services/mongoose.js b/services/mongoose.js
index 20765293a..4e242cf47 100644
--- a/services/mongoose.js
+++ b/services/mongoose.js
@@ -1,50 +1,47 @@
-const { MONGO_URL, WEBPACK, CREATE_MONGO_INDEXES } = require('../config');
-
+const {
+ MONGO_URL,
+ WEBPACK,
+ CREATE_MONGO_INDEXES,
+ LOGGING_LEVEL,
+} = require('../config');
+const { logger } = require('./logging');
const mongoose = require('mongoose');
-const debug = require('debug')('talk:db');
-const enabled = require('debug').enabled;
-const queryDebugger = require('debug')('talk:db:query');
-
-// Loading the formatter from Mongoose:
-//
-// https://github.com/Automattic/mongoose/blob/1a93d1f4d12e441e17ddf451e96fbc5f6e8f54b8/lib/drivers/node-mongodb-native/collection.js#L182
-//
-// so we can wrap parameters.
-const formatter = require('mongoose').Collection.prototype.$format;
// Provide a newly wrapped debugQuery function which wraps the `debug` package.
-function debugQuery(name, i, ...args) {
- let functionCall = ['db', name, i].join('.');
- let _args = [];
- for (let j = args.length - 1; j >= 0; --j) {
- if (formatter(args[j]) || _args.length) {
- _args.unshift(formatter(args[j]));
- }
- }
-
- let params = `(${_args.join(', ')})`;
-
- queryDebugger(functionCall + params);
+function debugQuery(name, operation, ...args) {
+ logger.debug(
+ {
+ query: `db.${name}.${operation}(${args
+ .map(arg => JSON.stringify(arg))
+ .join(', ')})`,
+ },
+ 'mongodb query'
+ );
}
// Use native promises
mongoose.Promise = global.Promise;
-// Check if debugging is enabled on the talk:db prefix.
-if (enabled('talk:db:query')) {
+// Check if verbose logging is enabled.
+if (['debug', 'trace'].includes(LOGGING_LEVEL)) {
// Enable the mongoose debugger, here we wrap the similar print function
// provided by setting the debug parameter.
mongoose.set('debug', debugQuery);
}
if (WEBPACK) {
- debug('Not connecting to mongodb during webpack build');
+ logger.debug('Not connecting to mongodb during webpack build');
- // @wyattjoh: We didn't call connect, but because we include mongoose, it will hold the socket ready,
- // preventing node from exiting. Calling disconnect here just ensures that the application
- // can quit correctly.
+ // @wyattjoh: We didn't call connect, but because we include mongoose, it will
+ // hold the socket ready, preventing node from exiting. Calling disconnect
+ // here just ensures that the application can quit correctly.
mongoose.disconnect();
} else {
+ mongoose.connection.on('connected', () => logger.debug('mongodb connected'));
+ mongoose.connection.on('disconnected', () =>
+ logger.debug('mongodb disconnected')
+ );
+
// Connect to the Mongo instance.
mongoose
.connect(MONGO_URL, {
@@ -53,9 +50,6 @@ if (WEBPACK) {
autoIndex: CREATE_MONGO_INDEXES,
},
})
- .then(() => {
- debug('connection established');
- })
.catch(err => {
console.error(err);
process.exit(1);
@@ -66,10 +60,13 @@ module.exports = mongoose;
// Here we include all the models that mongoose is used for, this ensures that
// when we import mongoose that we also start up all the indexing operations
-// here.
-require('../models/action');
-require('../models/asset');
-require('../models/comment');
-require('../models/setting');
-require('../models/user');
-require('./migration');
+// here. No point also in importing this if we're not actually doing any
+// indexing now.
+if (CREATE_MONGO_INDEXES) {
+ require('../models/action');
+ require('../models/asset');
+ require('../models/comment');
+ require('../models/setting');
+ require('../models/user');
+ require('./migration');
+}
diff --git a/services/passport.js b/services/passport.js
index 5748c911b..0ae06afb8 100644
--- a/services/passport.js
+++ b/services/passport.js
@@ -6,7 +6,12 @@ const TokensService = require('./tokens');
const fetch = require('node-fetch');
const FormData = require('form-data');
const LocalStrategy = require('passport-local').Strategy;
-const errors = require('../errors');
+const {
+ ErrLoginAttemptMaximumExceeded,
+ ErrNotAuthorized,
+ ErrAuthentication,
+ ErrNotVerified,
+} = require('../errors');
const uuid = require('uuid');
const debug = require('debug')('talk:services:passport');
const bowser = require('bowser');
@@ -75,7 +80,7 @@ const HandleGenerateCredentials = (req, res, next) => (err, user) => {
}
if (!user) {
- return next(errors.ErrNotAuthorized);
+ return next(new ErrNotAuthorized());
}
// Generate the token to re-issue to the frontend.
@@ -117,7 +122,7 @@ const HandleAuthPopupCallback = (req, res, next) => (err, user) => {
if (!user) {
return res.render('auth-callback', {
- auth: { err: errors.ErrNotAuthorized, data: null },
+ auth: { err: new ErrNotAuthorized(), data: null },
});
}
@@ -143,7 +148,7 @@ async function ValidateUserLogin(loginProfile, user, done) {
}
if (user.disabled) {
- return done(new errors.ErrAuthentication('Account disabled'));
+ return done(new ErrAuthentication('Account disabled'));
}
// If the user isn't a local user (i.e., a social user).
@@ -169,7 +174,7 @@ async function ValidateUserLogin(loginProfile, user, done) {
// If the profile doesn't have a metadata field, or it does not have a
// confirmed_at field, or that field is null, then send them back.
if (_.get(profile, 'metadata.confirmed_at', null) === null) {
- return done(errors.ErrNotVerified);
+ return done(new ErrNotVerified());
}
}
@@ -209,7 +214,7 @@ const checkGeneralTokenBlacklist = jwt =>
.get(`jtir[${jwt.jti}]`)
.then(expiry => {
if (expiry != null) {
- throw new errors.ErrAuthentication('token was revoked');
+ throw new ErrAuthentication('token was revoked');
}
});
@@ -392,7 +397,7 @@ const HandleFailedAttempt = async (email, userNeedsRecaptcha) => {
await UsersService.recordLoginAttempt(email);
} catch (err) {
if (
- err === errors.ErrLoginAttemptMaximumExceeded &&
+ err instanceof ErrLoginAttemptMaximumExceeded &&
!userNeedsRecaptcha &&
RECAPTCHA_ENABLED
) {
@@ -448,7 +453,7 @@ passport.use(
try {
await UsersService.checkLoginAttempts(email);
} catch (err) {
- if (err === errors.ErrLoginAttemptMaximumExceeded) {
+ if (err instanceof ErrLoginAttemptMaximumExceeded) {
// This says, we didn't have a recaptcha, yet we needed one.. Reject
// here.
diff --git a/services/redis.js b/services/redis.js
index 2576d2c13..0a25b34d6 100644
--- a/services/redis.js
+++ b/services/redis.js
@@ -1,7 +1,5 @@
const Redis = require('ioredis');
const merge = require('lodash/merge');
-const debug = require('debug')('talk:services:redis');
-const enabled = require('debug').enabled('talk:services:redis');
const {
REDIS_URL,
REDIS_RECONNECTION_BACKOFF_FACTOR,
@@ -9,29 +7,32 @@ const {
REDIS_CLIENT_CONFIG,
REDIS_CLUSTER_MODE,
REDIS_CLUSTER_CONFIGURATION,
+ LOGGING_LEVEL,
} = require('../config');
+const { createLogger } = require('./logging');
+const logger = createLogger('redis');
const attachMonitors = client => {
- debug('client created');
+ logger.debug('client created');
// Debug events.
- if (enabled) {
- client.on('connect', () => debug('client connected'));
- client.on('ready', () => debug('client ready'));
- client.on('close', () => debug('client closed the connection'));
+ if (['debug', 'trace'].includes(LOGGING_LEVEL)) {
+ client.on('connect', () => logger.info('client connected'));
+ client.on('ready', () => logger.debug('client ready'));
+ client.on('close', () => logger.debug('client closed the connection'));
client.on('reconnecting', () =>
- debug('client connection lost, attempting to reconnect')
+ logger.debug('client connection lost, attempting to reconnect')
);
- client.on('end', () => debug('client ended'));
+ client.on('end', () => logger.debug('client ended'));
}
// Error events.
client.on('error', err => {
if (err) {
- console.error('Error connecting to redis:', err);
+ logger.error({ err }, 'cannot connect to redis');
}
});
- client.on('node error', err => debug('node error', err));
+ client.on('node error', err => logger.error({ err }, 'node error'));
};
function retryStrategy(times) {
@@ -40,7 +41,7 @@ function retryStrategy(times) {
REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME
);
- debug(`retry strategy: try to reconnect ${delay} ms from now`);
+ logger.debug(`retry strategy: try to reconnect ${delay} ms from now`);
return delay;
}
diff --git a/services/settings.js b/services/settings.js
index f918f9d01..ee5125183 100644
--- a/services/settings.js
+++ b/services/settings.js
@@ -1,6 +1,6 @@
const SettingModel = require('../models/setting');
const cache = require('./cache');
-const errors = require('../errors');
+const { ErrSettingsNotInit } = require('../errors');
const { dotize } = require('./utils');
const { SETTINGS_CACHE_TIME } = require('../config');
@@ -17,7 +17,7 @@ const retrieve = async fields => {
settings = await SettingModel.findOne(selector);
}
if (!settings) {
- throw errors.ErrSettingsNotInit;
+ throw new ErrSettingsNotInit();
}
return settings;
diff --git a/services/setup.js b/services/setup.js
index 84f915ff2..2517d376b 100644
--- a/services/setup.js
+++ b/services/setup.js
@@ -2,7 +2,12 @@ const UsersService = require('./users');
const SettingsService = require('./settings');
const MigrationService = require('./migration');
const SettingsModel = require('../models/setting');
-const errors = require('../errors');
+const {
+ ErrMissingEmail,
+ ErrInstallLock,
+ ErrSettingsInit,
+ ErrSettingsNotInit,
+} = require('../errors');
const { INSTALL_LOCK } = require('../config');
/**
@@ -16,25 +21,25 @@ module.exports = class SetupService {
static async isAvailable() {
// Check if we have an install lock present.
if (INSTALL_LOCK) {
- throw errors.ErrInstallLock;
+ throw new ErrInstallLock();
}
try {
- // Get the current settings, we are expecing an error here.
+ // Get the current settings, we are expecting an error here.
await SettingsService.retrieve();
// We should NOT have gotten a settings object, this means that the
// application is already setup. Error out here.
- throw errors.ErrSettingsInit;
- } catch (e) {
- // If the error is `not init`, then we're good, otherwise, it's something
- // else.
- if (e !== errors.ErrSettingsNotInit) {
- throw e;
+ throw new ErrSettingsInit();
+ } catch (err) {
+ // Allow the request to keep going here.
+ if (err instanceof ErrSettingsNotInit) {
+ return;
}
- // Allow the request to keep going here.
- return;
+ // If the error is `not init`, then we're good, otherwise, it's something
+ // else.
+ throw err;
}
}
@@ -44,7 +49,7 @@ module.exports = class SetupService {
static validate({ settings, user: { email, username, password } }) {
// Verify the email address of the user.
if (!email) {
- return Promise.reject(errors.ErrMissingEmail);
+ throw new ErrMissingEmail();
}
// Create a settings model to use for validation.
diff --git a/services/tags.js b/services/tags.js
index 8183d0165..cc8934e0a 100644
--- a/services/tags.js
+++ b/services/tags.js
@@ -1,12 +1,10 @@
const CommentModel = require('../models/comment');
const AssetModel = require('../models/asset');
const UserModel = require('../models/user');
-
const AssetsService = require('./assets');
const SettingsService = require('./settings');
const { ADD_COMMENT_TAG } = require('../perms/constants');
-
-const errors = require('../errors');
+const { ErrNotAuthorized } = require('../errors');
const updateModel = async (item_type, query, update) => {
// Get the model to update with.
@@ -120,13 +118,13 @@ class TagsService {
return { tagLink, ownership: true };
}
- throw errors.ErrNotAuthorized;
+ throw new ErrNotAuthorized();
}
// Only admin/moderators can modify unique tags, these are tags that are not
// in the global list.
if (!user.can(ADD_COMMENT_TAG)) {
- throw errors.ErrNotAuthorized;
+ throw new ErrNotAuthorized();
}
// Generate the tag in the event now that we have to create the tag for this
diff --git a/services/users.js b/services/users.js
index 0617d5158..d2dd60b0b 100644
--- a/services/users.js
+++ b/services/users.js
@@ -1,6 +1,21 @@
const uuid = require('uuid');
const bcrypt = require('bcryptjs');
-const errors = require('../errors');
+const {
+ ErrMaxRateLimit,
+ ErrLoginAttemptMaximumExceeded,
+ ErrNotFound,
+ ErrPermissionUpdateUsername,
+ ErrSameUsernameProvided,
+ ErrUsernameTaken,
+ ErrMissingUsername,
+ ErrSpecialChars,
+ ErrMissingPassword,
+ ErrPasswordTooShort,
+ ErrMissingEmail,
+ ErrEmailTaken,
+ ErrEmailAlreadyVerified,
+ ErrCannotIgnoreStaff,
+} = require('../errors');
const { difference, sample, some, merge, random } = require('lodash');
const { ROOT_URL } = require('../config');
const { jwt: JWT_SECRET } = require('../secrets');
@@ -59,8 +74,8 @@ class UsersService {
try {
await loginRateLimiter.test(email.toLowerCase().trim());
} catch (err) {
- if (err === errors.ErrMaxRateLimit) {
- throw errors.ErrLoginAttemptMaximumExceeded;
+ if (err instanceof ErrMaxRateLimit) {
+ throw new ErrLoginAttemptMaximumExceeded();
}
throw err;
@@ -91,7 +106,7 @@ class UsersService {
if (user === null) {
user = await UserModel.findOne({ id });
if (user === null) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
// Date comparisons are difficult when using MongoDB. Javascript will
@@ -150,10 +165,10 @@ class UsersService {
runValidators: true,
}
);
- if (user === null) {
+ if (!user) {
user = await UserModel.findOne({ id });
- if (user === null) {
- throw errors.ErrNotFound;
+ if (!user) {
+ throw new ErrNotFound();
}
if (user.status.banned.status === status) {
@@ -204,7 +219,7 @@ class UsersService {
if (user === null) {
user = await UserModel.findOne({ id });
if (user === null) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
if (user.status.username.status === status) {
@@ -259,15 +274,15 @@ class UsersService {
if (!user) {
user = await UsersService.findById(id);
if (user === null) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
if (user.status.username.status !== fromStatus) {
- throw errors.ErrPermissionUpdateUsername;
+ throw new ErrPermissionUpdateUsername();
}
if (!resetAllowed && user.username === username) {
- throw errors.ErrSameUsernameProvided;
+ throw new ErrSameUsernameProvided();
}
throw new Error('edit username failed for an unexpected reason');
@@ -276,7 +291,7 @@ class UsersService {
return user;
} catch (err) {
if (err.code === 11000) {
- throw errors.ErrUsernameTaken;
+ throw new ErrUsernameTaken();
}
throw err;
@@ -317,7 +332,7 @@ class UsersService {
}
if (attempts >= RECAPTCHA_INCORRECT_TRIGGER) {
- throw errors.ErrLoginAttemptMaximumExceeded;
+ throw new ErrLoginAttemptMaximumExceeded();
}
}
@@ -515,11 +530,11 @@ class UsersService {
const onlyLettersNumbersUnderscore = /^[A-Za-z0-9_]+$/;
if (!username) {
- throw errors.ErrMissingUsername;
+ throw new ErrMissingUsername();
}
if (!onlyLettersNumbersUnderscore.test(username)) {
- throw errors.ErrSpecialChars;
+ throw new ErrSpecialChars();
}
if (checkAgainstWordlist) {
@@ -539,11 +554,11 @@ class UsersService {
*/
static isValidPassword(password) {
if (!password) {
- throw errors.ErrMissingPassword;
+ throw new ErrMissingPassword();
}
if (password.length < 8) {
- throw errors.ErrPasswordTooShort;
+ throw new ErrPasswordTooShort();
}
return password;
@@ -558,7 +573,7 @@ class UsersService {
*/
static async createLocalUser(ctx, email, password, username) {
if (!email) {
- throw errors.ErrMissingEmail;
+ throw new ErrMissingEmail();
}
email = email.toLowerCase().trim();
@@ -596,9 +611,9 @@ class UsersService {
} catch (err) {
if (err.code === 11000) {
if (err.message.match('Username')) {
- throw errors.ErrUsernameTaken;
+ throw new ErrUsernameTaken();
}
- throw errors.ErrEmailTaken;
+ throw new ErrEmailTaken();
}
throw err;
}
@@ -678,9 +693,7 @@ class UsersService {
*/
static async createPasswordResetToken(email, loc) {
if (!email || typeof email !== 'string') {
- throw new Error(
- 'email is required when creating a JWT for resetting passord'
- );
+ throw new ErrMissingEmail();
}
email = email.toLowerCase();
@@ -837,7 +850,7 @@ class UsersService {
// Ensure that the user email hasn't already been verified.
if (profile && profile.metadata && profile.metadata.confirmed_at) {
- throw errors.ErrEmailAlreadyVerified;
+ throw new ErrEmailAlreadyVerified();
}
return JWT_SECRET.sign(
@@ -875,16 +888,16 @@ class UsersService {
},
});
if (!user) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
const profile = user.profiles.find(({ id }) => id === decoded.email);
if (!profile) {
- throw errors.ErrNotFound;
+ throw new ErrNotFound();
}
if (profile.metadata && profile.metadata.confirmed_at !== null) {
- throw errors.ErrEmailAlreadyVerified;
+ throw new ErrEmailAlreadyVerified();
}
return decoded;
@@ -943,7 +956,7 @@ class UsersService {
const users = await UsersService.findByIdArray(usersToIgnore);
if (some(users, user => user.isStaff())) {
- throw errors.ErrCannotIgnoreStaff;
+ throw new ErrCannotIgnoreStaff();
}
return UserModel.update(
diff --git a/services/wordlist.js b/services/wordlist.js
index 04012adcb..9e7e1581e 100644
--- a/services/wordlist.js
+++ b/services/wordlist.js
@@ -1,7 +1,7 @@
const debug = require('debug')('talk:services:wordlist');
const _ = require('lodash');
const SettingsService = require('./settings');
-const Errors = require('../errors');
+const { ErrContainsProfanity } = require('../errors');
const memoize = require('lodash/memoize');
const { escapeRegExp } = require('./regex');
@@ -96,7 +96,7 @@ class Wordlist {
`the field "${fieldName}" contained a phrase "${phrase}" which contained a banned word/phrase`
);
- errors.banned = Errors.ErrContainsProfanity;
+ errors.banned = new ErrContainsProfanity(phrase);
// Stop looping through the fields now, we discovered the worst possible
// situation (a banned word).
@@ -109,7 +109,7 @@ class Wordlist {
`the field "${fieldName}" contained a phrase "${phrase}" which contained a suspected word/phrase`
);
- errors.suspect = Errors.ErrContainsProfanity;
+ errors.suspect = new ErrContainsProfanity(phrase);
// Continue looping through the fields now, we discovered a possible bad
// word (suspect).
@@ -167,7 +167,7 @@ class Wordlist {
return wl.load().then(() => {
if (wl.regexp.banned.test(username)) {
- return Errors.ErrContainsProfanity;
+ throw new ErrContainsProfanity(username);
}
});
}
diff --git a/test/e2e/specs/03_embedStream.js b/test/e2e/specs/03_embedStream.js
index f45c467e8..4b6831271 100644
--- a/test/e2e/specs/03_embedStream.js
+++ b/test/e2e/specs/03_embedStream.js
@@ -96,12 +96,6 @@ module.exports = {
comments.logout();
},
- 'not logged in user clicks my profile tab': client => {
- const embedStream = client.page.embedStream();
- const profile = embedStream.goToProfileSection();
-
- profile.assert.visible('@notLoggedIn');
- },
'admin logs in': client => {
const { testData: { admin } } = client.globals;
const embedStream = client.page.embedStream();
diff --git a/test/server/graph/context.js b/test/server/graph/context.js
index a788f509b..b3319d5c4 100644
--- a/test/server/graph/context.js
+++ b/test/server/graph/context.js
@@ -1,6 +1,6 @@
const User = require('../../../models/user');
const Context = require('../../../graph/context');
-const errors = require('../../../errors');
+const { ErrNotAuthorized } = require('../../../errors');
const SettingsService = require('../../../services/settings');
const { expect } = require('chai');
@@ -54,7 +54,7 @@ describe('graph.Context', () => {
throw new Error('should not reach this point');
})
.catch(err => {
- expect(err).to.be.equal(errors.ErrNotAuthorized);
+ expect(err).to.be.an.instanceof(ErrNotAuthorized);
});
});
});
diff --git a/test/server/services/wordlist.js b/test/server/services/wordlist.js
index 7a11dbf80..313dde49f 100644
--- a/test/server/services/wordlist.js
+++ b/test/server/services/wordlist.js
@@ -1,4 +1,4 @@
-const Errors = require('../../../errors');
+const { ErrContainsProfanity } = require('../../../errors');
const Wordlist = require('../../../services/wordlist');
const SettingsService = require('../../../services/settings');
@@ -103,7 +103,8 @@ describe('services.Wordlist', () => {
'content'
);
- expect(errors).to.have.property('banned', Errors.ErrContainsProfanity);
+ expect(errors).to.have.property('banned');
+ expect(errors.banned).to.be.an.instanceof(ErrContainsProfanity);
});
it('does not match on bodies not containing bad words', () => {
diff --git a/test/setupJest.js b/test/setupJest.js
new file mode 100644
index 000000000..6ed78a9c5
--- /dev/null
+++ b/test/setupJest.js
@@ -0,0 +1,31 @@
+const mongoose = require('../services/mongoose');
+
+beforeAll(function(done) {
+ mongoose.connection.on('open', function(err) {
+ if (err) {
+ return done(err);
+ }
+
+ return done();
+ });
+}, 30000);
+
+beforeEach(async () => {
+ await Promise.all(
+ Object.keys(mongoose.connection.collections).map(collection => {
+ return new Promise((resolve, reject) => {
+ mongoose.connection.collections[collection].remove(function(err) {
+ if (err) {
+ return reject(err);
+ }
+
+ return resolve();
+ });
+ });
+ })
+ );
+});
+
+afterAll(async function() {
+ await mongoose.disconnect();
+});
diff --git a/yarn.lock b/yarn.lock
index 07a395260..598b56829 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -159,7 +159,7 @@ a-sync-waterfall@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/a-sync-waterfall/-/a-sync-waterfall-1.0.0.tgz#38e8319d79379e24628845b53b96722b29e0e47c"
-abab@^1.0.0, abab@^1.0.3, abab@^1.0.4:
+abab@^1.0.0, abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@@ -186,7 +186,7 @@ acorn-globals@^1.0.4:
dependencies:
acorn "^2.1.0"
-acorn-globals@^3.0.0, acorn-globals@^3.1.0:
+acorn-globals@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf"
dependencies:
@@ -856,6 +856,13 @@ babel-jest@^21.2.0:
babel-plugin-istanbul "^4.0.0"
babel-preset-jest "^21.2.0"
+babel-jest@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-22.4.3.tgz#4b7a0b6041691bbd422ab49b3b73654a49a6627a"
+ dependencies:
+ babel-plugin-istanbul "^4.1.5"
+ babel-preset-jest "^22.4.3"
+
babel-loader@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.2.tgz#f6cbe122710f1aa2af4d881c6d5b54358ca24126"
@@ -890,10 +897,23 @@ babel-plugin-istanbul@^4.0.0:
istanbul-lib-instrument "^1.7.5"
test-exclude "^4.1.1"
+babel-plugin-istanbul@^4.1.5:
+ version "4.1.6"
+ resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
+ dependencies:
+ babel-plugin-syntax-object-rest-spread "^6.13.0"
+ find-up "^2.1.0"
+ istanbul-lib-instrument "^1.10.1"
+ test-exclude "^4.2.1"
+
babel-plugin-jest-hoist@^21.2.0:
version "21.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006"
+babel-plugin-jest-hoist@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.3.tgz#7d8bcccadc2667f96a0dcc6afe1891875ee6c14a"
+
babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
@@ -1226,6 +1246,13 @@ babel-preset-jest@^21.2.0:
babel-plugin-jest-hoist "^21.2.0"
babel-plugin-syntax-object-rest-spread "^6.13.0"
+babel-preset-jest@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.3.tgz#e92eef9813b7026ab4ca675799f37419b5a44156"
+ dependencies:
+ babel-plugin-jest-hoist "^22.4.3"
+ babel-plugin-syntax-object-rest-spread "^6.13.0"
+
babel-preset-react@^6.23.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380"
@@ -1652,6 +1679,13 @@ 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"
+bunyan-debug-stream@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-1.0.8.tgz#df612852d5d0b6d6df3f30214d8a7e4ee925106d"
+ dependencies:
+ colors "^1.0.3"
+ exception-formatter "^1.0.4"
+
bunyan@^1.8.12:
version "1.8.12"
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
@@ -2046,6 +2080,14 @@ cliui@^3.0.3, cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
+cliui@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
+ dependencies:
+ string-width "^2.1.1"
+ strip-ansi "^4.0.0"
+ wrap-ansi "^2.0.0"
+
clone@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
@@ -2135,6 +2177,10 @@ colors@1.0.3, colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
+colors@^1.0.3:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794"
+
colors@^1.1.2, colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@@ -2189,6 +2235,10 @@ commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+compare-versions@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.1.0.tgz#43310256a5c555aaed4193c04d8f154cf9c6efd5"
+
component-emitter@^1.2.0, component-emitter@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
@@ -2323,10 +2373,6 @@ content-security-policy-builder@1.1.0:
dependencies:
dashify "^0.2.0"
-content-type-parser@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.1.tgz#c3e56988c53c65127fb46d4032a3a900246fdc94"
-
content-type-parser@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
@@ -2335,7 +2381,11 @@ content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
-convert-source-map@^1.4.0, convert-source-map@^1.5.0:
+convert-source-map@^1.4.0:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5"
+
+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"
@@ -2721,7 +2771,7 @@ debug@*, debug@3.1.0, debug@^3.0.0, debug@^3.0.1, debug@^3.1.0:
dependencies:
ms "2.0.0"
-debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.3, debug@^2.6.8:
+debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
@@ -2874,6 +2924,10 @@ detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
+detect-newline@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
+
dialog-polyfill@^0.4.9:
version "0.4.9"
resolved "https://registry.yarnpkg.com/dialog-polyfill/-/dialog-polyfill-0.4.9.tgz#c690b3727c3d82e0f947bd5b910b32af8a2ef57d"
@@ -3195,6 +3249,16 @@ es-abstract@^1.4.3:
is-callable "^1.1.3"
is-regex "^1.0.4"
+es-abstract@^1.5.1:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681"
+ dependencies:
+ es-to-primitive "^1.1.1"
+ function-bind "^1.1.1"
+ has "^1.0.1"
+ is-callable "^1.1.3"
+ is-regex "^1.0.4"
+
es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864"
@@ -3480,6 +3544,12 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
+exception-formatter@^1.0.4:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/exception-formatter/-/exception-formatter-1.0.5.tgz#bda957319789cbabdf36848fb5288c59634b73a5"
+ dependencies:
+ colors "^1.0.3"
+
exec-sh@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38"
@@ -3514,6 +3584,10 @@ exit-hook@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/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"
+
expand-brackets@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
@@ -3546,17 +3620,6 @@ expect-ct@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.1.0.tgz#52735678de18530890d8d7b95f0ac63640958094"
-expect@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/expect/-/expect-21.2.1.tgz#003ac2ac7005c3c29e73b38a272d4afadd6d1d7b"
- dependencies:
- ansi-styles "^3.2.0"
- jest-diff "^21.2.1"
- jest-get-type "^21.2.0"
- jest-matcher-utils "^21.2.1"
- jest-message-util "^21.2.1"
- jest-regex-util "^21.2.0"
-
expect@^22.4.0:
version "22.4.0"
resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.0.tgz#371edf1ae15b83b5bf5ec34b42f1584660a36c16"
@@ -3568,6 +3631,17 @@ expect@^22.4.0:
jest-message-util "^22.4.0"
jest-regex-util "^22.1.0"
+expect@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674"
+ dependencies:
+ ansi-styles "^3.2.0"
+ jest-diff "^22.4.3"
+ jest-get-type "^22.4.3"
+ jest-matcher-utils "^22.4.3"
+ jest-message-util "^22.4.3"
+ jest-regex-util "^22.4.3"
+
exports-loader@^0.6.4:
version "0.6.4"
resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.6.4.tgz#d70fc6121975b35fc12830cf52754be2740fc886"
@@ -3999,20 +4073,13 @@ fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-fsevents@^1.0.0:
+fsevents@^1.0.0, fsevents@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8"
dependencies:
nan "^2.3.0"
node-pre-gyp "^0.6.39"
-fsevents@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4"
- dependencies:
- nan "^2.3.0"
- node-pre-gyp "^0.6.36"
-
fstream-ignore@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
@@ -4789,12 +4856,6 @@ html-comment-regex@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
-html-encoding-sniffer@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz#79bf7a785ea495fe66165e734153f363ff5437da"
- dependencies:
- whatwg-encoding "^1.0.1"
-
html-encoding-sniffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
@@ -4957,6 +5018,13 @@ import-lazy@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
+import-local@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc"
+ dependencies:
+ pkg-dir "^2.0.0"
+ resolve-cwd "^2.0.0"
+
imports-loader@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-0.7.1.tgz#f204b5f34702a32c1db7d48d89d5e867a0441253"
@@ -5500,33 +5568,50 @@ isstream@0.1.x, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
-istanbul-api@^1.1.1:
- version "1.1.14"
- resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.14.tgz#25bc5701f7c680c0ffff913de46e3619a3a6e680"
+istanbul-api@^1.1.14:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.1.tgz#4c3b05d18c0016d1022e079b98dc82c40f488954"
dependencies:
async "^2.1.4"
+ compare-versions "^3.1.0"
fileset "^2.0.2"
- istanbul-lib-coverage "^1.1.1"
- istanbul-lib-hook "^1.0.7"
- istanbul-lib-instrument "^1.8.0"
- istanbul-lib-report "^1.1.1"
- istanbul-lib-source-maps "^1.2.1"
- istanbul-reports "^1.1.2"
+ istanbul-lib-coverage "^1.2.0"
+ istanbul-lib-hook "^1.2.0"
+ istanbul-lib-instrument "^1.10.1"
+ istanbul-lib-report "^1.1.4"
+ istanbul-lib-source-maps "^1.2.4"
+ istanbul-reports "^1.3.0"
js-yaml "^3.7.0"
mkdirp "^0.5.1"
once "^1.4.0"
-istanbul-lib-coverage@^1.0.1, istanbul-lib-coverage@^1.1.1:
+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-hook@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc"
+istanbul-lib-coverage@^1.1.2, istanbul-lib-coverage@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341"
+
+istanbul-lib-hook@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz#ae556fd5a41a6e8efa0b1002b1e416dfeaf9816c"
dependencies:
append-transform "^0.4.0"
-istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0:
+istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.8.0:
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b"
+ 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.2.0"
+ semver "^5.3.0"
+
+istanbul-lib-instrument@^1.7.5:
version "1.8.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz#66f6c9421cc9ec4704f76f2db084ba9078a2b532"
dependencies:
@@ -5538,28 +5623,38 @@ istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-ins
istanbul-lib-coverage "^1.1.1"
semver "^5.3.0"
-istanbul-lib-report@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9"
+istanbul-lib-report@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz#e886cdf505c4ebbd8e099e4396a90d0a28e2acb5"
dependencies:
- istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-coverage "^1.2.0"
mkdirp "^0.5.1"
path-parse "^1.0.5"
supports-color "^3.1.2"
-istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c"
+istanbul-lib-source-maps@^1.2.1:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz#20fb54b14e14b3fb6edb6aca3571fd2143db44e6"
dependencies:
- debug "^2.6.3"
- istanbul-lib-coverage "^1.1.1"
+ debug "^3.1.0"
+ istanbul-lib-coverage "^1.1.2"
mkdirp "^0.5.1"
rimraf "^2.6.1"
source-map "^0.5.3"
-istanbul-reports@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.2.tgz#0fb2e3f6aa9922bd3ce45d05d8ab4d5e8e07bd4f"
+istanbul-lib-source-maps@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz#cc7ccad61629f4efff8e2f78adb8c522c9976ec7"
+ dependencies:
+ debug "^3.1.0"
+ istanbul-lib-coverage "^1.2.0"
+ mkdirp "^0.5.1"
+ rimraf "^2.6.1"
+ source-map "^0.5.3"
+
+istanbul-reports@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.3.0.tgz#2f322e81e1d9520767597dca3c20a0cce89a3554"
dependencies:
handlebars "^4.0.3"
@@ -5571,61 +5666,50 @@ iterall@^1.1.0, iterall@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9"
-jest-changed-files@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-21.2.0.tgz#5dbeecad42f5d88b482334902ce1cba6d9798d29"
+jest-changed-files@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-22.4.3.tgz#8882181e022c38bd46a2e4d18d44d19d90a90fb2"
dependencies:
throat "^4.0.0"
-jest-cli@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-21.2.1.tgz#9c528b6629d651911138d228bdb033c157ec8c00"
+jest-cli@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-22.4.3.tgz#bf16c4a5fb7edc3fa5b9bb7819e34139e88a72c7"
dependencies:
ansi-escapes "^3.0.0"
chalk "^2.0.1"
+ exit "^0.1.2"
glob "^7.1.2"
graceful-fs "^4.1.11"
+ import-local "^1.0.0"
is-ci "^1.0.10"
- istanbul-api "^1.1.1"
- istanbul-lib-coverage "^1.0.1"
- istanbul-lib-instrument "^1.4.2"
- istanbul-lib-source-maps "^1.1.0"
- jest-changed-files "^21.2.0"
- jest-config "^21.2.1"
- jest-environment-jsdom "^21.2.1"
- jest-haste-map "^21.2.0"
- jest-message-util "^21.2.1"
- jest-regex-util "^21.2.0"
- jest-resolve-dependencies "^21.2.0"
- jest-runner "^21.2.1"
- jest-runtime "^21.2.1"
- jest-snapshot "^21.2.1"
- jest-util "^21.2.1"
+ istanbul-api "^1.1.14"
+ istanbul-lib-coverage "^1.1.1"
+ istanbul-lib-instrument "^1.8.0"
+ istanbul-lib-source-maps "^1.2.1"
+ jest-changed-files "^22.4.3"
+ jest-config "^22.4.3"
+ jest-environment-jsdom "^22.4.3"
+ jest-get-type "^22.4.3"
+ jest-haste-map "^22.4.3"
+ jest-message-util "^22.4.3"
+ jest-regex-util "^22.4.3"
+ jest-resolve-dependencies "^22.4.3"
+ jest-runner "^22.4.3"
+ jest-runtime "^22.4.3"
+ jest-snapshot "^22.4.3"
+ jest-util "^22.4.3"
+ jest-validate "^22.4.3"
+ jest-worker "^22.4.3"
micromatch "^2.3.11"
- node-notifier "^5.0.2"
- pify "^3.0.0"
+ node-notifier "^5.2.1"
+ realpath-native "^1.0.0"
+ rimraf "^2.5.4"
slash "^1.0.0"
string-length "^2.0.0"
strip-ansi "^4.0.0"
which "^1.2.12"
- worker-farm "^1.3.1"
- yargs "^9.0.0"
-
-jest-config@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-21.2.1.tgz#c7586c79ead0bcc1f38c401e55f964f13bf2a480"
- dependencies:
- chalk "^2.0.1"
- glob "^7.1.1"
- jest-environment-jsdom "^21.2.1"
- jest-environment-node "^21.2.1"
- jest-get-type "^21.2.0"
- jest-jasmine2 "^21.2.1"
- jest-regex-util "^21.2.0"
- jest-resolve "^21.2.0"
- jest-util "^21.2.1"
- jest-validate "^21.2.1"
- pretty-format "^21.2.1"
+ yargs "^10.0.3"
jest-config@^22.4.2:
version "22.4.2"
@@ -5643,14 +5727,21 @@ jest-config@^22.4.2:
jest-validate "^22.4.2"
pretty-format "^22.4.0"
-jest-diff@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-21.2.1.tgz#46cccb6cab2d02ce98bc314011764bb95b065b4f"
+jest-config@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.3.tgz#0e9d57db267839ea31309119b41dc2fa31b76403"
dependencies:
chalk "^2.0.1"
- diff "^3.2.0"
- jest-get-type "^21.2.0"
- pretty-format "^21.2.1"
+ glob "^7.1.1"
+ jest-environment-jsdom "^22.4.3"
+ jest-environment-node "^22.4.3"
+ jest-get-type "^22.4.3"
+ jest-jasmine2 "^22.4.3"
+ jest-regex-util "^22.4.3"
+ jest-resolve "^22.4.3"
+ jest-util "^22.4.3"
+ jest-validate "^22.4.3"
+ pretty-format "^22.4.3"
jest-diff@^22.4.0:
version "22.4.0"
@@ -5661,17 +5752,24 @@ jest-diff@^22.4.0:
jest-get-type "^22.1.0"
pretty-format "^22.4.0"
-jest-docblock@^21.0.0, jest-docblock@^21.2.0:
+jest-diff@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030"
+ dependencies:
+ chalk "^2.0.1"
+ diff "^3.2.0"
+ jest-get-type "^22.4.3"
+ pretty-format "^22.4.3"
+
+jest-docblock@^21.0.0:
version "21.2.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414"
-jest-environment-jsdom@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-21.2.1.tgz#38d9980c8259b2a608ec232deee6289a60d9d5b4"
+jest-docblock@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.3.tgz#50886f132b42b280c903c592373bb6e93bb68b19"
dependencies:
- jest-mock "^21.2.0"
- jest-util "^21.2.1"
- jsdom "^9.12.0"
+ detect-newline "^2.1.0"
jest-environment-jsdom@^22.4.1:
version "22.4.1"
@@ -5681,12 +5779,13 @@ jest-environment-jsdom@^22.4.1:
jest-util "^22.4.1"
jsdom "^11.5.1"
-jest-environment-node@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-21.2.1.tgz#98c67df5663c7fbe20f6e792ac2272c740d3b8c8"
+jest-environment-jsdom@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e"
dependencies:
- jest-mock "^21.2.0"
- jest-util "^21.2.1"
+ jest-mock "^22.4.3"
+ jest-util "^22.4.3"
+ jsdom "^11.5.1"
jest-environment-node@^22.4.1:
version "22.4.1"
@@ -5695,37 +5794,32 @@ jest-environment-node@^22.4.1:
jest-mock "^22.2.0"
jest-util "^22.4.1"
-jest-get-type@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23"
+jest-environment-node@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129"
+ dependencies:
+ jest-mock "^22.4.3"
+ jest-util "^22.4.3"
jest-get-type@^22.1.0:
version "22.1.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.1.0.tgz#4e90af298ed6181edc85d2da500dbd2753e0d5a9"
-jest-haste-map@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-21.2.0.tgz#1363f0a8bb4338f24f001806571eff7a4b2ff3d8"
+jest-get-type@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
+
+jest-haste-map@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.4.3.tgz#25842fa2ba350200767ac27f658d58b9d5c2e20b"
dependencies:
fb-watchman "^2.0.0"
graceful-fs "^4.1.11"
- jest-docblock "^21.2.0"
+ jest-docblock "^22.4.3"
+ jest-serializer "^22.4.3"
+ jest-worker "^22.4.3"
micromatch "^2.3.11"
sane "^2.0.0"
- worker-farm "^1.3.1"
-
-jest-jasmine2@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-21.2.1.tgz#9cc6fc108accfa97efebce10c4308548a4ea7592"
- dependencies:
- chalk "^2.0.1"
- expect "^21.2.1"
- graceful-fs "^4.1.11"
- jest-diff "^21.2.1"
- jest-matcher-utils "^21.2.1"
- jest-message-util "^21.2.1"
- jest-snapshot "^21.2.1"
- p-cancelable "^0.3.0"
jest-jasmine2@^22.4.2:
version "22.4.2"
@@ -5743,6 +5837,22 @@ jest-jasmine2@^22.4.2:
jest-util "^22.4.1"
source-map-support "^0.5.0"
+jest-jasmine2@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.3.tgz#4daf64cd14c793da9db34a7c7b8dcfe52a745965"
+ dependencies:
+ chalk "^2.0.1"
+ co "^4.6.0"
+ expect "^22.4.3"
+ graceful-fs "^4.1.11"
+ is-generator-fn "^1.0.0"
+ jest-diff "^22.4.3"
+ jest-matcher-utils "^22.4.3"
+ jest-message-util "^22.4.3"
+ jest-snapshot "^22.4.3"
+ jest-util "^22.4.3"
+ source-map-support "^0.5.0"
+
jest-junit@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-3.6.0.tgz#f4c4358e5286364a4324dc14abddd526aadfbd38"
@@ -5751,13 +5861,11 @@ jest-junit@^3.6.0:
strip-ansi "^4.0.0"
xml "^1.0.1"
-jest-matcher-utils@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz#72c826eaba41a093ac2b4565f865eb8475de0f64"
+jest-leak-detector@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-22.4.3.tgz#2b7b263103afae8c52b6b91241a2de40117e5b35"
dependencies:
- chalk "^2.0.1"
- jest-get-type "^21.2.0"
- pretty-format "^21.2.1"
+ pretty-format "^22.4.3"
jest-matcher-utils@^22.4.0:
version "22.4.0"
@@ -5767,13 +5875,13 @@ jest-matcher-utils@^22.4.0:
jest-get-type "^22.1.0"
pretty-format "^22.4.0"
-jest-message-util@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-21.2.1.tgz#bfe5d4692c84c827d1dcf41823795558f0a1acbe"
+jest-matcher-utils@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff"
dependencies:
chalk "^2.0.1"
- micromatch "^2.3.11"
- slash "^1.0.0"
+ jest-get-type "^22.4.3"
+ pretty-format "^22.4.3"
jest-message-util@^22.4.0:
version "22.4.0"
@@ -5785,35 +5893,37 @@ jest-message-util@^22.4.0:
slash "^1.0.0"
stack-utils "^1.0.1"
-jest-mock@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-21.2.0.tgz#7eb0770e7317968165f61ea2a7281131534b3c0f"
+jest-message-util@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7"
+ dependencies:
+ "@babel/code-frame" "^7.0.0-beta.35"
+ chalk "^2.0.1"
+ micromatch "^2.3.11"
+ slash "^1.0.0"
+ stack-utils "^1.0.1"
jest-mock@^22.2.0:
version "22.2.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.2.0.tgz#444b3f9488a7473adae09bc8a77294afded397a7"
-jest-regex-util@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-21.2.0.tgz#1b1e33e63143babc3e0f2e6c9b5ba1eb34b2d530"
+jest-mock@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7"
jest-regex-util@^22.1.0:
version "22.1.0"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.1.0.tgz#5daf2fe270074b6da63e5d85f1c9acc866768f53"
-jest-resolve-dependencies@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-21.2.0.tgz#9e231e371e1a736a1ad4e4b9a843bc72bfe03d09"
- dependencies:
- jest-regex-util "^21.2.0"
+jest-regex-util@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af"
-jest-resolve@^21.2.0:
- version "21.2.0"
- resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-21.2.0.tgz#068913ad2ba6a20218e5fd32471f3874005de3a6"
+jest-resolve-dependencies@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-22.4.3.tgz#e2256a5a846732dc3969cb72f3c9ad7725a8195e"
dependencies:
- browser-resolve "^1.11.2"
- chalk "^2.0.1"
- is-builtin-module "^1.0.0"
+ jest-regex-util "^22.4.3"
jest-resolve@^22.4.2:
version "22.4.2"
@@ -5822,53 +5932,57 @@ jest-resolve@^22.4.2:
browser-resolve "^1.11.2"
chalk "^2.0.1"
-jest-runner@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-21.2.1.tgz#194732e3e518bfb3d7cbfc0fd5871246c7e1a467"
+jest-resolve@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea"
dependencies:
- jest-config "^21.2.1"
- jest-docblock "^21.2.0"
- jest-haste-map "^21.2.0"
- jest-jasmine2 "^21.2.1"
- jest-message-util "^21.2.1"
- jest-runtime "^21.2.1"
- jest-util "^21.2.1"
- pify "^3.0.0"
- throat "^4.0.0"
- worker-farm "^1.3.1"
+ browser-resolve "^1.11.2"
+ chalk "^2.0.1"
-jest-runtime@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-21.2.1.tgz#99dce15309c670442eee2ebe1ff53a3cbdbbb73e"
+jest-runner@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-22.4.3.tgz#298ddd6a22b992c64401b4667702b325e50610c3"
+ dependencies:
+ exit "^0.1.2"
+ jest-config "^22.4.3"
+ jest-docblock "^22.4.3"
+ jest-haste-map "^22.4.3"
+ jest-jasmine2 "^22.4.3"
+ jest-leak-detector "^22.4.3"
+ jest-message-util "^22.4.3"
+ jest-runtime "^22.4.3"
+ jest-util "^22.4.3"
+ jest-worker "^22.4.3"
+ throat "^4.0.0"
+
+jest-runtime@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-22.4.3.tgz#b69926c34b851b920f666c93e86ba2912087e3d0"
dependencies:
babel-core "^6.0.0"
- babel-jest "^21.2.0"
- babel-plugin-istanbul "^4.0.0"
+ babel-jest "^22.4.3"
+ babel-plugin-istanbul "^4.1.5"
chalk "^2.0.1"
convert-source-map "^1.4.0"
+ exit "^0.1.2"
graceful-fs "^4.1.11"
- jest-config "^21.2.1"
- jest-haste-map "^21.2.0"
- jest-regex-util "^21.2.0"
- jest-resolve "^21.2.0"
- jest-util "^21.2.1"
+ jest-config "^22.4.3"
+ jest-haste-map "^22.4.3"
+ jest-regex-util "^22.4.3"
+ jest-resolve "^22.4.3"
+ jest-util "^22.4.3"
+ jest-validate "^22.4.3"
json-stable-stringify "^1.0.1"
micromatch "^2.3.11"
+ realpath-native "^1.0.0"
slash "^1.0.0"
strip-bom "3.0.0"
write-file-atomic "^2.1.0"
- yargs "^9.0.0"
+ yargs "^10.0.3"
-jest-snapshot@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-21.2.1.tgz#29e49f16202416e47343e757e5eff948c07fd7b0"
- dependencies:
- chalk "^2.0.1"
- jest-diff "^21.2.1"
- jest-matcher-utils "^21.2.1"
- mkdirp "^0.5.1"
- natural-compare "^1.4.0"
- pretty-format "^21.2.1"
+jest-serializer@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-22.4.3.tgz#a679b81a7f111e4766235f4f0c46d230ee0f7436"
jest-snapshot@^22.4.0:
version "22.4.0"
@@ -5881,17 +5995,16 @@ jest-snapshot@^22.4.0:
natural-compare "^1.4.0"
pretty-format "^22.4.0"
-jest-util@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-21.2.1.tgz#a274b2f726b0897494d694a6c3d6a61ab819bb78"
+jest-snapshot@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2"
dependencies:
- callsites "^2.0.0"
chalk "^2.0.1"
- graceful-fs "^4.1.11"
- jest-message-util "^21.2.1"
- jest-mock "^21.2.0"
- jest-validate "^21.2.1"
+ jest-diff "^22.4.3"
+ jest-matcher-utils "^22.4.3"
mkdirp "^0.5.1"
+ natural-compare "^1.4.0"
+ pretty-format "^22.4.3"
jest-util@^22.4.1:
version "22.4.1"
@@ -5905,14 +6018,17 @@ jest-util@^22.4.1:
mkdirp "^0.5.1"
source-map "^0.6.0"
-jest-validate@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7"
+jest-util@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac"
dependencies:
+ callsites "^2.0.0"
chalk "^2.0.1"
- jest-get-type "^21.2.0"
- leven "^2.1.0"
- pretty-format "^21.2.1"
+ graceful-fs "^4.1.11"
+ is-ci "^1.0.10"
+ jest-message-util "^22.4.3"
+ mkdirp "^0.5.1"
+ source-map "^0.6.0"
jest-validate@^22.4.0, jest-validate@^22.4.2:
version "22.4.2"
@@ -5924,11 +6040,28 @@ jest-validate@^22.4.0, jest-validate@^22.4.2:
leven "^2.1.0"
pretty-format "^22.4.0"
-jest@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/jest/-/jest-21.2.1.tgz#c964e0b47383768a1438e3ccf3c3d470327604e1"
+jest-validate@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.3.tgz#0780954a5a7daaeec8d3c10834b9280865976b30"
dependencies:
- jest-cli "^21.2.1"
+ chalk "^2.0.1"
+ jest-config "^22.4.3"
+ jest-get-type "^22.4.3"
+ leven "^2.1.0"
+ pretty-format "^22.4.3"
+
+jest-worker@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.4.3.tgz#5c421417cba1c0abf64bf56bd5fb7968d79dd40b"
+ dependencies:
+ merge-stream "^1.0.1"
+
+jest@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-22.4.3.tgz#2261f4b117dc46d9a4a1a673d2150958dee92f16"
+ dependencies:
+ import-local "^1.0.0"
+ jest-cli "^22.4.3"
joi@^13.0.0:
version "13.1.2"
@@ -5981,13 +6114,20 @@ js-yaml@0.3.x:
version "0.3.7"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-0.3.7.tgz#d739d8ee86461e54b354d6a7d7d1f2ad9a167f62"
-js-yaml@^3.4.3, js-yaml@^3.5.2, js-yaml@^3.6.1, js-yaml@^3.7.0, js-yaml@^3.9.0, js-yaml@^3.9.1:
+js-yaml@^3.4.3, js-yaml@^3.5.2, js-yaml@^3.6.1, js-yaml@^3.9.0, js-yaml@^3.9.1:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
+js-yaml@^3.7.0:
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
js-yaml@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
@@ -6050,30 +6190,6 @@ jsdom@^7.0.2:
whatwg-url-compat "~0.6.5"
xml-name-validator ">= 2.0.1 < 3.0.0"
-jsdom@^9.12.0:
- version "9.12.0"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4"
- dependencies:
- abab "^1.0.3"
- acorn "^4.0.4"
- acorn-globals "^3.1.0"
- array-equal "^1.0.0"
- content-type-parser "^1.0.1"
- cssom ">= 0.3.2 < 0.4.0"
- cssstyle ">= 0.2.37 < 0.3.0"
- escodegen "^1.6.1"
- html-encoding-sniffer "^1.0.1"
- nwmatcher ">= 1.3.9 < 2.0.0"
- parse5 "^1.5.1"
- request "^2.79.0"
- sax "^1.2.1"
- symbol-tree "^3.2.1"
- tough-cookie "^2.3.2"
- webidl-conversions "^4.0.0"
- whatwg-encoding "^1.0.1"
- whatwg-url "^4.3.0"
- xml-name-validator "^2.0.1"
-
jsesc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
@@ -6971,6 +7087,12 @@ merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+merge-stream@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1"
+ dependencies:
+ readable-stream "^2.0.1"
+
merge@^1.1.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
@@ -7294,7 +7416,7 @@ moo-server@*, moo-server@1.3.x:
version "1.3.0"
resolved "https://registry.yarnpkg.com/moo-server/-/moo-server-1.3.0.tgz#5dc79569565a10d6efed5439491e69d2392e58f1"
-morgan@^1.6.1, morgan@^1.9.0:
+morgan@^1.6.1:
version "1.9.0"
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.0.tgz#d01fa6c65859b76fcf31b3cb53a3821a311d8051"
dependencies:
@@ -7560,16 +7682,16 @@ node-libs-browser@^2.0.0:
util "^0.10.3"
vm-browserify "0.0.4"
-node-notifier@^5.0.2:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.1.2.tgz#2fa9e12605fa10009d44549d6fcd8a63dde0e4ff"
+node-notifier@^5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea"
dependencies:
growly "^1.3.0"
- semver "^5.3.0"
- shellwords "^0.1.0"
- which "^1.2.12"
+ semver "^5.4.1"
+ shellwords "^0.1.1"
+ which "^1.3.0"
-node-pre-gyp@^0.6.36, node-pre-gyp@^0.6.39:
+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"
dependencies:
@@ -7843,7 +7965,7 @@ nunjucks@^3.1.2:
optionalDependencies:
chokidar "^1.6.0"
-"nwmatcher@>= 1.3.7 < 2.0.0", "nwmatcher@>= 1.3.9 < 2.0.0", nwmatcher@^1.4.3:
+"nwmatcher@>= 1.3.7 < 2.0.0", nwmatcher@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
@@ -7898,6 +8020,13 @@ object.entries@^1.0.4:
function-bind "^1.1.0"
has "^1.0.1"
+object.getownpropertydescriptors@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.5.1"
+
object.omit@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
@@ -8021,10 +8150,6 @@ output-file-sync@^1.1.2:
mkdirp "^0.5.1"
object-assign "^4.1.0"
-p-cancelable@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/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"
@@ -8861,16 +8986,16 @@ prettier@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93"
-pretty-format@^21.2.1:
- version "21.2.1"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36"
+pretty-format@^22.4.0:
+ version "22.4.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.0.tgz#237b1f7e1c50ed03bc65c03ccc29d7c8bb7beb94"
dependencies:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
-pretty-format@^22.4.0:
- version "22.4.0"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.0.tgz#237b1f7e1c50ed03bc65c03ccc29d7c8bb7beb94"
+pretty-format@^22.4.3:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f"
dependencies:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
@@ -9541,6 +9666,12 @@ readdirp@^2.0.0:
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"
+realpath-native@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.0.tgz#7885721a83b43bd5327609f0ddecb2482305fdf0"
+ dependencies:
+ util.promisify "^1.0.0"
+
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@@ -9729,7 +9860,7 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.0"
tough-cookie ">=2.3.3"
-request@2, request@^2.55.0, request@^2.74.0, request@^2.79.0, request@^2.81.0, request@^2.83.0:
+request@2, request@^2.55.0, request@^2.74.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"
dependencies:
@@ -9838,6 +9969,12 @@ require_optional@~1.0.0:
resolve-from "^2.0.0"
semver "^5.1.0"
+resolve-cwd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+ dependencies:
+ resolve-from "^3.0.0"
+
resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
@@ -9846,6 +9983,10 @@ resolve-from@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/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"
+
resolve-from@~4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
@@ -9981,13 +10122,13 @@ samsam@1.x, samsam@^1.1.3:
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
sane@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/sane/-/sane-2.2.0.tgz#d6d2e2fcab00e3d283c93b912b7c3a20846f1d56"
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.0.tgz#6359cd676f5efd9988b264d8ce3b827dd6b27bec"
dependencies:
- anymatch "^1.3.0"
+ anymatch "^2.0.0"
exec-sh "^0.2.0"
fb-watchman "^2.0.0"
- minimatch "^3.0.2"
+ micromatch "^3.1.4"
minimist "^1.1.1"
walker "~1.0.5"
watch "~0.18.0"
@@ -10022,7 +10163,7 @@ sax@0.5.x:
version "0.5.8"
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
-sax@^1.1.4, sax@^1.2.1, sax@^1.2.4, sax@~1.2.1:
+sax@^1.1.4, sax@^1.2.4, sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -10257,7 +10398,7 @@ shelljs@^0.7.0:
interpret "^1.0.0"
rechoir "^0.6.2"
-shellwords@^0.1.0:
+shellwords@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@@ -10871,7 +11012,7 @@ symbol-observable@^1.0.2, symbol-observable@^1.0.3, symbol-observable@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
-"symbol-tree@>= 3.1.0 < 4.0.0", symbol-tree@^3.2.1, symbol-tree@^3.2.2:
+"symbol-tree@>= 3.1.0 < 4.0.0", symbol-tree@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
@@ -10955,6 +11096,16 @@ test-exclude@^4.1.1:
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"
+test-exclude@^4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa"
+ dependencies:
+ arrify "^1.0.1"
+ micromatch "^3.1.8"
+ object-assign "^4.1.0"
+ read-pkg-up "^1.0.1"
+ require-main-filename "^1.0.1"
+
text-encoding@0.6.4, text-encoding@^0.6.4:
version "0.6.4"
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
@@ -11122,7 +11273,7 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
-tough-cookie@>=2.3.3, tough-cookie@^2.2.0, tough-cookie@^2.3.2, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
+tough-cookie@>=2.3.3, tough-cookie@^2.2.0, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
@@ -11134,7 +11285,7 @@ tr46@^1.0.0:
dependencies:
punycode "^2.1.0"
-tr46@~0.0.1, tr46@~0.0.3:
+tr46@~0.0.1:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
@@ -11450,6 +11601,13 @@ util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+util.promisify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
+ dependencies:
+ define-properties "^1.1.2"
+ object.getownpropertydescriptors "^2.0.3"
+
util@0.10.3, "util@>=0.10.3 <1", util@^0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
@@ -11563,11 +11721,7 @@ webidl-conversions@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-2.0.1.tgz#3bf8258f7d318c7443c36f2e169402a1a6703506"
-webidl-conversions@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
-
-webidl-conversions@^4.0.0, webidl-conversions@^4.0.1, webidl-conversions@^4.0.2:
+webidl-conversions@^4.0.1, webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
@@ -11634,13 +11788,6 @@ whatwg-url-compat@~0.6.5:
dependencies:
tr46 "~0.0.1"
-whatwg-url@^4.3.0:
- version "4.8.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0"
- dependencies:
- tr46 "~0.0.3"
- webidl-conversions "^3.0.0"
-
whatwg-url@^6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08"
@@ -11661,7 +11808,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-which@1, which@^1.2.10, which@^1.2.12, which@^1.2.9:
+which@1, which@^1.2.10, which@^1.2.12, which@^1.2.9, which@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
@@ -11787,7 +11934,7 @@ xdg-basedir@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
-"xml-name-validator@>= 2.0.1 < 3.0.0", xml-name-validator@^2.0.1:
+"xml-name-validator@>= 2.0.1 < 3.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
@@ -11870,6 +12017,29 @@ yargs-parser@^7.0.0:
dependencies:
camelcase "^4.1.0"
+yargs-parser@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
+ dependencies:
+ camelcase "^4.1.0"
+
+yargs@^10.0.3:
+ version "10.1.2"
+ resolved "https://registry.yarnpkg.com/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"
+ 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 "^8.1.0"
+
yargs@^3.19.0, yargs@^3.32.0:
version "3.32.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
@@ -11956,24 +12126,6 @@ yargs@^8.0.2:
y18n "^3.2.1"
yargs-parser "^7.0.0"
-yargs@^9.0.0:
- version "9.0.1"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c"
- 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@~3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"