Merge branch 'live-reported' of ssh://github.com/coralproject/talk into live-reported

This commit is contained in:
Chi Vinh Le
2018-01-19 17:04:49 +01:00
30 changed files with 778 additions and 252 deletions
+1
View File
@@ -5,6 +5,7 @@ ONBUILD ARG TALK_THREADING_LEVEL=3
ONBUILD ARG TALK_DEFAULT_STREAM_TAB=all
ONBUILD ARG TALK_DEFAULT_LANG=en
ONBUILD ARG TALK_PLUGINS_JSON
ONBUILD ARG TALK_WEBPACK_SOURCE_MAP
# Bundle app source
ONBUILD COPY . /usr/src/app
+73
View File
@@ -14,6 +14,7 @@ const AssetsService = require('../services/assets');
const mongoose = require('../services/mongoose');
const scraper = require('../services/scraper');
const inquirer = require('inquirer');
const { URL } = require('url');
// Register the shutdown criteria.
util.onshutdown([() => mongoose.disconnect()]);
@@ -125,6 +126,70 @@ async function merge(srcID, dstID) {
}
}
async function rewrite(search, replace, options) {
try {
search = new RegExp(search);
const assets = await AssetModel.find({
url: { $regex: search },
});
if (assets.length === 0) {
console.log(`No assets found with the pattern: ${search}`);
return util.shutdown(0);
}
let opts = [];
assets.forEach(({ id, url: oldURL }) => {
// Replace the url.
const newURL = oldURL.replace(search, replace);
// Try to validate that the new url is valid.
try {
new URL(newURL);
} catch (err) {
throw new Error(
`Rewrite would have replaced the valid URL ${oldURL} with an invalid one ${newURL}`
);
}
opts.push({
find: { id },
updateOne: { $set: { url: newURL } },
id,
oldURL,
newURL,
});
});
if (opts.length > 0) {
if (options.dryRun) {
const table = new Table({ head: ['ID', 'Old URL', 'New URL'] });
opts.forEach(({ id, oldURL, newURL }) => {
table.push([id, oldURL, newURL]);
});
console.log(table.toString());
} else {
const bulk = AssetModel.collection.initializeUnorderedBulkOp();
opts.forEach(({ find, updateOne, oldURL, newURL }) => {
// If the url was updated with the operation, then queue up the update op.
if (newURL !== oldURL) {
bulk.find(find).updateOne(updateOne);
}
});
await bulk.execute();
console.log(`${opts.length} assets had their url's updated`);
}
}
util.shutdown(0);
} catch (err) {
console.error(err);
util.shutdown(1);
}
}
//==============================================================================
// Setting up the program command line arguments.
//==============================================================================
@@ -151,6 +216,14 @@ program
)
.action(merge);
program
.command('rewrite <search> <replace>')
.option('-d, --dry-run', 'enables dry run of the replacement')
.description(
"rewrites asset url's using the provided regex replacement pattern"
)
.action(rewrite);
program.parse(process.argv);
// If there is no command listed, output help.
+7
View File
@@ -19,6 +19,13 @@ machine:
# - sudo apt-get install -y mongodb-org
# - sudo service mongod restart
# Force sync the time.
- date
- sudo service ntp stop
- sudo ntpdate -s time.nist.gov
- sudo service ntp start
- date
# Install chromium for e2e and remove old google-chrome
- sudo rm -rf /opt/google/chrome
- sudo rm -f /usr/bin/google-chrome*
@@ -4,7 +4,7 @@ import { CSSTransitionGroup } from 'react-transition-group';
import styles from './CommentAnimatedEdit.css';
import PropTypes from 'prop-types';
const CommentBodyHighlighter = ({ children, body }) => {
const CommentAnimatedEdit = ({ children, body }) => {
return (
<CSSTransitionGroup
component={'div'}
@@ -27,9 +27,9 @@ const CommentBodyHighlighter = ({ children, body }) => {
);
};
CommentBodyHighlighter.propTypes = {
CommentAnimatedEdit.propTypes = {
children: PropTypes.node,
body: PropTypes.string,
};
export default CommentBodyHighlighter;
export default CommentAnimatedEdit;
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { matchLinks } from '../utils';
import memoize from 'lodash/memoize';
@@ -62,16 +63,47 @@ function markLinks(body) {
return content;
}
export default ({ suspectWords, bannedWords, body, ...rest }) => {
// First highlight links.
const content = markLinks(body).map((element, index) => {
// Keep highlighted links.
if (typeof element !== 'string') {
return element;
}
const CommentFormatter = ({
body,
suspectWords,
bannedWords,
className = 'comment',
...rest
}) => {
// Breaking the body by line break
const textbreaks = body.split('\n');
// Highlight suspect and banned phrase inside this part of text.
return markPhrases(element, suspectWords, bannedWords, index);
});
return <div {...rest}>{content}</div>;
return (
<span className={`${className}-text`} {...rest}>
{textbreaks.map((line, i) => {
const content = markLinks(line).map((element, index) => {
// Keep highlighted links.
if (typeof element !== 'string') {
return element;
}
// Highlight suspect and banned phrase inside this part of text.
return markPhrases(element, suspectWords, bannedWords, index);
});
return (
<span key={i} className={`${className}-line`}>
{content}
{i !== textbreaks.length - 1 && (
<br className={`${className}-linebreak`} />
)}
</span>
);
})}
</span>
);
};
CommentFormatter.propTypes = {
className: PropTypes.string,
bannedWords: PropTypes.array,
suspectWords: PropTypes.array,
body: PropTypes.string,
};
export default CommentFormatter;
@@ -5,7 +5,7 @@ import { Link } from 'react-router';
import { Icon } from 'coral-ui';
import CommentDetails from './CommentDetails';
import styles from './UserDetailComment.css';
import CommentBodyHighlighter from 'coral-admin/src/components/CommentBodyHighlighter';
import CommentFormatter from 'coral-admin/src/components/CommentFormatter';
import IfHasLink from 'coral-admin/src/components/IfHasLink';
import cn from 'classnames';
import CommentAnimatedEdit from './CommentAnimatedEdit';
@@ -78,11 +78,12 @@ class UserDetailComment extends React.Component {
<CommentAnimatedEdit body={comment.body}>
<div className={styles.bodyContainer}>
<div className={styles.body}>
<CommentBodyHighlighter
<CommentFormatter
suspectWords={suspect}
bannedWords={banned}
body={comment.body}
/>{' '}
className="talk-admin-user-detail-comment"
/>
<a
className={styles.external}
href={`${comment.asset.url}?commentId=${comment.id}`}
@@ -8,7 +8,7 @@ import styles from './Comment.css';
import CommentLabels from 'coral-admin/src/components/CommentLabels';
import CommentAnimatedEdit from 'coral-admin/src/components/CommentAnimatedEdit';
import Slot from 'coral-framework/components/Slot';
import CommentBodyHighlighter from 'coral-admin/src/components/CommentBodyHighlighter';
import CommentFormatter from 'coral-admin/src/components/CommentFormatter';
import IfHasLink from 'coral-admin/src/components/IfHasLink';
import cn from 'classnames';
import ApproveButton from 'coral-admin/src/components/ApproveButton';
@@ -126,11 +126,12 @@ class Comment extends React.Component {
<CommentAnimatedEdit body={comment.body}>
<div className={styles.itemBody}>
<div className={styles.body}>
<CommentBodyHighlighter
<CommentFormatter
suspectWords={settings.wordlist.suspect}
bannedWords={settings.wordlist.banned}
className="talk-admin-comment"
body={comment.body}
/>{' '}
/>
<a
className={styles.external}
href={`${comment.asset.url}?commentId=${comment.id}`}
@@ -3,15 +3,15 @@ import { gql, compose } from 'react-apollo';
import { withFragments } from 'coral-framework/hocs';
import AssetStatusInfo from '../components/AssetStatusInfo';
import PropTypes from 'prop-types';
import { withUpdateAssetStatus } from 'coral-framework/graphql/mutations';
import {
withUpdateAssetStatus,
withCloseAsset,
} from 'coral-framework/graphql/mutations';
class AssetStatusInfoContainer extends React.Component {
openAsset = () =>
this.props.updateAssetStatus(this.props.asset.id, { closedAt: null });
closeAsset = () =>
this.props.updateAssetStatus(this.props.asset.id, {
closedAt: new Date().toISOString(),
});
closeAsset = () => this.props.closeAsset(this.props.asset.id);
render() {
return (
@@ -29,6 +29,7 @@ class AssetStatusInfoContainer extends React.Component {
AssetStatusInfoContainer.propTypes = {
asset: PropTypes.object.isRequired,
updateAssetStatus: PropTypes.func.isRequired,
closeAsset: PropTypes.func.isRequired,
};
const withAssetStatusInfoFragments = withFragments({
@@ -41,6 +42,10 @@ const withAssetStatusInfoFragments = withFragments({
`,
});
const enhance = compose(withAssetStatusInfoFragments, withUpdateAssetStatus);
const enhance = compose(
withAssetStatusInfoFragments,
withUpdateAssetStatus,
withCloseAsset
);
export default enhance(AssetStatusInfoContainer);
+16 -15
View File
@@ -3,27 +3,28 @@ import { createDefaultResponseFragments } from '../utils';
// fragments defined here are automatically registered.
export default {
...createDefaultResponseFragments(
'SetUserRoleResponse',
'ChangeUsernameResponse',
'SetUsernameResponse',
'BanUsersResponse',
'UnbanUserResponse',
'SetUserSuspensionStatusResponse',
'SetCommentStatusResponse',
'SetUsernameStatusResponse',
'UnsuspendUserResponse',
'SuspendUserResponse',
'ChangeUsernameResponse',
'CloseAssetResponse',
'CreateCommentResponse',
'CreateFlagResponse',
'EditCommentResponse',
'PostFlagResponse',
'CreateDontAgreeResponse',
'CreateFlagResponse',
'DeleteActionResponse',
'ModifyTagResponse',
'EditCommentResponse',
'IgnoreUserResponse',
'ModifyTagResponse',
'PostFlagResponse',
'SetCommentStatusResponse',
'SetUsernameResponse',
'SetUsernameStatusResponse',
'SetUserRoleResponse',
'SetUserSuspensionStatusResponse',
'StopIgnoringUserResponse',
'UpdateSettingsResponse',
'SuspendUserResponse',
'UnbanUserResponse',
'UnsuspendUserResponse',
'UpdateAssetSettingsResponse',
'UpdateAssetStatusResponse'
'UpdateAssetStatusResponse',
'UpdateSettingsResponse'
),
};
@@ -665,3 +665,46 @@ export const withUpdateAssetStatus = withMutation(
}),
}
);
export const withCloseAsset = withMutation(
gql`
mutation CloseAsset($id: ID!) {
closeAsset(id: $id) {
...CloseAssetResponse
}
}
`,
{
props: ({ mutate }) => ({
closeAsset: id => {
return mutate({
variables: {
id,
},
optimisticResponse: {
closeAsset: {
__typename: 'CloseAssetResponse',
errors: null,
},
},
update: proxy => {
const fragment = gql`
fragment Talk_CloseAssetResponse on Asset {
closedAt
isClosed
}
`;
const fragmentId = `Asset_${id}`;
const data = {
__typename: 'Asset',
closedAt: new Date(),
isClosed: true,
};
proxy.writeFragment({ fragment, id: fragmentId, data });
},
});
},
}),
}
);
+25 -12
View File
@@ -9,6 +9,8 @@ import 'moment/locale/es';
import 'moment/locale/fr';
import 'moment/locale/pt-br';
import { createStorage } from 'coral-framework/services/storage';
import daTA from 'timeago.js/locales/da';
import esTA from 'timeago.js/locales/es';
import frTA from 'timeago.js/locales/fr';
@@ -38,25 +40,35 @@ const translations = {
let lang;
let timeagoInstance;
function setLocale(locale) {
function setLocale(storage, locale) {
try {
localStorage.setItem('locale', locale);
if (storage) {
storage.setItem('locale', locale);
}
} catch (err) {
console.error(err);
}
}
function getLocale() {
return (
localStorage.getItem('locale') ||
navigator.language ||
defaultLanguage
).split('-')[0];
function getLocale(storage) {
try {
return (
(storage && storage.getItem('locale')) ||
navigator.language ||
defaultLanguage
).split('-')[0];
} catch (err) {
console.error(err);
return null;
}
}
function init() {
const locale = getLocale();
setLocale(locale);
export function setupTranslations() {
// Setup the translation framework with the storage.
const storage = createStorage();
const locale = getLocale(storage);
setLocale(storage, locale);
// Setting moment
moment.locale(locale);
@@ -114,4 +126,5 @@ export function t(key, ...replacements) {
export default t;
init();
// Setup the translations globally as soon as this module runs.
setupTranslations();
+13 -3
View File
@@ -265,6 +265,15 @@ const ErrCannotIgnoreStaff = new APIError('Cannot ignore staff members.', {
status: 400,
});
// ErrParentDoesNotVisible is returned when the user tries to reply to a comment
// that isn't visible.
const ErrParentDoesNotVisible = new APIError(
'Cannot reply to a comment that is not visible',
{
translation_key: 'COMMENT_PARENT_NOT_VISIBLE',
}
);
module.exports = {
APIError,
ErrAlreadyExists,
@@ -276,24 +285,25 @@ module.exports = {
ErrContainsProfanity,
ErrEditWindowHasEnded,
ErrEmailTaken,
ErrEmailVerificationToken,
ErrInstallLock,
ErrInvalidAssetURL,
ErrLoginAttemptMaximumExceeded,
ErrMaxRateLimit,
ErrMissingEmail,
ErrMissingPassword,
ErrEmailVerificationToken,
ErrPasswordResetToken,
ErrMissingUsername,
ErrNotAuthorized,
ErrNotFound,
ErrNotVerified,
ErrParentDoesNotVisible,
ErrPasswordResetToken,
ErrPasswordTooShort,
ErrPermissionUpdateUsername,
ErrSameUsernameProvided,
ErrSettingsInit,
ErrSettingsNotInit,
ErrSpecialChars,
ErrUsernameTaken,
ErrSameUsernameProvided,
ExtendableError,
};
+20
View File
@@ -38,11 +38,30 @@ const updateStatus = async (ctx, id, { closedAt, closedMessage }) =>
}
);
/**
* closeNow will close an asset for commenting.
*
* @param {Object} ctx graphql context
* @param {String} id the asset's id to close
*/
const closeNow = async (ctx, id) =>
AssetModel.update(
{
id,
},
{
$set: {
closedAt: new Date(),
},
}
);
module.exports = ctx => {
let mutators = {
Asset: {
updateSettings: () => Promise.reject(errors.ErrNotAuthorized),
updateStatus: () => Promise.reject(errors.ErrNotAuthorized),
closeNow: () => Promise.reject(errors.ErrNotAuthorized),
},
};
@@ -55,6 +74,7 @@ module.exports = ctx => {
if (ctx.user.can(UPDATE_ASSET_STATUS)) {
mutators.Asset.updateStatus = (id, status) =>
updateStatus(ctx, id, status);
mutators.Asset.closeNow = id => closeNow(ctx, id);
}
}
+3
View File
@@ -94,6 +94,9 @@ const RootMutation = {
) => {
await Asset.updateStatus(id, status);
},
closeAsset: async (_, { id }, { mutators: { Asset } }) => {
await Asset.closeNow(id);
},
setUserRole: async (_, { id, role }, { mutators: { User } }) => {
await User.setRole(id, role);
},
+11
View File
@@ -1111,6 +1111,14 @@ type UpdateAssetStatusResponse implements Response {
errors: [UserError!]
}
# CloseAssetResponse is the response returned with possibly some errors
# relating to the update status attempt.
type CloseAssetResponse implements Response {
# An array of errors relating to the mutation that occurred.
errors: [UserError!]
}
# UpdateAssetSettingsResponse is the response returned with possibly some errors
# relating to the update settings attempt.
type UpdateAssetSettingsResponse implements Response {
@@ -1446,6 +1454,9 @@ type RootMutation {
# Mutation is restricted.
updateAssetStatus(id: ID!, input: UpdateAssetStatusInput!): UpdateAssetStatusResponse
# closeAsset will close the asset for commenting based on server time.
closeAsset(id: ID!): CloseAssetResponse
# updateSettings will update the global settings.
# Mutation is restricted.
updateSettings(input: UpdateSettingsInput!): UpdateSettingsResponse
+1
View File
@@ -203,6 +203,7 @@ en:
embedlink:
copy: "Copy to Clipboard"
error:
COMMENT_PARENT_NOT_VISIBLE: "The comment that you're replying to has been removed or doesn't exist."
EMAIL_VERIFICATION_TOKEN_INVALID: "Email verification token is invalid."
PASSWORD_RESET_TOKEN_INVALID: "Your password reset link is invalid."
COMMENT_TOO_SHORT: "Comments should be more than one character, please revise your comment and try again."
+1
View File
@@ -182,6 +182,7 @@ es:
embedlink:
copy: "Copiar al portapapeles"
error:
COMMENT_PARENT_NOT_VISIBLE: "El comentario a la que estás contestando ha sido eliminado o no existe."
COMMENT_TOO_SHORT: "Tu comentario debe tener algo escrito"
COMMENTING_CLOSED: "Los comentarios ya estan cerrados"
confirm_password: "Las contraseñas no coinciden. Inténtelo nuevamente"
+11
View File
@@ -37,6 +37,17 @@ const ActionSchema = new Schema(
}
);
// Create an index on the `item_id` field so that queries looking for
// actions based on the item id can resolve faster.
ActionSchema.index(
{
item_id: 1,
},
{
background: true,
}
);
const Action = mongoose.model('Action', ActionSchema);
module.exports = Action;
+1 -1
View File
@@ -41,7 +41,7 @@ const AssetSchema = new Schema(
publication_date: Date,
modified_date: Date,
// This object is used exclusivly for storing settings that are to override
// This object is used exclusively for storing settings that are to override
// the base settings from the base Settings object. This is to be accessed
// always after running `rectifySettings` against it.
settings: {
+4 -2
View File
@@ -14,7 +14,7 @@
"start:development": "NODE_ENV=development ./bin/cli-serve -j -w",
"start": "NODE_ENV=production ./bin/cli-serve -j -w",
"prebuild": "npm-run-all clean generate-introspection",
"build": "NODE_ENV=production webpack -p --bail",
"build": "NODE_ENV=production parallel-webpack --bail",
"lint:yaml": "yamllint locales/*.yml",
"lint:js": "eslint bin/* .",
"lint": "npm-run-all lint:*",
@@ -138,6 +138,7 @@
"node-fetch": "^1.7.2",
"nodemailer": "^2.6.4",
"npm-run-all": "^4.1.2",
"parallel-webpack": "^2.2.0",
"passport": "^0.4.0",
"passport-jwt": "^3.0.0",
"passport-local": "^1.0.0",
@@ -178,11 +179,12 @@
"timeago.js": "^2.0.3",
"timekeeper": "^1.0.0",
"tlds": "^1.196.0",
"uglifyjs-webpack-plugin": "^1.1.6",
"url-join": "^2.0.2",
"url-loader": "^0.6.0",
"url-search-params": "^0.9.0",
"uuid": "^3.1.0",
"webpack": "2.4.1",
"webpack": "^3.10.0",
"webpack-sources": "^1.0.1",
"yaml-loader": "^0.4.0",
"yamljs": "^0.2.10"
+9 -10
View File
@@ -68,17 +68,16 @@ then
docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
fi
if [ "$CIRCLE_BRANCH" = "master" ]
# deploy based on the env
if [ -n "$CIRCLE_TAG" ]
then
# deploy based on the env
if [ -n "$CIRCLE_TAG" ]
then
deploy_tag
else
deploy_latest
fi
deploy_tag
else
deploy_branch
if [ "$CIRCLE_BRANCH" = "master" ]
then
deploy_latest
else
deploy_branch
fi
fi
fi
+20 -15
View File
@@ -7,24 +7,31 @@ const SettingsService = require('./settings');
const cloneDeep = require('lodash/cloneDeep');
const errors = require('../errors');
const events = require('./events');
const merge = require('lodash/merge');
const { COMMENTS_NEW, COMMENTS_EDIT } = require('./events/constants');
module.exports = class CommentsService {
/**
* Creates a new Comment that came from a public source.
* @param {Mixed} comment either a single comment or an array of comments.
* @param {Object} input either a single comment or an array of comments.
* @return {Promise}
*/
static async publicCreate(comment) {
// Check to see if this is an array of comments, if so map it out.
if (Array.isArray(comment)) {
return Promise.all(comment.map(CommentsService.publicCreate));
static async publicCreate(input) {
// Extract the parent_id from the comment, if there is one.
const { status = 'NONE', parent_id = null } = input;
// Check to see if we are replying to a comment, and if that comment is
// visible.
if (parent_id !== null) {
const parent = await CommentModel.findOne({ id: parent_id });
if (parent === null || !parent.visible) {
throw errors.ErrParentDoesNotVisible;
}
}
const { status = 'NONE' } = comment;
const commentModel = new CommentModel(
Object.assign(
// Create the comment in the database.
const comment = await CommentModel.create(
merge(
{
status_history: status
? [
@@ -36,21 +43,19 @@ module.exports = class CommentsService {
: [],
body_history: [
{
body: comment.body,
body: input.body,
created_at: new Date(),
},
],
},
comment
input
)
);
const savedCommentModel = await commentModel.save();
// Emit that the comment was created!
await events.emitAsync(COMMENTS_NEW, savedCommentModel);
await events.emitAsync(COMMENTS_NEW, comment);
return savedCommentModel;
return comment;
}
/**
+1 -1
View File
@@ -7,6 +7,6 @@
],
"extends": "../.eslintrc.json",
"rules": {
"mocha/no-exclusive-tests": "warn"
"mocha/no-exclusive-tests": "error"
}
}
+3
View File
@@ -121,6 +121,9 @@ module.exports = {
embedStream.goToConfigSection().closeStream();
// Pause to give time for action to succeed.
client.pause(1000);
embedStream
.goToCommentsSection()
.waitForElementVisible('@firstComment')
@@ -116,6 +116,8 @@ describe('graph.mutations.createComment', () => {
}
expect(data.createComment).to.have.property('errors').null;
expect(data.createComment).to.have.property('comment').not.null;
expect(data.createComment.comment).to.have.property('id').not
.null;
}
}
);
+8 -6
View File
@@ -34,12 +34,14 @@ describe('graph.queries.asset', () => {
username: 'usernameC',
},
]);
comments = await CommentsService.publicCreate(
[0, 0, 1, 1].map(idx => ({
author_id: users[idx].id,
asset_id: assets[idx].id,
body: `hello there! ${String(Math.random()).slice(2)}`,
}))
comments = await Promise.all(
[0, 0, 1, 1].map(idx =>
CommentsService.publicCreate({
author_id: users[idx].id,
asset_id: assets[idx].id,
body: `hello there! ${String(Math.random()).slice(2)}`,
})
)
);
});
+24 -22
View File
@@ -176,28 +176,30 @@ describe('services.AssetsService', () => {
);
// Create some comments on both assets.
await CommentsService.publicCreate([
{
asset_id: '1',
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
asset_id: '1',
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
asset_id: '2',
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
asset_id: '2',
body: 'This is a comment!',
status: 'ACCEPTED',
},
]);
await Promise.all(
[
{
asset_id: '1',
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
asset_id: '1',
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
asset_id: '2',
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
asset_id: '2',
body: 'This is a comment!',
status: 'ACCEPTED',
},
].map(comment => CommentsService.publicCreate(comment))
);
// Merge all the comments from asset 1 into asset 2, followed by deleting
// asset 1.
+58 -25
View File
@@ -131,6 +131,64 @@ describe('services.CommentsService', () => {
});
describe('#publicCreate()', () => {
describe('does not allow replies to comments that are not visible', () => {
it('parent not found', async () => {
try {
await CommentsService.publicCreate({
body: 'This is a comment!',
status: 'ACCEPTED',
parent_id: 'does not exist',
});
throw new Error('comment should not have been created');
} catch (err) {
expect(err).to.have.property(
'translation_key',
'COMMENT_PARENT_NOT_VISIBLE'
);
}
});
it('parent REJECTED', async () => {
try {
const parent = await CommentsService.publicCreate({
body: 'This is a comment!',
status: 'REJECTED',
});
await CommentsService.publicCreate({
body: 'This is a comment!',
status: 'ACCEPTED',
parent_id: parent.id,
});
throw new Error('comment should not have been created');
} catch (err) {
expect(err).to.have.property(
'translation_key',
'COMMENT_PARENT_NOT_VISIBLE'
);
}
});
it('parent SYSTEM_WITHHELD', async () => {
try {
const parent = await CommentsService.publicCreate({
body: 'This is a comment!',
status: 'SYSTEM_WITHHELD',
});
await CommentsService.publicCreate({
body: 'This is a comment!',
status: 'ACCEPTED',
parent_id: parent.id,
});
throw new Error('comment should not have been created');
} catch (err) {
expect(err).to.have.property(
'translation_key',
'COMMENT_PARENT_NOT_VISIBLE'
);
}
});
});
it('creates a new comment', async () => {
const c = await CommentsService.publicCreate({
body: 'This is a comment!',
@@ -142,31 +200,6 @@ describe('services.CommentsService', () => {
expect(c.id).to.be.uuid;
expect(c.status).to.be.equal('ACCEPTED');
});
it('creates many new comments', async () => {
const [c1, c2, c3] = await CommentsService.publicCreate([
{
body: 'This is a comment!',
status: 'ACCEPTED',
},
{
body: 'This is another comment!',
},
{
body: 'This is a rejected comment!',
status: 'REJECTED',
},
]);
expect(c1).to.not.be.null;
expect(c1.status).to.be.equal('ACCEPTED');
expect(c2).to.not.be.null;
expect(c2.status).to.be.equal('NONE');
expect(c3).to.not.be.null;
expect(c3.status).to.be.equal('REJECTED');
});
});
describe('#edit', () => {
+59 -1
View File
@@ -7,6 +7,7 @@ const precss = require('precss');
const _ = require('lodash');
const Copy = require('copy-webpack-plugin');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const debug = require('debug')('talk:webpack');
// Possibly load the config from the .env file (if there is one).
@@ -22,12 +23,30 @@ const buildTargets = ['coral-admin', 'coral-docs'];
const buildEmbeds = ['stream'];
// In production, default turn off source maps. In development, default use
// 'cheap-module-source-map'.
const DEFAULT_WEBPACK_SOURCE_MAP =
process.env.NODE_ENV === 'production' ? 'none' : 'cheap-module-source-map';
// TALK_WEBPACK_SOURCE_MAP is sourced from the environment, defaulting based on
// the environment.
const TALK_WEBPACK_SOURCE_MAP = _.get(
process.env,
'TALK_WEBPACK_SOURCE_MAP',
DEFAULT_WEBPACK_SOURCE_MAP
);
// Set the devtool based on the source map selection, 'none' just means turn off
// source maps.
const devtool =
TALK_WEBPACK_SOURCE_MAP === 'none' ? false : TALK_WEBPACK_SOURCE_MAP;
//==============================================================================
// Base Webpack Config
//==============================================================================
const config = {
devtool: 'cheap-module-source-map',
devtool,
target: 'web',
output: {
path: path.join(__dirname, 'dist'),
@@ -99,6 +118,7 @@ const config = {
new webpack.DefinePlugin({
'process.env': {
VERSION: `"${require('./package.json').version}"`,
NODE_ENV: `${JSON.stringify(process.env.NODE_ENV)}`,
},
}),
new webpack.EnvironmentPlugin({
@@ -153,6 +173,44 @@ const config = {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
// Pulled from https://slack.engineering/keep-webpack-fast-a-field-guide-for-better-build-performance-f56a5995e8f1
new UglifyJsPlugin({
uglifyOptions: {
compress: {
arrows: false,
booleans: false,
collapse_vars: false,
comparisons: false,
computed_props: false,
hoist_funs: false,
hoist_props: false,
hoist_vars: false,
if_return: false,
inline: false,
join_vars: false,
keep_infinity: true,
loops: false,
negate_iife: false,
properties: false,
reduce_funcs: false,
reduce_vars: false,
sequences: false,
side_effects: false,
switches: false,
top_retain: false,
toplevel: false,
typeofs: false,
unused: false,
// Switch off all types of compression except those needed to convince
// react-devtools that we're using a production build
conditionals: true,
dead_code: true,
evaluate: true,
},
mangle: true,
},
}),
new CompressionPlugin({
algorithm: 'gzip',
asset: '[path].gz[query]',
+299 -113
View File
@@ -153,8 +153,8 @@ acorn@^4.0.3, acorn@^4.0.4, acorn@~4.0.2:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
acorn@^5.0.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7"
version "5.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822"
acorn@^5.2.1:
version "5.2.1"
@@ -171,15 +171,11 @@ agent-base@2:
extend "~3.0.0"
semver "~5.0.1"
ajv-keywords@^1.1.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
ajv-keywords@^2.1.0:
ajv-keywords@^2.0.0, ajv-keywords@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
ajv@^4.7.0, ajv@^4.9.1:
ajv@^4.9.1, ajv@^4.9.2:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies:
@@ -195,7 +191,7 @@ ajv@^5.0.0:
json-schema-traverse "^0.3.0"
json-stable-stringify "^1.0.1"
ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0:
ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.3, ajv@^5.3.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
@@ -456,8 +452,8 @@ asap@^2.0.0, asap@~2.0.3:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
asn1.js@^4.0.0:
version "4.9.1"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40"
version "4.9.2"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a"
dependencies:
bn.js "^4.0.0"
inherits "^2.0.1"
@@ -511,7 +507,7 @@ async@2.1.4:
dependencies:
lodash "^4.14.0"
async@2.4.1, async@^2.1.2:
async@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7"
dependencies:
@@ -521,7 +517,7 @@ async@^1.4.0, async@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@^2.1.4, async@~2.6.0:
async@^2.1.2, async@^2.1.4, async@~2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
@@ -1261,7 +1257,7 @@ bluebird@3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
bluebird@3.5.1, bluebird@^3.3.4, bluebird@^3.4.6, bluebird@^3.5.0:
bluebird@3.5.1, bluebird@^3.0.6, bluebird@^3.3.4, bluebird@^3.4.6, bluebird@^3.5.0:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
@@ -1368,8 +1364,8 @@ browser-stdout@1.3.0:
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.0.tgz#1d2ad62a8b479f23f0ab631c1be86a82dbccbe48"
version "1.1.1"
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
dependencies:
buffer-xor "^1.0.3"
cipher-base "^1.0.0"
@@ -1413,11 +1409,11 @@ browserify-sign@^4.0.0:
inherits "^2.0.1"
parse-asn1 "^5.0.0"
browserify-zlib@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
browserify-zlib@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
dependencies:
pako "~0.2.0"
pako "~1.0.5"
browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
version "1.7.7"
@@ -1959,6 +1955,10 @@ commander@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781"
commander@~2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
common-tags@^1.4.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.5.1.tgz#e2e39931a013cd02253defeed89a1ad615a27f07"
@@ -2228,8 +2228,8 @@ cryptiles@3.x.x:
boom "5.x.x"
crypto-browserify@^3.11.0:
version "3.11.1"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f"
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
dependencies:
browserify-cipher "^1.0.0"
browserify-sign "^4.0.0"
@@ -2241,6 +2241,7 @@ crypto-browserify@^3.11.0:
pbkdf2 "^3.0.3"
public-encrypt "^4.0.0"
randombytes "^2.0.0"
randomfill "^1.0.3"
crypto-random-string@^1.0.0:
version "1.0.0"
@@ -2393,6 +2394,12 @@ d3-helpers@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/d3-helpers/-/d3-helpers-0.3.0.tgz#4b31dce4a2121a77336384574d893fbed5fb293d"
d@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
dependencies:
es5-ext "^0.10.9"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -2691,6 +2698,10 @@ duplexify@^3.1.2, duplexify@^3.4.2:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
easy-stack@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.0.tgz#12c91b3085a37f0baa336e9486eac4bf94e3e788"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
@@ -2748,7 +2759,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
dependencies:
once "^1.4.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"
dependencies:
@@ -2814,7 +2825,13 @@ enzyme@^3.0.0:
raf "^3.4.0"
rst-selector-parser "^2.2.3"
errno@^0.1.3, errno@^0.1.4:
errno@^0.1.3:
version "0.1.6"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026"
dependencies:
prr "~1.0.1"
errno@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
dependencies:
@@ -2854,6 +2871,32 @@ es-to-primitive@^1.1.1:
is-date-object "^1.0.1"
is-symbol "^1.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
version "0.10.38"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3"
dependencies:
es6-iterator "~2.0.3"
es6-symbol "~3.1.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"
dependencies:
d "1"
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
es6-map@^0.1.3:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-iterator "~2.0.1"
es6-set "~0.1.5"
es6-symbol "~3.1.1"
event-emitter "~0.3.5"
es6-promise@3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
@@ -2862,6 +2905,32 @@ es6-promise@^4.0.5:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
es6-set@~0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-iterator "~2.0.1"
es6-symbol "3.1.1"
event-emitter "~0.3.5"
es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-weak-map@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
dependencies:
d "1"
es5-ext "^0.10.14"
es6-iterator "^2.0.1"
es6-symbol "^3.1.1"
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -2885,6 +2954,15 @@ escodegen@1.x.x, escodegen@^1.6.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"
dependencies:
es6-map "^0.1.3"
es6-weak-map "^2.0.1"
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-config-prettier@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3"
@@ -3018,6 +3096,17 @@ etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
event-emitter@~0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
dependencies:
d "1"
es5-ext "~0.10.14"
event-pubsub@4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e"
event-stream@~3.3.0:
version "3.3.4"
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
@@ -4198,9 +4287,9 @@ httpreq@>=0.4.22:
version "0.4.24"
resolved "https://registry.yarnpkg.com/httpreq/-/httpreq-0.4.24.tgz#4335ffd82cd969668a39465c929ac61d6393627f"
https-browserify@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
https-proxy-agent@1, https-proxy-agent@^1.0.0:
version "1.0.0"
@@ -4405,7 +4494,7 @@ inquirer@3.3.0, inquirer@^3.0.6, inquirer@^3.2.2:
strip-ansi "^4.0.0"
through "^2.3.6"
interpret@^1.0.0:
interpret@^1.0.0, interpret@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
@@ -5072,6 +5161,16 @@ js-base64@^2.1.9:
version "2.3.2"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf"
js-message@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15"
js-queue@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/js-queue/-/js-queue-2.0.0.tgz#362213cf860f468f0125fc6c96abc1742531f948"
dependencies:
easy-stack "^1.0.0"
js-stringify@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db"
@@ -5428,7 +5527,7 @@ loader-runner@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
loader-utils@^0.2.15, loader-utils@^0.2.16:
loader-utils@^0.2.15:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
dependencies:
@@ -5437,7 +5536,7 @@ loader-utils@^0.2.15, loader-utils@^0.2.16:
json5 "^0.5.0"
object-assign "^4.0.1"
loader-utils@^1.0.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"
dependencies:
@@ -5514,7 +5613,7 @@ lodash._stack@^4.0.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/lodash._stack/-/lodash._stack-4.1.3.tgz#751aa76c1b964b047e76d14fc72a093fcb5e2dd0"
lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.1.0, lodash.assign@^4.2.0:
lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.0.8, lodash.assign@^4.1.0, lodash.assign@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
@@ -5569,7 +5668,11 @@ lodash.difference@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
lodash.flatten@^4.4.0:
lodash.endswith@^4.0.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09"
lodash.flatten@^4.2.0, lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
@@ -6268,29 +6371,37 @@ node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
node-ipc@^9.1.0:
version "9.1.1"
resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.1.1.tgz#4e245ed6938e65100e595ebc5dc34b16e8dd5d69"
dependencies:
event-pubsub "4.3.0"
js-message "1.0.5"
js-queue "2.0.0"
node-libs-browser@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.0.0.tgz#a3a59ec97024985b46e958379646f96c4b616646"
version "2.1.0"
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df"
dependencies:
assert "^1.1.1"
browserify-zlib "^0.1.4"
browserify-zlib "^0.2.0"
buffer "^4.3.0"
console-browserify "^1.1.0"
constants-browserify "^1.0.0"
crypto-browserify "^3.11.0"
domain-browser "^1.1.1"
events "^1.0.0"
https-browserify "0.0.1"
os-browserify "^0.2.0"
https-browserify "^1.0.0"
os-browserify "^0.3.0"
path-browserify "0.0.0"
process "^0.11.0"
process "^0.11.10"
punycode "^1.2.4"
querystring-es3 "^0.2.0"
readable-stream "^2.0.5"
readable-stream "^2.3.3"
stream-browserify "^2.0.1"
stream-http "^2.3.1"
string_decoder "^0.10.25"
timers-browserify "^2.0.2"
stream-http "^2.7.2"
string_decoder "^1.0.0"
timers-browserify "^2.0.4"
tty-browserify "0.0.0"
url "^0.11.0"
util "^0.10.3"
@@ -6595,9 +6706,9 @@ optionator@^0.8.1, optionator@^0.8.2:
type-check "~0.3.2"
wordwrap "~1.0.0"
os-browserify@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f"
os-browserify@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
os-homedir@^1.0.0, os-homedir@^1.0.1:
version "1.0.2"
@@ -6687,9 +6798,9 @@ package-json@^4.0.0:
registry-url "^3.0.3"
semver "^5.1.0"
pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
pako@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
parallel-transform@^1.1.0:
version "1.1.0"
@@ -6699,6 +6810,23 @@ parallel-transform@^1.1.0:
inherits "^2.0.3"
readable-stream "^2.1.5"
parallel-webpack@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parallel-webpack/-/parallel-webpack-2.2.0.tgz#7171440b684444610ba890d32439a33666ab46cb"
dependencies:
ajv "^4.9.2"
bluebird "^3.0.6"
chalk "^1.1.1"
interpret "^1.0.1"
lodash.assign "^4.0.8"
lodash.endswith "^4.0.1"
lodash.flatten "^4.2.0"
minimist "^1.2.0"
node-ipc "^9.1.0"
pluralize "^1.2.1"
supports-color "^3.1.2"
worker-farm "^1.3.1"
parse-asn1@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712"
@@ -6918,6 +7046,10 @@ pluralize@7.0.0, pluralize@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
pluralize@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
pop-iterate@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pop-iterate/-/pop-iterate-1.0.1.tgz#ceacfdab4abf353d7a0f2aaa2c1fc7b3f9413ba3"
@@ -7435,7 +7567,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"
process@^0.11.0:
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
@@ -7499,6 +7631,10 @@ prr@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
prr@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/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"
@@ -7732,12 +7868,19 @@ randomatic@^1.1.3:
is-number "^3.0.0"
kind-of "^4.0.0"
randombytes@^2.0.0, randombytes@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/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"
dependencies:
randombytes "^2.0.5"
safe-buffer "^5.1.0"
range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
@@ -7751,7 +7894,7 @@ raw-body@2, raw-body@2.3.2:
iconv-lite "0.4.19"
unpipe "1.0.0"
rc@^1.0.1, rc@^1.1.6, rc@^1.1.7:
rc@^1.0.1, rc@^1.1.6:
version "1.2.2"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
dependencies:
@@ -7760,6 +7903,15 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
rc@^1.1.7:
version "1.2.4"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.4.tgz#a0f606caae2a3b862bbd0ef85482c0125b315fa3"
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-addons-create-fragment@^15.0.0:
version "15.6.2"
resolved "https://registry.yarnpkg.com/react-addons-create-fragment/-/react-addons-create-fragment-15.6.2.tgz#a394de7c2c7becd6b5475ba1b97ac472ce7c74f8"
@@ -7956,7 +8108,7 @@ read-pkg@^3.0.0:
normalize-package-data "^2.3.2"
path-type "^3.0.0"
"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, 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@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.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
@@ -7986,7 +8138,7 @@ readable-stream@1.1.x:
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@2.2.7, readable-stream@^2.0.1, readable-stream@^2.2.6:
readable-stream@2.2.7:
version "2.2.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1"
dependencies:
@@ -8449,6 +8601,13 @@ schema-utils@^0.3.0:
dependencies:
ajv "^5.0.0"
schema-utils@^0.4.2:
version "0.4.3"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.3.tgz#e2a594d3395834d5e15da22b48be13517859458e"
dependencies:
ajv "^5.0.0"
ajv-keywords "^2.1.0"
secure-keys@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/secure-keys/-/secure-keys-1.0.0.tgz#f0c82d98a3b139a8776a8808050b824431087fca"
@@ -8485,7 +8644,11 @@ semver-regex@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9"
"semver@2 || 3 || 4 || 5", semver@5.4.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1:
"semver@2 || 3 || 4 || 5", semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
semver@5.4.1, semver@^5.0.3, semver@^5.1.0, semver@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
@@ -8757,10 +8920,6 @@ sort-keys@^1.0.0:
dependencies:
is-plain-obj "^1.0.0"
source-list-map@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
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"
@@ -8789,7 +8948,7 @@ source-map@0.4.x, source-map@^0.4.4:
dependencies:
amdefine ">=0.0.4"
source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6:
source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@@ -8877,13 +9036,13 @@ stream-each@^1.1.0:
end-of-stream "^1.1.0"
stream-shift "^1.0.0"
stream-http@^2.3.1:
version "2.7.2"
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
stream-http@^2.7.2:
version "2.8.0"
resolved "https://registry.yarnpkg.com/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"
@@ -8935,16 +9094,16 @@ string.prototype.padend@^3.0.0:
es-abstract "^1.4.3"
function-bind "^1.0.2"
string_decoder@^0.10.25, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
string_decoder@~1.0.0, string_decoder@~1.0.3:
string_decoder@^1.0.0, 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"
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"
stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@@ -9048,13 +9207,13 @@ supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3:
supports-color@^3.1.2, supports-color@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
dependencies:
has-flag "^1.0.0"
supports-color@^4, supports-color@^4.0.0, supports-color@^4.4.0:
supports-color@^4, supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
dependencies:
@@ -9095,7 +9254,7 @@ table@^4.0.1:
slice-ansi "1.0.0"
string-width "^2.1.1"
tapable@^0.2.7, tapable@~0.2.5:
tapable@^0.2.7:
version "0.2.8"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
@@ -9209,7 +9368,7 @@ timekeeper@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/timekeeper/-/timekeeper-1.0.0.tgz#2f38aee1e94b11dd66d8580ff1aa9dcc6a2ba0d8"
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"
dependencies:
@@ -9379,11 +9538,18 @@ uc.micro@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"
uglify-es@^3.3.4:
version "3.3.7"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.7.tgz#d1249af668666aba7cb1163e277455be9eb393cf"
dependencies:
commander "~2.13.0"
source-map "~0.6.1"
uglify-js@1.x:
version "1.3.5"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-1.3.5.tgz#4b5bfff9186effbaa888e4c9e94bd9fc4c94929d"
uglify-js@^2.6, uglify-js@^2.6.1, uglify-js@^2.8.5:
uglify-js@^2.6, uglify-js@^2.6.1, uglify-js@^2.8.29:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
dependencies:
@@ -9396,6 +9562,27 @@ 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"
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"
dependencies:
source-map "^0.5.6"
uglify-js "^2.8.29"
webpack-sources "^1.0.1"
uglifyjs-webpack-plugin@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.6.tgz#f4ba8449edcf17835c18ba6ae99b9d610857fb19"
dependencies:
cacache "^10.0.1"
find-cache-dir "^1.0.0"
schema-utils "^0.4.2"
serialize-javascript "^1.4.0"
source-map "^0.6.1"
uglify-es "^3.3.4"
webpack-sources "^1.1.0"
worker-farm "^1.5.2"
uid-number@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
@@ -9537,7 +9724,11 @@ uuid@^2.0.1, uuid@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a"
uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0:
uuid@^3.0.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
uuid@^3.0.1, uuid@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
@@ -9608,7 +9799,7 @@ watch@~0.18.0:
exec-sh "^0.2.0"
minimist "^1.2.0"
watchpack@^1.3.1:
watchpack@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
dependencies:
@@ -9632,45 +9823,39 @@ webidl-conversions@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
webpack-sources@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb"
dependencies:
source-list-map "^1.1.1"
source-map "~0.5.3"
webpack-sources@^1.0.1, webpack-sources@^1.0.2:
webpack-sources@^1.0.1, webpack-sources@^1.0.2, webpack-sources@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54"
dependencies:
source-list-map "^2.0.0"
source-map "~0.6.1"
webpack@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.4.1.tgz#15a91dbe34966d8a4b99c7d656efd92a2e5a6f6a"
webpack@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725"
dependencies:
acorn "^5.0.0"
acorn-dynamic-import "^2.0.0"
ajv "^4.7.0"
ajv-keywords "^1.1.1"
ajv "^5.1.5"
ajv-keywords "^2.0.0"
async "^2.1.2"
enhanced-resolve "^3.0.0"
enhanced-resolve "^3.4.0"
escope "^3.6.0"
interpret "^1.0.0"
json-loader "^0.5.4"
json5 "^0.5.1"
loader-runner "^2.3.0"
loader-utils "^0.2.16"
loader-utils "^1.1.0"
memory-fs "~0.4.1"
mkdirp "~0.5.0"
node-libs-browser "^2.0.0"
source-map "^0.5.3"
supports-color "^3.1.0"
tapable "~0.2.5"
uglify-js "^2.8.5"
watchpack "^1.3.1"
webpack-sources "^0.2.3"
yargs "^6.0.0"
supports-color "^4.2.1"
tapable "^0.2.7"
uglifyjs-webpack-plugin "^0.4.6"
watchpack "^1.4.0"
webpack-sources "^1.0.1"
yargs "^8.0.2"
whatwg-encoding@^1.0.1:
version "1.0.1"
@@ -9782,6 +9967,13 @@ worker-farm@^1.3.1:
errno "^0.1.4"
xtend "^4.0.1"
worker-farm@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae"
dependencies:
errno "^0.1.4"
xtend "^4.0.1"
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
@@ -9890,12 +10082,6 @@ yargs-parser@^3.2.0:
camelcase "^3.0.0"
lodash.assign "^4.1.0"
yargs-parser@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c"
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"
@@ -9952,23 +10138,23 @@ yargs@^5.0.0:
y18n "^3.2.1"
yargs-parser "^3.2.0"
yargs@^6.0.0:
version "6.6.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"
yargs@^8.0.2:
version "8.0.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
dependencies:
camelcase "^3.0.0"
camelcase "^4.1.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"
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 "^1.0.2"
which-module "^1.0.0"
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1"
yargs-parser "^4.2.0"
yargs-parser "^7.0.0"
yargs@^9.0.0:
version "9.0.1"