├── 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 |
34 | 35 | 36 | 37 | 38 |
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 |
46 |
47 | 62 | 79 | 91 |
92 | 97 |
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 | stack overflow 45 |
46 | {isSignup && ( 47 | 59 | )} 60 | 72 | 91 | 94 |
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 |
159 |

Your Answer

160 |
{ 162 | handlePostAns(e, question.answer.length); 163 | }} 164 | > 165 | 173 |
174 | 179 |
180 |

181 | Browse other Question tagged 182 | {question.questionTags.map((tag) => ( 183 | 184 | {" "} 185 | {tag}{" "} 186 | 187 | ))}{" "} 188 | or 189 | 193 | {" "} 194 | ask your own question. 195 | 196 |

197 |
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 |
23 |

Edit Your Profile

24 |

Public information

25 |
26 | 34 | 44 | 53 |
54 | 55 | 62 |
63 |
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 | pen 14 |

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

18 |
19 |
20 | pen 21 |

Podcast 374: How valuable is your screen name?

22 |
23 |
24 |

Featured on Meta

25 |
26 |
27 | pen 28 |

Review queue workflows - Final release....

29 |
30 |
31 | pen 32 |

33 | Please welcome Valued Associates: #958 - V2Blast #959 - SpencerG 34 |

35 |
36 |
37 | pen 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 | } --------------------------------------------------------------------------------