Merge branch 'master' into keyboard-shortcuts-modal
This commit is contained in:
12
.babelrc
12
.babelrc
@@ -1,10 +1,8 @@
|
||||
{
|
||||
"presets": [
|
||||
"react",
|
||||
"env"
|
||||
],
|
||||
"presets": ["react", "env"],
|
||||
"plugins": [
|
||||
"lodash",
|
||||
"styled-components",
|
||||
"transform-decorators-legacy",
|
||||
"transform-es2015-destructuring",
|
||||
"transform-object-rest-spread",
|
||||
@@ -13,9 +11,7 @@
|
||||
],
|
||||
"env": {
|
||||
"development": {
|
||||
"presets": [
|
||||
"react-hmre"
|
||||
]
|
||||
"presets": ["react-hmre"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,111 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { observable } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import styled from 'styled-components';
|
||||
import Flex from 'components/Flex';
|
||||
import { color } from 'styles/constants';
|
||||
|
||||
import styles from './DropdownMenu.scss';
|
||||
|
||||
const MenuItem = ({
|
||||
onClick,
|
||||
children,
|
||||
}: {
|
||||
type MenuItemProps = {
|
||||
onClick?: Function,
|
||||
children?: React.Element<any>,
|
||||
}) => {
|
||||
};
|
||||
|
||||
const DropdownMenuItem = ({ onClick, children }: MenuItemProps) => {
|
||||
return (
|
||||
<div className={styles.menuItem} onClick={onClick}>
|
||||
<MenuItem onClick={onClick}>
|
||||
{children}
|
||||
</div>
|
||||
</MenuItem>
|
||||
);
|
||||
};
|
||||
|
||||
//
|
||||
type DropdownMenuProps = {
|
||||
label: React.Element<any>,
|
||||
children?: React.Element<any>,
|
||||
};
|
||||
|
||||
class DropdownMenu extends React.Component {
|
||||
static propTypes = {
|
||||
label: React.PropTypes.node.isRequired,
|
||||
children: React.PropTypes.node.isRequired,
|
||||
};
|
||||
@observer class DropdownMenu extends React.Component {
|
||||
props: DropdownMenuProps;
|
||||
@observable menuOpen: boolean = false;
|
||||
|
||||
state = {
|
||||
menuVisible: false,
|
||||
};
|
||||
|
||||
onMouseEnter = () => {
|
||||
this.setState({ menuVisible: true });
|
||||
};
|
||||
|
||||
onMouseLeave = () => {
|
||||
this.setState({ menuVisible: false });
|
||||
};
|
||||
|
||||
onClick = () => {
|
||||
this.setState({ menuVisible: !this.state.menuVisible });
|
||||
handleClick = () => {
|
||||
this.menuOpen = !this.menuOpen;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className={styles.menuContainer}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
>
|
||||
<div className={styles.label} onClick={this.onClick}>
|
||||
{this.props.label}
|
||||
</div>
|
||||
<MenuContainer onClick={this.handleClick}>
|
||||
{this.menuOpen && <Backdrop />}
|
||||
|
||||
{this.state.menuVisible
|
||||
? <div className={styles.menu}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
: null}
|
||||
</div>
|
||||
<Label>
|
||||
{this.props.label}
|
||||
</Label>
|
||||
|
||||
{this.menuOpen &&
|
||||
<Menu>
|
||||
{this.props.children}
|
||||
</Menu>}
|
||||
</MenuContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default DropdownMenu;
|
||||
export { MenuItem };
|
||||
const Backdrop = styled.div`
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
`;
|
||||
|
||||
const Label = styled(Flex).attrs({
|
||||
justify: 'center',
|
||||
align: 'center',
|
||||
})`
|
||||
cursor: pointer;
|
||||
z-index: 1000;
|
||||
|
||||
min-height: 43px;
|
||||
margin: 0 5px;
|
||||
`;
|
||||
|
||||
const MenuContainer = styled.div`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const Menu = styled.div`
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
min-width: 160px;
|
||||
`;
|
||||
|
||||
const MenuItem = styled.div`
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
height: 32px;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-left: 2px solid transparent;
|
||||
|
||||
span {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-left: 2px solid ${color.primary};
|
||||
}
|
||||
`;
|
||||
|
||||
export { DropdownMenu, DropdownMenuItem };
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
@import '~styles/constants.scss';
|
||||
|
||||
.label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
min-height: 43px;
|
||||
margin: 0 5px;
|
||||
color: $actionColor;
|
||||
}
|
||||
|
||||
.menuContainer {
|
||||
position: relative;
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
top: $headerHeight;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
min-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
height: 32px;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-left: 2px solid transparent;
|
||||
|
||||
span {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $textColor;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-left: 2px solid $actionColor;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
// @flow
|
||||
import DropdownMenu, { MenuItem } from './DropdownMenu';
|
||||
import { DropdownMenu, DropdownMenuItem } from './DropdownMenu';
|
||||
import MoreIcon from './components/MoreIcon';
|
||||
export default DropdownMenu;
|
||||
export { MenuItem, MoreIcon };
|
||||
export { DropdownMenu, DropdownMenuItem, MoreIcon };
|
||||
|
||||
@@ -89,11 +89,12 @@ type KeyData = {
|
||||
case 's':
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
return this.props.onSave({ redirect: false });
|
||||
this.props.onSave();
|
||||
return state;
|
||||
case 'enter':
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.props.onSave();
|
||||
this.props.onSave({ redirect: false });
|
||||
return state;
|
||||
case 'escape':
|
||||
return this.props.onCancel();
|
||||
|
||||
21
frontend/components/Icon/CheckIcon.js
Normal file
21
frontend/components/Icon/CheckIcon.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import Icon from './Icon';
|
||||
import type { Props } from './Icon';
|
||||
|
||||
export default function CheckIcon(props: Props) {
|
||||
return (
|
||||
<Icon {...props}>
|
||||
<svg
|
||||
fill="#000000"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
||||
</svg>
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import keydown from 'react-keydown';
|
||||
import Flex from 'components/Flex';
|
||||
import { color, layout } from 'styles/constants';
|
||||
|
||||
import DropdownMenu, { MenuItem } from 'components/DropdownMenu';
|
||||
import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
|
||||
import { LoadingIndicatorBar } from 'components/LoadingIndicator';
|
||||
import Scrollable from 'components/Scrollable';
|
||||
import KeyboardShortcuts from 'components/KeyboardShortcuts';
|
||||
@@ -107,15 +107,17 @@ type Props = {
|
||||
</Flex>
|
||||
<DropdownMenu label={<Avatar src={user.user.avatarUrl} />}>
|
||||
<MenuLink to="/settings">
|
||||
<MenuItem>Settings</MenuItem>
|
||||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||||
</MenuLink>
|
||||
<MenuItem onClick={this.handleOpenKeyboardShortcuts}>
|
||||
Keyboard shortcuts
|
||||
</MenuItem>
|
||||
<MenuLink to="/developers">
|
||||
<MenuItem>API</MenuItem>
|
||||
<DropdownMenuItem>API</DropdownMenuItem>
|
||||
</MenuLink>
|
||||
<MenuItem onClick={this.handleLogout}>Logout</MenuItem>
|
||||
<DropdownMenuItem onClick={this.handleLogout}>
|
||||
Logout
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenu>
|
||||
</Header>
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import styled from 'styled-components';
|
||||
import CheckIcon from 'components/Icon/CheckIcon';
|
||||
import { fadeAndScaleIn } from 'styles/animations';
|
||||
|
||||
type Props = {
|
||||
onClick: Function,
|
||||
showCheckmark: boolean,
|
||||
disabled?: boolean,
|
||||
isNew?: boolean,
|
||||
};
|
||||
|
||||
@observer class SaveAction extends React.Component {
|
||||
class SaveAction extends React.Component {
|
||||
props: Props;
|
||||
|
||||
onClick = (event: MouseEvent) => {
|
||||
@@ -19,21 +22,38 @@ type Props = {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { disabled, isNew } = this.props;
|
||||
const { showCheckmark, disabled, isNew } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<a
|
||||
href
|
||||
onClick={this.onClick}
|
||||
style={{ opacity: disabled ? 0.5 : 1 }}
|
||||
title="Save changes (Cmd+Enter)"
|
||||
>
|
||||
{isNew ? 'Publish' : 'Save'}
|
||||
</a>
|
||||
</div>
|
||||
<Link
|
||||
href
|
||||
onClick={this.onClick}
|
||||
style={{ opacity: disabled ? 0.5 : 1 }}
|
||||
title="Save changes (Cmd+Enter)"
|
||||
>
|
||||
{showCheckmark && <SavedIcon />}
|
||||
{isNew ? 'Publish' : 'Save'}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const Link = styled.a`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const SavedIcon = styled(CheckIcon)`
|
||||
animation: ${fadeAndScaleIn} 250ms ease;
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default SaveAction;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import ReactModal from 'react-modal';
|
||||
import { modalFadeIn } from 'styles/animations';
|
||||
import { fadeAndScaleIn } from 'styles/animations';
|
||||
|
||||
import CloseIcon from 'components/Icon/CloseIcon';
|
||||
import Flex from 'components/Flex';
|
||||
@@ -46,7 +46,7 @@ const Content = styled(Flex)`
|
||||
`;
|
||||
|
||||
const StyledModal = styled(ReactModal)`
|
||||
animation: ${modalFadeIn} 250ms ease;
|
||||
animation: ${fadeAndScaleIn} 250ms ease;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ type Props = {
|
||||
|
||||
@observer class DocumentScene extends Component {
|
||||
props: Props;
|
||||
savedTimeout: number;
|
||||
state: {
|
||||
newDocument?: Document,
|
||||
};
|
||||
@@ -44,6 +45,7 @@ type Props = {
|
||||
isDragging: false,
|
||||
isLoading: false,
|
||||
newDocument: undefined,
|
||||
showAsSaved: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@@ -60,6 +62,7 @@ type Props = {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.savedTimeout);
|
||||
this.props.ui.clearActiveDocument();
|
||||
}
|
||||
|
||||
@@ -108,9 +111,19 @@ type Props = {
|
||||
|
||||
if (redirect || this.props.newDocument) {
|
||||
this.props.history.push(document.url);
|
||||
} else {
|
||||
this.showAsSaved();
|
||||
}
|
||||
};
|
||||
|
||||
showAsSaved() {
|
||||
this.setState({ showAsSaved: true });
|
||||
this.savedTimeout = setTimeout(
|
||||
() => this.setState({ showAsSaved: false }),
|
||||
2000
|
||||
);
|
||||
}
|
||||
|
||||
onImageUploadStart() {
|
||||
this.setState({ isLoading: true });
|
||||
}
|
||||
@@ -204,6 +217,7 @@ type Props = {
|
||||
<HeaderAction>
|
||||
{isEditing
|
||||
? <SaveAction
|
||||
showCheckmark={this.state.showAsSaved}
|
||||
onClick={this.onSave.bind(this, true)}
|
||||
disabled={get(this.document, 'isSaving')}
|
||||
isNew={!!isNew}
|
||||
|
||||
@@ -5,7 +5,11 @@ import get from 'lodash/get';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { observer } from 'mobx-react';
|
||||
import Document from 'models/Document';
|
||||
import DropdownMenu, { MenuItem, MoreIcon } from 'components/DropdownMenu';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuItem,
|
||||
MoreIcon,
|
||||
} from 'components/DropdownMenu';
|
||||
|
||||
type Props = {
|
||||
history: Object,
|
||||
@@ -63,12 +67,13 @@ type Props = {
|
||||
<DropdownMenu label={<MoreIcon />}>
|
||||
{collection &&
|
||||
<div>
|
||||
<MenuItem onClick={this.onCreateDocument}>
|
||||
<DropdownMenuItem onClick={this.onCreateDocument}>
|
||||
New document
|
||||
</MenuItem>
|
||||
</DropdownMenuItem>
|
||||
</div>}
|
||||
<MenuItem onClick={this.onExport}>Export</MenuItem>
|
||||
{allowDelete && <MenuItem onClick={this.onDelete}>Delete</MenuItem>}
|
||||
<DropdownMenuItem onClick={this.onExport}>Export</DropdownMenuItem>
|
||||
{allowDelete &&
|
||||
<DropdownMenuItem onClick={this.onDelete}>Delete</DropdownMenuItem>}
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import { searchUrl } from 'utils/routeHelpers';
|
||||
import styled from 'styled-components';
|
||||
import ArrowKeyNavigation from 'boundless-arrow-key-navigation';
|
||||
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import SearchField from './components/SearchField';
|
||||
import SearchStore from './SearchStore';
|
||||
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import DocumentPreview from 'components/DocumentPreview';
|
||||
import PageTitle from 'components/PageTitle';
|
||||
|
||||
@@ -23,7 +23,9 @@ type Props = {
|
||||
};
|
||||
|
||||
const Container = styled(CenteredContent)`
|
||||
position: relative;
|
||||
> div {
|
||||
position: relative;
|
||||
}
|
||||
`;
|
||||
|
||||
const ResultsWrapper = styled(Flex)`
|
||||
@@ -39,6 +41,12 @@ const ResultList = styled(Flex)`
|
||||
transition: all 400ms cubic-bezier(0.65, 0.05, 0.36, 1);
|
||||
`;
|
||||
|
||||
const StyledArrowKeyNavigation = styled(ArrowKeyNavigation)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
`;
|
||||
|
||||
@observer class Search extends React.Component {
|
||||
firstDocument: HTMLElement;
|
||||
props: Props;
|
||||
@@ -106,7 +114,7 @@ const ResultList = styled(Flex)`
|
||||
value={query || ''}
|
||||
/>
|
||||
<ResultList visible={hasResults}>
|
||||
<ArrowKeyNavigation
|
||||
<StyledArrowKeyNavigation
|
||||
mode={ArrowKeyNavigation.mode.VERTICAL}
|
||||
defaultActiveChildIndex={0}
|
||||
>
|
||||
@@ -118,7 +126,7 @@ const ResultList = styled(Flex)`
|
||||
highlight={this.store.searchTerm}
|
||||
/>
|
||||
))}
|
||||
</ArrowKeyNavigation>
|
||||
</StyledArrowKeyNavigation>
|
||||
</ResultList>
|
||||
</ResultsWrapper>
|
||||
</Container>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @flow
|
||||
import { keyframes } from 'styled-components';
|
||||
|
||||
export const modalFadeIn = keyframes`
|
||||
export const fadeAndScaleIn = keyframes`
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(.98);
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-loader": "6.2.5",
|
||||
"babel-plugin-lodash": "^3.2.11",
|
||||
"babel-plugin-styled-components": "^1.1.7",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-decorators-legacy": "1.3.4",
|
||||
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
|
||||
|
||||
@@ -9,6 +9,15 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#documents.search should require authentication 1`] = `
|
||||
Object {
|
||||
"error": "authentication_required",
|
||||
"message": "Authentication required",
|
||||
"ok": false,
|
||||
"status": 401,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`#documents.star should require authentication 1`] = `
|
||||
Object {
|
||||
"error": "authentication_required",
|
||||
|
||||
@@ -41,6 +41,28 @@ describe('#documents.list', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#documents.search', async () => {
|
||||
it('should return results', async () => {
|
||||
const { user } = await seed();
|
||||
const res = await server.post('/api/documents.search', {
|
||||
body: { token: user.getJwtToken(), query: 'much' },
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.length).toEqual(1);
|
||||
expect(body.data[0].text).toEqual('# Much guidance');
|
||||
});
|
||||
|
||||
it('should require authentication', async () => {
|
||||
const res = await server.post('/api/documents.search');
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(401);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#documents.viewed', async () => {
|
||||
it('should return empty result if no views', async () => {
|
||||
const { user } = await seed();
|
||||
|
||||
@@ -156,7 +156,7 @@ const Document = sequelize.define(
|
||||
});
|
||||
}
|
||||
},
|
||||
searchForUser: (user, query, options = {}) => {
|
||||
searchForUser: async (user, query, options = {}) => {
|
||||
const limit = options.limit || 15;
|
||||
const offset = options.offset || 0;
|
||||
|
||||
@@ -169,13 +169,18 @@ const Document = sequelize.define(
|
||||
LIMIT :limit OFFSET :offset;
|
||||
`;
|
||||
|
||||
return sequelize.query(sql, {
|
||||
replacements: {
|
||||
query,
|
||||
limit,
|
||||
offset,
|
||||
},
|
||||
model: Document,
|
||||
const ids = await sequelize
|
||||
.query(sql, {
|
||||
replacements: {
|
||||
query,
|
||||
limit,
|
||||
offset,
|
||||
},
|
||||
model: Document,
|
||||
})
|
||||
.map(document => document.id);
|
||||
return Document.findAll({
|
||||
where: { id: ids },
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
12
yarn.lock
12
yarn.lock
@@ -534,6 +534,12 @@ babel-plugin-react-transform@^2.0.2:
|
||||
dependencies:
|
||||
lodash "^4.6.1"
|
||||
|
||||
babel-plugin-styled-components@^1.1.7:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.1.7.tgz#a92c239779cc80e7838b645c12865c61c4ca71ce"
|
||||
dependencies:
|
||||
stylis "^3.2.1"
|
||||
|
||||
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"
|
||||
@@ -8259,6 +8265,10 @@ stylis@^2.0.0:
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-2.0.12.tgz#547253055d170f2a7ac2f6d09365d70635f2bec6"
|
||||
|
||||
stylis@^3.2.1:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.2.3.tgz#fed751d792af3f48a247769f55aca05c1a100a09"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
@@ -8913,7 +8923,7 @@ whatwg-encoding@^1.0.1:
|
||||
dependencies:
|
||||
iconv-lite "0.4.13"
|
||||
|
||||
whatwg-fetch@1.0.0, whatwg-fetch@>=0.10.0:
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-1.0.0.tgz#01c2ac4df40e236aaa18480e3be74bd5c8eb798e"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user