├── .env.example ├── .gitignore ├── README.md ├── app ├── controllers │ ├── AuthController.ts │ └── OrganizerController.ts ├── interfaces │ ├── Common.ts │ ├── IOrganizer.ts │ ├── IRole.ts │ └── index.d.ts ├── middleware │ ├── auth.ts │ ├── index.ts │ └── validateRequest.ts ├── models │ ├── OrganizerSchema.ts │ ├── RoleSchema.ts │ └── index.ts ├── routers │ ├── AuthRouter.ts │ ├── OrganizerRouter.ts │ ├── index.ts │ └── routes.ts ├── validations │ └── InvitationValidation.ts └── views │ └── InvitationEmail.ejs ├── index.ts ├── package.json ├── tsconfig.json ├── utils ├── constants │ └── constants.ts ├── enums │ └── enums.ts ├── errors │ ├── ApiError.ts │ ├── globalErrorHandler.ts │ ├── handleCastError.ts │ ├── handleValidationError.ts │ └── handleZodError.ts ├── helpers │ ├── bcrypt │ │ ├── compareString.ts │ │ ├── hashString.ts │ │ └── index.ts │ ├── email │ │ ├── index.ts │ │ ├── mailTeamplates.ts │ │ └── sendMail.ts │ ├── global │ │ ├── catchAsync.ts │ │ ├── getRequestUrl.ts │ │ ├── index.ts │ │ └── sendResponse.ts │ ├── jwt │ │ ├── generateToken.ts │ │ ├── index.ts │ │ └── verifyToken.ts │ ├── logger │ │ ├── index.ts │ │ ├── logger.ts │ │ └── requestLogger.ts │ └── transforms │ │ ├── calculatePagination.ts │ │ ├── generateKeyString.ts │ │ ├── index.ts │ │ ├── pick.ts │ │ ├── removeFile.ts │ │ └── returnFilePath.ts ├── json │ └── activityJson.ts ├── multer │ ├── configMulter.ts │ └── fileTransfer.ts ├── server │ ├── bootstrap.ts │ ├── config.ts │ ├── connectToDatabase.ts │ ├── globalMiddlewares.ts │ ├── handleRouteNotFound.ts │ ├── index.ts │ └── transporter.ts └── type │ ├── file.ts │ ├── pagination.ts │ └── types.ts └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | PORT=6001 2 | ENV=development 3 | 4 | MONGOOSE_URI= 5 | DATABASE_NAME= 6 | TOKEN_SECRET= 7 | TOKEN_SECRET_EXP=30d 8 | 9 | BYCRYPT_SALT_ROUND=10 10 | 11 | SENDER_EMAIL_HOSTNAME= 12 | SENDER_EMAIL_PORT=465 13 | SENDER_EMAIL_NAME=KidsAi 14 | SENDER_EMAIL_ID= 15 | SENDER_EMAIL_PASSWORD= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | logs 4 | dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Express Typescript Starter 2 | 3 | ## Features 4 | 5 | - [x] 6 | 7 | ## Technologies 8 | 9 | - [x] Node.js 10 | - [x] Express.js 11 | - [x] MongoDB 12 | 13 | ## How you will run this application to your machine? 14 | 15 | 1. Check that, you have install `Node.js`, `typescript` on your machine. 16 | 2. Clone the `main` branch of repository with command `git clone https://github.com/soumik9/express-typescript-starter.git` or download the code as zip and extract code. 17 | 3. Navigate to folder, then Open `command prompt` on the specific folder and run command `yarn` or `npm i` 18 | 4. Create a file name `.env` and copy all from `.env.example` then place the mongodb uri and other token as required. 19 | 5. All set, now run `command prompt` this command `yarn dev` or `npm run dev` -------------------------------------------------------------------------------- /app/controllers/AuthController.ts: -------------------------------------------------------------------------------- 1 | import { Request, RequestHandler, Response } from "express"; 2 | import httpStatus from "http-status"; 3 | import ApiError from "../../utils/errors/ApiError"; 4 | import { Organizer } from "../models"; 5 | import { catchAsync, sendResponse } from "../../utils/helpers/global"; 6 | import { compareString } from "../../utils/helpers/bcrypt"; 7 | import { generateToken } from "../../utils/helpers/jwt"; 8 | import { IOrganizer } from "../interfaces/IOrganizer"; 9 | 10 | // sass signin controller 11 | const Signin: RequestHandler = catchAsync( 12 | async (req: Request, res: Response) => { 13 | 14 | // parsing data 15 | const body = JSON.parse(req.body.data); 16 | const { email, password: reqPassword } = body; 17 | 18 | // checking email and password given 19 | if (!email || !reqPassword) 20 | throw new ApiError(httpStatus.BAD_REQUEST, 'Data not found!'); 21 | 22 | // finding user 23 | const findOrgnizer = await Organizer.isOrganizerExistsByEmail(email); 24 | if (!findOrgnizer) 25 | throw new ApiError(httpStatus.NOT_FOUND, 'You are not a registered user!'); 26 | 27 | // checking is organizer accepted invitation 28 | if (!findOrgnizer.isEmailVerified) 29 | throw new ApiError(httpStatus.NOT_FOUND, 'Accept your invitaion & try again!'); 30 | 31 | // checking is valid password 32 | const isValidPassword = await compareString(reqPassword, findOrgnizer.password); 33 | if (!isValidPassword) 34 | throw new ApiError(httpStatus.UNAUTHORIZED, 'Credential mismatch!'); 35 | 36 | // generating token 37 | const token = generateToken(findOrgnizer); 38 | 39 | // user data to send with response 40 | const { password, ...pwd } = findOrgnizer; 41 | 42 | sendResponse(res, { 43 | statusCode: httpStatus.OK, 44 | success: true, 45 | message: 'Login Success!', 46 | data: { 47 | accessToken: token as string, 48 | _id: pwd._id, 49 | name: pwd.name, 50 | surname: pwd.surname, 51 | }, 52 | }); 53 | } 54 | ) 55 | 56 | // profile of logged User 57 | const Profile: RequestHandler = catchAsync( 58 | async (req: Request, res: Response) => { 59 | 60 | // finding profile data 61 | const data = await Organizer.findById(req.user?._id).select("-password"); 62 | 63 | sendResponse(res, { 64 | statusCode: httpStatus.OK, 65 | success: true, 66 | message: 'Profile retrieved successfully!', 67 | data, 68 | }); 69 | } 70 | ) 71 | 72 | export default { 73 | Signin, 74 | Profile, 75 | }; -------------------------------------------------------------------------------- /app/controllers/OrganizerController.ts: -------------------------------------------------------------------------------- 1 | import { Request, RequestHandler, Response } from "express"; 2 | import { Organizer } from "../models"; 3 | import ApiError from "../../utils/errors/ApiError"; 4 | import httpStatus from "http-status"; 5 | import { catchAsync, sendResponse } from "../../utils/helpers/global"; 6 | import { mailTeamplates, sendMail } from "../../utils/helpers/email"; 7 | import { pick } from "../../utils/helpers/transforms"; 8 | import { config } from "../../utils/server"; 9 | import { IRole } from "../interfaces/IRole"; 10 | 11 | // filering and searhing constant 12 | export const organizerFilterableFields = ['isEmailVerified']; 13 | 14 | // create new organizer to a business controller 15 | const CreateNewOrganizerToSentInviteToAddUnderBusiness: RequestHandler = catchAsync( 16 | async (req: Request, res: Response) => { 17 | 18 | // parsing data 19 | const organizerData = req.body && req.body.data ? JSON.parse(req.body.data) : {}; 20 | 21 | // check organizer profile exists with any business by email 22 | const findOrgnizer = await Organizer.isOrganizerExistsByEmail(organizerData.email); 23 | if (findOrgnizer) 24 | throw new ApiError(httpStatus.NOT_FOUND, 'Already an employee of a business profile!'); 25 | 26 | // saving role info 27 | const data = await Organizer.create({ ...organizerData }); 28 | 29 | if (data._id) { 30 | // email template with invitation link 31 | const mailTemp = await mailTeamplates.sassInvitationEmailTemp(String(data._id), req); 32 | 33 | // sending invitation 34 | await sendMail({ 35 | email: organizerData.email, 36 | subject: String(config.SENDER_EMAIL_ID), 37 | content: mailTemp, 38 | }) 39 | } 40 | 41 | sendResponse(res, { 42 | statusCode: httpStatus.OK, 43 | success: true, 44 | message: `Organizer invitation sent successfully!`, 45 | data, 46 | }); 47 | } 48 | ) 49 | 50 | // get all organizers under a business 51 | const GetOrganizersUnderBusiness: RequestHandler = catchAsync( 52 | async (req: Request, res: Response) => { 53 | 54 | // filter data pick 55 | const andConditions = []; 56 | const filtersData = pick(req.query, organizerFilterableFields); 57 | 58 | // if any filterable query make it on object 59 | if (Object.keys(filtersData).length) { 60 | andConditions.push({ 61 | $and: Object.entries(filtersData).map(([field, value]) => ({ 62 | [field]: value, 63 | })), 64 | }); 65 | } 66 | 67 | // finalizing condition & find data 68 | const whereConditions = andConditions.length > 0 ? { $and: andConditions } : {}; 69 | const data = await Organizer.find(whereConditions); 70 | const total = await Organizer.find().countDocuments(); 71 | 72 | sendResponse(res, { 73 | statusCode: httpStatus.OK, 74 | success: true, 75 | message: `Organizers retrived successfully!`, 76 | meta: { 77 | total, 78 | showingTotal: data.length, 79 | }, 80 | data, 81 | }); 82 | } 83 | ) 84 | 85 | // get single organizer under business 86 | const GetOrganizerById: RequestHandler = catchAsync( 87 | async (req: Request, res: Response) => { 88 | 89 | const organizerId = req.params.organizerId; 90 | const data = await Organizer.findOne({ _id: organizerId }).select("-password"); 91 | 92 | sendResponse(res, { 93 | statusCode: httpStatus.OK, 94 | success: true, 95 | message: `Organizer retrived successfully!`, 96 | data, 97 | }); 98 | } 99 | ) 100 | 101 | // organizer update under business controller 102 | const UpdateOrganizerUnderBusiness: RequestHandler = catchAsync( 103 | async (req: Request, res: Response) => { 104 | 105 | // parsing data and params 106 | const organizerId = req.params.organizerId; 107 | const parsedData = req.body && req.body.data ? JSON.parse(req.body.data) : {}; 108 | const { isEmailVerified, password, confirmPassword, ...body } = parsedData; 109 | 110 | // Check if a organizer exists or not 111 | const existsOrganizer = await Organizer.isOrganizerExistsById(organizerId, "_id"); 112 | if (!existsOrganizer) 113 | throw new ApiError(httpStatus.BAD_REQUEST, 'Organizer not found.'); 114 | 115 | // updating role info 116 | const data = await Organizer.findOneAndUpdate({ _id: organizerId }, { 117 | $set: body 118 | }, { new: true, runValidators: true }) 119 | 120 | sendResponse(res, { 121 | statusCode: httpStatus.OK, 122 | success: true, 123 | message: `Organizer updated successfully!`, 124 | data, 125 | }); 126 | } 127 | ) 128 | 129 | // delete organizer 130 | const DeleteOrganizer: RequestHandler = catchAsync( 131 | async (req: Request, res: Response) => { 132 | 133 | const organizerId = req.params.organizerId; 134 | 135 | // Check if a organizer exists or not 136 | const existsOrganizer = await Organizer.isOrganizerExistsById(organizerId, "_id"); 137 | if (!existsOrganizer) 138 | throw new ApiError(httpStatus.BAD_REQUEST, 'Organizer not found.'); 139 | 140 | 141 | await Organizer.deleteOne({ _id: organizerId }) 142 | 143 | sendResponse(res, { 144 | statusCode: httpStatus.OK, 145 | success: true, 146 | message: `Organizer deleted successfully!`, 147 | }); 148 | } 149 | ) 150 | 151 | export default { 152 | CreateNewOrganizerToSentInviteToAddUnderBusiness, 153 | GetOrganizersUnderBusiness, 154 | GetOrganizerById, 155 | UpdateOrganizerUnderBusiness, 156 | DeleteOrganizer, 157 | }; -------------------------------------------------------------------------------- /app/interfaces/Common.ts: -------------------------------------------------------------------------------- 1 | import { Types } from "mongoose"; 2 | 3 | // common schema 4 | export interface ICommonSchema { 5 | _id?: string | Types.ObjectId; 6 | createdAt?: number; 7 | updatedAt?: number; 8 | __v?: number; 9 | } -------------------------------------------------------------------------------- /app/interfaces/IOrganizer.ts: -------------------------------------------------------------------------------- 1 | import { Model, Types } from "mongoose"; 2 | import { ICommonSchema } from "./Common"; 3 | import { IRole } from "./IRole"; 4 | 5 | // organizer interface 6 | export interface IOrganizer extends ICommonSchema { 7 | name: string; 8 | surname: string; 9 | email: string; 10 | phone: number; 11 | password: string; 12 | confirmPassword: string | undefined; 13 | isEmailVerified: boolean; 14 | role: string | Types.ObjectId | Partial; 15 | } 16 | 17 | // organizer schema methods 18 | export interface IOrganizerModel extends Model { 19 | isOrganizerExistsById(organizerId: string, select?: string): Promise; 20 | isOrganizerExistsByEmail(email: string, select?: string): Promise; 21 | } 22 | 23 | export interface IOrganizerDocument extends IOrganizer, Document { } -------------------------------------------------------------------------------- /app/interfaces/IRole.ts: -------------------------------------------------------------------------------- 1 | import { Model } from "mongoose"; 2 | import { ICommonSchema } from "./Common"; 3 | 4 | 5 | // role schema interface 6 | export interface IRole extends ICommonSchema { 7 | name: string; 8 | permissions: string[]; 9 | } 10 | 11 | // role schema methods 12 | export interface IRoleModel extends Model { 13 | isRoleExists(roleId: string): Promise; 14 | } 15 | 16 | export interface IRoleDocument extends IRole, Document { } -------------------------------------------------------------------------------- /app/interfaces/index.d.ts: -------------------------------------------------------------------------------- 1 | import { JwtPayload } from "jsonwebtoken"; 2 | import { IMulterFiles } from "../../utils/type/file"; 3 | 4 | declare global { 5 | namespace Express { 6 | interface Request { 7 | user: JwtPayload | null; 8 | file: any; 9 | files: any; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /app/middleware/auth.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from "express"; 2 | import { Secret } from 'jsonwebtoken' 3 | import ApiError from "../../utils/errors/ApiError"; 4 | import httpStatus from "http-status"; 5 | import verifyToken from "../../utils/helpers/jwt/verifyToken"; 6 | import config from "../../utils/server/config"; 7 | 8 | export default (...requiredPermissions: string[]) => async (req: Request, res: Response, next: NextFunction) => { 9 | try { 10 | const authHeader = req.headers.authorization; 11 | if (!authHeader) throw new ApiError(httpStatus.UNAUTHORIZED, 'Unauthorized access'); 12 | 13 | // getting token 14 | const token = authHeader.split(' ')[1]; 15 | 16 | // verify token 17 | let verifiedUser = null; 18 | verifiedUser = verifyToken(token, config.TOKEN_SECRET as Secret); 19 | req.user = verifiedUser; // email, _id, business 20 | 21 | // role diye guard korar jnno 22 | // if (requiredRoles.length && !requiredRoles.includes(verifiedUser.role)) { 23 | // throw new ApiError(httpStatus.FORBIDDEN, 'Forbidden'); 24 | // } 25 | 26 | // If any of the required permissions are missing, throw Forbidden error 27 | if (requiredPermissions.length && !requiredPermissions.every(permission => verifiedUser.permissions.includes(permission))) { 28 | throw new ApiError(httpStatus.FORBIDDEN, 'Forbidden'); 29 | } 30 | 31 | next(); 32 | } catch (error) { 33 | next(error); 34 | } 35 | } -------------------------------------------------------------------------------- /app/middleware/index.ts: -------------------------------------------------------------------------------- 1 | export { default as auth } from './auth'; 2 | export { default as validateRequest } from './validateRequest'; -------------------------------------------------------------------------------- /app/middleware/validateRequest.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { AnyZodObject, ZodEffects } from 'zod'; 3 | 4 | const validateRequest = (schema: AnyZodObject | ZodEffects) => 5 | async (req: Request, res: Response, next: NextFunction): Promise => { 6 | try { 7 | await schema.parseAsync({ 8 | body: req.body, 9 | query: req.query, 10 | params: req.params, 11 | cookies: req.cookies, 12 | }); 13 | return next(); 14 | } catch (error) { 15 | next(error); 16 | } 17 | }; 18 | 19 | export default validateRequest; -------------------------------------------------------------------------------- /app/models/OrganizerSchema.ts: -------------------------------------------------------------------------------- 1 | import { Schema, Types, model } from "mongoose"; 2 | import validator from "validator"; 3 | import { IOrganizer, IOrganizerDocument, IOrganizerModel } from "../interfaces/IOrganizer"; 4 | import moment from "moment"; 5 | 6 | const OrganizerSchema = new Schema({ 7 | name: { 8 | type: String, 9 | required: [true, 'Name is required'], 10 | }, 11 | email: { 12 | type: String, 13 | required: [true, 'Email is required'], 14 | unique: true, 15 | validate: [validator.isEmail, 'Please provide a valid email.'], 16 | }, 17 | phone: { 18 | type: Number, 19 | required: [true, 'Phone number is required'], 20 | }, 21 | password: { 22 | type: String, 23 | // required: [true, 'Password is required'], 24 | }, 25 | confirmPassword: { 26 | type: String, 27 | }, 28 | role: { 29 | type: Types.ObjectId, 30 | ref: "Role", 31 | required: [true, 'role id field is required'] 32 | }, 33 | createdAt: { 34 | type: Number, 35 | default: () => moment().unix(), 36 | }, 37 | updatedAt: { 38 | type: Number, 39 | default: () => moment().unix(), 40 | }, 41 | }); 42 | 43 | 44 | // checking is organizer found with the id 45 | OrganizerSchema.statics.isOrganizerExistsById = async function (organizerId: string, select: string): Promise { 46 | const organizer = await this.findById(organizerId).select(select).populate("role", "name").lean(); 47 | return organizer; 48 | } 49 | 50 | // checking is organizer found with the email 51 | OrganizerSchema.statics.isOrganizerExistsByEmail = async function (email: string, select: string): Promise { 52 | const organizer = await this.findOne({ email }).select(select).lean(); 53 | return organizer; 54 | } 55 | 56 | const Organizer = model("Organizer", OrganizerSchema); 57 | export default Organizer; -------------------------------------------------------------------------------- /app/models/RoleSchema.ts: -------------------------------------------------------------------------------- 1 | import { Schema, model } from "mongoose"; 2 | import { IRole, IRoleDocument, IRoleModel } from "../interfaces/IRole"; 3 | import moment from "moment"; 4 | 5 | const RoleSchema = new Schema({ 6 | name: { 7 | type: String, 8 | lowercase: true, 9 | required: [true, 'Organizer Role name is required'], 10 | // enum: { 11 | // values: RoleEnumValues, 12 | // message: `Role name value can not be {VALUE}, must be ${RoleEnumValues}` 13 | // }, 14 | }, 15 | permissions: { 16 | type: [String], 17 | validate: { 18 | validator: function (permissions: string[]) { 19 | // Check if all permissions are included in the ENUM_PERMISSION_NAMES enum 20 | // return permissions.every((permission: any) => Object.values(ENUM_PERMISSION_NAMES).includes(permission)); 21 | }, 22 | message: ({ value }) => `${value} is not a valid permission.` 23 | } 24 | }, 25 | createdAt: { 26 | type: Number, 27 | default: () => moment().unix(), 28 | }, 29 | updatedAt: { 30 | type: Number, 31 | default: () => moment().unix(), 32 | }, 33 | }); 34 | 35 | // checking is organizer found with the id 36 | RoleSchema.statics.isRoleExists = async function (roleId: string): Promise { 37 | const role = await this.findOne({ _id: roleId }).lean(); 38 | return role; 39 | } 40 | 41 | const Role = model("Role", RoleSchema); 42 | export default Role; -------------------------------------------------------------------------------- /app/models/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Organizer } from './OrganizerSchema' 2 | export { default as OrganizerRole } from './RoleSchema' -------------------------------------------------------------------------------- /app/routers/AuthRouter.ts: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | const router = express.Router(); 3 | 4 | // middlewares 5 | import auth from '../middleware/auth'; 6 | 7 | // controllers 8 | import AuthController from '../controllers/AuthController'; 9 | 10 | //routes 11 | router.post('/signin', AuthController.Signin); 12 | router.get('/profile', auth(), AuthController.Profile); 13 | 14 | export const AuthRouter = router; -------------------------------------------------------------------------------- /app/routers/OrganizerRouter.ts: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | const router = express.Router(); 3 | 4 | // middleware 5 | import auth from '../middleware/auth'; 6 | 7 | // controllers 8 | import OrganizerController from '../controllers/OrganizerController'; 9 | 10 | //routes 11 | router.get( 12 | '/all-under-business', 13 | auth(), 14 | OrganizerController.GetOrganizersUnderBusiness 15 | ); 16 | 17 | router.get( 18 | '/:organizerId', 19 | auth(), 20 | OrganizerController.GetOrganizerById 21 | ); 22 | 23 | router.post( 24 | '/create', 25 | auth(), 26 | OrganizerController.CreateNewOrganizerToSentInviteToAddUnderBusiness 27 | ); 28 | 29 | router.patch( 30 | '/update/:organizerId', 31 | auth(), 32 | OrganizerController.UpdateOrganizerUnderBusiness 33 | ); 34 | 35 | router.delete( 36 | '/delete/:organizerId', 37 | auth(), 38 | OrganizerController.DeleteOrganizer 39 | ); 40 | 41 | export const OrganizerRouter = router; -------------------------------------------------------------------------------- /app/routers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AuthRouter'; 2 | export * from './OrganizerRouter'; -------------------------------------------------------------------------------- /app/routers/routes.ts: -------------------------------------------------------------------------------- 1 | import express, { Router } from 'express'; 2 | import { 3 | AuthRouter, OrganizerRouter 4 | } from '../routers'; 5 | 6 | const router = express.Router(); 7 | 8 | const apiRoutes: { path: string, route: Router }[] = [ 9 | { 10 | path: '/auth', 11 | route: AuthRouter, 12 | }, 13 | { 14 | path: '/organizer', 15 | route: OrganizerRouter, 16 | }, 17 | ]; 18 | 19 | apiRoutes.forEach(route => router.use(route.path, route.route)); 20 | export default router; -------------------------------------------------------------------------------- /app/validations/InvitationValidation.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | const setPasswordByInvitationValidation = z.object({ 4 | body: z.object({ 5 | data: z.string({ 6 | required_error: 'data is required', 7 | }).transform(value => { 8 | const parsedData = JSON.parse(value); // Assuming data is JSON 9 | 10 | if (!(parsedData && typeof parsedData === 'object')) { 11 | throw new Error('Invalid data format'); // chekcing json format 12 | } 13 | return parsedData; 14 | }).refine(parsedData => { 15 | return 'email' in parsedData && 'password' in parsedData && 'confirmPassword' in parsedData; // requires properties 16 | }, { 17 | message: 'data must contain email, password & confirmPassword keys', 18 | path: ['formData', 'data'] 19 | }).refine(parsedData => { 20 | return parsedData.password.length >= 6; // check password minimum length 21 | }, { 22 | message: 'password must be at least 6 characters long', 23 | path: ['formData', 'data', 'password'] 24 | }).refine(parsedData => { 25 | const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // valid email check 26 | return emailRegex.test(parsedData.email); 27 | }, { 28 | message: 'email must be a valid email address', 29 | path: ['formData', 'data', 'email'] 30 | }), 31 | }), 32 | }); 33 | 34 | export default { 35 | setPasswordByInvitationValidation, 36 | }; -------------------------------------------------------------------------------- /app/views/InvitationEmail.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Invitation Email to Kids App SASS 7 | 8 | 9 |

Invitation to Our Website

10 |

Hello!

11 |

You are invited to our website.

12 |

Click `>here to accept the invitation!

13 |

We look forward to seeing you there!

14 | 15 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import express, { Application } from 'express' 2 | import routes from './app/routers/routes'; 3 | import globalErrorHandler from './utils/errors/globalErrorHandler'; 4 | import { bootstrap, globalMiddlewares, handleRouteNotFound } from './utils/server'; 5 | 6 | const app: Application = express(); 7 | 8 | // middleware 9 | globalMiddlewares(app); 10 | 11 | // all routes 12 | app.use('/api/v1', routes); 13 | 14 | // files route 15 | app.use('/public', express.static('public')) 16 | 17 | // global error handler 18 | app.use(globalErrorHandler); 19 | 20 | // handle route not found 21 | app.use(handleRouteNotFound) 22 | 23 | // server & database 24 | bootstrap(app); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-js-typescript", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "author": "Soumik Ahammed", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "node dist/index.js", 9 | "build": "tsc", 10 | "dev": "ts-node-dev --respawn --transpile-only index.ts", 11 | "start-dev": "nodemon index.js", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "dependencies": { 15 | "bcrypt": "^5.1.0", 16 | "cors": "^2.8.5", 17 | "dotenv": "^16.3.1", 18 | "ejs": "^3.1.10", 19 | "express": "^4.18.2", 20 | "express-mongo-sanitize": "^2.2.0", 21 | "helmet": "^7.1.0", 22 | "http-status": "^1.6.2", 23 | "jsonwebtoken": "^9.0.0", 24 | "moment": "^2.30.1", 25 | "mongoose": "^7.3.0", 26 | "multer": "^1.4.5-lts.1", 27 | "nodemailer": "^6.9.13", 28 | "validator": "^13.9.0", 29 | "winston": "^3.13.0", 30 | "xss-clean": "^0.1.4", 31 | "zod": "^3.23.8" 32 | }, 33 | "devDependencies": { 34 | "@types/bcrypt": "^5.0.0", 35 | "@types/cors": "^2.8.13", 36 | "@types/ejs": "^3.1.5", 37 | "@types/express": "^4.17.17", 38 | "@types/jsonwebtoken": "^9.0.2", 39 | "@types/multer": "^1.4.11", 40 | "@types/nodemailer": "^6.4.15", 41 | "@types/validator": "^13.7.17", 42 | "ts-node-dev": "^2.0.0", 43 | "typescript": "^5.4.5" 44 | } 45 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "typeRoots": [ 4 | "./node_modules/@types" 5 | ], 6 | /* Visit https://aka.ms/tsconfig to read more about this file */ 7 | /* Projects */ 8 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 9 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 10 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 11 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 12 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 13 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 14 | /* Language and Environment */ 15 | "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 16 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 17 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 18 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 19 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 20 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 21 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 22 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 23 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 24 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 25 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 26 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | /* JavaScript Support */ 46 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 47 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 48 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 49 | /* Emit */ 50 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 51 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 52 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 53 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 54 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 55 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 56 | "outDir": "./dist", /* Specify an output folder for all emitted files. */ 57 | // "removeComments": true, /* Disable emitting comments. */ 58 | // "noEmit": true, /* Disable emitting files from a compilation. */ 59 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 60 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 61 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 62 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 63 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 64 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 65 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 66 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 67 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 68 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 69 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 70 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 71 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 72 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 73 | /* Interop Constraints */ 74 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 75 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 76 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 77 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 78 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 79 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 80 | /* Type Checking */ 81 | "strict": true, /* Enable all strict type-checking options. */ 82 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 83 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 84 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 85 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 86 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 87 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 88 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 89 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 90 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 91 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 92 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 93 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 94 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 95 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 96 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 97 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 98 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 99 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 100 | /* Completeness */ 101 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 102 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 103 | } 104 | } -------------------------------------------------------------------------------- /utils/constants/constants.ts: -------------------------------------------------------------------------------- 1 | // pagination props 2 | export const paginationProps: string[] = ['page', 'limit', 'sortBy', 'sortOrder']; -------------------------------------------------------------------------------- /utils/enums/enums.ts: -------------------------------------------------------------------------------- 1 | export enum ENUM_ACTIVITY_TYPE { 2 | SEMESTER = 'semester', 3 | INDIVIDUAL = 'individual', 4 | } 5 | 6 | export enum ENUM_ACTIVITY_RANGE_TYPE { 7 | AGE = 'age', 8 | GRADE = 'grade', 9 | } 10 | 11 | export enum ENUM_DISCOUNT_TYPE { 12 | EURO = 'euro', 13 | PERCENTAGE = 'percentage', 14 | } 15 | 16 | export enum ENUM_STATUS_NAME { 17 | PENDING = 'pending', 18 | RUNNING = 'running', 19 | COMPLETED = 'completed', 20 | } 21 | 22 | export enum ENUM_PAYMENT_STATUS_NAME { 23 | PENDING = 'pending', 24 | PROCESSING = 'processing', 25 | COMPLETED = 'completed', 26 | } 27 | 28 | // converting all enum to arrays 29 | export const ActivityTypeEnumValues = Object.values(ENUM_ACTIVITY_TYPE); 30 | 31 | export const ActivityRangeTypeEnumValues = Object.values(ENUM_ACTIVITY_RANGE_TYPE); 32 | 33 | export const DiscountTypeEnumValues = Object.values(ENUM_DISCOUNT_TYPE); 34 | 35 | export const StatusEnumValues = Object.values(ENUM_STATUS_NAME); 36 | export const PayemntStatusEnumValues = Object.values(ENUM_PAYMENT_STATUS_NAME); -------------------------------------------------------------------------------- /utils/errors/ApiError.ts: -------------------------------------------------------------------------------- 1 | class ApiError extends Error { 2 | statusCode: number; 3 | 4 | constructor(statusCode: number, message: string | undefined, stack = '') { 5 | super(message); 6 | this.statusCode = statusCode; 7 | if (stack) { 8 | this.stack = stack; 9 | } else { 10 | Error.captureStackTrace(this, this.constructor); 11 | } 12 | } 13 | } 14 | 15 | export default ApiError; -------------------------------------------------------------------------------- /utils/errors/globalErrorHandler.ts: -------------------------------------------------------------------------------- 1 | import { ErrorRequestHandler, NextFunction, Request, Response } from 'express'; 2 | import config from '../server/config'; 3 | import ApiError from './ApiError'; 4 | import handleValidationError from './handleValidationError'; 5 | import handleCastError from './handleCastError'; 6 | import { IErrorMessage } from '../type/types'; 7 | import { ZodError } from 'zod'; 8 | import handleZodError from './handleZodError'; 9 | import { MulterError } from 'multer'; 10 | import httpStatus from 'http-status'; 11 | 12 | const globalErrorHandler: ErrorRequestHandler = ( 13 | error, 14 | req: Request, 15 | res: Response, 16 | next: NextFunction 17 | ) => { 18 | 19 | let statusCode = 500; 20 | let message = 'Something went wrong !'; 21 | let errorMessages: IErrorMessage[] = []; 22 | 23 | if (error?.name === 'ValidationError') { 24 | const simplifiedError = handleValidationError(error); 25 | statusCode = simplifiedError.statusCode; 26 | message = simplifiedError.message; 27 | errorMessages = simplifiedError.errorMessages; 28 | } else if (error instanceof ZodError) { 29 | const simplifiedError = handleZodError(error); 30 | statusCode = simplifiedError.statusCode; 31 | message = simplifiedError.message; 32 | errorMessages = simplifiedError.errorMessages; 33 | } else if (error?.name === 'CastError') { 34 | const simplifiedError = handleCastError(error); 35 | statusCode = simplifiedError.statusCode; 36 | message = simplifiedError.message; 37 | errorMessages = simplifiedError.errorMessages; 38 | } else if (error instanceof MulterError) { 39 | statusCode = httpStatus.INTERNAL_SERVER_ERROR; 40 | message = error?.message; 41 | errorMessages = error?.message 42 | ? [ 43 | { 44 | path: '', 45 | message: error?.message, 46 | }, 47 | ] 48 | : []; 49 | } else if (error instanceof ApiError) { 50 | statusCode = error?.statusCode; 51 | message = error.message; 52 | errorMessages = error?.message 53 | ? [ 54 | { 55 | path: '', 56 | message: error?.message, 57 | }, 58 | ] 59 | : []; 60 | } else if (error instanceof Error) { 61 | message = error?.message; 62 | errorMessages = error?.message 63 | ? [ 64 | { 65 | path: '', 66 | message: error?.message, 67 | }, 68 | ] 69 | : []; 70 | } 71 | 72 | res.status(statusCode).json({ 73 | success: false, 74 | message, 75 | errorMessages, 76 | stack: config.ENV !== 'production' ? error?.stack : undefined, 77 | }); 78 | }; 79 | 80 | export default globalErrorHandler; -------------------------------------------------------------------------------- /utils/errors/handleCastError.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | import { IErrorMessage } from '../type/types'; 3 | 4 | const handleCastError = (error: mongoose.Error.CastError) => { 5 | const errors: IErrorMessage[] = [ 6 | { 7 | path: error.path, 8 | message: 'Passed id is invalid!', 9 | }, 10 | ]; 11 | 12 | const statusCode = 400; 13 | return { 14 | statusCode, 15 | message: 'Cast Error occurs!', 16 | errorMessages: errors, 17 | }; 18 | }; 19 | 20 | export default handleCastError; -------------------------------------------------------------------------------- /utils/errors/handleValidationError.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | import { IErrorMessage, IErrorResponse } from '../type/types'; 3 | 4 | const handleValidationError = ( 5 | error: mongoose.Error.ValidationError 6 | ): IErrorResponse => { 7 | const errors: IErrorMessage[] = Object.values(error.errors).map( 8 | (el: mongoose.Error.ValidatorError | mongoose.Error.CastError) => { 9 | return { 10 | path: el?.path, 11 | message: el?.message, 12 | }; 13 | } 14 | ); 15 | const statusCode = 400; 16 | return { 17 | statusCode, 18 | message: 'Validation Error', 19 | errorMessages: errors, 20 | }; 21 | }; 22 | 23 | export default handleValidationError; -------------------------------------------------------------------------------- /utils/errors/handleZodError.ts: -------------------------------------------------------------------------------- 1 | import { ZodError, ZodIssue } from 'zod'; 2 | import { IGenericErrorMessage, IGenericErrorResponse } from '../type/types'; 3 | 4 | const handleZodError = (error: ZodError): IGenericErrorResponse => { 5 | const errors: IGenericErrorMessage[] = error.issues.map((issue: ZodIssue) => { 6 | return { 7 | path: issue?.path[issue.path.length - 1], 8 | message: issue?.message, 9 | }; 10 | }); 11 | 12 | const statusCode = 400; 13 | 14 | return { 15 | statusCode, 16 | message: 'Validation Error', 17 | errorMessages: errors, 18 | }; 19 | }; 20 | 21 | export default handleZodError; -------------------------------------------------------------------------------- /utils/helpers/bcrypt/compareString.ts: -------------------------------------------------------------------------------- 1 | import bcrypt from 'bcrypt'; 2 | 3 | export default async (comparableString: string, hashValue: string): Promise => { 4 | const isMatched = await bcrypt.compare(comparableString, hashValue); 5 | return isMatched; 6 | }; -------------------------------------------------------------------------------- /utils/helpers/bcrypt/hashString.ts: -------------------------------------------------------------------------------- 1 | import bcrypt from 'bcrypt'; 2 | import { config } from '../../server'; 3 | 4 | export default async (string: string): Promise => { 5 | const hashedString = await bcrypt.hashSync(string, Number(config.BYCRYPT_SALT_ROUND)); 6 | return hashedString; 7 | }; -------------------------------------------------------------------------------- /utils/helpers/bcrypt/index.ts: -------------------------------------------------------------------------------- 1 | export { default as compareString } from './compareString'; 2 | export { default as hashString } from './hashString'; -------------------------------------------------------------------------------- /utils/helpers/email/index.ts: -------------------------------------------------------------------------------- 1 | export { default as mailTeamplates } from './mailTeamplates'; 2 | export { default as sendMail } from './sendMail'; -------------------------------------------------------------------------------- /utils/helpers/email/mailTeamplates.ts: -------------------------------------------------------------------------------- 1 | import { Request } from "express"; 2 | import getRequestUrl from "../global/getRequestUrl"; 3 | import fs from 'fs' 4 | import ejs from 'ejs' 5 | 6 | const sassInvitationEmailTemp = async (organizerId: string, req: Request) => { 7 | 8 | // making url for invitation 9 | const base64Hash = Buffer.from(organizerId).toString('base64'); 10 | 11 | const invitationUrl = `${getRequestUrl.getRequestBaseUrl(req)}/api/v1/invitation/set-password/${base64Hash}`; 12 | 13 | // Render the EJS template with data 14 | const templateContent = fs.readFileSync('app/views/InvitationEmail.ejs', 'utf8'); 15 | const mailTemp = ejs.render(templateContent, { invitationUrl }); 16 | 17 | return mailTemp; 18 | } 19 | 20 | export default { 21 | sassInvitationEmailTemp 22 | } -------------------------------------------------------------------------------- /utils/helpers/email/sendMail.ts: -------------------------------------------------------------------------------- 1 | import httpStatus from "http-status"; 2 | import ApiError from "../../errors/ApiError"; 3 | import transporter from "../../server/transporter"; 4 | import { config } from "../../server"; 5 | import { errorLogger, infoLogger } from "../logger/logger"; 6 | 7 | interface ISendMail { 8 | email: string; 9 | subject: string; 10 | content: string; 11 | } 12 | 13 | const sendMail = async ({ email, subject, content }: ISendMail) => { 14 | try { 15 | await transporter.verify(); 16 | infoLogger.info(`Server is ready to take our messages`); 17 | 18 | const response = await transporter.sendMail({ 19 | from: config.SENDER_EMAIL_ID, 20 | to: email, 21 | subject: subject, 22 | html: content 23 | }); 24 | 25 | return response; 26 | } catch (error) { 27 | errorLogger.error(`Error on mail server: ${error instanceof Error ? error.message : 'unknown'}`); 28 | throw new ApiError(httpStatus.BAD_REQUEST, 'Failed to send email to user.'); 29 | } 30 | }; 31 | 32 | export default sendMail; -------------------------------------------------------------------------------- /utils/helpers/global/catchAsync.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, RequestHandler, Response } from 'express'; 2 | import { errorLogger } from '../logger/logger'; 3 | 4 | const catchAsync = 5 | (fn: RequestHandler) => 6 | async (req: Request, res: Response, next: NextFunction): Promise => { 7 | try { 8 | await fn(req, res, next); 9 | } catch (error) { 10 | next(error); 11 | errorLogger.error(error); 12 | } 13 | }; 14 | 15 | export default catchAsync; -------------------------------------------------------------------------------- /utils/helpers/global/getRequestUrl.ts: -------------------------------------------------------------------------------- 1 | import { Request } from "express"; 2 | 3 | const getRequestFulllUrl = (req: Request) => { 4 | return req.protocol + '://' + req.get('host') + req.originalUrl; 5 | } 6 | 7 | const getRequestBaseUrl = (req: Request) => { 8 | return req.protocol + '://' + req.get('host'); 9 | } 10 | 11 | export default { 12 | getRequestFulllUrl, 13 | getRequestBaseUrl, 14 | }; -------------------------------------------------------------------------------- /utils/helpers/global/index.ts: -------------------------------------------------------------------------------- 1 | export { default as catchAsync } from './catchAsync'; 2 | export { default as getRequestUrl } from './sendResponse'; 3 | export { default as sendResponse } from './sendResponse'; -------------------------------------------------------------------------------- /utils/helpers/global/sendResponse.ts: -------------------------------------------------------------------------------- 1 | import { Response } from 'express'; 2 | import { IApiReponse } from '../../type/types'; 3 | 4 | const sendResponse = (res: Response, data: IApiReponse): void => { 5 | const responseData: IApiReponse = { 6 | statusCode: data.statusCode, 7 | success: data.success, 8 | message: data.message || null, 9 | meta: data.meta || null || undefined, 10 | data: data.data || null || undefined, 11 | }; 12 | 13 | res.status(data.statusCode).json(responseData); 14 | }; 15 | 16 | export default sendResponse; -------------------------------------------------------------------------------- /utils/helpers/jwt/generateToken.ts: -------------------------------------------------------------------------------- 1 | import jwt, { Secret } from 'jsonwebtoken' 2 | import { config } from '../../server'; 3 | import { IOrganizer } from '../../../app/interfaces/IOrganizer'; 4 | 5 | export default (data: Partial): String => { 6 | 7 | const payload = { 8 | _id: data._id, 9 | }; 10 | 11 | // token generating 12 | const token = jwt.sign( 13 | payload, 14 | config.TOKEN_SECRET as Secret, 15 | { expiresIn: config.TOKEN_SECRET_EXP } 16 | ); 17 | 18 | return token; 19 | }; -------------------------------------------------------------------------------- /utils/helpers/jwt/index.ts: -------------------------------------------------------------------------------- 1 | export { default as generateToken } from './generateToken'; 2 | export { default as verifyToken } from './verifyToken'; -------------------------------------------------------------------------------- /utils/helpers/jwt/verifyToken.ts: -------------------------------------------------------------------------------- 1 | import jwt, { JwtPayload, Secret } from 'jsonwebtoken'; 2 | 3 | const verifyToken = (token: string, secret: Secret): JwtPayload => { 4 | return jwt.verify(token, secret) as JwtPayload; 5 | }; 6 | 7 | export default verifyToken; -------------------------------------------------------------------------------- /utils/helpers/logger/index.ts: -------------------------------------------------------------------------------- 1 | export { default as requestLogger } from './requestLogger'; -------------------------------------------------------------------------------- /utils/helpers/logger/logger.ts: -------------------------------------------------------------------------------- 1 | import winston from "winston"; 2 | import fs from "fs"; 3 | import path from "path"; 4 | 5 | // Set the log directory 6 | const logDirectory = path.join(process.cwd(), 'logs'); 7 | if (!fs.existsSync(logDirectory)) { 8 | fs.mkdirSync(logDirectory); 9 | } 10 | 11 | // Custom log colors 12 | const customColors = { 13 | error: "red", 14 | warn: "yellow", 15 | info: "green", 16 | http: "cyan", 17 | verbose: "blue", 18 | debug: "magenta", 19 | silly: "gray", 20 | }; 21 | 22 | winston.addColors(customColors); 23 | 24 | const createLogger = (level: string, filename: string) => { 25 | const logger = winston.createLogger({ 26 | level: level, 27 | format: winston.format.combine( 28 | winston.format.timestamp(), 29 | winston.format.printf(({ level, message, timestamp }) => { 30 | let formattedMessage = `${timestamp} - `; 31 | if (level) { 32 | formattedMessage += `[${level.toUpperCase()}] `; 33 | } 34 | formattedMessage += 35 | typeof message === "object" 36 | ? JSON.stringify(message, null, 2) 37 | : message; 38 | return formattedMessage; 39 | }) 40 | ), 41 | transports: [ 42 | new winston.transports.Console({ 43 | format: winston.format.combine( 44 | winston.format.colorize({ all: true }), 45 | winston.format.simple() 46 | ), 47 | }), 48 | new winston.transports.File({ 49 | filename: path.join(logDirectory, filename), 50 | level: level, 51 | }), 52 | ], 53 | }); 54 | 55 | return logger; 56 | }; 57 | 58 | // Create specific loggers 59 | const infoLogger = createLogger("info", "combined.log"); 60 | const httpLogger = createLogger("http", "http.log"); 61 | const errorLogger = createLogger("error", "error.log"); 62 | 63 | export { 64 | infoLogger, 65 | httpLogger, 66 | errorLogger 67 | }; -------------------------------------------------------------------------------- /utils/helpers/logger/requestLogger.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from "express"; 2 | import { httpLogger } from "./logger"; 3 | import getRequestUrl from "../global/getRequestUrl"; 4 | import moment from "moment"; 5 | 6 | const requestLogger = (req: Request, res: Response, next: NextFunction) => { 7 | const { method, url } = req; 8 | const startTime = moment(); 9 | 10 | res.on('finish', () => { 11 | const endTime = moment(); 12 | const duration = endTime.diff(startTime); 13 | const formattedDuration = moment.duration(duration).asMilliseconds(); 14 | const message = `${method} ${getRequestUrl.getRequestFulllUrl(req) + url} ${res.statusCode} - ${formattedDuration}ms`; 15 | httpLogger.http(message); 16 | }); 17 | 18 | next(); 19 | }; 20 | 21 | export default requestLogger; -------------------------------------------------------------------------------- /utils/helpers/transforms/calculatePagination.ts: -------------------------------------------------------------------------------- 1 | import { IPaginationOptions, IPaginationOptionsResult } from "../../type/pagination"; 2 | 3 | const calculatePagination = (options: IPaginationOptions): IPaginationOptionsResult => { 4 | const page = Number(options.page || 1); 5 | const limit = Number(options.limit); 6 | const skip = (page - 1) * limit; 7 | 8 | const sortBy = options.sortBy || 'createdAt'; 9 | const sortOrder = options.sortOrder || 'desc'; 10 | 11 | return { 12 | page, 13 | limit, 14 | skip, 15 | sortBy, 16 | sortOrder, 17 | }; 18 | }; 19 | 20 | export default calculatePagination; -------------------------------------------------------------------------------- /utils/helpers/transforms/generateKeyString.ts: -------------------------------------------------------------------------------- 1 | import { IKeyValueObject } from "../../type/types"; 2 | 3 | const generateKeyString = (selectableFields: IKeyValueObject) => { 4 | 5 | const keys = Object.keys(selectableFields); // Extract keys from the queries object 6 | const keysString = keys.join(' '); // Generate string with keys separated by spaces 7 | 8 | return keysString; 9 | } 10 | 11 | export default generateKeyString; -------------------------------------------------------------------------------- /utils/helpers/transforms/index.ts: -------------------------------------------------------------------------------- 1 | export { default as calculatePagination } from './calculatePagination'; 2 | export { default as generateKeyString } from './generateKeyString'; 3 | export { default as pick } from './pick'; 4 | export { default as removeFile } from './removeFile'; 5 | export { default as returnFilePath } from './returnFilePath'; -------------------------------------------------------------------------------- /utils/helpers/transforms/pick.ts: -------------------------------------------------------------------------------- 1 | //['page','limit','sortBy','sortOrder'] 2 | 3 | const pick = , k extends keyof T>( 4 | obj: T, 5 | keys: k[] 6 | ): Partial => { 7 | const resultAsObj: Partial = {}; 8 | 9 | for (const key of keys) { 10 | if (obj && Object.hasOwnProperty.call(obj, key)) { 11 | resultAsObj[key] = obj[key]; 12 | } 13 | } 14 | return resultAsObj; 15 | }; 16 | 17 | export default pick; -------------------------------------------------------------------------------- /utils/helpers/transforms/removeFile.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import { errorLogger, infoLogger } from '../logger/logger'; 3 | 4 | const removeFile = async (imgPath: string) => { 5 | if (fs.existsSync(imgPath)) { 6 | fs.unlinkSync(imgPath); 7 | infoLogger.info(`File ${imgPath} deleted successfully`); 8 | } else { 9 | errorLogger.error(`File ${imgPath} does not exist`); 10 | } 11 | } 12 | 13 | export default removeFile; -------------------------------------------------------------------------------- /utils/helpers/transforms/returnFilePath.ts: -------------------------------------------------------------------------------- 1 | import { IMulterFiles, IUploadFile } from "../../type/file"; 2 | 3 | // single image file upload -> image path 4 | const returnSingleFilePath = async (files: any) => { 5 | 6 | let filePath; 7 | 8 | if (files && Object.keys(files).length > 0) { 9 | if (Array.isArray(files)) { 10 | filePath = files[0].path; 11 | } else { 12 | filePath = files.single?.[0]?.path; 13 | } 14 | } 15 | 16 | return filePath; 17 | } 18 | 19 | // mutiple image file upload -> image paths 20 | const returnMultipleFilePath = async (files: any) => { 21 | 22 | let imagesPaths: string[] = []; 23 | 24 | if (files && Object.keys(files).length > 0) { 25 | files.multiple.map((item: IUploadFile) => { 26 | imagesPaths.push(item.path); 27 | }) 28 | } 29 | 30 | return imagesPaths; 31 | } 32 | 33 | export default { 34 | returnSingleFilePath, 35 | returnMultipleFilePath, 36 | } -------------------------------------------------------------------------------- /utils/json/activityJson.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soumik9/express-typescript-starter/757b6c558db08ebe2c9c5630c956a9995d930e49/utils/json/activityJson.ts -------------------------------------------------------------------------------- /utils/multer/configMulter.ts: -------------------------------------------------------------------------------- 1 | import { Request } from "express"; 2 | import multer from 'multer' 3 | import path from 'path' 4 | import fs from 'fs' 5 | 6 | const storage = multer.diskStorage({ 7 | destination: (req, file, cb) => { 8 | const uploadDir = path.join(__dirname, "../../public/files/"); 9 | if (!fs.existsSync(uploadDir)) { 10 | fs.mkdirSync(uploadDir, { recursive: true }); 11 | } 12 | cb(null, "public/files"); 13 | }, 14 | filename: (req: Request, file: Express.Multer.File, cb: (error: Error | null, filename: string) => void) => { 15 | const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); 16 | cb(null, uniqueSuffix + '-' + file.originalname); 17 | }, 18 | }); 19 | 20 | const upload = multer({ 21 | storage: storage, 22 | fileFilter: (req: Request, file: Express.Multer.File, cb: (error: any, acceptFile: boolean) => void) => { 23 | const supportedFile = /jpg|jpeg|png|webp|svg|pdf/; 24 | const extension = path.extname(file.originalname); 25 | 26 | if (supportedFile.test(extension)) { 27 | cb(null, true); 28 | } else { 29 | cb(new Error('Must be a jpg/png/jpeg/webp/svg file'), false); 30 | } 31 | }, 32 | }); 33 | 34 | 35 | export default upload; -------------------------------------------------------------------------------- /utils/multer/fileTransfer.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | import { errorLogger, infoLogger } from "../helpers/logger/logger"; 4 | 5 | // Function to move file to specific folder 6 | const singleFileTransfer = (filePath: string, destinationFolder: string) => { 7 | 8 | const fileName = path.basename(filePath); 9 | const newFilePath = path.join(__dirname, "../../public", destinationFolder, fileName); 10 | const fileUrl = `public/${destinationFolder}/${fileName}`; // the new url of the file 11 | 12 | // Check if the destination folder exists, if not, create it 13 | if (!fs.existsSync(path.dirname(newFilePath))) { 14 | fs.mkdirSync(path.dirname(newFilePath), { recursive: true }); 15 | } 16 | 17 | // Move the file to the destination folder 18 | fs.rename(filePath, newFilePath, (err) => { 19 | if (err) { 20 | errorLogger.error(`Error moving file: ${err}`); 21 | } else { 22 | infoLogger.info(`File moved successfully to ${newFilePath}`); 23 | } 24 | }); 25 | 26 | return fileUrl; 27 | } 28 | 29 | // Function to move files to specific folder 30 | const multipleFilesTransfer = async (imagePaths: string[], destinationFolder: string) => { 31 | 32 | const paths: string[] = []; 33 | 34 | imagePaths.map((item) => { 35 | const newPath = singleFileTransfer(item, destinationFolder); 36 | paths.push(newPath); 37 | }) 38 | 39 | return paths; 40 | } 41 | 42 | export { 43 | singleFileTransfer, 44 | multipleFilesTransfer 45 | }; -------------------------------------------------------------------------------- /utils/server/bootstrap.ts: -------------------------------------------------------------------------------- 1 | import { Application } from "express"; 2 | import { Server } from 'http'; 3 | import connectToDatabase from "./connectToDatabase"; 4 | import config from "./config"; 5 | import { errorLogger, infoLogger } from "../helpers/logger/logger"; 6 | 7 | 8 | // server related works 9 | process.on('uncaughtException', (error) => { 10 | errorLogger.error(`Error uncaught exception server: ${error.message}`); 11 | process.exit(1); 12 | }); 13 | 14 | // server listener 15 | const bootstrap = async (app: Application) => { 16 | let server: Server; 17 | 18 | try { 19 | // server listen 20 | server = app.listen(process.env.PORT, () => { 21 | infoLogger.info(`Listening on port http://localhost:${config.PORT}/api/v1`); 22 | 23 | // connect database after server started 24 | connectToDatabase() 25 | }); 26 | } catch (error) { 27 | errorLogger.error(`Error creating server: ${error instanceof Error ? error.message : 'unknown'}`); 28 | process.exit(1); 29 | } 30 | } 31 | 32 | export default bootstrap; -------------------------------------------------------------------------------- /utils/server/config.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import path from 'path'; 3 | 4 | dotenv.config({ path: path.join(process.cwd(), '.env') }); 5 | 6 | export default { 7 | ENV: process.env.NODE_ENV, 8 | PORT: process.env.PORT, 9 | 10 | MONGOOSE_URI: process.env.MONGOOSE_URI, 11 | DATABASE_NAME: process.env.DATABASE_NAME, 12 | 13 | TOKEN_SECRET: process.env.TOKEN_SECRET, 14 | TOKEN_SECRET_EXP: process.env.TOKEN_SECRET_EXP, 15 | 16 | BYCRYPT_SALT_ROUND: process.env.BYCRYPT_SALT_ROUND, 17 | 18 | SENDER_EMAIL_NAME: process.env.SENDER_EMAIL_NAME, 19 | SENDER_EMAIL_HOSTNAME: process.env.SENDER_EMAIL_HOSTNAME, 20 | SENDER_EMAIL_PORT: process.env.SENDER_EMAIL_PORT, 21 | SENDER_EMAIL_ID: process.env.SENDER_EMAIL_ID, 22 | SENDER_EMAIL_PASSWORD: process.env.SENDER_EMAIL_PASSWORD, 23 | }; -------------------------------------------------------------------------------- /utils/server/connectToDatabase.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import config from "./config"; 3 | import { errorLogger, infoLogger } from "../helpers/logger/logger"; 4 | 5 | const connectToDatabase = async () => { 6 | const uri = `${config.MONGOOSE_URI}/${config.DATABASE_NAME}`; 7 | try { 8 | await mongoose.connect(uri, { 9 | // Specify the write concern mode 10 | writeConcern: { w: "majority" }, 11 | }); 12 | infoLogger.info("Connected to MongoDB using Mongoose!"); 13 | } catch (error) { 14 | errorLogger.error(`Error connecting database: ${error instanceof Error ? error.message : 'unknown'}`); 15 | process.exit(1); // @TODO: need to fix logger issue 16 | } 17 | }; 18 | 19 | export default connectToDatabase; -------------------------------------------------------------------------------- /utils/server/globalMiddlewares.ts: -------------------------------------------------------------------------------- 1 | import express, { Application } from "express"; 2 | import cors from 'cors' 3 | import helmet from "helmet"; 4 | // import xss from 'xss-clean' // types missing 5 | import sanitize from 'express-mongo-sanitize' 6 | import upload from "../multer/configMulter"; 7 | import { requestLogger } from "../helpers/logger"; 8 | 9 | const globalMiddleware = (app: Application) => { 10 | 11 | app.use(cors()); 12 | app.use(express.json()); 13 | app.use(express.urlencoded({ extended: true })); 14 | app.use(sanitize()); 15 | // app.use(xss()); 16 | app.use(helmet()); 17 | app.use(requestLogger); 18 | 19 | // multer configure 20 | app.use( 21 | upload.fields([ 22 | { name: "single", maxCount: 1 }, 23 | { name: "multiple", maxCount: 10 }, 24 | ]) 25 | ); 26 | } 27 | 28 | export default globalMiddleware; -------------------------------------------------------------------------------- /utils/server/handleRouteNotFound.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import httpStatus from "http-status"; 3 | 4 | const handleRouteNotFound = (req: Request, res: Response) => { 5 | res.status(httpStatus.NOT_FOUND).json({ 6 | success: false, 7 | message: 'Not Found', 8 | errorMessages: [ 9 | { 10 | path: req.originalUrl, 11 | message: 'API Not Found', 12 | }, 13 | ], 14 | }); 15 | } 16 | 17 | export default handleRouteNotFound; -------------------------------------------------------------------------------- /utils/server/index.ts: -------------------------------------------------------------------------------- 1 | export { default as bootstrap } from './bootstrap'; 2 | export { default as config } from './config'; 3 | export { default as connectToDatabase } from './connectToDatabase'; 4 | export { default as globalMiddlewares } from './globalMiddlewares'; 5 | export { default as handleRouteNotFound } from './handleRouteNotFound'; 6 | export { default as transporter } from './transporter'; -------------------------------------------------------------------------------- /utils/server/transporter.ts: -------------------------------------------------------------------------------- 1 | import nodemailer from 'nodemailer' 2 | import config from './config' 3 | 4 | const transporter = nodemailer.createTransport({ 5 | host: config.SENDER_EMAIL_HOSTNAME, 6 | port: Number(config.SENDER_EMAIL_PORT), 7 | auth: { 8 | user: config.SENDER_EMAIL_ID, 9 | pass: config.SENDER_EMAIL_PASSWORD, 10 | }, 11 | }) 12 | 13 | export default transporter -------------------------------------------------------------------------------- /utils/type/file.ts: -------------------------------------------------------------------------------- 1 | export type IUploadFile = { 2 | fieldname: string, 3 | originalname: string, 4 | encoding: string, 5 | mimetype: string, 6 | destination: string, 7 | filename: string, 8 | path: string, 9 | size: number 10 | } 11 | 12 | export interface IMulterFiles { 13 | single?: IUploadFile[] | undefined; 14 | multiple?: IUploadFile[] | undefined; 15 | // You can define other fields here as needed 16 | } 17 | 18 | export type ICloudinaryResponse = { 19 | asset_id: string, 20 | public_id: string, 21 | version: number, 22 | version_id: string, 23 | signature: string, 24 | width: number, 25 | height: number, 26 | format: string, 27 | resource_type: string, 28 | created_at: string, 29 | tags: string[], 30 | pages: number, 31 | bytes: number, 32 | type: string, 33 | etag: string, 34 | placeholder: boolean, 35 | url: string, 36 | secure_url: string, 37 | folder: string, 38 | original_filename: string, 39 | original_extension: string, 40 | api_key: string, 41 | UploadApiResponse: string | undefined 42 | } -------------------------------------------------------------------------------- /utils/type/pagination.ts: -------------------------------------------------------------------------------- 1 | import { SortOrder } from "mongoose"; 2 | 3 | export interface IPaginationOptions { 4 | page?: number; 5 | limit?: number; 6 | sortBy?: string; 7 | sortOrder?: SortOrder; 8 | }; 9 | 10 | export interface IPaginationOptionsResult { 11 | page: number; 12 | limit: number; 13 | skip: number; 14 | sortBy: string; 15 | sortOrder: SortOrder; 16 | }; -------------------------------------------------------------------------------- /utils/type/types.ts: -------------------------------------------------------------------------------- 1 | export type IGenericErrorMessage = { 2 | path: string | number; 3 | message: string; 4 | }; 5 | 6 | export type IGenericErrorResponse = { 7 | statusCode: number; 8 | message: string; 9 | errorMessages: IGenericErrorMessage[]; 10 | }; 11 | 12 | export type IErrorMessage = { 13 | path: string | number; 14 | message: string; 15 | }; 16 | 17 | export type IErrorResponse = { 18 | statusCode: number; 19 | message: string; 20 | errorMessages: IErrorMessage[]; 21 | }; 22 | 23 | export interface IApiReponse { 24 | statusCode: number; 25 | success: boolean; 26 | message?: string | null; 27 | meta?: { 28 | page?: number; 29 | limit?: number; 30 | showingTotal?: number; 31 | total: number; 32 | }; 33 | data?: T | null; 34 | }; 35 | 36 | export interface IKeyValueObject { 37 | [key: string]: string | undefined; 38 | }; -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@colors/colors@1.6.0", "@colors/colors@^1.6.0": 6 | version "1.6.0" 7 | resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" 8 | integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== 9 | 10 | "@cspotcode/source-map-support@^0.8.0": 11 | version "0.8.1" 12 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 13 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 14 | dependencies: 15 | "@jridgewell/trace-mapping" "0.3.9" 16 | 17 | "@dabh/diagnostics@^2.0.2": 18 | version "2.0.3" 19 | resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a" 20 | integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== 21 | dependencies: 22 | colorspace "1.1.x" 23 | enabled "2.0.x" 24 | kuler "^2.0.0" 25 | 26 | "@jridgewell/resolve-uri@^3.0.3": 27 | version "3.1.2" 28 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" 29 | integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== 30 | 31 | "@jridgewell/sourcemap-codec@^1.4.10": 32 | version "1.4.15" 33 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 34 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 35 | 36 | "@jridgewell/trace-mapping@0.3.9": 37 | version "0.3.9" 38 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 39 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 40 | dependencies: 41 | "@jridgewell/resolve-uri" "^3.0.3" 42 | "@jridgewell/sourcemap-codec" "^1.4.10" 43 | 44 | "@mapbox/node-pre-gyp@^1.0.11": 45 | version "1.0.11" 46 | resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" 47 | integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== 48 | dependencies: 49 | detect-libc "^2.0.0" 50 | https-proxy-agent "^5.0.0" 51 | make-dir "^3.1.0" 52 | node-fetch "^2.6.7" 53 | nopt "^5.0.0" 54 | npmlog "^5.0.1" 55 | rimraf "^3.0.2" 56 | semver "^7.3.5" 57 | tar "^6.1.11" 58 | 59 | "@mongodb-js/saslprep@^1.1.0": 60 | version "1.1.0" 61 | resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.0.tgz#022fa36620a7287d17acd05c4aae1e5f390d250d" 62 | integrity sha512-Xfijy7HvfzzqiOAhAepF4SGN5e9leLkMvg/OPOF97XemjfVCYN/oWa75wnkc6mltMSTwY+XlbhWgUOJmkFspSw== 63 | dependencies: 64 | sparse-bitfield "^3.0.3" 65 | 66 | "@tsconfig/node10@^1.0.7": 67 | version "1.0.11" 68 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" 69 | integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== 70 | 71 | "@tsconfig/node12@^1.0.7": 72 | version "1.0.11" 73 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 74 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 75 | 76 | "@tsconfig/node14@^1.0.0": 77 | version "1.0.3" 78 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 79 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 80 | 81 | "@tsconfig/node16@^1.0.2": 82 | version "1.0.4" 83 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" 84 | integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== 85 | 86 | "@types/bcrypt@^5.0.0": 87 | version "5.0.0" 88 | resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-5.0.0.tgz#a835afa2882d165aff5690893db314eaa98b9f20" 89 | integrity sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw== 90 | dependencies: 91 | "@types/node" "*" 92 | 93 | "@types/body-parser@*": 94 | version "1.19.3" 95 | resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.3.tgz#fb558014374f7d9e56c8f34bab2042a3a07d25cd" 96 | integrity sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ== 97 | dependencies: 98 | "@types/connect" "*" 99 | "@types/node" "*" 100 | 101 | "@types/connect@*": 102 | version "3.4.36" 103 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.36.tgz#e511558c15a39cb29bd5357eebb57bd1459cd1ab" 104 | integrity sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w== 105 | dependencies: 106 | "@types/node" "*" 107 | 108 | "@types/cors@^2.8.13": 109 | version "2.8.14" 110 | resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.14.tgz#94eeb1c95eda6a8ab54870a3bf88854512f43a92" 111 | integrity sha512-RXHUvNWYICtbP6s18PnOCaqToK8y14DnLd75c6HfyKf228dxy7pHNOQkxPtvXKp/hINFMDjbYzsj63nnpPMSRQ== 112 | dependencies: 113 | "@types/node" "*" 114 | 115 | "@types/ejs@^3.1.5": 116 | version "3.1.5" 117 | resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117" 118 | integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg== 119 | 120 | "@types/express-serve-static-core@^4.17.33": 121 | version "4.17.37" 122 | resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz#7e4b7b59da9142138a2aaa7621f5abedce8c7320" 123 | integrity sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg== 124 | dependencies: 125 | "@types/node" "*" 126 | "@types/qs" "*" 127 | "@types/range-parser" "*" 128 | "@types/send" "*" 129 | 130 | "@types/express@*": 131 | version "4.17.21" 132 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" 133 | integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== 134 | dependencies: 135 | "@types/body-parser" "*" 136 | "@types/express-serve-static-core" "^4.17.33" 137 | "@types/qs" "*" 138 | "@types/serve-static" "*" 139 | 140 | "@types/express@^4.17.17": 141 | version "4.17.19" 142 | resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.19.tgz#6ff9b4851fda132c5d3dcd2f89fdb6a7a0031ced" 143 | integrity sha512-UtOfBtzN9OvpZPPbnnYunfjM7XCI4jyk1NvnFhTVz5krYAnW4o5DCoIekvms+8ApqhB4+9wSge1kBijdfTSmfg== 144 | dependencies: 145 | "@types/body-parser" "*" 146 | "@types/express-serve-static-core" "^4.17.33" 147 | "@types/qs" "*" 148 | "@types/serve-static" "*" 149 | 150 | "@types/http-errors@*": 151 | version "2.0.2" 152 | resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.2.tgz#a86e00bbde8950364f8e7846687259ffcd96e8c2" 153 | integrity sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg== 154 | 155 | "@types/jsonwebtoken@^9.0.2": 156 | version "9.0.3" 157 | resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz#1f22283b8e1f933af9e195d720798b64b399d84c" 158 | integrity sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA== 159 | dependencies: 160 | "@types/node" "*" 161 | 162 | "@types/mime@*": 163 | version "3.0.2" 164 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.2.tgz#c1ae807f13d308ee7511a5b81c74f327028e66e8" 165 | integrity sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ== 166 | 167 | "@types/mime@^1": 168 | version "1.3.3" 169 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.3.tgz#bbe64987e0eb05de150c305005055c7ad784a9ce" 170 | integrity sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg== 171 | 172 | "@types/multer@^1.4.11": 173 | version "1.4.11" 174 | resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.11.tgz#c70792670513b4af1159a2b60bf48cc932af55c5" 175 | integrity sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w== 176 | dependencies: 177 | "@types/express" "*" 178 | 179 | "@types/node@*": 180 | version "20.8.4" 181 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.4.tgz#0e9ebb2ff29d5c3302fc84477d066fa7c6b441aa" 182 | integrity sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A== 183 | dependencies: 184 | undici-types "~5.25.1" 185 | 186 | "@types/nodemailer@^6.4.15": 187 | version "6.4.15" 188 | resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.15.tgz#494be695e11c438f7f5df738fb4ab740312a6ed2" 189 | integrity sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ== 190 | dependencies: 191 | "@types/node" "*" 192 | 193 | "@types/qs@*": 194 | version "6.9.8" 195 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" 196 | integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== 197 | 198 | "@types/range-parser@*": 199 | version "1.2.5" 200 | resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.5.tgz#38bd1733ae299620771bd414837ade2e57757498" 201 | integrity sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA== 202 | 203 | "@types/send@*": 204 | version "0.17.2" 205 | resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.2.tgz#af78a4495e3c2b79bfbdac3955fdd50e03cc98f2" 206 | integrity sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw== 207 | dependencies: 208 | "@types/mime" "^1" 209 | "@types/node" "*" 210 | 211 | "@types/serve-static@*": 212 | version "1.15.3" 213 | resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.3.tgz#2cfacfd1fd4520bbc3e292cca432d5e8e2e3ee61" 214 | integrity sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg== 215 | dependencies: 216 | "@types/http-errors" "*" 217 | "@types/mime" "*" 218 | "@types/node" "*" 219 | 220 | "@types/strip-bom@^3.0.0": 221 | version "3.0.0" 222 | resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" 223 | integrity sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ== 224 | 225 | "@types/strip-json-comments@0.0.30": 226 | version "0.0.30" 227 | resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" 228 | integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== 229 | 230 | "@types/triple-beam@^1.3.2": 231 | version "1.3.5" 232 | resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" 233 | integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== 234 | 235 | "@types/validator@^13.7.17": 236 | version "13.11.2" 237 | resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.2.tgz#a2502325a3c0bd29f36dbac3b763223edd801e17" 238 | integrity sha512-nIKVVQKT6kGKysnNt+xLobr+pFJNssJRi2s034wgWeFBUx01fI8BeHTW2TcRp7VcFu9QCYG8IlChTuovcm0oKQ== 239 | 240 | "@types/webidl-conversions@*": 241 | version "7.0.1" 242 | resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.1.tgz#2b9a2062b39a7272343c185cdb884f2e52188f75" 243 | integrity sha512-8hKOnOan+Uu+NgMaCouhg3cT9x5fFZ92Jwf+uDLXLu/MFRbXxlWwGeQY7KVHkeSft6RvY+tdxklUBuyY9eIEKg== 244 | 245 | "@types/whatwg-url@^8.2.1": 246 | version "8.2.2" 247 | resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.2.tgz#749d5b3873e845897ada99be4448041d4cc39e63" 248 | integrity sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA== 249 | dependencies: 250 | "@types/node" "*" 251 | "@types/webidl-conversions" "*" 252 | 253 | abbrev@1: 254 | version "1.1.1" 255 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 256 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 257 | 258 | accepts@~1.3.8: 259 | version "1.3.8" 260 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" 261 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== 262 | dependencies: 263 | mime-types "~2.1.34" 264 | negotiator "0.6.3" 265 | 266 | acorn-walk@^8.1.1: 267 | version "8.3.2" 268 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" 269 | integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== 270 | 271 | acorn@^8.4.1: 272 | version "8.11.3" 273 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" 274 | integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== 275 | 276 | agent-base@6: 277 | version "6.0.2" 278 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" 279 | integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== 280 | dependencies: 281 | debug "4" 282 | 283 | ansi-regex@^5.0.1: 284 | version "5.0.1" 285 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 286 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 287 | 288 | ansi-styles@^4.1.0: 289 | version "4.3.0" 290 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 291 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 292 | dependencies: 293 | color-convert "^2.0.1" 294 | 295 | anymatch@~3.1.2: 296 | version "3.1.3" 297 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 298 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 299 | dependencies: 300 | normalize-path "^3.0.0" 301 | picomatch "^2.0.4" 302 | 303 | append-field@^1.0.0: 304 | version "1.0.0" 305 | resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" 306 | integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== 307 | 308 | "aproba@^1.0.3 || ^2.0.0": 309 | version "2.0.0" 310 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" 311 | integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== 312 | 313 | are-we-there-yet@^2.0.0: 314 | version "2.0.0" 315 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" 316 | integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== 317 | dependencies: 318 | delegates "^1.0.0" 319 | readable-stream "^3.6.0" 320 | 321 | arg@^4.1.0: 322 | version "4.1.3" 323 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 324 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 325 | 326 | array-flatten@1.1.1: 327 | version "1.1.1" 328 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 329 | integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== 330 | 331 | async@^3.2.3: 332 | version "3.2.5" 333 | resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" 334 | integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== 335 | 336 | balanced-match@^1.0.0: 337 | version "1.0.2" 338 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 339 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 340 | 341 | bcrypt@^5.1.0: 342 | version "5.1.1" 343 | resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.1.1.tgz#0f732c6dcb4e12e5b70a25e326a72965879ba6e2" 344 | integrity sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww== 345 | dependencies: 346 | "@mapbox/node-pre-gyp" "^1.0.11" 347 | node-addon-api "^5.0.0" 348 | 349 | binary-extensions@^2.0.0: 350 | version "2.3.0" 351 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" 352 | integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== 353 | 354 | body-parser@1.20.1: 355 | version "1.20.1" 356 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" 357 | integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== 358 | dependencies: 359 | bytes "3.1.2" 360 | content-type "~1.0.4" 361 | debug "2.6.9" 362 | depd "2.0.0" 363 | destroy "1.2.0" 364 | http-errors "2.0.0" 365 | iconv-lite "0.4.24" 366 | on-finished "2.4.1" 367 | qs "6.11.0" 368 | raw-body "2.5.1" 369 | type-is "~1.6.18" 370 | unpipe "1.0.0" 371 | 372 | brace-expansion@^1.1.7: 373 | version "1.1.11" 374 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 375 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 376 | dependencies: 377 | balanced-match "^1.0.0" 378 | concat-map "0.0.1" 379 | 380 | brace-expansion@^2.0.1: 381 | version "2.0.1" 382 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 383 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 384 | dependencies: 385 | balanced-match "^1.0.0" 386 | 387 | braces@~3.0.2: 388 | version "3.0.2" 389 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 390 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 391 | dependencies: 392 | fill-range "^7.0.1" 393 | 394 | bson@^5.5.0: 395 | version "5.5.0" 396 | resolved "https://registry.yarnpkg.com/bson/-/bson-5.5.0.tgz#a419cc69f368d2def3b8b22ea03ed1c9be40e53f" 397 | integrity sha512-B+QB4YmDx9RStKv8LLSl/aVIEV3nYJc3cJNNTK2Cd1TL+7P+cNpw9mAPeCgc5K+j01Dv6sxUzcITXDx7ZU3F0w== 398 | 399 | buffer-equal-constant-time@1.0.1: 400 | version "1.0.1" 401 | resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" 402 | integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== 403 | 404 | buffer-from@^1.0.0: 405 | version "1.1.2" 406 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 407 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 408 | 409 | busboy@^1.0.0: 410 | version "1.6.0" 411 | resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" 412 | integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== 413 | dependencies: 414 | streamsearch "^1.1.0" 415 | 416 | bytes@3.1.2: 417 | version "3.1.2" 418 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" 419 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== 420 | 421 | call-bind@^1.0.0: 422 | version "1.0.2" 423 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" 424 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 425 | dependencies: 426 | function-bind "^1.1.1" 427 | get-intrinsic "^1.0.2" 428 | 429 | chalk@^4.0.2: 430 | version "4.1.2" 431 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 432 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 433 | dependencies: 434 | ansi-styles "^4.1.0" 435 | supports-color "^7.1.0" 436 | 437 | chokidar@^3.5.1: 438 | version "3.6.0" 439 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" 440 | integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== 441 | dependencies: 442 | anymatch "~3.1.2" 443 | braces "~3.0.2" 444 | glob-parent "~5.1.2" 445 | is-binary-path "~2.1.0" 446 | is-glob "~4.0.1" 447 | normalize-path "~3.0.0" 448 | readdirp "~3.6.0" 449 | optionalDependencies: 450 | fsevents "~2.3.2" 451 | 452 | chownr@^2.0.0: 453 | version "2.0.0" 454 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" 455 | integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== 456 | 457 | color-convert@^1.9.3: 458 | version "1.9.3" 459 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 460 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 461 | dependencies: 462 | color-name "1.1.3" 463 | 464 | color-convert@^2.0.1: 465 | version "2.0.1" 466 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 467 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 468 | dependencies: 469 | color-name "~1.1.4" 470 | 471 | color-name@1.1.3: 472 | version "1.1.3" 473 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 474 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 475 | 476 | color-name@^1.0.0, color-name@~1.1.4: 477 | version "1.1.4" 478 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 479 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 480 | 481 | color-string@^1.6.0: 482 | version "1.9.1" 483 | resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" 484 | integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== 485 | dependencies: 486 | color-name "^1.0.0" 487 | simple-swizzle "^0.2.2" 488 | 489 | color-support@^1.1.2: 490 | version "1.1.3" 491 | resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" 492 | integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== 493 | 494 | color@^3.1.3: 495 | version "3.2.1" 496 | resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" 497 | integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== 498 | dependencies: 499 | color-convert "^1.9.3" 500 | color-string "^1.6.0" 501 | 502 | colorspace@1.1.x: 503 | version "1.1.4" 504 | resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" 505 | integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== 506 | dependencies: 507 | color "^3.1.3" 508 | text-hex "1.0.x" 509 | 510 | concat-map@0.0.1: 511 | version "0.0.1" 512 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 513 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 514 | 515 | concat-stream@^1.5.2: 516 | version "1.6.2" 517 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" 518 | integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== 519 | dependencies: 520 | buffer-from "^1.0.0" 521 | inherits "^2.0.3" 522 | readable-stream "^2.2.2" 523 | typedarray "^0.0.6" 524 | 525 | console-control-strings@^1.0.0, console-control-strings@^1.1.0: 526 | version "1.1.0" 527 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 528 | integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== 529 | 530 | content-disposition@0.5.4: 531 | version "0.5.4" 532 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" 533 | integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== 534 | dependencies: 535 | safe-buffer "5.2.1" 536 | 537 | content-type@~1.0.4: 538 | version "1.0.5" 539 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" 540 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== 541 | 542 | cookie-signature@1.0.6: 543 | version "1.0.6" 544 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 545 | integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== 546 | 547 | cookie@0.5.0: 548 | version "0.5.0" 549 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" 550 | integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== 551 | 552 | core-util-is@~1.0.0: 553 | version "1.0.3" 554 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" 555 | integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== 556 | 557 | cors@^2.8.5: 558 | version "2.8.5" 559 | resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" 560 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== 561 | dependencies: 562 | object-assign "^4" 563 | vary "^1" 564 | 565 | create-require@^1.1.0: 566 | version "1.1.1" 567 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 568 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 569 | 570 | debug@2.6.9: 571 | version "2.6.9" 572 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 573 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 574 | dependencies: 575 | ms "2.0.0" 576 | 577 | debug@4, debug@4.x: 578 | version "4.3.4" 579 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 580 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 581 | dependencies: 582 | ms "2.1.2" 583 | 584 | delegates@^1.0.0: 585 | version "1.0.0" 586 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 587 | integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== 588 | 589 | depd@2.0.0: 590 | version "2.0.0" 591 | resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" 592 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 593 | 594 | destroy@1.2.0: 595 | version "1.2.0" 596 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" 597 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 598 | 599 | detect-libc@^2.0.0: 600 | version "2.0.2" 601 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" 602 | integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== 603 | 604 | diff@^4.0.1: 605 | version "4.0.2" 606 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 607 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 608 | 609 | dotenv@^16.3.1: 610 | version "16.3.1" 611 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" 612 | integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== 613 | 614 | dynamic-dedupe@^0.3.0: 615 | version "0.3.0" 616 | resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" 617 | integrity sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ== 618 | dependencies: 619 | xtend "^4.0.0" 620 | 621 | ecdsa-sig-formatter@1.0.11: 622 | version "1.0.11" 623 | resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" 624 | integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== 625 | dependencies: 626 | safe-buffer "^5.0.1" 627 | 628 | ee-first@1.1.1: 629 | version "1.1.1" 630 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 631 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 632 | 633 | ejs@^3.1.10: 634 | version "3.1.10" 635 | resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" 636 | integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== 637 | dependencies: 638 | jake "^10.8.5" 639 | 640 | emoji-regex@^8.0.0: 641 | version "8.0.0" 642 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 643 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 644 | 645 | enabled@2.0.x: 646 | version "2.0.0" 647 | resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" 648 | integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== 649 | 650 | encodeurl@~1.0.2: 651 | version "1.0.2" 652 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 653 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== 654 | 655 | escape-html@~1.0.3: 656 | version "1.0.3" 657 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 658 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 659 | 660 | etag@~1.8.1: 661 | version "1.8.1" 662 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 663 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 664 | 665 | express-mongo-sanitize@^2.2.0: 666 | version "2.2.0" 667 | resolved "https://registry.yarnpkg.com/express-mongo-sanitize/-/express-mongo-sanitize-2.2.0.tgz#c8c2d45e137f213950f70bf586704e0db5cfe356" 668 | integrity sha512-PZBs5nwhD6ek9ZuP+W2xmpvcrHwXZxD5GdieX2dsjPbAbH4azOkrHbycBud2QRU+YQF1CT+pki/lZGedHgo/dQ== 669 | 670 | express@^4.18.2: 671 | version "4.18.2" 672 | resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" 673 | integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== 674 | dependencies: 675 | accepts "~1.3.8" 676 | array-flatten "1.1.1" 677 | body-parser "1.20.1" 678 | content-disposition "0.5.4" 679 | content-type "~1.0.4" 680 | cookie "0.5.0" 681 | cookie-signature "1.0.6" 682 | debug "2.6.9" 683 | depd "2.0.0" 684 | encodeurl "~1.0.2" 685 | escape-html "~1.0.3" 686 | etag "~1.8.1" 687 | finalhandler "1.2.0" 688 | fresh "0.5.2" 689 | http-errors "2.0.0" 690 | merge-descriptors "1.0.1" 691 | methods "~1.1.2" 692 | on-finished "2.4.1" 693 | parseurl "~1.3.3" 694 | path-to-regexp "0.1.7" 695 | proxy-addr "~2.0.7" 696 | qs "6.11.0" 697 | range-parser "~1.2.1" 698 | safe-buffer "5.2.1" 699 | send "0.18.0" 700 | serve-static "1.15.0" 701 | setprototypeof "1.2.0" 702 | statuses "2.0.1" 703 | type-is "~1.6.18" 704 | utils-merge "1.0.1" 705 | vary "~1.1.2" 706 | 707 | fecha@^4.2.0: 708 | version "4.2.3" 709 | resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" 710 | integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== 711 | 712 | filelist@^1.0.4: 713 | version "1.0.4" 714 | resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" 715 | integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== 716 | dependencies: 717 | minimatch "^5.0.1" 718 | 719 | fill-range@^7.0.1: 720 | version "7.0.1" 721 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 722 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 723 | dependencies: 724 | to-regex-range "^5.0.1" 725 | 726 | finalhandler@1.2.0: 727 | version "1.2.0" 728 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" 729 | integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== 730 | dependencies: 731 | debug "2.6.9" 732 | encodeurl "~1.0.2" 733 | escape-html "~1.0.3" 734 | on-finished "2.4.1" 735 | parseurl "~1.3.3" 736 | statuses "2.0.1" 737 | unpipe "~1.0.0" 738 | 739 | fn.name@1.x.x: 740 | version "1.1.0" 741 | resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" 742 | integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== 743 | 744 | forwarded@0.2.0: 745 | version "0.2.0" 746 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" 747 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 748 | 749 | fresh@0.5.2: 750 | version "0.5.2" 751 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 752 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== 753 | 754 | fs-minipass@^2.0.0: 755 | version "2.1.0" 756 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" 757 | integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== 758 | dependencies: 759 | minipass "^3.0.0" 760 | 761 | fs.realpath@^1.0.0: 762 | version "1.0.0" 763 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 764 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 765 | 766 | fsevents@~2.3.2: 767 | version "2.3.3" 768 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 769 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 770 | 771 | function-bind@^1.1.1: 772 | version "1.1.1" 773 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 774 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 775 | 776 | function-bind@^1.1.2: 777 | version "1.1.2" 778 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" 779 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== 780 | 781 | gauge@^3.0.0: 782 | version "3.0.2" 783 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" 784 | integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== 785 | dependencies: 786 | aproba "^1.0.3 || ^2.0.0" 787 | color-support "^1.1.2" 788 | console-control-strings "^1.0.0" 789 | has-unicode "^2.0.1" 790 | object-assign "^4.1.1" 791 | signal-exit "^3.0.0" 792 | string-width "^4.2.3" 793 | strip-ansi "^6.0.1" 794 | wide-align "^1.1.2" 795 | 796 | get-intrinsic@^1.0.2: 797 | version "1.2.1" 798 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" 799 | integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== 800 | dependencies: 801 | function-bind "^1.1.1" 802 | has "^1.0.3" 803 | has-proto "^1.0.1" 804 | has-symbols "^1.0.3" 805 | 806 | glob-parent@~5.1.2: 807 | version "5.1.2" 808 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 809 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 810 | dependencies: 811 | is-glob "^4.0.1" 812 | 813 | glob@^7.1.3: 814 | version "7.2.3" 815 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 816 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 817 | dependencies: 818 | fs.realpath "^1.0.0" 819 | inflight "^1.0.4" 820 | inherits "2" 821 | minimatch "^3.1.1" 822 | once "^1.3.0" 823 | path-is-absolute "^1.0.0" 824 | 825 | has-flag@^4.0.0: 826 | version "4.0.0" 827 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 828 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 829 | 830 | has-proto@^1.0.1: 831 | version "1.0.1" 832 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" 833 | integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== 834 | 835 | has-symbols@^1.0.3: 836 | version "1.0.3" 837 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 838 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 839 | 840 | has-unicode@^2.0.1: 841 | version "2.0.1" 842 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 843 | integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== 844 | 845 | has@^1.0.3: 846 | version "1.0.4" 847 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" 848 | integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== 849 | 850 | hasown@^2.0.0: 851 | version "2.0.2" 852 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" 853 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== 854 | dependencies: 855 | function-bind "^1.1.2" 856 | 857 | helmet@^7.1.0: 858 | version "7.1.0" 859 | resolved "https://registry.yarnpkg.com/helmet/-/helmet-7.1.0.tgz#287279e00f8a3763d5dccbaf1e5ee39b8c3784ca" 860 | integrity sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg== 861 | 862 | http-errors@2.0.0: 863 | version "2.0.0" 864 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" 865 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 866 | dependencies: 867 | depd "2.0.0" 868 | inherits "2.0.4" 869 | setprototypeof "1.2.0" 870 | statuses "2.0.1" 871 | toidentifier "1.0.1" 872 | 873 | http-status@^1.6.2: 874 | version "1.7.0" 875 | resolved "https://registry.yarnpkg.com/http-status/-/http-status-1.7.0.tgz#df919bb5dcb879275e839ea0b2677664995d38c2" 876 | integrity sha512-6HZ8T2ywZKtNKOrRA22x4Z+fK+UiWzimWYSTROVHrZ46RX+hKsg9wCQiodRtfNrKfsvOkwsXA6R9q+TmDY+8nQ== 877 | 878 | https-proxy-agent@^5.0.0: 879 | version "5.0.1" 880 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" 881 | integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== 882 | dependencies: 883 | agent-base "6" 884 | debug "4" 885 | 886 | iconv-lite@0.4.24: 887 | version "0.4.24" 888 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 889 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 890 | dependencies: 891 | safer-buffer ">= 2.1.2 < 3" 892 | 893 | inflight@^1.0.4: 894 | version "1.0.6" 895 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 896 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 897 | dependencies: 898 | once "^1.3.0" 899 | wrappy "1" 900 | 901 | inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: 902 | version "2.0.4" 903 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 904 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 905 | 906 | ip@^2.0.0: 907 | version "2.0.0" 908 | resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" 909 | integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== 910 | 911 | ipaddr.js@1.9.1: 912 | version "1.9.1" 913 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 914 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 915 | 916 | is-arrayish@^0.3.1: 917 | version "0.3.2" 918 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" 919 | integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== 920 | 921 | is-binary-path@~2.1.0: 922 | version "2.1.0" 923 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 924 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 925 | dependencies: 926 | binary-extensions "^2.0.0" 927 | 928 | is-core-module@^2.13.0: 929 | version "2.13.1" 930 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" 931 | integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== 932 | dependencies: 933 | hasown "^2.0.0" 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 sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 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.1, is-glob@~4.0.1: 946 | version "4.0.3" 947 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 948 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 949 | dependencies: 950 | is-extglob "^2.1.1" 951 | 952 | is-number@^7.0.0: 953 | version "7.0.0" 954 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 955 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 956 | 957 | is-stream@^2.0.0: 958 | version "2.0.1" 959 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 960 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 961 | 962 | isarray@~1.0.0: 963 | version "1.0.0" 964 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 965 | integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== 966 | 967 | jake@^10.8.5: 968 | version "10.9.1" 969 | resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.1.tgz#8dc96b7fcc41cb19aa502af506da4e1d56f5e62b" 970 | integrity sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w== 971 | dependencies: 972 | async "^3.2.3" 973 | chalk "^4.0.2" 974 | filelist "^1.0.4" 975 | minimatch "^3.1.2" 976 | 977 | jsonwebtoken@^9.0.0: 978 | version "9.0.2" 979 | resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" 980 | integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== 981 | dependencies: 982 | jws "^3.2.2" 983 | lodash.includes "^4.3.0" 984 | lodash.isboolean "^3.0.3" 985 | lodash.isinteger "^4.0.4" 986 | lodash.isnumber "^3.0.3" 987 | lodash.isplainobject "^4.0.6" 988 | lodash.isstring "^4.0.1" 989 | lodash.once "^4.0.0" 990 | ms "^2.1.1" 991 | semver "^7.5.4" 992 | 993 | jwa@^1.4.1: 994 | version "1.4.1" 995 | resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" 996 | integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== 997 | dependencies: 998 | buffer-equal-constant-time "1.0.1" 999 | ecdsa-sig-formatter "1.0.11" 1000 | safe-buffer "^5.0.1" 1001 | 1002 | jws@^3.2.2: 1003 | version "3.2.2" 1004 | resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" 1005 | integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== 1006 | dependencies: 1007 | jwa "^1.4.1" 1008 | safe-buffer "^5.0.1" 1009 | 1010 | kareem@2.5.1: 1011 | version "2.5.1" 1012 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d" 1013 | integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA== 1014 | 1015 | kuler@^2.0.0: 1016 | version "2.0.0" 1017 | resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" 1018 | integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== 1019 | 1020 | lodash.includes@^4.3.0: 1021 | version "4.3.0" 1022 | resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" 1023 | integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== 1024 | 1025 | lodash.isboolean@^3.0.3: 1026 | version "3.0.3" 1027 | resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" 1028 | integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== 1029 | 1030 | lodash.isinteger@^4.0.4: 1031 | version "4.0.4" 1032 | resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" 1033 | integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== 1034 | 1035 | lodash.isnumber@^3.0.3: 1036 | version "3.0.3" 1037 | resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" 1038 | integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== 1039 | 1040 | lodash.isplainobject@^4.0.6: 1041 | version "4.0.6" 1042 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 1043 | integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== 1044 | 1045 | lodash.isstring@^4.0.1: 1046 | version "4.0.1" 1047 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 1048 | integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== 1049 | 1050 | lodash.once@^4.0.0: 1051 | version "4.1.1" 1052 | resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" 1053 | integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== 1054 | 1055 | logform@^2.3.2, logform@^2.4.0: 1056 | version "2.6.0" 1057 | resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.0.tgz#8c82a983f05d6eaeb2d75e3decae7a768b2bf9b5" 1058 | integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== 1059 | dependencies: 1060 | "@colors/colors" "1.6.0" 1061 | "@types/triple-beam" "^1.3.2" 1062 | fecha "^4.2.0" 1063 | ms "^2.1.1" 1064 | safe-stable-stringify "^2.3.1" 1065 | triple-beam "^1.3.0" 1066 | 1067 | lru-cache@^6.0.0: 1068 | version "6.0.0" 1069 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1070 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1071 | dependencies: 1072 | yallist "^4.0.0" 1073 | 1074 | make-dir@^3.1.0: 1075 | version "3.1.0" 1076 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" 1077 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 1078 | dependencies: 1079 | semver "^6.0.0" 1080 | 1081 | make-error@^1.1.1: 1082 | version "1.3.6" 1083 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 1084 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 1085 | 1086 | media-typer@0.3.0: 1087 | version "0.3.0" 1088 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 1089 | integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== 1090 | 1091 | memory-pager@^1.0.2: 1092 | version "1.5.0" 1093 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 1094 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== 1095 | 1096 | merge-descriptors@1.0.1: 1097 | version "1.0.1" 1098 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 1099 | integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== 1100 | 1101 | methods@~1.1.2: 1102 | version "1.1.2" 1103 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 1104 | integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== 1105 | 1106 | mime-db@1.52.0: 1107 | version "1.52.0" 1108 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 1109 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 1110 | 1111 | mime-types@~2.1.24, mime-types@~2.1.34: 1112 | version "2.1.35" 1113 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 1114 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 1115 | dependencies: 1116 | mime-db "1.52.0" 1117 | 1118 | mime@1.6.0: 1119 | version "1.6.0" 1120 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 1121 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 1122 | 1123 | minimatch@^3.1.1, minimatch@^3.1.2: 1124 | version "3.1.2" 1125 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1126 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1127 | dependencies: 1128 | brace-expansion "^1.1.7" 1129 | 1130 | minimatch@^5.0.1: 1131 | version "5.1.6" 1132 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" 1133 | integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== 1134 | dependencies: 1135 | brace-expansion "^2.0.1" 1136 | 1137 | minimist@^1.2.6: 1138 | version "1.2.8" 1139 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 1140 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 1141 | 1142 | minipass@^3.0.0: 1143 | version "3.3.6" 1144 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" 1145 | integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== 1146 | dependencies: 1147 | yallist "^4.0.0" 1148 | 1149 | minipass@^5.0.0: 1150 | version "5.0.0" 1151 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" 1152 | integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== 1153 | 1154 | minizlib@^2.1.1: 1155 | version "2.1.2" 1156 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" 1157 | integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== 1158 | dependencies: 1159 | minipass "^3.0.0" 1160 | yallist "^4.0.0" 1161 | 1162 | mkdirp@^0.5.4: 1163 | version "0.5.6" 1164 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" 1165 | integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== 1166 | dependencies: 1167 | minimist "^1.2.6" 1168 | 1169 | mkdirp@^1.0.3, mkdirp@^1.0.4: 1170 | version "1.0.4" 1171 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 1172 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 1173 | 1174 | moment@^2.30.1: 1175 | version "2.30.1" 1176 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" 1177 | integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== 1178 | 1179 | mongodb-connection-string-url@^2.6.0: 1180 | version "2.6.0" 1181 | resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz#57901bf352372abdde812c81be47b75c6b2ec5cf" 1182 | integrity sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ== 1183 | dependencies: 1184 | "@types/whatwg-url" "^8.2.1" 1185 | whatwg-url "^11.0.0" 1186 | 1187 | mongodb@5.9.0: 1188 | version "5.9.0" 1189 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-5.9.0.tgz#5a22065fa8cfaf1d58bf2e3c451cd2c4bfa983a2" 1190 | integrity sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA== 1191 | dependencies: 1192 | bson "^5.5.0" 1193 | mongodb-connection-string-url "^2.6.0" 1194 | socks "^2.7.1" 1195 | optionalDependencies: 1196 | "@mongodb-js/saslprep" "^1.1.0" 1197 | 1198 | mongoose@^7.3.0: 1199 | version "7.6.1" 1200 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-7.6.1.tgz#39e4d25af26d0399468d4c0ac7373c4a8a838e3e" 1201 | integrity sha512-Iflr60FL7mabBdgAtumLTwEGdZGV6IKHfF7F75En2JWpPitorwQeCFqWPcPHRnBxncKANl3gwI9nh2Yb4y3/sA== 1202 | dependencies: 1203 | bson "^5.5.0" 1204 | kareem "2.5.1" 1205 | mongodb "5.9.0" 1206 | mpath "0.9.0" 1207 | mquery "5.0.0" 1208 | ms "2.1.3" 1209 | sift "16.0.1" 1210 | 1211 | mpath@0.9.0: 1212 | version "0.9.0" 1213 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904" 1214 | integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew== 1215 | 1216 | mquery@5.0.0: 1217 | version "5.0.0" 1218 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-5.0.0.tgz#a95be5dfc610b23862df34a47d3e5d60e110695d" 1219 | integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg== 1220 | dependencies: 1221 | debug "4.x" 1222 | 1223 | ms@2.0.0: 1224 | version "2.0.0" 1225 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1226 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 1227 | 1228 | ms@2.1.2: 1229 | version "2.1.2" 1230 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1231 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1232 | 1233 | ms@2.1.3, ms@^2.1.1: 1234 | version "2.1.3" 1235 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 1236 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1237 | 1238 | multer@^1.4.5-lts.1: 1239 | version "1.4.5-lts.1" 1240 | resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.5-lts.1.tgz#803e24ad1984f58edffbc79f56e305aec5cfd1ac" 1241 | integrity sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ== 1242 | dependencies: 1243 | append-field "^1.0.0" 1244 | busboy "^1.0.0" 1245 | concat-stream "^1.5.2" 1246 | mkdirp "^0.5.4" 1247 | object-assign "^4.1.1" 1248 | type-is "^1.6.4" 1249 | xtend "^4.0.0" 1250 | 1251 | negotiator@0.6.3: 1252 | version "0.6.3" 1253 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" 1254 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== 1255 | 1256 | node-addon-api@^5.0.0: 1257 | version "5.1.0" 1258 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" 1259 | integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== 1260 | 1261 | node-fetch@^2.6.7: 1262 | version "2.7.0" 1263 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" 1264 | integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== 1265 | dependencies: 1266 | whatwg-url "^5.0.0" 1267 | 1268 | nodemailer@^6.9.13: 1269 | version "6.9.13" 1270 | resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.13.tgz#5b292bf1e92645f4852ca872c56a6ba6c4a3d3d6" 1271 | integrity sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA== 1272 | 1273 | nopt@^5.0.0: 1274 | version "5.0.0" 1275 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" 1276 | integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== 1277 | dependencies: 1278 | abbrev "1" 1279 | 1280 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1281 | version "3.0.0" 1282 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1283 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1284 | 1285 | npmlog@^5.0.1: 1286 | version "5.0.1" 1287 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" 1288 | integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== 1289 | dependencies: 1290 | are-we-there-yet "^2.0.0" 1291 | console-control-strings "^1.1.0" 1292 | gauge "^3.0.0" 1293 | set-blocking "^2.0.0" 1294 | 1295 | object-assign@^4, object-assign@^4.1.1: 1296 | version "4.1.1" 1297 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1298 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 1299 | 1300 | object-inspect@^1.9.0: 1301 | version "1.12.3" 1302 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" 1303 | integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== 1304 | 1305 | on-finished@2.4.1: 1306 | version "2.4.1" 1307 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" 1308 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 1309 | dependencies: 1310 | ee-first "1.1.1" 1311 | 1312 | once@^1.3.0: 1313 | version "1.4.0" 1314 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1315 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1316 | dependencies: 1317 | wrappy "1" 1318 | 1319 | one-time@^1.0.0: 1320 | version "1.0.0" 1321 | resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" 1322 | integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== 1323 | dependencies: 1324 | fn.name "1.x.x" 1325 | 1326 | parseurl@~1.3.3: 1327 | version "1.3.3" 1328 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 1329 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 1330 | 1331 | path-is-absolute@^1.0.0: 1332 | version "1.0.1" 1333 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1334 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1335 | 1336 | path-parse@^1.0.7: 1337 | version "1.0.7" 1338 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 1339 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1340 | 1341 | path-to-regexp@0.1.7: 1342 | version "0.1.7" 1343 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 1344 | integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== 1345 | 1346 | picomatch@^2.0.4, picomatch@^2.2.1: 1347 | version "2.3.1" 1348 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1349 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1350 | 1351 | process-nextick-args@~2.0.0: 1352 | version "2.0.1" 1353 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 1354 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 1355 | 1356 | proxy-addr@~2.0.7: 1357 | version "2.0.7" 1358 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" 1359 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 1360 | dependencies: 1361 | forwarded "0.2.0" 1362 | ipaddr.js "1.9.1" 1363 | 1364 | punycode@^2.1.1: 1365 | version "2.3.0" 1366 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" 1367 | integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== 1368 | 1369 | qs@6.11.0: 1370 | version "6.11.0" 1371 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" 1372 | integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== 1373 | dependencies: 1374 | side-channel "^1.0.4" 1375 | 1376 | range-parser@~1.2.1: 1377 | version "1.2.1" 1378 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 1379 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 1380 | 1381 | raw-body@2.5.1: 1382 | version "2.5.1" 1383 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" 1384 | integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== 1385 | dependencies: 1386 | bytes "3.1.2" 1387 | http-errors "2.0.0" 1388 | iconv-lite "0.4.24" 1389 | unpipe "1.0.0" 1390 | 1391 | readable-stream@^2.2.2: 1392 | version "2.3.8" 1393 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" 1394 | integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== 1395 | dependencies: 1396 | core-util-is "~1.0.0" 1397 | inherits "~2.0.3" 1398 | isarray "~1.0.0" 1399 | process-nextick-args "~2.0.0" 1400 | safe-buffer "~5.1.1" 1401 | string_decoder "~1.1.1" 1402 | util-deprecate "~1.0.1" 1403 | 1404 | readable-stream@^3.4.0, readable-stream@^3.6.0: 1405 | version "3.6.2" 1406 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" 1407 | integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== 1408 | dependencies: 1409 | inherits "^2.0.3" 1410 | string_decoder "^1.1.1" 1411 | util-deprecate "^1.0.1" 1412 | 1413 | readdirp@~3.6.0: 1414 | version "3.6.0" 1415 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1416 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1417 | dependencies: 1418 | picomatch "^2.2.1" 1419 | 1420 | resolve@^1.0.0: 1421 | version "1.22.8" 1422 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" 1423 | integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== 1424 | dependencies: 1425 | is-core-module "^2.13.0" 1426 | path-parse "^1.0.7" 1427 | supports-preserve-symlinks-flag "^1.0.0" 1428 | 1429 | rimraf@^2.6.1: 1430 | version "2.7.1" 1431 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" 1432 | integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== 1433 | dependencies: 1434 | glob "^7.1.3" 1435 | 1436 | rimraf@^3.0.2: 1437 | version "3.0.2" 1438 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1439 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1440 | dependencies: 1441 | glob "^7.1.3" 1442 | 1443 | safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: 1444 | version "5.2.1" 1445 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1446 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1447 | 1448 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 1449 | version "5.1.2" 1450 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1451 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 1452 | 1453 | safe-stable-stringify@^2.3.1: 1454 | version "2.4.3" 1455 | resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" 1456 | integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== 1457 | 1458 | "safer-buffer@>= 2.1.2 < 3": 1459 | version "2.1.2" 1460 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1461 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 1462 | 1463 | semver@^6.0.0: 1464 | version "6.3.1" 1465 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" 1466 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== 1467 | 1468 | semver@^7.3.5, semver@^7.5.4: 1469 | version "7.5.4" 1470 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" 1471 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== 1472 | dependencies: 1473 | lru-cache "^6.0.0" 1474 | 1475 | send@0.18.0: 1476 | version "0.18.0" 1477 | resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" 1478 | integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== 1479 | dependencies: 1480 | debug "2.6.9" 1481 | depd "2.0.0" 1482 | destroy "1.2.0" 1483 | encodeurl "~1.0.2" 1484 | escape-html "~1.0.3" 1485 | etag "~1.8.1" 1486 | fresh "0.5.2" 1487 | http-errors "2.0.0" 1488 | mime "1.6.0" 1489 | ms "2.1.3" 1490 | on-finished "2.4.1" 1491 | range-parser "~1.2.1" 1492 | statuses "2.0.1" 1493 | 1494 | serve-static@1.15.0: 1495 | version "1.15.0" 1496 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" 1497 | integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== 1498 | dependencies: 1499 | encodeurl "~1.0.2" 1500 | escape-html "~1.0.3" 1501 | parseurl "~1.3.3" 1502 | send "0.18.0" 1503 | 1504 | set-blocking@^2.0.0: 1505 | version "2.0.0" 1506 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 1507 | integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== 1508 | 1509 | setprototypeof@1.2.0: 1510 | version "1.2.0" 1511 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" 1512 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 1513 | 1514 | side-channel@^1.0.4: 1515 | version "1.0.4" 1516 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" 1517 | integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== 1518 | dependencies: 1519 | call-bind "^1.0.0" 1520 | get-intrinsic "^1.0.2" 1521 | object-inspect "^1.9.0" 1522 | 1523 | sift@16.0.1: 1524 | version "16.0.1" 1525 | resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.1.tgz#e9c2ccc72191585008cf3e36fc447b2d2633a053" 1526 | integrity sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ== 1527 | 1528 | signal-exit@^3.0.0: 1529 | version "3.0.7" 1530 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 1531 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1532 | 1533 | simple-swizzle@^0.2.2: 1534 | version "0.2.2" 1535 | resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" 1536 | integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== 1537 | dependencies: 1538 | is-arrayish "^0.3.1" 1539 | 1540 | smart-buffer@^4.2.0: 1541 | version "4.2.0" 1542 | resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" 1543 | integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== 1544 | 1545 | socks@^2.7.1: 1546 | version "2.7.1" 1547 | resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" 1548 | integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== 1549 | dependencies: 1550 | ip "^2.0.0" 1551 | smart-buffer "^4.2.0" 1552 | 1553 | source-map-support@^0.5.12: 1554 | version "0.5.21" 1555 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" 1556 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 1557 | dependencies: 1558 | buffer-from "^1.0.0" 1559 | source-map "^0.6.0" 1560 | 1561 | source-map@^0.6.0: 1562 | version "0.6.1" 1563 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1564 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1565 | 1566 | sparse-bitfield@^3.0.3: 1567 | version "3.0.3" 1568 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 1569 | integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ== 1570 | dependencies: 1571 | memory-pager "^1.0.2" 1572 | 1573 | stack-trace@0.0.x: 1574 | version "0.0.10" 1575 | resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" 1576 | integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== 1577 | 1578 | statuses@2.0.1: 1579 | version "2.0.1" 1580 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" 1581 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 1582 | 1583 | streamsearch@^1.1.0: 1584 | version "1.1.0" 1585 | resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" 1586 | integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== 1587 | 1588 | "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: 1589 | version "4.2.3" 1590 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1591 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1592 | dependencies: 1593 | emoji-regex "^8.0.0" 1594 | is-fullwidth-code-point "^3.0.0" 1595 | strip-ansi "^6.0.1" 1596 | 1597 | string_decoder@^1.1.1: 1598 | version "1.3.0" 1599 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1600 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1601 | dependencies: 1602 | safe-buffer "~5.2.0" 1603 | 1604 | string_decoder@~1.1.1: 1605 | version "1.1.1" 1606 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 1607 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 1608 | dependencies: 1609 | safe-buffer "~5.1.0" 1610 | 1611 | strip-ansi@^6.0.1: 1612 | version "6.0.1" 1613 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1614 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1615 | dependencies: 1616 | ansi-regex "^5.0.1" 1617 | 1618 | strip-bom@^3.0.0: 1619 | version "3.0.0" 1620 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 1621 | integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== 1622 | 1623 | strip-json-comments@^2.0.0: 1624 | version "2.0.1" 1625 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 1626 | integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== 1627 | 1628 | supports-color@^7.1.0: 1629 | version "7.2.0" 1630 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1631 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1632 | dependencies: 1633 | has-flag "^4.0.0" 1634 | 1635 | supports-preserve-symlinks-flag@^1.0.0: 1636 | version "1.0.0" 1637 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1638 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1639 | 1640 | tar@^6.1.11: 1641 | version "6.2.0" 1642 | resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" 1643 | integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== 1644 | dependencies: 1645 | chownr "^2.0.0" 1646 | fs-minipass "^2.0.0" 1647 | minipass "^5.0.0" 1648 | minizlib "^2.1.1" 1649 | mkdirp "^1.0.3" 1650 | yallist "^4.0.0" 1651 | 1652 | text-hex@1.0.x: 1653 | version "1.0.0" 1654 | resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" 1655 | integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== 1656 | 1657 | to-regex-range@^5.0.1: 1658 | version "5.0.1" 1659 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1660 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1661 | dependencies: 1662 | is-number "^7.0.0" 1663 | 1664 | toidentifier@1.0.1: 1665 | version "1.0.1" 1666 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" 1667 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 1668 | 1669 | tr46@^3.0.0: 1670 | version "3.0.0" 1671 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" 1672 | integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== 1673 | dependencies: 1674 | punycode "^2.1.1" 1675 | 1676 | tr46@~0.0.3: 1677 | version "0.0.3" 1678 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 1679 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 1680 | 1681 | tree-kill@^1.2.2: 1682 | version "1.2.2" 1683 | resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 1684 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1685 | 1686 | triple-beam@^1.3.0: 1687 | version "1.4.1" 1688 | resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" 1689 | integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== 1690 | 1691 | ts-node-dev@^2.0.0: 1692 | version "2.0.0" 1693 | resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-2.0.0.tgz#bdd53e17ab3b5d822ef519928dc6b4a7e0f13065" 1694 | integrity sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w== 1695 | dependencies: 1696 | chokidar "^3.5.1" 1697 | dynamic-dedupe "^0.3.0" 1698 | minimist "^1.2.6" 1699 | mkdirp "^1.0.4" 1700 | resolve "^1.0.0" 1701 | rimraf "^2.6.1" 1702 | source-map-support "^0.5.12" 1703 | tree-kill "^1.2.2" 1704 | ts-node "^10.4.0" 1705 | tsconfig "^7.0.0" 1706 | 1707 | ts-node@^10.4.0: 1708 | version "10.9.2" 1709 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" 1710 | integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== 1711 | dependencies: 1712 | "@cspotcode/source-map-support" "^0.8.0" 1713 | "@tsconfig/node10" "^1.0.7" 1714 | "@tsconfig/node12" "^1.0.7" 1715 | "@tsconfig/node14" "^1.0.0" 1716 | "@tsconfig/node16" "^1.0.2" 1717 | acorn "^8.4.1" 1718 | acorn-walk "^8.1.1" 1719 | arg "^4.1.0" 1720 | create-require "^1.1.0" 1721 | diff "^4.0.1" 1722 | make-error "^1.1.1" 1723 | v8-compile-cache-lib "^3.0.1" 1724 | yn "3.1.1" 1725 | 1726 | tsconfig@^7.0.0: 1727 | version "7.0.0" 1728 | resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" 1729 | integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== 1730 | dependencies: 1731 | "@types/strip-bom" "^3.0.0" 1732 | "@types/strip-json-comments" "0.0.30" 1733 | strip-bom "^3.0.0" 1734 | strip-json-comments "^2.0.0" 1735 | 1736 | type-is@^1.6.4, type-is@~1.6.18: 1737 | version "1.6.18" 1738 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 1739 | integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== 1740 | dependencies: 1741 | media-typer "0.3.0" 1742 | mime-types "~2.1.24" 1743 | 1744 | typedarray@^0.0.6: 1745 | version "0.0.6" 1746 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 1747 | integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== 1748 | 1749 | typescript@^5.4.5: 1750 | version "5.4.5" 1751 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" 1752 | integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== 1753 | 1754 | undici-types@~5.25.1: 1755 | version "5.25.3" 1756 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" 1757 | integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== 1758 | 1759 | unpipe@1.0.0, unpipe@~1.0.0: 1760 | version "1.0.0" 1761 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1762 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== 1763 | 1764 | util-deprecate@^1.0.1, util-deprecate@~1.0.1: 1765 | version "1.0.2" 1766 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1767 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1768 | 1769 | utils-merge@1.0.1: 1770 | version "1.0.1" 1771 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 1772 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== 1773 | 1774 | v8-compile-cache-lib@^3.0.1: 1775 | version "3.0.1" 1776 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1777 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1778 | 1779 | validator@^13.9.0: 1780 | version "13.11.0" 1781 | resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b" 1782 | integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== 1783 | 1784 | vary@^1, vary@~1.1.2: 1785 | version "1.1.2" 1786 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 1787 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== 1788 | 1789 | webidl-conversions@^3.0.0: 1790 | version "3.0.1" 1791 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1792 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1793 | 1794 | webidl-conversions@^7.0.0: 1795 | version "7.0.0" 1796 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" 1797 | integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== 1798 | 1799 | whatwg-url@^11.0.0: 1800 | version "11.0.0" 1801 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" 1802 | integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== 1803 | dependencies: 1804 | tr46 "^3.0.0" 1805 | webidl-conversions "^7.0.0" 1806 | 1807 | whatwg-url@^5.0.0: 1808 | version "5.0.0" 1809 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1810 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1811 | dependencies: 1812 | tr46 "~0.0.3" 1813 | webidl-conversions "^3.0.0" 1814 | 1815 | wide-align@^1.1.2: 1816 | version "1.1.5" 1817 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" 1818 | integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== 1819 | dependencies: 1820 | string-width "^1.0.2 || 2 || 3 || 4" 1821 | 1822 | winston-transport@^4.7.0: 1823 | version "4.7.0" 1824 | resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.0.tgz#e302e6889e6ccb7f383b926df6936a5b781bd1f0" 1825 | integrity sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg== 1826 | dependencies: 1827 | logform "^2.3.2" 1828 | readable-stream "^3.6.0" 1829 | triple-beam "^1.3.0" 1830 | 1831 | winston@^3.13.0: 1832 | version "3.13.0" 1833 | resolved "https://registry.yarnpkg.com/winston/-/winston-3.13.0.tgz#e76c0d722f78e04838158c61adc1287201de7ce3" 1834 | integrity sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ== 1835 | dependencies: 1836 | "@colors/colors" "^1.6.0" 1837 | "@dabh/diagnostics" "^2.0.2" 1838 | async "^3.2.3" 1839 | is-stream "^2.0.0" 1840 | logform "^2.4.0" 1841 | one-time "^1.0.0" 1842 | readable-stream "^3.4.0" 1843 | safe-stable-stringify "^2.3.1" 1844 | stack-trace "0.0.x" 1845 | triple-beam "^1.3.0" 1846 | winston-transport "^4.7.0" 1847 | 1848 | wrappy@1: 1849 | version "1.0.2" 1850 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1851 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1852 | 1853 | xss-clean@^0.1.4: 1854 | version "0.1.4" 1855 | resolved "https://registry.yarnpkg.com/xss-clean/-/xss-clean-0.1.4.tgz#592b7f59cc52d39d4b8c397787243817639fb73d" 1856 | integrity sha512-4hArTFHYxrifK9VXOu/zFvwjTXVjKByPi6woUHb1IqxlX0Z4xtFBRjOhTKuYV/uE1VswbYsIh5vUEYp7MmoISQ== 1857 | dependencies: 1858 | xss-filters "1.2.7" 1859 | 1860 | xss-filters@1.2.7: 1861 | version "1.2.7" 1862 | resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a" 1863 | integrity sha512-KzcmYT/f+YzcYrYRqw6mXxd25BEZCxBQnf+uXTopQDIhrmiaLwO+f+yLsIvvNlPhYvgff8g3igqrBxYh9k8NbQ== 1864 | 1865 | xtend@^4.0.0: 1866 | version "4.0.2" 1867 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 1868 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 1869 | 1870 | yallist@^4.0.0: 1871 | version "4.0.0" 1872 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1873 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1874 | 1875 | yn@3.1.1: 1876 | version "3.1.1" 1877 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 1878 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 1879 | 1880 | zod@^3.23.8: 1881 | version "3.23.8" 1882 | resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" 1883 | integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== 1884 | --------------------------------------------------------------------------------