├── .gitignore
├── README.md
├── client
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── assets
│ │ ├── landing.jpg
│ │ ├── logo.svg
│ │ ├── logout.svg
│ │ ├── pencil.svg
│ │ ├── play-btn.svg
│ │ ├── plus-circle-fill.svg
│ │ └── trash.svg
│ ├── components
│ │ ├── auth
│ │ │ ├── LoginForm.js
│ │ │ └── RegisterForm.js
│ │ ├── layout
│ │ │ ├── AlertMessage.js
│ │ │ ├── Landing.js
│ │ │ └── NavbarMenu.js
│ │ ├── posts
│ │ │ ├── ActionButton.js
│ │ │ ├── AddPostModal.js
│ │ │ ├── SinglePost.js
│ │ │ └── UpdatePostModal.js
│ │ └── routing
│ │ │ └── ProtectedRoute.js
│ ├── contexts
│ │ ├── AuthContext.js
│ │ ├── PostContext.js
│ │ └── constants.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reducers
│ │ ├── authReducer.js
│ │ └── postReducer.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ ├── utils
│ │ └── setAuthToken.js
│ └── views
│ │ ├── About.js
│ │ ├── Auth.js
│ │ └── Dashboard.js
└── yarn.lock
├── screenshots
├── screenshot_1.png
├── screenshot_2.png
├── screenshot_3.png
├── screenshot_4.png
├── screenshot_5.png
└── screenshot_6.png
└── server
├── .env
├── package.json
├── request.http
├── src
├── config
│ └── db.js
├── index.js
├── middleware
│ └── auth.js
├── models
│ ├── Post.js
│ └── User.js
└── routers
│ ├── auth.js
│ └── post.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | server/dist
2 | server/node_modules
3 | # server/.env
4 |
5 | client/node_modules
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **Follow me:**
2 | - [Facebook](https://www.facebook.com/zendy199x/)
3 | - [Linkedin](https://www.linkedin.com/in/zendy199x/)
4 | - [Github](https://www.github.com/zendy199x/)
5 |
6 | **Contact me:**
7 | - Mail: zendy199x@gmail.com
8 | - Skype: nhokkute.nguyenduc
9 | - Zalo: [Zendy](https://zalo.me/nguyenduc94/)
10 |
11 | ### Setup
12 |
13 | **Server**
14 | ```bash
15 | cd server && yarn server
16 | ```
17 |
18 | **Client**
19 | ```bash
20 | cd client && yarn start
21 | ```
22 |
23 | ### Screenshots
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `yarn build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "axios": "^0.21.1",
7 | "cra-template": "1.1.2",
8 | "react": "^17.0.2",
9 | "react-bootstrap": "^1.6.1",
10 | "react-dom": "^17.0.2",
11 | "react-router-dom": "^5.2.1",
12 | "react-scripts": "4.0.3",
13 | "web-vitals": "^2.1.0"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": [
23 | "react-app",
24 | "react-app/jest"
25 | ]
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
24 |
33 | MERN Stack
34 |
35 |
36 |
37 |
38 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/client/public/logo192.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/client/public/logo512.png
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/src/App.css:
--------------------------------------------------------------------------------
1 | .landing {
2 | position: relative;
3 | background: url('./assets/landing.jpg') no-repeat center center/cover;
4 | height: 100vh;
5 | }
6 |
7 | .dark-overlay {
8 | background-color: rgba(0, 0, 0, 0.5);
9 | height: 100%;
10 | }
11 |
12 | .landing-inner {
13 | height: 100%;
14 | margin: auto;
15 | display: flex;
16 | flex-direction: column;
17 | justify-content: center;
18 | align-items: center;
19 | text-align: center;
20 | }
21 |
22 | .landing-inner form {
23 | width: 30%;
24 | }
25 |
26 | .landing-inner h1,
27 | .landing-inner h4,
28 | .landing-inner p {
29 | color: white;
30 | }
31 |
32 | .spinner-container {
33 | position: absolute;
34 | top: 50%;
35 | left: 50%;
36 | -moz-transform: translateX(-50%) translateY(-50%);
37 | -webkit-transform: translateX(-50%) translateY(-50%);
38 | transform: translateX(-50%) translateY(-50%);
39 | }
40 |
41 | /* Post button */
42 | .post-button {
43 | padding-top: 0;
44 | background: transparent;
45 | border: none;
46 | }
47 |
48 | .post-button:hover {
49 | background: transparent;
50 | }
51 |
52 | a.post-button.btn:focus,
53 | a.post-button.btn:active {
54 | outline: none;
55 | background: transparent;
56 | border: none;
57 | box-shadow: none;
58 | }
59 |
60 | button.post-button.btn:focus,
61 | button.post-button.btn:active {
62 | outline: none;
63 | background: transparent;
64 | border: none;
65 | box-shadow: none;
66 | }
67 |
68 | /* Floating add button */
69 | .btn-floating {
70 | position: fixed;
71 | right: 3rem;
72 | bottom: 3rem;
73 | background: transparent;
74 | border: none;
75 | }
76 |
77 | .btn-floating:hover {
78 | background: transparent;
79 | }
80 |
81 | .btn-floating:focus,
82 | .btn-floating:active {
83 | outline: none;
84 | background: transparent;
85 | border: none;
86 | box-shadow: none;
87 | }
88 |
89 | /* Add new post tooltip */
90 | .tooltip {
91 | background: transparent;
92 | }
93 |
94 | .tooltip .arrow::before {
95 | border-left-color: #78c2ad;
96 | }
97 |
98 | .tooltip-inner {
99 | background: #78c2ad;
100 | }
101 |
102 | /* Post border thicker */
103 | .border-success,
104 | .border-warning,
105 | .border-danger {
106 | border-width: 2px;
107 | }
108 |
109 | /* Post title */
110 | .post-title {
111 | margin-bottom: 0.5rem;
112 | }
--------------------------------------------------------------------------------
/client/src/App.js:
--------------------------------------------------------------------------------
1 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
2 | import "./App.css";
3 | import Landing from "./components/layout/Landing";
4 | import ProtectedRoute from "./components/routing/ProtectedRoute";
5 | import AuthContextProvider from "./contexts/AuthContext";
6 | import PostContextProvider from "./contexts/PostContext";
7 | import About from "./views/About";
8 | import Auth from "./views/Auth";
9 | import Dashboard from "./views/Dashboard";
10 |
11 | function App() {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 | }
22 | />
23 | }
27 | />
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 |
37 | export default App;
38 |
--------------------------------------------------------------------------------
/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/client/src/assets/landing.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/client/src/assets/landing.jpg
--------------------------------------------------------------------------------
/client/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/logout.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/pencil.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/play-btn.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/plus-circle-fill.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/trash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/components/auth/LoginForm.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState } from "react";
2 | import { Button, Form } from "react-bootstrap";
3 | import { Link } from "react-router-dom";
4 | import { AuthContext } from "../../contexts/AuthContext";
5 | import AlertMessage from "../layout/AlertMessage";
6 |
7 | const LoginForm = () => {
8 | // Context
9 | const { loginUser } = useContext(AuthContext);
10 |
11 | // const history = useHistory();
12 |
13 | const [loginForm, setLoginForm] = useState({
14 | username: "",
15 | password: "",
16 | });
17 |
18 | const [alert, setAlert] = useState(null);
19 |
20 | const { username, password } = loginForm;
21 |
22 | const onChangeLoginForm = (event) =>
23 | setLoginForm({ ...loginForm, [event.target.name]: event.target.value });
24 |
25 | const handleLogin = async (event) => {
26 | event.preventDefault();
27 |
28 | try {
29 | const loginData = await loginUser(loginForm);
30 | if (loginData.success) {
31 | // history.push("/dashboard");
32 | } else {
33 | setAlert({ type: "danger", message: loginData.message });
34 | setTimeout(() => setAlert(null), 5000);
35 | }
36 | } catch (error) {
37 | console.log(error);
38 | }
39 | };
40 |
41 | return (
42 | <>
43 |
47 |
55 |
56 |
57 |
65 |
66 |
69 |
70 |
71 | Don't have an account?{" "}
72 |
73 |
76 |
77 |
78 | >
79 | );
80 | };
81 |
82 | export default LoginForm;
83 |
--------------------------------------------------------------------------------
/client/src/components/auth/RegisterForm.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState } from "react";
2 | import { Button, Form } from "react-bootstrap";
3 | import { Link } from "react-router-dom";
4 | import { AuthContext } from "../../contexts/AuthContext";
5 | import AlertMessage from "../layout/AlertMessage";
6 |
7 | const RegisterForm = () => {
8 | // Context
9 | const { registerUser } = useContext(AuthContext);
10 |
11 | const [registerForm, setRegisterForm] = useState({
12 | username: "",
13 | password: "",
14 | confirmPassword: "",
15 | });
16 |
17 | const [alert, setAlert] = useState(null);
18 |
19 | const { username, password, confirmPassword } = registerForm;
20 |
21 | const onChangeRegisterForm = (event) =>
22 | setRegisterForm({
23 | ...registerForm,
24 | [event.target.name]: event.target.value,
25 | });
26 |
27 | const handleRegister = async (event) => {
28 | event.preventDefault();
29 |
30 | if (password !== confirmPassword) {
31 | setAlert({ type: "danger", message: "Passwords do not match" });
32 | setTimeout(() => setAlert(null), 5000);
33 | return;
34 | }
35 |
36 | try {
37 | const registerData = await registerUser(registerForm);
38 | if (!registerData.success) {
39 | setAlert({ type: "danger", message: registerData.message });
40 | setTimeout(() => setAlert(null), 5000);
41 | }
42 | } catch (error) {
43 | console.log(error);
44 | }
45 | };
46 |
47 | return (
48 | <>
49 |
53 |
61 |
62 |
63 |
71 |
72 |
73 |
81 |
82 |
85 |
86 |
87 | Don't have an account?{" "}
88 |
89 |
92 |
93 |
94 | >
95 | );
96 | };
97 |
98 | export default RegisterForm;
99 |
--------------------------------------------------------------------------------
/client/src/components/layout/AlertMessage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Alert } from 'react-bootstrap';
3 |
4 | const AlertMessage = ({ info }) => {
5 | return info === null ? null : (
6 | {info.message}
7 | );
8 | };
9 |
10 | export default AlertMessage;
11 |
--------------------------------------------------------------------------------
/client/src/components/layout/Landing.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Redirect } from "react-router-dom";
3 |
4 | const Landing = () => {
5 | return ;
6 | };
7 |
8 | export default Landing;
9 |
--------------------------------------------------------------------------------
/client/src/components/layout/NavbarMenu.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { Button, Nav, Navbar } from "react-bootstrap";
3 | import { Link } from "react-router-dom";
4 | import learnItLogo from "../../assets/logo.svg";
5 | import logoutIcon from "../../assets/logout.svg";
6 | import { AuthContext } from "../../contexts/AuthContext";
7 |
8 | const NavbarMenu = () => {
9 | const {
10 | authState: {
11 | user: { username },
12 | },
13 | logoutUser
14 | } = useContext(AuthContext);
15 |
16 | const handleLogout = () => logoutUser();
17 |
18 | return (
19 |
20 |
21 |
28 | LearnIt
29 |
30 |
31 |
32 |
33 |
37 |
53 |
54 |
70 |
71 |
72 | );
73 | };
74 |
75 | export default NavbarMenu;
76 |
--------------------------------------------------------------------------------
/client/src/components/posts/ActionButton.js:
--------------------------------------------------------------------------------
1 | import { useContext } from "react";
2 | import { Button } from "react-bootstrap";
3 | import editIcon from "../../assets/pencil.svg";
4 | import playIcon from "../../assets/play-btn.svg";
5 | import deleteIcon from "../../assets/trash.svg";
6 | import { PostContext } from "../../contexts/PostContext";
7 |
8 | const ActionButtons = ({ url, _id }) => {
9 | const { deletePost, findPost, setShowUpdatePostModal } =
10 | useContext(PostContext);
11 |
12 | const choosePost = (postId) => {
13 | findPost(postId);
14 | setShowUpdatePostModal(true);
15 | };
16 |
17 | return (
18 | <>
19 |
22 |
25 |
28 | >
29 | );
30 | };
31 |
32 | export default ActionButtons;
33 |
--------------------------------------------------------------------------------
/client/src/components/posts/AddPostModal.js:
--------------------------------------------------------------------------------
1 | import { useContext, useState } from "react";
2 | import { Button, Form, Modal } from "react-bootstrap";
3 | import { PostContext } from "../../contexts/PostContext";
4 |
5 | const AddPostModal = () => {
6 | // Contexts
7 | const { showAddPostModal, setShowAddPostModal, addPost, setShowToast } =
8 | useContext(PostContext);
9 |
10 | // State
11 | const [newPost, setNewPost] = useState({
12 | title: "",
13 | description: "",
14 | url: "",
15 | status: "TO LEARN",
16 | });
17 |
18 | const { title, description, url } = newPost;
19 |
20 | const onChangeNewPostForm = (event) =>
21 | setNewPost({ ...newPost, [event.target.name]: event.target.value });
22 |
23 | const closeDialog = () => {
24 | resetAddPostData();
25 | };
26 |
27 | const onSubmit = async (event) => {
28 | event.preventDefault();
29 | const { success, message } = await addPost(newPost);
30 | resetAddPostData();
31 | setShowToast({ show: true, message, type: success ? "success" : "danger" });
32 | };
33 |
34 | const resetAddPostData = () => {
35 | setNewPost({ title: "", description: "", url: "", status: "TO LEARN" });
36 | setShowAddPostModal(false);
37 | };
38 |
39 | return (
40 |
41 |
42 | What do you want to learn?
43 |
44 |
95 |
96 | );
97 | };
98 |
99 | export default AddPostModal;
100 |
--------------------------------------------------------------------------------
/client/src/components/posts/SinglePost.js:
--------------------------------------------------------------------------------
1 | import { Badge, Card, Col, Row } from "react-bootstrap";
2 | import ActionButtons from "./ActionButton";
3 |
4 | const SinglePost = ({ post: { _id, status, title, description, url } }) => (
5 |
15 |
16 |
17 |
18 |
19 | {title}
20 |
30 | {status}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | {description}
39 |
40 |
41 | );
42 |
43 | export default SinglePost;
44 |
--------------------------------------------------------------------------------
/client/src/components/posts/UpdatePostModal.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect, useState } from "react";
2 | import { Button, Form, Modal } from "react-bootstrap";
3 | import { PostContext } from "../../contexts/PostContext";
4 |
5 | const UpdatePostModal = () => {
6 | // Contexts
7 | const {
8 | postState: { post },
9 | showUpdatePostModal,
10 | setShowUpdatePostModal,
11 | updatePost,
12 | setShowToast,
13 | } = useContext(PostContext);
14 |
15 | // State
16 | const [updatedPost, setUpdatedPost] = useState(post);
17 |
18 | useEffect(() => setUpdatedPost(post), [post]);
19 |
20 | const { title, description, url, status } = updatedPost;
21 |
22 | const onChangeUpdatedPostForm = (event) =>
23 | setUpdatedPost({ ...updatedPost, [event.target.name]: event.target.value });
24 |
25 | const closeDialog = () => {
26 | setUpdatedPost(post);
27 | setShowUpdatePostModal(false);
28 | };
29 |
30 | const onSubmit = async (event) => {
31 | event.preventDefault();
32 | const { success, message } = await updatePost(updatedPost);
33 | setShowUpdatePostModal(false);
34 | setShowToast({ show: true, message, type: success ? "success" : "danger" });
35 | };
36 |
37 | return (
38 |
39 |
40 | Making progress?
41 |
42 |
108 |
109 | );
110 | };
111 |
112 | export default UpdatePostModal;
113 |
--------------------------------------------------------------------------------
/client/src/components/routing/ProtectedRoute.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { Spinner } from "react-bootstrap";
3 | import { Redirect, Route } from "react-router-dom";
4 | import { AuthContext } from "../../contexts/AuthContext";
5 | import NavbarMenu from "../layout/NavbarMenu";
6 |
7 | const ProtectedRoute = ({ component: Component, ...rest }) => {
8 | const {
9 | authState: { authLoading, isAuthenticated },
10 | } = useContext(AuthContext);
11 |
12 | if (authLoading) {
13 | return (
14 |
15 |
16 |
17 | );
18 | }
19 |
20 | return (
21 |
24 | isAuthenticated ? (
25 | <>
26 |
27 |
28 | >
29 | ) : (
30 |
31 | )
32 | }
33 | />
34 | );
35 | };
36 |
37 | export default ProtectedRoute;
38 |
--------------------------------------------------------------------------------
/client/src/contexts/AuthContext.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { createContext, useEffect, useReducer } from "react";
3 | import { SET_AUTH } from "../contexts/constants";
4 | import { authReducer } from "../reducers/authReducer";
5 | import setAuthToken from "../utils/setAuthToken";
6 | import { apiUrl, LOCAL_STORAGE_TOKEN_NAME } from "./constants";
7 |
8 | export const AuthContext = createContext();
9 |
10 | const AuthContextProvider = ({ children }) => {
11 | const [authState, dispatch] = useReducer(authReducer, {
12 | authLoading: true,
13 | isAuthenticated: false,
14 | user: null,
15 | });
16 |
17 | // Authenticate user
18 | const loadUser = async () => {
19 | if (localStorage[LOCAL_STORAGE_TOKEN_NAME]) {
20 | setAuthToken(localStorage[LOCAL_STORAGE_TOKEN_NAME]);
21 | }
22 |
23 | try {
24 | const response = await axios.get(`${apiUrl}/auth`);
25 | if (response.data.success) {
26 | dispatch({
27 | type: SET_AUTH,
28 | payload: {
29 | isAuthenticated: true,
30 | user: response.data.user,
31 | },
32 | });
33 | }
34 | } catch (error) {
35 | localStorage.removeItem(LOCAL_STORAGE_TOKEN_NAME);
36 | setAuthToken(null);
37 | dispatch({
38 | type: SET_AUTH,
39 | payload: {
40 | isAuthenticated: false,
41 | user: null,
42 | },
43 | });
44 | }
45 | };
46 |
47 | useEffect(() => loadUser(), []);
48 |
49 | // Login
50 | const loginUser = async (userForm) => {
51 | try {
52 | const response = await axios.post(`${apiUrl}/auth/login`, userForm);
53 | if (response.data.success)
54 | localStorage.setItem(
55 | LOCAL_STORAGE_TOKEN_NAME,
56 | response.data.accessToken
57 | );
58 |
59 | await loadUser();
60 |
61 | return response.data;
62 | } catch (error) {
63 | if (error.response.data) return error.response.data;
64 | else return { success: false, message: error.message };
65 | }
66 | };
67 |
68 | // Register
69 | const registerUser = async (userForm) => {
70 | try {
71 | const response = await axios.post(`${apiUrl}/auth/register`, userForm);
72 | if (response.data.success)
73 | localStorage.setItem(
74 | LOCAL_STORAGE_TOKEN_NAME,
75 | response.data.accessToken
76 | );
77 |
78 | await loadUser();
79 |
80 | return response.data;
81 | } catch (error) {
82 | if (error.response.data) return error.response.data;
83 | else return { success: false, message: error.message };
84 | }
85 | };
86 |
87 | // Logout
88 | const logoutUser = () => {
89 | localStorage.removeItem(LOCAL_STORAGE_TOKEN_NAME);
90 | dispatch({
91 | type: "SET_AUTH",
92 | payload: {
93 | isAuthenticated: false,
94 | user: null,
95 | },
96 | });
97 | };
98 |
99 | // Context data
100 | const authContextData = { loginUser, registerUser, logoutUser, authState };
101 |
102 | // Return provider
103 | return (
104 |
105 | {children}
106 |
107 | );
108 | };
109 |
110 | export default AuthContextProvider;
111 |
--------------------------------------------------------------------------------
/client/src/contexts/PostContext.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { createContext, useReducer, useState } from "react";
3 | import { postReducer } from "../reducers/postReducer";
4 | import {
5 | ADD_POST,
6 | apiUrl,
7 | DELETE_POST,
8 | FIND_POST,
9 | POSTS_LOADED_FAIL,
10 | POSTS_LOADED_SUCCESS,
11 | UPDATE_POST,
12 | } from "./constants";
13 |
14 | export const PostContext = createContext();
15 |
16 | const PostContextProvider = ({ children }) => {
17 | // State
18 | const [postState, dispatch] = useReducer(postReducer, {
19 | post: null,
20 | posts: [],
21 | postsLoading: true,
22 | });
23 |
24 | const [showAddPostModal, setShowAddPostModal] = useState(false);
25 | const [showUpdatePostModal, setShowUpdatePostModal] = useState(false);
26 | const [showToast, setShowToast] = useState({
27 | show: false,
28 | message: "",
29 | type: null,
30 | });
31 |
32 | // Get all posts
33 | const getPosts = async () => {
34 | try {
35 | const response = await axios.get(`${apiUrl}/posts`);
36 | if (response.data.success) {
37 | dispatch({ type: POSTS_LOADED_SUCCESS, payload: response.data.posts });
38 | }
39 | } catch (error) {
40 | dispatch({ type: POSTS_LOADED_FAIL });
41 | }
42 | };
43 |
44 | // Add post
45 | const addPost = async (newPost) => {
46 | try {
47 | const response = await axios.post(`${apiUrl}/posts`, newPost);
48 | if (response.data.success) {
49 | dispatch({ type: ADD_POST, payload: response.data.post });
50 | return response.data;
51 | }
52 | } catch (error) {
53 | return error.response.data
54 | ? error.response.data
55 | : { success: false, message: "Server error" };
56 | }
57 | };
58 |
59 | // Delete post
60 | const deletePost = async (postId) => {
61 | try {
62 | const response = await axios.delete(`${apiUrl}/posts/${postId}`);
63 | if (response.data.success)
64 | dispatch({ type: DELETE_POST, payload: postId });
65 | } catch (error) {
66 | console.log(error);
67 | }
68 | };
69 |
70 | // Find post when user is updating post
71 | const findPost = (postId) => {
72 | const post = postState.posts.find((post) => post._id === postId);
73 | dispatch({ type: FIND_POST, payload: post });
74 | };
75 |
76 | // Update post
77 | const updatePost = async (updatedPost) => {
78 | try {
79 | const response = await axios.put(
80 | `${apiUrl}/posts/${updatedPost._id}`,
81 | updatedPost
82 | );
83 | if (response.data.success) {
84 | dispatch({ type: UPDATE_POST, payload: response.data.post });
85 | return response.data;
86 | }
87 | } catch (error) {
88 | return error.response.data
89 | ? error.response.data
90 | : { success: false, message: "Server error" };
91 | }
92 | };
93 |
94 | // Post context data
95 | const postContextData = {
96 | postState,
97 | getPosts,
98 | showAddPostModal,
99 | setShowAddPostModal,
100 | showUpdatePostModal,
101 | setShowUpdatePostModal,
102 | addPost,
103 | showToast,
104 | setShowToast,
105 | deletePost,
106 | findPost,
107 | updatePost,
108 | };
109 |
110 | return (
111 |
112 | {children}
113 |
114 | );
115 | };
116 |
117 | export default PostContextProvider;
118 |
--------------------------------------------------------------------------------
/client/src/contexts/constants.js:
--------------------------------------------------------------------------------
1 | export const apiUrl =
2 | process.env.NODE_ENV !== "production" ? `http://localhost:5000/api` : ``;
3 |
4 | export const LOCAL_STORAGE_TOKEN_NAME = `learnit_mern`;
5 |
6 | export const SET_AUTH = "SET_AUTH";
7 | export const POSTS_LOADED_SUCCESS = "POSTS_LOADED_SUCCESS";
8 | export const POSTS_LOADED_FAIL = "POSTS_LOADED_FAIL";
9 | export const ADD_POST = 'ADD_POST'
10 | export const DELETE_POST = 'DELETE_POST'
11 | export const UPDATE_POST = 'UPDATE_POST'
12 | export const FIND_POST = 'FIND_POST'
--------------------------------------------------------------------------------
/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/reducers/authReducer.js:
--------------------------------------------------------------------------------
1 | import { SET_AUTH } from '../contexts/constants'
2 |
3 | export const authReducer = (state, action) => {
4 | const {
5 | type,
6 | payload: { isAuthenticated, user },
7 | } = action;
8 |
9 | switch (type) {
10 | case SET_AUTH:
11 | return {
12 | ...state,
13 | authLoading: false,
14 | isAuthenticated,
15 | user,
16 | };
17 |
18 | default:
19 | return state;
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/client/src/reducers/postReducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | ADD_POST,
3 | DELETE_POST, FIND_POST, POSTS_LOADED_FAIL, POSTS_LOADED_SUCCESS, UPDATE_POST
4 | } from '../contexts/constants';
5 |
6 | export const postReducer = (state, action) => {
7 | const { type, payload } = action;
8 |
9 | switch (type) {
10 | case POSTS_LOADED_SUCCESS:
11 | return {
12 | ...state,
13 | posts: payload,
14 | postsLoading: false,
15 | };
16 |
17 | case POSTS_LOADED_FAIL:
18 | return {
19 | ...state,
20 | posts: [],
21 | postsLoading: false,
22 | };
23 |
24 | case ADD_POST:
25 | return {
26 | ...state,
27 | posts: [...state.posts, payload],
28 | };
29 |
30 | case DELETE_POST:
31 | return {
32 | ...state,
33 | posts: state.posts.filter((post) => post._id !== payload),
34 | };
35 |
36 | case FIND_POST:
37 | return { ...state, post: payload };
38 |
39 | case UPDATE_POST:
40 | const newPosts = state.posts.map((post) =>
41 | post._id === payload._id ? payload : post
42 | );
43 |
44 | return {
45 | ...state,
46 | posts: newPosts,
47 | };
48 |
49 | default:
50 | return state;
51 | }
52 | };
53 |
--------------------------------------------------------------------------------
/client/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/client/src/utils/setAuthToken.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | const setAuthToken = (token) => {
4 | if (token) {
5 | axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
6 | } else {
7 | delete axios.defaults.headers.common["Authorization"];
8 | }
9 | };
10 |
11 | export default setAuthToken;
12 |
--------------------------------------------------------------------------------
/client/src/views/About.js:
--------------------------------------------------------------------------------
1 | import Button from "react-bootstrap/Button";
2 | import Row from "react-bootstrap/Row";
3 | import Col from "react-bootstrap/Col";
4 |
5 | const About = () => {
6 | return (
7 |
8 |
9 |
12 |
13 |
14 | );
15 | };
16 |
17 | export default About;
18 |
--------------------------------------------------------------------------------
/client/src/views/Auth.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { Spinner } from "react-bootstrap";
3 | import { Redirect } from "react-router";
4 | import LoginForm from "../components/auth/LoginForm";
5 | import RegisterForm from "../components/auth/RegisterForm";
6 | import { AuthContext } from "../contexts/AuthContext";
7 |
8 | const Auth = ({ authRoute }) => {
9 | const {
10 | authState: { authLoading, isAuthenticated },
11 | } = useContext(AuthContext);
12 |
13 | let body;
14 |
15 | if (authLoading) {
16 | body = (
17 |
18 |
19 |
20 | );
21 | } else if (isAuthenticated) {
22 | return ;
23 | } else {
24 | body = (
25 | <>
26 | {authRoute === "login" && }
27 | {authRoute === "register" && }
28 | >
29 | );
30 | }
31 |
32 | return (
33 |
34 |
35 |
36 |
LearnIt
37 | Keep track of what you are learning
38 | {body}
39 |
40 |
41 |
42 | );
43 | };
44 |
45 | export default Auth;
46 |
--------------------------------------------------------------------------------
/client/src/views/Dashboard.js:
--------------------------------------------------------------------------------
1 | import { PostContext } from "../contexts/PostContext";
2 | import { AuthContext } from "../contexts/AuthContext";
3 | import { useContext, useEffect } from "react";
4 | import {
5 | Spinner,
6 | Button,
7 | Card,
8 | Row,
9 | Toast,
10 | OverlayTrigger,
11 | Tooltip,
12 | Col,
13 | } from "react-bootstrap";
14 | import SinglePost from "../components/posts/SinglePost";
15 | import AddPostModal from "../components/posts/AddPostModal";
16 | import UpdatePostModal from "../components/posts/UpdatePostModal";
17 | import addIcon from "../assets/plus-circle-fill.svg";
18 |
19 | const Dashboard = () => {
20 | // Contexts
21 | const {
22 | authState: {
23 | user: { username },
24 | },
25 | } = useContext(AuthContext);
26 |
27 | const {
28 | postState: { post, posts, postsLoading },
29 | getPosts,
30 | setShowAddPostModal,
31 | showToast: { show, message, type },
32 | setShowToast,
33 | } = useContext(PostContext);
34 |
35 | // Get all posts
36 | // eslint-disable-next-line react-hooks/exhaustive-deps
37 | useEffect(() => getPosts(), []);
38 |
39 | let body = null;
40 |
41 | if (postsLoading) {
42 | body = (
43 |
44 |
45 |
46 | );
47 | } else if (posts.length === 0) {
48 | body = (
49 | <>
50 |
51 | Hi {username}
52 |
53 | Welcome to LearnIt
54 |
55 | Click the button below to track your first skill to learn
56 |
57 |
63 |
64 |
65 | >
66 | );
67 | } else {
68 | body = (
69 | <>
70 |
71 | {posts.map((post) => (
72 |
73 |
74 |
75 | ))}
76 |
77 |
78 | {/* Open Add Post Modal */}
79 | Add a new thing to learn}
82 | >
83 |
89 |
90 | >
91 | );
92 | }
93 |
94 | return (
95 | <>
96 | {body}
97 |
98 | {post !== null && }
99 | {/* After post is added, show toast */}
100 |
112 |
113 | {message}
114 |
115 |
116 | >
117 | );
118 | };
119 |
120 | export default Dashboard;
121 |
--------------------------------------------------------------------------------
/screenshots/screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/screenshots/screenshot_1.png
--------------------------------------------------------------------------------
/screenshots/screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/screenshots/screenshot_2.png
--------------------------------------------------------------------------------
/screenshots/screenshot_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/screenshots/screenshot_3.png
--------------------------------------------------------------------------------
/screenshots/screenshot_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/screenshots/screenshot_4.png
--------------------------------------------------------------------------------
/screenshots/screenshot_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/screenshots/screenshot_5.png
--------------------------------------------------------------------------------
/screenshots/screenshot_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendy199x/MERN-Stack/a459fe84ed7723c3b37fcedc77ea2ec411e0eec6/screenshots/screenshot_6.png
--------------------------------------------------------------------------------
/server/.env:
--------------------------------------------------------------------------------
1 | PORT=5000
2 | SESSION_DB_USERNAME=zendy
3 | SESSION_DB_PASSWORD=zendy
4 | ACCESS_TOKEN_SECRET=abcxyz
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mern-server",
3 | "version": "1.0.0",
4 | "description": "MERN server",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "server": "nodemon src/index"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/zendy199x/MERN-Stack.git"
13 | },
14 | "author": "Zendy",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/zendy199x/MERN-Stack/issues"
18 | },
19 | "homepage": "https://github.com/zendy199x/MERN-Stack#readme",
20 | "dependencies": {
21 | "argon2": "^0.28.2",
22 | "cors": "^2.8.5",
23 | "dotenv": "^10.0.0",
24 | "express": "^4.17.1",
25 | "jsonwebtoken": "^8.5.1",
26 | "mongoose": "5.13.8"
27 | },
28 | "devDependencies": {
29 | "nodemon": "^2.0.12"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/server/request.http:
--------------------------------------------------------------------------------
1 | # GET http://localhost:5000
2 |
3 | # Register
4 | POST http://localhost:5000/api/auth/register
5 | Content-Type: application/json
6 |
7 | {
8 | "username": "zendy1",
9 | "password": "zendy"
10 | }
11 |
12 | ###
13 |
14 | # Login
15 | POST http://localhost:5000/api/auth/login
16 | Content-Type: application/json
17 |
18 | {
19 | "username": "zendy1",
20 | "password": "zendy"
21 | }
22 |
23 | ###
24 |
25 | # Create post
26 | POST http://localhost:5000/api/posts
27 | Content-Type: application/json
28 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTMyNGFiN2JkNTdiNmNlOWYwYmRjZTgiLCJpYXQiOjE2MzA2ODc0NTN9.riX9Ln4wwMOwF3CheCn4Rw3IsZscgt1SVyx8rqewjYE
29 |
30 | {
31 | "title": "title 2",
32 | "description": "description 2",
33 | "url": "gooogle.com",
34 | "status": "LEARNING"
35 | }
36 |
37 | ###
38 |
39 | # Get post
40 | GET http://localhost:5000/api/posts
41 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTMyNGFiN2JkNTdiNmNlOWYwYmRjZTgiLCJpYXQiOjE2MzA2ODc0NTN9.riX9Ln4wwMOwF3CheCn4Rw3IsZscgt1SVyx8rqewjYE
42 |
43 |
44 | ###
45 |
46 | # Update post
47 | PUT http://localhost:5000/api/posts/61324ac8bd57b6ce9f0bdceb
48 | Content-Type: application/json
49 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTMyNGFiN2JkNTdiNmNlOWYwYmRjZTgiLCJpYXQiOjE2MzA2ODc0NTN9.riX9Ln4wwMOwF3CheCn4Rw3IsZscgt1SVyx8rqewjYE
50 |
51 | {
52 | "title": "Vue",
53 | "description": "Learn Vue",
54 | "url": "youtube.com",
55 | "status": "LEARNING"
56 | }
57 |
58 |
59 | ###
60 |
61 | # Delete post
62 | DELETE http://localhost:5000/api/posts/613252260ae41dd672f5ed36
63 | Content-Type: application/json
64 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTMyNGFiN2JkNTdiNmNlOWYwYmRjZTgiLCJpYXQiOjE2MzA2ODc0NTN9.riX9Ln4wwMOwF3CheCn4Rw3IsZscgt1SVyx8rqewjYE
65 |
--------------------------------------------------------------------------------
/server/src/config/db.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const mongoUrl = `mongodb+srv://${process.env.SESSION_DB_USERNAME}:${process.env.SESSION_DB_PASSWORD}@cluster0.bbsjh.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`
4 |
5 | const connectDB = async () => {
6 | try {
7 | await mongoose.connect(mongoUrl, {
8 | useCreateIndex: true,
9 | useNewUrlParser: true,
10 | useUnifiedTopology: true,
11 | useFindAndModify: false,
12 | }),
13 | console.log(`MongoDB connected`);
14 | } catch (error) {
15 | console.log(error.message);
16 | process.exit(1); // error code
17 | }
18 | };
19 |
20 | module.exports = connectDB;
21 |
--------------------------------------------------------------------------------
/server/src/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const cors = require("cors");
3 | require("dotenv").config();
4 | const connectDB = require("./config/db");
5 |
6 | const authRouter = require("./routers/auth");
7 | const postRouter = require("./routers/post");
8 |
9 | // start app
10 | const app = express();
11 | app.use(express.json());
12 | app.use(cors());
13 |
14 | // connect DB
15 | connectDB();
16 |
17 | app.use("/api/auth", authRouter);
18 | app.use("/api/posts", postRouter);
19 |
20 | const PORT = process.env.PORT || 5000;
21 |
22 | app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
23 |
--------------------------------------------------------------------------------
/server/src/middleware/auth.js:
--------------------------------------------------------------------------------
1 | const jwt = require("jsonwebtoken");
2 |
3 | // Authorization = Bearer abcxyz
4 |
5 | const verifyToken = (req, res, next) => {
6 | const authHeader = req.header("Authorization");
7 | const token = authHeader && authHeader.split(" ")[1];
8 |
9 | if (!token)
10 | return res
11 | .status(401)
12 | .json({ success: false, message: "Access token not found" });
13 |
14 | try {
15 | const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
16 |
17 | req.userId = decoded.userId;
18 | next();
19 | } catch (error) {
20 | console.log(error);
21 | return res.status(403).json({ success: false, message: "Invalid token" });
22 | }
23 | };
24 |
25 | module.exports = verifyToken;
26 |
--------------------------------------------------------------------------------
/server/src/models/Post.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const PostSchema = new Schema({
5 | title: {
6 | type: String,
7 | require: true,
8 | },
9 | description: {
10 | type: String,
11 | },
12 | url: {
13 | type: String,
14 | },
15 | status: {
16 | type: String,
17 | enum: ["TO LEARN", "LEARNING", "LEARNED"],
18 | },
19 | user: {
20 | type: Schema.Types.ObjectId,
21 | ref: "users",
22 | },
23 | });
24 |
25 | module.exports = mongoose.model("posts", PostSchema);
26 |
--------------------------------------------------------------------------------
/server/src/models/User.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const UserSchema = new Schema({
5 | username: {
6 | type: String,
7 | required: true,
8 | unique: true,
9 | },
10 | password: {
11 | type: String,
12 | required: true,
13 | },
14 | createdAt: {
15 | type: Date,
16 | default: Date.now(),
17 | },
18 | });
19 |
20 | module.exports = mongoose.model("users", UserSchema);
21 |
--------------------------------------------------------------------------------
/server/src/routers/auth.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const argon2 = require("argon2");
3 | const jwt = require("jsonwebtoken");
4 | const verifyToken = require("../middleware/auth");
5 |
6 | const router = express.Router();
7 |
8 | const User = require("../models/User");
9 |
10 | // @route GET api/auth
11 | // @desc Check if user is logged in
12 | // @access Public
13 | router.get("/", verifyToken, async (req, res) => {
14 | try {
15 | const user = await User.findById(req.userId).select("-password");
16 | if (!user)
17 | return res
18 | .status(400)
19 | .json({ success: false, message: "User not found" });
20 |
21 | res.json({ success: true, user });
22 | } catch (error) {
23 | console.log(error);
24 | res.status(500).json({ success: false, message: `Internal server error` });
25 | }
26 | });
27 |
28 | // @route POST api/auth/register
29 | // @desc Register user
30 | // @access Public
31 | router.post("/register", async (req, res) => {
32 | const { username, password } = req.body;
33 |
34 | // Simple validation
35 | if (!username || !password) {
36 | return res
37 | .status(400)
38 | .json({ success: false, message: "Missing username and/or password" });
39 | }
40 |
41 | try {
42 | // Check for existing user
43 | const user = await User.findOne({ username });
44 |
45 | if (user)
46 | return res
47 | .status(400)
48 | .json({ success: false, message: "User already taken" });
49 |
50 | // All good
51 | const hashedPassword = await argon2.hash(password);
52 | const newUser = new User({ username, password: hashedPassword });
53 |
54 | await newUser.save();
55 |
56 | // Return token
57 | const accessToken = jwt.sign(
58 | { userId: newUser._id },
59 | process.env.ACCESS_TOKEN_SECRET
60 | );
61 |
62 | res.json({
63 | success: true,
64 | message: `User created successfully`,
65 | accessToken,
66 | });
67 | } catch (error) {
68 | console.log(error);
69 | res.status(500).json({ success: false, message: `Internal server error` });
70 | }
71 | });
72 |
73 | // @route POST api/auth/login
74 | // @desc Login user
75 | // @access Public
76 | router.post("/login", async (req, res) => {
77 | const { username, password } = req.body;
78 | if (!username || !password)
79 | return res
80 | .status(400)
81 | .json({ success: false, message: "Missing username and/or password" });
82 |
83 | try {
84 | // Check for existing user
85 | const user = await User.findOne({ username });
86 | if (!user)
87 | return res
88 | .status(400)
89 | .json({ success: false, message: "Incorrect username or password" });
90 |
91 | // Username found
92 | const passwordValid = await argon2.verify(user.password, password);
93 | if (!passwordValid)
94 | return res
95 | .status(400)
96 | .json({ success: false, message: "Incorrect username or password" });
97 |
98 | // All good
99 | const accessToken = jwt.sign(
100 | { userId: user._id },
101 | process.env.ACCESS_TOKEN_SECRET
102 | );
103 |
104 | res.json({
105 | success: true,
106 | message: `User logged in successfully`,
107 | accessToken,
108 | });
109 | } catch (error) {
110 | console.log(error);
111 | res.status(500).json({ success: false, message: `Internal server error` });
112 | }
113 | });
114 |
115 | module.exports = router;
116 |
--------------------------------------------------------------------------------
/server/src/routers/post.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const verifyToken = require("../middleware/auth");
4 |
5 | const Post = require("../models/Post");
6 |
7 | // @routes GET api/posts
8 | // @desc Get post
9 | // @access Private
10 | router.get("/", verifyToken, async (req, res) => {
11 | try {
12 | const posts = await Post.find({ user: req.userId }).populate("user", [
13 | "username",
14 | ]);
15 | res.json({ success: true, posts });
16 | } catch (error) {
17 | console.log(error);
18 | res.status(500).json({ success: false, message: `Internal server error` });
19 | }
20 | });
21 |
22 | // @routes POST api/posts
23 | // @desc Create post
24 | // @access Private
25 | router.post("/", verifyToken, async (req, res) => {
26 | const { title, description, url, status } = req.body;
27 |
28 | // Simple validation
29 | if (!title)
30 | return res
31 | .status(400)
32 | .json({ success: false, message: "Title is required" });
33 |
34 | try {
35 | const newPost = new Post({
36 | title,
37 | description,
38 | url: url.startsWith("https://") ? url : `https://${url}`,
39 | status: status || "TO LEARN",
40 | user: req.userId,
41 | });
42 |
43 | await newPost.save();
44 |
45 | res.json({ success: true, message: "Happy learning!", post: newPost });
46 | } catch (error) {
47 | console.log(error);
48 | res.status(500).json({ success: false, message: `Internal server error` });
49 | }
50 | });
51 |
52 | // @routes PUT api/posts
53 | // @desc Update post
54 | // @access Private
55 | router.put("/:id", verifyToken, async (req, res) => {
56 | const { title, description, url, status } = req.body;
57 |
58 | // Simple validation
59 | if (!title)
60 | return res
61 | .status(400)
62 | .json({ success: false, message: "Title is required" });
63 |
64 | try {
65 | let updatedPost = {
66 | title,
67 | description: description || "",
68 | url: (url.startsWith("https://") ? url : `https://${url}`) || "",
69 | status: status || "TO LEARN",
70 | };
71 |
72 | const postUpdateCondition = { _id: req.params.id, user: req.userId };
73 |
74 | updatedPost = await Post.findOneAndUpdate(
75 | postUpdateCondition,
76 | updatedPost,
77 | { new: true }
78 | );
79 |
80 | // User not authorised to update post or post not found
81 | if (!updatedPost)
82 | return res.status(401).json({
83 | success: false,
84 | message: "Post not found or user not authorised",
85 | });
86 |
87 | res.json({
88 | success: true,
89 | message: "Excellent progress!",
90 | post: updatedPost,
91 | });
92 | } catch (error) {
93 | console.log(error);
94 | res.status(500).json({ success: false, message: "Internal server error" });
95 | }
96 | });
97 |
98 | // @route DELETE api/posts
99 | // @desc Delete post
100 | // @access Private
101 | router.delete("/:id", verifyToken, async (req, res) => {
102 | try {
103 | const postDeleteCondition = { _id: req.params.id, user: req.userId };
104 | const deletedPost = await Post.findOneAndDelete(postDeleteCondition);
105 |
106 | // User not authorised or post not found
107 | if (!deletedPost)
108 | return res.status(401).json({
109 | success: false,
110 | message: "Post not found or user not authorised",
111 | });
112 |
113 | res.json({ success: true, post: deletedPost });
114 | } catch (error) {
115 | console.log(error);
116 | res.status(500).json({ success: false, message: "Internal server error" });
117 | }
118 | });
119 |
120 | module.exports = router;
121 |
--------------------------------------------------------------------------------
/server/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@mapbox/node-pre-gyp@^1.0.1":
6 | version "1.0.5"
7 | resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950"
8 | integrity sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==
9 | dependencies:
10 | detect-libc "^1.0.3"
11 | https-proxy-agent "^5.0.0"
12 | make-dir "^3.1.0"
13 | node-fetch "^2.6.1"
14 | nopt "^5.0.0"
15 | npmlog "^4.1.2"
16 | rimraf "^3.0.2"
17 | semver "^7.3.4"
18 | tar "^6.1.0"
19 |
20 | "@phc/format@^1.0.0":
21 | version "1.0.0"
22 | resolved "https://registry.yarnpkg.com/@phc/format/-/format-1.0.0.tgz#b5627003b3216dc4362125b13f48a4daa76680e4"
23 | integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==
24 |
25 | "@sindresorhus/is@^0.14.0":
26 | version "0.14.0"
27 | resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
28 | integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
29 |
30 | "@szmarczak/http-timer@^1.1.2":
31 | version "1.1.2"
32 | resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
33 | integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
34 | dependencies:
35 | defer-to-connect "^1.0.1"
36 |
37 | "@types/bson@*":
38 | version "4.2.0"
39 | resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.2.0.tgz#a2f71e933ff54b2c3bf267b67fa221e295a33337"
40 | integrity sha512-ELCPqAdroMdcuxqwMgUpifQyRoTpyYCNr1V9xKyF40VsBobsj+BbWNRvwGchMgBPGqkw655ypkjj2MEF5ywVwg==
41 | dependencies:
42 | bson "*"
43 |
44 | "@types/mongodb@^3.5.27":
45 | version "3.6.20"
46 | resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.6.20.tgz#b7c5c580644f6364002b649af1c06c3c0454e1d2"
47 | integrity sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==
48 | dependencies:
49 | "@types/bson" "*"
50 | "@types/node" "*"
51 |
52 | "@types/node@*":
53 | version "16.7.10"
54 | resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.10.tgz#7aa732cc47341c12a16b7d562f519c2383b6d4fc"
55 | integrity sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==
56 |
57 | abbrev@1:
58 | version "1.1.1"
59 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
60 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
61 |
62 | accepts@~1.3.7:
63 | version "1.3.7"
64 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
65 | integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
66 | dependencies:
67 | mime-types "~2.1.24"
68 | negotiator "0.6.2"
69 |
70 | agent-base@6:
71 | version "6.0.2"
72 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
73 | integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
74 | dependencies:
75 | debug "4"
76 |
77 | ansi-align@^3.0.0:
78 | version "3.0.0"
79 | resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
80 | integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==
81 | dependencies:
82 | string-width "^3.0.0"
83 |
84 | ansi-regex@^2.0.0:
85 | version "2.1.1"
86 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
87 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
88 |
89 | ansi-regex@^3.0.0:
90 | version "3.0.0"
91 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
92 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
93 |
94 | ansi-regex@^4.1.0:
95 | version "4.1.0"
96 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
97 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
98 |
99 | ansi-regex@^5.0.0:
100 | version "5.0.0"
101 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
102 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
103 |
104 | ansi-styles@^4.1.0:
105 | version "4.3.0"
106 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
107 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
108 | dependencies:
109 | color-convert "^2.0.1"
110 |
111 | anymatch@~3.1.2:
112 | version "3.1.2"
113 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
114 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
115 | dependencies:
116 | normalize-path "^3.0.0"
117 | picomatch "^2.0.4"
118 |
119 | aproba@^1.0.3:
120 | version "1.2.0"
121 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
122 | integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
123 |
124 | are-we-there-yet@~1.1.2:
125 | version "1.1.7"
126 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146"
127 | integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==
128 | dependencies:
129 | delegates "^1.0.0"
130 | readable-stream "^2.0.6"
131 |
132 | argon2@^0.28.2:
133 | version "0.28.2"
134 | resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.28.2.tgz#b583e4ef5b052a83bfe146752844b9fa526dba29"
135 | integrity sha512-8oRk3kPlL0lLletENzhpbF9zoZJqvIHwTkjBseMrg1uD4gBMqhqnjJz1z3lEtwT0oqQAEkEwsEpsjaQBBRHcWw==
136 | dependencies:
137 | "@mapbox/node-pre-gyp" "^1.0.1"
138 | "@phc/format" "^1.0.0"
139 | node-addon-api "^3.0.2"
140 | opencollective-postinstall "^2.0.3"
141 |
142 | array-flatten@1.1.1:
143 | version "1.1.1"
144 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
145 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
146 |
147 | balanced-match@^1.0.0:
148 | version "1.0.2"
149 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
150 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
151 |
152 | base64-js@^1.3.1:
153 | version "1.5.1"
154 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
155 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
156 |
157 | binary-extensions@^2.0.0:
158 | version "2.2.0"
159 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
160 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
161 |
162 | bl@^2.2.1:
163 | version "2.2.1"
164 | resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5"
165 | integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==
166 | dependencies:
167 | readable-stream "^2.3.5"
168 | safe-buffer "^5.1.1"
169 |
170 | bluebird@3.5.1:
171 | version "3.5.1"
172 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
173 | integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==
174 |
175 | body-parser@1.19.0:
176 | version "1.19.0"
177 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
178 | integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
179 | dependencies:
180 | bytes "3.1.0"
181 | content-type "~1.0.4"
182 | debug "2.6.9"
183 | depd "~1.1.2"
184 | http-errors "1.7.2"
185 | iconv-lite "0.4.24"
186 | on-finished "~2.3.0"
187 | qs "6.7.0"
188 | raw-body "2.4.0"
189 | type-is "~1.6.17"
190 |
191 | boxen@^4.2.0:
192 | version "4.2.0"
193 | resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
194 | integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==
195 | dependencies:
196 | ansi-align "^3.0.0"
197 | camelcase "^5.3.1"
198 | chalk "^3.0.0"
199 | cli-boxes "^2.2.0"
200 | string-width "^4.1.0"
201 | term-size "^2.1.0"
202 | type-fest "^0.8.1"
203 | widest-line "^3.1.0"
204 |
205 | brace-expansion@^1.1.7:
206 | version "1.1.11"
207 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
208 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
209 | dependencies:
210 | balanced-match "^1.0.0"
211 | concat-map "0.0.1"
212 |
213 | braces@~3.0.2:
214 | version "3.0.2"
215 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
216 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
217 | dependencies:
218 | fill-range "^7.0.1"
219 |
220 | bson@*:
221 | version "4.5.1"
222 | resolved "https://registry.yarnpkg.com/bson/-/bson-4.5.1.tgz#02e9d649ce017ab14ed258737756c11809963d6c"
223 | integrity sha512-XqFP74pbTVLyLy5KFxVfTUyRrC1mgOlmu/iXHfXqfCKT59jyP9lwbotGfbN59cHBRbJSamZNkrSopjv+N0SqAA==
224 | dependencies:
225 | buffer "^5.6.0"
226 |
227 | bson@^1.1.4:
228 | version "1.1.6"
229 | resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a"
230 | integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==
231 |
232 | buffer-equal-constant-time@1.0.1:
233 | version "1.0.1"
234 | resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
235 | integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
236 |
237 | buffer@^5.6.0:
238 | version "5.7.1"
239 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
240 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
241 | dependencies:
242 | base64-js "^1.3.1"
243 | ieee754 "^1.1.13"
244 |
245 | bytes@3.1.0:
246 | version "3.1.0"
247 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
248 | integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
249 |
250 | cacheable-request@^6.0.0:
251 | version "6.1.0"
252 | resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
253 | integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
254 | dependencies:
255 | clone-response "^1.0.2"
256 | get-stream "^5.1.0"
257 | http-cache-semantics "^4.0.0"
258 | keyv "^3.0.0"
259 | lowercase-keys "^2.0.0"
260 | normalize-url "^4.1.0"
261 | responselike "^1.0.2"
262 |
263 | camelcase@^5.3.1:
264 | version "5.3.1"
265 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
266 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
267 |
268 | chalk@^3.0.0:
269 | version "3.0.0"
270 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
271 | integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
272 | dependencies:
273 | ansi-styles "^4.1.0"
274 | supports-color "^7.1.0"
275 |
276 | chokidar@^3.2.2:
277 | version "3.5.2"
278 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
279 | integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
280 | dependencies:
281 | anymatch "~3.1.2"
282 | braces "~3.0.2"
283 | glob-parent "~5.1.2"
284 | is-binary-path "~2.1.0"
285 | is-glob "~4.0.1"
286 | normalize-path "~3.0.0"
287 | readdirp "~3.6.0"
288 | optionalDependencies:
289 | fsevents "~2.3.2"
290 |
291 | chownr@^2.0.0:
292 | version "2.0.0"
293 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
294 | integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
295 |
296 | ci-info@^2.0.0:
297 | version "2.0.0"
298 | resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
299 | integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
300 |
301 | cli-boxes@^2.2.0:
302 | version "2.2.1"
303 | resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
304 | integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
305 |
306 | clone-response@^1.0.2:
307 | version "1.0.2"
308 | resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
309 | integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
310 | dependencies:
311 | mimic-response "^1.0.0"
312 |
313 | code-point-at@^1.0.0:
314 | version "1.1.0"
315 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
316 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
317 |
318 | color-convert@^2.0.1:
319 | version "2.0.1"
320 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
321 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
322 | dependencies:
323 | color-name "~1.1.4"
324 |
325 | color-name@~1.1.4:
326 | version "1.1.4"
327 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
328 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
329 |
330 | concat-map@0.0.1:
331 | version "0.0.1"
332 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
333 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
334 |
335 | configstore@^5.0.1:
336 | version "5.0.1"
337 | resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
338 | integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==
339 | dependencies:
340 | dot-prop "^5.2.0"
341 | graceful-fs "^4.1.2"
342 | make-dir "^3.0.0"
343 | unique-string "^2.0.0"
344 | write-file-atomic "^3.0.0"
345 | xdg-basedir "^4.0.0"
346 |
347 | console-control-strings@^1.0.0, console-control-strings@~1.1.0:
348 | version "1.1.0"
349 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
350 | integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
351 |
352 | content-disposition@0.5.3:
353 | version "0.5.3"
354 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
355 | integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
356 | dependencies:
357 | safe-buffer "5.1.2"
358 |
359 | content-type@~1.0.4:
360 | version "1.0.4"
361 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
362 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
363 |
364 | cookie-signature@1.0.6:
365 | version "1.0.6"
366 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
367 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
368 |
369 | cookie@0.4.0:
370 | version "0.4.0"
371 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
372 | integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
373 |
374 | core-util-is@~1.0.0:
375 | version "1.0.3"
376 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
377 | integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
378 |
379 | cors@^2.8.5:
380 | version "2.8.5"
381 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
382 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
383 | dependencies:
384 | object-assign "^4"
385 | vary "^1"
386 |
387 | crypto-random-string@^2.0.0:
388 | version "2.0.0"
389 | resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
390 | integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
391 |
392 | debug@2.6.9, debug@^2.2.0:
393 | version "2.6.9"
394 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
395 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
396 | dependencies:
397 | ms "2.0.0"
398 |
399 | debug@3.1.0:
400 | version "3.1.0"
401 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
402 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
403 | dependencies:
404 | ms "2.0.0"
405 |
406 | debug@4:
407 | version "4.3.2"
408 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
409 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
410 | dependencies:
411 | ms "2.1.2"
412 |
413 | debug@^3.2.6:
414 | version "3.2.7"
415 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
416 | integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
417 | dependencies:
418 | ms "^2.1.1"
419 |
420 | decompress-response@^3.3.0:
421 | version "3.3.0"
422 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
423 | integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
424 | dependencies:
425 | mimic-response "^1.0.0"
426 |
427 | deep-extend@^0.6.0:
428 | version "0.6.0"
429 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
430 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
431 |
432 | defer-to-connect@^1.0.1:
433 | version "1.1.3"
434 | resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
435 | integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
436 |
437 | delegates@^1.0.0:
438 | version "1.0.0"
439 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
440 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
441 |
442 | denque@^1.4.1:
443 | version "1.5.1"
444 | resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
445 | integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
446 |
447 | depd@~1.1.2:
448 | version "1.1.2"
449 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
450 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
451 |
452 | destroy@~1.0.4:
453 | version "1.0.4"
454 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
455 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
456 |
457 | detect-libc@^1.0.3:
458 | version "1.0.3"
459 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
460 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
461 |
462 | dot-prop@^5.2.0:
463 | version "5.3.0"
464 | resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
465 | integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
466 | dependencies:
467 | is-obj "^2.0.0"
468 |
469 | dotenv@^10.0.0:
470 | version "10.0.0"
471 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
472 | integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
473 |
474 | duplexer3@^0.1.4:
475 | version "0.1.4"
476 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
477 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
478 |
479 | ecdsa-sig-formatter@1.0.11:
480 | version "1.0.11"
481 | resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
482 | integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
483 | dependencies:
484 | safe-buffer "^5.0.1"
485 |
486 | ee-first@1.1.1:
487 | version "1.1.1"
488 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
489 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
490 |
491 | emoji-regex@^7.0.1:
492 | version "7.0.3"
493 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
494 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
495 |
496 | emoji-regex@^8.0.0:
497 | version "8.0.0"
498 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
499 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
500 |
501 | encodeurl@~1.0.2:
502 | version "1.0.2"
503 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
504 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
505 |
506 | end-of-stream@^1.1.0:
507 | version "1.4.4"
508 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
509 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
510 | dependencies:
511 | once "^1.4.0"
512 |
513 | escape-goat@^2.0.0:
514 | version "2.1.1"
515 | resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
516 | integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
517 |
518 | escape-html@~1.0.3:
519 | version "1.0.3"
520 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
521 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
522 |
523 | etag@~1.8.1:
524 | version "1.8.1"
525 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
526 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
527 |
528 | express@^4.17.1:
529 | version "4.17.1"
530 | resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
531 | integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
532 | dependencies:
533 | accepts "~1.3.7"
534 | array-flatten "1.1.1"
535 | body-parser "1.19.0"
536 | content-disposition "0.5.3"
537 | content-type "~1.0.4"
538 | cookie "0.4.0"
539 | cookie-signature "1.0.6"
540 | debug "2.6.9"
541 | depd "~1.1.2"
542 | encodeurl "~1.0.2"
543 | escape-html "~1.0.3"
544 | etag "~1.8.1"
545 | finalhandler "~1.1.2"
546 | fresh "0.5.2"
547 | merge-descriptors "1.0.1"
548 | methods "~1.1.2"
549 | on-finished "~2.3.0"
550 | parseurl "~1.3.3"
551 | path-to-regexp "0.1.7"
552 | proxy-addr "~2.0.5"
553 | qs "6.7.0"
554 | range-parser "~1.2.1"
555 | safe-buffer "5.1.2"
556 | send "0.17.1"
557 | serve-static "1.14.1"
558 | setprototypeof "1.1.1"
559 | statuses "~1.5.0"
560 | type-is "~1.6.18"
561 | utils-merge "1.0.1"
562 | vary "~1.1.2"
563 |
564 | fill-range@^7.0.1:
565 | version "7.0.1"
566 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
567 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
568 | dependencies:
569 | to-regex-range "^5.0.1"
570 |
571 | finalhandler@~1.1.2:
572 | version "1.1.2"
573 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
574 | integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
575 | dependencies:
576 | debug "2.6.9"
577 | encodeurl "~1.0.2"
578 | escape-html "~1.0.3"
579 | on-finished "~2.3.0"
580 | parseurl "~1.3.3"
581 | statuses "~1.5.0"
582 | unpipe "~1.0.0"
583 |
584 | forwarded@0.2.0:
585 | version "0.2.0"
586 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
587 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
588 |
589 | fresh@0.5.2:
590 | version "0.5.2"
591 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
592 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
593 |
594 | fs-minipass@^2.0.0:
595 | version "2.1.0"
596 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
597 | integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
598 | dependencies:
599 | minipass "^3.0.0"
600 |
601 | fs.realpath@^1.0.0:
602 | version "1.0.0"
603 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
604 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
605 |
606 | fsevents@~2.3.2:
607 | version "2.3.2"
608 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
609 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
610 |
611 | gauge@~2.7.3:
612 | version "2.7.4"
613 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
614 | integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
615 | dependencies:
616 | aproba "^1.0.3"
617 | console-control-strings "^1.0.0"
618 | has-unicode "^2.0.0"
619 | object-assign "^4.1.0"
620 | signal-exit "^3.0.0"
621 | string-width "^1.0.1"
622 | strip-ansi "^3.0.1"
623 | wide-align "^1.1.0"
624 |
625 | get-stream@^4.1.0:
626 | version "4.1.0"
627 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
628 | integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
629 | dependencies:
630 | pump "^3.0.0"
631 |
632 | get-stream@^5.1.0:
633 | version "5.2.0"
634 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
635 | integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
636 | dependencies:
637 | pump "^3.0.0"
638 |
639 | glob-parent@~5.1.2:
640 | version "5.1.2"
641 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
642 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
643 | dependencies:
644 | is-glob "^4.0.1"
645 |
646 | glob@^7.1.3:
647 | version "7.1.7"
648 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
649 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
650 | dependencies:
651 | fs.realpath "^1.0.0"
652 | inflight "^1.0.4"
653 | inherits "2"
654 | minimatch "^3.0.4"
655 | once "^1.3.0"
656 | path-is-absolute "^1.0.0"
657 |
658 | global-dirs@^2.0.1:
659 | version "2.1.0"
660 | resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d"
661 | integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==
662 | dependencies:
663 | ini "1.3.7"
664 |
665 | got@^9.6.0:
666 | version "9.6.0"
667 | resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
668 | integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
669 | dependencies:
670 | "@sindresorhus/is" "^0.14.0"
671 | "@szmarczak/http-timer" "^1.1.2"
672 | cacheable-request "^6.0.0"
673 | decompress-response "^3.3.0"
674 | duplexer3 "^0.1.4"
675 | get-stream "^4.1.0"
676 | lowercase-keys "^1.0.1"
677 | mimic-response "^1.0.1"
678 | p-cancelable "^1.0.0"
679 | to-readable-stream "^1.0.0"
680 | url-parse-lax "^3.0.0"
681 |
682 | graceful-fs@^4.1.2:
683 | version "4.2.8"
684 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
685 | integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
686 |
687 | has-flag@^3.0.0:
688 | version "3.0.0"
689 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
690 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
691 |
692 | has-flag@^4.0.0:
693 | version "4.0.0"
694 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
695 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
696 |
697 | has-unicode@^2.0.0:
698 | version "2.0.1"
699 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
700 | integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
701 |
702 | has-yarn@^2.1.0:
703 | version "2.1.0"
704 | resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
705 | integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==
706 |
707 | http-cache-semantics@^4.0.0:
708 | version "4.1.0"
709 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
710 | integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
711 |
712 | http-errors@1.7.2:
713 | version "1.7.2"
714 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
715 | integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
716 | dependencies:
717 | depd "~1.1.2"
718 | inherits "2.0.3"
719 | setprototypeof "1.1.1"
720 | statuses ">= 1.5.0 < 2"
721 | toidentifier "1.0.0"
722 |
723 | http-errors@~1.7.2:
724 | version "1.7.3"
725 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
726 | integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
727 | dependencies:
728 | depd "~1.1.2"
729 | inherits "2.0.4"
730 | setprototypeof "1.1.1"
731 | statuses ">= 1.5.0 < 2"
732 | toidentifier "1.0.0"
733 |
734 | https-proxy-agent@^5.0.0:
735 | version "5.0.0"
736 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
737 | integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
738 | dependencies:
739 | agent-base "6"
740 | debug "4"
741 |
742 | iconv-lite@0.4.24:
743 | version "0.4.24"
744 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
745 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
746 | dependencies:
747 | safer-buffer ">= 2.1.2 < 3"
748 |
749 | ieee754@^1.1.13:
750 | version "1.2.1"
751 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
752 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
753 |
754 | ignore-by-default@^1.0.1:
755 | version "1.0.1"
756 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
757 | integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
758 |
759 | import-lazy@^2.1.0:
760 | version "2.1.0"
761 | resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
762 | integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
763 |
764 | imurmurhash@^0.1.4:
765 | version "0.1.4"
766 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
767 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
768 |
769 | inflight@^1.0.4:
770 | version "1.0.6"
771 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
772 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
773 | dependencies:
774 | once "^1.3.0"
775 | wrappy "1"
776 |
777 | inherits@2, inherits@2.0.4, inherits@~2.0.3:
778 | version "2.0.4"
779 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
780 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
781 |
782 | inherits@2.0.3:
783 | version "2.0.3"
784 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
785 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
786 |
787 | ini@1.3.7:
788 | version "1.3.7"
789 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
790 | integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
791 |
792 | ini@~1.3.0:
793 | version "1.3.8"
794 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
795 | integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
796 |
797 | ipaddr.js@1.9.1:
798 | version "1.9.1"
799 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
800 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
801 |
802 | is-binary-path@~2.1.0:
803 | version "2.1.0"
804 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
805 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
806 | dependencies:
807 | binary-extensions "^2.0.0"
808 |
809 | is-ci@^2.0.0:
810 | version "2.0.0"
811 | resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
812 | integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
813 | dependencies:
814 | ci-info "^2.0.0"
815 |
816 | is-extglob@^2.1.1:
817 | version "2.1.1"
818 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
819 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
820 |
821 | is-fullwidth-code-point@^1.0.0:
822 | version "1.0.0"
823 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
824 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
825 | dependencies:
826 | number-is-nan "^1.0.0"
827 |
828 | is-fullwidth-code-point@^2.0.0:
829 | version "2.0.0"
830 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
831 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
832 |
833 | is-fullwidth-code-point@^3.0.0:
834 | version "3.0.0"
835 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
836 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
837 |
838 | is-glob@^4.0.1, is-glob@~4.0.1:
839 | version "4.0.1"
840 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
841 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
842 | dependencies:
843 | is-extglob "^2.1.1"
844 |
845 | is-installed-globally@^0.3.1:
846 | version "0.3.2"
847 | resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141"
848 | integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==
849 | dependencies:
850 | global-dirs "^2.0.1"
851 | is-path-inside "^3.0.1"
852 |
853 | is-npm@^4.0.0:
854 | version "4.0.0"
855 | resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d"
856 | integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==
857 |
858 | is-number@^7.0.0:
859 | version "7.0.0"
860 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
861 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
862 |
863 | is-obj@^2.0.0:
864 | version "2.0.0"
865 | resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
866 | integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
867 |
868 | is-path-inside@^3.0.1:
869 | version "3.0.3"
870 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
871 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
872 |
873 | is-typedarray@^1.0.0:
874 | version "1.0.0"
875 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
876 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
877 |
878 | is-yarn-global@^0.3.0:
879 | version "0.3.0"
880 | resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
881 | integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
882 |
883 | isarray@~1.0.0:
884 | version "1.0.0"
885 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
886 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
887 |
888 | json-buffer@3.0.0:
889 | version "3.0.0"
890 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
891 | integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
892 |
893 | jsonwebtoken@^8.5.1:
894 | version "8.5.1"
895 | resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
896 | integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
897 | dependencies:
898 | jws "^3.2.2"
899 | lodash.includes "^4.3.0"
900 | lodash.isboolean "^3.0.3"
901 | lodash.isinteger "^4.0.4"
902 | lodash.isnumber "^3.0.3"
903 | lodash.isplainobject "^4.0.6"
904 | lodash.isstring "^4.0.1"
905 | lodash.once "^4.0.0"
906 | ms "^2.1.1"
907 | semver "^5.6.0"
908 |
909 | jwa@^1.4.1:
910 | version "1.4.1"
911 | resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
912 | integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
913 | dependencies:
914 | buffer-equal-constant-time "1.0.1"
915 | ecdsa-sig-formatter "1.0.11"
916 | safe-buffer "^5.0.1"
917 |
918 | jws@^3.2.2:
919 | version "3.2.2"
920 | resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
921 | integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
922 | dependencies:
923 | jwa "^1.4.1"
924 | safe-buffer "^5.0.1"
925 |
926 | kareem@2.3.2:
927 | version "2.3.2"
928 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.2.tgz#78c4508894985b8d38a0dc15e1a8e11078f2ca93"
929 | integrity sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==
930 |
931 | keyv@^3.0.0:
932 | version "3.1.0"
933 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
934 | integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
935 | dependencies:
936 | json-buffer "3.0.0"
937 |
938 | latest-version@^5.0.0:
939 | version "5.1.0"
940 | resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face"
941 | integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==
942 | dependencies:
943 | package-json "^6.3.0"
944 |
945 | lodash.includes@^4.3.0:
946 | version "4.3.0"
947 | resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
948 | integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
949 |
950 | lodash.isboolean@^3.0.3:
951 | version "3.0.3"
952 | resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
953 | integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
954 |
955 | lodash.isinteger@^4.0.4:
956 | version "4.0.4"
957 | resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
958 | integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
959 |
960 | lodash.isnumber@^3.0.3:
961 | version "3.0.3"
962 | resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
963 | integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
964 |
965 | lodash.isplainobject@^4.0.6:
966 | version "4.0.6"
967 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
968 | integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
969 |
970 | lodash.isstring@^4.0.1:
971 | version "4.0.1"
972 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
973 | integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
974 |
975 | lodash.once@^4.0.0:
976 | version "4.1.1"
977 | resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
978 | integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
979 |
980 | lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
981 | version "1.0.1"
982 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
983 | integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
984 |
985 | lowercase-keys@^2.0.0:
986 | version "2.0.0"
987 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
988 | integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
989 |
990 | lru-cache@^6.0.0:
991 | version "6.0.0"
992 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
993 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
994 | dependencies:
995 | yallist "^4.0.0"
996 |
997 | make-dir@^3.0.0, make-dir@^3.1.0:
998 | version "3.1.0"
999 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
1000 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
1001 | dependencies:
1002 | semver "^6.0.0"
1003 |
1004 | media-typer@0.3.0:
1005 | version "0.3.0"
1006 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
1007 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
1008 |
1009 | memory-pager@^1.0.2:
1010 | version "1.5.0"
1011 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
1012 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==
1013 |
1014 | merge-descriptors@1.0.1:
1015 | version "1.0.1"
1016 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
1017 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
1018 |
1019 | methods@~1.1.2:
1020 | version "1.1.2"
1021 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
1022 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
1023 |
1024 | mime-db@1.49.0:
1025 | version "1.49.0"
1026 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed"
1027 | integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==
1028 |
1029 | mime-types@~2.1.24:
1030 | version "2.1.32"
1031 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5"
1032 | integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==
1033 | dependencies:
1034 | mime-db "1.49.0"
1035 |
1036 | mime@1.6.0:
1037 | version "1.6.0"
1038 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
1039 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
1040 |
1041 | mimic-response@^1.0.0, mimic-response@^1.0.1:
1042 | version "1.0.1"
1043 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
1044 | integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
1045 |
1046 | minimatch@^3.0.4:
1047 | version "3.0.4"
1048 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
1049 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
1050 | dependencies:
1051 | brace-expansion "^1.1.7"
1052 |
1053 | minimist@^1.2.0:
1054 | version "1.2.5"
1055 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
1056 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
1057 |
1058 | minipass@^3.0.0:
1059 | version "3.1.3"
1060 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
1061 | integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==
1062 | dependencies:
1063 | yallist "^4.0.0"
1064 |
1065 | minizlib@^2.1.1:
1066 | version "2.1.2"
1067 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
1068 | integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
1069 | dependencies:
1070 | minipass "^3.0.0"
1071 | yallist "^4.0.0"
1072 |
1073 | mkdirp@^1.0.3:
1074 | version "1.0.4"
1075 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
1076 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
1077 |
1078 | mongodb@3.6.11:
1079 | version "3.6.11"
1080 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.11.tgz#8a59a0491a92b00a8c925f72ed9d9a5b054aebb2"
1081 | integrity sha512-4Y4lTFHDHZZdgMaHmojtNAlqkvddX2QQBEN0K//GzxhGwlI9tZ9R0vhbjr1Decw+TF7qK0ZLjQT292XgHRRQgw==
1082 | dependencies:
1083 | bl "^2.2.1"
1084 | bson "^1.1.4"
1085 | denque "^1.4.1"
1086 | optional-require "^1.0.3"
1087 | safe-buffer "^5.1.2"
1088 | optionalDependencies:
1089 | saslprep "^1.0.0"
1090 |
1091 | mongoose-legacy-pluralize@1.0.2:
1092 | version "1.0.2"
1093 | resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4"
1094 | integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==
1095 |
1096 | mongoose@5.13.8:
1097 | version "5.13.8"
1098 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.13.8.tgz#1477c306b9f1d1c737ad95ce1b4acac9aec4a421"
1099 | integrity sha512-z3d+qei9Dem/LxRcJi0cdGPKzQnYk71oHEsEfYm17JA/vLiAbJiGuBS2hW7vkd9afkPAqu3KsPZh2ax0c5iPQw==
1100 | dependencies:
1101 | "@types/mongodb" "^3.5.27"
1102 | bson "^1.1.4"
1103 | kareem "2.3.2"
1104 | mongodb "3.6.11"
1105 | mongoose-legacy-pluralize "1.0.2"
1106 | mpath "0.8.3"
1107 | mquery "3.2.5"
1108 | ms "2.1.2"
1109 | optional-require "1.0.x"
1110 | regexp-clone "1.0.0"
1111 | safe-buffer "5.2.1"
1112 | sift "13.5.2"
1113 | sliced "1.0.1"
1114 |
1115 | mpath@0.8.3:
1116 | version "0.8.3"
1117 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.8.3.tgz#828ac0d187f7f42674839d74921970979abbdd8f"
1118 | integrity sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==
1119 |
1120 | mquery@3.2.5:
1121 | version "3.2.5"
1122 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.2.5.tgz#8f2305632e4bb197f68f60c0cffa21aaf4060c51"
1123 | integrity sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==
1124 | dependencies:
1125 | bluebird "3.5.1"
1126 | debug "3.1.0"
1127 | regexp-clone "^1.0.0"
1128 | safe-buffer "5.1.2"
1129 | sliced "1.0.1"
1130 |
1131 | ms@2.0.0:
1132 | version "2.0.0"
1133 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
1134 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
1135 |
1136 | ms@2.1.1:
1137 | version "2.1.1"
1138 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
1139 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
1140 |
1141 | ms@2.1.2:
1142 | version "2.1.2"
1143 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
1144 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
1145 |
1146 | ms@^2.1.1:
1147 | version "2.1.3"
1148 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
1149 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
1150 |
1151 | negotiator@0.6.2:
1152 | version "0.6.2"
1153 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
1154 | integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
1155 |
1156 | node-addon-api@^3.0.2:
1157 | version "3.2.1"
1158 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
1159 | integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
1160 |
1161 | node-fetch@^2.6.1:
1162 | version "2.6.1"
1163 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
1164 | integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
1165 |
1166 | nodemon@^2.0.12:
1167 | version "2.0.12"
1168 | resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.12.tgz#5dae4e162b617b91f1873b3bfea215dd71e144d5"
1169 | integrity sha512-egCTmNZdObdBxUBw6ZNwvZ/xzk24CKRs5K6d+5zbmrMr7rOpPmfPeF6OxM3DDpaRx331CQRFEktn+wrFFfBSOA==
1170 | dependencies:
1171 | chokidar "^3.2.2"
1172 | debug "^3.2.6"
1173 | ignore-by-default "^1.0.1"
1174 | minimatch "^3.0.4"
1175 | pstree.remy "^1.1.7"
1176 | semver "^5.7.1"
1177 | supports-color "^5.5.0"
1178 | touch "^3.1.0"
1179 | undefsafe "^2.0.3"
1180 | update-notifier "^4.1.0"
1181 |
1182 | nopt@^5.0.0:
1183 | version "5.0.0"
1184 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"
1185 | integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==
1186 | dependencies:
1187 | abbrev "1"
1188 |
1189 | nopt@~1.0.10:
1190 | version "1.0.10"
1191 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
1192 | integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=
1193 | dependencies:
1194 | abbrev "1"
1195 |
1196 | normalize-path@^3.0.0, normalize-path@~3.0.0:
1197 | version "3.0.0"
1198 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
1199 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
1200 |
1201 | normalize-url@^4.1.0:
1202 | version "4.5.1"
1203 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
1204 | integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
1205 |
1206 | npmlog@^4.1.2:
1207 | version "4.1.2"
1208 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
1209 | integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
1210 | dependencies:
1211 | are-we-there-yet "~1.1.2"
1212 | console-control-strings "~1.1.0"
1213 | gauge "~2.7.3"
1214 | set-blocking "~2.0.0"
1215 |
1216 | number-is-nan@^1.0.0:
1217 | version "1.0.1"
1218 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
1219 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
1220 |
1221 | object-assign@^4, object-assign@^4.1.0:
1222 | version "4.1.1"
1223 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
1224 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
1225 |
1226 | on-finished@~2.3.0:
1227 | version "2.3.0"
1228 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
1229 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
1230 | dependencies:
1231 | ee-first "1.1.1"
1232 |
1233 | once@^1.3.0, once@^1.3.1, once@^1.4.0:
1234 | version "1.4.0"
1235 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
1236 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
1237 | dependencies:
1238 | wrappy "1"
1239 |
1240 | opencollective-postinstall@^2.0.3:
1241 | version "2.0.3"
1242 | resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
1243 | integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==
1244 |
1245 | optional-require@1.0.x:
1246 | version "1.0.3"
1247 | resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.0.3.tgz#275b8e9df1dc6a17ad155369c2422a440f89cb07"
1248 | integrity sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==
1249 |
1250 | optional-require@^1.0.3:
1251 | version "1.1.7"
1252 | resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.1.7.tgz#9ab5b254f59534108d4b2201d9ae96a063abc015"
1253 | integrity sha512-cIeRZocXsZnZYn+SevbtSqNlLbeoS4mLzuNn4fvXRMDRNhTGg0sxuKXl0FnZCtnew85LorNxIbZp5OeliILhMw==
1254 | dependencies:
1255 | require-at "^1.0.6"
1256 |
1257 | p-cancelable@^1.0.0:
1258 | version "1.1.0"
1259 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
1260 | integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
1261 |
1262 | package-json@^6.3.0:
1263 | version "6.5.0"
1264 | resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
1265 | integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==
1266 | dependencies:
1267 | got "^9.6.0"
1268 | registry-auth-token "^4.0.0"
1269 | registry-url "^5.0.0"
1270 | semver "^6.2.0"
1271 |
1272 | parseurl@~1.3.3:
1273 | version "1.3.3"
1274 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
1275 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
1276 |
1277 | path-is-absolute@^1.0.0:
1278 | version "1.0.1"
1279 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
1280 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
1281 |
1282 | path-to-regexp@0.1.7:
1283 | version "0.1.7"
1284 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
1285 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
1286 |
1287 | picomatch@^2.0.4, picomatch@^2.2.1:
1288 | version "2.3.0"
1289 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
1290 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
1291 |
1292 | prepend-http@^2.0.0:
1293 | version "2.0.0"
1294 | resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
1295 | integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
1296 |
1297 | process-nextick-args@~2.0.0:
1298 | version "2.0.1"
1299 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
1300 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
1301 |
1302 | proxy-addr@~2.0.5:
1303 | version "2.0.7"
1304 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
1305 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
1306 | dependencies:
1307 | forwarded "0.2.0"
1308 | ipaddr.js "1.9.1"
1309 |
1310 | pstree.remy@^1.1.7:
1311 | version "1.1.8"
1312 | resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
1313 | integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
1314 |
1315 | pump@^3.0.0:
1316 | version "3.0.0"
1317 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
1318 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
1319 | dependencies:
1320 | end-of-stream "^1.1.0"
1321 | once "^1.3.1"
1322 |
1323 | pupa@^2.0.1:
1324 | version "2.1.1"
1325 | resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62"
1326 | integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==
1327 | dependencies:
1328 | escape-goat "^2.0.0"
1329 |
1330 | qs@6.7.0:
1331 | version "6.7.0"
1332 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
1333 | integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
1334 |
1335 | range-parser@~1.2.1:
1336 | version "1.2.1"
1337 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
1338 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
1339 |
1340 | raw-body@2.4.0:
1341 | version "2.4.0"
1342 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
1343 | integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
1344 | dependencies:
1345 | bytes "3.1.0"
1346 | http-errors "1.7.2"
1347 | iconv-lite "0.4.24"
1348 | unpipe "1.0.0"
1349 |
1350 | rc@^1.2.8:
1351 | version "1.2.8"
1352 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
1353 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
1354 | dependencies:
1355 | deep-extend "^0.6.0"
1356 | ini "~1.3.0"
1357 | minimist "^1.2.0"
1358 | strip-json-comments "~2.0.1"
1359 |
1360 | readable-stream@^2.0.6, readable-stream@^2.3.5:
1361 | version "2.3.7"
1362 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
1363 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
1364 | dependencies:
1365 | core-util-is "~1.0.0"
1366 | inherits "~2.0.3"
1367 | isarray "~1.0.0"
1368 | process-nextick-args "~2.0.0"
1369 | safe-buffer "~5.1.1"
1370 | string_decoder "~1.1.1"
1371 | util-deprecate "~1.0.1"
1372 |
1373 | readdirp@~3.6.0:
1374 | version "3.6.0"
1375 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
1376 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
1377 | dependencies:
1378 | picomatch "^2.2.1"
1379 |
1380 | regexp-clone@1.0.0, regexp-clone@^1.0.0:
1381 | version "1.0.0"
1382 | resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63"
1383 | integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==
1384 |
1385 | registry-auth-token@^4.0.0:
1386 | version "4.2.1"
1387 | resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250"
1388 | integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==
1389 | dependencies:
1390 | rc "^1.2.8"
1391 |
1392 | registry-url@^5.0.0:
1393 | version "5.1.0"
1394 | resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009"
1395 | integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==
1396 | dependencies:
1397 | rc "^1.2.8"
1398 |
1399 | require-at@^1.0.6:
1400 | version "1.0.6"
1401 | resolved "https://registry.yarnpkg.com/require-at/-/require-at-1.0.6.tgz#9eb7e3c5e00727f5a4744070a7f560d4de4f6e6a"
1402 | integrity sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==
1403 |
1404 | responselike@^1.0.2:
1405 | version "1.0.2"
1406 | resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
1407 | integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
1408 | dependencies:
1409 | lowercase-keys "^1.0.0"
1410 |
1411 | rimraf@^3.0.2:
1412 | version "3.0.2"
1413 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
1414 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
1415 | dependencies:
1416 | glob "^7.1.3"
1417 |
1418 | safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
1419 | version "5.1.2"
1420 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
1421 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
1422 |
1423 | safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2:
1424 | version "5.2.1"
1425 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
1426 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
1427 |
1428 | "safer-buffer@>= 2.1.2 < 3":
1429 | version "2.1.2"
1430 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
1431 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
1432 |
1433 | saslprep@^1.0.0:
1434 | version "1.0.3"
1435 | resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
1436 | integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==
1437 | dependencies:
1438 | sparse-bitfield "^3.0.3"
1439 |
1440 | semver-diff@^3.1.1:
1441 | version "3.1.1"
1442 | resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
1443 | integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==
1444 | dependencies:
1445 | semver "^6.3.0"
1446 |
1447 | semver@^5.6.0, semver@^5.7.1:
1448 | version "5.7.1"
1449 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
1450 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
1451 |
1452 | semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
1453 | version "6.3.0"
1454 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
1455 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
1456 |
1457 | semver@^7.3.4:
1458 | version "7.3.5"
1459 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
1460 | integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
1461 | dependencies:
1462 | lru-cache "^6.0.0"
1463 |
1464 | send@0.17.1:
1465 | version "0.17.1"
1466 | resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
1467 | integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
1468 | dependencies:
1469 | debug "2.6.9"
1470 | depd "~1.1.2"
1471 | destroy "~1.0.4"
1472 | encodeurl "~1.0.2"
1473 | escape-html "~1.0.3"
1474 | etag "~1.8.1"
1475 | fresh "0.5.2"
1476 | http-errors "~1.7.2"
1477 | mime "1.6.0"
1478 | ms "2.1.1"
1479 | on-finished "~2.3.0"
1480 | range-parser "~1.2.1"
1481 | statuses "~1.5.0"
1482 |
1483 | serve-static@1.14.1:
1484 | version "1.14.1"
1485 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
1486 | integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
1487 | dependencies:
1488 | encodeurl "~1.0.2"
1489 | escape-html "~1.0.3"
1490 | parseurl "~1.3.3"
1491 | send "0.17.1"
1492 |
1493 | set-blocking@~2.0.0:
1494 | version "2.0.0"
1495 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
1496 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
1497 |
1498 | setprototypeof@1.1.1:
1499 | version "1.1.1"
1500 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
1501 | integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
1502 |
1503 | sift@13.5.2:
1504 | version "13.5.2"
1505 | resolved "https://registry.yarnpkg.com/sift/-/sift-13.5.2.tgz#24a715e13c617b086166cd04917d204a591c9da6"
1506 | integrity sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==
1507 |
1508 | signal-exit@^3.0.0, signal-exit@^3.0.2:
1509 | version "3.0.3"
1510 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
1511 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
1512 |
1513 | sliced@1.0.1:
1514 | version "1.0.1"
1515 | resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41"
1516 | integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=
1517 |
1518 | sparse-bitfield@^3.0.3:
1519 | version "3.0.3"
1520 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
1521 | integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE=
1522 | dependencies:
1523 | memory-pager "^1.0.2"
1524 |
1525 | "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
1526 | version "1.5.0"
1527 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
1528 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
1529 |
1530 | string-width@^1.0.1:
1531 | version "1.0.2"
1532 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
1533 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
1534 | dependencies:
1535 | code-point-at "^1.0.0"
1536 | is-fullwidth-code-point "^1.0.0"
1537 | strip-ansi "^3.0.0"
1538 |
1539 | "string-width@^1.0.2 || 2":
1540 | version "2.1.1"
1541 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
1542 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
1543 | dependencies:
1544 | is-fullwidth-code-point "^2.0.0"
1545 | strip-ansi "^4.0.0"
1546 |
1547 | string-width@^3.0.0:
1548 | version "3.1.0"
1549 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
1550 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
1551 | dependencies:
1552 | emoji-regex "^7.0.1"
1553 | is-fullwidth-code-point "^2.0.0"
1554 | strip-ansi "^5.1.0"
1555 |
1556 | string-width@^4.0.0, string-width@^4.1.0:
1557 | version "4.2.2"
1558 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
1559 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
1560 | dependencies:
1561 | emoji-regex "^8.0.0"
1562 | is-fullwidth-code-point "^3.0.0"
1563 | strip-ansi "^6.0.0"
1564 |
1565 | string_decoder@~1.1.1:
1566 | version "1.1.1"
1567 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
1568 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
1569 | dependencies:
1570 | safe-buffer "~5.1.0"
1571 |
1572 | strip-ansi@^3.0.0, strip-ansi@^3.0.1:
1573 | version "3.0.1"
1574 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
1575 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
1576 | dependencies:
1577 | ansi-regex "^2.0.0"
1578 |
1579 | strip-ansi@^4.0.0:
1580 | version "4.0.0"
1581 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
1582 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
1583 | dependencies:
1584 | ansi-regex "^3.0.0"
1585 |
1586 | strip-ansi@^5.1.0:
1587 | version "5.2.0"
1588 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
1589 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
1590 | dependencies:
1591 | ansi-regex "^4.1.0"
1592 |
1593 | strip-ansi@^6.0.0:
1594 | version "6.0.0"
1595 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
1596 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
1597 | dependencies:
1598 | ansi-regex "^5.0.0"
1599 |
1600 | strip-json-comments@~2.0.1:
1601 | version "2.0.1"
1602 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
1603 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
1604 |
1605 | supports-color@^5.5.0:
1606 | version "5.5.0"
1607 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
1608 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
1609 | dependencies:
1610 | has-flag "^3.0.0"
1611 |
1612 | supports-color@^7.1.0:
1613 | version "7.2.0"
1614 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
1615 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
1616 | dependencies:
1617 | has-flag "^4.0.0"
1618 |
1619 | tar@^6.1.0:
1620 | version "6.1.11"
1621 | resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
1622 | integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
1623 | dependencies:
1624 | chownr "^2.0.0"
1625 | fs-minipass "^2.0.0"
1626 | minipass "^3.0.0"
1627 | minizlib "^2.1.1"
1628 | mkdirp "^1.0.3"
1629 | yallist "^4.0.0"
1630 |
1631 | term-size@^2.1.0:
1632 | version "2.2.1"
1633 | resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
1634 | integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
1635 |
1636 | to-readable-stream@^1.0.0:
1637 | version "1.0.0"
1638 | resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
1639 | integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
1640 |
1641 | to-regex-range@^5.0.1:
1642 | version "5.0.1"
1643 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
1644 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
1645 | dependencies:
1646 | is-number "^7.0.0"
1647 |
1648 | toidentifier@1.0.0:
1649 | version "1.0.0"
1650 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
1651 | integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
1652 |
1653 | touch@^3.1.0:
1654 | version "3.1.0"
1655 | resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
1656 | integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==
1657 | dependencies:
1658 | nopt "~1.0.10"
1659 |
1660 | type-fest@^0.8.1:
1661 | version "0.8.1"
1662 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
1663 | integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
1664 |
1665 | type-is@~1.6.17, type-is@~1.6.18:
1666 | version "1.6.18"
1667 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
1668 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
1669 | dependencies:
1670 | media-typer "0.3.0"
1671 | mime-types "~2.1.24"
1672 |
1673 | typedarray-to-buffer@^3.1.5:
1674 | version "3.1.5"
1675 | resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
1676 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
1677 | dependencies:
1678 | is-typedarray "^1.0.0"
1679 |
1680 | undefsafe@^2.0.3:
1681 | version "2.0.3"
1682 | resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae"
1683 | integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==
1684 | dependencies:
1685 | debug "^2.2.0"
1686 |
1687 | unique-string@^2.0.0:
1688 | version "2.0.0"
1689 | resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
1690 | integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==
1691 | dependencies:
1692 | crypto-random-string "^2.0.0"
1693 |
1694 | unpipe@1.0.0, unpipe@~1.0.0:
1695 | version "1.0.0"
1696 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
1697 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
1698 |
1699 | update-notifier@^4.1.0:
1700 | version "4.1.3"
1701 | resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3"
1702 | integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==
1703 | dependencies:
1704 | boxen "^4.2.0"
1705 | chalk "^3.0.0"
1706 | configstore "^5.0.1"
1707 | has-yarn "^2.1.0"
1708 | import-lazy "^2.1.0"
1709 | is-ci "^2.0.0"
1710 | is-installed-globally "^0.3.1"
1711 | is-npm "^4.0.0"
1712 | is-yarn-global "^0.3.0"
1713 | latest-version "^5.0.0"
1714 | pupa "^2.0.1"
1715 | semver-diff "^3.1.1"
1716 | xdg-basedir "^4.0.0"
1717 |
1718 | url-parse-lax@^3.0.0:
1719 | version "3.0.0"
1720 | resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
1721 | integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
1722 | dependencies:
1723 | prepend-http "^2.0.0"
1724 |
1725 | util-deprecate@~1.0.1:
1726 | version "1.0.2"
1727 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
1728 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
1729 |
1730 | utils-merge@1.0.1:
1731 | version "1.0.1"
1732 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
1733 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
1734 |
1735 | vary@^1, vary@~1.1.2:
1736 | version "1.1.2"
1737 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
1738 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
1739 |
1740 | wide-align@^1.1.0:
1741 | version "1.1.3"
1742 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
1743 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
1744 | dependencies:
1745 | string-width "^1.0.2 || 2"
1746 |
1747 | widest-line@^3.1.0:
1748 | version "3.1.0"
1749 | resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
1750 | integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
1751 | dependencies:
1752 | string-width "^4.0.0"
1753 |
1754 | wrappy@1:
1755 | version "1.0.2"
1756 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1757 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
1758 |
1759 | write-file-atomic@^3.0.0:
1760 | version "3.0.3"
1761 | resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
1762 | integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
1763 | dependencies:
1764 | imurmurhash "^0.1.4"
1765 | is-typedarray "^1.0.0"
1766 | signal-exit "^3.0.2"
1767 | typedarray-to-buffer "^3.1.5"
1768 |
1769 | xdg-basedir@^4.0.0:
1770 | version "4.0.0"
1771 | resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
1772 | integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
1773 |
1774 | yallist@^4.0.0:
1775 | version "4.0.0"
1776 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
1777 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
1778 |
--------------------------------------------------------------------------------