mirror of
https://github.com/outline/outline.git
synced 2026-06-13 19:35:02 +03:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ffcd020cc6 | |||
| 2e12e28b8c | |||
| c0db3ea02a | |||
| 0bb9fb8fff | |||
| 8cb4a06595 | |||
| 08c71690c2 | |||
| 179176c312 | |||
| c446a91f7d | |||
| ec55299c8b | |||
| 26c574ab58 | |||
| 6dd6768f07 |
@@ -3,7 +3,7 @@ jobs:
|
||||
build:
|
||||
working_directory: ~/outline
|
||||
docker:
|
||||
- image: circleci/node:12
|
||||
- image: circleci/node:14
|
||||
- image: circleci/redis:latest
|
||||
- image: circleci/postgres:9.6.5-alpine-ram
|
||||
environment:
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"react-app",
|
||||
"plugin:import/errors",
|
||||
"plugin:import/warnings",
|
||||
"plugin:flowtype/recommended"
|
||||
"plugin:flowtype/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"plugins": [
|
||||
"prettier",
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function DelayedMount({ delay = 250, children }: Props) {
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}, []);
|
||||
}, [delay]);
|
||||
|
||||
if (!isShowing) {
|
||||
return null;
|
||||
|
||||
@@ -20,12 +20,7 @@ type Props = {
|
||||
onClose: () => void,
|
||||
};
|
||||
|
||||
function HoverPreview({ node, documents, onClose, event }: Props) {
|
||||
// previews only work for internal doc links for now
|
||||
if (!isInternalUrl(node.href)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function HoverPreviewInternal({ node, documents, onClose, event }: Props) {
|
||||
const slug = parseDocumentSlugFromUrl(node.href);
|
||||
|
||||
const [isVisible, setVisible] = React.useState(false);
|
||||
@@ -131,6 +126,15 @@ function HoverPreview({ node, documents, onClose, event }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
function HoverPreview({ node, ...rest }: Props) {
|
||||
// previews only work for internal doc links for now
|
||||
if (!isInternalUrl(node.href)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <HoverPreviewInternal {...rest} node={node} />;
|
||||
}
|
||||
|
||||
const Animate = styled.div`
|
||||
animation: ${fadeAndSlideIn} 150ms ease;
|
||||
|
||||
|
||||
@@ -44,21 +44,22 @@ class Layout extends React.Component<Props> {
|
||||
@observable redirectTo: ?string;
|
||||
@observable keyboardShortcutsOpen: boolean = false;
|
||||
|
||||
componentWillMount() {
|
||||
this.updateBackground();
|
||||
constructor(props) {
|
||||
super();
|
||||
this.updateBackground(props);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.updateBackground();
|
||||
this.updateBackground(this.props);
|
||||
|
||||
if (this.redirectTo) {
|
||||
this.redirectTo = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
updateBackground() {
|
||||
updateBackground(props) {
|
||||
// ensure the wider page color always matches the theme
|
||||
window.document.body.style.background = this.props.theme.background;
|
||||
window.document.body.style.background = props.theme.background;
|
||||
}
|
||||
|
||||
@keydown("shift+/")
|
||||
|
||||
@@ -17,7 +17,8 @@ class Mask extends React.Component<Props> {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
constructor() {
|
||||
super();
|
||||
this.width = randomInteger(75, 100);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ const Title = styled.span`
|
||||
`;
|
||||
|
||||
const StyledGoToIcon = styled(GoToIcon)`
|
||||
opacity: 0.25;
|
||||
fill: ${(props) => props.theme.divider};
|
||||
`;
|
||||
|
||||
const ResultWrapper = styled.div`
|
||||
|
||||
@@ -1,65 +1,60 @@
|
||||
// @flow
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
import { CloseIcon, MenuIcon } from "outline-icons";
|
||||
import * as React from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import type { Location } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import breakpoint from "styled-components-breakpoint";
|
||||
import UiStore from "stores/UiStore";
|
||||
import Fade from "components/Fade";
|
||||
import Flex from "components/Flex";
|
||||
import usePrevious from "hooks/usePrevious";
|
||||
import useStores from "hooks/useStores";
|
||||
|
||||
let firstRender = true;
|
||||
|
||||
type Props = {
|
||||
children: React.Node,
|
||||
location: Location,
|
||||
ui: UiStore,
|
||||
};
|
||||
|
||||
@observer
|
||||
class Sidebar extends React.Component<Props> {
|
||||
componentWillReceiveProps = (nextProps: Props) => {
|
||||
if (this.props.location !== nextProps.location) {
|
||||
this.props.ui.hideMobileSidebar();
|
||||
function Sidebar({ location, children }: Props) {
|
||||
const { ui } = useStores();
|
||||
const previousLocation = usePrevious(location);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (location !== previousLocation) {
|
||||
ui.hideMobileSidebar();
|
||||
}
|
||||
};
|
||||
}, [ui, location]);
|
||||
|
||||
toggleSidebar = () => {
|
||||
this.props.ui.toggleMobileSidebar();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { children, ui } = this.props;
|
||||
const content = (
|
||||
<Container
|
||||
editMode={ui.editMode}
|
||||
const content = (
|
||||
<Container
|
||||
editMode={ui.editMode}
|
||||
mobileSidebarVisible={ui.mobileSidebarVisible}
|
||||
column
|
||||
>
|
||||
<Toggle
|
||||
onClick={ui.toggleMobileSidebar}
|
||||
mobileSidebarVisible={ui.mobileSidebarVisible}
|
||||
column
|
||||
>
|
||||
<Toggle
|
||||
onClick={this.toggleSidebar}
|
||||
mobileSidebarVisible={ui.mobileSidebarVisible}
|
||||
>
|
||||
{ui.mobileSidebarVisible ? (
|
||||
<CloseIcon size={32} />
|
||||
) : (
|
||||
<MenuIcon size={32} />
|
||||
)}
|
||||
</Toggle>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
{ui.mobileSidebarVisible ? (
|
||||
<CloseIcon size={32} />
|
||||
) : (
|
||||
<MenuIcon size={32} />
|
||||
)}
|
||||
</Toggle>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
||||
// Fade in the sidebar on first render after page load
|
||||
if (firstRender) {
|
||||
firstRender = false;
|
||||
return <Fade>{content}</Fade>;
|
||||
}
|
||||
|
||||
return content;
|
||||
// Fade in the sidebar on first render after page load
|
||||
if (firstRender) {
|
||||
firstRender = false;
|
||||
return <Fade>{content}</Fade>;
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
const Container = styled(Flex)`
|
||||
@@ -117,4 +112,4 @@ const Toggle = styled.a`
|
||||
`};
|
||||
`;
|
||||
|
||||
export default withRouter(inject("ui")(Sidebar));
|
||||
export default withRouter(observer(Sidebar));
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// @flow
|
||||
import { observable, action } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { CollapsedIcon } from "outline-icons";
|
||||
import * as React from "react";
|
||||
@@ -25,79 +24,80 @@ type Props = {
|
||||
depth?: number,
|
||||
};
|
||||
|
||||
@observer
|
||||
class SidebarLink extends React.Component<Props> {
|
||||
@observable expanded: ?boolean = this.props.expanded;
|
||||
function SidebarLink({
|
||||
icon,
|
||||
children,
|
||||
onClick,
|
||||
to,
|
||||
label,
|
||||
active,
|
||||
menu,
|
||||
menuOpen,
|
||||
hideDisclosure,
|
||||
theme,
|
||||
exact,
|
||||
href,
|
||||
depth,
|
||||
...rest
|
||||
}: Props) {
|
||||
const [expanded, setExpanded] = React.useState(rest.expanded);
|
||||
|
||||
style = {
|
||||
paddingLeft: `${(this.props.depth || 0) * 16 + 16}px`,
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
if (nextProps.expanded !== undefined) {
|
||||
this.expanded = nextProps.expanded;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
handleClick = (ev: SyntheticEvent<>) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
this.expanded = !this.expanded;
|
||||
};
|
||||
|
||||
@action
|
||||
handleExpand = () => {
|
||||
this.expanded = true;
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
icon,
|
||||
children,
|
||||
onClick,
|
||||
to,
|
||||
label,
|
||||
active,
|
||||
menu,
|
||||
menuOpen,
|
||||
hideDisclosure,
|
||||
exact,
|
||||
href,
|
||||
} = this.props;
|
||||
const showDisclosure = !!children && !hideDisclosure;
|
||||
const activeStyle = {
|
||||
color: this.props.theme.text,
|
||||
background: this.props.theme.sidebarItemBackground,
|
||||
fontWeight: 600,
|
||||
...this.style,
|
||||
const style = React.useMemo(() => {
|
||||
return {
|
||||
paddingLeft: `${(depth || 0) * 16 + 16}px`,
|
||||
};
|
||||
}, [depth]);
|
||||
|
||||
return (
|
||||
<Wrapper column>
|
||||
<StyledNavLink
|
||||
activeStyle={activeStyle}
|
||||
style={active ? activeStyle : this.style}
|
||||
onClick={onClick}
|
||||
exact={exact !== false}
|
||||
to={to}
|
||||
as={to ? undefined : href ? "a" : "div"}
|
||||
href={href}
|
||||
>
|
||||
{icon && <IconWrapper>{icon}</IconWrapper>}
|
||||
<Label onClick={this.handleExpand}>
|
||||
{showDisclosure && (
|
||||
<Disclosure expanded={this.expanded} onClick={this.handleClick} />
|
||||
)}
|
||||
{label}
|
||||
</Label>
|
||||
{menu && <Action menuOpen={menuOpen}>{menu}</Action>}
|
||||
</StyledNavLink>
|
||||
{this.expanded && children}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
React.useEffect(() => {
|
||||
if (rest.expanded) {
|
||||
setExpanded(rest.expanded);
|
||||
}
|
||||
}, [rest.expanded]);
|
||||
|
||||
const handleClick = React.useCallback(
|
||||
(ev: SyntheticEvent<>) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
setExpanded(!expanded);
|
||||
},
|
||||
[expanded]
|
||||
);
|
||||
|
||||
const handleExpand = React.useCallback(() => {
|
||||
setExpanded(true);
|
||||
}, []);
|
||||
|
||||
const showDisclosure = !!children && !hideDisclosure;
|
||||
const activeStyle = {
|
||||
color: theme.text,
|
||||
background: theme.sidebarItemBackground,
|
||||
fontWeight: 600,
|
||||
...style,
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper column>
|
||||
<StyledNavLink
|
||||
activeStyle={activeStyle}
|
||||
style={active ? activeStyle : style}
|
||||
onClick={onClick}
|
||||
exact={exact !== false}
|
||||
to={to}
|
||||
as={to ? undefined : href ? "a" : "div"}
|
||||
href={href}
|
||||
>
|
||||
{icon && <IconWrapper>{icon}</IconWrapper>}
|
||||
<Label onClick={handleExpand}>
|
||||
{showDisclosure && (
|
||||
<Disclosure expanded={expanded} onClick={handleClick} />
|
||||
)}
|
||||
{label}
|
||||
</Label>
|
||||
{menu && <Action menuOpen={menuOpen}>{menu}</Action>}
|
||||
</StyledNavLink>
|
||||
{expanded && children}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
// accounts for whitespace around icon
|
||||
@@ -171,4 +171,4 @@ const Disclosure = styled(CollapsedIcon)`
|
||||
${({ expanded }) => !expanded && "transform: rotate(-90deg);"};
|
||||
`;
|
||||
|
||||
export default withRouter(withTheme(SidebarLink));
|
||||
export default withRouter(withTheme(observer(SidebarLink)));
|
||||
|
||||
@@ -3,7 +3,7 @@ import { find } from "lodash";
|
||||
import { observable } from "mobx";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import io from "socket.io-client";
|
||||
import io, { Socket } from "socket.io-client";
|
||||
import AuthStore from "stores/AuthStore";
|
||||
import CollectionsStore from "stores/CollectionsStore";
|
||||
import DocumentPresenceStore from "stores/DocumentPresenceStore";
|
||||
@@ -13,6 +13,7 @@ import MembershipsStore from "stores/MembershipsStore";
|
||||
import PoliciesStore from "stores/PoliciesStore";
|
||||
import UiStore from "stores/UiStore";
|
||||
import ViewsStore from "stores/ViewsStore";
|
||||
import { getVisibilityListener, getPageVisible } from "utils/pageVisibility";
|
||||
|
||||
export const SocketContext: any = React.createContext();
|
||||
|
||||
@@ -31,9 +32,35 @@ type Props = {
|
||||
|
||||
@observer
|
||||
class SocketProvider extends React.Component<Props> {
|
||||
@observable socket;
|
||||
@observable socket: Socket;
|
||||
|
||||
componentDidMount() {
|
||||
this.createConnection();
|
||||
|
||||
document.addEventListener(getVisibilityListener(), this.checkConnection);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.socket) {
|
||||
this.socket.authenticated = false;
|
||||
this.socket.disconnect();
|
||||
}
|
||||
|
||||
document.removeEventListener(getVisibilityListener(), this.checkConnection);
|
||||
}
|
||||
|
||||
checkConnection = () => {
|
||||
if (this.socket && this.socket.disconnected && getPageVisible()) {
|
||||
// null-ifying this reference is important, do not remove. Without it
|
||||
// references to old sockets are potentially held in context
|
||||
this.socket.close();
|
||||
this.socket = null;
|
||||
|
||||
this.createConnection();
|
||||
}
|
||||
};
|
||||
|
||||
createConnection = () => {
|
||||
this.socket = io(window.location.origin, {
|
||||
path: "/realtime",
|
||||
transports: ["websocket"],
|
||||
@@ -264,14 +291,7 @@ class SocketProvider extends React.Component<Props> {
|
||||
this.socket.on("user.presence", (event) => {
|
||||
presence.touch(event.documentId, event.userId, event.isEditing);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.socket) {
|
||||
this.socket.disconnect();
|
||||
this.socket.authenticated = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// @flow
|
||||
import * as React from "react";
|
||||
|
||||
export default function usePrevious(value: any) {
|
||||
const ref = React.useRef();
|
||||
React.useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// @flow
|
||||
import { MobXProviderContext } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import RootStore from "stores";
|
||||
|
||||
export default function useStores(): typeof RootStore {
|
||||
return React.useContext(MobXProviderContext);
|
||||
}
|
||||
+14
-22
@@ -12,32 +12,24 @@ import Toasts from "components/Toasts";
|
||||
import Routes from "./routes";
|
||||
import env from "env";
|
||||
|
||||
let DevTools;
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
DevTools = require("mobx-react-devtools").default; // eslint-disable-line global-require
|
||||
}
|
||||
|
||||
const element = document.getElementById("root");
|
||||
|
||||
if (element) {
|
||||
render(
|
||||
<>
|
||||
<ErrorBoundary>
|
||||
<Provider {...stores}>
|
||||
<Theme>
|
||||
<Router>
|
||||
<>
|
||||
<ScrollToTop>
|
||||
<Routes />
|
||||
</ScrollToTop>
|
||||
<Toasts />
|
||||
</>
|
||||
</Router>
|
||||
</Theme>
|
||||
</Provider>
|
||||
</ErrorBoundary>
|
||||
{DevTools && <DevTools position={{ bottom: 0, right: 0 }} />}
|
||||
</>,
|
||||
<ErrorBoundary>
|
||||
<Provider {...stores}>
|
||||
<Theme>
|
||||
<Router>
|
||||
<>
|
||||
<ScrollToTop>
|
||||
<Routes />
|
||||
</ScrollToTop>
|
||||
<Toasts />
|
||||
</>
|
||||
</Router>
|
||||
</Theme>
|
||||
</Provider>
|
||||
</ErrorBoundary>,
|
||||
element
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ class CollectionScene extends React.Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { id } = nextProps.match.params;
|
||||
componentDidUpdate(prevProps) {
|
||||
const { id } = this.props.match.params;
|
||||
|
||||
if (id && id !== this.props.match.params.id) {
|
||||
if (id && id !== prevProps.match.params.id) {
|
||||
this.loadContent(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ class DocumentScene extends React.Component<Props> {
|
||||
ev.preventDefault();
|
||||
const { document, abilities } = this.props;
|
||||
|
||||
if (abilities.update) {
|
||||
if (abilities.move) {
|
||||
this.props.history.push(documentMoveUrl(document));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ class DocumentMove extends React.Component<Props> {
|
||||
@computed
|
||||
get results(): DocumentPath[] {
|
||||
const { document, collections } = this.props;
|
||||
const onlyShowCollections = document.isTemplate;
|
||||
|
||||
let results = [];
|
||||
if (collections.isLoaded) {
|
||||
@@ -62,17 +63,23 @@ class DocumentMove extends React.Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude root from search results if document is already at the root
|
||||
if (!document.parentDocumentId) {
|
||||
results = results.filter((result) => result.id !== document.collectionId);
|
||||
}
|
||||
if (onlyShowCollections) {
|
||||
results = results.filter((result) => result.type === "collection");
|
||||
} else {
|
||||
// Exclude root from search results if document is already at the root
|
||||
if (!document.parentDocumentId) {
|
||||
results = results.filter(
|
||||
(result) => result.id !== document.collectionId
|
||||
);
|
||||
}
|
||||
|
||||
// Exclude document if on the path to result, or the same result
|
||||
results = results.filter(
|
||||
(result) =>
|
||||
!result.path.map((doc) => doc.id).includes(document.id) &&
|
||||
last(result.path.map((doc) => doc.id)) !== document.parentDocumentId
|
||||
);
|
||||
// Exclude document if on the path to result, or the same result
|
||||
results = results.filter(
|
||||
(result) =>
|
||||
!result.path.map((doc) => doc.id).includes(document.id) &&
|
||||
last(result.path.map((doc) => doc.id)) !== document.parentDocumentId
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export default class SocketPresence extends React.Component<Props> {
|
||||
}
|
||||
|
||||
setupOnce = () => {
|
||||
if (this.context && !this.previousContext) {
|
||||
if (this.context && this.context !== this.previousContext) {
|
||||
this.previousContext = this.context;
|
||||
|
||||
if (this.context.authenticated) {
|
||||
|
||||
+12
-12
@@ -109,34 +109,34 @@ class UiStore {
|
||||
};
|
||||
|
||||
@action
|
||||
enableEditMode() {
|
||||
enableEditMode = () => {
|
||||
this.editMode = true;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
disableEditMode() {
|
||||
disableEditMode = () => {
|
||||
this.editMode = false;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
enableProgressBar() {
|
||||
enableProgressBar = () => {
|
||||
this.progressBarVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
disableProgressBar() {
|
||||
disableProgressBar = () => {
|
||||
this.progressBarVisible = false;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
toggleMobileSidebar() {
|
||||
toggleMobileSidebar = () => {
|
||||
this.mobileSidebarVisible = !this.mobileSidebarVisible;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
hideMobileSidebar() {
|
||||
hideMobileSidebar = () => {
|
||||
this.mobileSidebarVisible = false;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
showToast = (
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// @flow
|
||||
let hidden = "hidden";
|
||||
let visibilityChange = "visibilitychange";
|
||||
|
||||
if ("hidden" in document) {
|
||||
hidden = "hidden";
|
||||
visibilityChange = "visibilitychange";
|
||||
} else if ("mozHidden" in document) {
|
||||
// Firefox up to v17
|
||||
hidden = "mozHidden";
|
||||
visibilityChange = "mozvisibilitychange";
|
||||
} else if ("webkitHidden" in document) {
|
||||
// Chrome up to v32, Android up to v4.4, Blackberry up to v10
|
||||
hidden = "webkitHidden";
|
||||
visibilityChange = "webkitvisibilitychange";
|
||||
}
|
||||
|
||||
export function getVisibilityListener(): string {
|
||||
return visibilityChange;
|
||||
}
|
||||
|
||||
export function getPageVisible(): boolean {
|
||||
// $FlowFixMe
|
||||
return !document[hidden];
|
||||
}
|
||||
+12
-12
@@ -6,16 +6,16 @@
|
||||
"clean": "rimraf dist",
|
||||
"build:webpack": "NODE_ENV=production webpack --config webpack.config.prod.js",
|
||||
"build:analyze": "NODE_ENV=production webpack --config webpack.config.prod.js --json > stats.json",
|
||||
"build": "npm run clean && npm run build:webpack",
|
||||
"build": "yarn clean && yarn build:webpack",
|
||||
"start": "NODE_ENV=production node index.js",
|
||||
"dev": "NODE_ENV=development nodemon --watch server index.js",
|
||||
"lint": "eslint app server shared",
|
||||
"flow": "flow",
|
||||
"deploy": "git push heroku master",
|
||||
"heroku-postbuild": "npm run build && npm run sequelize:migrate",
|
||||
"heroku-postbuild": "yarn build && yarn sequelize:migrate",
|
||||
"sequelize:create-migration": "sequelize migration:create",
|
||||
"sequelize:migrate": "sequelize db:migrate",
|
||||
"test": "npm run test:app && npm run test:server",
|
||||
"test": "yarn test:app && yarn test:server",
|
||||
"test:app": "jest",
|
||||
"test:server": "jest --config=server/.jestconfig.json --runInBand --forceExit",
|
||||
"test:watch": "jest --config=server/.jestconfig.json --runInBand --forceExit --watchAll"
|
||||
@@ -48,7 +48,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12 <14"
|
||||
"node": ">= 12 <15"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -115,13 +115,13 @@
|
||||
"koa-static": "^4.0.1",
|
||||
"lodash": "^4.17.19",
|
||||
"mobx": "4.6.0",
|
||||
"mobx-react": "^5.4.2",
|
||||
"mobx-react": "^6.2.5",
|
||||
"natural-sort": "^1.0.0",
|
||||
"nodemailer": "^4.4.0",
|
||||
"outline-icons": "^1.21.0-6",
|
||||
"oy-vey": "^0.10.0",
|
||||
"pg": "^6.1.5",
|
||||
"pg-hstore": "2.3.2",
|
||||
"pg": "^8.3.0",
|
||||
"pg-hstore": "^2.3.3",
|
||||
"polished": "3.6.5",
|
||||
"query-string": "^4.3.4",
|
||||
"randomstring": "1.1.5",
|
||||
@@ -140,9 +140,9 @@
|
||||
"react-waypoint": "^9.0.2",
|
||||
"rich-markdown-editor": "^10.6.1",
|
||||
"semver": "^7.3.2",
|
||||
"sequelize": "^5.21.1",
|
||||
"sequelize-cli": "^5.5.0",
|
||||
"sequelize-encrypted": "^0.1.0",
|
||||
"sequelize": "^6.3.4",
|
||||
"sequelize-cli": "^6.2.0",
|
||||
"sequelize-encrypted": "^1.0.0",
|
||||
"slate": "0.45.0",
|
||||
"slate-md-serializer": "5.5.4",
|
||||
"slug": "^1.0.0",
|
||||
@@ -170,13 +170,13 @@
|
||||
"eslint-plugin-jsx-a11y": "^6.1.0",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"eslint-plugin-react": "^7.20.0",
|
||||
"eslint-plugin-react-hooks": "^4.1.0",
|
||||
"fetch-test-server": "^1.1.0",
|
||||
"flow-bin": "^0.104.0",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"jest-cli": "^26.0.0",
|
||||
"koa-webpack-dev-middleware": "^1.4.5",
|
||||
"koa-webpack-hot-middleware": "^1.0.3",
|
||||
"mobx-react-devtools": "^6.0.3",
|
||||
"nodemon": "^1.19.4",
|
||||
"prettier": "^2.0.5",
|
||||
"rimraf": "^2.5.4",
|
||||
@@ -191,4 +191,4 @@
|
||||
"js-yaml": "^3.13.1"
|
||||
},
|
||||
"version": "0.46.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,80 +22,97 @@ export default async function documentMover({
|
||||
const result = { collections: [], documents: [] };
|
||||
const collectionChanged = collectionId !== document.collectionId;
|
||||
|
||||
try {
|
||||
transaction = await sequelize.transaction();
|
||||
if (document.template) {
|
||||
if (!collectionChanged) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// remove from original collection
|
||||
const collection = await document.getCollection({ transaction });
|
||||
const documentJson = await collection.removeDocumentInStructure(document, {
|
||||
save: false,
|
||||
});
|
||||
|
||||
// if the collection is the same then it will get saved below, this
|
||||
// line prevents a pointless intermediate save from occurring.
|
||||
if (collectionChanged) await collection.save({ transaction });
|
||||
|
||||
// add to new collection (may be the same)
|
||||
document.collectionId = collectionId;
|
||||
document.parentDocumentId = parentDocumentId;
|
||||
document.parentDocumentId = null;
|
||||
|
||||
const newCollection: Collection = collectionChanged
|
||||
? await Collection.findByPk(collectionId, { transaction })
|
||||
: collection;
|
||||
await newCollection.addDocumentToStructure(document, index, {
|
||||
documentJson,
|
||||
});
|
||||
result.collections.push(collection);
|
||||
|
||||
// if collection does not remain the same loop through children and change their
|
||||
// collectionId too. This includes archived children, otherwise their collection
|
||||
// would be wrong once restored.
|
||||
if (collectionChanged) {
|
||||
result.collections.push(newCollection);
|
||||
|
||||
const loopChildren = async (documentId) => {
|
||||
const childDocuments = await Document.findAll({
|
||||
where: { parentDocumentId: documentId },
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
childDocuments.map(async (child) => {
|
||||
await loopChildren(child.id);
|
||||
await child.update({ collectionId }, { transaction });
|
||||
child.collection = newCollection;
|
||||
result.documents.push(child);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
await loopChildren(document.id);
|
||||
}
|
||||
|
||||
await document.save({ transaction });
|
||||
await document.save();
|
||||
result.documents.push(document);
|
||||
} else {
|
||||
try {
|
||||
transaction = await sequelize.transaction();
|
||||
|
||||
await transaction.commit();
|
||||
// remove from original collection
|
||||
const collection = await Collection.findByPk(document.collectionId, {
|
||||
transaction,
|
||||
});
|
||||
const documentJson = await collection.removeDocumentInStructure(
|
||||
document,
|
||||
{
|
||||
save: false,
|
||||
}
|
||||
);
|
||||
|
||||
await Event.create({
|
||||
name: "documents.move",
|
||||
actorId: user.id,
|
||||
documentId: document.id,
|
||||
collectionId,
|
||||
teamId: document.teamId,
|
||||
data: {
|
||||
title: document.title,
|
||||
collectionIds: result.collections.map((c) => c.id),
|
||||
documentIds: result.documents.map((d) => d.id),
|
||||
},
|
||||
ip,
|
||||
});
|
||||
} catch (err) {
|
||||
if (transaction) {
|
||||
await transaction.rollback();
|
||||
// if the collection is the same then it will get saved below, this
|
||||
// line prevents a pointless intermediate save from occurring.
|
||||
if (collectionChanged) await collection.save({ transaction });
|
||||
|
||||
// add to new collection (may be the same)
|
||||
document.collectionId = collectionId;
|
||||
document.parentDocumentId = parentDocumentId;
|
||||
|
||||
const newCollection: Collection = collectionChanged
|
||||
? await Collection.findByPk(collectionId, { transaction })
|
||||
: collection;
|
||||
await newCollection.addDocumentToStructure(document, index, {
|
||||
documentJson,
|
||||
});
|
||||
result.collections.push(collection);
|
||||
|
||||
// if collection does not remain the same loop through children and change their
|
||||
// collectionId too. This includes archived children, otherwise their collection
|
||||
// would be wrong once restored.
|
||||
if (collectionChanged) {
|
||||
result.collections.push(newCollection);
|
||||
|
||||
const loopChildren = async (documentId) => {
|
||||
const childDocuments = await Document.findAll({
|
||||
where: { parentDocumentId: documentId },
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
childDocuments.map(async (child) => {
|
||||
await loopChildren(child.id);
|
||||
await child.update({ collectionId }, { transaction });
|
||||
child.collection = newCollection;
|
||||
result.documents.push(child);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
await loopChildren(document.id);
|
||||
}
|
||||
|
||||
await document.save({ transaction });
|
||||
result.documents.push(document);
|
||||
|
||||
await transaction.commit();
|
||||
} catch (err) {
|
||||
if (transaction) {
|
||||
await transaction.rollback();
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
await Event.create({
|
||||
name: "documents.move",
|
||||
actorId: user.id,
|
||||
documentId: document.id,
|
||||
collectionId,
|
||||
teamId: document.teamId,
|
||||
data: {
|
||||
title: document.title,
|
||||
collectionIds: result.collections.map((c) => c.id),
|
||||
documentIds: result.documents.map((d) => d.id),
|
||||
},
|
||||
ip,
|
||||
});
|
||||
|
||||
// we need to send all updated models back to the client
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
},
|
||||
"production": {
|
||||
"use_env_variable": "DATABASE_URL",
|
||||
"dialect": "postgres"
|
||||
"dialect": "postgres",
|
||||
"dialectOptions": {
|
||||
"ssl": {
|
||||
"rejectUnauthorized": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ const Authentication = sequelize.define("authentication", {
|
||||
},
|
||||
service: DataTypes.STRING,
|
||||
scopes: DataTypes.ARRAY(DataTypes.STRING),
|
||||
token: encryptedFields.vault("token"),
|
||||
token: encryptedFields().vault("token"),
|
||||
});
|
||||
|
||||
Authentication.associate = (models) => {
|
||||
|
||||
@@ -250,11 +250,13 @@ Collection.prototype.addDocumentToStructure = async function (
|
||||
}
|
||||
|
||||
// Sequelize doesn't seem to set the value with splice on JSONB field
|
||||
this.documentStructure = this.documentStructure;
|
||||
// https://github.com/sequelize/sequelize/blob/e1446837196c07b8ff0c23359b958d68af40fd6d/src/model.js#L3937
|
||||
this.changed("documentStructure", true);
|
||||
|
||||
if (options.save !== false) {
|
||||
await this.save({
|
||||
...options,
|
||||
fields: ["documentStructure"],
|
||||
transaction,
|
||||
});
|
||||
if (transaction) {
|
||||
|
||||
@@ -27,7 +27,7 @@ const User = sequelize.define(
|
||||
service: { type: DataTypes.STRING, allowNull: true },
|
||||
serviceId: { type: DataTypes.STRING, allowNull: true, unique: true },
|
||||
slackData: DataTypes.JSONB,
|
||||
jwtSecret: encryptedFields.vault("jwtSecret"),
|
||||
jwtSecret: encryptedFields().vault("jwtSecret"),
|
||||
lastActiveAt: DataTypes.DATE,
|
||||
lastActiveIp: { type: DataTypes.STRING, allowNull: true },
|
||||
lastSignedInAt: DataTypes.DATE,
|
||||
|
||||
@@ -71,7 +71,21 @@ allow(User, "createChildDocument", Document, (user, document) => {
|
||||
return user.teamId === document.teamId;
|
||||
});
|
||||
|
||||
allow(User, ["move", "pin", "unpin"], Document, (user, document) => {
|
||||
allow(User, "move", Document, (user, document) => {
|
||||
if (document.archivedAt) return false;
|
||||
if (document.deletedAt) return false;
|
||||
if (!document.publishedAt) return false;
|
||||
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "update", document.collection)) return false;
|
||||
|
||||
return user.teamId === document.teamId;
|
||||
});
|
||||
|
||||
allow(User, ["pin", "unpin"], Document, (user, document) => {
|
||||
if (document.archivedAt) return false;
|
||||
if (document.deletedAt) return false;
|
||||
if (document.template) return false;
|
||||
@@ -112,16 +126,16 @@ allow(User, "restore", Document, (user, document) => {
|
||||
});
|
||||
|
||||
allow(User, "archive", Document, (user, document) => {
|
||||
if (!document.publishedAt) return false;
|
||||
if (document.archivedAt) return false;
|
||||
if (document.deletedAt) return false;
|
||||
|
||||
invariant(
|
||||
document.collection,
|
||||
"collection is missing, did you forget to include in the query scope?"
|
||||
);
|
||||
if (cannot(user, "update", document.collection)) return false;
|
||||
|
||||
if (!document.publishedAt) return false;
|
||||
if (document.archivedAt) return false;
|
||||
if (document.deletedAt) return false;
|
||||
|
||||
return user.teamId === document.teamId;
|
||||
});
|
||||
|
||||
|
||||
@@ -72,11 +72,13 @@ export default async function present(document: Document, options: ?Options) {
|
||||
data.updatedBy = presentUser(document.updatedBy);
|
||||
|
||||
// TODO: This could be further optimized
|
||||
data.collaborators = await User.findAll({
|
||||
where: {
|
||||
id: takeRight(document.collaboratorIds, 10) || [],
|
||||
},
|
||||
}).map(presentUser);
|
||||
data.collaborators = (
|
||||
await User.findAll({
|
||||
where: {
|
||||
id: takeRight(document.collaboratorIds, 10) || [],
|
||||
},
|
||||
})
|
||||
).map(presentUser);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
+12
-5
@@ -3,16 +3,23 @@ import debug from "debug";
|
||||
import Sequelize from "sequelize";
|
||||
import EncryptedField from "sequelize-encrypted";
|
||||
|
||||
export const encryptedFields = EncryptedField(
|
||||
Sequelize,
|
||||
process.env.SECRET_KEY
|
||||
);
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
export const encryptedFields = () =>
|
||||
EncryptedField(Sequelize, process.env.SECRET_KEY);
|
||||
|
||||
export const DataTypes = Sequelize;
|
||||
export const Op = Sequelize.Op;
|
||||
|
||||
export const sequelize = new Sequelize(process.env.DATABASE_URL, {
|
||||
// logging: console.log,
|
||||
logging: debug("sql"),
|
||||
typeValidation: true,
|
||||
dialectOptions: {
|
||||
ssl: isProduction
|
||||
? {
|
||||
// Ref.: https://github.com/brianc/node-postgres/issues/2009
|
||||
rejectUnauthorized: false,
|
||||
}
|
||||
: false,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -28,5 +28,4 @@ function runMigrations() {
|
||||
runMigrations();
|
||||
|
||||
// This is needed for the relative manual mock to be picked up
|
||||
// $FlowFixMe
|
||||
jest.mock("../events");
|
||||
|
||||
@@ -6,7 +6,9 @@ export function flushdb() {
|
||||
const sql = sequelize.getQueryInterface();
|
||||
const tables = Object.keys(sequelize.models).map((model) => {
|
||||
const n = sequelize.models[model].getTableName();
|
||||
return sql.quoteTable(typeof n === "string" ? n : n.tableName);
|
||||
return sql.queryGenerator.quoteTable(
|
||||
typeof n === "string" ? n : n.tableName
|
||||
);
|
||||
});
|
||||
|
||||
const query = `TRUNCATE ${tables.join(", ")} CASCADE`;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.8.3":
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
||||
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
|
||||
@@ -40,7 +40,7 @@
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.11.0", "@babel/generator@^7.8.6":
|
||||
"@babel/generator@^7.11.0":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c"
|
||||
integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==
|
||||
@@ -130,7 +130,7 @@
|
||||
"@babel/traverse" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.8.3":
|
||||
"@babel/helper-function-name@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a"
|
||||
integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==
|
||||
@@ -139,7 +139,7 @@
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.10.4", "@babel/helper-get-function-arity@^7.8.3":
|
||||
"@babel/helper-get-function-arity@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
|
||||
integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==
|
||||
@@ -235,14 +235,14 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.11.0"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.8.3":
|
||||
"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f"
|
||||
integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.11.0"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.9.0":
|
||||
"@babel/helper-validator-identifier@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
|
||||
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
|
||||
@@ -266,7 +266,7 @@
|
||||
"@babel/traverse" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4", "@babel/highlight@^7.8.3":
|
||||
"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
|
||||
integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
|
||||
@@ -275,7 +275,7 @@
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.7.0", "@babel/parser@^7.8.6":
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.7.0":
|
||||
version "7.11.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9"
|
||||
integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==
|
||||
@@ -964,7 +964,7 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.10.4", "@babel/template@^7.3.3", "@babel/template@^7.8.3":
|
||||
"@babel/template@^7.10.4", "@babel/template@^7.3.3":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
|
||||
integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==
|
||||
@@ -988,7 +988,7 @@
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.8.7":
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d"
|
||||
integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==
|
||||
@@ -2496,7 +2496,7 @@ blob@0.0.5:
|
||||
resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
|
||||
integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
|
||||
|
||||
bluebird@^3.5.0, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2:
|
||||
bluebird@^3.5.5, bluebird@^3.7.2:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||
@@ -2722,10 +2722,10 @@ buffer-indexof-polyfill@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz#a9fb806ce8145d5428510ce72f278bb363a638bf"
|
||||
integrity sha1-qfuAbOgUXVQoUQznLyeLs2OmOL8=
|
||||
|
||||
buffer-writer@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-1.0.1.tgz#22a936901e3029afcd7547eb4487ceb697a3bf08"
|
||||
integrity sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg=
|
||||
buffer-writer@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
|
||||
integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
|
||||
|
||||
buffer-xor@^1.0.3:
|
||||
version "1.0.3"
|
||||
@@ -3190,14 +3190,6 @@ cloneable-readable@^1.0.0:
|
||||
process-nextick-args "^2.0.0"
|
||||
readable-stream "^2.3.5"
|
||||
|
||||
cls-bluebird@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.1.0.tgz#37ef1e080a8ffb55c2f4164f536f1919e7968aee"
|
||||
integrity sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=
|
||||
dependencies:
|
||||
is-bluebird "^1.0.2"
|
||||
shimmer "^1.1.0"
|
||||
|
||||
cluster-key-slot@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
|
||||
@@ -4391,6 +4383,11 @@ eslint-plugin-prettier@^3.1.0:
|
||||
dependencies:
|
||||
prettier-linter-helpers "^1.0.0"
|
||||
|
||||
eslint-plugin-react-hooks@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.0.tgz#6323fbd5e650e84b2987ba76370523a60f4e7925"
|
||||
integrity sha512-36zilUcDwDReiORXmcmTc6rRumu9JIM3WjSvV0nclHoUQ0CNrX866EwONvLR/UqaeqFutbAnVu8PEmctdo2SRQ==
|
||||
|
||||
eslint-plugin-react@^7.20.0:
|
||||
version "7.20.5"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.20.5.tgz#29480f3071f64a04b2c3d99d9b460ce0f76fb857"
|
||||
@@ -5075,11 +5072,6 @@ gcp-metadata@^3.4.0:
|
||||
gaxios "^2.1.0"
|
||||
json-bigint "^0.3.0"
|
||||
|
||||
generic-pool@2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-2.4.3.tgz#780c36f69dfad05a5a045dd37be7adca11a4f6ff"
|
||||
integrity sha1-eAw29p360FpaBF3Te+etyhGk9v8=
|
||||
|
||||
gensync@^1.0.0-beta.1:
|
||||
version "1.0.0-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
|
||||
@@ -5943,11 +5935,6 @@ is-binary-path@~2.1.0:
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-bluebird@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2"
|
||||
integrity sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=
|
||||
|
||||
is-buffer@^1.1.5, is-buffer@~1.1.1:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
@@ -6712,11 +6699,6 @@ js-search@^1.4.2:
|
||||
resolved "https://registry.yarnpkg.com/js-search/-/js-search-1.4.3.tgz#23a86d7e064ca53a473930edc48615b6b1c1954a"
|
||||
integrity sha512-Sny5pf00kX1sM1KzvUC9nGYWXOvBfy30rmvZWeRktpg+esQKedIXrXNee/I2CAnsouCyaTjitZpRflDACx4toA==
|
||||
|
||||
js-string-escape@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
|
||||
integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
@@ -7513,7 +7495,7 @@ lodash.uniq@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
"lodash@>=3.5 <5", lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5:
|
||||
"lodash@>=3.5 <5", lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5:
|
||||
version "4.17.19"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
||||
@@ -7900,35 +7882,34 @@ mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
mobx-react-devtools@^6.0.3:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react-devtools/-/mobx-react-devtools-6.1.1.tgz#a462b944085cf11ff96fc937d12bf31dab4c8984"
|
||||
integrity sha512-nc5IXLdEUFLn3wZal65KF3/JFEFd+mbH4KTz/IG5BOPyw7jo8z29w/8qm7+wiCyqVfUIgJ1gL4+HVKmcXIOgqA==
|
||||
mobx-react-lite@>=2.0.6:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz#1bfb3b4272668e288047cf0c7940b14e91cba284"
|
||||
integrity sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q==
|
||||
|
||||
mobx-react@^5.4.2:
|
||||
version "5.4.4"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-5.4.4.tgz#b3de9c6eabcd0ed8a40036888cb0221ab9568b80"
|
||||
integrity sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==
|
||||
mobx-react@^6.2.5:
|
||||
version "6.2.5"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.2.5.tgz#9020a17b79cc6dc3d124ad89ab36eb9ea540a45b"
|
||||
integrity sha512-LxtXXW0GkOAO6VOIg2m/6WL6ZuKlzOWwESIFdrWelI0ZMIvtKCMZVUuulcO5GAWSDsH0ApaMkGLoaPqKjzyziQ==
|
||||
dependencies:
|
||||
hoist-non-react-statics "^3.0.0"
|
||||
react-lifecycles-compat "^3.0.2"
|
||||
mobx-react-lite ">=2.0.6"
|
||||
|
||||
mobx@4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-4.6.0.tgz#88a8ed21ff81b8861778c4b0d38e3dcdd1a7ddde"
|
||||
integrity sha512-qoX4BsUpA37yLzYAmNsApPiRlpMr8uwt+KYVTJNv9IhpD8NQVMno/K3EqZKAsiWo9IEvPOuQ0B6z7Z7ISjULpA==
|
||||
|
||||
moment-timezone@^0.5.21, moment-timezone@^0.5.25:
|
||||
version "0.5.28"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338"
|
||||
integrity sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw==
|
||||
moment-timezone@^0.5.25, moment-timezone@^0.5.31:
|
||||
version "0.5.31"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.31.tgz#9c40d8c5026f0c7ab46eda3d63e49c155148de05"
|
||||
integrity sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
"moment@>= 2.9.0", moment@^2.24.0:
|
||||
version "2.24.0"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
||||
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
|
||||
"moment@>= 2.9.0", moment@^2.26.0:
|
||||
version "2.27.0"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
|
||||
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
|
||||
|
||||
move-concurrently@^1.0.1:
|
||||
version "1.0.1"
|
||||
@@ -8212,11 +8193,6 @@ oauth-sign@~0.9.0:
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
object-assign@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
|
||||
integrity sha1-ejs9DpgGPUP0wD8uiubNUahog6A=
|
||||
|
||||
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@@ -8548,10 +8524,10 @@ package-json@^4.0.0:
|
||||
registry-url "^3.0.3"
|
||||
semver "^5.1.0"
|
||||
|
||||
packet-reader@0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-0.3.1.tgz#cd62e60af8d7fea8a705ec4ff990871c46871f27"
|
||||
integrity sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=
|
||||
packet-reader@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
|
||||
integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
|
||||
|
||||
pako@~1.0.2, pako@~1.0.5:
|
||||
version "1.0.11"
|
||||
@@ -8746,15 +8722,15 @@ performance-now@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
pg-connection-string@0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
|
||||
integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=
|
||||
pg-connection-string@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.3.0.tgz#c13fcb84c298d0bfa9ba12b40dd6c23d946f55d6"
|
||||
integrity sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w==
|
||||
|
||||
pg-hstore@2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.2.tgz#f7ef053e7b9b892ae986af2f7cbe86432dfcf24f"
|
||||
integrity sha1-9+8FPnubiSrphq8vfL6GQy388k8=
|
||||
pg-hstore@^2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.3.tgz#d1978c12a85359830b1388d3b0ff233b88928e96"
|
||||
integrity sha512-qpeTpdkguFgfdoidtfeTho1Q1zPVPbtMHgs8eQ+Aan05iLmIs3Z3oo5DOZRclPGoQ4i68I1kCtQSJSa7i0ZVYg==
|
||||
dependencies:
|
||||
underscore "^1.7.0"
|
||||
|
||||
@@ -8763,40 +8739,42 @@ pg-int8@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
|
||||
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
|
||||
|
||||
pg-pool@1.*:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-1.8.0.tgz#f7ec73824c37a03f076f51bfdf70e340147c4f37"
|
||||
integrity sha1-9+xzgkw3oD8Hb1G/33DjQBR8Tzc=
|
||||
dependencies:
|
||||
generic-pool "2.4.3"
|
||||
object-assign "4.1.0"
|
||||
pg-pool@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.2.1.tgz#5f4afc0f58063659aeefa952d36af49fa28b30e0"
|
||||
integrity sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==
|
||||
|
||||
pg-types@1.*:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.13.0.tgz#75f490b8a8abf75f1386ef5ec4455ecf6b345c63"
|
||||
integrity sha512-lfKli0Gkl/+za/+b6lzENajczwZHc7D5kiUCZfgm914jipD2kIOIvEkAhZ8GrW3/TUoP9w8FHjwpPObBye5KQQ==
|
||||
pg-protocol@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.2.5.tgz#28a1492cde11646ff2d2d06bdee42a3ba05f126c"
|
||||
integrity sha512-1uYCckkuTfzz/FCefvavRywkowa6M5FohNMF5OjKrqo9PSR8gYc8poVmwwYQaBxhmQdBjhtP514eXy9/Us2xKg==
|
||||
|
||||
pg-types@^2.1.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
|
||||
integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
|
||||
dependencies:
|
||||
pg-int8 "1.0.1"
|
||||
postgres-array "~1.0.0"
|
||||
postgres-array "~2.0.0"
|
||||
postgres-bytea "~1.0.0"
|
||||
postgres-date "~1.0.0"
|
||||
postgres-date "~1.0.4"
|
||||
postgres-interval "^1.1.0"
|
||||
|
||||
pg@^6.1.5:
|
||||
version "6.4.2"
|
||||
resolved "https://registry.yarnpkg.com/pg/-/pg-6.4.2.tgz#c364011060eac7a507a2ae063eb857ece910e27f"
|
||||
integrity sha1-w2QBEGDqx6UHoq4GPrhX7OkQ4n8=
|
||||
pg@^8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pg/-/pg-8.3.0.tgz#941383300d38eef51ecb88a0188cec441ab64d81"
|
||||
integrity sha512-jQPKWHWxbI09s/Z9aUvoTbvGgoj98AU7FDCcQ7kdejupn/TcNpx56v2gaOTzXkzOajmOEJEdi9eTh9cA2RVAjQ==
|
||||
dependencies:
|
||||
buffer-writer "1.0.1"
|
||||
js-string-escape "1.0.1"
|
||||
packet-reader "0.3.1"
|
||||
pg-connection-string "0.1.3"
|
||||
pg-pool "1.*"
|
||||
pg-types "1.*"
|
||||
pgpass "1.*"
|
||||
buffer-writer "2.0.0"
|
||||
packet-reader "1.0.0"
|
||||
pg-connection-string "^2.3.0"
|
||||
pg-pool "^3.2.1"
|
||||
pg-protocol "^1.2.5"
|
||||
pg-types "^2.1.0"
|
||||
pgpass "1.x"
|
||||
semver "4.3.2"
|
||||
|
||||
pgpass@1.*:
|
||||
pgpass@1.x:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306"
|
||||
integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=
|
||||
@@ -8873,20 +8851,20 @@ postcss-value-parser@^4.0.2:
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d"
|
||||
integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==
|
||||
|
||||
postgres-array@~1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.3.tgz#c561fc3b266b21451fc6555384f4986d78ec80f5"
|
||||
integrity sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==
|
||||
postgres-array@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
||||
integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
|
||||
|
||||
postgres-bytea@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
|
||||
integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
|
||||
|
||||
postgres-date@~1.0.0:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.5.tgz#710b27de5f27d550f6e80b5d34f7ba189213c2ee"
|
||||
integrity sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==
|
||||
postgres-date@~1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.6.tgz#4925e8085b30c2ba1a06ac91b9a3473954a2ce2d"
|
||||
integrity sha512-o2a4gxeFcox+CgB3Ig/kNHBP23PiEXHCXx7pcIIsvzoNz4qv+lKTyiSkjOXIMNUl12MO/mOYl2K6wR9X5K6Plg==
|
||||
|
||||
postgres-interval@^1.1.0:
|
||||
version "1.2.0"
|
||||
@@ -9372,7 +9350,7 @@ react-keydown@^1.7.3:
|
||||
dependencies:
|
||||
core-js "^3.1.2"
|
||||
|
||||
react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.2:
|
||||
react-lifecycles-compat@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
@@ -10097,50 +10075,47 @@ semver@^7.2.1, semver@^7.3.2:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||
|
||||
sequelize-cli@^5.5.0:
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/sequelize-cli/-/sequelize-cli-5.5.1.tgz#0b9c2fc04d082cc8ae0a8fe270b96bb606152bab"
|
||||
integrity sha512-ZM4kUZvY3y14y+Rq3cYxGH7YDJz11jWHcN2p2x7rhAIemouu4CEXr5ebw30lzTBtyXV4j2kTO+nUjZOqzG7k+Q==
|
||||
sequelize-cli@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/sequelize-cli/-/sequelize-cli-6.2.0.tgz#fd02bfeae23b8226872f9947f3f8212cc49a4771"
|
||||
integrity sha512-6WQ2x91hg30dUn66mXHnzvHATZ4pyI1GHSNbS/TNN/vRR4BLRSLijadeMgC8zqmKDsL0VqzVVopJWfJakuP++Q==
|
||||
dependencies:
|
||||
bluebird "^3.5.3"
|
||||
cli-color "^1.4.0"
|
||||
fs-extra "^7.0.1"
|
||||
js-beautify "^1.8.8"
|
||||
lodash "^4.17.5"
|
||||
resolve "^1.5.0"
|
||||
umzug "^2.1.0"
|
||||
umzug "^2.3.0"
|
||||
yargs "^13.1.0"
|
||||
|
||||
sequelize-encrypted@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sequelize-encrypted/-/sequelize-encrypted-0.1.0.tgz#f9c7a94dc1b4413e1347a49f06cd07b7f3bf9916"
|
||||
integrity sha1-+cepTcG0QT4TR6SfBs0Ht/O/mRY=
|
||||
sequelize-encrypted@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sequelize-encrypted/-/sequelize-encrypted-1.0.0.tgz#49c5f48edcebd3504cc18bcb4876600d53e311d7"
|
||||
integrity sha1-ScX0jtzr01BMwYvLSHZgDVPjEdc=
|
||||
|
||||
sequelize-pool@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-2.3.0.tgz#64f1fe8744228172c474f530604b6133be64993d"
|
||||
integrity sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==
|
||||
sequelize-pool@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668"
|
||||
integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==
|
||||
|
||||
sequelize@^5.21.1:
|
||||
version "5.21.6"
|
||||
resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-5.21.6.tgz#5bf9b687336ce9157a3b386ad653fa130a5fa38a"
|
||||
integrity sha512-RsgEpP2PP7txeoTWxoLLoe3xX8R2WYQAO7LNba2Ok3/pV5EFfKZry4fJXH56DUHJB909msMCHg0CJKDsQVbjcQ==
|
||||
sequelize@^6.3.4:
|
||||
version "6.3.4"
|
||||
resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.3.4.tgz#dd6f4801ba5e4d7a6f845a5ad3e616f24453694f"
|
||||
integrity sha512-W6Y96N5QHTgEz5Q37v2GYbKufSXaw0b3v4rCLTPbcCMfIG0MHI42Ozp7IwiyV9bdNkfFEdY7XP8R6lWrWg4hUw==
|
||||
dependencies:
|
||||
bluebird "^3.5.0"
|
||||
cls-bluebird "^2.1.0"
|
||||
debug "^4.1.1"
|
||||
dottie "^2.0.0"
|
||||
inflection "1.12.0"
|
||||
lodash "^4.17.15"
|
||||
moment "^2.24.0"
|
||||
moment-timezone "^0.5.21"
|
||||
moment "^2.26.0"
|
||||
moment-timezone "^0.5.31"
|
||||
retry-as-promised "^3.2.0"
|
||||
semver "^6.3.0"
|
||||
sequelize-pool "^2.3.0"
|
||||
semver "^7.3.2"
|
||||
sequelize-pool "^6.0.0"
|
||||
toposort-class "^1.0.1"
|
||||
uuid "^3.3.3"
|
||||
uuid "^8.1.0"
|
||||
validator "^10.11.0"
|
||||
wkx "^0.4.8"
|
||||
wkx "^0.5.0"
|
||||
|
||||
serialize-javascript@^4.0.0:
|
||||
version "4.0.0"
|
||||
@@ -10235,11 +10210,6 @@ shellwords@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
|
||||
|
||||
shimmer@^1.1.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
|
||||
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
|
||||
|
||||
side-channel@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
|
||||
@@ -11349,7 +11319,7 @@ uid2@0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82"
|
||||
integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=
|
||||
|
||||
umzug@^2.1.0:
|
||||
umzug@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/umzug/-/umzug-2.3.0.tgz#0ef42b62df54e216b05dcaf627830a6a8b84a184"
|
||||
integrity sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==
|
||||
@@ -11618,12 +11588,12 @@ uuid@3.3.2:
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
|
||||
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
|
||||
|
||||
uuid@^3.3.2, uuid@^3.3.3, uuid@^3.4.0:
|
||||
uuid@^3.3.2, uuid@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
uuid@^8.2.0:
|
||||
uuid@^8.1.0, uuid@^8.2.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
|
||||
integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==
|
||||
@@ -11909,10 +11879,10 @@ windows-release@^3.1.0:
|
||||
dependencies:
|
||||
execa "^1.0.0"
|
||||
|
||||
wkx@^0.4.8:
|
||||
version "0.4.8"
|
||||
resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003"
|
||||
integrity sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==
|
||||
wkx@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c"
|
||||
integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user