feat(my-joy-instances): simpler user scripts editor (#1289)

fixes #1187
This commit is contained in:
Sara Vieira 2018-03-01 13:47:30 +00:00 committed by Sérgio Ramos
parent abe7a58e3f
commit 9d10a3fa92
30 changed files with 763 additions and 6556 deletions

View File

@ -130,9 +130,7 @@ export default compose(
i => ImageType[i] === 'Infrastructure Container' i => ImageType[i] === 'Infrastructure Container'
); );
const filtered = filter const filtered = filter ? index.search(filter) : images;
? index.search(filter)
: images;
return { return {
images: filtered images: filtered

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -3378,6 +3378,7 @@ exports[`renders <KeyValue input="textarea" /> without throwing 1`] = `
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="p" id="p"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>

View File

@ -0,0 +1,40 @@
import React, { PureComponent, Fragment } from 'react';
import { Field } from 'redux-form';
import { Margin } from 'styled-components-spacing';
import { FormGroup, Button, H3, P } from 'joyent-ui-toolkit';
import Editor from 'joyent-ui-toolkit/dist/es/editor';
class EditorField extends PureComponent {
render() {
return <Editor {...this.props} onBlur={null} mode="sh" />;
}
}
export default ({ onSubmit }) => (
<form onSubmit={onSubmit}>
<FormGroup name="value" field={Field} fluid>
<Field name="value" component={EditorField} />
<Margin bottom={4} top={4}>
<Button type="submit">Next</Button>
</Margin>
</FormGroup>
</form>
);
export const Overview = ({ script, lines }) => (
<Margin top={3}>
{script ? (
<Fragment>
<H3 noMargin>User script added</H3>
<Margin top={2}>
<P>
{lines} line{lines === 1 ? '' : 's'} of code
</P>
</Margin>
</Fragment>
) : (
<H3>No user script added</H3>
)}
</Margin>
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1011,6 +1011,7 @@ exports[`renders <AddForm /> without throwing 1`] = `
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="l" id="l"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -2141,6 +2142,7 @@ exports[`renders <EditForm /> without throwing 1`] = `
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="n" id="n"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1428,6 +1428,7 @@ Array [
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="t" id="t"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -3440,6 +3441,7 @@ Array [
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="l" id="l"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -4585,6 +4587,7 @@ Array [
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="n" id="n"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -6020,6 +6023,7 @@ Array [
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="p" id="p"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -7184,6 +7188,7 @@ Array [
className="c18 c19" className="c18 c19"
disabled={false} disabled={false}
id="r" id="r"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>

View File

@ -2,16 +2,16 @@ import React, { Fragment } from 'react';
import { compose } from 'react-apollo'; import { compose } from 'react-apollo';
import { set } from 'react-redux-values'; import { set } from 'react-redux-values';
import ReduxForm from 'declarative-redux-form'; import ReduxForm from 'declarative-redux-form';
import { destroy } from 'redux-form';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import get from 'lodash.get'; import get from 'lodash.get';
import Flex from 'styled-flex-component';
import { ScriptIcon, Button, KeyValue } from 'joyent-ui-toolkit'; import { ScriptIcon, Button } from 'joyent-ui-toolkit';
import Editor from 'joyent-ui-toolkit/dist/es/editor';
import Title from '@components/create-instance/title'; import Title from '@components/create-instance/title';
import Description from '@components/description'; import Description from '@components/description';
import UserScriptForm, { Overview } from '@components/create-instance/user-script';
const FORM_NAME = 'create-instance-user-script'; const FORM_NAME = 'create-instance-user-script';
@ -22,10 +22,9 @@ export const UserScript = ({
edit, edit,
formOpen, formOpen,
script = {}, script = {},
lines,
handleChangeOpenForm, handleChangeOpenForm,
handleSubmit, handleSubmit,
handleRemove,
handleNext,
handleEdit, handleEdit,
step step
}) => ( }) => (
@ -39,67 +38,58 @@ export const UserScript = ({
User Script User Script
</Title> </Title>
{expanded ? ( {expanded ? (
<Description> <Fragment>
User script can be used to inject a custom boot script. <Description>
</Description> User script can be used to inject a custom boot script.
</Description>
{formOpen ? (
<ReduxForm
form={FORM_NAME}
destroyOnUnmount={false}
forceUnregisterOnUnmount={true}
onSubmit={handleSubmit}
>
{props => <UserScriptForm {...props} />}
</ReduxForm>
) : null}
</Fragment>
) : null} ) : null}
<ReduxForm
form={FORM_NAME}
destroyOnUnmount={false}
forceUnregisterOnUnmount={true}
initialValues={script}
onSubmit={handleSubmit}
>
{props =>
!formOpen && create ? null : (
<KeyValue
{...props}
expanded={formOpen}
method={edit ? 'edit' : 'add'}
input="textarea"
type="user script"
onToggleExpanded={() => handleChangeOpenForm(!formOpen)}
onCancel={() => handleChangeOpenForm(false)}
onRemove={handleRemove}
editor={Editor}
onlyValue
/>
)
}
</ReduxForm>
{expanded ? ( {expanded ? (
<Margin top={formOpen || script.value ? 4 : 2} bottom={7}> <Margin top={formOpen || script.value ? 4 : 2} bottom={7}>
{script.value || formOpen ? null : ( {script.value || formOpen ? null : (
<Button <Flex alignCenter>
type="button" <Button
onClick={() => handleChangeOpenForm(true)} type="button"
secondary onClick={() => handleChangeOpenForm(true)}
> secondary
Add User Script >
</Button> Add User Script
</Button>
<Button type="submit" onClick={handleSubmit}>
Next
</Button>
</Flex>
)} )}
<Button type="submit" onClick={handleNext}>
Next
</Button>
</Margin> </Margin>
) : proceeded ? ( ) : proceeded ? (
<Margin top={4} bottom={7}> <Fragment>
<Button type="button" onClick={handleEdit} secondary> <Overview script={script} lines={lines} />
Edit <Margin top={4} bottom={7}>
</Button> <Button type="button" onClick={handleEdit} secondary>
</Margin> Edit
</Button>
</Margin>
</Fragment>
) : null} ) : null}
</Fragment> </Fragment>
); );
export default compose( export default compose(
connect( connect(
({ values }, ownProps) => { ({ values, form }, ownProps) => {
const formOpen = get(values, 'create-instance-user-script-open', false); const formOpen = get(values, 'create-instance-user-script-open', false);
const script = get(form, `${FORM_NAME}.values.value`, '');
const script = get(values, 'create-instance-user-script', { const lines = script.split('\n').length;
name: 'user-script'
});
const proceeded = get( const proceeded = get(
values, values,
@ -109,6 +99,7 @@ export default compose(
return { return {
script, script,
lines,
proceeded: proceeded || script.value, proceeded: proceeded || script.value,
create: !script.value, create: !script.value,
edit: script.value, edit: script.value,
@ -116,17 +107,11 @@ export default compose(
}; };
}, },
(dispatch, { history }) => ({ (dispatch, { history }) => ({
handleNext: () => {
dispatch(
set({ name: 'create-instance-user-script-proceeded', value: true })
);
return history.push(`/~create/networks${history.location.search}`);
},
handleEdit: () => { handleEdit: () => {
dispatch( dispatch([
set({ name: 'create-instance-user-script-proceeded', value: true }) set({ name: 'create-instance-user-script-proceeded', value: true }),
); set({ name: `create-instance-user-script-open`, value: true })
]);
return history.push(`/~create/user-script${history.location.search}`); return history.push(`/~create/user-script${history.location.search}`);
}, },
@ -136,20 +121,12 @@ export default compose(
]); ]);
}, },
handleSubmit: value => { handleSubmit: value => {
return dispatch([ dispatch([
set({ name: `create-instance-user-script`, value: { ...value } }), set({ name: `create-instance-user-script-open`, value: false }),
set({ name: `create-instance-user-script-open`, value: false }) set({ name: 'create-instance-user-script-proceeded', value: true })
]);
},
handleRemove: () => {
return dispatch([
destroy(FORM_NAME),
set({
name: `create-instance-user-script`,
value: { name: 'user-script' }
}),
set({ name: `create-instance-user-script-open`, value: false })
]); ]);
return history.push(`/~create/networks${history.location.search}`);
} }
}) })
) )

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1776,6 +1776,7 @@ exports[`renders <Metadata addOpen /> without throwing 1`] = `
className="c30 c31" className="c30 c31"
disabled={false} disabled={false}
id="x" id="x"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -4516,6 +4517,7 @@ exports[`renders <Metadata metadata /> without throwing 1`] = `
className="c33 c34" className="c33 c34"
disabled={false} disabled={false}
id="C" id="C"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -4735,6 +4737,7 @@ exports[`renders <Metadata metadata /> without throwing 1`] = `
className="c33 c34" className="c33 c34"
disabled={false} disabled={false}
id="E" id="E"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>
@ -4954,6 +4957,7 @@ exports[`renders <Metadata metadata /> without throwing 1`] = `
className="c33 c34" className="c33 c34"
disabled={false} disabled={false}
id="G" id="G"
name="name"
onBlur={undefined} onBlur={undefined}
/> />
</div> </div>

View File

@ -1,4 +1,4 @@
import React, { PureComponent, Fragment } from 'react'; import React, { Fragment } from 'react';
import { Margin, Padding } from 'styled-components-spacing'; import { Margin, Padding } from 'styled-components-spacing';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withTheme } from 'styled-components'; import { withTheme } from 'styled-components';
@ -51,26 +51,6 @@ const Bold = styled.span`
font-weight: ${props => props.theme.font.weight.semibold}; font-weight: ${props => props.theme.font.weight.semibold};
`; `;
class ValueTextareaField extends PureComponent {
render() {
const { input = {}, submitting, editor } = this.props;
return input.value === 'user-script' ? (
<Field
name="value"
component={props =>
React.createElement(editor, {
...props,
mode: 'sh'
})
}
/>
) : (
<Textarea monospace resize="vertical" disabled={submitting} fluid />
);
}
}
const TextareaKeyValue = ({ const TextareaKeyValue = ({
type, type,
submitting, submitting,
@ -103,11 +83,12 @@ const TextareaKeyValue = ({
<FormGroup name="value" field={Field} fluid> <FormGroup name="value" field={Field} fluid>
<FormLabel>{titleCase(type)} value</FormLabel> <FormLabel>{titleCase(type)} value</FormLabel>
<Margin top={0.5}> <Margin top={0.5}>
<Field <Textarea
monospace
name="name" name="name"
resize="vertical"
disabled={submitting}
fluid fluid
component={ValueTextareaField}
props={{ submitting, editor }}
/> />
</Margin> </Margin>
<Row> <Row>
@ -182,7 +163,6 @@ export const KeyValue = ({
pristine = true, pristine = true,
invalid = false, invalid = false,
removing = false, removing = false,
handleSubmit,
onToggleExpanded = () => null, onToggleExpanded = () => null,
onCancel = () => null, onCancel = () => null,
onRemove = () => null, onRemove = () => null,

View File

@ -246,10 +246,10 @@ accept@3.x.x:
hoek "5.x.x" hoek "5.x.x"
accepts@~1.3.4: accepts@~1.3.4:
version "1.3.4" version "1.3.5"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
dependencies: dependencies:
mime-types "~2.1.16" mime-types "~2.1.18"
negotiator "0.6.1" negotiator "0.6.1"
acorn-dynamic-import@^2.0.0: acorn-dynamic-import@^2.0.0:
@ -1945,12 +1945,18 @@ boom@6.x.x:
dependencies: dependencies:
hoek "5.x.x" hoek "5.x.x"
boom@7.1.x, boom@7.x.x: boom@7.1.x:
version "7.1.1" version "7.1.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-7.1.1.tgz#50392a4e3417e971f1ad28622c20e832275260bb" resolved "https://registry.yarnpkg.com/boom/-/boom-7.1.1.tgz#50392a4e3417e971f1ad28622c20e832275260bb"
dependencies: dependencies:
hoek "5.x.x" hoek "5.x.x"
boom@7.x.x:
version "7.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-7.2.0.tgz#2bff24a55565767fde869ec808317eb10c48e966"
dependencies:
hoek "5.x.x"
bounce@1.2.x, bounce@1.x.x: bounce@1.2.x, bounce@1.x.x:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/bounce/-/bounce-1.2.0.tgz#e3bac68c73fd256e38096551efc09f504873c8c8" resolved "https://registry.yarnpkg.com/bounce/-/bounce-1.2.0.tgz#e3bac68c73fd256e38096551efc09f504873c8c8"
@ -2407,7 +2413,7 @@ checksum@^0.1.1:
dependencies: dependencies:
optimist "~0.3.5" optimist "~0.3.5"
chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0: chokidar@^1.6.0, chokidar@^1.6.1:
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies: dependencies:
@ -2422,7 +2428,7 @@ chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0:
optionalDependencies: optionalDependencies:
fsevents "^1.0.0" fsevents "^1.0.0"
chokidar@^2.0.0: chokidar@^2.0.0, chokidar@^2.0.2:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7"
dependencies: dependencies:
@ -2807,8 +2813,8 @@ content-type@1.0.4, content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
content@4.x.x: content@4.x.x:
version "4.0.3" version "4.0.4"
resolved "https://registry.yarnpkg.com/content/-/content-4.0.3.tgz#2224e0449e4258617bc5f7fb4dc2f17f321d21fc" resolved "https://registry.yarnpkg.com/content/-/content-4.0.4.tgz#2941609c89593ed2e1504d72c9a28e9516f163e0"
dependencies: dependencies:
boom "7.x.x" boom "7.x.x"
@ -5200,8 +5206,8 @@ hapi-triton-auth@^2.0.0:
wreck "14.0.x" wreck "14.0.x"
hapi@^17.2.0: hapi@^17.2.0:
version "17.2.0" version "17.2.1"
resolved "https://registry.yarnpkg.com/hapi/-/hapi-17.2.0.tgz#e5d74b65235b443225e05d7b7510cdb80d4887e7" resolved "https://registry.yarnpkg.com/hapi/-/hapi-17.2.1.tgz#177ca6b8d38b91509aea6ea63295cc726890f006"
dependencies: dependencies:
accept "3.x.x" accept "3.x.x"
ammo "3.x.x" ammo "3.x.x"
@ -7383,7 +7389,7 @@ mime-db@1.x.x, "mime-db@>= 1.33.0 < 2", mime-db@~1.33.0:
version "1.33.0" version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
mime-types@^2.1.12, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7:
version "2.1.18" version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
dependencies: dependencies:
@ -7582,6 +7588,10 @@ negotiator@0.6.1:
version "0.6.1" version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
neo-async@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f"
nigel@3.x.x: nigel@3.x.x:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/nigel/-/nigel-3.0.0.tgz#a6e3378a8a34281e75ba1641e886a415d4be93ad" resolved "https://registry.yarnpkg.com/nigel/-/nigel-3.0.0.tgz#a6e3378a8a34281e75ba1641e886a415d4be93ad"
@ -8687,10 +8697,14 @@ preserve@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
prettier@1.11.0, prettier@^1.11.0, prettier@^1.7.4: prettier@1.11.0:
version "1.11.0" version "1.11.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.0.tgz#c024f70cab158c993f50fc0c25ffe738cb8b0f85" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.0.tgz#c024f70cab158c993f50fc0c25ffe738cb8b0f85"
prettier@^1.11.0, prettier@^1.7.4:
version "1.11.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75"
pretty-bytes@^4.0.2: pretty-bytes@^4.0.2:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9"
@ -11740,12 +11754,12 @@ watch@~0.10.0:
resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc" resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc"
watchpack@^1.4.0: watchpack@^1.4.0:
version "1.4.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed"
dependencies: dependencies:
async "^2.1.2" chokidar "^2.0.2"
chokidar "^1.7.0"
graceful-fs "^4.1.2" graceful-fs "^4.1.2"
neo-async "^2.5.0"
wbuf@^1.1.0, wbuf@^1.7.2: wbuf@^1.1.0, wbuf@^1.7.2:
version "1.7.2" version "1.7.2"