├── README.md
├── client
├── .env
├── .gitignore
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── AllRoutes.jsx
│ ├── App.css
│ ├── App.js
│ ├── Pages
│ ├── AskQuestion
│ │ ├── AskQuestion.css
│ │ └── AskQuestion.jsx
│ ├── Auth
│ │ ├── AboutAuth.jsx
│ │ ├── Auth.css
│ │ └── Auth.jsx
│ ├── Home
│ │ └── Home.jsx
│ ├── Questions
│ │ ├── DisplayAnswer.jsx
│ │ ├── DisplayQuestion.jsx
│ │ ├── Questions.css
│ │ ├── Questions.jsx
│ │ └── QuestionsDetails.jsx
│ ├── Tags
│ │ ├── Tags.css
│ │ ├── Tags.jsx
│ │ ├── TagsList.jsx
│ │ └── tagList.js
│ ├── UserProfile
│ │ ├── EditProfileForm.jsx
│ │ ├── ProfileBio.jsx
│ │ ├── UserProfile.jsx
│ │ └── UsersProfile.css
│ └── Users
│ │ ├── User.jsx
│ │ ├── Users.css
│ │ ├── Users.jsx
│ │ └── UsersList.jsx
│ ├── actions
│ ├── auth.js
│ ├── currentUser.js
│ ├── question.js
│ └── users.js
│ ├── api
│ └── index.js
│ ├── assets
│ ├── Globe.svg
│ ├── bars-solid.svg
│ ├── blacklogo.svg
│ ├── comment-alt-solid.svg
│ ├── icon.png
│ ├── logo.png
│ ├── pen-solid.svg
│ ├── search-solid.svg
│ ├── sort-down.svg
│ └── sort-up.svg
│ ├── components
│ ├── Avatar
│ │ └── Avatar.jsx
│ ├── HomeMainbar
│ │ ├── HomeMainbar.css
│ │ ├── HomeMainbar.jsx
│ │ ├── QuestionList.jsx
│ │ └── Questions.jsx
│ ├── LeftSidebar
│ │ ├── LeftSidebar.css
│ │ └── LeftSidebar.jsx
│ ├── Navbar
│ │ ├── Navbar.css
│ │ └── Navbar.jsx
│ └── RightSidebar
│ │ ├── RightSidebar.css
│ │ ├── RightSidebar.jsx
│ │ ├── Widget.jsx
│ │ └── WidgetTags.jsx
│ ├── index.css
│ ├── index.js
│ └── reducers
│ ├── auth.js
│ ├── currentUser.js
│ ├── index.js
│ ├── questions.js
│ └── users.js
├── server
├── .gitignore
├── connectMongoDb.js
├── controllers
│ ├── Answers.js
│ ├── Questions.js
│ ├── auth.js
│ └── users.js
├── index.js
├── middleware
│ └── auth.js
├── models
│ ├── Questions.js
│ └── auth.js
├── package-lock.json
├── package.json
└── routes
│ ├── Answers.js
│ ├── Questions.js
│ └── users.js
└── vercel.json
/README.md:
--------------------------------------------------------------------------------
1 | # Stack OverFlow Clone
2 |
3 | This website is a question forum and made to look like Stack Overflow.
4 |
5 | The Code of this Project is Completely Written by Atharv Hatwar
6 |
7 |
8 | ## Installation
9 |
10 | Fork and clone the repo and follow the below steps:
11 |
12 | Install Node.js
13 | Open client and server directories in VS code
14 | Install Dependencies using the command
15 |
16 | ```Start
17 | cd client
18 | npm start
19 |
20 | ```
21 |
22 | # Usage
23 |
24 | *React js
25 | Node js
26 | Express js
27 | MongoDb
28 | Redux
29 | Json web token*
30 |
31 |
32 |
33 |
34 | ## Contributing
35 |
36 | Pull requests are welcome. For major changes, please open an issue first
37 | to discuss what you would like to change.
38 |
39 | Please make sure to update tests as appropriate.
40 |
41 | ## License
42 |
43 | [MIT](https://choosealicense.com/licenses/mit/)
44 |
--------------------------------------------------------------------------------
/client/.env:
--------------------------------------------------------------------------------
1 | #REACT_APP_API_URL="https://mern-app-gamma-ivory.vercel.app/api"
2 | REACT_APP_API_URL="http://localhost:5000/api"
--------------------------------------------------------------------------------
/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/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client2",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@fortawesome/fontawesome-svg-core": "^6.3.0",
7 | "@fortawesome/free-solid-svg-icons": "^6.3.0",
8 | "@fortawesome/react-fontawesome": "^0.2.0",
9 | "@testing-library/jest-dom": "^5.16.5",
10 | "@testing-library/react": "^13.4.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "axios": "^1.3.3",
13 | "jwt-decode": "^3.1.2",
14 | "moment": "^2.29.4",
15 | "react": "^18.2.0",
16 | "react-copy-to-clipboard": "^5.1.0",
17 | "react-dom": "^18.2.0",
18 | "react-redux": "^8.0.5",
19 | "react-router-dom": "^6.8.1",
20 | "react-scripts": "5.0.1",
21 | "redux": "^4.2.1",
22 | "redux-thunk": "^2.4.2",
23 | "web-vitals": "^2.1.4"
24 | },
25 | "scripts": {
26 | "start": "react-scripts start",
27 | "build": "react-scripts build",
28 | "test": "react-scripts test",
29 | "eject": "react-scripts eject"
30 | },
31 | "eslintConfig": {
32 | "extends": [
33 | "react-app",
34 | "react-app/jest"
35 | ]
36 | },
37 | "browserslist": {
38 | "production": [
39 | ">0.2%",
40 | "not dead",
41 | "not op_mini all"
42 | ],
43 | "development": [
44 | "last 1 chrome version",
45 | "last 1 firefox version",
46 | "last 1 safari version"
47 | ]
48 | },
49 | "description": "This project was bootstrapped with [Create React App].",
50 | "main": "index.js",
51 | "devDependencies": {
52 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11"
53 | },
54 | "repository": {
55 | "type": "git",
56 | "url": "atharvhatwar"
57 | },
58 | "keywords": [
59 | "stackoverflow"
60 | ],
61 | "author": "Atharv Hatwar",
62 | "license": "ISC"
63 | }
64 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atharv01h/Stackoverflow-clone/a1464c5a7bd05790f4c4009262b91ab88957f81b/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 | Stack Overflow Clone
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/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/AllRoutes.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Routes, Route } from "react-router-dom";
3 |
4 | import Home from "./Pages/Home/Home";
5 | import Auth from "./Pages/Auth/Auth";
6 | import Questions from "./Pages/Questions/Questions";
7 | import AskQuestion from "./Pages/AskQuestion/AskQuestion";
8 | import DisplayQuestion from "./Pages/Questions/DisplayQuestion";
9 | import Tags from "./Pages/Tags/Tags";
10 | import Users from "./Pages/Users/Users";
11 | import UserProfile from "./Pages/UserProfile/UserProfile";
12 |
13 | const AllRoutes = ({ slideIn, handleSlideIn }) => {
14 | return (
15 |
16 | }
19 | />
20 | } />
21 | } />
22 | }
25 | />
26 |
30 | }
31 | />
32 | }
35 | />
36 | }
39 | />
40 |
44 | }
45 | />
46 |
47 | );
48 | };
49 |
50 | export default AllRoutes;
51 |
--------------------------------------------------------------------------------
/client/src/App.css:
--------------------------------------------------------------------------------
1 | .home-container-1 {
2 | min-height: 100vh;
3 | max-width: 1250px;
4 | width: 100%;
5 | display: flex;
6 | justify-content: space-between;
7 | margin: 0% auto;
8 | }
9 |
10 | .home-container-2 {
11 | max-width: 1100px;
12 | width: calc(100% - 164px);
13 | padding: 24px;
14 | box-sizing: border-box;
15 | }
16 |
17 | @media screen and (max-width: 760px) {
18 | .home-container-2 {
19 | max-width: 100%;
20 | width: 100%;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/client/src/App.js:
--------------------------------------------------------------------------------
1 | import { BrowserRouter as Router } from "react-router-dom";
2 | import { useEffect, useState } from "react";
3 | import { useDispatch } from "react-redux";
4 | import "./App.css";
5 | import Navbar from "./components/Navbar/Navbar";
6 | import AllRoutes from "./AllRoutes";
7 | import { fetchAllQuestions } from "./actions/question";
8 | import { fetchAllUsers } from "./actions/users";
9 |
10 | function App() {
11 | const dispatch = useDispatch();
12 |
13 | useEffect(() => {
14 | dispatch(fetchAllQuestions());
15 | dispatch(fetchAllUsers());
16 | }, [dispatch]);
17 |
18 | const [slideIn, setSlideIn] = useState(true);
19 |
20 | useEffect(() => {
21 | if (window.innerWidth <= 760) {
22 | setSlideIn(false);
23 | }
24 | }, []);
25 |
26 | const handleSlideIn = () => {
27 | if (window.innerWidth <= 760) {
28 | setSlideIn((state) => !state);
29 | }
30 | };
31 |
32 | return (
33 |
39 | );
40 | }
41 |
42 | export default App;
43 |
--------------------------------------------------------------------------------
/client/src/Pages/AskQuestion/AskQuestion.css:
--------------------------------------------------------------------------------
1 | .ask-question {
2 | min-height: 80vh;
3 | background-color: #f1f2f3;
4 | }
5 |
6 | .ask-ques-container {
7 | margin: auto;
8 | padding: 0px 20px 20px 20px;
9 | max-width: 1200px;
10 | }
11 |
12 | .ask-ques-container h1 {
13 | padding: 80px 0px 20px 0px;
14 | }
15 |
16 | .ask-ques-container form .ask-form-container {
17 | padding: 20px;
18 | background-color: white;
19 | border-radius: 3px;
20 | box-shadow: 0 10px 25px rgb(0 0 0 / 5%), 0 20px 48px rgb(0 0 0 / 5%),
21 | 0 1px 4px rgb(0 0 0 / 10%);
22 | }
23 |
24 | .ask-form-container label h4 {
25 | margin-bottom: 0%;
26 | }
27 |
28 | .ask-form-container label p {
29 | margin: 0%;
30 | font-size: 13px;
31 | padding: 3px 0px;
32 | }
33 |
34 | .ask-form-container label input,
35 | .ask-form-container label textarea {
36 | padding: 10px;
37 | border: solid 1px #0000003e;
38 | font-family: "Roboto", sans-serif;
39 | width: calc(100% - 20px);
40 | resize: none;
41 | }
42 |
43 | .review-btn {
44 | margin: 50px 0px;
45 | padding: 10px;
46 | background-color: #009dff;
47 | border: solid 1px #009dff;
48 | color: white;
49 | border-radius: 4px;
50 | cursor: pointer;
51 | transition: 0.3s;
52 | }
53 | .review-btn:hover {
54 | background-color: #0086d8;
55 | }
56 |
--------------------------------------------------------------------------------
/client/src/Pages/AskQuestion/AskQuestion.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import { useNavigate } from "react-router-dom";
4 |
5 | import "./AskQuestion.css";
6 | import { askQuestion } from "../../actions/question";
7 |
8 | const AskQuestion = () => {
9 | const [questionTitle, setQuestionTitle] = useState("");
10 | const [questionBody, setQuestionBody] = useState("");
11 | const [questionTags, setQuestionTags] = useState("");
12 |
13 | const dispatch = useDispatch();
14 | const User = useSelector((state) => state.currentUserReducer);
15 | const navigate = useNavigate();
16 |
17 | const handleSubmit = (e) => {
18 | e.preventDefault();
19 | if (User) {
20 | if (questionTitle && questionBody && questionTags) {
21 | dispatch(
22 | askQuestion(
23 | {
24 | questionTitle,
25 | questionBody,
26 | questionTags,
27 | userPosted: User.result.name,
28 | },
29 | navigate
30 | )
31 | );
32 | } else alert("Please enter all the fields");
33 | } else alert("Login to ask question");
34 | };
35 |
36 | const handleEnter = (e) => {
37 | if (e.key === "Enter") {
38 | setQuestionBody(questionBody + "\n");
39 | }
40 | };
41 | return (
42 |
43 |
44 |
Ask a public Question
45 |
98 |
99 |
100 | );
101 | };
102 |
103 | export default AskQuestion;
104 |
--------------------------------------------------------------------------------
/client/src/Pages/Auth/AboutAuth.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const AboutAuth = () => {
4 | return (
5 |
6 |
Join the Stack Overflow community
7 |
Get unstuck — ask a question
8 |
Unlock new privileges like voting and commenting
9 |
Save your favorite tags, filters, and jobs
10 |
Earn reputation and badges
11 |
12 | Collaborate and share knowledge with a private group for
13 |
14 |
15 | Get Stack Overflow for Teams free for up to 50 users.
16 |
17 |
18 | );
19 | };
20 |
21 | export default AboutAuth;
22 |
--------------------------------------------------------------------------------
/client/src/Pages/Auth/Auth.css:
--------------------------------------------------------------------------------
1 | .auth-section {
2 | min-height: 100vh;
3 | margin: 0% auto;
4 | background-color: #f1f2f3;
5 | display: flex;
6 | justify-content: center;
7 | align-items: center;
8 | }
9 |
10 | .auth-container-1 {
11 | padding: 20px;
12 | margin-right: 30px;
13 | }
14 |
15 | .login-logo {
16 | padding: 20px 30px;
17 | }
18 |
19 | .auth-container-2 {
20 | min-width: 20%;
21 | display: flex;
22 | flex-direction: column;
23 | justify-content: center;
24 | align-items: center;
25 | }
26 |
27 | .auth-container-2 form {
28 | width: 100%;
29 | padding: 20px;
30 | background-color: white;
31 | border-radius: 10px;
32 | display: flex;
33 | flex-direction: column;
34 | justify-content: space-evenly;
35 | box-shadow: 0 10px 25px rgb(0 0 0 / 5%), 0 20px 48px rgb(0 0 0 / 5%),
36 | 0 1px 4px rgb(0 0 0 / 10%);
37 | }
38 |
39 | .auth-container-2 form p {
40 | word-wrap: break-word;
41 | }
42 |
43 | .auth-container-2 form label input {
44 | padding: 10px;
45 | width: calc(100% - 30px);
46 | border: solid 1px #0000003e;
47 | font-size: 13px;
48 | }
49 |
50 | .auth-container-2 form label:nth-child(1) h4,
51 | .auth-container-2 form label:nth-child(2) h4,
52 | .auth-container-2 form label:nth-child(3) h4 {
53 | margin-bottom: 5px;
54 | margin-top: 10px;
55 | }
56 |
57 | .auth-container-2 form label:nth-child(4) {
58 | display: flex;
59 | }
60 |
61 | .auth-container-2 form label:nth-child(4) input {
62 | width: 15%;
63 | margin: 13px 0px;
64 | }
65 |
66 | .auth-btn {
67 | margin-top: 10px;
68 | padding: 10px 5px;
69 | background-color: #009dff;
70 | border: solid 1px #009dff;
71 | color: white;
72 | border-radius: 5px;
73 | cursor: pointer;
74 | transition: 0.2s;
75 | font-size: 13px;
76 | font-weight: 500;
77 | }
78 |
79 | .auth-btn:hover {
80 | background-color: #018ce3;
81 | }
82 |
83 | .handle-switch-btn {
84 | background-color: transparent;
85 | color: #007ac6;
86 | border: none;
87 | font-size: 13px;
88 | cursor: pointer;
89 | }
90 |
91 | @media screen and (max-width: 820px) {
92 | .auth-container-1 {
93 | display: none;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/client/src/Pages/Auth/Auth.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useDispatch } from "react-redux";
3 | import { useNavigate } from "react-router-dom";
4 |
5 | import "./Auth.css";
6 | import icon from "../../assets/icon.png";
7 | import AboutAuth from "./AboutAuth";
8 | import { signup, login } from "../../actions/auth";
9 | const Auth = () => {
10 | const [isSignup, setIsSignup] = useState(false);
11 | const [name, setName] = useState("");
12 | const [email, setEmail] = useState("");
13 | const [password, setPassword] = useState("");
14 |
15 | const dispatch = useDispatch();
16 | const navigate = useNavigate();
17 |
18 | const handleSwitch = () => {
19 | setIsSignup(!isSignup);
20 | setName("");
21 | setEmail("");
22 | setPassword("");
23 | };
24 |
25 | const handleSubmit = (e) => {
26 | e.preventDefault();
27 | if (!email && !password) {
28 | alert("Enter email and password");
29 | }
30 | if (isSignup) {
31 | if (!name) {
32 | alert("Enter a name to continue");
33 | }
34 | dispatch(signup({ name, email, password }, navigate));
35 | } else {
36 | dispatch(login({ email, password }, navigate));
37 | }
38 | };
39 |
40 | return (
41 |
42 | {isSignup && }
43 |
44 |

45 |
95 |
96 | {isSignup ? "Already have an account?" : "Don't have an account?"}
97 |
104 |
105 |
106 |
107 | );
108 | };
109 |
110 | export default Auth;
111 |
--------------------------------------------------------------------------------
/client/src/Pages/Home/Home.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "../../App.css";
4 | import LeftSidebar from "../../components/LeftSidebar/LeftSidebar";
5 | import RightSidebar from "../../components/RightSidebar/RightSidebar";
6 | import HomeMainbar from "../../components/HomeMainbar/HomeMainbar";
7 |
8 | const Home = ({ slideIn }) => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | };
19 |
20 | export default Home;
21 |
--------------------------------------------------------------------------------
/client/src/Pages/Questions/DisplayAnswer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import moment from "moment";
3 | import { Link, useParams } from "react-router-dom";
4 | import { useSelector, useDispatch } from "react-redux";
5 |
6 | import Avatar from "../../components/Avatar/Avatar";
7 | import { deleteAnswer } from "../../actions/question";
8 |
9 | const DisplayAnswer = ({ question, handleShare }) => {
10 | const User = useSelector((state) => state.currentUserReducer);
11 | const { id } = useParams();
12 | const dispatch = useDispatch();
13 | const handleDelete = (answerId, noOfAnswers) => {
14 | dispatch(deleteAnswer(id, answerId, noOfAnswers - 1));
15 | };
16 | return (
17 |
18 | {question.answer.map((ans) => (
19 |
20 |
{ans.answerBody}
21 |
22 |
23 |
26 | {User?.result?._id === ans?.userId && (
27 |
33 | )}
34 |
35 |
36 |
answered {moment(ans.answeredOn).fromNow()}
37 |
42 |
48 | {ans.userAnswered.charAt(0).toUpperCase()}
49 |
50 |
{ans.userAnswered}
51 |
52 |
53 |
54 |
55 | ))}
56 |
57 | );
58 | };
59 |
60 | export default DisplayAnswer;
61 |
--------------------------------------------------------------------------------
/client/src/Pages/Questions/DisplayQuestion.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import LeftSidebar from "../../components/LeftSidebar/LeftSidebar";
3 | import RightSidebar from "../../components/RightSidebar/RightSidebar";
4 | import QuestionsDetails from "./QuestionsDetails";
5 |
6 | const DisplayQuestion = ({ slideIn, handleSlideIn }) => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | );
16 | };
17 |
18 | export default DisplayQuestion;
19 |
--------------------------------------------------------------------------------
/client/src/Pages/Questions/Questions.css:
--------------------------------------------------------------------------------
1 | .question-details-page {
2 | width: calc(100% - 300px - 24px);
3 | float: left;
4 | margin: 25px 0px;
5 | padding: 0px;
6 | }
7 |
8 | .question-details-container {
9 | margin-bottom: 20px;
10 | padding-bottom: 20px;
11 | border-bottom: solid 1px rgba(0, 0, 0, 0.112);
12 | }
13 | .question-details-container-2 {
14 | display: flex;
15 | }
16 | .question-votes {
17 | padding: 5px 20px 5px 10px;
18 | }
19 | .question-votes p {
20 | margin: 0%;
21 | font-size: 25px;
22 | text-align: center;
23 | }
24 | .votes-icon {
25 | font-size: 40px;
26 | cursor: pointer;
27 | color: rgb(206, 203, 203);
28 | }
29 | .votes-icon:active {
30 | color: #ef8236;
31 | }
32 | .question-details-container .question-body {
33 | line-height: 22px;
34 | white-space: pre-line;
35 | }
36 |
37 | .question-details-container .question-details-tags {
38 | display: flex;
39 | align-items: center;
40 | justify-content: flex-start;
41 | }
42 |
43 | .question-details-container .question-details-tags p,
44 | .post-ans-container p .ans-tags {
45 | padding: 5px 5px;
46 | margin: 3px;
47 | font-size: 13px;
48 | border-radius: 2px;
49 | background-color: #e1ecf4;
50 | color: #39739d;
51 | text-decoration: none;
52 | line-height: 22px;
53 | }
54 | .question-actions-user {
55 | width: 100%;
56 | display: flex;
57 | align-items: center;
58 | justify-content: space-between;
59 | }
60 |
61 | .question-actions-user button,
62 | .edit-question-btn {
63 | background-color: transparent;
64 | border: none;
65 | padding: 5px 0px;
66 | margin: 0px 10px 0px 0px;
67 | text-decoration: none;
68 | color: #939292;
69 | cursor: pointer;
70 | font-size: 14px;
71 | transition: 0.3s;
72 | }
73 | .question-actions-user button:active {
74 | border-bottom: solid 2px black;
75 | }
76 | .question-actions-user div:nth-child(2) p,
77 | .question-actions-user div:nth-child(2) .user-link {
78 | text-decoration: none;
79 | font-size: 14px;
80 | margin: 0%;
81 | }
82 | .user-link {
83 | display: flex;
84 | align-items: center;
85 | }
86 | .user-link div {
87 | padding-left: 10px;
88 | }
89 | /* post answer container */
90 |
91 | .post-ans-container form textarea {
92 | padding: 10px;
93 | border: solid 1px rgba(0, 0, 0, 0.3);
94 | font-family: "Roboto", sans-serif;
95 | width: calc(100% - 20px);
96 | resize: vertical;
97 | }
98 |
99 | .post-ans-container form .post-ans-btn {
100 | margin: 20px 0px;
101 | padding: 10px 10px;
102 | background-color: #009dff;
103 | color: white;
104 | border: solid 1px #009dff;
105 | border-radius: 4px;
106 | cursor: pointer;
107 | transition: 0.5s all;
108 | }
109 |
110 | .post-ans-container form .post-ans-btn:hover {
111 | background-color: #0086d8;
112 | }
113 |
114 | /* Display answer container */
115 |
116 | .display-ans {
117 | padding-bottom: 20px;
118 | border-bottom: solid 1px rgba(0, 0, 0, 0.112);
119 | }
120 |
121 | .display-ans p {
122 | font-size: 14px;
123 | line-height: 18px;
124 | white-space: pre-line;
125 | }
126 |
127 | @media screen and (max-width: 1020px) {
128 | .question-details-page {
129 | width: calc(100% - 24px);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/client/src/Pages/Questions/Questions.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "../../App.css";
4 | import LeftSidebar from "../../components/LeftSidebar/LeftSidebar";
5 | import RightSidebar from "../../components/RightSidebar/RightSidebar";
6 | import HomeMainbar from "../../components/HomeMainbar/HomeMainbar";
7 |
8 | const Questions = ({ slideIn, handleSlideIn }) => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | };
19 |
20 | export default Questions;
21 |
--------------------------------------------------------------------------------
/client/src/Pages/Questions/QuestionsDetails.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useParams, Link, useNavigate, useLocation } from "react-router-dom";
3 | import { useSelector, useDispatch } from "react-redux";
4 | import moment from "moment";
5 | import copy from "copy-to-clipboard";
6 |
7 | import upvote from "../../assets/sort-up.svg";
8 | import downvote from "../../assets/sort-down.svg";
9 | import "./Questions.css";
10 | import Avatar from "../../components/Avatar/Avatar";
11 | import DisplayAnswer from "./DisplayAnswer";
12 | import {
13 | postAnswer,
14 | deleteQuestion,
15 | voteQuestion,
16 | } from "../../actions/question";
17 |
18 | const QuestionsDetails = () => {
19 | const { id } = useParams();
20 | const questionsList = useSelector((state) => state.questionsReducer);
21 |
22 | const [Answer, setAnswer] = useState("");
23 | const Navigate = useNavigate();
24 | const dispatch = useDispatch();
25 | const User = useSelector((state) => state.currentUserReducer);
26 | const location = useLocation();
27 | const url = "http://localhost:3000";
28 |
29 | const handlePostAns = (e, answerLength) => {
30 | e.preventDefault();
31 | if (User === null) {
32 | alert("Login or Signup to answer a question");
33 | Navigate("/Auth");
34 | } else {
35 | if (Answer === "") {
36 | alert("Enter an answer before submitting");
37 | } else {
38 | dispatch(
39 | postAnswer({
40 | id,
41 | noOfAnswers: answerLength + 1,
42 | answerBody: Answer,
43 | userAnswered: User.result.name,
44 | })
45 | );
46 | setAnswer("");
47 | }
48 | }
49 | };
50 |
51 | const handleShare = () => {
52 | copy(url + location.pathname);
53 | alert("Copied url : " + url + location.pathname);
54 | };
55 |
56 | const handleDelete = () => {
57 | dispatch(deleteQuestion(id, Navigate));
58 | };
59 |
60 | const handleUpVote = () => {
61 | if (User === null) {
62 | alert("Login or Signup to up vote a question");
63 | Navigate("/Auth");
64 | } else {
65 | dispatch(voteQuestion(id, "upVote"));
66 | }
67 | };
68 |
69 | const handleDownVote = () => {
70 | if (User === null) {
71 | alert("Login or Signup to down vote a question");
72 | Navigate("/Auth");
73 | } else {
74 | dispatch(voteQuestion(id, "downVote"));
75 | }
76 | };
77 |
78 | return (
79 |
80 | {questionsList.data === null ? (
81 |
Loading...
82 | ) : (
83 | <>
84 | {questionsList.data
85 | .filter((question) => question._id === id)
86 | .map((question) => (
87 |
88 |
89 | {question.questionTitle}
90 |
91 |
92 |

99 |
{question.upVote.length - question.downVote.length}
100 |

107 |
108 |
109 |
{question.questionBody}
110 |
111 | {question.questionTags.map((tag) => (
112 |
{tag}
113 | ))}
114 |
115 |
116 |
117 |
120 | {User?.result?._id === question?.userId && (
121 |
124 | )}
125 |
126 |
127 |
asked {moment(question.askedOn).fromNow()}
128 |
133 |
139 | {question.userPosted.charAt(0).toUpperCase()}
140 |
141 |
{question.userPosted}
142 |
143 |
144 |
145 |
146 |
147 |
148 | {question.noOfAnswers !== 0 && (
149 |
150 | {question.noOfAnswers} Answers
151 |
156 |
157 | )}
158 |
198 |
199 | ))}
200 | >
201 | )}
202 |
203 | );
204 | };
205 |
206 | export default QuestionsDetails;
207 |
--------------------------------------------------------------------------------
/client/src/Pages/Tags/Tags.css:
--------------------------------------------------------------------------------
1 | .tags-h1 {
2 | margin-top: 50px;
3 | font-weight: 400;
4 | }
5 |
6 | .tags-p {
7 | margin: 0px;
8 | font-size: 15px;
9 | }
10 |
11 | .tags-list-container {
12 | padding: 30px 0px;
13 | display: grid;
14 | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
15 | gap: 10px;
16 | }
17 |
18 | .tag {
19 | padding: 10px;
20 | border: solid 1px #d2d2d2;
21 | border-radius: 2px;
22 | }
23 |
24 | .tag h5 {
25 | display: inline-block;
26 | margin: 10px 0px;
27 | padding: 5px 5px;
28 | background-color: #e1ecf4;
29 | color: #39739d;
30 | }
31 |
32 | .tag p {
33 | font-size: 14px;
34 | color: #323232;
35 | line-height: 17px;
36 | }
37 |
--------------------------------------------------------------------------------
/client/src/Pages/Tags/Tags.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import LeftSidebar from "../../components/LeftSidebar/LeftSidebar";
4 | import TagsList from "./TagsList";
5 | import "./Tags.css";
6 | import { tagsList } from "./tagList";
7 |
8 | const Tags = ({ slideIn, handleSlideIn }) => {
9 | return (
10 |
11 |
12 |
13 |
Tags
14 |
15 | A tag is a keyword or label that categorizes your question with other,
16 | similar questions.
17 |
18 |
19 | Using the right tags makes it easier for others to find and answer
20 | your question.
21 |
22 |
23 | {tagsList.map((tag, index) => (
24 |
25 | ))}
26 |
27 |
28 |
29 | );
30 | };
31 |
32 | export default Tags;
33 |
--------------------------------------------------------------------------------
/client/src/Pages/Tags/TagsList.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./Tags.css";
3 |
4 | const TagsList = ({ tag }) => {
5 | return (
6 |
7 |
{tag.tagName}
8 |
{tag.tagDesc}
9 |
10 | );
11 | };
12 |
13 | export default TagsList;
14 |
--------------------------------------------------------------------------------
/client/src/Pages/Tags/tagList.js:
--------------------------------------------------------------------------------
1 | export const tagsList = [
2 | {
3 | tagName: "javascript",
4 | tagDesc:
5 | "For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Please include all relevant tags on your question;",
6 | },
7 | {
8 | tagName: "python",
9 | tagDesc:
10 | "Python is a multi-paradigm, dynamically typed, multipurpose programming language. It is designed to be quick to learn, understand, and use, and enforces a clean and uniform syntax.",
11 | },
12 | {
13 | tagName: "c#",
14 | tagDesc:
15 | "C# (pronounced 'see sharp') is a high level, statically typed, multi-paradigm programming language developed by Microsoft",
16 | },
17 | {
18 | tagName: "java",
19 | tagDesc:
20 | "Java is a high-level object oriented programming language. Use this tag when you're having problems using or understanding the language itself. ",
21 | },
22 | {
23 | tagName: "php",
24 | tagDesc:
25 | "PHP is a widely used, open source, general-purpose, multi-paradigm, dynamically typed and interpreted scripting language originally designed for server-side web development",
26 | },
27 | {
28 | tagName: "html",
29 | tagDesc:
30 | "HTML (HyperText Markup Language) is the markup language for creating web pages and other information to be displayed in a web browser.",
31 | },
32 | {
33 | tagName: "android",
34 | tagDesc:
35 | "Android is Google's mobile operating system, used for programming or developing digital devices (Smartphones, Tablets, Automobiles, TVs, Wear, Glass, IoT).",
36 | },
37 | {
38 | tagName: "css",
39 | tagDesc:
40 | "CSS is a representation style sheet language used for describing the look and formatting of HTML, XML documents and SVG elements including colors, layout, fonts, and animations",
41 | },
42 | {
43 | tagName: "Reactjs",
44 | tagDesc:
45 | "React is a JavaScript library for building user interfaces. It uses a declarative, component-based paradigm and aims to be both efficient and flexible.",
46 | },
47 | {
48 | tagName: "node.js",
49 | tagDesc:
50 | "Node.js is an event-based, non-blocking, asynchronous I/O runtime that uses Google's V8 JavaScript engine and libuv library. ",
51 | },
52 | ];
53 |
--------------------------------------------------------------------------------
/client/src/Pages/UserProfile/EditProfileForm.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useDispatch } from "react-redux";
3 | import { updateProfile } from "../../actions/users";
4 |
5 | const EditProfileForm = ({ currentUser, setSwitch }) => {
6 | const [name, setName] = useState(currentUser?.result?.name);
7 | const [about, setAbout] = useState(currentUser?.result?.about);
8 | const [tags, setTags] = useState([]);
9 | const dispatch = useDispatch();
10 | console.log(tags);
11 | const handleSubmit = (e) => {
12 | e.preventDefault();
13 | if (tags[0] === "" || tags.length === 0) {
14 | alert("Update tags field");
15 | } else {
16 | dispatch(updateProfile(currentUser?.result?._id, { name, about, tags }));
17 | }
18 | setSwitch(false);
19 | };
20 |
21 | return (
22 |
64 | );
65 | };
66 |
67 | export default EditProfileForm;
68 |
--------------------------------------------------------------------------------
/client/src/Pages/UserProfile/ProfileBio.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const ProfileBio = ({ currentProfile }) => {
4 | return (
5 |
6 |
7 | {currentProfile?.tags.length !== 0 ? (
8 | <>
9 |
Tags watched
10 | {currentProfile?.tags.map((tag) => (
11 |
{tag}
12 | ))}
13 | >
14 | ) : (
15 |
0 tags watched
16 | )}
17 |
18 |
19 | {currentProfile?.about ? (
20 | <>
21 |
About
22 |
{currentProfile?.about}
23 | >
24 | ) : (
25 |
No bio found
26 | )}
27 |
28 |
29 | );
30 | };
31 |
32 | export default ProfileBio;
33 |
--------------------------------------------------------------------------------
/client/src/Pages/UserProfile/UserProfile.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useSelector } from "react-redux";
3 | import { useParams } from "react-router";
4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
5 | import { faBirthdayCake, faPen } from "@fortawesome/free-solid-svg-icons";
6 | import moment from "moment";
7 |
8 | import LeftSidebar from "../../components/LeftSidebar/LeftSidebar";
9 | import Avatar from "../../components/Avatar/Avatar";
10 | import EditProfileForm from "./EditProfileForm";
11 | import ProfileBio from "./ProfileBio";
12 | import "./UsersProfile.css";
13 |
14 | const UserProfile = ({ slideIn, handleSlideIn }) => {
15 | const { id } = useParams();
16 | const users = useSelector((state) => state.usersReducer);
17 | const currentProfile = users.filter((user) => user._id === id)[0];
18 | const currentUser = useSelector((state) => state.currentUserReducer);
19 | const [Switch, setSwitch] = useState(false);
20 |
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 | {currentProfile?.name.charAt(0).toUpperCase()}
36 |
37 |
38 |
{currentProfile?.name}
39 |
40 | Joined{" "}
41 | {moment(currentProfile?.joinedOn).fromNow()}
42 |
43 |
44 |
45 | {currentUser?.result._id === id && (
46 |
53 | )}
54 |
55 | <>
56 | {Switch ? (
57 |
61 | ) : (
62 |
63 | )}
64 | >
65 |
66 |
67 |
68 | );
69 | };
70 |
71 | export default UserProfile;
72 |
--------------------------------------------------------------------------------
/client/src/Pages/UserProfile/UsersProfile.css:
--------------------------------------------------------------------------------
1 | .user-details-container {
2 | width: 100%;
3 | margin-top: 50px;
4 | display: flex;
5 | align-items: flex-start;
6 | justify-content: space-between;
7 | }
8 |
9 | .user-details {
10 | display: flex;
11 | align-items: flex-start;
12 | }
13 |
14 | .user-name {
15 | padding-left: 20px;
16 | }
17 | .user-name p {
18 | color: #7e7e7e;
19 | }
20 | .edit-profile-btn {
21 | padding: 8px 10px;
22 | border: solid 1px #7e7e7e;
23 | border-radius: 2px;
24 | background-color: white;
25 | cursor: pointer;
26 | transition: 0.3s;
27 | }
28 | .edit-profile-btn:hover {
29 | background-color: #f5f9fc;
30 | }
31 | .edit-profile-title {
32 | padding: 20px 0px;
33 | border-bottom: solid 1px #dbd9d9;
34 | }
35 | .edit-profile-title-2 {
36 | color: grey;
37 | font-weight: 400;
38 | }
39 | .edit-profile-form {
40 | padding: 20px;
41 | border: solid 1px #dbd9d9;
42 | border-radius: 5px;
43 | }
44 | .edit-profile-form label h3 {
45 | margin: 0%;
46 | padding: 3px 0px;
47 | }
48 | .edit-profile-form label p {
49 | margin: 0%;
50 | padding: 3px 0px;
51 | }
52 | .edit-profile-form label input,
53 | .edit-profile-form label textarea {
54 | padding: 5px;
55 | margin-bottom: 20px;
56 | border: solid 1px #dbd9d9;
57 | width: 50%;
58 | }
59 |
60 | .user-submit-btn {
61 | padding: 14px 10px;
62 | background-color: #0a95ff;
63 | color: white;
64 | border: none;
65 | border-radius: 5px;
66 | transition: 0.2s;
67 | cursor: pointer;
68 | }
69 |
70 | .user-submit-btn:hover {
71 | background-color: #0074cc;
72 | }
73 |
74 | .user-cancel-btn {
75 | padding: 14px 10px;
76 | color: #0a95ff;
77 | background-color: transparent;
78 | border: none;
79 | margin-left: 10px;
80 | cursor: pointer;
81 | }
82 |
--------------------------------------------------------------------------------
/client/src/Pages/Users/User.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | import "./Users.css";
5 |
6 | const User = ({ user }) => {
7 | return (
8 |
9 | {user.name.charAt(0).toUpperCase()}
10 | {user.name}
11 |
12 | );
13 | };
14 |
15 | export default User;
16 |
--------------------------------------------------------------------------------
/client/src/Pages/Users/Users.css:
--------------------------------------------------------------------------------
1 | .user-list-container {
2 | padding: 30px 0px;
3 | display: grid;
4 | grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
5 | gap: 30px;
6 | }
7 |
8 | .user-profile-link {
9 | display: flex;
10 | align-items: center;
11 | justify-content: flex-start;
12 | text-decoration: none;
13 | color: black;
14 | }
15 |
16 | .user-profile-link h3 {
17 | padding: 10px 13px;
18 | background-color: #d3d3d3;
19 | border-radius: 50%;
20 | }
21 |
22 | .user-profile-link h5 {
23 | margin: 0px 10px;
24 | }
25 |
--------------------------------------------------------------------------------
/client/src/Pages/Users/Users.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import "./Users.css";
4 | import LeftSidebar from "../../components/LeftSidebar/LeftSidebar";
5 | import UsersList from "./UsersList";
6 |
7 | const Users = ({ slideIn, handleSlideIn }) => {
8 | return (
9 |
10 |
11 |
12 |
Users
13 |
14 |
15 |
16 | );
17 | };
18 |
19 | export default Users;
20 |
--------------------------------------------------------------------------------
/client/src/Pages/Users/UsersList.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useSelector } from "react-redux";
3 |
4 | import User from "./User";
5 | import "./Users.css";
6 |
7 | const UsersList = () => {
8 | const users = useSelector((state) => state.usersReducer);
9 |
10 | return (
11 |
12 | {users.map((user) => (
13 |
14 | ))}
15 |
16 | );
17 | };
18 |
19 | export default UsersList;
20 |
--------------------------------------------------------------------------------
/client/src/actions/auth.js:
--------------------------------------------------------------------------------
1 | import * as api from "../api";
2 | import { setCurrentUser } from "./currentUser";
3 | import { fetchAllUsers } from "./users";
4 |
5 | export const signup = (authData, navigate) => async (dispatch) => {
6 | try {
7 | const { data } = await api.signUp(authData);
8 | dispatch({ type: "AUTH", data });
9 | dispatch(setCurrentUser(JSON.parse(localStorage.getItem("Profile"))));
10 | dispatch(fetchAllUsers());
11 | navigate("/");
12 | } catch (error) {
13 | console.log(error);
14 | }
15 | };
16 |
17 | export const login = (authData, navigate) => async (dispatch) => {
18 | try {
19 | const { data } = await api.logIn(authData);
20 | dispatch({ type: "AUTH", data });
21 | dispatch(setCurrentUser(JSON.parse(localStorage.getItem("Profile"))));
22 | navigate("/");
23 | } catch (error) {
24 | console.log(error);
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/client/src/actions/currentUser.js:
--------------------------------------------------------------------------------
1 | export const setCurrentUser = (data) => {
2 | return {
3 | type: "FETCH_CURRENT_USER",
4 | payload: data,
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/client/src/actions/question.js:
--------------------------------------------------------------------------------
1 | import * as api from "../api/index";
2 |
3 | export const askQuestion = (questionData, navigate) => async (dispatch) => {
4 | try {
5 | const { data } = await api.postQuestion(questionData);
6 | dispatch({ type: "POST_QUESTION", payload: data });
7 | dispatch(fetchAllQuestions());
8 | navigate("/");
9 | } catch (error) {
10 | console.log(error);
11 | }
12 | };
13 |
14 | export const fetchAllQuestions = () => async (disptach) => {
15 | try {
16 | const { data } = await api.getAllQuestions();
17 | disptach({ type: "FETCH_ALL_QUESTIONS", payload: data });
18 | } catch (error) {
19 | console.log(error);
20 | }
21 | };
22 |
23 | export const deleteQuestion = (id, navigate) => async (dispatch) => {
24 | try {
25 | await api.deleteQuestion(id);
26 | dispatch(fetchAllQuestions());
27 | navigate("/");
28 | } catch (error) {
29 | console.log(error);
30 | }
31 | };
32 |
33 | export const voteQuestion = (id, value) => async (dispatch) => {
34 | try {
35 | await api.voteQuestion(id, value);
36 | dispatch(fetchAllQuestions());
37 | } catch (error) {
38 | console.log(error);
39 | }
40 | };
41 |
42 | export const postAnswer = (answerData) => async (dispatch) => {
43 | try {
44 | const { id, noOfAnswers, answerBody, userAnswered } = answerData;
45 | const { data } = await api.postAnswer(
46 | id,
47 | noOfAnswers,
48 | answerBody,
49 | userAnswered
50 | );
51 | dispatch({ type: "POST_ANSWER", payload: data });
52 | dispatch(fetchAllQuestions());
53 | } catch (error) {
54 | console.log(error);
55 | }
56 | };
57 |
58 | export const deleteAnswer = (id, answerId, noOfAnswers) => async (dispatch) => {
59 | try {
60 | await api.deleteAnswer(id, answerId, noOfAnswers);
61 | dispatch(fetchAllQuestions());
62 | } catch (error) {
63 | console.log(error);
64 | }
65 | };
66 |
--------------------------------------------------------------------------------
/client/src/actions/users.js:
--------------------------------------------------------------------------------
1 | import * as api from "../api";
2 |
3 | export const fetchAllUsers = () => async (dispatch) => {
4 | try {
5 | const { data } = await api.getAllUsers();
6 | dispatch({ type: "FETCH_USERS", payload: data });
7 | } catch (error) {
8 | console.log(error);
9 | }
10 | };
11 | export const updateProfile = (id, updateData) => async (dispatch) => {
12 | try {
13 | const { data } = await api.updateProfile(id, updateData);
14 | dispatch({ type: "UPDATE_CURRENT_USER", payload: data });
15 | } catch (error) {
16 | console.log(error);
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/client/src/api/index.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | const API = axios.create({
4 | baseURL: process.env.REACT_APP_API_URL,
5 | });
6 |
7 | API.interceptors.request.use((req) => {
8 | if (localStorage.getItem("Profile")) {
9 | req.headers.authorization = `Bearer ${
10 | JSON.parse(localStorage.getItem("Profile")).token
11 | }`;
12 | }
13 | return req;
14 | });
15 |
16 | console.log(process.env.REACT_APP_API_URL)
17 |
18 | export const logIn = (authData) => API.post("/user/login", authData);
19 | export const signUp = (authData) => API.post("/user/signup", authData);
20 |
21 | export const postQuestion = (questionData) =>
22 | API.post("/questions/Ask", questionData);
23 | export const getAllQuestions = () => API.get("/questions/get");
24 | export const deleteQuestion = (id) => API.delete(`/questions/delete/${id}`);
25 | export const voteQuestion = (id, value) =>
26 | API.patch(`/questions/vote/${id}`, { value });
27 |
28 | export const postAnswer = (id, noOfAnswers, answerBody, userAnswered) =>
29 | API.patch(`/answer/post/${id}`, { noOfAnswers, answerBody, userAnswered });
30 | export const deleteAnswer = (id, answerId, noOfAnswers) =>
31 | API.patch(`/answer/delete/${id}`, { answerId, noOfAnswers });
32 |
33 | export const getAllUsers = () => API.get("/user/getAllUsers");
34 | export const updateProfile = (id, updateData) =>
35 | API.patch(`/user/update/${id}`, updateData);
36 |
--------------------------------------------------------------------------------
/client/src/assets/Globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/bars-solid.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/blacklogo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/comment-alt-solid.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atharv01h/Stackoverflow-clone/a1464c5a7bd05790f4c4009262b91ab88957f81b/client/src/assets/icon.png
--------------------------------------------------------------------------------
/client/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atharv01h/Stackoverflow-clone/a1464c5a7bd05790f4c4009262b91ab88957f81b/client/src/assets/logo.png
--------------------------------------------------------------------------------
/client/src/assets/pen-solid.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/search-solid.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/sort-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/assets/sort-up.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/components/Avatar/Avatar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Avatar = ({
4 | children,
5 | backgroundColor,
6 | px,
7 | py,
8 | color,
9 | borderRadius,
10 | fontSize,
11 | cursor,
12 | }) => {
13 | const style = {
14 | backgroundColor,
15 | padding: `${py} ${px}`,
16 | color: color || "black",
17 | borderRadius,
18 | fontSize,
19 | textAlign: "center",
20 | cursor: cursor || null,
21 | textDecoration: "none",
22 | };
23 |
24 | return {children}
;
25 | };
26 |
27 | export default Avatar;
28 |
--------------------------------------------------------------------------------
/client/src/components/HomeMainbar/HomeMainbar.css:
--------------------------------------------------------------------------------
1 | .main-bar {
2 | width: calc(100% - 300px - 24px);
3 | float: left;
4 | margin: 25px 0px;
5 | padding: 0;
6 | }
7 |
8 | .main-bar-header {
9 | display: flex;
10 | justify-content: space-between;
11 | align-items: center;
12 | }
13 |
14 | .main-bar-header h1 {
15 | font-weight: 400;
16 | }
17 |
18 | .main-bar-header .ask-btn {
19 | padding: 10px 15px;
20 | border-radius: 4px;
21 | background-color: #009dff;
22 | color: white;
23 | border: none;
24 | text-decoration: none;
25 | transition: 0.3s;
26 | }
27 |
28 | .main-bar-header .ask-btn:hover {
29 | background-color: #0086d8;
30 | }
31 |
32 | .display-question-container {
33 | min-height: 80px;
34 | width: 100%;
35 | display: flex;
36 | align-items: center;
37 | background-color: #fdf7e2;
38 | border-bottom: solid 1px #edeff0;
39 | }
40 |
41 | .display-question-container .display-votes-ans {
42 | padding: 10px;
43 | }
44 |
45 | .display-question-container .display-votes-ans p {
46 | margin: 0%;
47 | text-align: center;
48 | }
49 |
50 | .display-question-details {
51 | flex-grow: 1;
52 | padding: 10px;
53 | margin: 0%;
54 | }
55 |
56 | .question-title-link {
57 | text-decoration: none;
58 | color: #037ecb;
59 | transition: 0.3s;
60 | }
61 |
62 | .question-title-link:hover {
63 | color: #009dff;
64 | }
65 |
66 | .display-tags-time .display-tags {
67 | display: flex;
68 | flex-wrap: wrap;
69 | }
70 |
71 | .display-tags-time {
72 | display: flex;
73 | flex-wrap: wrap;
74 | align-items: center;
75 | justify-content: space-between;
76 | }
77 |
78 | .display-tags-time .display-tags p {
79 | margin: 2px;
80 | padding: 4px;
81 | font-size: 13px;
82 | background-color: #edeff0;
83 | color: #39739d;
84 | }
85 | .display-tags-time .display-time {
86 | font-size: 13px;
87 | }
88 |
89 | @media screen and (max-width: 1020px) {
90 | .main-bar {
91 | width: 100%;
92 | }
93 | }
94 |
95 | @media screen and (max-width: 740px) {
96 | .display-question-container .display-votes-ans {
97 | padding: 10px;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/client/src/components/HomeMainbar/HomeMainbar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useLocation, useNavigate } from "react-router-dom";
3 | import { useSelector } from "react-redux";
4 | import "./HomeMainbar.css";
5 | import QuestionList from "./QuestionList";
6 |
7 | const HomeMainbar = () => {
8 | const location = useLocation();
9 | const user = 1;
10 | const navigate = useNavigate();
11 |
12 | const questionsList = useSelector((state) => state.questionsReducer);
13 |
14 | const checkAuth = () => {
15 | if (user === null) {
16 | alert("login or signup to ask a question");
17 | navigate("/Auth");
18 | } else {
19 | navigate("/AskQuestion");
20 | }
21 | };
22 |
23 | return (
24 |
25 |
26 | {location.pathname === "/" ? (
27 |
Top Questions
28 | ) : (
29 | All Questions
30 | )}
31 |
34 |
35 |
36 | {questionsList.data === null ? (
37 |
Loading...
38 | ) : (
39 | <>
40 |
{questionsList.data.length} questions
41 |
42 | >
43 | )}
44 |
45 |
46 | );
47 | };
48 |
49 | export default HomeMainbar;
50 |
--------------------------------------------------------------------------------
/client/src/components/HomeMainbar/QuestionList.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Questions from "./Questions";
3 | const QuestionList = ({ questionsList }) => {
4 | return (
5 | <>
6 | {questionsList.map((question) => (
7 |
8 | ))}
9 | >
10 | );
11 | };
12 |
13 | export default QuestionList;
14 |
--------------------------------------------------------------------------------
/client/src/components/HomeMainbar/Questions.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import moment from "moment";
4 |
5 | const Questions = ({ question }) => {
6 | return (
7 |
8 |
9 |
{question.upVote.length - question.downVote.length}
10 |
votes
11 |
12 |
13 |
{question.noOfAnswers}
14 |
answers
15 |
16 |
17 |
18 | {question.questionTitle.length > (window.innerWidth <= 400 ? 70 : 90)
19 | ? question.questionTitle.substring(
20 | 0,
21 | window.innerWidth <= 400 ? 70 : 90
22 | ) + "..."
23 | : question.questionTitle}
24 |
25 |
26 |
27 | {question.questionTags.map((tag) => (
28 |
{tag}
29 | ))}
30 |
31 |
32 | asked {moment(question.askedOn).fromNow()} {question.userPosted}
33 |
34 |
35 |
36 |
37 | );
38 | };
39 |
40 | export default Questions;
41 |
--------------------------------------------------------------------------------
/client/src/components/LeftSidebar/LeftSidebar.css:
--------------------------------------------------------------------------------
1 | .left-sidebar {
2 | width: 164px;
3 | box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
4 | background-color: white;
5 | height: auto;
6 | min-height: 100vh;
7 | transition: box-shadow ease-in-out 0.1s, transform ease-in-out 0.1s;
8 | box-sizing: border-box;
9 | font-size: 13px;
10 | }
11 |
12 | .nav-btn {
13 | background-color: inherit;
14 | width: 100%;
15 | border: none;
16 | padding: 0%;
17 | }
18 |
19 | .side-nav {
20 | height: auto;
21 | max-width: 100%;
22 | position: sticky;
23 | margin: 50px 0px;
24 | padding: 20px 0px;
25 | }
26 |
27 | .side-nav-div {
28 | padding: 10px 0px;
29 | }
30 |
31 | .side-nav-div div {
32 | padding-left: 10px;
33 | }
34 |
35 | .side-nav-links {
36 | text-decoration: none;
37 | color: #3a3a3a;
38 | display: flex;
39 | align-items: center;
40 | justify-content: flex-start;
41 | padding-left: 10px;
42 | transition: 0.2s;
43 | }
44 |
45 | .side-nav-links:hover {
46 | color: black;
47 | }
48 |
49 | .active {
50 | font-weight: bolder;
51 | color: black;
52 | background-color: rgb(225, 225, 225);
53 | border-right: solid 3px #ef8236;
54 | }
55 |
56 | @media screen and (max-width: 760px) {
57 | .left-sidebar {
58 | position: absolute;
59 | transform: translateX(-100%);
60 | z-index: 10;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/client/src/components/LeftSidebar/LeftSidebar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./LeftSidebar.css";
3 | import { NavLink } from "react-router-dom";
4 | import Globe from "../../assets/Globe.svg";
5 |
6 | const LeftSidebar = ({ slideIn, handleSlideIn }) => {
7 | const slideInStyle = {
8 | transform: "translateX(0%)",
9 | };
10 |
11 | const slideOutStyle = {
12 | transform: "translateX(-100%)",
13 | };
14 |
15 | return (
16 |
20 |
62 |
63 | );
64 | };
65 |
66 | export default LeftSidebar;
67 |
--------------------------------------------------------------------------------
/client/src/components/Navbar/Navbar.css:
--------------------------------------------------------------------------------
1 | .main-nav {
2 | min-height: 50px;
3 | width: 100%;
4 | margin: 0% auto;
5 | border-top: solid 3px #ef8236;
6 | box-shadow: 0px 1px 5px #00000033;
7 | position: fixed;
8 | z-index: 15;
9 | top: 0%;
10 | left: 0%;
11 | background-color: #f8f9f9;
12 | display: flex;
13 | justify-content: center;
14 | align-items: center;
15 | }
16 |
17 | .navbar {
18 | height: 100%;
19 | min-width: 85%;
20 | display: flex;
21 | align-items: center;
22 | justify-content: space-between;
23 | }
24 |
25 | .slide-in-icon {
26 | display: none;
27 | transition: 0.2s;
28 | padding: 5px 6px 3px 6px;
29 | border-radius: 50%;
30 | background-color: inherit;
31 | border: none;
32 | cursor: pointer;
33 | }
34 |
35 | .navbar .navbar-1 {
36 | display: flex;
37 | align-items: center;
38 | flex-grow: 1;
39 | }
40 |
41 | .navbar .navbar-2 {
42 | display: flex;
43 | align-items: center;
44 | }
45 |
46 | .nav-logo {
47 | padding: 5px 25px;
48 | }
49 |
50 | .nav-item {
51 | margin: 0px 3px;
52 | font-size: small;
53 | font-weight: 500;
54 | text-decoration: none;
55 | color: rgb(69, 69, 69);
56 | transition: 0.2s;
57 | }
58 |
59 | .nav-btn {
60 | cursor: pointer;
61 | border-radius: 20px;
62 | padding: 10px 20px;
63 | }
64 |
65 | .nav-item:hover,
66 | .slide-in-icon:hover {
67 | background-color: rgb(226, 226, 226);
68 | }
69 |
70 | .navbar .navbar-1 form {
71 | flex-grow: 1;
72 | padding: 0px 12px;
73 | position: relative;
74 | }
75 |
76 | .navbar .navbar-1 form input {
77 | min-width: 90%;
78 | margin: 0;
79 | padding: 8px 10px 8px 32px;
80 | font-size: 13px;
81 | border: solid 1px #0000003e;
82 | border-radius: 3px;
83 | }
84 |
85 | .navbar .navbar-1 form .search-icon {
86 | position: absolute;
87 | left: 25px;
88 | top: 8px;
89 | }
90 |
91 | .nav-links {
92 | padding: 7px 13px;
93 | border: solid 1px blue;
94 | border-radius: 3px;
95 | background-color: #e7f8fe;
96 | cursor: pointer;
97 | }
98 |
99 | .nav-links:hover {
100 | background-color: #d3e4eb;
101 | }
102 |
103 | @media screen and (max-width: 1120px) {
104 | .navbar .navbar-1 form {
105 | display: none;
106 | }
107 | }
108 |
109 | @media screen and (max-width: 760px) {
110 | .slide-in-icon {
111 | display: block;
112 | }
113 | }
114 |
115 | @media screen and (max-width: 620px) {
116 | .navbar .navbar-1 .res-nav {
117 | display: none;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/client/src/components/Navbar/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useEffect } from "react";
2 | import { Link, useNavigate } from "react-router-dom";
3 | import { useSelector, useDispatch } from "react-redux";
4 | import decode from "jwt-decode";
5 |
6 | import logo from "../../assets/logo.png";
7 | import search from "../../assets/search-solid.svg";
8 | import Avatar from "../../components/Avatar/Avatar";
9 | import "./Navbar.css";
10 | import { setCurrentUser } from "../../actions/currentUser";
11 | import bars from "../../assets/bars-solid.svg";
12 |
13 | const Navbar = ({ handleSlideIn }) => {
14 | const dispatch = useDispatch();
15 | var User = useSelector((state) => state.currentUserReducer);
16 | const navigate = useNavigate();
17 |
18 | const handleLogout = useCallback(() => {
19 | dispatch({ type: "LOGOUT" });
20 | navigate("/");
21 | dispatch(setCurrentUser(null));
22 | }, [dispatch, navigate]);
23 |
24 | useEffect(() => {
25 | const token = User?.token;
26 | if (token) {
27 | const decodedToken = decode(token);
28 | if (decodedToken.exp * 1000 < new Date().getTime()) {
29 | handleLogout();
30 | }
31 | }
32 | dispatch(setCurrentUser(JSON.parse(localStorage.getItem("Profile"))));
33 | }, [User?.token, dispatch, handleLogout]);
34 |
35 | return (
36 |
88 | );
89 | };
90 |
91 | export default Navbar;
92 |
--------------------------------------------------------------------------------
/client/src/components/RightSidebar/RightSidebar.css:
--------------------------------------------------------------------------------
1 | .right-sidebar {
2 | float: right;
3 | width: 300px;
4 | margin: 40px 0px 15px 24px;
5 | font-size: 15px;
6 | }
7 |
8 | .widget {
9 | margin-top: 10px;
10 | box-shadow: 3px 3px 10px rgb(0 0 0 / 5%), -3px -3px 10px rgb(0 0 0 / 5%);
11 | }
12 |
13 | .widget h4 {
14 | background-color: #fbf3d5;
15 | margin: 0%;
16 | padding: 15px;
17 | border: solid 1px #f1e5bc;
18 | font-size: 13px;
19 | }
20 |
21 | .right-sidebar-div-1 {
22 | background-color: #fdf7e2;
23 | padding: 15px;
24 | border: solid 1px #f1e5bc;
25 | }
26 |
27 | .right-sidebar-div-1 .right-sidebar-div-2 {
28 | display: flex;
29 | align-items: flex-start;
30 | justify-content: space-evenly;
31 | }
32 |
33 | .right-sidebar-div-1 .right-sidebar-div-2 p {
34 | padding-left: 10px;
35 | margin-top: 0%;
36 | font-size: 13px;
37 | }
38 |
39 | .widget-tags {
40 | margin-top: 40px;
41 | box-shadow: 3px 3px 10px rgb(0 0 0 / 5%), -3px -3px 10px rgb(0 0 0 / 5%);
42 | }
43 |
44 | .widget-tags h4 {
45 | margin: 0%;
46 | padding: 15px;
47 | background-color: #f8f9f9;
48 | border: solid 1px #e3e6e8;
49 | font-size: 13px;
50 | }
51 |
52 | .widget-tags-div {
53 | display: flex;
54 | flex-flow: row wrap;
55 | align-items: center;
56 | justify-content: space-evenly;
57 | border: solid 1px #e3e6e8;
58 | padding: 10px;
59 | }
60 |
61 | .widget-tags-div p {
62 | padding: 5px;
63 | background-color: #e1ecf4;
64 | color: #39739d;
65 | border-radius: 2px;
66 | font-size: 13px;
67 | }
68 |
69 | @media screen and (max-width: 1020px) {
70 | .right-sidebar {
71 | display: none;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/client/src/components/RightSidebar/RightSidebar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./RightSidebar.css";
3 | import Widget from "./Widget";
4 | import WidgetTags from "./WidgetTags";
5 |
6 | const RightSidebar = () => {
7 | return (
8 |
12 | );
13 | };
14 |
15 | export default RightSidebar;
16 |
--------------------------------------------------------------------------------
/client/src/components/RightSidebar/Widget.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./RightSidebar.css";
3 | import comment from "../../assets/comment-alt-solid.svg";
4 | import pen from "../../assets/pen-solid.svg";
5 | import blackLogo from "../../assets/blacklogo.svg";
6 |
7 | const Widget = () => {
8 | return (
9 |
10 |
The Overflow Blog
11 |
12 |
13 |

14 |
15 | Observability is key to the future of software (and your DevOps
16 | career)
17 |
18 |
19 |
20 |

21 |
Podcast 374: How valuable is your screen name?
22 |
23 |
24 |
Featured on Meta
25 |
26 |
27 |

28 |
Review queue workflows - Final release....
29 |
30 |
31 |

32 |
33 | Please welcome Valued Associates: #958 - V2Blast #959 - SpencerG
34 |
35 |
36 |
37 |

38 |
39 | Outdated Answers: accepted answer is now unpinned on Stack Overflow
40 |
41 |
42 |
43 |
Hot Meta Posts
44 |
45 |
46 |
38
47 |
48 | Why was this spam flag declined, yet the question marked as spam?
49 |
50 |
51 |
52 |
20
53 |
54 | What is the best course of action when a user has high enough rep
55 | to...
56 |
57 |
58 |
59 |
14
60 |
Is a link to the "How to ask" help page a useful comment?
61 |
62 |
63 |
64 | );
65 | };
66 |
67 | export default Widget;
68 |
--------------------------------------------------------------------------------
/client/src/components/RightSidebar/WidgetTags.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const WidgetTags = () => {
4 | const tags = [
5 | "c",
6 | "css",
7 | "express",
8 | "firebase",
9 | "html",
10 | "java",
11 | "javascript",
12 | "mern",
13 | "mongodb",
14 | "mysql",
15 | "next.js",
16 | "node.js",
17 | "php",
18 | "python",
19 | "reactjs",
20 | ];
21 |
22 | return (
23 |
24 |
Watched tags
25 |
26 | {tags.map((tag) => (
27 |
{tag}
28 | ))}
29 |
30 |
31 | );
32 | };
33 |
34 | export default WidgetTags;
35 |
--------------------------------------------------------------------------------
/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/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import { Provider } from "react-redux";
6 | import { createStore, applyMiddleware, compose } from "redux";
7 | import thunk from "redux-thunk";
8 | import Reducers from "./reducers";
9 |
10 | const store = createStore(Reducers, compose(applyMiddleware(thunk)));
11 |
12 | const root = ReactDOM.createRoot(document.getElementById("root"));
13 | root.render(
14 |
15 |
16 |
17 |
18 |
19 | );
20 |
--------------------------------------------------------------------------------
/client/src/reducers/auth.js:
--------------------------------------------------------------------------------
1 | const authReducer = (state = { data: null }, action) => {
2 | switch (action.type) {
3 | case "AUTH":
4 | localStorage.setItem("Profile", JSON.stringify({ ...action?.data }));
5 | return { ...state, data: action?.data };
6 | case "LOGOUT":
7 | localStorage.clear();
8 | return { ...state, data: null };
9 | default:
10 | return state;
11 | }
12 | };
13 |
14 | export default authReducer;
15 |
--------------------------------------------------------------------------------
/client/src/reducers/currentUser.js:
--------------------------------------------------------------------------------
1 | const currentUserReducer = (state = null, action) => {
2 | switch (action.type) {
3 | case "FETCH_CURRENT_USER":
4 | return action.payload;
5 | default:
6 | return state;
7 | }
8 | };
9 |
10 | export default currentUserReducer;
11 |
--------------------------------------------------------------------------------
/client/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 | import authReducer from "./auth";
3 | import currentUserReducer from "./currentUser";
4 | import questionsReducer from "./questions";
5 | import usersReducer from "./users";
6 |
7 | export default combineReducers({
8 | authReducer,
9 | currentUserReducer,
10 | questionsReducer,
11 | usersReducer,
12 | });
13 |
--------------------------------------------------------------------------------
/client/src/reducers/questions.js:
--------------------------------------------------------------------------------
1 | const questionsReducer = (state = { data: null }, action) => {
2 | switch (action.type) {
3 | case "POST_QUESTION":
4 | return { ...state };
5 | case "POST_ANSWER":
6 | return { ...state };
7 | case "FETCH_ALL_QUESTIONS":
8 | return { ...state, data: action.payload };
9 | default:
10 | return state;
11 | }
12 | };
13 | export default questionsReducer;
14 |
--------------------------------------------------------------------------------
/client/src/reducers/users.js:
--------------------------------------------------------------------------------
1 | const usersReducer = (states = [], action) => {
2 | switch (action.type) {
3 | case "FETCH_USERS":
4 | return action.payload;
5 | case "UPDATE_CURRENT_USER":
6 | return states.map((state) =>
7 | state._id === action.payload._id ? action.payload : state
8 | );
9 | default:
10 | return states;
11 | }
12 | };
13 |
14 | export default usersReducer;
15 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | .env
--------------------------------------------------------------------------------
/server/connectMongoDb.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const connectDB = async () => {
4 | try {
5 | mongoose.set('strictQuery', false);
6 | const conn = await mongoose.connect(process.env.CONNECTION_URL, {
7 | useNewUrlParser: true,
8 | useUnifiedTopology: true,
9 | });
10 | console.log(`MongoDB connected: ${conn.connection.host}`);
11 | } catch (error) {
12 | console.error(error);
13 | process.exit(1);
14 | }
15 | };
16 |
17 | export default connectDB;
18 |
--------------------------------------------------------------------------------
/server/controllers/Answers.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 | import Questions from "../models/Questions.js";
3 |
4 | export const postAnswer = async (req, res) => {
5 | const { id: _id } = req.params;
6 | const { noOfAnswers, answerBody, userAnswered } = req.body;
7 | const userId = req.userId;
8 | if (!mongoose.Types.ObjectId.isValid(_id)) {
9 | return res.status(404).send("question unavailable...");
10 | }
11 |
12 | updateNoOfQuestions(_id, noOfAnswers);
13 | try {
14 | const updatedQuestion = await Questions.findByIdAndUpdate(_id, {
15 | $addToSet: { answer: [{ answerBody, userAnswered, userId }] },
16 | });
17 | res.status(200).json(updatedQuestion);
18 | } catch (error) {
19 | res.status(400).json("error in updating");
20 | }
21 | };
22 |
23 | const updateNoOfQuestions = async (_id, noOfAnswers) => {
24 | try {
25 | await Questions.findByIdAndUpdate(_id, {
26 | $set: { noOfAnswers: noOfAnswers },
27 | });
28 | } catch (error) {
29 | console.log(error);
30 | }
31 | };
32 |
33 | export const deleteAnswer = async (req, res) => {
34 | const { id: _id } = req.params;
35 | const { answerId, noOfAnswers } = req.body;
36 |
37 | if (!mongoose.Types.ObjectId.isValid(_id)) {
38 | return res.status(404).send("Question unavailable...");
39 | }
40 | if (!mongoose.Types.ObjectId.isValid(answerId)) {
41 | return res.status(404).send("Answer unavailable...");
42 | }
43 | updateNoOfQuestions(_id, noOfAnswers);
44 | try {
45 | await Questions.updateOne(
46 | { _id },
47 | { $pull: { answer: { _id: answerId } } }
48 | );
49 | res.status(200).json({ message: "Successfully deleted..." });
50 | } catch (error) {
51 | res.status(405).json(error);
52 | }
53 | };
54 |
--------------------------------------------------------------------------------
/server/controllers/Questions.js:
--------------------------------------------------------------------------------
1 | import Questions from "../models/Questions.js";
2 | import mongoose from "mongoose";
3 |
4 | export const AskQuestion = async (req, res) => {
5 | const postQuestionData = req.body;
6 | const userId = req.userId;
7 | const postQuestion = new Questions({ ...postQuestionData, userId });
8 | try {
9 | await postQuestion.save();
10 | res.status(200).json("Posted a question successfully");
11 | } catch (error) {
12 | console.log(error);
13 | res.status(409).json("Couldn't post a new question");
14 | }
15 | };
16 |
17 | export const getAllQuestions = async (req, res) => {
18 | try {
19 | const questionList = await Questions.find().sort({ askedOn: -1 });
20 | res.status(200).json(questionList);
21 | } catch (error) {
22 | res.status(404).json({ message: error.message });
23 | }
24 | };
25 |
26 | export const deleteQuestion = async (req, res) => {
27 | const { id: _id } = req.params;
28 |
29 | if (!mongoose.Types.ObjectId.isValid(_id)) {
30 | return res.status(404).send("question unavailable...");
31 | }
32 |
33 | try {
34 | await Questions.findByIdAndRemove(_id);
35 | res.status(200).json({ message: "successfully deleted..." });
36 | } catch (error) {
37 | res.status(404).json({ message: error.message });
38 | }
39 | };
40 |
41 | export const voteQuestion = async (req, res) => {
42 | const { id: _id } = req.params;
43 | const { value } = req.body;
44 | const userId = req.userId;
45 |
46 | if (!mongoose.Types.ObjectId.isValid(_id)) {
47 | return res.status(404).send("question unavailable...");
48 | }
49 |
50 | try {
51 | const question = await Questions.findById(_id);
52 | const upIndex = question.upVote.findIndex((id) => id === String(userId));
53 | const downIndex = question.downVote.findIndex(
54 | (id) => id === String(userId)
55 | );
56 |
57 | if (value === "upVote") {
58 | if (downIndex !== -1) {
59 | question.downVote = question.downVote.filter(
60 | (id) => id !== String(userId)
61 | );
62 | }
63 | if (upIndex === -1) {
64 | question.upVote.push(userId);
65 | } else {
66 | question.upVote = question.upVote.filter((id) => id !== String(userId));
67 | }
68 | } else if (value === "downVote") {
69 | if (upIndex !== -1) {
70 | question.upVote = question.upVote.filter((id) => id !== String(userId));
71 | }
72 | if (downIndex === -1) {
73 | question.downVote.push(userId);
74 | } else {
75 | question.downVote = question.downVote.filter(
76 | (id) => id !== String(userId)
77 | );
78 | }
79 | }
80 | await Questions.findByIdAndUpdate(_id, question);
81 | res.status(200).json({ message: "voted successfully..." });
82 | } catch (error) {
83 | res.status(404).json({ message: "id not found" });
84 | }
85 | };
86 |
--------------------------------------------------------------------------------
/server/controllers/auth.js:
--------------------------------------------------------------------------------
1 | import jwt from "jsonwebtoken";
2 | import bcrypt from "bcryptjs";
3 |
4 | import users from "../models/auth.js";
5 |
6 | export const signup = async (req, res) => {
7 | const { name, email, password } = req.body;
8 | try {
9 | const existinguser = await users.findOne({ email });
10 | if (existinguser) {
11 | return res.status(404).json({ message: "User already Exist." });
12 | }
13 |
14 | const hashedPassword = await bcrypt.hash(password, 12);
15 | const newUser = await users.create({
16 | name,
17 | email,
18 | password: hashedPassword,
19 | });
20 | const token = jwt.sign(
21 | { email: newUser.email, id: newUser._id },
22 | process.env.JWT_SECRET,
23 | { expiresIn: "1h" }
24 | );
25 | res.status(200).json({ result: newUser, token });
26 | } catch (error) {
27 | res.status(500).json("Something went worng...");
28 | }
29 | };
30 |
31 | export const login = async (req, res) => {
32 | const { email, password } = req.body;
33 | try {
34 | const existinguser = await users.findOne({ email });
35 | if (!existinguser) {
36 | return res.status(404).json({ message: "User don't Exist." });
37 | }
38 | const isPasswordCrt = await bcrypt.compare(password, existinguser.password);
39 | if (!isPasswordCrt) {
40 | return res.status(400).json({ message: "Invalid credentials" });
41 | }
42 | const token = jwt.sign(
43 | { email: existinguser.email, id: existinguser._id },
44 | process.env.JWT_SECRET,
45 | { expiresIn: "1h" }
46 | );
47 | res.status(200).json({ result: existinguser, token });
48 | } catch (error) {
49 | res.status(500).json("Something went worng...");
50 | }
51 | };
52 |
--------------------------------------------------------------------------------
/server/controllers/users.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 | import users from "../models/auth.js";
3 |
4 | export const getAllUsers = async (req, res) => {
5 | try {
6 | const allUsers = await users.find();
7 | const allUserDetails = [];
8 | allUsers.forEach((user) => {
9 | allUserDetails.push({
10 | _id: user._id,
11 | name: user.name,
12 | about: user.about,
13 | tags: user.tags,
14 | joinedOn: user.joinedOn,
15 | });
16 | });
17 | res.status(200).json(allUserDetails);
18 | } catch (error) {
19 | res.status(404).json({ message: error.message });
20 | }
21 | };
22 |
23 | export const updateProfile = async (req, res) => {
24 | const { id: _id } = req.params;
25 | const { name, about, tags } = req.body;
26 |
27 | if (!mongoose.Types.ObjectId.isValid(_id)) {
28 | return res.status(404).send("question unavailable...");
29 | }
30 |
31 | try {
32 | const updatedProfile = await users.findByIdAndUpdate(
33 | _id,
34 | { $set: { name: name, about: about, tags: tags } },
35 | { new: true }
36 | );
37 | res.status(200).json(updatedProfile);
38 | } catch (error) {
39 | res.status(405).json({ message: error.message });
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 | import cors from "cors";
3 | import dotenv from "dotenv";
4 |
5 | import userRoutes from "./routes/users.js";
6 | import questionRoutes from "./routes/Questions.js";
7 | import answerRoutes from "./routes/Answers.js";
8 | import connectDB from "./connectMongoDb.js";
9 |
10 | dotenv.config();
11 | await connectDB();
12 | const app = express();
13 |
14 | app.use(express.json({ limit: "30mb", extended: true }));
15 | app.use(express.urlencoded({ limit: "30mb", extended: true }));
16 | app.use(cors());
17 |
18 | app.get('/', (req, res) => {
19 | res.json({ message: 'Hello, this is a simple API response!' });
20 | });
21 |
22 | app.use("/api/user", userRoutes);
23 | app.use("/api/questions", questionRoutes);
24 | app.use("/api/answer", answerRoutes);
25 |
26 | const PORT = process.env.PORT || 5000;
27 |
28 | app.listen(PORT, () => {
29 | console.log(`Server running on port ${PORT}`);
30 | });
31 |
--------------------------------------------------------------------------------
/server/middleware/auth.js:
--------------------------------------------------------------------------------
1 | import jwt from "jsonwebtoken";
2 |
3 | const auth = (req, res, next) => {
4 | try {
5 | if (!req.headers?.authorization) {
6 | return res.status(401).json({
7 | "success": false,
8 | "message": "Unauthorized"
9 | });
10 | }
11 | const token = req.headers.authorization.split(" ")[1];
12 |
13 | let decodeData = jwt.verify(token, process.env.JWT_SECRET);
14 | req.userId = decodeData?.id;
15 |
16 | next();
17 | } catch (error) {
18 | console.log(error);
19 | }
20 | };
21 |
22 | export default auth;
23 |
--------------------------------------------------------------------------------
/server/models/Questions.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const QuestionSchema = mongoose.Schema({
4 | questionTitle: { type: String, required: "Question must have a title" },
5 | questionBody: { type: String, required: "Question must have a body" },
6 | questionTags: { type: [String], required: "Question must have a tags" },
7 | noOfAnswers: { type: Number, default: 0 },
8 | upVote: { type: [String], default: [] },
9 | downVote: { type: [String], default: [] },
10 | userPosted: { type: String, required: "Question must have an author" },
11 | userId: { type: String },
12 | askedOn: { type: Date, default: Date.now },
13 | answer: [
14 | {
15 | answerBody: String,
16 | userAnswered: String,
17 | userId: String,
18 | answeredOn: { type: Date, default: Date.now },
19 | },
20 | ],
21 | });
22 |
23 | export default mongoose.model("Question", QuestionSchema);
24 |
--------------------------------------------------------------------------------
/server/models/auth.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const userSchema = mongoose.Schema({
4 | name: { type: String, required: true },
5 | email: { type: String, required: true },
6 | password: { type: String, required: true },
7 | about: { type: String },
8 | tags: { type: [String] },
9 | joinedOn: { type: Date, default: Date.now },
10 | });
11 |
12 | export default mongoose.model("User", userSchema);
13 |
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "server",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "bcryptjs": "^2.4.3",
13 | "cors": "^2.8.5",
14 | "dotenv": "^10.0.0",
15 | "express": "^4.17.1",
16 | "jsonwebtoken": "^8.5.1",
17 | "mongoose": "^6.0.12",
18 | "nodemon": "^2.0.14"
19 | }
20 | },
21 | "node_modules/@aws-crypto/crc32": {
22 | "version": "3.0.0",
23 | "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz",
24 | "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==",
25 | "optional": true,
26 | "dependencies": {
27 | "@aws-crypto/util": "^3.0.0",
28 | "@aws-sdk/types": "^3.222.0",
29 | "tslib": "^1.11.1"
30 | }
31 | },
32 | "node_modules/@aws-crypto/crc32/node_modules/tslib": {
33 | "version": "1.14.1",
34 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
35 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
36 | "optional": true
37 | },
38 | "node_modules/@aws-crypto/ie11-detection": {
39 | "version": "3.0.0",
40 | "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz",
41 | "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==",
42 | "optional": true,
43 | "dependencies": {
44 | "tslib": "^1.11.1"
45 | }
46 | },
47 | "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": {
48 | "version": "1.14.1",
49 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
50 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
51 | "optional": true
52 | },
53 | "node_modules/@aws-crypto/sha256-browser": {
54 | "version": "3.0.0",
55 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz",
56 | "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==",
57 | "optional": true,
58 | "dependencies": {
59 | "@aws-crypto/ie11-detection": "^3.0.0",
60 | "@aws-crypto/sha256-js": "^3.0.0",
61 | "@aws-crypto/supports-web-crypto": "^3.0.0",
62 | "@aws-crypto/util": "^3.0.0",
63 | "@aws-sdk/types": "^3.222.0",
64 | "@aws-sdk/util-locate-window": "^3.0.0",
65 | "@aws-sdk/util-utf8-browser": "^3.0.0",
66 | "tslib": "^1.11.1"
67 | }
68 | },
69 | "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": {
70 | "version": "1.14.1",
71 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
72 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
73 | "optional": true
74 | },
75 | "node_modules/@aws-crypto/sha256-js": {
76 | "version": "3.0.0",
77 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz",
78 | "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==",
79 | "optional": true,
80 | "dependencies": {
81 | "@aws-crypto/util": "^3.0.0",
82 | "@aws-sdk/types": "^3.222.0",
83 | "tslib": "^1.11.1"
84 | }
85 | },
86 | "node_modules/@aws-crypto/sha256-js/node_modules/tslib": {
87 | "version": "1.14.1",
88 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
89 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
90 | "optional": true
91 | },
92 | "node_modules/@aws-crypto/supports-web-crypto": {
93 | "version": "3.0.0",
94 | "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz",
95 | "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==",
96 | "optional": true,
97 | "dependencies": {
98 | "tslib": "^1.11.1"
99 | }
100 | },
101 | "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": {
102 | "version": "1.14.1",
103 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
104 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
105 | "optional": true
106 | },
107 | "node_modules/@aws-crypto/util": {
108 | "version": "3.0.0",
109 | "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz",
110 | "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==",
111 | "optional": true,
112 | "dependencies": {
113 | "@aws-sdk/types": "^3.222.0",
114 | "@aws-sdk/util-utf8-browser": "^3.0.0",
115 | "tslib": "^1.11.1"
116 | }
117 | },
118 | "node_modules/@aws-crypto/util/node_modules/tslib": {
119 | "version": "1.14.1",
120 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
121 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
122 | "optional": true
123 | },
124 | "node_modules/@aws-sdk/client-cognito-identity": {
125 | "version": "3.379.1",
126 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.379.1.tgz",
127 | "integrity": "sha512-aONC8IyC54OMcdoRCqI+Fw4VIIlonWmFdLDyZPfGoqwYpe/Vqz7DPF7s/ohqiZBSpEt2SzZeKHEpmkBPR8fpkw==",
128 | "optional": true,
129 | "dependencies": {
130 | "@aws-crypto/sha256-browser": "3.0.0",
131 | "@aws-crypto/sha256-js": "3.0.0",
132 | "@aws-sdk/client-sts": "3.379.1",
133 | "@aws-sdk/credential-provider-node": "3.379.1",
134 | "@aws-sdk/middleware-host-header": "3.379.1",
135 | "@aws-sdk/middleware-logger": "3.378.0",
136 | "@aws-sdk/middleware-recursion-detection": "3.378.0",
137 | "@aws-sdk/middleware-signing": "3.379.1",
138 | "@aws-sdk/middleware-user-agent": "3.379.1",
139 | "@aws-sdk/types": "3.378.0",
140 | "@aws-sdk/util-endpoints": "3.378.0",
141 | "@aws-sdk/util-user-agent-browser": "3.378.0",
142 | "@aws-sdk/util-user-agent-node": "3.378.0",
143 | "@smithy/config-resolver": "^2.0.1",
144 | "@smithy/fetch-http-handler": "^2.0.1",
145 | "@smithy/hash-node": "^2.0.1",
146 | "@smithy/invalid-dependency": "^2.0.1",
147 | "@smithy/middleware-content-length": "^2.0.1",
148 | "@smithy/middleware-endpoint": "^2.0.1",
149 | "@smithy/middleware-retry": "^2.0.1",
150 | "@smithy/middleware-serde": "^2.0.1",
151 | "@smithy/middleware-stack": "^2.0.0",
152 | "@smithy/node-config-provider": "^2.0.1",
153 | "@smithy/node-http-handler": "^2.0.1",
154 | "@smithy/protocol-http": "^2.0.1",
155 | "@smithy/smithy-client": "^2.0.1",
156 | "@smithy/types": "^2.0.2",
157 | "@smithy/url-parser": "^2.0.1",
158 | "@smithy/util-base64": "^2.0.0",
159 | "@smithy/util-body-length-browser": "^2.0.0",
160 | "@smithy/util-body-length-node": "^2.0.0",
161 | "@smithy/util-defaults-mode-browser": "^2.0.1",
162 | "@smithy/util-defaults-mode-node": "^2.0.1",
163 | "@smithy/util-retry": "^2.0.0",
164 | "@smithy/util-utf8": "^2.0.0",
165 | "tslib": "^2.5.0"
166 | },
167 | "engines": {
168 | "node": ">=14.0.0"
169 | }
170 | },
171 | "node_modules/@aws-sdk/client-sso": {
172 | "version": "3.379.1",
173 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.379.1.tgz",
174 | "integrity": "sha512-2N16TPnRcq+seNP8VY/Zq7kfnrUOrJMbVNpyDZWGe5Qglua3n8v/FzxmXFNI87MiSODq8IHtiXhggWhefCd+TA==",
175 | "optional": true,
176 | "dependencies": {
177 | "@aws-crypto/sha256-browser": "3.0.0",
178 | "@aws-crypto/sha256-js": "3.0.0",
179 | "@aws-sdk/middleware-host-header": "3.379.1",
180 | "@aws-sdk/middleware-logger": "3.378.0",
181 | "@aws-sdk/middleware-recursion-detection": "3.378.0",
182 | "@aws-sdk/middleware-user-agent": "3.379.1",
183 | "@aws-sdk/types": "3.378.0",
184 | "@aws-sdk/util-endpoints": "3.378.0",
185 | "@aws-sdk/util-user-agent-browser": "3.378.0",
186 | "@aws-sdk/util-user-agent-node": "3.378.0",
187 | "@smithy/config-resolver": "^2.0.1",
188 | "@smithy/fetch-http-handler": "^2.0.1",
189 | "@smithy/hash-node": "^2.0.1",
190 | "@smithy/invalid-dependency": "^2.0.1",
191 | "@smithy/middleware-content-length": "^2.0.1",
192 | "@smithy/middleware-endpoint": "^2.0.1",
193 | "@smithy/middleware-retry": "^2.0.1",
194 | "@smithy/middleware-serde": "^2.0.1",
195 | "@smithy/middleware-stack": "^2.0.0",
196 | "@smithy/node-config-provider": "^2.0.1",
197 | "@smithy/node-http-handler": "^2.0.1",
198 | "@smithy/protocol-http": "^2.0.1",
199 | "@smithy/smithy-client": "^2.0.1",
200 | "@smithy/types": "^2.0.2",
201 | "@smithy/url-parser": "^2.0.1",
202 | "@smithy/util-base64": "^2.0.0",
203 | "@smithy/util-body-length-browser": "^2.0.0",
204 | "@smithy/util-body-length-node": "^2.0.0",
205 | "@smithy/util-defaults-mode-browser": "^2.0.1",
206 | "@smithy/util-defaults-mode-node": "^2.0.1",
207 | "@smithy/util-retry": "^2.0.0",
208 | "@smithy/util-utf8": "^2.0.0",
209 | "tslib": "^2.5.0"
210 | },
211 | "engines": {
212 | "node": ">=14.0.0"
213 | }
214 | },
215 | "node_modules/@aws-sdk/client-sso-oidc": {
216 | "version": "3.379.1",
217 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.379.1.tgz",
218 | "integrity": "sha512-B6hZ2ysPyvafCMf6gls1jHI/IUviVZ4+TURpNfUBqThg/hZ1IMxc4BLkXca6VlgzYR+bWU8GKiClS9fFH6mu0g==",
219 | "optional": true,
220 | "dependencies": {
221 | "@aws-crypto/sha256-browser": "3.0.0",
222 | "@aws-crypto/sha256-js": "3.0.0",
223 | "@aws-sdk/middleware-host-header": "3.379.1",
224 | "@aws-sdk/middleware-logger": "3.378.0",
225 | "@aws-sdk/middleware-recursion-detection": "3.378.0",
226 | "@aws-sdk/middleware-user-agent": "3.379.1",
227 | "@aws-sdk/types": "3.378.0",
228 | "@aws-sdk/util-endpoints": "3.378.0",
229 | "@aws-sdk/util-user-agent-browser": "3.378.0",
230 | "@aws-sdk/util-user-agent-node": "3.378.0",
231 | "@smithy/config-resolver": "^2.0.1",
232 | "@smithy/fetch-http-handler": "^2.0.1",
233 | "@smithy/hash-node": "^2.0.1",
234 | "@smithy/invalid-dependency": "^2.0.1",
235 | "@smithy/middleware-content-length": "^2.0.1",
236 | "@smithy/middleware-endpoint": "^2.0.1",
237 | "@smithy/middleware-retry": "^2.0.1",
238 | "@smithy/middleware-serde": "^2.0.1",
239 | "@smithy/middleware-stack": "^2.0.0",
240 | "@smithy/node-config-provider": "^2.0.1",
241 | "@smithy/node-http-handler": "^2.0.1",
242 | "@smithy/protocol-http": "^2.0.1",
243 | "@smithy/smithy-client": "^2.0.1",
244 | "@smithy/types": "^2.0.2",
245 | "@smithy/url-parser": "^2.0.1",
246 | "@smithy/util-base64": "^2.0.0",
247 | "@smithy/util-body-length-browser": "^2.0.0",
248 | "@smithy/util-body-length-node": "^2.0.0",
249 | "@smithy/util-defaults-mode-browser": "^2.0.1",
250 | "@smithy/util-defaults-mode-node": "^2.0.1",
251 | "@smithy/util-retry": "^2.0.0",
252 | "@smithy/util-utf8": "^2.0.0",
253 | "tslib": "^2.5.0"
254 | },
255 | "engines": {
256 | "node": ">=14.0.0"
257 | }
258 | },
259 | "node_modules/@aws-sdk/client-sts": {
260 | "version": "3.379.1",
261 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.379.1.tgz",
262 | "integrity": "sha512-gEnKuk9bYjThvmxCgOgCn1qa+rRX8IgIRE2+xhbWhlpDanozhkDq9aMB5moX4tBNYQEmi1LtGD+JOvOoZRnToQ==",
263 | "optional": true,
264 | "dependencies": {
265 | "@aws-crypto/sha256-browser": "3.0.0",
266 | "@aws-crypto/sha256-js": "3.0.0",
267 | "@aws-sdk/credential-provider-node": "3.379.1",
268 | "@aws-sdk/middleware-host-header": "3.379.1",
269 | "@aws-sdk/middleware-logger": "3.378.0",
270 | "@aws-sdk/middleware-recursion-detection": "3.378.0",
271 | "@aws-sdk/middleware-sdk-sts": "3.379.1",
272 | "@aws-sdk/middleware-signing": "3.379.1",
273 | "@aws-sdk/middleware-user-agent": "3.379.1",
274 | "@aws-sdk/types": "3.378.0",
275 | "@aws-sdk/util-endpoints": "3.378.0",
276 | "@aws-sdk/util-user-agent-browser": "3.378.0",
277 | "@aws-sdk/util-user-agent-node": "3.378.0",
278 | "@smithy/config-resolver": "^2.0.1",
279 | "@smithy/fetch-http-handler": "^2.0.1",
280 | "@smithy/hash-node": "^2.0.1",
281 | "@smithy/invalid-dependency": "^2.0.1",
282 | "@smithy/middleware-content-length": "^2.0.1",
283 | "@smithy/middleware-endpoint": "^2.0.1",
284 | "@smithy/middleware-retry": "^2.0.1",
285 | "@smithy/middleware-serde": "^2.0.1",
286 | "@smithy/middleware-stack": "^2.0.0",
287 | "@smithy/node-config-provider": "^2.0.1",
288 | "@smithy/node-http-handler": "^2.0.1",
289 | "@smithy/protocol-http": "^2.0.1",
290 | "@smithy/smithy-client": "^2.0.1",
291 | "@smithy/types": "^2.0.2",
292 | "@smithy/url-parser": "^2.0.1",
293 | "@smithy/util-base64": "^2.0.0",
294 | "@smithy/util-body-length-browser": "^2.0.0",
295 | "@smithy/util-body-length-node": "^2.0.0",
296 | "@smithy/util-defaults-mode-browser": "^2.0.1",
297 | "@smithy/util-defaults-mode-node": "^2.0.1",
298 | "@smithy/util-retry": "^2.0.0",
299 | "@smithy/util-utf8": "^2.0.0",
300 | "fast-xml-parser": "4.2.5",
301 | "tslib": "^2.5.0"
302 | },
303 | "engines": {
304 | "node": ">=14.0.0"
305 | }
306 | },
307 | "node_modules/@aws-sdk/credential-provider-cognito-identity": {
308 | "version": "3.379.1",
309 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.379.1.tgz",
310 | "integrity": "sha512-29X4nxo+47TeENgCpaTeMaK66cn7Uv7Fo4HPvGoevtWljqMqlSSNwQgmvpvqkQWGNtG6Ma/7GXkPMBuoqpwC8g==",
311 | "optional": true,
312 | "dependencies": {
313 | "@aws-sdk/client-cognito-identity": "3.379.1",
314 | "@aws-sdk/types": "3.378.0",
315 | "@smithy/property-provider": "^2.0.0",
316 | "@smithy/types": "^2.0.2",
317 | "tslib": "^2.5.0"
318 | },
319 | "engines": {
320 | "node": ">=14.0.0"
321 | }
322 | },
323 | "node_modules/@aws-sdk/credential-provider-env": {
324 | "version": "3.378.0",
325 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.378.0.tgz",
326 | "integrity": "sha512-B2OVdO9kBClDwGgWTBLAQwFV8qYTYGyVujg++1FZFSFMt8ORFdZ5fNpErvJtiSjYiOOQMzyBeSNhKyYNXCiJjQ==",
327 | "optional": true,
328 | "dependencies": {
329 | "@aws-sdk/types": "3.378.0",
330 | "@smithy/property-provider": "^2.0.0",
331 | "@smithy/types": "^2.0.2",
332 | "tslib": "^2.5.0"
333 | },
334 | "engines": {
335 | "node": ">=14.0.0"
336 | }
337 | },
338 | "node_modules/@aws-sdk/credential-provider-ini": {
339 | "version": "3.379.1",
340 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.379.1.tgz",
341 | "integrity": "sha512-YhEsJIskzCFwIIKiMN9GSHQkgWwj/b7rq0ofhsXsCRimFtdVkmMlB9veE6vtFAuXpX/WOGWdlWek1az0V22uuw==",
342 | "optional": true,
343 | "dependencies": {
344 | "@aws-sdk/credential-provider-env": "3.378.0",
345 | "@aws-sdk/credential-provider-process": "3.378.0",
346 | "@aws-sdk/credential-provider-sso": "3.379.1",
347 | "@aws-sdk/credential-provider-web-identity": "3.378.0",
348 | "@aws-sdk/types": "3.378.0",
349 | "@smithy/credential-provider-imds": "^2.0.0",
350 | "@smithy/property-provider": "^2.0.0",
351 | "@smithy/shared-ini-file-loader": "^2.0.0",
352 | "@smithy/types": "^2.0.2",
353 | "tslib": "^2.5.0"
354 | },
355 | "engines": {
356 | "node": ">=14.0.0"
357 | }
358 | },
359 | "node_modules/@aws-sdk/credential-provider-node": {
360 | "version": "3.379.1",
361 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.379.1.tgz",
362 | "integrity": "sha512-39Y4OHKn6a8lY8YJhSLLw08aZytWxfvSjM4ObIEnE6hjLl8gsL9vROKKITsh3q6iGQ1EDSWMWZL50aOh3LJUIg==",
363 | "optional": true,
364 | "dependencies": {
365 | "@aws-sdk/credential-provider-env": "3.378.0",
366 | "@aws-sdk/credential-provider-ini": "3.379.1",
367 | "@aws-sdk/credential-provider-process": "3.378.0",
368 | "@aws-sdk/credential-provider-sso": "3.379.1",
369 | "@aws-sdk/credential-provider-web-identity": "3.378.0",
370 | "@aws-sdk/types": "3.378.0",
371 | "@smithy/credential-provider-imds": "^2.0.0",
372 | "@smithy/property-provider": "^2.0.0",
373 | "@smithy/shared-ini-file-loader": "^2.0.0",
374 | "@smithy/types": "^2.0.2",
375 | "tslib": "^2.5.0"
376 | },
377 | "engines": {
378 | "node": ">=14.0.0"
379 | }
380 | },
381 | "node_modules/@aws-sdk/credential-provider-process": {
382 | "version": "3.378.0",
383 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.378.0.tgz",
384 | "integrity": "sha512-KFTIy7u+wXj3eDua4rgS0tODzMnXtXhAm1RxzCW9FL5JLBBrd82ymCj1Dp72217Sw5Do6NjCnDTTNkCHZMA77w==",
385 | "optional": true,
386 | "dependencies": {
387 | "@aws-sdk/types": "3.378.0",
388 | "@smithy/property-provider": "^2.0.0",
389 | "@smithy/shared-ini-file-loader": "^2.0.0",
390 | "@smithy/types": "^2.0.2",
391 | "tslib": "^2.5.0"
392 | },
393 | "engines": {
394 | "node": ">=14.0.0"
395 | }
396 | },
397 | "node_modules/@aws-sdk/credential-provider-sso": {
398 | "version": "3.379.1",
399 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.379.1.tgz",
400 | "integrity": "sha512-PhGtu1+JbUntYP/5CSfazQhWsjUBiksEuhg9fLhYl5OAgZVjVygbgoNVUz/gM7gZJSEMsasTazkn7yZVzO/k7w==",
401 | "optional": true,
402 | "dependencies": {
403 | "@aws-sdk/client-sso": "3.379.1",
404 | "@aws-sdk/token-providers": "3.379.1",
405 | "@aws-sdk/types": "3.378.0",
406 | "@smithy/property-provider": "^2.0.0",
407 | "@smithy/shared-ini-file-loader": "^2.0.0",
408 | "@smithy/types": "^2.0.2",
409 | "tslib": "^2.5.0"
410 | },
411 | "engines": {
412 | "node": ">=14.0.0"
413 | }
414 | },
415 | "node_modules/@aws-sdk/credential-provider-web-identity": {
416 | "version": "3.378.0",
417 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.378.0.tgz",
418 | "integrity": "sha512-GWjydOszhc4xDF8xuPtBvboglXQr0gwCW1oHAvmLcOT38+Hd6qnKywnMSeoXYRPgoKfF9TkWQgW1jxplzCG0UA==",
419 | "optional": true,
420 | "dependencies": {
421 | "@aws-sdk/types": "3.378.0",
422 | "@smithy/property-provider": "^2.0.0",
423 | "@smithy/types": "^2.0.2",
424 | "tslib": "^2.5.0"
425 | },
426 | "engines": {
427 | "node": ">=14.0.0"
428 | }
429 | },
430 | "node_modules/@aws-sdk/credential-providers": {
431 | "version": "3.379.1",
432 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.379.1.tgz",
433 | "integrity": "sha512-srPdRQmavvWAwtrlYqo5GaIhIH0bhMl0knzxIDUf81aBfitNKACWwnbML7TpL/dWSPH2b7ciOBWneK1o1GKNLg==",
434 | "optional": true,
435 | "dependencies": {
436 | "@aws-sdk/client-cognito-identity": "3.379.1",
437 | "@aws-sdk/client-sso": "3.379.1",
438 | "@aws-sdk/client-sts": "3.379.1",
439 | "@aws-sdk/credential-provider-cognito-identity": "3.379.1",
440 | "@aws-sdk/credential-provider-env": "3.378.0",
441 | "@aws-sdk/credential-provider-ini": "3.379.1",
442 | "@aws-sdk/credential-provider-node": "3.379.1",
443 | "@aws-sdk/credential-provider-process": "3.378.0",
444 | "@aws-sdk/credential-provider-sso": "3.379.1",
445 | "@aws-sdk/credential-provider-web-identity": "3.378.0",
446 | "@aws-sdk/types": "3.378.0",
447 | "@smithy/credential-provider-imds": "^2.0.0",
448 | "@smithy/property-provider": "^2.0.0",
449 | "@smithy/types": "^2.0.2",
450 | "tslib": "^2.5.0"
451 | },
452 | "engines": {
453 | "node": ">=14.0.0"
454 | }
455 | },
456 | "node_modules/@aws-sdk/middleware-host-header": {
457 | "version": "3.379.1",
458 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.379.1.tgz",
459 | "integrity": "sha512-LI4KpAFWNWVr2aH2vRVblr0Y8tvDz23lj8LOmbDmCrzd5M21nxuocI/8nEAQj55LiTIf9Zs+dHCdsyegnFXdrA==",
460 | "optional": true,
461 | "dependencies": {
462 | "@aws-sdk/types": "3.378.0",
463 | "@smithy/protocol-http": "^2.0.1",
464 | "@smithy/types": "^2.0.2",
465 | "tslib": "^2.5.0"
466 | },
467 | "engines": {
468 | "node": ">=14.0.0"
469 | }
470 | },
471 | "node_modules/@aws-sdk/middleware-logger": {
472 | "version": "3.378.0",
473 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.378.0.tgz",
474 | "integrity": "sha512-l1DyaDLm3KeBMNMuANI3scWh8Xvu248x+vw6Z7ExWOhGXFmQ1MW7YvASg/SdxWkhlF9HmkkTif1LdMB22x6QDA==",
475 | "optional": true,
476 | "dependencies": {
477 | "@aws-sdk/types": "3.378.0",
478 | "@smithy/types": "^2.0.2",
479 | "tslib": "^2.5.0"
480 | },
481 | "engines": {
482 | "node": ">=14.0.0"
483 | }
484 | },
485 | "node_modules/@aws-sdk/middleware-recursion-detection": {
486 | "version": "3.378.0",
487 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.378.0.tgz",
488 | "integrity": "sha512-mUMfHAz0oGNIWiTZHTVJb+I515Hqs2zx1j36Le4MMiiaMkPW1SRUF1FIwGuc1wh6E8jB5q+XfEMriDjRi4TZRA==",
489 | "optional": true,
490 | "dependencies": {
491 | "@aws-sdk/types": "3.378.0",
492 | "@smithy/protocol-http": "^2.0.1",
493 | "@smithy/types": "^2.0.2",
494 | "tslib": "^2.5.0"
495 | },
496 | "engines": {
497 | "node": ">=14.0.0"
498 | }
499 | },
500 | "node_modules/@aws-sdk/middleware-sdk-sts": {
501 | "version": "3.379.1",
502 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.379.1.tgz",
503 | "integrity": "sha512-SK3gSyT0XbLiY12+AjLFYL9YngxOXHnZF3Z33Cdd4a+AUYrVBV7JBEEGD1Nlwrcmko+3XgaKlmgUaR5s91MYvg==",
504 | "optional": true,
505 | "dependencies": {
506 | "@aws-sdk/middleware-signing": "3.379.1",
507 | "@aws-sdk/types": "3.378.0",
508 | "@smithy/types": "^2.0.2",
509 | "tslib": "^2.5.0"
510 | },
511 | "engines": {
512 | "node": ">=14.0.0"
513 | }
514 | },
515 | "node_modules/@aws-sdk/middleware-signing": {
516 | "version": "3.379.1",
517 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.379.1.tgz",
518 | "integrity": "sha512-kBk2ZUvR84EM4fICjr8K+Ykpf8SI1UzzPp2/UVYZ0X+4H/ZCjfSqohGRwHykMqeplne9qHSL7/rGJs1H3l3gPg==",
519 | "optional": true,
520 | "dependencies": {
521 | "@aws-sdk/types": "3.378.0",
522 | "@smithy/property-provider": "^2.0.0",
523 | "@smithy/protocol-http": "^2.0.1",
524 | "@smithy/signature-v4": "^2.0.0",
525 | "@smithy/types": "^2.0.2",
526 | "@smithy/util-middleware": "^2.0.0",
527 | "tslib": "^2.5.0"
528 | },
529 | "engines": {
530 | "node": ">=14.0.0"
531 | }
532 | },
533 | "node_modules/@aws-sdk/middleware-user-agent": {
534 | "version": "3.379.1",
535 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.379.1.tgz",
536 | "integrity": "sha512-4zIGeAIuutcRieAvovs82uBNhJBHuxfxaAUqrKiw49xUBG7xeNVUl+DYPSpbALbEIy4ujfwWCBOOWVCt6dyUZg==",
537 | "optional": true,
538 | "dependencies": {
539 | "@aws-sdk/types": "3.378.0",
540 | "@aws-sdk/util-endpoints": "3.378.0",
541 | "@smithy/protocol-http": "^2.0.1",
542 | "@smithy/types": "^2.0.2",
543 | "tslib": "^2.5.0"
544 | },
545 | "engines": {
546 | "node": ">=14.0.0"
547 | }
548 | },
549 | "node_modules/@aws-sdk/token-providers": {
550 | "version": "3.379.1",
551 | "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.379.1.tgz",
552 | "integrity": "sha512-NlYPkArJ7A/txCrjqqkje+4hsv7pSOqm+Qdx3BUIOc7PRYrBVs/XwThxUkGceSntVXoNlO8g9DFL0NY53/wb8Q==",
553 | "optional": true,
554 | "dependencies": {
555 | "@aws-sdk/client-sso-oidc": "3.379.1",
556 | "@aws-sdk/types": "3.378.0",
557 | "@smithy/property-provider": "^2.0.0",
558 | "@smithy/shared-ini-file-loader": "^2.0.0",
559 | "@smithy/types": "^2.0.2",
560 | "tslib": "^2.5.0"
561 | },
562 | "engines": {
563 | "node": ">=14.0.0"
564 | }
565 | },
566 | "node_modules/@aws-sdk/types": {
567 | "version": "3.378.0",
568 | "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.378.0.tgz",
569 | "integrity": "sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w==",
570 | "optional": true,
571 | "dependencies": {
572 | "@smithy/types": "^2.0.2",
573 | "tslib": "^2.5.0"
574 | },
575 | "engines": {
576 | "node": ">=14.0.0"
577 | }
578 | },
579 | "node_modules/@aws-sdk/util-endpoints": {
580 | "version": "3.378.0",
581 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.378.0.tgz",
582 | "integrity": "sha512-NU5C2l2xAXxpyB5nT0fIhahLPlJoJdzHWw4uC53KH9b4PrjHtgvgCN8beIsD3QxyfgeoM4A5J9Auo6WurfRnLw==",
583 | "optional": true,
584 | "dependencies": {
585 | "@aws-sdk/types": "3.378.0",
586 | "tslib": "^2.5.0"
587 | },
588 | "engines": {
589 | "node": ">=14.0.0"
590 | }
591 | },
592 | "node_modules/@aws-sdk/util-locate-window": {
593 | "version": "3.310.0",
594 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz",
595 | "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==",
596 | "optional": true,
597 | "dependencies": {
598 | "tslib": "^2.5.0"
599 | },
600 | "engines": {
601 | "node": ">=14.0.0"
602 | }
603 | },
604 | "node_modules/@aws-sdk/util-user-agent-browser": {
605 | "version": "3.378.0",
606 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.378.0.tgz",
607 | "integrity": "sha512-FSCpagzftK1W+m7Ar6lpX7/Gr9y5P56nhFYz8U4EYQ4PkufS6czWX9YW+/FA5OYV0vlQ/SvPqMnzoHIPUNhZrQ==",
608 | "optional": true,
609 | "dependencies": {
610 | "@aws-sdk/types": "3.378.0",
611 | "@smithy/types": "^2.0.2",
612 | "bowser": "^2.11.0",
613 | "tslib": "^2.5.0"
614 | }
615 | },
616 | "node_modules/@aws-sdk/util-user-agent-node": {
617 | "version": "3.378.0",
618 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.378.0.tgz",
619 | "integrity": "sha512-IdwVJV0E96MkJeFte4dlWqvB+oiqCiZ5lOlheY3W9NynTuuX0GGYNC8Y9yIsV8Oava1+ujpJq0ww6qXdYxmO4A==",
620 | "optional": true,
621 | "dependencies": {
622 | "@aws-sdk/types": "3.378.0",
623 | "@smithy/node-config-provider": "^2.0.1",
624 | "@smithy/types": "^2.0.2",
625 | "tslib": "^2.5.0"
626 | },
627 | "engines": {
628 | "node": ">=14.0.0"
629 | },
630 | "peerDependencies": {
631 | "aws-crt": ">=1.0.0"
632 | },
633 | "peerDependenciesMeta": {
634 | "aws-crt": {
635 | "optional": true
636 | }
637 | }
638 | },
639 | "node_modules/@aws-sdk/util-utf8-browser": {
640 | "version": "3.259.0",
641 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz",
642 | "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==",
643 | "optional": true,
644 | "dependencies": {
645 | "tslib": "^2.3.1"
646 | }
647 | },
648 | "node_modules/@smithy/abort-controller": {
649 | "version": "2.0.1",
650 | "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.1.tgz",
651 | "integrity": "sha512-0s7XjIbsTwZyUW9OwXQ8J6x1UiA1TNCh60Vaw56nHahL7kUZsLhmTlWiaxfLkFtO2Utkj8YewcpHTYpxaTzO+w==",
652 | "optional": true,
653 | "dependencies": {
654 | "@smithy/types": "^2.0.2",
655 | "tslib": "^2.5.0"
656 | },
657 | "engines": {
658 | "node": ">=14.0.0"
659 | }
660 | },
661 | "node_modules/@smithy/config-resolver": {
662 | "version": "2.0.1",
663 | "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.1.tgz",
664 | "integrity": "sha512-l83Pm7hV+8CBQOCmBRopWDtF+CURUJol7NsuPYvimiDhkC2F8Ba9T1imSFE+pD1UIJ9jlsDPAnZfPJT5cjnuEw==",
665 | "optional": true,
666 | "dependencies": {
667 | "@smithy/types": "^2.0.2",
668 | "@smithy/util-config-provider": "^2.0.0",
669 | "@smithy/util-middleware": "^2.0.0",
670 | "tslib": "^2.5.0"
671 | },
672 | "engines": {
673 | "node": ">=14.0.0"
674 | }
675 | },
676 | "node_modules/@smithy/credential-provider-imds": {
677 | "version": "2.0.1",
678 | "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.1.tgz",
679 | "integrity": "sha512-8VxriuRINNEfVZjEFKBY75y9ZWAx73DZ5K/u+3LmB6r8WR2h3NaFxFKMlwlq0uzNdGhD1ouKBn9XWEGYHKiPLw==",
680 | "optional": true,
681 | "dependencies": {
682 | "@smithy/node-config-provider": "^2.0.1",
683 | "@smithy/property-provider": "^2.0.1",
684 | "@smithy/types": "^2.0.2",
685 | "@smithy/url-parser": "^2.0.1",
686 | "tslib": "^2.5.0"
687 | },
688 | "engines": {
689 | "node": ">=14.0.0"
690 | }
691 | },
692 | "node_modules/@smithy/eventstream-codec": {
693 | "version": "2.0.1",
694 | "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.1.tgz",
695 | "integrity": "sha512-/IiNB7gQM2y2ZC/GAWOWDa8+iXfhr1g9Xe5979cQEOdCWDISvrAiv18cn3OtIQUhbYOR3gm7QtCpkq1to2takQ==",
696 | "optional": true,
697 | "dependencies": {
698 | "@aws-crypto/crc32": "3.0.0",
699 | "@smithy/types": "^2.0.2",
700 | "@smithy/util-hex-encoding": "^2.0.0",
701 | "tslib": "^2.5.0"
702 | }
703 | },
704 | "node_modules/@smithy/fetch-http-handler": {
705 | "version": "2.0.1",
706 | "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.0.1.tgz",
707 | "integrity": "sha512-/SoU/ClazgcdOxgE4zA7RX8euiELwpsrKCSvulVQvu9zpmqJRyEJn8ZTWYFV17/eHOBdHTs9kqodhNhsNT+cUw==",
708 | "optional": true,
709 | "dependencies": {
710 | "@smithy/protocol-http": "^2.0.1",
711 | "@smithy/querystring-builder": "^2.0.1",
712 | "@smithy/types": "^2.0.2",
713 | "@smithy/util-base64": "^2.0.0",
714 | "tslib": "^2.5.0"
715 | }
716 | },
717 | "node_modules/@smithy/hash-node": {
718 | "version": "2.0.1",
719 | "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.1.tgz",
720 | "integrity": "sha512-oTKYimQdF4psX54ZonpcIE+MXjMUWFxLCNosjPkJPFQ9whRX0K/PFX/+JZGRQh3zO9RlEOEUIbhy9NO+Wha6hw==",
721 | "optional": true,
722 | "dependencies": {
723 | "@smithy/types": "^2.0.2",
724 | "@smithy/util-buffer-from": "^2.0.0",
725 | "@smithy/util-utf8": "^2.0.0",
726 | "tslib": "^2.5.0"
727 | },
728 | "engines": {
729 | "node": ">=14.0.0"
730 | }
731 | },
732 | "node_modules/@smithy/invalid-dependency": {
733 | "version": "2.0.1",
734 | "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.1.tgz",
735 | "integrity": "sha512-2q/Eb0AE662zwyMV+z+TL7deBwcHCgaZZGc0RItamBE8kak3MzCi/EZCNoFWoBfxgQ4jfR12wm8KKsSXhJzJtQ==",
736 | "optional": true,
737 | "dependencies": {
738 | "@smithy/types": "^2.0.2",
739 | "tslib": "^2.5.0"
740 | }
741 | },
742 | "node_modules/@smithy/is-array-buffer": {
743 | "version": "2.0.0",
744 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz",
745 | "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==",
746 | "optional": true,
747 | "dependencies": {
748 | "tslib": "^2.5.0"
749 | },
750 | "engines": {
751 | "node": ">=14.0.0"
752 | }
753 | },
754 | "node_modules/@smithy/middleware-content-length": {
755 | "version": "2.0.1",
756 | "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.1.tgz",
757 | "integrity": "sha512-IZhRSk5GkVBcrKaqPXddBS2uKhaqwBgaSgbBb1OJyGsKe7SxRFbclWS0LqOR9fKUkDl+3lL8E2ffpo6EQg0igw==",
758 | "optional": true,
759 | "dependencies": {
760 | "@smithy/protocol-http": "^2.0.1",
761 | "@smithy/types": "^2.0.2",
762 | "tslib": "^2.5.0"
763 | },
764 | "engines": {
765 | "node": ">=14.0.0"
766 | }
767 | },
768 | "node_modules/@smithy/middleware-endpoint": {
769 | "version": "2.0.1",
770 | "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.1.tgz",
771 | "integrity": "sha512-uz/KI1MBd9WHrrkVFZO4L4Wyv24raf0oR4EsOYEeG5jPJO5U+C7MZGLcMxX8gWERDn1sycBDqmGv8fjUMLxT6w==",
772 | "optional": true,
773 | "dependencies": {
774 | "@smithy/middleware-serde": "^2.0.1",
775 | "@smithy/types": "^2.0.2",
776 | "@smithy/url-parser": "^2.0.1",
777 | "@smithy/util-middleware": "^2.0.0",
778 | "tslib": "^2.5.0"
779 | },
780 | "engines": {
781 | "node": ">=14.0.0"
782 | }
783 | },
784 | "node_modules/@smithy/middleware-retry": {
785 | "version": "2.0.1",
786 | "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.1.tgz",
787 | "integrity": "sha512-NKHF4i0gjSyjO6C0ZyjEpNqzGgIu7s8HOK6oT/1Jqws2Q1GynR1xV8XTUs1gKXeaNRzbzKQRewHHmfPwZjOtHA==",
788 | "optional": true,
789 | "dependencies": {
790 | "@smithy/protocol-http": "^2.0.1",
791 | "@smithy/service-error-classification": "^2.0.0",
792 | "@smithy/types": "^2.0.2",
793 | "@smithy/util-middleware": "^2.0.0",
794 | "@smithy/util-retry": "^2.0.0",
795 | "tslib": "^2.5.0",
796 | "uuid": "^8.3.2"
797 | },
798 | "engines": {
799 | "node": ">=14.0.0"
800 | }
801 | },
802 | "node_modules/@smithy/middleware-serde": {
803 | "version": "2.0.1",
804 | "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.1.tgz",
805 | "integrity": "sha512-uKxPaC6ItH9ZXdpdqNtf8sda7GcU4SPMp0tomq/5lUg9oiMa/Q7+kD35MUrpKaX3IVXVrwEtkjCU9dogZ/RAUA==",
806 | "optional": true,
807 | "dependencies": {
808 | "@smithy/types": "^2.0.2",
809 | "tslib": "^2.5.0"
810 | },
811 | "engines": {
812 | "node": ">=14.0.0"
813 | }
814 | },
815 | "node_modules/@smithy/middleware-stack": {
816 | "version": "2.0.0",
817 | "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.0.tgz",
818 | "integrity": "sha512-31XC1xNF65nlbc16yuh3wwTudmqs6qy4EseQUGF8A/p2m/5wdd/cnXJqpniy/XvXVwkHPz/GwV36HqzHtIKATQ==",
819 | "optional": true,
820 | "dependencies": {
821 | "tslib": "^2.5.0"
822 | },
823 | "engines": {
824 | "node": ">=14.0.0"
825 | }
826 | },
827 | "node_modules/@smithy/node-config-provider": {
828 | "version": "2.0.1",
829 | "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.1.tgz",
830 | "integrity": "sha512-Zoel4CPkKRTQ2XxmozZUfqBYqjPKL53/SvTDhJHj+VBSiJy6MXRav1iDCyFPS92t40Uh+Yi+Km5Ch3hQ+c/zSA==",
831 | "optional": true,
832 | "dependencies": {
833 | "@smithy/property-provider": "^2.0.1",
834 | "@smithy/shared-ini-file-loader": "^2.0.1",
835 | "@smithy/types": "^2.0.2",
836 | "tslib": "^2.5.0"
837 | },
838 | "engines": {
839 | "node": ">=14.0.0"
840 | }
841 | },
842 | "node_modules/@smithy/node-http-handler": {
843 | "version": "2.0.1",
844 | "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.0.1.tgz",
845 | "integrity": "sha512-Zv3fxk3p9tsmPT2CKMsbuwbbxnq2gzLDIulxv+yI6aE+02WPYorObbbe9gh7SW3weadMODL1vTfOoJ9yFypDzg==",
846 | "optional": true,
847 | "dependencies": {
848 | "@smithy/abort-controller": "^2.0.1",
849 | "@smithy/protocol-http": "^2.0.1",
850 | "@smithy/querystring-builder": "^2.0.1",
851 | "@smithy/types": "^2.0.2",
852 | "tslib": "^2.5.0"
853 | },
854 | "engines": {
855 | "node": ">=14.0.0"
856 | }
857 | },
858 | "node_modules/@smithy/property-provider": {
859 | "version": "2.0.1",
860 | "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.1.tgz",
861 | "integrity": "sha512-pmJRyY9SF6sutWIktIhe+bUdSQDxv/qZ4mYr3/u+u45riTPN7nmRxPo+e4sjWVoM0caKFjRSlj3tf5teRFy0Vg==",
862 | "optional": true,
863 | "dependencies": {
864 | "@smithy/types": "^2.0.2",
865 | "tslib": "^2.5.0"
866 | },
867 | "engines": {
868 | "node": ">=14.0.0"
869 | }
870 | },
871 | "node_modules/@smithy/protocol-http": {
872 | "version": "2.0.1",
873 | "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-2.0.1.tgz",
874 | "integrity": "sha512-mrkMAp0wtaDEIkgRObWYxI1Kun1tm6Iu6rK+X4utb6Ah7Uc3Kk4VIWwK/rBHdYGReiLIrxFCB1rq4a2gyZnSgg==",
875 | "optional": true,
876 | "dependencies": {
877 | "@smithy/types": "^2.0.2",
878 | "tslib": "^2.5.0"
879 | },
880 | "engines": {
881 | "node": ">=14.0.0"
882 | }
883 | },
884 | "node_modules/@smithy/querystring-builder": {
885 | "version": "2.0.1",
886 | "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.1.tgz",
887 | "integrity": "sha512-bp+93WFzx1FojVEIeFPtG0A1pKsFdCUcZvVdZdRlmNooOUrz9Mm9bneRd8hDwAQ37pxiZkCOxopSXXRQN10mYw==",
888 | "optional": true,
889 | "dependencies": {
890 | "@smithy/types": "^2.0.2",
891 | "@smithy/util-uri-escape": "^2.0.0",
892 | "tslib": "^2.5.0"
893 | },
894 | "engines": {
895 | "node": ">=14.0.0"
896 | }
897 | },
898 | "node_modules/@smithy/querystring-parser": {
899 | "version": "2.0.1",
900 | "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.1.tgz",
901 | "integrity": "sha512-h+e7k1z+IvI2sSbUBG9Aq46JsgLl4UqIUl6aigAlRBj+P6ocNXpM6Yn1vMBw5ijtXeZbYpd1YvCxwDgdw3jhmg==",
902 | "optional": true,
903 | "dependencies": {
904 | "@smithy/types": "^2.0.2",
905 | "tslib": "^2.5.0"
906 | },
907 | "engines": {
908 | "node": ">=14.0.0"
909 | }
910 | },
911 | "node_modules/@smithy/service-error-classification": {
912 | "version": "2.0.0",
913 | "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.0.tgz",
914 | "integrity": "sha512-2z5Nafy1O0cTf69wKyNjGW/sNVMiqDnb4jgwfMG8ye8KnFJ5qmJpDccwIbJNhXIfbsxTg9SEec2oe1cexhMJvw==",
915 | "optional": true,
916 | "engines": {
917 | "node": ">=14.0.0"
918 | }
919 | },
920 | "node_modules/@smithy/shared-ini-file-loader": {
921 | "version": "2.0.1",
922 | "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.1.tgz",
923 | "integrity": "sha512-a463YiZrPGvM+F336rIF8pLfQsHAdCRAn/BiI/EWzg5xLoxbC7GSxIgliDDXrOu0z8gT3nhVsif85eU6jyct3A==",
924 | "optional": true,
925 | "dependencies": {
926 | "@smithy/types": "^2.0.2",
927 | "tslib": "^2.5.0"
928 | },
929 | "engines": {
930 | "node": ">=14.0.0"
931 | }
932 | },
933 | "node_modules/@smithy/signature-v4": {
934 | "version": "2.0.1",
935 | "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.1.tgz",
936 | "integrity": "sha512-jztv5Mirca42ilxmMDjzLdXcoAmRhZskGafGL49sRo5u7swEZcToEFrq6vtX5YMbSyTVrE9Teog5EFexY5Ff2Q==",
937 | "optional": true,
938 | "dependencies": {
939 | "@smithy/eventstream-codec": "^2.0.1",
940 | "@smithy/is-array-buffer": "^2.0.0",
941 | "@smithy/types": "^2.0.2",
942 | "@smithy/util-hex-encoding": "^2.0.0",
943 | "@smithy/util-middleware": "^2.0.0",
944 | "@smithy/util-uri-escape": "^2.0.0",
945 | "@smithy/util-utf8": "^2.0.0",
946 | "tslib": "^2.5.0"
947 | },
948 | "engines": {
949 | "node": ">=14.0.0"
950 | }
951 | },
952 | "node_modules/@smithy/smithy-client": {
953 | "version": "2.0.1",
954 | "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.0.1.tgz",
955 | "integrity": "sha512-LHC5m6tYpEu1iNbONfvMbwtErboyTZJfEIPoD78Ei5MVr36vZQCaCla5mvo36+q/a2NAk2//fA5Rx3I1Kf7+lQ==",
956 | "optional": true,
957 | "dependencies": {
958 | "@smithy/middleware-stack": "^2.0.0",
959 | "@smithy/types": "^2.0.2",
960 | "@smithy/util-stream": "^2.0.1",
961 | "tslib": "^2.5.0"
962 | },
963 | "engines": {
964 | "node": ">=14.0.0"
965 | }
966 | },
967 | "node_modules/@smithy/types": {
968 | "version": "2.0.2",
969 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz",
970 | "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==",
971 | "optional": true,
972 | "dependencies": {
973 | "tslib": "^2.5.0"
974 | },
975 | "engines": {
976 | "node": ">=14.0.0"
977 | }
978 | },
979 | "node_modules/@smithy/url-parser": {
980 | "version": "2.0.1",
981 | "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.1.tgz",
982 | "integrity": "sha512-NpHVOAwddo+OyyIoujDL9zGL96piHWrTNXqltWmBvlUoWgt1HPyBuKs6oHjioyFnNZXUqveTOkEEq0U5w6Uv8A==",
983 | "optional": true,
984 | "dependencies": {
985 | "@smithy/querystring-parser": "^2.0.1",
986 | "@smithy/types": "^2.0.2",
987 | "tslib": "^2.5.0"
988 | }
989 | },
990 | "node_modules/@smithy/util-base64": {
991 | "version": "2.0.0",
992 | "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.0.tgz",
993 | "integrity": "sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==",
994 | "optional": true,
995 | "dependencies": {
996 | "@smithy/util-buffer-from": "^2.0.0",
997 | "tslib": "^2.5.0"
998 | },
999 | "engines": {
1000 | "node": ">=14.0.0"
1001 | }
1002 | },
1003 | "node_modules/@smithy/util-body-length-browser": {
1004 | "version": "2.0.0",
1005 | "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz",
1006 | "integrity": "sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==",
1007 | "optional": true,
1008 | "dependencies": {
1009 | "tslib": "^2.5.0"
1010 | }
1011 | },
1012 | "node_modules/@smithy/util-body-length-node": {
1013 | "version": "2.0.0",
1014 | "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.0.0.tgz",
1015 | "integrity": "sha512-ZV7Z/WHTMxHJe/xL/56qZwSUcl63/5aaPAGjkfynJm4poILjdD4GmFI+V+YWabh2WJIjwTKZ5PNsuvPQKt93Mg==",
1016 | "optional": true,
1017 | "dependencies": {
1018 | "tslib": "^2.5.0"
1019 | },
1020 | "engines": {
1021 | "node": ">=14.0.0"
1022 | }
1023 | },
1024 | "node_modules/@smithy/util-buffer-from": {
1025 | "version": "2.0.0",
1026 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz",
1027 | "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==",
1028 | "optional": true,
1029 | "dependencies": {
1030 | "@smithy/is-array-buffer": "^2.0.0",
1031 | "tslib": "^2.5.0"
1032 | },
1033 | "engines": {
1034 | "node": ">=14.0.0"
1035 | }
1036 | },
1037 | "node_modules/@smithy/util-config-provider": {
1038 | "version": "2.0.0",
1039 | "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz",
1040 | "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==",
1041 | "optional": true,
1042 | "dependencies": {
1043 | "tslib": "^2.5.0"
1044 | },
1045 | "engines": {
1046 | "node": ">=14.0.0"
1047 | }
1048 | },
1049 | "node_modules/@smithy/util-defaults-mode-browser": {
1050 | "version": "2.0.1",
1051 | "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.1.tgz",
1052 | "integrity": "sha512-w72Qwsb+IaEYEFtYICn0Do42eFju78hTaBzzJfT107lFOPdbjWjKnFutV+6GL/nZd5HWXY7ccAKka++C3NrjHw==",
1053 | "optional": true,
1054 | "dependencies": {
1055 | "@smithy/property-provider": "^2.0.1",
1056 | "@smithy/types": "^2.0.2",
1057 | "bowser": "^2.11.0",
1058 | "tslib": "^2.5.0"
1059 | },
1060 | "engines": {
1061 | "node": ">= 10.0.0"
1062 | }
1063 | },
1064 | "node_modules/@smithy/util-defaults-mode-node": {
1065 | "version": "2.0.1",
1066 | "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.1.tgz",
1067 | "integrity": "sha512-dNF45caelEBambo0SgkzQ0v76m4YM+aFKZNTtSafy7P5dVF8TbjZuR2UX1A5gJABD9XK6lzN+v/9Yfzj/EDgGg==",
1068 | "optional": true,
1069 | "dependencies": {
1070 | "@smithy/config-resolver": "^2.0.1",
1071 | "@smithy/credential-provider-imds": "^2.0.1",
1072 | "@smithy/node-config-provider": "^2.0.1",
1073 | "@smithy/property-provider": "^2.0.1",
1074 | "@smithy/types": "^2.0.2",
1075 | "tslib": "^2.5.0"
1076 | },
1077 | "engines": {
1078 | "node": ">= 10.0.0"
1079 | }
1080 | },
1081 | "node_modules/@smithy/util-hex-encoding": {
1082 | "version": "2.0.0",
1083 | "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz",
1084 | "integrity": "sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==",
1085 | "optional": true,
1086 | "dependencies": {
1087 | "tslib": "^2.5.0"
1088 | },
1089 | "engines": {
1090 | "node": ">=14.0.0"
1091 | }
1092 | },
1093 | "node_modules/@smithy/util-middleware": {
1094 | "version": "2.0.0",
1095 | "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.0.tgz",
1096 | "integrity": "sha512-eCWX4ECuDHn1wuyyDdGdUWnT4OGyIzV0LN1xRttBFMPI9Ff/4heSHVxneyiMtOB//zpXWCha1/SWHJOZstG7kA==",
1097 | "optional": true,
1098 | "dependencies": {
1099 | "tslib": "^2.5.0"
1100 | },
1101 | "engines": {
1102 | "node": ">=14.0.0"
1103 | }
1104 | },
1105 | "node_modules/@smithy/util-retry": {
1106 | "version": "2.0.0",
1107 | "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.0.tgz",
1108 | "integrity": "sha512-/dvJ8afrElasuiiIttRJeoS2sy8YXpksQwiM/TcepqdRVp7u4ejd9C4IQURHNjlfPUT7Y6lCDSa2zQJbdHhVTg==",
1109 | "optional": true,
1110 | "dependencies": {
1111 | "@smithy/service-error-classification": "^2.0.0",
1112 | "tslib": "^2.5.0"
1113 | },
1114 | "engines": {
1115 | "node": ">= 14.0.0"
1116 | }
1117 | },
1118 | "node_modules/@smithy/util-stream": {
1119 | "version": "2.0.1",
1120 | "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.1.tgz",
1121 | "integrity": "sha512-2a0IOtwIKC46EEo7E7cxDN8u2jwOiYYJqcFKA6rd5rdXqKakHT2Gc+AqHWngr0IEHUfW92zX12wRQKwyoqZf2Q==",
1122 | "optional": true,
1123 | "dependencies": {
1124 | "@smithy/fetch-http-handler": "^2.0.1",
1125 | "@smithy/node-http-handler": "^2.0.1",
1126 | "@smithy/types": "^2.0.2",
1127 | "@smithy/util-base64": "^2.0.0",
1128 | "@smithy/util-buffer-from": "^2.0.0",
1129 | "@smithy/util-hex-encoding": "^2.0.0",
1130 | "@smithy/util-utf8": "^2.0.0",
1131 | "tslib": "^2.5.0"
1132 | },
1133 | "engines": {
1134 | "node": ">=14.0.0"
1135 | }
1136 | },
1137 | "node_modules/@smithy/util-uri-escape": {
1138 | "version": "2.0.0",
1139 | "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz",
1140 | "integrity": "sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==",
1141 | "optional": true,
1142 | "dependencies": {
1143 | "tslib": "^2.5.0"
1144 | },
1145 | "engines": {
1146 | "node": ">=14.0.0"
1147 | }
1148 | },
1149 | "node_modules/@smithy/util-utf8": {
1150 | "version": "2.0.0",
1151 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz",
1152 | "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==",
1153 | "optional": true,
1154 | "dependencies": {
1155 | "@smithy/util-buffer-from": "^2.0.0",
1156 | "tslib": "^2.5.0"
1157 | },
1158 | "engines": {
1159 | "node": ">=14.0.0"
1160 | }
1161 | },
1162 | "node_modules/@types/node": {
1163 | "version": "20.4.5",
1164 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
1165 | "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg=="
1166 | },
1167 | "node_modules/@types/webidl-conversions": {
1168 | "version": "7.0.0",
1169 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
1170 | "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
1171 | },
1172 | "node_modules/@types/whatwg-url": {
1173 | "version": "8.2.2",
1174 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz",
1175 | "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==",
1176 | "dependencies": {
1177 | "@types/node": "*",
1178 | "@types/webidl-conversions": "*"
1179 | }
1180 | },
1181 | "node_modules/abbrev": {
1182 | "version": "1.1.1",
1183 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
1184 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
1185 | },
1186 | "node_modules/accepts": {
1187 | "version": "1.3.8",
1188 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
1189 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
1190 | "dependencies": {
1191 | "mime-types": "~2.1.34",
1192 | "negotiator": "0.6.3"
1193 | },
1194 | "engines": {
1195 | "node": ">= 0.6"
1196 | }
1197 | },
1198 | "node_modules/anymatch": {
1199 | "version": "3.1.3",
1200 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
1201 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
1202 | "dependencies": {
1203 | "normalize-path": "^3.0.0",
1204 | "picomatch": "^2.0.4"
1205 | },
1206 | "engines": {
1207 | "node": ">= 8"
1208 | }
1209 | },
1210 | "node_modules/array-flatten": {
1211 | "version": "1.1.1",
1212 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
1213 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
1214 | },
1215 | "node_modules/balanced-match": {
1216 | "version": "1.0.2",
1217 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1218 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
1219 | },
1220 | "node_modules/base64-js": {
1221 | "version": "1.5.1",
1222 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
1223 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
1224 | "funding": [
1225 | {
1226 | "type": "github",
1227 | "url": "https://github.com/sponsors/feross"
1228 | },
1229 | {
1230 | "type": "patreon",
1231 | "url": "https://www.patreon.com/feross"
1232 | },
1233 | {
1234 | "type": "consulting",
1235 | "url": "https://feross.org/support"
1236 | }
1237 | ]
1238 | },
1239 | "node_modules/bcryptjs": {
1240 | "version": "2.4.3",
1241 | "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
1242 | "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
1243 | },
1244 | "node_modules/binary-extensions": {
1245 | "version": "2.2.0",
1246 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
1247 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
1248 | "engines": {
1249 | "node": ">=8"
1250 | }
1251 | },
1252 | "node_modules/body-parser": {
1253 | "version": "1.20.1",
1254 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
1255 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
1256 | "dependencies": {
1257 | "bytes": "3.1.2",
1258 | "content-type": "~1.0.4",
1259 | "debug": "2.6.9",
1260 | "depd": "2.0.0",
1261 | "destroy": "1.2.0",
1262 | "http-errors": "2.0.0",
1263 | "iconv-lite": "0.4.24",
1264 | "on-finished": "2.4.1",
1265 | "qs": "6.11.0",
1266 | "raw-body": "2.5.1",
1267 | "type-is": "~1.6.18",
1268 | "unpipe": "1.0.0"
1269 | },
1270 | "engines": {
1271 | "node": ">= 0.8",
1272 | "npm": "1.2.8000 || >= 1.4.16"
1273 | }
1274 | },
1275 | "node_modules/bowser": {
1276 | "version": "2.11.0",
1277 | "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
1278 | "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==",
1279 | "optional": true
1280 | },
1281 | "node_modules/brace-expansion": {
1282 | "version": "1.1.11",
1283 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1284 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1285 | "dependencies": {
1286 | "balanced-match": "^1.0.0",
1287 | "concat-map": "0.0.1"
1288 | }
1289 | },
1290 | "node_modules/braces": {
1291 | "version": "3.0.2",
1292 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
1293 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
1294 | "dependencies": {
1295 | "fill-range": "^7.0.1"
1296 | },
1297 | "engines": {
1298 | "node": ">=8"
1299 | }
1300 | },
1301 | "node_modules/bson": {
1302 | "version": "4.7.2",
1303 | "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz",
1304 | "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==",
1305 | "dependencies": {
1306 | "buffer": "^5.6.0"
1307 | },
1308 | "engines": {
1309 | "node": ">=6.9.0"
1310 | }
1311 | },
1312 | "node_modules/buffer": {
1313 | "version": "5.7.1",
1314 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
1315 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
1316 | "funding": [
1317 | {
1318 | "type": "github",
1319 | "url": "https://github.com/sponsors/feross"
1320 | },
1321 | {
1322 | "type": "patreon",
1323 | "url": "https://www.patreon.com/feross"
1324 | },
1325 | {
1326 | "type": "consulting",
1327 | "url": "https://feross.org/support"
1328 | }
1329 | ],
1330 | "dependencies": {
1331 | "base64-js": "^1.3.1",
1332 | "ieee754": "^1.1.13"
1333 | }
1334 | },
1335 | "node_modules/buffer-equal-constant-time": {
1336 | "version": "1.0.1",
1337 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
1338 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
1339 | },
1340 | "node_modules/bytes": {
1341 | "version": "3.1.2",
1342 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
1343 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
1344 | "engines": {
1345 | "node": ">= 0.8"
1346 | }
1347 | },
1348 | "node_modules/call-bind": {
1349 | "version": "1.0.2",
1350 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
1351 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
1352 | "dependencies": {
1353 | "function-bind": "^1.1.1",
1354 | "get-intrinsic": "^1.0.2"
1355 | },
1356 | "funding": {
1357 | "url": "https://github.com/sponsors/ljharb"
1358 | }
1359 | },
1360 | "node_modules/chokidar": {
1361 | "version": "3.5.3",
1362 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
1363 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
1364 | "funding": [
1365 | {
1366 | "type": "individual",
1367 | "url": "https://paulmillr.com/funding/"
1368 | }
1369 | ],
1370 | "dependencies": {
1371 | "anymatch": "~3.1.2",
1372 | "braces": "~3.0.2",
1373 | "glob-parent": "~5.1.2",
1374 | "is-binary-path": "~2.1.0",
1375 | "is-glob": "~4.0.1",
1376 | "normalize-path": "~3.0.0",
1377 | "readdirp": "~3.6.0"
1378 | },
1379 | "engines": {
1380 | "node": ">= 8.10.0"
1381 | },
1382 | "optionalDependencies": {
1383 | "fsevents": "~2.3.2"
1384 | }
1385 | },
1386 | "node_modules/concat-map": {
1387 | "version": "0.0.1",
1388 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1389 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
1390 | },
1391 | "node_modules/content-disposition": {
1392 | "version": "0.5.4",
1393 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
1394 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
1395 | "dependencies": {
1396 | "safe-buffer": "5.2.1"
1397 | },
1398 | "engines": {
1399 | "node": ">= 0.6"
1400 | }
1401 | },
1402 | "node_modules/content-type": {
1403 | "version": "1.0.5",
1404 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
1405 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
1406 | "engines": {
1407 | "node": ">= 0.6"
1408 | }
1409 | },
1410 | "node_modules/cookie": {
1411 | "version": "0.5.0",
1412 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
1413 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
1414 | "engines": {
1415 | "node": ">= 0.6"
1416 | }
1417 | },
1418 | "node_modules/cookie-signature": {
1419 | "version": "1.0.6",
1420 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
1421 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
1422 | },
1423 | "node_modules/cors": {
1424 | "version": "2.8.5",
1425 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
1426 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
1427 | "dependencies": {
1428 | "object-assign": "^4",
1429 | "vary": "^1"
1430 | },
1431 | "engines": {
1432 | "node": ">= 0.10"
1433 | }
1434 | },
1435 | "node_modules/debug": {
1436 | "version": "2.6.9",
1437 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1438 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1439 | "dependencies": {
1440 | "ms": "2.0.0"
1441 | }
1442 | },
1443 | "node_modules/depd": {
1444 | "version": "2.0.0",
1445 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1446 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
1447 | "engines": {
1448 | "node": ">= 0.8"
1449 | }
1450 | },
1451 | "node_modules/destroy": {
1452 | "version": "1.2.0",
1453 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
1454 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
1455 | "engines": {
1456 | "node": ">= 0.8",
1457 | "npm": "1.2.8000 || >= 1.4.16"
1458 | }
1459 | },
1460 | "node_modules/dotenv": {
1461 | "version": "10.0.0",
1462 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
1463 | "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
1464 | "engines": {
1465 | "node": ">=10"
1466 | }
1467 | },
1468 | "node_modules/ecdsa-sig-formatter": {
1469 | "version": "1.0.11",
1470 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
1471 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
1472 | "dependencies": {
1473 | "safe-buffer": "^5.0.1"
1474 | }
1475 | },
1476 | "node_modules/ee-first": {
1477 | "version": "1.1.1",
1478 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1479 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
1480 | },
1481 | "node_modules/encodeurl": {
1482 | "version": "1.0.2",
1483 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
1484 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
1485 | "engines": {
1486 | "node": ">= 0.8"
1487 | }
1488 | },
1489 | "node_modules/escape-html": {
1490 | "version": "1.0.3",
1491 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1492 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
1493 | },
1494 | "node_modules/etag": {
1495 | "version": "1.8.1",
1496 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
1497 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
1498 | "engines": {
1499 | "node": ">= 0.6"
1500 | }
1501 | },
1502 | "node_modules/express": {
1503 | "version": "4.18.2",
1504 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
1505 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
1506 | "dependencies": {
1507 | "accepts": "~1.3.8",
1508 | "array-flatten": "1.1.1",
1509 | "body-parser": "1.20.1",
1510 | "content-disposition": "0.5.4",
1511 | "content-type": "~1.0.4",
1512 | "cookie": "0.5.0",
1513 | "cookie-signature": "1.0.6",
1514 | "debug": "2.6.9",
1515 | "depd": "2.0.0",
1516 | "encodeurl": "~1.0.2",
1517 | "escape-html": "~1.0.3",
1518 | "etag": "~1.8.1",
1519 | "finalhandler": "1.2.0",
1520 | "fresh": "0.5.2",
1521 | "http-errors": "2.0.0",
1522 | "merge-descriptors": "1.0.1",
1523 | "methods": "~1.1.2",
1524 | "on-finished": "2.4.1",
1525 | "parseurl": "~1.3.3",
1526 | "path-to-regexp": "0.1.7",
1527 | "proxy-addr": "~2.0.7",
1528 | "qs": "6.11.0",
1529 | "range-parser": "~1.2.1",
1530 | "safe-buffer": "5.2.1",
1531 | "send": "0.18.0",
1532 | "serve-static": "1.15.0",
1533 | "setprototypeof": "1.2.0",
1534 | "statuses": "2.0.1",
1535 | "type-is": "~1.6.18",
1536 | "utils-merge": "1.0.1",
1537 | "vary": "~1.1.2"
1538 | },
1539 | "engines": {
1540 | "node": ">= 0.10.0"
1541 | }
1542 | },
1543 | "node_modules/fast-xml-parser": {
1544 | "version": "4.2.5",
1545 | "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz",
1546 | "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==",
1547 | "funding": [
1548 | {
1549 | "type": "paypal",
1550 | "url": "https://paypal.me/naturalintelligence"
1551 | },
1552 | {
1553 | "type": "github",
1554 | "url": "https://github.com/sponsors/NaturalIntelligence"
1555 | }
1556 | ],
1557 | "optional": true,
1558 | "dependencies": {
1559 | "strnum": "^1.0.5"
1560 | },
1561 | "bin": {
1562 | "fxparser": "src/cli/cli.js"
1563 | }
1564 | },
1565 | "node_modules/fill-range": {
1566 | "version": "7.0.1",
1567 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1568 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1569 | "dependencies": {
1570 | "to-regex-range": "^5.0.1"
1571 | },
1572 | "engines": {
1573 | "node": ">=8"
1574 | }
1575 | },
1576 | "node_modules/finalhandler": {
1577 | "version": "1.2.0",
1578 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
1579 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
1580 | "dependencies": {
1581 | "debug": "2.6.9",
1582 | "encodeurl": "~1.0.2",
1583 | "escape-html": "~1.0.3",
1584 | "on-finished": "2.4.1",
1585 | "parseurl": "~1.3.3",
1586 | "statuses": "2.0.1",
1587 | "unpipe": "~1.0.0"
1588 | },
1589 | "engines": {
1590 | "node": ">= 0.8"
1591 | }
1592 | },
1593 | "node_modules/forwarded": {
1594 | "version": "0.2.0",
1595 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
1596 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
1597 | "engines": {
1598 | "node": ">= 0.6"
1599 | }
1600 | },
1601 | "node_modules/fresh": {
1602 | "version": "0.5.2",
1603 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
1604 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
1605 | "engines": {
1606 | "node": ">= 0.6"
1607 | }
1608 | },
1609 | "node_modules/fsevents": {
1610 | "version": "2.3.2",
1611 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
1612 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1613 | "hasInstallScript": true,
1614 | "optional": true,
1615 | "os": [
1616 | "darwin"
1617 | ],
1618 | "engines": {
1619 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1620 | }
1621 | },
1622 | "node_modules/function-bind": {
1623 | "version": "1.1.1",
1624 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1625 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
1626 | },
1627 | "node_modules/get-intrinsic": {
1628 | "version": "1.2.1",
1629 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
1630 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
1631 | "dependencies": {
1632 | "function-bind": "^1.1.1",
1633 | "has": "^1.0.3",
1634 | "has-proto": "^1.0.1",
1635 | "has-symbols": "^1.0.3"
1636 | },
1637 | "funding": {
1638 | "url": "https://github.com/sponsors/ljharb"
1639 | }
1640 | },
1641 | "node_modules/glob-parent": {
1642 | "version": "5.1.2",
1643 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1644 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1645 | "dependencies": {
1646 | "is-glob": "^4.0.1"
1647 | },
1648 | "engines": {
1649 | "node": ">= 6"
1650 | }
1651 | },
1652 | "node_modules/has": {
1653 | "version": "1.0.3",
1654 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1655 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1656 | "dependencies": {
1657 | "function-bind": "^1.1.1"
1658 | },
1659 | "engines": {
1660 | "node": ">= 0.4.0"
1661 | }
1662 | },
1663 | "node_modules/has-flag": {
1664 | "version": "3.0.0",
1665 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1666 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
1667 | "engines": {
1668 | "node": ">=4"
1669 | }
1670 | },
1671 | "node_modules/has-proto": {
1672 | "version": "1.0.1",
1673 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
1674 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
1675 | "engines": {
1676 | "node": ">= 0.4"
1677 | },
1678 | "funding": {
1679 | "url": "https://github.com/sponsors/ljharb"
1680 | }
1681 | },
1682 | "node_modules/has-symbols": {
1683 | "version": "1.0.3",
1684 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1685 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
1686 | "engines": {
1687 | "node": ">= 0.4"
1688 | },
1689 | "funding": {
1690 | "url": "https://github.com/sponsors/ljharb"
1691 | }
1692 | },
1693 | "node_modules/http-errors": {
1694 | "version": "2.0.0",
1695 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
1696 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
1697 | "dependencies": {
1698 | "depd": "2.0.0",
1699 | "inherits": "2.0.4",
1700 | "setprototypeof": "1.2.0",
1701 | "statuses": "2.0.1",
1702 | "toidentifier": "1.0.1"
1703 | },
1704 | "engines": {
1705 | "node": ">= 0.8"
1706 | }
1707 | },
1708 | "node_modules/iconv-lite": {
1709 | "version": "0.4.24",
1710 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1711 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1712 | "dependencies": {
1713 | "safer-buffer": ">= 2.1.2 < 3"
1714 | },
1715 | "engines": {
1716 | "node": ">=0.10.0"
1717 | }
1718 | },
1719 | "node_modules/ieee754": {
1720 | "version": "1.2.1",
1721 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
1722 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
1723 | "funding": [
1724 | {
1725 | "type": "github",
1726 | "url": "https://github.com/sponsors/feross"
1727 | },
1728 | {
1729 | "type": "patreon",
1730 | "url": "https://www.patreon.com/feross"
1731 | },
1732 | {
1733 | "type": "consulting",
1734 | "url": "https://feross.org/support"
1735 | }
1736 | ]
1737 | },
1738 | "node_modules/ignore-by-default": {
1739 | "version": "1.0.1",
1740 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
1741 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
1742 | },
1743 | "node_modules/inherits": {
1744 | "version": "2.0.4",
1745 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1746 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1747 | },
1748 | "node_modules/ip": {
1749 | "version": "2.0.0",
1750 | "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
1751 | "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
1752 | },
1753 | "node_modules/ipaddr.js": {
1754 | "version": "1.9.1",
1755 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1756 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
1757 | "engines": {
1758 | "node": ">= 0.10"
1759 | }
1760 | },
1761 | "node_modules/is-binary-path": {
1762 | "version": "2.1.0",
1763 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1764 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1765 | "dependencies": {
1766 | "binary-extensions": "^2.0.0"
1767 | },
1768 | "engines": {
1769 | "node": ">=8"
1770 | }
1771 | },
1772 | "node_modules/is-extglob": {
1773 | "version": "2.1.1",
1774 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1775 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1776 | "engines": {
1777 | "node": ">=0.10.0"
1778 | }
1779 | },
1780 | "node_modules/is-glob": {
1781 | "version": "4.0.3",
1782 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1783 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1784 | "dependencies": {
1785 | "is-extglob": "^2.1.1"
1786 | },
1787 | "engines": {
1788 | "node": ">=0.10.0"
1789 | }
1790 | },
1791 | "node_modules/is-number": {
1792 | "version": "7.0.0",
1793 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1794 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1795 | "engines": {
1796 | "node": ">=0.12.0"
1797 | }
1798 | },
1799 | "node_modules/jsonwebtoken": {
1800 | "version": "8.5.1",
1801 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
1802 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
1803 | "dependencies": {
1804 | "jws": "^3.2.2",
1805 | "lodash.includes": "^4.3.0",
1806 | "lodash.isboolean": "^3.0.3",
1807 | "lodash.isinteger": "^4.0.4",
1808 | "lodash.isnumber": "^3.0.3",
1809 | "lodash.isplainobject": "^4.0.6",
1810 | "lodash.isstring": "^4.0.1",
1811 | "lodash.once": "^4.0.0",
1812 | "ms": "^2.1.1",
1813 | "semver": "^5.6.0"
1814 | },
1815 | "engines": {
1816 | "node": ">=4",
1817 | "npm": ">=1.4.28"
1818 | }
1819 | },
1820 | "node_modules/jsonwebtoken/node_modules/ms": {
1821 | "version": "2.1.3",
1822 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1823 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1824 | },
1825 | "node_modules/jwa": {
1826 | "version": "1.4.1",
1827 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
1828 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
1829 | "dependencies": {
1830 | "buffer-equal-constant-time": "1.0.1",
1831 | "ecdsa-sig-formatter": "1.0.11",
1832 | "safe-buffer": "^5.0.1"
1833 | }
1834 | },
1835 | "node_modules/jws": {
1836 | "version": "3.2.2",
1837 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
1838 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
1839 | "dependencies": {
1840 | "jwa": "^1.4.1",
1841 | "safe-buffer": "^5.0.1"
1842 | }
1843 | },
1844 | "node_modules/kareem": {
1845 | "version": "2.5.1",
1846 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz",
1847 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==",
1848 | "engines": {
1849 | "node": ">=12.0.0"
1850 | }
1851 | },
1852 | "node_modules/lodash.includes": {
1853 | "version": "4.3.0",
1854 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
1855 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
1856 | },
1857 | "node_modules/lodash.isboolean": {
1858 | "version": "3.0.3",
1859 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
1860 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
1861 | },
1862 | "node_modules/lodash.isinteger": {
1863 | "version": "4.0.4",
1864 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
1865 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
1866 | },
1867 | "node_modules/lodash.isnumber": {
1868 | "version": "3.0.3",
1869 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
1870 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
1871 | },
1872 | "node_modules/lodash.isplainobject": {
1873 | "version": "4.0.6",
1874 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
1875 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
1876 | },
1877 | "node_modules/lodash.isstring": {
1878 | "version": "4.0.1",
1879 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
1880 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
1881 | },
1882 | "node_modules/lodash.once": {
1883 | "version": "4.1.1",
1884 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
1885 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
1886 | },
1887 | "node_modules/media-typer": {
1888 | "version": "0.3.0",
1889 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1890 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
1891 | "engines": {
1892 | "node": ">= 0.6"
1893 | }
1894 | },
1895 | "node_modules/memory-pager": {
1896 | "version": "1.5.0",
1897 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
1898 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
1899 | "optional": true
1900 | },
1901 | "node_modules/merge-descriptors": {
1902 | "version": "1.0.1",
1903 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1904 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
1905 | },
1906 | "node_modules/methods": {
1907 | "version": "1.1.2",
1908 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1909 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
1910 | "engines": {
1911 | "node": ">= 0.6"
1912 | }
1913 | },
1914 | "node_modules/mime": {
1915 | "version": "1.6.0",
1916 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1917 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1918 | "bin": {
1919 | "mime": "cli.js"
1920 | },
1921 | "engines": {
1922 | "node": ">=4"
1923 | }
1924 | },
1925 | "node_modules/mime-db": {
1926 | "version": "1.52.0",
1927 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1928 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1929 | "engines": {
1930 | "node": ">= 0.6"
1931 | }
1932 | },
1933 | "node_modules/mime-types": {
1934 | "version": "2.1.35",
1935 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1936 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1937 | "dependencies": {
1938 | "mime-db": "1.52.0"
1939 | },
1940 | "engines": {
1941 | "node": ">= 0.6"
1942 | }
1943 | },
1944 | "node_modules/minimatch": {
1945 | "version": "3.1.2",
1946 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1947 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1948 | "dependencies": {
1949 | "brace-expansion": "^1.1.7"
1950 | },
1951 | "engines": {
1952 | "node": "*"
1953 | }
1954 | },
1955 | "node_modules/mongodb": {
1956 | "version": "4.16.0",
1957 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.16.0.tgz",
1958 | "integrity": "sha512-0EB113Fsucaq1wsY0dOhi1fmZOwFtLOtteQkiqOXGklvWMnSH3g2QS53f0KTP+/6qOkuoXE2JksubSZNmxeI+g==",
1959 | "dependencies": {
1960 | "bson": "^4.7.2",
1961 | "mongodb-connection-string-url": "^2.5.4",
1962 | "socks": "^2.7.1"
1963 | },
1964 | "engines": {
1965 | "node": ">=12.9.0"
1966 | },
1967 | "optionalDependencies": {
1968 | "@aws-sdk/credential-providers": "^3.186.0",
1969 | "saslprep": "^1.0.3"
1970 | }
1971 | },
1972 | "node_modules/mongodb-connection-string-url": {
1973 | "version": "2.6.0",
1974 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz",
1975 | "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==",
1976 | "dependencies": {
1977 | "@types/whatwg-url": "^8.2.1",
1978 | "whatwg-url": "^11.0.0"
1979 | }
1980 | },
1981 | "node_modules/mongoose": {
1982 | "version": "6.11.4",
1983 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.11.4.tgz",
1984 | "integrity": "sha512-q9NaW9/BBYZofx80SqlR7uoSR09CS3g02y+KMj1lNLUxcFFsPshupY3WWisNFauYG9gyuDF4L/RgyIK3obSghg==",
1985 | "dependencies": {
1986 | "bson": "^4.7.2",
1987 | "kareem": "2.5.1",
1988 | "mongodb": "4.16.0",
1989 | "mpath": "0.9.0",
1990 | "mquery": "4.0.3",
1991 | "ms": "2.1.3",
1992 | "sift": "16.0.1"
1993 | },
1994 | "engines": {
1995 | "node": ">=12.0.0"
1996 | },
1997 | "funding": {
1998 | "type": "opencollective",
1999 | "url": "https://opencollective.com/mongoose"
2000 | }
2001 | },
2002 | "node_modules/mongoose/node_modules/ms": {
2003 | "version": "2.1.3",
2004 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2005 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
2006 | },
2007 | "node_modules/mpath": {
2008 | "version": "0.9.0",
2009 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
2010 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
2011 | "engines": {
2012 | "node": ">=4.0.0"
2013 | }
2014 | },
2015 | "node_modules/mquery": {
2016 | "version": "4.0.3",
2017 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.3.tgz",
2018 | "integrity": "sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==",
2019 | "dependencies": {
2020 | "debug": "4.x"
2021 | },
2022 | "engines": {
2023 | "node": ">=12.0.0"
2024 | }
2025 | },
2026 | "node_modules/mquery/node_modules/debug": {
2027 | "version": "4.3.4",
2028 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
2029 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
2030 | "dependencies": {
2031 | "ms": "2.1.2"
2032 | },
2033 | "engines": {
2034 | "node": ">=6.0"
2035 | },
2036 | "peerDependenciesMeta": {
2037 | "supports-color": {
2038 | "optional": true
2039 | }
2040 | }
2041 | },
2042 | "node_modules/mquery/node_modules/ms": {
2043 | "version": "2.1.2",
2044 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2045 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
2046 | },
2047 | "node_modules/ms": {
2048 | "version": "2.0.0",
2049 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
2050 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
2051 | },
2052 | "node_modules/negotiator": {
2053 | "version": "0.6.3",
2054 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
2055 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
2056 | "engines": {
2057 | "node": ">= 0.6"
2058 | }
2059 | },
2060 | "node_modules/nodemon": {
2061 | "version": "2.0.22",
2062 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
2063 | "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
2064 | "dependencies": {
2065 | "chokidar": "^3.5.2",
2066 | "debug": "^3.2.7",
2067 | "ignore-by-default": "^1.0.1",
2068 | "minimatch": "^3.1.2",
2069 | "pstree.remy": "^1.1.8",
2070 | "semver": "^5.7.1",
2071 | "simple-update-notifier": "^1.0.7",
2072 | "supports-color": "^5.5.0",
2073 | "touch": "^3.1.0",
2074 | "undefsafe": "^2.0.5"
2075 | },
2076 | "bin": {
2077 | "nodemon": "bin/nodemon.js"
2078 | },
2079 | "engines": {
2080 | "node": ">=8.10.0"
2081 | },
2082 | "funding": {
2083 | "type": "opencollective",
2084 | "url": "https://opencollective.com/nodemon"
2085 | }
2086 | },
2087 | "node_modules/nodemon/node_modules/debug": {
2088 | "version": "3.2.7",
2089 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
2090 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
2091 | "dependencies": {
2092 | "ms": "^2.1.1"
2093 | }
2094 | },
2095 | "node_modules/nodemon/node_modules/ms": {
2096 | "version": "2.1.3",
2097 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2098 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
2099 | },
2100 | "node_modules/nopt": {
2101 | "version": "1.0.10",
2102 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
2103 | "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
2104 | "dependencies": {
2105 | "abbrev": "1"
2106 | },
2107 | "bin": {
2108 | "nopt": "bin/nopt.js"
2109 | },
2110 | "engines": {
2111 | "node": "*"
2112 | }
2113 | },
2114 | "node_modules/normalize-path": {
2115 | "version": "3.0.0",
2116 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
2117 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
2118 | "engines": {
2119 | "node": ">=0.10.0"
2120 | }
2121 | },
2122 | "node_modules/object-assign": {
2123 | "version": "4.1.1",
2124 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
2125 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
2126 | "engines": {
2127 | "node": ">=0.10.0"
2128 | }
2129 | },
2130 | "node_modules/object-inspect": {
2131 | "version": "1.12.3",
2132 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
2133 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
2134 | "funding": {
2135 | "url": "https://github.com/sponsors/ljharb"
2136 | }
2137 | },
2138 | "node_modules/on-finished": {
2139 | "version": "2.4.1",
2140 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
2141 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
2142 | "dependencies": {
2143 | "ee-first": "1.1.1"
2144 | },
2145 | "engines": {
2146 | "node": ">= 0.8"
2147 | }
2148 | },
2149 | "node_modules/parseurl": {
2150 | "version": "1.3.3",
2151 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
2152 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
2153 | "engines": {
2154 | "node": ">= 0.8"
2155 | }
2156 | },
2157 | "node_modules/path-to-regexp": {
2158 | "version": "0.1.7",
2159 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
2160 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
2161 | },
2162 | "node_modules/picomatch": {
2163 | "version": "2.3.1",
2164 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
2165 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
2166 | "engines": {
2167 | "node": ">=8.6"
2168 | },
2169 | "funding": {
2170 | "url": "https://github.com/sponsors/jonschlinkert"
2171 | }
2172 | },
2173 | "node_modules/proxy-addr": {
2174 | "version": "2.0.7",
2175 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
2176 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
2177 | "dependencies": {
2178 | "forwarded": "0.2.0",
2179 | "ipaddr.js": "1.9.1"
2180 | },
2181 | "engines": {
2182 | "node": ">= 0.10"
2183 | }
2184 | },
2185 | "node_modules/pstree.remy": {
2186 | "version": "1.1.8",
2187 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
2188 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
2189 | },
2190 | "node_modules/punycode": {
2191 | "version": "2.3.0",
2192 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
2193 | "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
2194 | "engines": {
2195 | "node": ">=6"
2196 | }
2197 | },
2198 | "node_modules/qs": {
2199 | "version": "6.11.0",
2200 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
2201 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
2202 | "dependencies": {
2203 | "side-channel": "^1.0.4"
2204 | },
2205 | "engines": {
2206 | "node": ">=0.6"
2207 | },
2208 | "funding": {
2209 | "url": "https://github.com/sponsors/ljharb"
2210 | }
2211 | },
2212 | "node_modules/range-parser": {
2213 | "version": "1.2.1",
2214 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
2215 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
2216 | "engines": {
2217 | "node": ">= 0.6"
2218 | }
2219 | },
2220 | "node_modules/raw-body": {
2221 | "version": "2.5.1",
2222 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
2223 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
2224 | "dependencies": {
2225 | "bytes": "3.1.2",
2226 | "http-errors": "2.0.0",
2227 | "iconv-lite": "0.4.24",
2228 | "unpipe": "1.0.0"
2229 | },
2230 | "engines": {
2231 | "node": ">= 0.8"
2232 | }
2233 | },
2234 | "node_modules/readdirp": {
2235 | "version": "3.6.0",
2236 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
2237 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
2238 | "dependencies": {
2239 | "picomatch": "^2.2.1"
2240 | },
2241 | "engines": {
2242 | "node": ">=8.10.0"
2243 | }
2244 | },
2245 | "node_modules/safe-buffer": {
2246 | "version": "5.2.1",
2247 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
2248 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
2249 | "funding": [
2250 | {
2251 | "type": "github",
2252 | "url": "https://github.com/sponsors/feross"
2253 | },
2254 | {
2255 | "type": "patreon",
2256 | "url": "https://www.patreon.com/feross"
2257 | },
2258 | {
2259 | "type": "consulting",
2260 | "url": "https://feross.org/support"
2261 | }
2262 | ]
2263 | },
2264 | "node_modules/safer-buffer": {
2265 | "version": "2.1.2",
2266 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2267 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
2268 | },
2269 | "node_modules/saslprep": {
2270 | "version": "1.0.3",
2271 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
2272 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
2273 | "optional": true,
2274 | "dependencies": {
2275 | "sparse-bitfield": "^3.0.3"
2276 | },
2277 | "engines": {
2278 | "node": ">=6"
2279 | }
2280 | },
2281 | "node_modules/semver": {
2282 | "version": "5.7.2",
2283 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
2284 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
2285 | "bin": {
2286 | "semver": "bin/semver"
2287 | }
2288 | },
2289 | "node_modules/send": {
2290 | "version": "0.18.0",
2291 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
2292 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
2293 | "dependencies": {
2294 | "debug": "2.6.9",
2295 | "depd": "2.0.0",
2296 | "destroy": "1.2.0",
2297 | "encodeurl": "~1.0.2",
2298 | "escape-html": "~1.0.3",
2299 | "etag": "~1.8.1",
2300 | "fresh": "0.5.2",
2301 | "http-errors": "2.0.0",
2302 | "mime": "1.6.0",
2303 | "ms": "2.1.3",
2304 | "on-finished": "2.4.1",
2305 | "range-parser": "~1.2.1",
2306 | "statuses": "2.0.1"
2307 | },
2308 | "engines": {
2309 | "node": ">= 0.8.0"
2310 | }
2311 | },
2312 | "node_modules/send/node_modules/ms": {
2313 | "version": "2.1.3",
2314 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2315 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
2316 | },
2317 | "node_modules/serve-static": {
2318 | "version": "1.15.0",
2319 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
2320 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
2321 | "dependencies": {
2322 | "encodeurl": "~1.0.2",
2323 | "escape-html": "~1.0.3",
2324 | "parseurl": "~1.3.3",
2325 | "send": "0.18.0"
2326 | },
2327 | "engines": {
2328 | "node": ">= 0.8.0"
2329 | }
2330 | },
2331 | "node_modules/setprototypeof": {
2332 | "version": "1.2.0",
2333 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
2334 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
2335 | },
2336 | "node_modules/side-channel": {
2337 | "version": "1.0.4",
2338 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
2339 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
2340 | "dependencies": {
2341 | "call-bind": "^1.0.0",
2342 | "get-intrinsic": "^1.0.2",
2343 | "object-inspect": "^1.9.0"
2344 | },
2345 | "funding": {
2346 | "url": "https://github.com/sponsors/ljharb"
2347 | }
2348 | },
2349 | "node_modules/sift": {
2350 | "version": "16.0.1",
2351 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz",
2352 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ=="
2353 | },
2354 | "node_modules/simple-update-notifier": {
2355 | "version": "1.1.0",
2356 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
2357 | "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
2358 | "dependencies": {
2359 | "semver": "~7.0.0"
2360 | },
2361 | "engines": {
2362 | "node": ">=8.10.0"
2363 | }
2364 | },
2365 | "node_modules/simple-update-notifier/node_modules/semver": {
2366 | "version": "7.0.0",
2367 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
2368 | "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
2369 | "bin": {
2370 | "semver": "bin/semver.js"
2371 | }
2372 | },
2373 | "node_modules/smart-buffer": {
2374 | "version": "4.2.0",
2375 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
2376 | "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
2377 | "engines": {
2378 | "node": ">= 6.0.0",
2379 | "npm": ">= 3.0.0"
2380 | }
2381 | },
2382 | "node_modules/socks": {
2383 | "version": "2.7.1",
2384 | "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
2385 | "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
2386 | "dependencies": {
2387 | "ip": "^2.0.0",
2388 | "smart-buffer": "^4.2.0"
2389 | },
2390 | "engines": {
2391 | "node": ">= 10.13.0",
2392 | "npm": ">= 3.0.0"
2393 | }
2394 | },
2395 | "node_modules/sparse-bitfield": {
2396 | "version": "3.0.3",
2397 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
2398 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
2399 | "optional": true,
2400 | "dependencies": {
2401 | "memory-pager": "^1.0.2"
2402 | }
2403 | },
2404 | "node_modules/statuses": {
2405 | "version": "2.0.1",
2406 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
2407 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
2408 | "engines": {
2409 | "node": ">= 0.8"
2410 | }
2411 | },
2412 | "node_modules/strnum": {
2413 | "version": "1.0.5",
2414 | "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
2415 | "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
2416 | "optional": true
2417 | },
2418 | "node_modules/supports-color": {
2419 | "version": "5.5.0",
2420 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2421 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2422 | "dependencies": {
2423 | "has-flag": "^3.0.0"
2424 | },
2425 | "engines": {
2426 | "node": ">=4"
2427 | }
2428 | },
2429 | "node_modules/to-regex-range": {
2430 | "version": "5.0.1",
2431 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2432 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2433 | "dependencies": {
2434 | "is-number": "^7.0.0"
2435 | },
2436 | "engines": {
2437 | "node": ">=8.0"
2438 | }
2439 | },
2440 | "node_modules/toidentifier": {
2441 | "version": "1.0.1",
2442 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
2443 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
2444 | "engines": {
2445 | "node": ">=0.6"
2446 | }
2447 | },
2448 | "node_modules/touch": {
2449 | "version": "3.1.0",
2450 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
2451 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
2452 | "dependencies": {
2453 | "nopt": "~1.0.10"
2454 | },
2455 | "bin": {
2456 | "nodetouch": "bin/nodetouch.js"
2457 | }
2458 | },
2459 | "node_modules/tr46": {
2460 | "version": "3.0.0",
2461 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
2462 | "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
2463 | "dependencies": {
2464 | "punycode": "^2.1.1"
2465 | },
2466 | "engines": {
2467 | "node": ">=12"
2468 | }
2469 | },
2470 | "node_modules/tslib": {
2471 | "version": "2.6.1",
2472 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
2473 | "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==",
2474 | "optional": true
2475 | },
2476 | "node_modules/type-is": {
2477 | "version": "1.6.18",
2478 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
2479 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
2480 | "dependencies": {
2481 | "media-typer": "0.3.0",
2482 | "mime-types": "~2.1.24"
2483 | },
2484 | "engines": {
2485 | "node": ">= 0.6"
2486 | }
2487 | },
2488 | "node_modules/undefsafe": {
2489 | "version": "2.0.5",
2490 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
2491 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
2492 | },
2493 | "node_modules/unpipe": {
2494 | "version": "1.0.0",
2495 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
2496 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
2497 | "engines": {
2498 | "node": ">= 0.8"
2499 | }
2500 | },
2501 | "node_modules/utils-merge": {
2502 | "version": "1.0.1",
2503 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
2504 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
2505 | "engines": {
2506 | "node": ">= 0.4.0"
2507 | }
2508 | },
2509 | "node_modules/uuid": {
2510 | "version": "8.3.2",
2511 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
2512 | "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
2513 | "optional": true,
2514 | "bin": {
2515 | "uuid": "dist/bin/uuid"
2516 | }
2517 | },
2518 | "node_modules/vary": {
2519 | "version": "1.1.2",
2520 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
2521 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
2522 | "engines": {
2523 | "node": ">= 0.8"
2524 | }
2525 | },
2526 | "node_modules/webidl-conversions": {
2527 | "version": "7.0.0",
2528 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
2529 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
2530 | "engines": {
2531 | "node": ">=12"
2532 | }
2533 | },
2534 | "node_modules/whatwg-url": {
2535 | "version": "11.0.0",
2536 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
2537 | "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
2538 | "dependencies": {
2539 | "tr46": "^3.0.0",
2540 | "webidl-conversions": "^7.0.0"
2541 | },
2542 | "engines": {
2543 | "node": ">=12"
2544 | }
2545 | }
2546 | }
2547 | }
2548 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "start": "node index.js",
8 | "dev": "nodemon index.js"
9 | },
10 | "author": "Atharv Hatwar",
11 | "license": "ISC",
12 | "dependencies": {
13 | "bcryptjs": "^2.4.3",
14 | "cors": "^2.8.5",
15 | "dotenv": "^10.0.0",
16 | "express": "^4.17.1",
17 | "jsonwebtoken": "^8.5.1",
18 | "mongoose": "^6.0.12",
19 | "nodemon": "^2.0.14"
20 | },
21 | "keywords": [
22 | "stackoverflow"
23 | ],
24 | "description": ""
25 | }
26 |
--------------------------------------------------------------------------------
/server/routes/Answers.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 |
3 | import { postAnswer, deleteAnswer } from "../controllers/Answers.js";
4 | import auth from "../middleware/auth.js";
5 |
6 | const router = express.Router();
7 |
8 | router.patch("/post/:id", auth, postAnswer);
9 | router.patch("/delete/:id", auth, deleteAnswer);
10 |
11 | export default router;
12 |
--------------------------------------------------------------------------------
/server/routes/Questions.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 |
3 | import {
4 | AskQuestion,
5 | getAllQuestions,
6 | deleteQuestion,
7 | voteQuestion,
8 | } from "../controllers/Questions.js";
9 | import auth from "../middleware/auth.js";
10 |
11 | const router = express.Router();
12 |
13 | router.post("/Ask", auth, AskQuestion);
14 | router.get("/get", getAllQuestions);
15 | router.delete("/delete/:id", auth, deleteQuestion);
16 | router.patch("/vote/:id", auth, voteQuestion);
17 |
18 | export default router;
19 |
--------------------------------------------------------------------------------
/server/routes/users.js:
--------------------------------------------------------------------------------
1 | import express from "express";
2 |
3 | import { login, signup } from "../controllers/auth.js";
4 | import { getAllUsers, updateProfile } from "../controllers/users.js";
5 | import auth from "../middleware/auth.js";
6 |
7 | const router = express.Router();
8 |
9 | router.post("/signup", signup);
10 | router.post("/login", login);
11 |
12 | router.get("/getAllUsers", getAllUsers);
13 | router.patch("/update/:id", auth, updateProfile);
14 |
15 | export default router;
16 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "builds": [
4 | {
5 | "src": "server/index.js",
6 | "use": "@vercel/node"
7 | },
8 | {
9 | "src": "client/package.json",
10 | "use": "@vercel/static-build",
11 | "config": {
12 | "buildCommand": "npm install && npm run build",
13 | "outputDirectory": "build"
14 | }
15 | }
16 | ],
17 | "routes": [
18 | {
19 | "src": "/api/(.*)",
20 | "dest": "server/index.js"
21 | },
22 | {
23 | "src": "/(.*)",
24 | "dest": "client/$1"
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------