├── .DS_Store ├── .env.example ├── .eslintrc.json ├── .gitignore ├── .prettierrc ├── LICENSE.md ├── Procfile ├── README.md ├── package.json ├── src ├── api │ ├── controllers │ │ ├── errorController.js │ │ ├── historyController.js │ │ ├── memberController.js │ │ ├── projectController.js │ │ ├── tasksController.js │ │ └── userController.js │ ├── index.js │ ├── middlewares │ │ ├── accessToProjectMiddleware.js │ │ ├── authMiddleware.js │ │ ├── authorizeMiddleware.js │ │ └── isAdminInProjectMiddleware.js │ └── routes │ │ ├── historyRoutes.js │ │ ├── memberRoutes.js │ │ ├── projectRoutes.js │ │ ├── tasksRoutes.js │ │ └── userRoutes.js ├── app.js ├── config │ └── index.js ├── loaders │ ├── index.js │ ├── initDB.js │ └── initExpress.js ├── models │ ├── Comments.js │ ├── History.js │ ├── Member.js │ ├── Project.js │ ├── Task.js │ └── User.js └── utils │ ├── AppError.js │ ├── auth0.js │ └── catchAsync.js └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishwajeetraj11/projectboard-backend/41a9442e6ee9e46ceeb1ea0d1901b335c28b9a39/.DS_Store -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | DB_PASSWORD= 2 | MONGODB_URI= 3 | PORT= 4 | CLIENT_ORIGIN_URL= 5 | AUTH0_AUDIENCE= 6 | AUTH0_DOMAIN= 7 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": ["eslint:recommended","airbnb-base", "prettier"], 7 | "plugins": ["prettier"], 8 | "globals": { 9 | "Atomics": "readonly", 10 | "SharedArrayBuffer": "readonly" 11 | }, 12 | "parserOptions": { 13 | "ecmaVersion": 12, 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "prettier/prettier": "error", 18 | "class-methods-use-this": "off", 19 | "no-param-reassign": "off", 20 | "camelcase": "off", 21 | "no-unused-vars": ["error", { "argsIgnorePattern": "next" }] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | node_modules/* 3 | .env 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Vishwajeet Raj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node src/app.js 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Project Board - Project Management Platform. 2 | 3 | Live: https://projectboard-application.vercel.app/ 4 | Backend: https://github.com/vishwajeetraj11/projectboard-backend 5 | Fronend: https://github.com/vishwajeetraj11/projectboard 6 | 7 | # Deployment: 8 | ### Frontend: Vercel 9 | ### Backend: Heroku 10 | 11 | 12 | ## 💻 Screens 13 | Landing Page | Tasks Page 14 | :-------------------------:|:-------------------------: 15 | Project Board Landing Page | Project Board Tasks Page 16 | History Page | Task Detail 17 | Project Board Task Detail Page | Project Board Task Detail Page 18 | Boards | All Projects 19 | Project Board Boards Screen | Project Board All Projects Screen 20 | Edit Project / Edit Profile | Add Members 21 | Project Board Edit Screen | ADD Members Screen 22 | Manage Members 23 | Manage Members Screen 24 | 25 | # Setting up Auth0 26 | 1. Login/Signup to Auth0 27 | 2. Create Application: ```Single Page Web Applications``` 28 | 3. Create API (inside Auth0 ) to get API Audience (required for env). 29 | 4. Inside The Application configure these urls 30 | Allowed Callback URLs ```http://localhost:/``` 31 | Allowed Logout URLs ```http://localhost:/``` 32 | Allowed Web Origins ```http://localhost:/``` 33 | 4. Setup Custom Database: https://www.youtube.com/watch?v=TXnDFU4sG0A&t=306s 34 | 35 | # Getting Started: 36 | - Clone both frontend and backend 37 | - Make an account if you don't already have one on Auth0 and get required credentials. (check .env.example) 38 | - Get your mongodb db uri 39 | - Install Dependencies 40 | - Make sure you setup auth0 before this. 41 | - That's it you are done. ```npm start``` or ```yarn start``` 42 | 43 |

Support

44 | 45 | Buy Me A Coffee 46 | 47 |

Vishwajeet Raj – vishwajeet.netlify.app

48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "main": "src/app.js", 5 | "author": "Vishwajeet Raj", 6 | "license": "MIT", 7 | "type": "module", 8 | "scripts": { 9 | "start": "node src/app.js", 10 | "dev": "nodemon src/app.js", 11 | "start:prod": "SET NODE_ENV=production& nodemon src/app.js" 12 | }, 13 | "dependencies": { 14 | "axios": "^0.21.1", 15 | "cors": "^2.8.5", 16 | "dotenv": "^10.0.0", 17 | "express": "^4.17.1", 18 | "express-jwt": "^6.0.0", 19 | "helmet": "^4.6.0", 20 | "jwks-rsa": "^2.0.4", 21 | "jwt-decode": "^3.1.2", 22 | "mongoose": "^5.13.5", 23 | "morgan": "^1.10.0", 24 | "socket.io": "^4.1.3" 25 | }, 26 | "devDependencies": { 27 | "eslint": "^7.32.0", 28 | "eslint-config-prettier": "^8.3.0", 29 | "eslint-plugin-prettier": "^3.4.0", 30 | "prettier": "^2.3.2" 31 | }, 32 | "engines": { 33 | "node": ">=14.x" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/api/controllers/errorController.js: -------------------------------------------------------------------------------- 1 | import { AppError } from '../../utils/AppError.js'; 2 | 3 | const handleCastErrorDB = (err) => { 4 | const message = `Invalid ${err.path}: ${err.value}`; 5 | 6 | return new AppError(message, 400); 7 | }; 8 | const handleDuplicateFieldsDB = (err) => { 9 | const value = err.errmsg.match(/(["'])(?:(?=(\\?))\2.)*?\1/)[0]; 10 | 11 | const message = `Duplicate field value: ${value}. Please use another value.`; 12 | 13 | return new AppError(message, 400); 14 | }; 15 | 16 | const handleValidationErrorDB = (err) => { 17 | const errors = Object.values(err.errors).map((el) => el.message); 18 | 19 | const message = `Invalid input data. ${errors.join('. ')}`; 20 | return new AppError(message, 400); 21 | }; 22 | 23 | const handleJWTError = () => 24 | new AppError('Invalid Token, Please Login Again', 401); 25 | 26 | const handleTokenExpiredError = () => 27 | new AppError('Your Token has expired, Please Login Again', 401); 28 | 29 | const sendErrorDev = (err, req, res) => { 30 | if (req.originalUrl.startsWith('/api')) { 31 | return res.status(err.statusCode).json({ 32 | status: err.status, 33 | error: err, 34 | message: err.message, 35 | stack: err.stack, 36 | }); 37 | } 38 | }; 39 | 40 | const sendErrorProd = (err, req, res) => { 41 | if (req.originalUrl.startsWith('/api')) { 42 | // 1. Operational, trusted error: send message to client 43 | if (err.isOperational) { 44 | return res.status(err.statusCode).json({ 45 | status: err.status, 46 | message: err.message, 47 | }); 48 | } 49 | // 1. Log Error 50 | console.error('Error', err); 51 | 52 | // 2. Send generic message 53 | return res.status(500).json({ 54 | status: 'error', 55 | message: 'Something went very wrong', 56 | }); 57 | } 58 | }; 59 | 60 | export const globalErrorHandler = (err, req, res, next) => { 61 | // console.log(err.stack); 62 | err.statusCode = err.statusCode || 500; 63 | err.status = err.status || 'error'; 64 | if (process.env.NODE_ENV === 'development') { 65 | sendErrorDev(err, req, res); 66 | } else if (process.env.NODE_ENV === 'production') { 67 | let error = { ...err }; 68 | error.message = err.message; 69 | if (error.name === 'CastError') error = handleCastErrorDB(error); 70 | if (error.code === 11000) error = handleDuplicateFieldsDB(error); 71 | if (error.name === 'ValidationError') 72 | error = handleValidationErrorDB(error); 73 | if (error.name === 'JsonWebTokenError') error = handleJWTError(); 74 | if (error.name === 'TokenExpiredError') error = handleTokenExpiredError(); 75 | 76 | sendErrorProd(error, req, res); 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /src/api/controllers/historyController.js: -------------------------------------------------------------------------------- 1 | import { catchAsync } from '../../utils/catchAsync.js'; 2 | import { User } from '../../models/User.js'; 3 | import { History } from '../../models/History.js'; 4 | 5 | export const getProjectHistory = catchAsync(async (req, res, next) => { 6 | const { projectId } = req.params; 7 | const history = await History.find({ 8 | project: projectId, 9 | }).sort({ createdAt: -1 }); 10 | await User.populate(history, { 11 | path: 'user extraDetails.user', 12 | }); 13 | return res.status(200).json({ status: 'success', history }); 14 | }); 15 | 16 | export const getTaskHistory = catchAsync(async (req, res, next) => { 17 | const { projectId, taskId } = req.params; 18 | const history = await History.find({ 19 | project: projectId, 20 | task: taskId, 21 | }).sort({ createdAt: -1 }); 22 | await User.populate(history, { 23 | path: 'user extraDetails.user', 24 | }); 25 | return res.status(200).json({ status: 'success', history }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/api/controllers/memberController.js: -------------------------------------------------------------------------------- 1 | import { Member } from '../../models/Member.js'; 2 | import { History } from '../../models/History.js'; 3 | import { User } from '../../models/User.js'; 4 | import { Project } from '../../models/Project.js'; 5 | import { AppError } from '../../utils/AppError.js'; 6 | import { catchAsync } from '../../utils/catchAsync.js'; 7 | 8 | export const addMemberToProject = catchAsync(async (req, res, next) => { 9 | const { projectId, id } = req.params; 10 | // console.log({ currentUser: req.user.userId, userToAdd: id }); 11 | const project = await Project.findById(projectId); 12 | if (!project) { 13 | next( 14 | new AppError( 15 | 'The project you are trying to add a member in does not exist.' 16 | ), 17 | 404 18 | ); 19 | } 20 | const memberAlreadyExist = await Member.findOne({ 21 | user: id, 22 | project: project._id, 23 | }); 24 | 25 | if (memberAlreadyExist) { 26 | return next( 27 | new AppError('This user is already a member in the project.', 409) 28 | ); 29 | } 30 | 31 | const memberCount = await Member.countDocuments({ 32 | project: project._id, 33 | }); 34 | 35 | if (memberCount >= 5) { 36 | return next( 37 | new AppError('One project can only have 3 members as of now.', 409) 38 | ); 39 | } 40 | 41 | const member = await Member.create({ 42 | project: project._id, 43 | user: id, 44 | access: 'member', 45 | }); 46 | 47 | const history = await History.create({ 48 | project: project._id, 49 | user: req.user.userId, 50 | action: 'add-member', 51 | extraDetails: { 52 | member: member, 53 | user: member.user, 54 | }, 55 | }); 56 | 57 | await User.populate(history, 'user extraDetails.user'); 58 | 59 | return res.status(201).json({ 60 | status: 'success', 61 | project: project, 62 | member, 63 | history, 64 | }); 65 | }); 66 | 67 | export const getAllMembersOfProject = catchAsync(async (req, res) => { 68 | const { projectId } = req.params; 69 | const members = await Member.find({ project: projectId }).select( 70 | 'user access' 71 | ); 72 | await User.populate(members, { 73 | path: 'user', 74 | }); 75 | res.status(200).json({ status: 'success', count: members.length, members }); 76 | }); 77 | 78 | export const deleteAmemberFromProject = catchAsync(async (req, res, next) => { 79 | const { projectId, id } = req.params; 80 | const member = await Member.findById(id); 81 | if (member.access === 'admin') { 82 | return next( 83 | new AppError('An admin cannot remove itself from project.', 406) 84 | ); 85 | } 86 | 87 | const history = await History.create({ 88 | project: projectId, 89 | user: req.user.userId, 90 | action: 'remove-member', 91 | extraDetails: { 92 | member: member, 93 | user: member.user, 94 | }, 95 | }); 96 | 97 | await User.populate(history, 'user extraDetails.user'); 98 | 99 | const deletedMember = await Member.findByIdAndDelete(req.params.id); 100 | if (!deletedMember) { 101 | return next( 102 | new AppError("The member you are trying to delete doesn't exist.", 404) 103 | ); 104 | } 105 | res.status(204).json({ 106 | status: 'success', 107 | message: 'Member removed successfully', 108 | history, 109 | }); 110 | }); 111 | -------------------------------------------------------------------------------- /src/api/controllers/projectController.js: -------------------------------------------------------------------------------- 1 | import { Member } from '../../models/Member.js'; 2 | import { Project } from '../../models/Project.js'; 3 | import { Task } from '../../models/Task.js'; 4 | import { History } from '../../models/History.js'; 5 | import { User } from '../../models/User.js'; 6 | import { AppError } from '../../utils/AppError.js'; 7 | import { catchAsync } from '../../utils/catchAsync.js'; 8 | 9 | export const getAllProjects = catchAsync(async (req, res) => { 10 | const { scope } = req.query; 11 | const filterObj = { 12 | user: req.user.userId, 13 | }; 14 | if (scope === 'admin') { 15 | filterObj.access = 'admin'; 16 | } else if (scope === 'shared') { 17 | filterObj.access = 'member'; 18 | } 19 | 20 | // const projects = await Project.find(filterObj); 21 | const members = await Member.find(filterObj); 22 | await Project.populate(members, 'project'); 23 | await User.populate(members, 'user'); 24 | 25 | return res.status(200).json({ status: 'success', projects: members }); 26 | }); 27 | 28 | export const getProjectById = catchAsync(async (req, res, next) => { 29 | const project = await Project.findById(req.params.id); 30 | if (!project) { 31 | return next(new AppError('No project found.', 404)); 32 | } 33 | return res.status(200).json({ status: 'success', project }); 34 | }); 35 | 36 | export const createProject = catchAsync(async (req, res) => { 37 | const { title, description } = req.body; 38 | const newProject = await Project.create({ 39 | title, 40 | description, 41 | admin: req.user.userId, 42 | }); 43 | const member = await Member.create({ 44 | project: newProject._id, 45 | user: req.user.userId, 46 | access: 'admin', 47 | }); 48 | return res.status(201).json({ 49 | status: 'success', 50 | project: newProject, 51 | member, 52 | }); 53 | }); 54 | 55 | export const updateProject = catchAsync(async (req, res) => { 56 | const { id } = req.params; 57 | const { title, description } = req.body; 58 | const updatedProject = await Project.findByIdAndUpdate( 59 | id, 60 | { 61 | title, 62 | description, 63 | }, 64 | { 65 | new: true, 66 | runValidators: true, 67 | } 68 | ); 69 | 70 | return res.status(200).json({ 71 | status: 'success', 72 | project: updatedProject, 73 | }); 74 | }); 75 | 76 | export const deleteProject = catchAsync(async (req, res, next) => { 77 | const { id } = req.params; 78 | const project = await Project.findById(id); 79 | 80 | if (!project) { 81 | return next( 82 | new AppError("The project you are trying to delete doesn't exist.", 404) 83 | ); 84 | } 85 | 86 | await Member.deleteMany({ project: project._id }); 87 | await History.deleteMany({ project: project._id }); 88 | await Task.deleteMany({ project: project._id }); 89 | 90 | await project.remove(); 91 | res.status(204).json({ 92 | status: 'success', 93 | message: 'Project deleted Successfully', 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /src/api/controllers/tasksController.js: -------------------------------------------------------------------------------- 1 | import { catchAsync } from '../../utils/catchAsync.js'; 2 | import { Task } from '../../models/Task.js'; 3 | import { AppError } from '../../utils/AppError.js'; 4 | import { User } from '../../models/User.js'; 5 | import { Member } from '../../models/Member.js'; 6 | import { Project } from '../../models/Project.js'; 7 | import { History } from '../../models/History.js'; 8 | 9 | export const getAllTasks = catchAsync(async (req, res, next) => { 10 | const { projectId } = req.params; 11 | const tasks = await Task.find({ 12 | project: projectId, 13 | }).sort('order'); 14 | await Member.populate(tasks, { 15 | path: 'assignee author', 16 | }); 17 | await User.populate(tasks, { 18 | path: 'author.user assignee.user', 19 | }); 20 | return res.status(200).json({ status: 'success', tasks }); 21 | }); 22 | 23 | export const getTaskById = catchAsync(async (req, res, next) => { 24 | const { id } = req.params; 25 | const task = await Task.findById(id).populate({ 26 | path: 'author project assignee', 27 | Model: [User, Project, Member], 28 | }); 29 | await User.populate(task, { 30 | path: 'assignee.user', 31 | }); 32 | if (!task) { 33 | return next( 34 | new AppError("The Task you are looking for doesn't exist.", 404) 35 | ); 36 | } 37 | return res.status(200).json({ status: 'success', task }); 38 | }); 39 | 40 | export const createTask = catchAsync(async (req, res) => { 41 | const { projectId } = req.params; 42 | 43 | const tasksWithSameStatus = await Task.find({ 44 | status: req.body.status, 45 | project: projectId, 46 | }); 47 | const newTask = await Task.create({ 48 | ...req.body, 49 | author: req.user.memberId, 50 | project: projectId, 51 | order: tasksWithSameStatus.length, 52 | }); 53 | 54 | const history = await History.create({ 55 | task: newTask._id, 56 | project: projectId, 57 | user: req.user.userId, 58 | action: 'create', 59 | extraDetails: { 60 | taskTitle: newTask.title, 61 | }, 62 | }); 63 | await User.populate(history, 'user extraDetails.user'); 64 | return res.status(200).json({ 65 | status: 'success', 66 | task: newTask, 67 | history, 68 | }); 69 | }); 70 | 71 | export const updateTask = catchAsync(async (req, res, next) => { 72 | const { projectId, id } = req.params; 73 | const { 74 | title, 75 | description, 76 | status, 77 | priority, 78 | label, 79 | startDate, 80 | dueDate, 81 | assignee, 82 | } = req.body; 83 | const history = {}; 84 | 85 | // if (status) { 86 | // return next( 87 | // new AppError('You cannot update status through this route.', 403) 88 | // ); 89 | // } 90 | const taskToUpdate = await Task.findById(id); 91 | if (!taskToUpdate) { 92 | return next( 93 | new AppError("The Task you are trying to update doesn't exist.", 404) 94 | ); 95 | } 96 | const updatedTask = await Task.findByIdAndUpdate(id, req.body, { 97 | new: true, 98 | runValidators: true, 99 | }); 100 | if (title) { 101 | history.title = await History.create({ 102 | task: updatedTask._id, 103 | project: projectId, 104 | user: req.user.userId, 105 | action: 'update', 106 | extraDetails: { 107 | updatedField: 'title', 108 | updatedValue: updatedTask.title, 109 | }, 110 | }); 111 | await User.populate(history, 'user'); 112 | } 113 | 114 | if (description) { 115 | history.description = await History.create({ 116 | task: updatedTask._id, 117 | project: projectId, 118 | user: req.user.userId, 119 | action: 'update', 120 | extraDetails: { 121 | updatedField: 'description', 122 | updatedValue: updatedTask.description, 123 | }, 124 | }); 125 | await User.populate(history, 'user'); 126 | } 127 | 128 | if (priority) { 129 | history.priority = await History.create({ 130 | task: updatedTask._id, 131 | project: projectId, 132 | user: req.user.userId, 133 | action: 'update', 134 | extraDetails: { 135 | updatedField: 'priority', 136 | updatedValue: updatedTask.priority, 137 | }, 138 | }); 139 | await User.populate(history, 'user'); 140 | } 141 | 142 | if (startDate) { 143 | history.startDate = await History.create({ 144 | task: updatedTask._id, 145 | project: projectId, 146 | user: req.user.userId, 147 | action: 'update', 148 | extraDetails: { 149 | updatedField: 'startDate', 150 | updatedValue: updatedTask.startDate, 151 | }, 152 | }); 153 | await User.populate(history, 'user'); 154 | } 155 | 156 | if (dueDate) { 157 | history.dueDate = await History.create({ 158 | task: updatedTask._id, 159 | project: projectId, 160 | user: req.user.userId, 161 | action: 'update', 162 | extraDetails: { 163 | updatedField: 'dueDate', 164 | updatedValue: updatedTask.dueDate, 165 | }, 166 | }); 167 | await User.populate(history, 'user'); 168 | } 169 | 170 | if (label) { 171 | history.label = await History.create({ 172 | task: updatedTask._id, 173 | project: projectId, 174 | user: req.user.userId, 175 | action: 'update', 176 | extraDetails: { 177 | updatedField: 'label', 178 | updatedValue: updatedTask.label, 179 | }, 180 | }); 181 | await User.populate(history, 'user'); 182 | } 183 | 184 | if (assignee) { 185 | await Member.populate(updatedTask, 'assignee'); 186 | history.assignee = await History.create({ 187 | task: updatedTask._id, 188 | project: projectId, 189 | user: req.user.userId, 190 | action: 'assign', 191 | extraDetails: { 192 | user: updatedTask.assignee.user, 193 | }, 194 | }); 195 | await User.populate(history, 'user extraDetails.user'); 196 | } 197 | 198 | if (status) { 199 | const destinationLength = await Task.countDocuments({ 200 | status: updatedTask.status, 201 | project: projectId, 202 | }); 203 | updatedTask.order = !destinationLength ? 0 : destinationLength - 1; 204 | await updatedTask.save(); 205 | 206 | await Task.updateMany( 207 | { 208 | status: taskToUpdate.status, 209 | project: projectId, 210 | order: { 211 | $gt: taskToUpdate.order, 212 | }, 213 | }, 214 | { 215 | $inc: { order: -1 }, 216 | } 217 | ); 218 | 219 | const destinationTasks = await Task.find({ 220 | status: updatedTask.status, 221 | project: projectId, 222 | }); 223 | const sourceTasks = await Task.find({ 224 | status: taskToUpdate.status, 225 | project: projectId, 226 | }); 227 | history.status = await History.create({ 228 | task: updatedTask._id, 229 | project: projectId, 230 | user: req.user.userId, 231 | action: 'update', 232 | extraDetails: { 233 | updatedField: 'status', 234 | updatedValue: updatedTask.status, 235 | }, 236 | }); 237 | await User.populate(history, 'user'); 238 | res.status(200).json({ 239 | status: 'success', 240 | updatedTask, 241 | sourceTasks, 242 | destinationTasks, 243 | sourceStatus: taskToUpdate.status, 244 | destinationStatus: updatedTask.status, 245 | history, 246 | }); 247 | return; 248 | } 249 | 250 | res.status(200).json({ 251 | status: 'success', 252 | updatedTask, 253 | history, 254 | }); 255 | }); 256 | 257 | export const deleteTask = catchAsync(async (req, res, next) => { 258 | const { projectId, id } = req.params; 259 | 260 | const taskToDelete = await Task.findById(id); 261 | if (!taskToDelete) { 262 | return next( 263 | new AppError("The Task you are trying to delete doesn't exist.", 404) 264 | ); 265 | } 266 | // db.collection.updateMany(filter, update, options) 267 | await Task.updateMany( 268 | { 269 | status: taskToDelete.status, 270 | project: taskToDelete.project, 271 | order: { 272 | $gt: taskToDelete.order, 273 | }, 274 | }, 275 | { 276 | $inc: { order: -1 }, 277 | }, 278 | { 279 | new: true, 280 | runValidators: true, 281 | } 282 | ); 283 | 284 | // const sourceTasks = await Task.find({ 285 | // status: taskToDelete.status, 286 | // project: projectId, 287 | // }); 288 | 289 | const history = await History.create({ 290 | task: taskToDelete._id, 291 | project: projectId, 292 | user: req.user.userId, 293 | action: 'delete', 294 | extraDetails: { 295 | taskTitle: taskToDelete.title, 296 | }, 297 | }); 298 | 299 | await User.populate(history, 'user extraDetails.user'); 300 | 301 | await taskToDelete.remove(); 302 | 303 | res.status(204).json({ 304 | status: 'success', 305 | message: 'Task removed successfully', 306 | // sourceStatus: taskToDelete.status, 307 | // sourceTasks, 308 | }); 309 | }); 310 | 311 | // Board Drag n Drop 312 | export const updateTaskStatusInBoard = catchAsync(async (req, res, next) => { 313 | const { id, projectId } = req.params; 314 | const { destinationStatus, sourceStatus, sourceIndex, destinationIndex } = 315 | req.body; 316 | 317 | const task = await Task.findById(id); 318 | if (!task) { 319 | return next(new AppError('Task not found.', 404)); 320 | } 321 | // const srcStatusTasks = await Task.updateMany( 322 | await Task.updateMany( 323 | { 324 | status: sourceStatus, 325 | project: projectId, 326 | order: { 327 | $gt: task.order, 328 | }, 329 | }, 330 | { 331 | $inc: { order: -1 }, 332 | } 333 | ); 334 | 335 | // const destStatusTasks = await Task.updateMany( 336 | await Task.updateMany( 337 | { 338 | status: destinationStatus, 339 | project: projectId, 340 | order: { 341 | $gte: destinationIndex, 342 | }, 343 | }, 344 | { 345 | $inc: { order: 1 }, 346 | } 347 | ); 348 | 349 | task.status = destinationStatus; 350 | task.order = destinationIndex; 351 | await task.save(); 352 | 353 | const sourceTasks = await Task.find({ 354 | project: projectId, 355 | status: sourceStatus, 356 | }); 357 | 358 | const destinationTasks = await Task.find({ 359 | project: projectId, 360 | status: destinationStatus, 361 | }); 362 | 363 | const history = await History.create({ 364 | task: task._id, 365 | project: projectId, 366 | user: req.user.userId, 367 | action: 'update', 368 | extraDetails: { 369 | updatedField: 'status', 370 | updatedValue: task.status, 371 | }, 372 | }); 373 | 374 | await User.populate(history, 'user'); 375 | 376 | res.status(200).json({ 377 | status: 'success', 378 | destinationStatus, 379 | sourceStatus, 380 | sourceIndex, 381 | destinationIndex, 382 | task, 383 | sourceTasks, 384 | destinationTasks, 385 | history, 386 | }); 387 | }); 388 | -------------------------------------------------------------------------------- /src/api/controllers/userController.js: -------------------------------------------------------------------------------- 1 | import { User } from '../../models/User.js'; 2 | import { AppError } from '../../utils/AppError.js'; 3 | import { catchAsync } from '../../utils/catchAsync.js'; 4 | 5 | export const getProfile = catchAsync(async (req, res, next) => { 6 | const user = await User.findById(req.user.userId).select( 7 | '-transaction -client_id -tenant -request_language' 8 | ); 9 | 10 | if (!user) { 11 | return next(new AppError('No user found.', 404)); 12 | } 13 | res.status(200).json({ 14 | status: 'success', 15 | user, 16 | }); 17 | }); 18 | 19 | export const updateProfile = catchAsync(async (req, res, next) => { 20 | const { username, firstName, lastName, photo } = req.body; 21 | const updatedUser = await User.findByIdAndUpdate( 22 | req.user.userId, 23 | { 24 | username, 25 | firstName, 26 | lastName, 27 | photo, 28 | }, 29 | { new: true, runValidators: true } 30 | ); 31 | res.status(200).json({ 32 | status: 'success', 33 | updatedUser, 34 | }); 35 | }); 36 | 37 | export const getUsers = catchAsync(async (req, res, next) => { 38 | const filter = req.query.keyword 39 | ? { 40 | $or: [ 41 | { 42 | email: { 43 | $regex: req.query.keyword, 44 | $options: 'i', 45 | }, 46 | }, 47 | { 48 | username: { 49 | $regex: req.query.keyword, 50 | $options: 'i', 51 | }, 52 | }, 53 | ], 54 | } 55 | : {}; 56 | const count = await User.countDocuments(filter); 57 | const users = await User.find(filter); 58 | if (!users.length) { 59 | return next(new AppError('No Users Found', 404)); 60 | } 61 | res.status(200).json({ status: 'success', count, users }); 62 | }); 63 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import { taskRouter } from './routes/tasksRoutes.js'; 2 | import { projectRouter } from './routes/projectRoutes.js'; 3 | import { userRouter } from './routes/userRoutes.js'; 4 | import { memberRouter } from './routes/memberRoutes.js'; 5 | 6 | export { taskRouter, projectRouter, userRouter, memberRouter }; 7 | -------------------------------------------------------------------------------- /src/api/middlewares/accessToProjectMiddleware.js: -------------------------------------------------------------------------------- 1 | import { Member } from '../../models/Member.js'; 2 | import { AppError } from '../../utils/AppError.js'; 3 | import { catchAsync } from '../../utils/catchAsync.js'; 4 | 5 | export const accessToProjectMiddleware = catchAsync(async (req, res, next) => { 6 | const { projectId } = req.params; 7 | const isMember = await Member.findOne({ 8 | user: req.user.userId, 9 | project: projectId, 10 | }); 11 | if (!isMember) { 12 | return next( 13 | new AppError('You do not have the access to this project.', 403) 14 | ); 15 | } 16 | req.user.memberId = isMember._id; 17 | next(); 18 | }); 19 | -------------------------------------------------------------------------------- /src/api/middlewares/authMiddleware.js: -------------------------------------------------------------------------------- 1 | import jwt from 'express-jwt'; 2 | import jwksRsa from 'jwks-rsa'; 3 | import { config } from '../../config/index.js'; 4 | 5 | export const checkJwt = jwt({ 6 | secret: jwksRsa.expressJwtSecret({ 7 | cache: true, 8 | rateLimit: true, 9 | jwksRequestsPerMinute: 5, 10 | jwksUri: `https://${config.domain}/.well-known/jwks.json`, 11 | }), 12 | 13 | audience: config.audience, 14 | issuer: `https://${config.domain}/`, 15 | algorithms: ['RS256'], 16 | }); 17 | -------------------------------------------------------------------------------- /src/api/middlewares/authorizeMiddleware.js: -------------------------------------------------------------------------------- 1 | import { AppError } from '../../utils/AppError.js'; 2 | import { getUserDetails } from '../../utils/auth0.js'; 3 | import { catchAsync } from '../../utils/catchAsync.js'; 4 | import jwt_decode from 'jwt-decode'; 5 | 6 | export const authorizeMiddleware = catchAsync(async (req, res, next) => { 7 | let token; 8 | if ( 9 | req.headers.authorization && 10 | req.headers.authorization.startsWith('Bearer') 11 | ) { 12 | try { 13 | token = req.headers.authorization.split(' ')[1]; 14 | if (!token) { 15 | next(new AppError('Authorization Token was not found!', 404)); 16 | } 17 | // const { data } = await getUserDetails(token); 18 | const decoded = jwt_decode(token); 19 | req.user = decoded; 20 | const userId = req.user.sub.split('|')[1]; 21 | req.user.userId = userId; 22 | next(); 23 | } catch (error) { 24 | next(new AppError('Authorization Error', 404)); 25 | } 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /src/api/middlewares/isAdminInProjectMiddleware.js: -------------------------------------------------------------------------------- 1 | import { Member } from '../../models/Member.js'; 2 | import { AppError } from '../../utils/AppError.js'; 3 | import { catchAsync } from '../../utils/catchAsync.js'; 4 | 5 | export const isAdminInProject = catchAsync(async (req, res, next) => { 6 | const { projectId } = req.params; 7 | const isAdmin = await Member.findOne({ 8 | user: req.user.userId, 9 | project: projectId, 10 | access: 'admin', 11 | }); 12 | req.user.isAdmin = true; 13 | if (!isAdmin) { 14 | return next( 15 | new AppError('You need to be admin inorder to perform this action.', 403) 16 | ); 17 | } 18 | next(); 19 | }); 20 | -------------------------------------------------------------------------------- /src/api/routes/historyRoutes.js: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { 3 | getProjectHistory, 4 | getTaskHistory, 5 | } from '../controllers/historyController.js'; 6 | 7 | import { checkJwt } from '../middlewares/authMiddleware.js'; 8 | import { authorizeMiddleware } from '../middlewares/authorizeMiddleware.js'; 9 | 10 | export const historyRouter = Router(); 11 | historyRouter.use(checkJwt); 12 | historyRouter.use(authorizeMiddleware); 13 | historyRouter.route('/projects/:projectId').get(getProjectHistory); 14 | historyRouter.route('/projects/:projectId/tasks/:taskId').get(getTaskHistory); 15 | -------------------------------------------------------------------------------- /src/api/routes/memberRoutes.js: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { 3 | addMemberToProject, 4 | getAllMembersOfProject, 5 | deleteAmemberFromProject, 6 | } from '../controllers/memberController.js'; 7 | 8 | import { checkJwt } from '../middlewares/authMiddleware.js'; 9 | import { authorizeMiddleware } from '../middlewares/authorizeMiddleware.js'; 10 | import { isAdminInProject } from '../middlewares/isAdminInProjectMiddleware.js'; 11 | 12 | export const memberRouter = Router({ mergeParams: true }); 13 | memberRouter.use(checkJwt); 14 | memberRouter.use(authorizeMiddleware); 15 | memberRouter.route('/').get(getAllMembersOfProject); 16 | memberRouter.use(isAdminInProject); 17 | memberRouter 18 | .route('/:id') 19 | .delete(deleteAmemberFromProject) 20 | .post(addMemberToProject); 21 | -------------------------------------------------------------------------------- /src/api/routes/projectRoutes.js: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { 3 | createProject, 4 | deleteProject, 5 | getAllProjects, 6 | getProjectById, 7 | updateProject, 8 | } from '../controllers/projectController.js'; 9 | 10 | import { checkJwt } from '../middlewares/authMiddleware.js'; 11 | import { authorizeMiddleware } from '../middlewares/authorizeMiddleware.js'; 12 | 13 | import { memberRouter } from './memberRoutes.js'; 14 | import { taskRouter } from './tasksRoutes.js'; 15 | 16 | export const projectRouter = Router(); 17 | projectRouter.use(checkJwt); 18 | projectRouter.use(authorizeMiddleware); 19 | projectRouter.use('/:projectId/tasks', taskRouter); 20 | projectRouter.use('/:projectId/members', memberRouter); 21 | projectRouter.route('/').get(getAllProjects).post(createProject); 22 | projectRouter 23 | .route('/:id') 24 | .get(getProjectById) 25 | .patch(updateProject) 26 | .delete(deleteProject); 27 | -------------------------------------------------------------------------------- /src/api/routes/tasksRoutes.js: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { 3 | getAllTasks, 4 | getTaskById, 5 | createTask, 6 | updateTask, 7 | deleteTask, 8 | updateTaskStatusInBoard, 9 | // updateTaskStatus, 10 | } from '../controllers/tasksController.js'; 11 | import { checkJwt } from '../middlewares/authMiddleware.js'; 12 | import { authorizeMiddleware } from '../middlewares/authorizeMiddleware.js'; 13 | import { accessToProjectMiddleware } from '../middlewares/accessToProjectMiddleware.js'; 14 | 15 | export const taskRouter = Router({ mergeParams: true }); 16 | taskRouter.use(checkJwt); 17 | taskRouter.use(authorizeMiddleware); 18 | taskRouter.use(accessToProjectMiddleware); 19 | taskRouter.route('/').get(getAllTasks).post(createTask); 20 | taskRouter.route('/:id/update').patch(updateTaskStatusInBoard); 21 | // taskRouter.route('/:id/update-status').patch(updateTaskStatus); 22 | taskRouter.route('/:id').get(getTaskById).patch(updateTask).delete(deleteTask); 23 | -------------------------------------------------------------------------------- /src/api/routes/userRoutes.js: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { 3 | getProfile, 4 | updateProfile, 5 | getUsers, 6 | } from '../controllers/userController.js'; 7 | import { checkJwt } from '../middlewares/authMiddleware.js'; 8 | import { authorizeMiddleware } from '../middlewares/authorizeMiddleware.js'; 9 | 10 | export const userRouter = Router(); 11 | userRouter.use(checkJwt); 12 | userRouter.use(authorizeMiddleware); 13 | userRouter.route('/').get(getUsers); 14 | userRouter.route('/profile').get(getProfile).patch(updateProfile); 15 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import { connectDB, initExpress } from './loaders/index.js'; 2 | import { config } from './config/index.js'; 3 | import express from 'express'; 4 | import { Server } from 'socket.io'; 5 | import cors from 'cors'; 6 | connectDB(); 7 | 8 | // async function startServer() { 9 | try { 10 | const app = express(); 11 | initExpress({ app }); 12 | app.use(cors()); 13 | const server = app 14 | .listen(config.port, () => { 15 | console.log(` 16 | ################################################ 17 | 🛡️ Server listening on port: ${config.port} 🛡️ 18 | ################################################ 19 | `); 20 | }) 21 | .on('error', (err) => { 22 | console.log(err); 23 | process.exit(1); 24 | }); 25 | 26 | const io = new Server(server, { 27 | pingTimeout: 60000, 28 | // allowEIO3: true, 29 | // allowUpgrades: true, // false by default // this needs to be provided when using v4 on server and v2.3 on client 30 | cors: { 31 | origin: 'https://localhost:3000', 32 | methods: ['GET', 'POST'], 33 | }, 34 | }); 35 | 36 | io.on('connection', (socket) => { 37 | console.log('connection established'); 38 | socket.on('member-loggedIn', ({ member }) => { 39 | socket.join(member); 40 | }); 41 | socket.on( 42 | 'board_task_status_change', 43 | ({ member, updatedTask, memberIds }) => { 44 | memberIds.forEach((memb) => { 45 | if (memb === member) return; 46 | socket.in(memb).emit('board_update', { updatedTask }); 47 | }); 48 | } 49 | ); 50 | 51 | socket.on('delete_task_update', ({ member, taskId, memberIds }) => { 52 | memberIds.forEach((memb) => { 53 | if (memb === member) return; 54 | socket.in(memb).emit('delete_update', { taskId }); 55 | }); 56 | }); 57 | 58 | socket.on('create_task_update', ({ member, newTask, memberIds }) => { 59 | memberIds.forEach((memb) => { 60 | if (memb === member) return; 61 | socket.in(memb).emit('create_update', { newTask }); 62 | }); 63 | }); 64 | 65 | socket.on('disconnect', () => { 66 | console.log('End......'); 67 | }); 68 | }); 69 | io.on('connect_error', (err) => { 70 | console.log(`connect_error due to ${err.message}`); 71 | }); 72 | } catch (e) { 73 | console.log(e); 74 | } 75 | // } 76 | 77 | // startServer(); 78 | -------------------------------------------------------------------------------- /src/config/index.js: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | 3 | // Set the NODE_ENV to 'development' by default 4 | process.env.NODE_ENV = process.env.NODE_ENV || 'development'; 5 | 6 | const envFound = dotenv.config(); 7 | // if (envFound.error) { 8 | // // This error should crash whole process 9 | 10 | // throw new Error("⚠️ Couldn't find .env file ⚠️"); 11 | // } 12 | 13 | export const config = { 14 | /** 15 | * Your favorite port 16 | */ 17 | port: parseInt(process.env.PORT, 10), 18 | 19 | /** 20 | * That long string from mongodb 21 | */ 22 | databaseURL: process.env.MONGODB_URI, 23 | 24 | /** 25 | * MongoDB (DB) password 26 | */ 27 | databasePassword: process.env.DB_PASSWORD, 28 | 29 | /** 30 | * API configs 31 | */ 32 | api: { 33 | prefix: '/api/v1', 34 | }, 35 | 36 | /** 37 | * Auth0 Credentials 38 | */ 39 | audience: process.env.AUTH0_AUDIENCE, 40 | domain: process.env.AUTH0_DOMAIN, 41 | clientOriginUrl: process.env.CLIENT_ORIGIN_URL, 42 | }; 43 | -------------------------------------------------------------------------------- /src/loaders/index.js: -------------------------------------------------------------------------------- 1 | import { initExpress } from './initExpress.js'; 2 | import { connectDB } from './initDB.js'; 3 | 4 | export { initExpress, connectDB }; 5 | -------------------------------------------------------------------------------- /src/loaders/initDB.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | import { config } from '../config/index.js'; 3 | 4 | export const connectDB = async () => { 5 | try { 6 | let database_url = config.databaseURL; 7 | database_url = database_url.replace('', config.databasePassword); 8 | 9 | const connection = await mongoose.connect(database_url, { 10 | useUnifiedTopology: true, 11 | useNewUrlParser: true, 12 | useFindAndModify: false, 13 | useCreateIndex: true, 14 | }); 15 | console.log(`MongoDB Connected: ${connection.connection.host}`); 16 | } catch (error) { 17 | console.log(`Error: ${error.message}`); 18 | // process.exit(1) -> it going to exit with failure 19 | process.exit(1); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /src/loaders/initExpress.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import cors from 'cors'; 3 | import { projectRouter, userRouter } from '../api/index.js'; 4 | import { config } from '../config/index.js'; 5 | import morgan from 'morgan'; 6 | import { AppError } from '../utils/AppError.js'; 7 | import { globalErrorHandler } from '../api/controllers/errorController.js'; 8 | import helmet from 'helmet'; 9 | import { historyRouter } from '../api/routes/historyRoutes.js'; 10 | 11 | export const initExpress = ({ app }) => { 12 | app.use(helmet()); 13 | // Useful if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc) 14 | // It shows the real origin IP in the heroku or Cloudwatch logs 15 | app.enable('trust proxy'); 16 | // The magic package that prevents frontend developers going nuts 17 | // Alternate description: 18 | // Enable Cross Origin Resource Sharing to all origins by default 19 | if (process.env.NODE_ENV === 'production') { 20 | app.use(cors({ origin: 'https://projectboard.vercel.app' })); 21 | } else { 22 | app.use(cors()); 23 | } 24 | 25 | // Development Logging 26 | if (process.env.NODE_ENV === 'development') { 27 | app.use(morgan('dev')); 28 | } 29 | 30 | // Middleware that transforms the raw string of req.body into json 31 | app.use(express.json()); 32 | // Load API routes 33 | app.get('/', (req, res) => res.send('API is running')); 34 | app.use(`${config.api.prefix}/projects`, projectRouter); 35 | app.use(`${config.api.prefix}/users`, userRouter); 36 | app.use(`${config.api.prefix}/history`, historyRouter); 37 | 38 | // all runs for all http methods 39 | app.all('*', (req, res, next) => { 40 | next(new AppError(`Can't find ${req.originalUrl} on the server!`, 404)); 41 | }); 42 | 43 | app.use(globalErrorHandler); 44 | }; 45 | -------------------------------------------------------------------------------- /src/models/Comments.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const commentSchema = mongoose.Schema({ 4 | project: { 5 | type: mongoose.Schema.Types.ObjectId, 6 | required: true, 7 | ref: 'Project', 8 | }, 9 | user: { 10 | type: mongoose.Schema.Types.ObjectId, 11 | required: true, 12 | ref: 'User', 13 | }, 14 | task: { 15 | type: mongoose.Schema.Types.ObjectId, 16 | required: true, 17 | ref: 'Task', 18 | }, 19 | comment: { 20 | type: String, 21 | required: true, 22 | }, 23 | }); 24 | 25 | export const Comment = mongoose.model('Comment', commentSchema); 26 | -------------------------------------------------------------------------------- /src/models/History.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const historySchema = mongoose.Schema( 4 | { 5 | task: { 6 | type: mongoose.Schema.Types.ObjectId, 7 | ref: 'Task', 8 | }, 9 | project: { 10 | type: mongoose.Schema.Types.ObjectId, 11 | required: true, 12 | ref: 'Project', 13 | }, 14 | user: { 15 | type: mongoose.Schema.Types.ObjectId, 16 | required: true, 17 | ref: 'User', 18 | }, 19 | action: { 20 | type: String, 21 | enum: [ 22 | 'create', 23 | 'update', 24 | 'delete', 25 | 'change', 26 | 'assign', 27 | 'add-member', 28 | 'remove-member', 29 | ], 30 | required: true, 31 | }, 32 | extraDetails: mongoose.Schema.Types.Mixed, 33 | }, 34 | { 35 | timestamps: true, 36 | } 37 | ); 38 | 39 | export const History = mongoose.model('History', historySchema); 40 | -------------------------------------------------------------------------------- /src/models/Member.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const memberSchema = mongoose.Schema( 4 | { 5 | project: { 6 | type: mongoose.Schema.Types.ObjectId, 7 | ref: 'Project', 8 | required: true, 9 | }, 10 | user: { 11 | type: mongoose.Schema.Types.ObjectId, 12 | ref: 'User', 13 | required: true, 14 | }, 15 | access: { 16 | type: String, 17 | enum: ['admin', 'member'], 18 | default: 'member', 19 | }, 20 | }, 21 | { 22 | toJSON: { virtuals: true }, 23 | toObject: { virtuals: true }, 24 | timestamps: true, 25 | } 26 | ); 27 | 28 | export const Member = mongoose.model('Member', memberSchema); 29 | -------------------------------------------------------------------------------- /src/models/Project.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const projectSchema = mongoose.Schema( 4 | { 5 | title: { 6 | type: String, 7 | required: true, 8 | }, 9 | description: { 10 | type: String, 11 | required: true, 12 | }, 13 | }, 14 | { 15 | toJSON: { virtuals: true }, 16 | toObject: { virtuals: true }, 17 | timestamps: true, 18 | } 19 | ); 20 | 21 | projectSchema.virtual('members', { 22 | ref: 'Member', 23 | foreignField: 'project', 24 | localField: '_id', 25 | }); 26 | 27 | export const Project = mongoose.model('Project', projectSchema); 28 | -------------------------------------------------------------------------------- /src/models/Task.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const taskSchema = mongoose.Schema( 4 | { 5 | order: { 6 | type: Number, 7 | required: true, 8 | }, 9 | project: { 10 | type: mongoose.Schema.Types.ObjectId, 11 | required: true, 12 | ref: 'Project', 13 | }, 14 | author: { 15 | type: mongoose.Schema.Types.ObjectId, 16 | required: true, 17 | ref: 'Member', 18 | }, 19 | title: { 20 | type: String, 21 | required: true, 22 | }, 23 | description: { 24 | type: String, 25 | default: 'No Description', 26 | }, 27 | label: { 28 | type: String, 29 | default: 'No Label', 30 | enum: ['Bug', 'Feature', 'Improvement', 'No Label'], 31 | }, 32 | priority: { 33 | type: String, 34 | default: 'no_priority', 35 | enum: ['no_priority', 'low', 'medium', 'high', 'urgent'], 36 | }, 37 | status: { 38 | type: String, 39 | default: 'backlog', 40 | enum: ['backlog', 'todo', 'in_progress', 'done', 'cancelled'], 41 | }, 42 | assignee: { 43 | type: mongoose.Schema.Types.ObjectId, 44 | ref: 'Member', 45 | }, 46 | startDate: { 47 | type: Date, 48 | default: Date.now, 49 | }, 50 | dueDate: { 51 | type: Date, 52 | }, 53 | }, 54 | { 55 | toJSON: { virtuals: true }, 56 | toObject: { virtuals: true }, 57 | timestamps: true, 58 | } 59 | ); 60 | 61 | taskSchema.index({ order: 1 }); 62 | 63 | export const Task = mongoose.model('Task', taskSchema); 64 | -------------------------------------------------------------------------------- /src/models/User.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const userSchema = mongoose.Schema( 4 | { 5 | firstName: { 6 | type: String, 7 | }, 8 | lastName: { 9 | type: String, 10 | }, 11 | username: { 12 | type: String, 13 | index: { 14 | unique: true, 15 | partialFilterExpression: { username: { $type: 'string' } }, 16 | }, 17 | }, 18 | email: { 19 | type: String, 20 | required: true, 21 | unique: true, 22 | }, 23 | password: { 24 | type: String, 25 | required: true, 26 | select: false, 27 | }, 28 | email_verified: { 29 | type: Boolean, 30 | }, 31 | photo: { 32 | type: String, 33 | }, 34 | tenant: { 35 | type: String, 36 | select: false, 37 | }, 38 | transaction: { 39 | type: mongoose.Schema.Types.Mixed, 40 | select: false, 41 | }, 42 | client_id: { 43 | type: String, 44 | select: false, 45 | }, 46 | connection: { 47 | type: String, 48 | select: false, 49 | }, 50 | request_language: { 51 | type: String, 52 | select: false, 53 | }, 54 | }, 55 | { 56 | toJSON: { virtuals: true }, 57 | toObject: { virtuals: true }, 58 | timestamps: true, 59 | } 60 | ); 61 | userSchema.virtual('projects', { 62 | ref: 'Member', 63 | foreignField: 'user', 64 | localField: '_id', 65 | }); 66 | 67 | // userSchema.set('toObject', { virtuals: true }); 68 | // userSchema.set('toJSON', { virtuals: true }); 69 | 70 | export const User = mongoose.model('User', userSchema); 71 | -------------------------------------------------------------------------------- /src/utils/AppError.js: -------------------------------------------------------------------------------- 1 | class AppError extends Error { 2 | constructor(message, statusCode) { 3 | super(message); 4 | this.statusCode = statusCode; 5 | // this.status if 404 then fail else if 500(bad request) then error 6 | this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; 7 | this.isOperational = true; 8 | Error.captureStackTrace(this, this.constructor); 9 | } 10 | } 11 | 12 | export { AppError }; 13 | -------------------------------------------------------------------------------- /src/utils/auth0.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { config } from '../config/index.js'; 3 | 4 | export const getUserDetails = (token) => 5 | axios({ 6 | url: `https://${config.domain}/userinfo`, 7 | method: 'GET', 8 | headers: { 9 | Authorization: `Bearer ${token}`, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /src/utils/catchAsync.js: -------------------------------------------------------------------------------- 1 | export const catchAsync = (fn) => { 2 | return (req, res, next) => { 3 | fn(req, res, next).catch(next); 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@7.12.11": 6 | version "7.12.11" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" 8 | integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== 9 | dependencies: 10 | "@babel/highlight" "^7.10.4" 11 | 12 | "@babel/helper-validator-identifier@^7.14.5": 13 | version "7.14.9" 14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" 15 | integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== 16 | 17 | "@babel/highlight@^7.10.4": 18 | version "7.14.5" 19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" 20 | integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== 21 | dependencies: 22 | "@babel/helper-validator-identifier" "^7.14.5" 23 | chalk "^2.0.0" 24 | js-tokens "^4.0.0" 25 | 26 | "@eslint/eslintrc@^0.4.3": 27 | version "0.4.3" 28 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" 29 | integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== 30 | dependencies: 31 | ajv "^6.12.4" 32 | debug "^4.1.1" 33 | espree "^7.3.0" 34 | globals "^13.9.0" 35 | ignore "^4.0.6" 36 | import-fresh "^3.2.1" 37 | js-yaml "^3.13.1" 38 | minimatch "^3.0.4" 39 | strip-json-comments "^3.1.1" 40 | 41 | "@humanwhocodes/config-array@^0.5.0": 42 | version "0.5.0" 43 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" 44 | integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== 45 | dependencies: 46 | "@humanwhocodes/object-schema" "^1.2.0" 47 | debug "^4.1.1" 48 | minimatch "^3.0.4" 49 | 50 | "@humanwhocodes/object-schema@^1.2.0": 51 | version "1.2.0" 52 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" 53 | integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== 54 | 55 | "@panva/asn1.js@^1.0.0": 56 | version "1.0.0" 57 | resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6" 58 | integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw== 59 | 60 | "@types/body-parser@*": 61 | version "1.19.1" 62 | resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.1.tgz#0c0174c42a7d017b818303d4b5d969cb0b75929c" 63 | integrity sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg== 64 | dependencies: 65 | "@types/connect" "*" 66 | "@types/node" "*" 67 | 68 | "@types/bson@*": 69 | version "4.0.5" 70 | resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.0.5.tgz#9e0e1d1a6f8866483f96868a9b33bc804926b1fc" 71 | integrity sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg== 72 | dependencies: 73 | "@types/node" "*" 74 | 75 | "@types/component-emitter@^1.2.10": 76 | version "1.2.10" 77 | resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea" 78 | integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg== 79 | 80 | "@types/connect@*": 81 | version "3.4.35" 82 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" 83 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 84 | dependencies: 85 | "@types/node" "*" 86 | 87 | "@types/cookie@^0.4.0": 88 | version "0.4.1" 89 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" 90 | integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== 91 | 92 | "@types/cors@^2.8.10": 93 | version "2.8.12" 94 | resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" 95 | integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== 96 | 97 | "@types/express-jwt@0.0.42": 98 | version "0.0.42" 99 | resolved "https://registry.yarnpkg.com/@types/express-jwt/-/express-jwt-0.0.42.tgz#4f04e1fadf9d18725950dc041808a4a4adf7f5ae" 100 | integrity sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag== 101 | dependencies: 102 | "@types/express" "*" 103 | "@types/express-unless" "*" 104 | 105 | "@types/express-serve-static-core@^4.17.18": 106 | version "4.17.24" 107 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz#ea41f93bf7e0d59cd5a76665068ed6aab6815c07" 108 | integrity sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA== 109 | dependencies: 110 | "@types/node" "*" 111 | "@types/qs" "*" 112 | "@types/range-parser" "*" 113 | 114 | "@types/express-unless@*": 115 | version "0.5.2" 116 | resolved "https://registry.yarnpkg.com/@types/express-unless/-/express-unless-0.5.2.tgz#07e29883d280778588644b03563d8796f870f20e" 117 | integrity sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ== 118 | dependencies: 119 | "@types/express" "*" 120 | 121 | "@types/express@*": 122 | version "4.17.13" 123 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" 124 | integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== 125 | dependencies: 126 | "@types/body-parser" "*" 127 | "@types/express-serve-static-core" "^4.17.18" 128 | "@types/qs" "*" 129 | "@types/serve-static" "*" 130 | 131 | "@types/mime@^1": 132 | version "1.3.2" 133 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" 134 | integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== 135 | 136 | "@types/mongodb@^3.5.27": 137 | version "3.6.20" 138 | resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.6.20.tgz#b7c5c580644f6364002b649af1c06c3c0454e1d2" 139 | integrity sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ== 140 | dependencies: 141 | "@types/bson" "*" 142 | "@types/node" "*" 143 | 144 | "@types/node@*": 145 | version "16.4.13" 146 | resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.13.tgz#7dfd9c14661edc65cccd43a29eb454174642370d" 147 | integrity sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg== 148 | 149 | "@types/node@>=10.0.0": 150 | version "16.6.1" 151 | resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.1.tgz#aee62c7b966f55fc66c7b6dfa1d58db2a616da61" 152 | integrity sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw== 153 | 154 | "@types/qs@*": 155 | version "6.9.7" 156 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" 157 | integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== 158 | 159 | "@types/range-parser@*": 160 | version "1.2.4" 161 | resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" 162 | integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== 163 | 164 | "@types/serve-static@*": 165 | version "1.13.10" 166 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" 167 | integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== 168 | dependencies: 169 | "@types/mime" "^1" 170 | "@types/node" "*" 171 | 172 | accepts@~1.3.4, accepts@~1.3.7: 173 | version "1.3.7" 174 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" 175 | integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== 176 | dependencies: 177 | mime-types "~2.1.24" 178 | negotiator "0.6.2" 179 | 180 | acorn-jsx@^5.3.1: 181 | version "5.3.2" 182 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 183 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 184 | 185 | acorn@^7.4.0: 186 | version "7.4.1" 187 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" 188 | integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 189 | 190 | ajv@^6.10.0, ajv@^6.12.4: 191 | version "6.12.6" 192 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 193 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 194 | dependencies: 195 | fast-deep-equal "^3.1.1" 196 | fast-json-stable-stringify "^2.0.0" 197 | json-schema-traverse "^0.4.1" 198 | uri-js "^4.2.2" 199 | 200 | ajv@^8.0.1: 201 | version "8.6.2" 202 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" 203 | integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== 204 | dependencies: 205 | fast-deep-equal "^3.1.1" 206 | json-schema-traverse "^1.0.0" 207 | require-from-string "^2.0.2" 208 | uri-js "^4.2.2" 209 | 210 | ansi-colors@^4.1.1: 211 | version "4.1.1" 212 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 213 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 214 | 215 | ansi-regex@^5.0.0: 216 | version "5.0.0" 217 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 218 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 219 | 220 | ansi-styles@^3.2.1: 221 | version "3.2.1" 222 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 223 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 224 | dependencies: 225 | color-convert "^1.9.0" 226 | 227 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 228 | version "4.3.0" 229 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 230 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 231 | dependencies: 232 | color-convert "^2.0.1" 233 | 234 | argparse@^1.0.7: 235 | version "1.0.10" 236 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 237 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 238 | dependencies: 239 | sprintf-js "~1.0.2" 240 | 241 | array-flatten@1.1.1: 242 | version "1.1.1" 243 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 244 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 245 | 246 | astral-regex@^2.0.0: 247 | version "2.0.0" 248 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" 249 | integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== 250 | 251 | async@^1.5.0: 252 | version "1.5.2" 253 | resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" 254 | integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= 255 | 256 | axios@^0.21.1: 257 | version "0.21.1" 258 | resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" 259 | integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== 260 | dependencies: 261 | follow-redirects "^1.10.0" 262 | 263 | balanced-match@^1.0.0: 264 | version "1.0.2" 265 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 266 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 267 | 268 | base64-arraybuffer@0.1.4: 269 | version "0.1.4" 270 | resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" 271 | integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= 272 | 273 | base64id@2.0.0, base64id@~2.0.0: 274 | version "2.0.0" 275 | resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" 276 | integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== 277 | 278 | basic-auth@~2.0.1: 279 | version "2.0.1" 280 | resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" 281 | integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== 282 | dependencies: 283 | safe-buffer "5.1.2" 284 | 285 | bl@^2.2.1: 286 | version "2.2.1" 287 | resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5" 288 | integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g== 289 | dependencies: 290 | readable-stream "^2.3.5" 291 | safe-buffer "^5.1.1" 292 | 293 | bluebird@3.5.1: 294 | version "3.5.1" 295 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 296 | integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== 297 | 298 | body-parser@1.19.0: 299 | version "1.19.0" 300 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 301 | integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== 302 | dependencies: 303 | bytes "3.1.0" 304 | content-type "~1.0.4" 305 | debug "2.6.9" 306 | depd "~1.1.2" 307 | http-errors "1.7.2" 308 | iconv-lite "0.4.24" 309 | on-finished "~2.3.0" 310 | qs "6.7.0" 311 | raw-body "2.4.0" 312 | type-is "~1.6.17" 313 | 314 | brace-expansion@^1.1.7: 315 | version "1.1.11" 316 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 317 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 318 | dependencies: 319 | balanced-match "^1.0.0" 320 | concat-map "0.0.1" 321 | 322 | bson@^1.1.4: 323 | version "1.1.6" 324 | resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a" 325 | integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg== 326 | 327 | buffer-equal-constant-time@1.0.1: 328 | version "1.0.1" 329 | resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" 330 | integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= 331 | 332 | bytes@3.1.0: 333 | version "3.1.0" 334 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 335 | integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== 336 | 337 | callsites@^3.0.0: 338 | version "3.1.0" 339 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 340 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 341 | 342 | chalk@^2.0.0: 343 | version "2.4.2" 344 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 345 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 346 | dependencies: 347 | ansi-styles "^3.2.1" 348 | escape-string-regexp "^1.0.5" 349 | supports-color "^5.3.0" 350 | 351 | chalk@^4.0.0: 352 | version "4.1.2" 353 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 354 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 355 | dependencies: 356 | ansi-styles "^4.1.0" 357 | supports-color "^7.1.0" 358 | 359 | color-convert@^1.9.0: 360 | version "1.9.3" 361 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 362 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 363 | dependencies: 364 | color-name "1.1.3" 365 | 366 | color-convert@^2.0.1: 367 | version "2.0.1" 368 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 369 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 370 | dependencies: 371 | color-name "~1.1.4" 372 | 373 | color-name@1.1.3: 374 | version "1.1.3" 375 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 376 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 377 | 378 | color-name@~1.1.4: 379 | version "1.1.4" 380 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 381 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 382 | 383 | component-emitter@~1.3.0: 384 | version "1.3.0" 385 | resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" 386 | integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== 387 | 388 | concat-map@0.0.1: 389 | version "0.0.1" 390 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 391 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 392 | 393 | content-disposition@0.5.3: 394 | version "0.5.3" 395 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" 396 | integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== 397 | dependencies: 398 | safe-buffer "5.1.2" 399 | 400 | content-type@~1.0.4: 401 | version "1.0.4" 402 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 403 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 404 | 405 | cookie-signature@1.0.6: 406 | version "1.0.6" 407 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 408 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 409 | 410 | cookie@0.4.0: 411 | version "0.4.0" 412 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" 413 | integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== 414 | 415 | cookie@~0.4.1: 416 | version "0.4.1" 417 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" 418 | integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== 419 | 420 | core-util-is@~1.0.0: 421 | version "1.0.2" 422 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 423 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 424 | 425 | cors@^2.8.5, cors@~2.8.5: 426 | version "2.8.5" 427 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" 428 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== 429 | dependencies: 430 | object-assign "^4" 431 | vary "^1" 432 | 433 | cross-spawn@^7.0.2: 434 | version "7.0.3" 435 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 436 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 437 | dependencies: 438 | path-key "^3.1.0" 439 | shebang-command "^2.0.0" 440 | which "^2.0.1" 441 | 442 | debug@2.6.9: 443 | version "2.6.9" 444 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 445 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 446 | dependencies: 447 | ms "2.0.0" 448 | 449 | debug@3.1.0: 450 | version "3.1.0" 451 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 452 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 453 | dependencies: 454 | ms "2.0.0" 455 | 456 | debug@^4.0.1, debug@^4.1.1, debug@^4.3.2, debug@~4.3.1: 457 | version "4.3.2" 458 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" 459 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 460 | dependencies: 461 | ms "2.1.2" 462 | 463 | deep-is@^0.1.3: 464 | version "0.1.3" 465 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 466 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 467 | 468 | denque@^1.4.1: 469 | version "1.5.0" 470 | resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de" 471 | integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ== 472 | 473 | depd@~1.1.2: 474 | version "1.1.2" 475 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 476 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 477 | 478 | depd@~2.0.0: 479 | version "2.0.0" 480 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 481 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 482 | 483 | destroy@~1.0.4: 484 | version "1.0.4" 485 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 486 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 487 | 488 | doctrine@^3.0.0: 489 | version "3.0.0" 490 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 491 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 492 | dependencies: 493 | esutils "^2.0.2" 494 | 495 | dotenv@^10.0.0: 496 | version "10.0.0" 497 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" 498 | integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== 499 | 500 | ecdsa-sig-formatter@1.0.11: 501 | version "1.0.11" 502 | resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" 503 | integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== 504 | dependencies: 505 | safe-buffer "^5.0.1" 506 | 507 | ee-first@1.1.1: 508 | version "1.1.1" 509 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 510 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 511 | 512 | emoji-regex@^8.0.0: 513 | version "8.0.0" 514 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 515 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 516 | 517 | encodeurl@~1.0.2: 518 | version "1.0.2" 519 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 520 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 521 | 522 | engine.io-parser@~4.0.0: 523 | version "4.0.2" 524 | resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.2.tgz#e41d0b3fb66f7bf4a3671d2038a154024edb501e" 525 | integrity sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg== 526 | dependencies: 527 | base64-arraybuffer "0.1.4" 528 | 529 | engine.io@~5.1.1: 530 | version "5.1.1" 531 | resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-5.1.1.tgz#a1f97e51ddf10cbd4db8b5ff4b165aad3760cdd3" 532 | integrity sha512-aMWot7H5aC8L4/T8qMYbLdvKlZOdJTH54FxfdFunTGvhMx1BHkJOntWArsVfgAZVwAO9LC2sryPWRcEeUzCe5w== 533 | dependencies: 534 | accepts "~1.3.4" 535 | base64id "2.0.0" 536 | cookie "~0.4.1" 537 | cors "~2.8.5" 538 | debug "~4.3.1" 539 | engine.io-parser "~4.0.0" 540 | ws "~7.4.2" 541 | 542 | enquirer@^2.3.5: 543 | version "2.3.6" 544 | resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" 545 | integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== 546 | dependencies: 547 | ansi-colors "^4.1.1" 548 | 549 | escape-html@~1.0.3: 550 | version "1.0.3" 551 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 552 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 553 | 554 | escape-string-regexp@^1.0.5: 555 | version "1.0.5" 556 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 557 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 558 | 559 | escape-string-regexp@^4.0.0: 560 | version "4.0.0" 561 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 562 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 563 | 564 | eslint-config-prettier@^8.3.0: 565 | version "8.3.0" 566 | resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" 567 | integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== 568 | 569 | eslint-plugin-prettier@^3.4.0: 570 | version "3.4.0" 571 | resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" 572 | integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== 573 | dependencies: 574 | prettier-linter-helpers "^1.0.0" 575 | 576 | eslint-scope@^5.1.1: 577 | version "5.1.1" 578 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" 579 | integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== 580 | dependencies: 581 | esrecurse "^4.3.0" 582 | estraverse "^4.1.1" 583 | 584 | eslint-utils@^2.1.0: 585 | version "2.1.0" 586 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" 587 | integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== 588 | dependencies: 589 | eslint-visitor-keys "^1.1.0" 590 | 591 | eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: 592 | version "1.3.0" 593 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" 594 | integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== 595 | 596 | eslint-visitor-keys@^2.0.0: 597 | version "2.1.0" 598 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" 599 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 600 | 601 | eslint@^7.32.0: 602 | version "7.32.0" 603 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" 604 | integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== 605 | dependencies: 606 | "@babel/code-frame" "7.12.11" 607 | "@eslint/eslintrc" "^0.4.3" 608 | "@humanwhocodes/config-array" "^0.5.0" 609 | ajv "^6.10.0" 610 | chalk "^4.0.0" 611 | cross-spawn "^7.0.2" 612 | debug "^4.0.1" 613 | doctrine "^3.0.0" 614 | enquirer "^2.3.5" 615 | escape-string-regexp "^4.0.0" 616 | eslint-scope "^5.1.1" 617 | eslint-utils "^2.1.0" 618 | eslint-visitor-keys "^2.0.0" 619 | espree "^7.3.1" 620 | esquery "^1.4.0" 621 | esutils "^2.0.2" 622 | fast-deep-equal "^3.1.3" 623 | file-entry-cache "^6.0.1" 624 | functional-red-black-tree "^1.0.1" 625 | glob-parent "^5.1.2" 626 | globals "^13.6.0" 627 | ignore "^4.0.6" 628 | import-fresh "^3.0.0" 629 | imurmurhash "^0.1.4" 630 | is-glob "^4.0.0" 631 | js-yaml "^3.13.1" 632 | json-stable-stringify-without-jsonify "^1.0.1" 633 | levn "^0.4.1" 634 | lodash.merge "^4.6.2" 635 | minimatch "^3.0.4" 636 | natural-compare "^1.4.0" 637 | optionator "^0.9.1" 638 | progress "^2.0.0" 639 | regexpp "^3.1.0" 640 | semver "^7.2.1" 641 | strip-ansi "^6.0.0" 642 | strip-json-comments "^3.1.0" 643 | table "^6.0.9" 644 | text-table "^0.2.0" 645 | v8-compile-cache "^2.0.3" 646 | 647 | espree@^7.3.0, espree@^7.3.1: 648 | version "7.3.1" 649 | resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" 650 | integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== 651 | dependencies: 652 | acorn "^7.4.0" 653 | acorn-jsx "^5.3.1" 654 | eslint-visitor-keys "^1.3.0" 655 | 656 | esprima@^4.0.0: 657 | version "4.0.1" 658 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 659 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 660 | 661 | esquery@^1.4.0: 662 | version "1.4.0" 663 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" 664 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 665 | dependencies: 666 | estraverse "^5.1.0" 667 | 668 | esrecurse@^4.3.0: 669 | version "4.3.0" 670 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 671 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 672 | dependencies: 673 | estraverse "^5.2.0" 674 | 675 | estraverse@^4.1.1: 676 | version "4.3.0" 677 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 678 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 679 | 680 | estraverse@^5.1.0, estraverse@^5.2.0: 681 | version "5.2.0" 682 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" 683 | integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== 684 | 685 | esutils@^2.0.2: 686 | version "2.0.3" 687 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 688 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 689 | 690 | etag@~1.8.1: 691 | version "1.8.1" 692 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 693 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 694 | 695 | express-jwt@^6.0.0: 696 | version "6.0.0" 697 | resolved "https://registry.yarnpkg.com/express-jwt/-/express-jwt-6.0.0.tgz#20886c730983ffb1c706a4383235df86eff349b8" 698 | integrity sha512-C26y9myRjx7CyhZ+BAT3p+gQyRCoDZ7qo8plCvLDaRT6je6ALIAQknT6XLVQGFKwIy/Ux7lvM2MNap5dt0T7gA== 699 | dependencies: 700 | async "^1.5.0" 701 | express-unless "^0.3.0" 702 | jsonwebtoken "^8.1.0" 703 | lodash.set "^4.0.0" 704 | 705 | express-unless@^0.3.0: 706 | version "0.3.1" 707 | resolved "https://registry.yarnpkg.com/express-unless/-/express-unless-0.3.1.tgz#2557c146e75beb903e2d247f9b5ba01452696e20" 708 | integrity sha1-JVfBRudb65A+LSR/m1ugFFJpbiA= 709 | 710 | express@^4.17.1: 711 | version "4.17.1" 712 | resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" 713 | integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== 714 | dependencies: 715 | accepts "~1.3.7" 716 | array-flatten "1.1.1" 717 | body-parser "1.19.0" 718 | content-disposition "0.5.3" 719 | content-type "~1.0.4" 720 | cookie "0.4.0" 721 | cookie-signature "1.0.6" 722 | debug "2.6.9" 723 | depd "~1.1.2" 724 | encodeurl "~1.0.2" 725 | escape-html "~1.0.3" 726 | etag "~1.8.1" 727 | finalhandler "~1.1.2" 728 | fresh "0.5.2" 729 | merge-descriptors "1.0.1" 730 | methods "~1.1.2" 731 | on-finished "~2.3.0" 732 | parseurl "~1.3.3" 733 | path-to-regexp "0.1.7" 734 | proxy-addr "~2.0.5" 735 | qs "6.7.0" 736 | range-parser "~1.2.1" 737 | safe-buffer "5.1.2" 738 | send "0.17.1" 739 | serve-static "1.14.1" 740 | setprototypeof "1.1.1" 741 | statuses "~1.5.0" 742 | type-is "~1.6.18" 743 | utils-merge "1.0.1" 744 | vary "~1.1.2" 745 | 746 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 747 | version "3.1.3" 748 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 749 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 750 | 751 | fast-diff@^1.1.2: 752 | version "1.2.0" 753 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" 754 | integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== 755 | 756 | fast-json-stable-stringify@^2.0.0: 757 | version "2.1.0" 758 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 759 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 760 | 761 | fast-levenshtein@^2.0.6: 762 | version "2.0.6" 763 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 764 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 765 | 766 | file-entry-cache@^6.0.1: 767 | version "6.0.1" 768 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 769 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 770 | dependencies: 771 | flat-cache "^3.0.4" 772 | 773 | finalhandler@~1.1.2: 774 | version "1.1.2" 775 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" 776 | integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== 777 | dependencies: 778 | debug "2.6.9" 779 | encodeurl "~1.0.2" 780 | escape-html "~1.0.3" 781 | on-finished "~2.3.0" 782 | parseurl "~1.3.3" 783 | statuses "~1.5.0" 784 | unpipe "~1.0.0" 785 | 786 | flat-cache@^3.0.4: 787 | version "3.0.4" 788 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" 789 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 790 | dependencies: 791 | flatted "^3.1.0" 792 | rimraf "^3.0.2" 793 | 794 | flatted@^3.1.0: 795 | version "3.2.2" 796 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" 797 | integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== 798 | 799 | follow-redirects@^1.10.0: 800 | version "1.14.1" 801 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" 802 | integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== 803 | 804 | forwarded@0.2.0: 805 | version "0.2.0" 806 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" 807 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 808 | 809 | fresh@0.5.2: 810 | version "0.5.2" 811 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 812 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 813 | 814 | fs.realpath@^1.0.0: 815 | version "1.0.0" 816 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 817 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 818 | 819 | functional-red-black-tree@^1.0.1: 820 | version "1.0.1" 821 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 822 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 823 | 824 | glob-parent@^5.1.2: 825 | version "5.1.2" 826 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 827 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 828 | dependencies: 829 | is-glob "^4.0.1" 830 | 831 | glob@^7.1.3: 832 | version "7.1.7" 833 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" 834 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== 835 | dependencies: 836 | fs.realpath "^1.0.0" 837 | inflight "^1.0.4" 838 | inherits "2" 839 | minimatch "^3.0.4" 840 | once "^1.3.0" 841 | path-is-absolute "^1.0.0" 842 | 843 | globals@^13.6.0, globals@^13.9.0: 844 | version "13.10.0" 845 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.10.0.tgz#60ba56c3ac2ca845cfbf4faeca727ad9dd204676" 846 | integrity sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g== 847 | dependencies: 848 | type-fest "^0.20.2" 849 | 850 | has-flag@^3.0.0: 851 | version "3.0.0" 852 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 853 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 854 | 855 | has-flag@^4.0.0: 856 | version "4.0.0" 857 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 858 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 859 | 860 | helmet@^4.6.0: 861 | version "4.6.0" 862 | resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.6.0.tgz#579971196ba93c5978eb019e4e8ec0e50076b4df" 863 | integrity sha512-HVqALKZlR95ROkrnesdhbbZJFi/rIVSoNq6f3jA/9u6MIbTsPh3xZwihjeI5+DO/2sOV6HMHooXcEOuwskHpTg== 864 | 865 | http-errors@1.7.2: 866 | version "1.7.2" 867 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" 868 | integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== 869 | dependencies: 870 | depd "~1.1.2" 871 | inherits "2.0.3" 872 | setprototypeof "1.1.1" 873 | statuses ">= 1.5.0 < 2" 874 | toidentifier "1.0.0" 875 | 876 | http-errors@~1.7.2: 877 | version "1.7.3" 878 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" 879 | integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== 880 | dependencies: 881 | depd "~1.1.2" 882 | inherits "2.0.4" 883 | setprototypeof "1.1.1" 884 | statuses ">= 1.5.0 < 2" 885 | toidentifier "1.0.0" 886 | 887 | iconv-lite@0.4.24: 888 | version "0.4.24" 889 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 890 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 891 | dependencies: 892 | safer-buffer ">= 2.1.2 < 3" 893 | 894 | ignore@^4.0.6: 895 | version "4.0.6" 896 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" 897 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== 898 | 899 | import-fresh@^3.0.0, import-fresh@^3.2.1: 900 | version "3.3.0" 901 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 902 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 903 | dependencies: 904 | parent-module "^1.0.0" 905 | resolve-from "^4.0.0" 906 | 907 | imurmurhash@^0.1.4: 908 | version "0.1.4" 909 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 910 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 911 | 912 | inflight@^1.0.4: 913 | version "1.0.6" 914 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 915 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 916 | dependencies: 917 | once "^1.3.0" 918 | wrappy "1" 919 | 920 | inherits@2, inherits@2.0.4, inherits@~2.0.3: 921 | version "2.0.4" 922 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 923 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 924 | 925 | inherits@2.0.3: 926 | version "2.0.3" 927 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 928 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 929 | 930 | ipaddr.js@1.9.1: 931 | version "1.9.1" 932 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 933 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 934 | 935 | is-extglob@^2.1.1: 936 | version "2.1.1" 937 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 938 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 939 | 940 | is-fullwidth-code-point@^3.0.0: 941 | version "3.0.0" 942 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 943 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 944 | 945 | is-glob@^4.0.0, is-glob@^4.0.1: 946 | version "4.0.1" 947 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 948 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 949 | dependencies: 950 | is-extglob "^2.1.1" 951 | 952 | isarray@~1.0.0: 953 | version "1.0.0" 954 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 955 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 956 | 957 | isexe@^2.0.0: 958 | version "2.0.0" 959 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 960 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 961 | 962 | jose@^2.0.5: 963 | version "2.0.5" 964 | resolved "https://registry.yarnpkg.com/jose/-/jose-2.0.5.tgz#29746a18d9fff7dcf9d5d2a6f62cb0c7cd27abd3" 965 | integrity sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA== 966 | dependencies: 967 | "@panva/asn1.js" "^1.0.0" 968 | 969 | js-tokens@^4.0.0: 970 | version "4.0.0" 971 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 972 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 973 | 974 | js-yaml@^3.13.1: 975 | version "3.14.1" 976 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 977 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 978 | dependencies: 979 | argparse "^1.0.7" 980 | esprima "^4.0.0" 981 | 982 | json-schema-traverse@^0.4.1: 983 | version "0.4.1" 984 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 985 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 986 | 987 | json-schema-traverse@^1.0.0: 988 | version "1.0.0" 989 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" 990 | integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== 991 | 992 | json-stable-stringify-without-jsonify@^1.0.1: 993 | version "1.0.1" 994 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 995 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 996 | 997 | jsonwebtoken@^8.1.0: 998 | version "8.5.1" 999 | resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" 1000 | integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== 1001 | dependencies: 1002 | jws "^3.2.2" 1003 | lodash.includes "^4.3.0" 1004 | lodash.isboolean "^3.0.3" 1005 | lodash.isinteger "^4.0.4" 1006 | lodash.isnumber "^3.0.3" 1007 | lodash.isplainobject "^4.0.6" 1008 | lodash.isstring "^4.0.1" 1009 | lodash.once "^4.0.0" 1010 | ms "^2.1.1" 1011 | semver "^5.6.0" 1012 | 1013 | jwa@^1.4.1: 1014 | version "1.4.1" 1015 | resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" 1016 | integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== 1017 | dependencies: 1018 | buffer-equal-constant-time "1.0.1" 1019 | ecdsa-sig-formatter "1.0.11" 1020 | safe-buffer "^5.0.1" 1021 | 1022 | jwks-rsa@^2.0.4: 1023 | version "2.0.4" 1024 | resolved "https://registry.yarnpkg.com/jwks-rsa/-/jwks-rsa-2.0.4.tgz#59d95e39f300783a8582ef8aa37d5ebbc6a8aa6f" 1025 | integrity sha512-iJqVCECYZZ+3oPmY1qXv3Fq+3ywDtuNEVBvG41pPlaR0zyGxa12nC0beAOBBUhETJmc05puS50mRQN4NkCGhmg== 1026 | dependencies: 1027 | "@types/express-jwt" "0.0.42" 1028 | debug "^4.3.2" 1029 | jose "^2.0.5" 1030 | limiter "^1.1.5" 1031 | lru-memoizer "^2.1.4" 1032 | 1033 | jws@^3.2.2: 1034 | version "3.2.2" 1035 | resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" 1036 | integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== 1037 | dependencies: 1038 | jwa "^1.4.1" 1039 | safe-buffer "^5.0.1" 1040 | 1041 | jwt-decode@^3.1.2: 1042 | version "3.1.2" 1043 | resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" 1044 | integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== 1045 | 1046 | kareem@2.3.2: 1047 | version "2.3.2" 1048 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.2.tgz#78c4508894985b8d38a0dc15e1a8e11078f2ca93" 1049 | integrity sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ== 1050 | 1051 | levn@^0.4.1: 1052 | version "0.4.1" 1053 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 1054 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 1055 | dependencies: 1056 | prelude-ls "^1.2.1" 1057 | type-check "~0.4.0" 1058 | 1059 | limiter@^1.1.5: 1060 | version "1.1.5" 1061 | resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" 1062 | integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA== 1063 | 1064 | lodash.clonedeep@^4.5.0: 1065 | version "4.5.0" 1066 | resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" 1067 | integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= 1068 | 1069 | lodash.includes@^4.3.0: 1070 | version "4.3.0" 1071 | resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" 1072 | integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= 1073 | 1074 | lodash.isboolean@^3.0.3: 1075 | version "3.0.3" 1076 | resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" 1077 | integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= 1078 | 1079 | lodash.isinteger@^4.0.4: 1080 | version "4.0.4" 1081 | resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" 1082 | integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= 1083 | 1084 | lodash.isnumber@^3.0.3: 1085 | version "3.0.3" 1086 | resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" 1087 | integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= 1088 | 1089 | lodash.isplainobject@^4.0.6: 1090 | version "4.0.6" 1091 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 1092 | integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= 1093 | 1094 | lodash.isstring@^4.0.1: 1095 | version "4.0.1" 1096 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 1097 | integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= 1098 | 1099 | lodash.merge@^4.6.2: 1100 | version "4.6.2" 1101 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 1102 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 1103 | 1104 | lodash.once@^4.0.0: 1105 | version "4.1.1" 1106 | resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" 1107 | integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= 1108 | 1109 | lodash.set@^4.0.0: 1110 | version "4.3.2" 1111 | resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" 1112 | integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= 1113 | 1114 | lodash.truncate@^4.4.2: 1115 | version "4.4.2" 1116 | resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" 1117 | integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= 1118 | 1119 | lru-cache@^6.0.0: 1120 | version "6.0.0" 1121 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1122 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1123 | dependencies: 1124 | yallist "^4.0.0" 1125 | 1126 | lru-cache@~4.0.0: 1127 | version "4.0.2" 1128 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" 1129 | integrity sha1-HRdnnAac2l0ECZGgnbwsDbN35V4= 1130 | dependencies: 1131 | pseudomap "^1.0.1" 1132 | yallist "^2.0.0" 1133 | 1134 | lru-memoizer@^2.1.4: 1135 | version "2.1.4" 1136 | resolved "https://registry.yarnpkg.com/lru-memoizer/-/lru-memoizer-2.1.4.tgz#b864d92b557f00b1eeb322156a0409cb06dafac6" 1137 | integrity sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ== 1138 | dependencies: 1139 | lodash.clonedeep "^4.5.0" 1140 | lru-cache "~4.0.0" 1141 | 1142 | media-typer@0.3.0: 1143 | version "0.3.0" 1144 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 1145 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 1146 | 1147 | memory-pager@^1.0.2: 1148 | version "1.5.0" 1149 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 1150 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== 1151 | 1152 | merge-descriptors@1.0.1: 1153 | version "1.0.1" 1154 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 1155 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 1156 | 1157 | methods@~1.1.2: 1158 | version "1.1.2" 1159 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 1160 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 1161 | 1162 | mime-db@1.49.0: 1163 | version "1.49.0" 1164 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" 1165 | integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== 1166 | 1167 | mime-types@~2.1.24: 1168 | version "2.1.32" 1169 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" 1170 | integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== 1171 | dependencies: 1172 | mime-db "1.49.0" 1173 | 1174 | mime@1.6.0: 1175 | version "1.6.0" 1176 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 1177 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 1178 | 1179 | minimatch@^3.0.4: 1180 | version "3.0.4" 1181 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1182 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 1183 | dependencies: 1184 | brace-expansion "^1.1.7" 1185 | 1186 | mongodb@3.6.10: 1187 | version "3.6.10" 1188 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.10.tgz#f10e990113c86b195c8af0599b9b3a90748b6ee4" 1189 | integrity sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q== 1190 | dependencies: 1191 | bl "^2.2.1" 1192 | bson "^1.1.4" 1193 | denque "^1.4.1" 1194 | optional-require "^1.0.3" 1195 | safe-buffer "^5.1.2" 1196 | optionalDependencies: 1197 | saslprep "^1.0.0" 1198 | 1199 | mongoose-legacy-pluralize@1.0.2: 1200 | version "1.0.2" 1201 | resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4" 1202 | integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ== 1203 | 1204 | mongoose@^5.13.5: 1205 | version "5.13.5" 1206 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.13.5.tgz#9c8c0b46d35116dd4ea47683dfa836137e475243" 1207 | integrity sha512-sSUAk9GWgA8r3w3nVNrNjBaDem86aevwXO8ltDMKzCf+rjnteMMQkXHQdn1ePkt7alROEPZYCAjiRjptWRSPiQ== 1208 | dependencies: 1209 | "@types/mongodb" "^3.5.27" 1210 | bson "^1.1.4" 1211 | kareem "2.3.2" 1212 | mongodb "3.6.10" 1213 | mongoose-legacy-pluralize "1.0.2" 1214 | mpath "0.8.3" 1215 | mquery "3.2.5" 1216 | ms "2.1.2" 1217 | optional-require "1.0.x" 1218 | regexp-clone "1.0.0" 1219 | safe-buffer "5.2.1" 1220 | sift "13.5.2" 1221 | sliced "1.0.1" 1222 | 1223 | morgan@^1.10.0: 1224 | version "1.10.0" 1225 | resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" 1226 | integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== 1227 | dependencies: 1228 | basic-auth "~2.0.1" 1229 | debug "2.6.9" 1230 | depd "~2.0.0" 1231 | on-finished "~2.3.0" 1232 | on-headers "~1.0.2" 1233 | 1234 | mpath@0.8.3: 1235 | version "0.8.3" 1236 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.8.3.tgz#828ac0d187f7f42674839d74921970979abbdd8f" 1237 | integrity sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA== 1238 | 1239 | mquery@3.2.5: 1240 | version "3.2.5" 1241 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.2.5.tgz#8f2305632e4bb197f68f60c0cffa21aaf4060c51" 1242 | integrity sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A== 1243 | dependencies: 1244 | bluebird "3.5.1" 1245 | debug "3.1.0" 1246 | regexp-clone "^1.0.0" 1247 | safe-buffer "5.1.2" 1248 | sliced "1.0.1" 1249 | 1250 | ms@2.0.0: 1251 | version "2.0.0" 1252 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1253 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 1254 | 1255 | ms@2.1.1: 1256 | version "2.1.1" 1257 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 1258 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 1259 | 1260 | ms@2.1.2: 1261 | version "2.1.2" 1262 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1263 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1264 | 1265 | ms@^2.1.1: 1266 | version "2.1.3" 1267 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 1268 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1269 | 1270 | natural-compare@^1.4.0: 1271 | version "1.4.0" 1272 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 1273 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 1274 | 1275 | negotiator@0.6.2: 1276 | version "0.6.2" 1277 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" 1278 | integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== 1279 | 1280 | object-assign@^4: 1281 | version "4.1.1" 1282 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1283 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 1284 | 1285 | on-finished@~2.3.0: 1286 | version "2.3.0" 1287 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 1288 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 1289 | dependencies: 1290 | ee-first "1.1.1" 1291 | 1292 | on-headers@~1.0.2: 1293 | version "1.0.2" 1294 | resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" 1295 | integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== 1296 | 1297 | once@^1.3.0: 1298 | version "1.4.0" 1299 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1300 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1301 | dependencies: 1302 | wrappy "1" 1303 | 1304 | optional-require@1.0.x: 1305 | version "1.0.3" 1306 | resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.0.3.tgz#275b8e9df1dc6a17ad155369c2422a440f89cb07" 1307 | integrity sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA== 1308 | 1309 | optional-require@^1.0.3: 1310 | version "1.1.6" 1311 | resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.1.6.tgz#886693c22d166c79377137dfb60cd653fa49a967" 1312 | integrity sha512-ZO2GGh1A84LV90OAIsMDmIJ5k/f7crSjP4aJSuLudp7C7wfVOAoyWWHV8Jf3ZMHyNHwpLD/DGhzaxbbN/duF+g== 1313 | dependencies: 1314 | require-at "^1.0.6" 1315 | 1316 | optionator@^0.9.1: 1317 | version "0.9.1" 1318 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" 1319 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 1320 | dependencies: 1321 | deep-is "^0.1.3" 1322 | fast-levenshtein "^2.0.6" 1323 | levn "^0.4.1" 1324 | prelude-ls "^1.2.1" 1325 | type-check "^0.4.0" 1326 | word-wrap "^1.2.3" 1327 | 1328 | parent-module@^1.0.0: 1329 | version "1.0.1" 1330 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 1331 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1332 | dependencies: 1333 | callsites "^3.0.0" 1334 | 1335 | parseurl@~1.3.3: 1336 | version "1.3.3" 1337 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 1338 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 1339 | 1340 | path-is-absolute@^1.0.0: 1341 | version "1.0.1" 1342 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1343 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1344 | 1345 | path-key@^3.1.0: 1346 | version "3.1.1" 1347 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1348 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1349 | 1350 | path-to-regexp@0.1.7: 1351 | version "0.1.7" 1352 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 1353 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 1354 | 1355 | prelude-ls@^1.2.1: 1356 | version "1.2.1" 1357 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 1358 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 1359 | 1360 | prettier-linter-helpers@^1.0.0: 1361 | version "1.0.0" 1362 | resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" 1363 | integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== 1364 | dependencies: 1365 | fast-diff "^1.1.2" 1366 | 1367 | prettier@^2.3.2: 1368 | version "2.3.2" 1369 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" 1370 | integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== 1371 | 1372 | process-nextick-args@~2.0.0: 1373 | version "2.0.1" 1374 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 1375 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 1376 | 1377 | progress@^2.0.0: 1378 | version "2.0.3" 1379 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 1380 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 1381 | 1382 | proxy-addr@~2.0.5: 1383 | version "2.0.7" 1384 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" 1385 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 1386 | dependencies: 1387 | forwarded "0.2.0" 1388 | ipaddr.js "1.9.1" 1389 | 1390 | pseudomap@^1.0.1: 1391 | version "1.0.2" 1392 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 1393 | integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= 1394 | 1395 | punycode@^2.1.0: 1396 | version "2.1.1" 1397 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 1398 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1399 | 1400 | qs@6.7.0: 1401 | version "6.7.0" 1402 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" 1403 | integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== 1404 | 1405 | range-parser@~1.2.1: 1406 | version "1.2.1" 1407 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 1408 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 1409 | 1410 | raw-body@2.4.0: 1411 | version "2.4.0" 1412 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" 1413 | integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== 1414 | dependencies: 1415 | bytes "3.1.0" 1416 | http-errors "1.7.2" 1417 | iconv-lite "0.4.24" 1418 | unpipe "1.0.0" 1419 | 1420 | readable-stream@^2.3.5: 1421 | version "2.3.7" 1422 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 1423 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 1424 | dependencies: 1425 | core-util-is "~1.0.0" 1426 | inherits "~2.0.3" 1427 | isarray "~1.0.0" 1428 | process-nextick-args "~2.0.0" 1429 | safe-buffer "~5.1.1" 1430 | string_decoder "~1.1.1" 1431 | util-deprecate "~1.0.1" 1432 | 1433 | regexp-clone@1.0.0, regexp-clone@^1.0.0: 1434 | version "1.0.0" 1435 | resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63" 1436 | integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw== 1437 | 1438 | regexpp@^3.1.0: 1439 | version "3.2.0" 1440 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" 1441 | integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 1442 | 1443 | require-at@^1.0.6: 1444 | version "1.0.6" 1445 | resolved "https://registry.yarnpkg.com/require-at/-/require-at-1.0.6.tgz#9eb7e3c5e00727f5a4744070a7f560d4de4f6e6a" 1446 | integrity sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g== 1447 | 1448 | require-from-string@^2.0.2: 1449 | version "2.0.2" 1450 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" 1451 | integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== 1452 | 1453 | resolve-from@^4.0.0: 1454 | version "4.0.0" 1455 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 1456 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1457 | 1458 | rimraf@^3.0.2: 1459 | version "3.0.2" 1460 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1461 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1462 | dependencies: 1463 | glob "^7.1.3" 1464 | 1465 | safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1466 | version "5.1.2" 1467 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1468 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 1469 | 1470 | safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2: 1471 | version "5.2.1" 1472 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1473 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1474 | 1475 | "safer-buffer@>= 2.1.2 < 3": 1476 | version "2.1.2" 1477 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1478 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 1479 | 1480 | saslprep@^1.0.0: 1481 | version "1.0.3" 1482 | resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" 1483 | integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== 1484 | dependencies: 1485 | sparse-bitfield "^3.0.3" 1486 | 1487 | semver@^5.6.0: 1488 | version "5.7.1" 1489 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 1490 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 1491 | 1492 | semver@^7.2.1: 1493 | version "7.3.5" 1494 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" 1495 | integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== 1496 | dependencies: 1497 | lru-cache "^6.0.0" 1498 | 1499 | send@0.17.1: 1500 | version "0.17.1" 1501 | resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" 1502 | integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== 1503 | dependencies: 1504 | debug "2.6.9" 1505 | depd "~1.1.2" 1506 | destroy "~1.0.4" 1507 | encodeurl "~1.0.2" 1508 | escape-html "~1.0.3" 1509 | etag "~1.8.1" 1510 | fresh "0.5.2" 1511 | http-errors "~1.7.2" 1512 | mime "1.6.0" 1513 | ms "2.1.1" 1514 | on-finished "~2.3.0" 1515 | range-parser "~1.2.1" 1516 | statuses "~1.5.0" 1517 | 1518 | serve-static@1.14.1: 1519 | version "1.14.1" 1520 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" 1521 | integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== 1522 | dependencies: 1523 | encodeurl "~1.0.2" 1524 | escape-html "~1.0.3" 1525 | parseurl "~1.3.3" 1526 | send "0.17.1" 1527 | 1528 | setprototypeof@1.1.1: 1529 | version "1.1.1" 1530 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 1531 | integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== 1532 | 1533 | shebang-command@^2.0.0: 1534 | version "2.0.0" 1535 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1536 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1537 | dependencies: 1538 | shebang-regex "^3.0.0" 1539 | 1540 | shebang-regex@^3.0.0: 1541 | version "3.0.0" 1542 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1543 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1544 | 1545 | sift@13.5.2: 1546 | version "13.5.2" 1547 | resolved "https://registry.yarnpkg.com/sift/-/sift-13.5.2.tgz#24a715e13c617b086166cd04917d204a591c9da6" 1548 | integrity sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA== 1549 | 1550 | slice-ansi@^4.0.0: 1551 | version "4.0.0" 1552 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" 1553 | integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== 1554 | dependencies: 1555 | ansi-styles "^4.0.0" 1556 | astral-regex "^2.0.0" 1557 | is-fullwidth-code-point "^3.0.0" 1558 | 1559 | sliced@1.0.1: 1560 | version "1.0.1" 1561 | resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" 1562 | integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E= 1563 | 1564 | socket.io-adapter@~2.3.1: 1565 | version "2.3.1" 1566 | resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz#a442720cb09a4823cfb81287dda1f9b52d4ccdb2" 1567 | integrity sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw== 1568 | 1569 | socket.io-parser@~4.0.4: 1570 | version "4.0.4" 1571 | resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" 1572 | integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== 1573 | dependencies: 1574 | "@types/component-emitter" "^1.2.10" 1575 | component-emitter "~1.3.0" 1576 | debug "~4.3.1" 1577 | 1578 | socket.io@^4.1.3: 1579 | version "4.1.3" 1580 | resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.1.3.tgz#d114328ef27ab31b889611792959c3fa6d502500" 1581 | integrity sha512-tLkaY13RcO4nIRh1K2hT5iuotfTaIQw7cVIe0FUykN3SuQi0cm7ALxuyT5/CtDswOMWUzMGTibxYNx/gU7In+Q== 1582 | dependencies: 1583 | "@types/cookie" "^0.4.0" 1584 | "@types/cors" "^2.8.10" 1585 | "@types/node" ">=10.0.0" 1586 | accepts "~1.3.4" 1587 | base64id "~2.0.0" 1588 | debug "~4.3.1" 1589 | engine.io "~5.1.1" 1590 | socket.io-adapter "~2.3.1" 1591 | socket.io-parser "~4.0.4" 1592 | 1593 | sparse-bitfield@^3.0.3: 1594 | version "3.0.3" 1595 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 1596 | integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= 1597 | dependencies: 1598 | memory-pager "^1.0.2" 1599 | 1600 | sprintf-js@~1.0.2: 1601 | version "1.0.3" 1602 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1603 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 1604 | 1605 | "statuses@>= 1.5.0 < 2", statuses@~1.5.0: 1606 | version "1.5.0" 1607 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 1608 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 1609 | 1610 | string-width@^4.2.0: 1611 | version "4.2.2" 1612 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" 1613 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== 1614 | dependencies: 1615 | emoji-regex "^8.0.0" 1616 | is-fullwidth-code-point "^3.0.0" 1617 | strip-ansi "^6.0.0" 1618 | 1619 | string_decoder@~1.1.1: 1620 | version "1.1.1" 1621 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1622 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 1623 | dependencies: 1624 | safe-buffer "~5.1.0" 1625 | 1626 | strip-ansi@^6.0.0: 1627 | version "6.0.0" 1628 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 1629 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 1630 | dependencies: 1631 | ansi-regex "^5.0.0" 1632 | 1633 | strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: 1634 | version "3.1.1" 1635 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1636 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1637 | 1638 | supports-color@^5.3.0: 1639 | version "5.5.0" 1640 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1641 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1642 | dependencies: 1643 | has-flag "^3.0.0" 1644 | 1645 | supports-color@^7.1.0: 1646 | version "7.2.0" 1647 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1648 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1649 | dependencies: 1650 | has-flag "^4.0.0" 1651 | 1652 | table@^6.0.9: 1653 | version "6.7.1" 1654 | resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" 1655 | integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== 1656 | dependencies: 1657 | ajv "^8.0.1" 1658 | lodash.clonedeep "^4.5.0" 1659 | lodash.truncate "^4.4.2" 1660 | slice-ansi "^4.0.0" 1661 | string-width "^4.2.0" 1662 | strip-ansi "^6.0.0" 1663 | 1664 | text-table@^0.2.0: 1665 | version "0.2.0" 1666 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1667 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1668 | 1669 | toidentifier@1.0.0: 1670 | version "1.0.0" 1671 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 1672 | integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== 1673 | 1674 | type-check@^0.4.0, type-check@~0.4.0: 1675 | version "0.4.0" 1676 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 1677 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1678 | dependencies: 1679 | prelude-ls "^1.2.1" 1680 | 1681 | type-fest@^0.20.2: 1682 | version "0.20.2" 1683 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1684 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1685 | 1686 | type-is@~1.6.17, type-is@~1.6.18: 1687 | version "1.6.18" 1688 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 1689 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 1690 | dependencies: 1691 | media-typer "0.3.0" 1692 | mime-types "~2.1.24" 1693 | 1694 | unpipe@1.0.0, unpipe@~1.0.0: 1695 | version "1.0.0" 1696 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1697 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 1698 | 1699 | uri-js@^4.2.2: 1700 | version "4.4.1" 1701 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1702 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1703 | dependencies: 1704 | punycode "^2.1.0" 1705 | 1706 | util-deprecate@~1.0.1: 1707 | version "1.0.2" 1708 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1709 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 1710 | 1711 | utils-merge@1.0.1: 1712 | version "1.0.1" 1713 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 1714 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 1715 | 1716 | v8-compile-cache@^2.0.3: 1717 | version "2.3.0" 1718 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 1719 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 1720 | 1721 | vary@^1, vary@~1.1.2: 1722 | version "1.1.2" 1723 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 1724 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 1725 | 1726 | which@^2.0.1: 1727 | version "2.0.2" 1728 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1729 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1730 | dependencies: 1731 | isexe "^2.0.0" 1732 | 1733 | word-wrap@^1.2.3: 1734 | version "1.2.3" 1735 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 1736 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1737 | 1738 | wrappy@1: 1739 | version "1.0.2" 1740 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1741 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1742 | 1743 | ws@~7.4.2: 1744 | version "7.4.6" 1745 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" 1746 | integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== 1747 | 1748 | yallist@^2.0.0: 1749 | version "2.1.2" 1750 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 1751 | integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= 1752 | 1753 | yallist@^4.0.0: 1754 | version "4.0.0" 1755 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1756 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1757 | --------------------------------------------------------------------------------