diff --git a/week4/.gitignore b/week4/.gitignore new file mode 100644 index 0000000..2e28dfc --- /dev/null +++ b/week4/.gitignore @@ -0,0 +1,5 @@ +node_modules +# Keep environment variables out of version control +.env +.DS_Store +.vscode \ No newline at end of file diff --git a/week4/nodemon.json b/week4/nodemon.json new file mode 100644 index 0000000..bd415b2 --- /dev/null +++ b/week4/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["src", ".env"], + "ext": "js,ts,json", + "ignore": ["src/**/*.spec.ts"], + "exec": "ts-node --transpile-only ./src/index.ts" +} diff --git a/week4/package.json b/week4/package.json new file mode 100644 index 0000000..fc4c3f1 --- /dev/null +++ b/week4/package.json @@ -0,0 +1,20 @@ +{ + "name": "seminar4", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "dev": "nodemon", + "build": "tsc && node dist" + }, + "devDependencies": { + "@types/express": "^4.17.14", + "@types/node": "^18.11.9", + "nodemon": "^2.0.20" + }, + "dependencies": { + "@prisma/client": "^4.5.0", + "express": "^4.18.2", + "prisma": "^4.5.0" + } +} diff --git a/week4/prisma/schema.prisma b/week4/prisma/schema.prisma new file mode 100644 index 0000000..e6ef290 --- /dev/null +++ b/week4/prisma/schema.prisma @@ -0,0 +1,15 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + id Int @unique @default(autoincrement()) + userName String + age Int? + email String? @db.VarChar(400) +} diff --git a/week4/src/controller/index.ts b/week4/src/controller/index.ts new file mode 100644 index 0000000..d2ddc5f --- /dev/null +++ b/week4/src/controller/index.ts @@ -0,0 +1 @@ +export { default as userController } from "./userController"; diff --git a/week4/src/controller/userController.ts b/week4/src/controller/userController.ts new file mode 100644 index 0000000..f2f04cf --- /dev/null +++ b/week4/src/controller/userController.ts @@ -0,0 +1,65 @@ +import { Request, Response } from "express"; +import { userService } from "../service"; + +//* 유저 생성 (추후 회원가입) +const createUser = async ( req: Request, res: Response ) => { + const { userName, email, age } = req.body; // req.body에 필드가 많은 경우에 대비하여 비구조화 할당 + + if (!userName || !email || !age) { + return res.status(400).json({ status: 400, message: "유저 생성 실패" }); + } + + const data = await userService.createUser(userName, email, age); // 컨트롤러의 역할을 분명히 하기 위해 DB와의 통신 내용은 적지 X. + + if (!data) { + return res.status(400).json({ status: 400, message: "유저 생성 실패" }); + } + return res.status(200).json({ status: 200, message: "유저 조회 성공", data }); +}; + +//* 유저 전체 조회 +const getAllUser = async ( req: Request, res: Response ) => { + const data = await userService.getAllUser(); + return res.status(200).json({ status: 200, message: "유저 전체 조회 성공", data }); +}; + +//* 유저 정보 업데이트 +const updateUser = async ( req: Request, res: Response ) => { + const { name } = req.body; + const { userId } = req.params; + + if (!name) return res.status(400).json({ status: 400, message: "유저 업데이트 실패!"}); + + const updatedUser = await userService.updateUser(+userId, name); // path parameter가 되면 string이 되어버리니까 + 써주기 + return res.status(200).json({ status: 200, message: "유저 업데이트 성공", updatedUser}); +}; + +//* 유저 삭제 +const deleteUser = async ( req: Request, res: Response ) => { + const { userId } = req.params; + + await userService.deleteUser(+userId); + return res.status(200).json({ status: 200, message: "유저 삭제 성공" }); +}; + +const getUserById = async (req: Request, res: Response) => { + const { userId } = req.params; + + const data = await userService.getUserById(+userId); // + : String -> Number (Number()와 동일) + + if (!data) { + return res.status(404).json({ status: 404, message: "NOT_FOUND" }); + } + + return res.status(200).json({ status: 200, message: "유저 조회 성공", data }); +}; + +const userController = { + createUser, + getAllUser, + updateUser, + deleteUser, + getUserById, +}; + +export default userController; diff --git a/week4/src/index.ts b/week4/src/index.ts new file mode 100644 index 0000000..e7a0809 --- /dev/null +++ b/week4/src/index.ts @@ -0,0 +1,24 @@ +import express, { NextFunction, Request, Response } from "express"; +import router from "./router"; + +const app = express(); // express 객체 받아옴 +const PORT = 3000; // 사용할 port를 3000번으로 설정 + +app.use(express.json()); // express 에서 request body를 json 으로 받아오겠다. + +app.use("/api", router); // use -> 모든 요청 +// localhost:8000/api -> api 폴더 +// localhost:8000/api/user -> user.ts + +//* HTTP method - GET +app.get("/", (req: Request, res: Response, next: NextFunction) => { + res.send("마! 이게 서버다!!!!!!!!!!!!!!!!!!!!"); +}); + +app.listen(PORT, () => { + console.log(` + ############################################# + 🛡️ Server listening on port: ${PORT} 🛡️ + ############################################# + `); +}); // 8000 번 포트에서 서버를 실행하겠다! diff --git a/week4/src/router/index.ts b/week4/src/router/index.ts new file mode 100644 index 0000000..9974b16 --- /dev/null +++ b/week4/src/router/index.ts @@ -0,0 +1,8 @@ +import { Router } from "express"; +import userRouter from "./userRouter"; + +const router: Router = Router(); + +router.use("/user", userRouter); + +export default router; diff --git a/week4/src/router/userRouter.ts b/week4/src/router/userRouter.ts new file mode 100644 index 0000000..fe7eaec --- /dev/null +++ b/week4/src/router/userRouter.ts @@ -0,0 +1,20 @@ +import { Router } from "express"; +import { userController } from "../controller"; + +const router: Router = Router(); + +router.get("/:userId", userController.getUserById); + +// 유저 생성 - POST api/user +router.post('/', userController.createUser); + +// 전체 유저 조회 - GET api/user +router.get('/', userController.getAllUser); + +// 유저 정보 업데이트 - PATCH api/user/:userId +router.patch('/:userId', userController.updateUser); + +// 유저 삭제 - DELETE api/user/:userId +router.delete('/:userId', userController.deleteUser); + +export default router; diff --git a/week4/src/service/index.ts b/week4/src/service/index.ts new file mode 100644 index 0000000..67d995e --- /dev/null +++ b/week4/src/service/index.ts @@ -0,0 +1 @@ +export { default as userService } from "./userService"; diff --git a/week4/src/service/userService.ts b/week4/src/service/userService.ts new file mode 100644 index 0000000..e6491f9 --- /dev/null +++ b/week4/src/service/userService.ts @@ -0,0 +1,63 @@ +import { PrismaClient } from "@prisma/client"; +const prisma = new PrismaClient(); + +// 유저 생성 +const createUser = async (name: string, email: string, age: number) => { + const data = await prisma.user.create({ // prisma를 이용해 user table에 create + data: { + userName: name, // DB에는 name이라는 필드가 없지만, 이런식으로는 가능(스키마에 선언된 필드 userName에는 controller에서 name으로 받은 것을 넣어주라~) + age, + email, + } + }); + + return data; +}; + +// 유저 전체 조회 +const getAllUser = async () => { + const data = await prisma.user.findMany(); + return data; +}; + +// 유저 정보 업데이트 +const updateUser = async (userId: number, name: string) => { + const data = await prisma.user.update({ + where: { // 어디를 (??) + id: userId + }, + data: { // 어떻게 바꿀건지 (??맞나..) + userName: name + } + }) +}; + +// 유저 삭제 +const deleteUser = async (userId: number) => { + await prisma.user.delete({ + where: { + id: userId, + }, + }); +}; + +//* userId로 유저 조회 +const getUserById = async (userId: number) => { + const user = await prisma.user.findUnique({ // id는 PK -> unique + where: { + id: userId, // where : 일종의 필터. 조건. id가 userId인 경우만 조회 + }, + }); + + return user; +}; + +const userService = { + createUser, + getAllUser, + updateUser, + deleteUser, + getUserById, +}; + +export default userService; diff --git a/week4/tsconfig.json b/week4/tsconfig.json new file mode 100644 index 0000000..8075b2f --- /dev/null +++ b/week4/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es6", //? 어떤 버전으로 컴파일 + "allowSyntheticDefaultImports": true, //? default export가 없는 모듈에서 default imports를 허용 + "experimentalDecorators": true, //? decorator 실험적 허용 + "emitDecoratorMetadata": true, //? 데코레이터가 있는 선언에 대해 특정 타입의 메타 데이터를 내보내는 실험적인 지원 + "skipLibCheck": true, //? 정의 파일 타입 체크 여부 + "moduleResolution": "node", //? commonJS -> node 에서 동작 + "module": "commonjs", //? import 문법 + "strict": true, //? 타입 검사 엄격하게 + "pretty": true, //? error 메시지 예쁘게 + "sourceMap": true, //? 소스맵 파일 생성 -> .ts가 .js 파일로 트랜스 시 .js.map 생성 + "outDir": "./dist", //? 트랜스 파일 (.js) 저장 경로 + "allowJs": true, //? js 파일 ts에서 import 허용 + "esModuleInterop": true, //? ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있게 허용 + "typeRoots": [ + "./src/types/express.d.ts", //? 타입(*.d.ts)파일을 가져올 디렉토리 설정 + "./node_modules/@types" //? 설정 안할시 기본적으로 ./node_modules/@types + ] + }, + "include": [ + "./src/**/*" //? build 시 포함 + ], + "exclude": [ + "node_modules", //? build 시 제외 + "tests" + ] +} diff --git a/week4/yarn.lock b/week4/yarn.lock new file mode 100644 index 0000000..ca19658 --- /dev/null +++ b/week4/yarn.lock @@ -0,0 +1,704 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@prisma/client@^4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.5.0.tgz#f708549bee3da396d5741d846b4e4306b120210c" + integrity sha512-B2cV0OPI1smhdYUxsJoLYQLoMlLH06MUxgFUWQnHodGMX98VRVXKmQE/9OcrTNkqtke5RC+YU24Szxd04tZA2g== + dependencies: + "@prisma/engines-version" "4.5.0-43.0362da9eebca54d94c8ef5edd3b2e90af99ba452" + +"@prisma/engines-version@4.5.0-43.0362da9eebca54d94c8ef5edd3b2e90af99ba452": + version "4.5.0-43.0362da9eebca54d94c8ef5edd3b2e90af99ba452" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.5.0-43.0362da9eebca54d94c8ef5edd3b2e90af99ba452.tgz#5b7fae294ee9bd9790d0e7b7a0b0912e4222ac08" + integrity sha512-o7LyVx8PPJBLrEzLl6lpxxk2D5VnlM4Fwmrbq0NoT6pr5aa1OuHD9ZG+WJY6TlR/iD9bhmo2LNcxddCMr5Rv2A== + +"@prisma/engines@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.5.0.tgz#82df347a893a5ae2a67707d44772ba181f4b9328" + integrity sha512-4t9ir2SbQQr/wMCNU4YpHWp5hU14J2m3wHUZnGJPpmBF8YtkisxyVyQsKd1e6FyLTaGq8LOLhm6VLYHKqKNm+g== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@^4.17.18": + version "4.17.31" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.14": + version "4.17.14" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/node@*", "@types/node@^18.11.9": + version "18.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/serve-static@*": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +express@^4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +nodemon@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.20.tgz#e3537de768a492e8d74da5c5813cb0c7486fc701" + integrity sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prisma@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.5.0.tgz#361ae3f4476d0821b97645e5da42975a7c2943bb" + integrity sha512-9Aeg4qiKlv9Wsjz4NO8k2CzRzlvS3A4FYVJ5+28sBBZ0eEwbiVOE/Jj7v6rZC1tFW2s4GSICQOAyuOjc6WsNew== + dependencies: + "@prisma/engines" "4.5.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +simple-update-notifier@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" + integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== + dependencies: + semver "~7.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== diff --git a/week6/.gitignore b/week6/.gitignore new file mode 100644 index 0000000..11ddd8d --- /dev/null +++ b/week6/.gitignore @@ -0,0 +1,3 @@ +node_modules +# Keep environment variables out of version control +.env diff --git a/week6/nodemon.json b/week6/nodemon.json new file mode 100644 index 0000000..bd415b2 --- /dev/null +++ b/week6/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["src", ".env"], + "ext": "js,ts,json", + "ignore": ["src/**/*.spec.ts"], + "exec": "ts-node --transpile-only ./src/index.ts" +} diff --git a/week6/package.json b/week6/package.json new file mode 100644 index 0000000..a0ad48e --- /dev/null +++ b/week6/package.json @@ -0,0 +1,29 @@ +{ + "name": "seminar4", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "dev": "nodemon", + "build": "tsc && node dist", + "db:pull": "npx prisma db pull", + "db:push": "npx prisma db push", + "generate": "npx prisma generate" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/express": "^4.17.14", + "@types/express-validator": "^3.0.0", + "@types/jsonwebtoken": "^8.5.9", + "@types/node": "^18.11.9", + "nodemon": "^2.0.20" + }, + "dependencies": { + "@prisma/client": "^4.6.1", + "bcryptjs": "^2.4.3", + "express": "^4.18.2", + "express-validator": "^6.14.2", + "jsonwebtoken": "^8.5.1", + "prisma": "^4.6.1" + } +} diff --git a/week6/prisma/schema.prisma b/week6/prisma/schema.prisma new file mode 100644 index 0000000..d6c6ecb --- /dev/null +++ b/week6/prisma/schema.prisma @@ -0,0 +1,16 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + id Int @id(map: "user_pk") @unique(map: "user_id_uindex") @default(autoincrement()) + userName String @db.VarChar(100) + age Int? + email String @db.VarChar(400) + password String @db.VarChar(400) +} diff --git a/week6/src/constants/index.ts b/week6/src/constants/index.ts new file mode 100644 index 0000000..9491b7b --- /dev/null +++ b/week6/src/constants/index.ts @@ -0,0 +1,3 @@ +export { default as rm } from "./responseMessage"; +export { default as sc } from "./statusCode"; +export { default as tokenType } from "./tokenType"; diff --git a/week6/src/constants/response.ts b/week6/src/constants/response.ts new file mode 100644 index 0000000..1441aab --- /dev/null +++ b/week6/src/constants/response.ts @@ -0,0 +1,16 @@ +export const success = (status: number, message: string, data?: any) => { + return { + status, + success: true, + message, + data, + }; +}; + +export const fail = (status: number, message: string) => { + return { + status, + success: false, + message, + }; +}; diff --git a/week6/src/constants/responseMessage.ts b/week6/src/constants/responseMessage.ts new file mode 100644 index 0000000..b27784b --- /dev/null +++ b/week6/src/constants/responseMessage.ts @@ -0,0 +1,33 @@ +export default { + NULL_VALUE: "필요한 값이 없습니다.", + OUT_OF_VALUE: "파라미터 값이 잘못되었습니다.", + NOT_FOUND: "잘못된 경로입니다.", + BAD_REQUEST: "잘못된 요청입니다.", + + // 회원가입 및 로그인 + SIGNUP_SUCCESS: "회원 가입 성공", + SIGNUP_FAIL: "회원 가입 실패", + SIGNIN_SUCCESS: "로그인 성공", + SIGNIN_FAIL: "로그인 실패", + ALREADY_NICKNAME: "이미 사용중인 닉네임입니다.", + INVALID_PASSWORD: "잘못된 비밀번호입니다.", + + // 유저 + READ_USER_SUCCESS: "유저 조회 성공", + READ_ALL_USERS_SUCCESS: "모든 유저 조회 성공", + UPDATE_USER_SUCCESS: "유저 수정 성공", + DELETE_USER_SUCCESS: "유저 탈퇴 성공", + DELETE_USER_FAIL: "유저 탈퇴 실패", + NO_USER: "탈퇴했거나 가입하지 않은 유저입니다.", + + // 토큰 + CREATE_TOKEN_SUCCESS: "토큰 재발급 성공", + EXPIRED_TOKEN: "토큰이 만료되었습니다.", + EXPIRED_ALL_TOKEN: "모든 토큰이 만료되었습니다.", + INVALID_TOKEN: "유효하지 않은 토큰입니다.", + VALID_TOKEN: "유효한 토큰입니다.", + EMPTY_TOKEN: "토큰 값이 없습니다.", + + // 서버 내 오류 + INTERNAL_SERVER_ERROR: "서버 내 오류", +}; diff --git a/week6/src/constants/statusCode.ts b/week6/src/constants/statusCode.ts new file mode 100644 index 0000000..c9f04ce --- /dev/null +++ b/week6/src/constants/statusCode.ts @@ -0,0 +1,15 @@ +export default { + OK: 200, // 목록, 상세, 수정 성공 + CREATED: 201, // POST나 PUT으로 데이터 등록할 경우 사용 + // 어떠한 생성 작업을 요청받아 생성 작업을 성공 + ACCEPTED: 202, // 요청은 받았지만, 아직 동작을 수행하지 않은 상태로 요청이 적절함을 의미한다. + NO_CONTENT: 204, // 요청이 성공은 했지만 응답할 콘텐츠가 없을 경우를 뜻한다. + BAD_REQUEST: 400, // 클라이언트가 올바르지 못한 요청을 보내고 있음을 의미 + UNAUTHORIZED: 401, // 로그인을 하지 않아 권한이 없음. 권한 인증 요구 + FORBIDDEN: 403, // 요청이 서버에 의해 거부 되었음을 의미. 금지된 페이지 + NOT_FOUND: 404, // 요청한 URL을 찾을 수 없음을 의미 + CONFLICT: 409, // 클라이언트 요청에 대해 서버에서 충돌 요소가 발생 할수 있음을 의미 + INTERNAL_SERVER_ERROR: 500, // 서버에 오류가 발생하여 응답 할 수 없음을 의미 + SERVICE_UNAVAILABLE: 503, // 현재 서버가 유지보수 등의 이유로 일시적인 사용 불가함을 의미 + DB_ERROR: 600, +}; diff --git a/week6/src/constants/tokenType.ts b/week6/src/constants/tokenType.ts new file mode 100644 index 0000000..23cde90 --- /dev/null +++ b/week6/src/constants/tokenType.ts @@ -0,0 +1,4 @@ +export default { + TOKEN_EXPIRED: -3, + TOKEN_INVALID: -2, +}; diff --git a/week6/src/controller/index.ts b/week6/src/controller/index.ts new file mode 100644 index 0000000..d2ddc5f --- /dev/null +++ b/week6/src/controller/index.ts @@ -0,0 +1 @@ +export { default as userController } from "./userController"; diff --git a/week6/src/controller/userController.ts b/week6/src/controller/userController.ts new file mode 100644 index 0000000..cd63fe4 --- /dev/null +++ b/week6/src/controller/userController.ts @@ -0,0 +1,135 @@ +import { UserCreateDTO } from "./../../../week4/src/interfaces/UserCreateDTO"; +import { validationResult } from "express-validator"; +import { Request, Response } from "express"; +import { userService } from "../service"; +import { rm, sc } from "../constants"; +import { fail, success } from "../constants/response"; +import jwtHandler from "../modules/jwtHandler"; +import { UserSignInDTO } from "../interfaces/UserSignInDTO"; + +// 유저 생성 +const createUser = async (req: Request, res: Response) => { + // validation의 결과를 바탕으로 분기 처리 + const error = validationResult(req); + if (!error.isEmpty()) { + return res + .status(sc.BAD_REQUEST) + .send(fail(sc.BAD_REQUEST, rm.BAD_REQUEST)); + } + + // 기존 비구조화 할당 방식 -> DTO의 형태 + const UserCreateDto: UserCreateDTO = req.body; + const data = await userService.createUser(UserCreateDto); + + if (!data) { + return res + .status(sc.BAD_REQUEST) + .send(fail(sc.BAD_REQUEST, rm.SIGNUP_FAIL)); + } + + // jwtHandler 내 sign 함수를 이용해 accessToken 생성 + const accessToken = jwtHandler.sign(data.id); + + const result = { + id: data.id, + name: data.userName, + accessToken, + }; + + return res + .status(sc.CREATED) + .send(success(sc.CREATED, rm.SIGNUP_SUCCESS, result)); +}; + +// 로그인 +const signInUser = async (req: Request, res: Response) => { + const error = validationResult(req); + if (!error.isEmpty()) { + return res + .status(sc.BAD_REQUEST) + .send(fail(sc.BAD_REQUEST, rm.BAD_REQUEST)); + } + + const userSignInDto: UserSignInDTO = req.body; + + try { + const userId = await userService.signIn(userSignInDto); + + if (!userId) + return res.status(sc.NOT_FOUND).send(fail(sc.NOT_FOUND, rm.NOT_FOUND)); + else if (userId === sc.UNAUTHORIZED) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.INVALID_PASSWORD)); + + const accessToken = jwtHandler.sign(userId); + + const result = { + id: userId, + accessToken, + }; + + res.status(sc.OK).send(success(sc.OK, rm.SIGNIN_SUCCESS, result)); + } catch (e) { + console.log(error); + // 서버 내부에서 오류 발생 + res + .status(sc.INTERNAL_SERVER_ERROR) + .send(fail(sc.INTERNAL_SERVER_ERROR, rm.INTERNAL_SERVER_ERROR)); + } +}; + +// 유저 전체 조회 +const getAllUser = async (req: Request, res: Response) => { + const data = await userService.getAllUser(); + return res + .status(200) + .json({ status: 200, message: "유저 전체 조회 성공", data }); +}; + +// 유저 정보 업데이트 +const updateUser = async (req: Request, res: Response) => { + const { userName } = req.body; + const { userId } = req.params; + + if (!userName) + return res + .status(400) + .json({ status: 400, message: "유저 업데이트 실패 " }); + + const updatedUser = await userService.updateUser(+userId, userName); // path parameter로 받으면 string이니까 꼼수써주기! + return res + .status(200) + .json({ status: 200, message: "유저 업데이트 성공", updatedUser }); +}; + +// 유저 삭제 +const deleteUser = async (req: Request, res: Response) => { + const { userId } = req.params; + + await userService.deleteUser(+userId); + return res.status(200).json({ status: 200, message: "유저 삭제 성공" }); +}; + +// 특정 유저 조회 +const getUserById = async (req: Request, res: Response) => { + const { userId } = req.params; + + const data = await userService.getUserById(+userId); + + if (!data) { + return res.status(404).json({ status: 404, message: "NOT_FOUND" }); + } + return res.status(200).json({ status: 200, message: "유저 조회 성공", data }); +}; + +const userController = { + createUser, + signInUser, + getAllUser, + updateUser, + deleteUser, + getUserById, +}; + +export default userController; diff --git a/week6/src/index.ts b/week6/src/index.ts new file mode 100644 index 0000000..e7a0809 --- /dev/null +++ b/week6/src/index.ts @@ -0,0 +1,24 @@ +import express, { NextFunction, Request, Response } from "express"; +import router from "./router"; + +const app = express(); // express 객체 받아옴 +const PORT = 3000; // 사용할 port를 3000번으로 설정 + +app.use(express.json()); // express 에서 request body를 json 으로 받아오겠다. + +app.use("/api", router); // use -> 모든 요청 +// localhost:8000/api -> api 폴더 +// localhost:8000/api/user -> user.ts + +//* HTTP method - GET +app.get("/", (req: Request, res: Response, next: NextFunction) => { + res.send("마! 이게 서버다!!!!!!!!!!!!!!!!!!!!"); +}); + +app.listen(PORT, () => { + console.log(` + ############################################# + 🛡️ Server listening on port: ${PORT} 🛡️ + ############################################# + `); +}); // 8000 번 포트에서 서버를 실행하겠다! diff --git a/week6/src/interfaces/UserCreateDTO.ts b/week6/src/interfaces/UserCreateDTO.ts new file mode 100644 index 0000000..17d77c9 --- /dev/null +++ b/week6/src/interfaces/UserCreateDTO.ts @@ -0,0 +1,6 @@ +export interface UserCreateDTO { + name: string; + age: number; + email: string; + password: string; +} diff --git a/week6/src/interfaces/UserSignInDTO.ts b/week6/src/interfaces/UserSignInDTO.ts new file mode 100644 index 0000000..47fde5a --- /dev/null +++ b/week6/src/interfaces/UserSignInDTO.ts @@ -0,0 +1,4 @@ +export interface UserSignInDTO { + email: string; + password: string; +} diff --git a/week6/src/middlewares/auth.ts b/week6/src/middlewares/auth.ts new file mode 100644 index 0000000..dc70d90 --- /dev/null +++ b/week6/src/middlewares/auth.ts @@ -0,0 +1,44 @@ +import { NextFunction, Request, Response } from "express"; +import { JwtPayload } from "jsonwebtoken"; +import { rm, sc } from "../constants"; +import { fail } from "../constants/response"; +import tokenType from "../constants/tokenType"; +import jwtHandler from "../modules/jwtHandler"; + +export default async (req: Request, res: Response, next: NextFunction) => { + const token = req.headers.authorization?.split(" ").reverse()[0]; // Bearer ~~ 에서 토큰만 파싱 + if (!token) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.EMPTY_TOKEN)); + + try { + const decoded = jwtHandler.verify(token); // jwtHandler에서 만들어둔 verify로 토큰 검사 + + // 토큰 에러 분기 처리 + if (decoded === tokenType.TOKEN_EXPIRED) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.EXPIRED_TOKEN)); + if (decoded === tokenType.TOKEN_INVALID) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.INVALID_TOKEN)); + + // decode한 후 담겨있는 userId를 꺼내옴 + const userId: number = (decoded as JwtPayload).userId; + if (!userId) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.VALID_TOKEN)); + + // 얻어낸 userId를 Request Body 내 userId 필드에 담고, 다음 미들웨어로 넘김 ( next() ) + req.body.userId = userId; + next(); + } catch (error) { + console.log(error); + res + .status(sc.INTERNAL_SERVER_ERROR) + .send(fail(sc.INTERNAL_SERVER_ERROR, rm.INTERNAL_SERVER_ERROR)); + } +}; diff --git a/week6/src/middlewares/index.ts b/week6/src/middlewares/index.ts new file mode 100644 index 0000000..0d3b686 --- /dev/null +++ b/week6/src/middlewares/index.ts @@ -0,0 +1 @@ +export { default as auth } from "./auth"; diff --git a/week6/src/modules/jwtHandler.ts b/week6/src/modules/jwtHandler.ts new file mode 100644 index 0000000..564a27b --- /dev/null +++ b/week6/src/modules/jwtHandler.ts @@ -0,0 +1,38 @@ +import jwt from "jsonwebtoken"; +import { tokenType } from "../constants"; + +// 받아온 userId를 담는 access token 생성 +const sign = (userId: number) => { + const payload = { + userId, + }; + + const accessToken = jwt.sign(payload, process.env.JWT_SECRET as string, { + expiresIn: "2h", + }); + return accessToken; +}; + +// token 검사! +const verify = (token: string) => { + let decoded: string | jwt.JwtPayload; + + try { + decoded = jwt.verify(token, process.env.JWT_SECRET as string); + } catch (error: any) { + if (error.message === "jwt expired") { + return tokenType.TOKEN_EXPIRED; + } else if (error.message === "invalid token") { + return tokenType.TOKEN_INVALID; + } else { + return tokenType.TOKEN_INVALID; + } + } + + return decoded; +}; + +export default { + sign, + verify, +}; diff --git a/week6/src/router/index.ts b/week6/src/router/index.ts new file mode 100644 index 0000000..9974b16 --- /dev/null +++ b/week6/src/router/index.ts @@ -0,0 +1,8 @@ +import { Router } from "express"; +import userRouter from "./userRouter"; + +const router: Router = Router(); + +router.use("/user", userRouter); + +export default router; diff --git a/week6/src/router/userRouter.ts b/week6/src/router/userRouter.ts new file mode 100644 index 0000000..2c9a3e9 --- /dev/null +++ b/week6/src/router/userRouter.ts @@ -0,0 +1,42 @@ +import { Router } from "express"; +import { body } from "express-validator"; +import { userController } from "../controller"; +import { auth } from "../middlewares"; + +const router: Router = Router(); + +router.get("/:userId", auth, userController.getUserById); + +// 전체 유저 조회 - GET api/user +router.get("/", userController.getAllUser); + +// 유저 생성 - POST api/user +router.post( + "/", + [ + body("name").notEmpty(), + body("email").notEmpty(), + body("password").isLength({ min: 6 }), + ], + userController.createUser +); + +// 로그인 - POST api/user/signin +router.post( + "/signin", + [ + body("email").notEmpty(), + body("email").isEmail(), + body("password").notEmpty(), + body("password").isLength({ min: 6 }), + ], + userController.signInUser +); + +// 유저 정보 업데이트 - PATCH api/user/:userId +router.patch("/:userId", userController.updateUser); + +// 유저 삭제 - DELETE api/user/:userId +router.delete("/:userId", userController.deleteUser); + +export default router; diff --git a/week6/src/service/index.ts b/week6/src/service/index.ts new file mode 100644 index 0000000..67d995e --- /dev/null +++ b/week6/src/service/index.ts @@ -0,0 +1 @@ +export { default as userService } from "./userService"; diff --git a/week6/src/service/userService.ts b/week6/src/service/userService.ts new file mode 100644 index 0000000..5f04fb3 --- /dev/null +++ b/week6/src/service/userService.ts @@ -0,0 +1,97 @@ +import bcrypt from "bcryptjs"; +import { UserCreateDTO } from "./../../../week4/src/interfaces/UserCreateDTO"; +import { PrismaClient } from "@prisma/client"; +import { UserSignInDTO } from "../interfaces/UserSignInDTO"; +import { sc } from "../constants"; +const prisma = new PrismaClient(); + +// 유저 생성 +const createUser = async (userCreateDto: UserCreateDTO) => { + // 넘겨받은 password를 bcrypt의 도움을 받아 암호화 + const salt = await bcrypt.genSalt(10); // 매우 작은 임의의 랜덤 텍스트 salt + const password = await bcrypt.hash(userCreateDto.password, salt); // 위에서 랜덤을 생성한 salt를 이용해 암호화 + + const data = await prisma.user.create({ + data: { + userName: userCreateDto?.name, + email: userCreateDto.email, + age: userCreateDto?.age, + password, + }, + }); + + return data; +}; + +// 로그인 +const signIn = async (userSignInDto: UserSignInDTO) => { + try { + const user = await prisma.user.findFirst({ + where: { + email: userSignInDto.email, + }, + }); + if (!user) return null; + + //? bcrypt가 DB에 저장된 기존 password와 넘겨 받은 password를 대조하고, + //? match false시 401을 리턴 + const isMatch = await bcrypt.compare(userSignInDto.password, user.password); + if (!isMatch) return sc.UNAUTHORIZED; + + return user.id; + } catch (error) { + console.log(error); + throw error; + } +}; + +// 유저 전체 조회 +const getAllUser = async () => { + const data = await prisma.user.findMany(); + return data; +}; + +// 유저 정보 업데이트 +const updateUser = async (userId: number, userName: string) => { + const data = await prisma.user.update({ + where: { + id: userId, + }, + data: { + userName, + }, + }); + + return data; +}; + +// 유저 삭제 +const deleteUser = async (userId: number) => { + await prisma.user.delete({ + where: { + id: userId, + }, + }); +}; + +//* userId로 유저 조회 +const getUserById = async (userId: number) => { + const user = await prisma.user.findUnique({ + where: { + id: userId, + }, + }); + + return user; +}; + +const userService = { + createUser, + signIn, + getAllUser, + updateUser, + deleteUser, + getUserById, +}; + +export default userService; diff --git a/week6/tsconfig.json b/week6/tsconfig.json new file mode 100644 index 0000000..8075b2f --- /dev/null +++ b/week6/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es6", //? 어떤 버전으로 컴파일 + "allowSyntheticDefaultImports": true, //? default export가 없는 모듈에서 default imports를 허용 + "experimentalDecorators": true, //? decorator 실험적 허용 + "emitDecoratorMetadata": true, //? 데코레이터가 있는 선언에 대해 특정 타입의 메타 데이터를 내보내는 실험적인 지원 + "skipLibCheck": true, //? 정의 파일 타입 체크 여부 + "moduleResolution": "node", //? commonJS -> node 에서 동작 + "module": "commonjs", //? import 문법 + "strict": true, //? 타입 검사 엄격하게 + "pretty": true, //? error 메시지 예쁘게 + "sourceMap": true, //? 소스맵 파일 생성 -> .ts가 .js 파일로 트랜스 시 .js.map 생성 + "outDir": "./dist", //? 트랜스 파일 (.js) 저장 경로 + "allowJs": true, //? js 파일 ts에서 import 허용 + "esModuleInterop": true, //? ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있게 허용 + "typeRoots": [ + "./src/types/express.d.ts", //? 타입(*.d.ts)파일을 가져올 디렉토리 설정 + "./node_modules/@types" //? 설정 안할시 기본적으로 ./node_modules/@types + ] + }, + "include": [ + "./src/**/*" //? build 시 포함 + ], + "exclude": [ + "node_modules", //? build 시 제외 + "tests" + ] +} diff --git a/week6/yarn.lock b/week6/yarn.lock new file mode 100644 index 0000000..d7added --- /dev/null +++ b/week6/yarn.lock @@ -0,0 +1,826 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@prisma/client@^4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.6.1.tgz#e8e1d347ecbff44158d21b6591bb99650c8503a8" + integrity sha512-M1+NNrMzqaOIxT7PBGcTs3IZo7d1EW/+gVQd4C4gUgWBDGgD9AcIeZnUSidgWClmpMSgVUdnVORjsWWGUameYA== + dependencies: + "@prisma/engines-version" "4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32" + +"@prisma/engines-version@4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32": + version "4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32.tgz#90a71bbdfd5172fc674009346a6ad6b84410cc0a" + integrity sha512-HUCmkXAU2jqp2O1RvNtbE+seLGLyJGEABZS/R38rZjSAafAy0WzBuHq+tbZMnD+b5OSCsTVtIPVcuvx1ySxcWQ== + +"@prisma/engines@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.6.1.tgz#ae31309cc0f600f2da22708697b3be4eb1e46f9e" + integrity sha512-3u2/XxvxB+Q7cMXHnKU0CpBiUK1QWqpgiBv28YDo1zOIJE3FCF8DI2vrp6vuwjGt5h0JGXDSvmSf4D4maVjJdw== + +"@types/bcryptjs@^2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae" + integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@^4.17.18": + version "4.17.31" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express-validator@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/express-validator/-/express-validator-3.0.0.tgz#e6f3cab842e5ae376a1cfa11295202ec380b68d1" + integrity sha512-LusnB0YhTXpBT25PXyGPQlK7leE1e41Vezq1hHEUwjfkopM1Pkv2X2Ppxqh9c+w/HZ6Udzki8AJotKNjDTGdkQ== + dependencies: + express-validator "*" + +"@types/express@^4.17.14": + version "4.17.14" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/jsonwebtoken@^8.5.9": + version "8.5.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586" + integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg== + dependencies: + "@types/node" "*" + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/node@*", "@types/node@^18.11.9": + version "18.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/serve-static@*": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +express-validator@*, express-validator@^6.14.2: + version "6.14.2" + resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-6.14.2.tgz#6147893f7bec0e14162c3a88b3653121afc4678f" + integrity sha512-8XfAUrQ6Y7dIIuy9KcUPCfG/uCbvREctrxf5EeeME+ulanJ4iiW71lWmm9r4YcKKYOCBMan0WpVg7FtHu4Z4Wg== + dependencies: + lodash "^4.17.21" + validator "^13.7.0" + +express@^4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +nodemon@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.20.tgz#e3537de768a492e8d74da5c5813cb0c7486fc701" + integrity sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prisma@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.6.1.tgz#6c85fb667abed006a6b849c9c1ddd81d3f071b87" + integrity sha512-BR4itMCuzrDV4tn3e2TF+nh1zIX/RVU0isKtKoN28ADeoJ9nYaMhiuRRkFd2TZN8+l/XfYzoRKyHzUFXLQhmBQ== + dependencies: + "@prisma/engines" "4.6.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +safe-buffer@5.2.1, safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.6.0, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +simple-update-notifier@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" + integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== + dependencies: + semver "~7.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== diff --git a/week7/.gitignore b/week7/.gitignore new file mode 100644 index 0000000..11ddd8d --- /dev/null +++ b/week7/.gitignore @@ -0,0 +1,3 @@ +node_modules +# Keep environment variables out of version control +.env diff --git a/week7/nodemon.json b/week7/nodemon.json new file mode 100644 index 0000000..bd415b2 --- /dev/null +++ b/week7/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["src", ".env"], + "ext": "js,ts,json", + "ignore": ["src/**/*.spec.ts"], + "exec": "ts-node --transpile-only ./src/index.ts" +} diff --git a/week7/package.json b/week7/package.json new file mode 100644 index 0000000..fdb1c88 --- /dev/null +++ b/week7/package.json @@ -0,0 +1,35 @@ +{ + "name": "seminar4", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "dev": "nodemon", + "build": "tsc && node dist", + "db:pull": "npx prisma db pull", + "db:push": "npx prisma db push", + "generate": "npx prisma generate" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/express": "^4.17.14", + "@types/express-validator": "^3.0.0", + "@types/jsonwebtoken": "^8.5.9", + "@types/multer": "^1.4.7", + "@types/multer-s3": "^3.0.0", + "@types/node": "^18.11.9", + "nodemon": "^2.0.20" + }, + "dependencies": { + "@aws-sdk/client-s3": "^3.222.0", + "@prisma/client": "^4.6.1", + "bcryptjs": "^2.4.3", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "express-validator": "^6.14.2", + "jsonwebtoken": "^8.5.1", + "multer": "^1.4.5-lts.1", + "multer-s3": "^3.0.1", + "prisma": "^4.6.1" + } +} diff --git a/week7/prisma/schema.prisma b/week7/prisma/schema.prisma new file mode 100644 index 0000000..c7663a2 --- /dev/null +++ b/week7/prisma/schema.prisma @@ -0,0 +1,27 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model User { + user_id Int @id @unique @default(autoincrement()) + age Int? + email String? @db.VarChar(40) + password String? @db.VarChar(40) + gender String? + birth DateTime? @db.Date + userName String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Image { + id Int @id @default(autoincrement()) + image String? @db.VarChar(800) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/week7/src/config/index.ts b/week7/src/config/index.ts new file mode 100644 index 0000000..b7787e4 --- /dev/null +++ b/week7/src/config/index.ts @@ -0,0 +1,28 @@ +import dotenv from "dotenv"; + +// Set the NODE_ENV to 'development' by default +process.env.NODE_ENV = process.env.NODE_ENV || "development"; + +const envFound = dotenv.config(); + +if (envFound.error) { + throw new Error("⚠️ Couldn't find .env file ⚠️"); +} + +export default { + port: parseInt(process.env.PORT as string, 10) as number, + + // 데이터베이스 + database: process.env.DATABASE_URL as string, + + // JWT + jwtSecret: process.env.JWT_SECRET as string, + jwtAlgo: process.env.JWT_ALGO as string, + + // AWS + s3AccessKey: process.env.S3_ACCESS_KEY as string, + s3SecretKey: process.env.S3_SECRET_KEY as string, + bucketName: process.env.S3_BUCKET as string, + +} + diff --git a/week7/src/config/s3Config.ts b/week7/src/config/s3Config.ts new file mode 100644 index 0000000..4f68a78 --- /dev/null +++ b/week7/src/config/s3Config.ts @@ -0,0 +1,12 @@ +import { S3Client } from "@aws-sdk/client-s3"; +import config from "."; + +const s3: S3Client = new S3Client({ + region: "ap-northeast-2", + credentials: { + accessKeyId: config.s3AccessKey, + secretAccessKey: config.s3SecretKey, + }, +}); + +export default s3; \ No newline at end of file diff --git a/week7/src/constants/index.ts b/week7/src/constants/index.ts new file mode 100644 index 0000000..9491b7b --- /dev/null +++ b/week7/src/constants/index.ts @@ -0,0 +1,3 @@ +export { default as rm } from "./responseMessage"; +export { default as sc } from "./statusCode"; +export { default as tokenType } from "./tokenType"; diff --git a/week7/src/constants/response.ts b/week7/src/constants/response.ts new file mode 100644 index 0000000..1441aab --- /dev/null +++ b/week7/src/constants/response.ts @@ -0,0 +1,16 @@ +export const success = (status: number, message: string, data?: any) => { + return { + status, + success: true, + message, + data, + }; +}; + +export const fail = (status: number, message: string) => { + return { + status, + success: false, + message, + }; +}; diff --git a/week7/src/constants/responseMessage.ts b/week7/src/constants/responseMessage.ts new file mode 100644 index 0000000..efd9bd2 --- /dev/null +++ b/week7/src/constants/responseMessage.ts @@ -0,0 +1,40 @@ +export default { + NULL_VALUE: "필요한 값이 없습니다.", + OUT_OF_VALUE: "파라미터 값이 잘못되었습니다.", + NOT_FOUND: "잘못된 경로입니다.", + BAD_REQUEST: "잘못된 요청입니다.", + + // 회원가입 및 로그인 + SIGNUP_SUCCESS: "회원 가입 성공", + SIGNUP_FAIL: "회원 가입 실패", + SIGNIN_SUCCESS: "로그인 성공", + SIGNIN_FAIL: "로그인 실패", + ALREADY_NICKNAME: "이미 사용중인 닉네임입니다.", + INVALID_PASSWORD: "잘못된 비밀번호입니다.", + + // 유저 + READ_USER_SUCCESS: "유저 조회 성공", + READ_ALL_USERS_SUCCESS: "모든 유저 조회 성공", + UPDATE_USER_SUCCESS: "유저 수정 성공", + DELETE_USER_SUCCESS: "유저 탈퇴 성공", + DELETE_USER_FAIL: "유저 탈퇴 실패", + NO_USER: "탈퇴했거나 가입하지 않은 유저입니다.", + SEARCH_USER_SUCCESS: "유저 검색 성공", + SEARCH_USER_FAIL: "유저 검색 실패", + + // 이미지 + NO_IMAGE: "이미지가 없습니다.", + CREATE_IMAGE_SUCCESS: "이미지 저장 성공", + CREATE_IMAGE_FAIL: "이미지 저장 실패", + + // 토큰 + CREATE_TOKEN_SUCCESS: "토큰 재발급 성공", + EXPIRED_TOKEN: "토큰이 만료되었습니다.", + EXPIRED_ALL_TOKEN: "모든 토큰이 만료되었습니다.", + INVALID_TOKEN: "유효하지 않은 토큰입니다.", + VALID_TOKEN: "유효한 토큰입니다.", + EMPTY_TOKEN: "토큰 값이 없습니다.", + + // 서버 내 오류 + INTERNAL_SERVER_ERROR: "서버 내 오류", +}; diff --git a/week7/src/constants/statusCode.ts b/week7/src/constants/statusCode.ts new file mode 100644 index 0000000..c9f04ce --- /dev/null +++ b/week7/src/constants/statusCode.ts @@ -0,0 +1,15 @@ +export default { + OK: 200, // 목록, 상세, 수정 성공 + CREATED: 201, // POST나 PUT으로 데이터 등록할 경우 사용 + // 어떠한 생성 작업을 요청받아 생성 작업을 성공 + ACCEPTED: 202, // 요청은 받았지만, 아직 동작을 수행하지 않은 상태로 요청이 적절함을 의미한다. + NO_CONTENT: 204, // 요청이 성공은 했지만 응답할 콘텐츠가 없을 경우를 뜻한다. + BAD_REQUEST: 400, // 클라이언트가 올바르지 못한 요청을 보내고 있음을 의미 + UNAUTHORIZED: 401, // 로그인을 하지 않아 권한이 없음. 권한 인증 요구 + FORBIDDEN: 403, // 요청이 서버에 의해 거부 되었음을 의미. 금지된 페이지 + NOT_FOUND: 404, // 요청한 URL을 찾을 수 없음을 의미 + CONFLICT: 409, // 클라이언트 요청에 대해 서버에서 충돌 요소가 발생 할수 있음을 의미 + INTERNAL_SERVER_ERROR: 500, // 서버에 오류가 발생하여 응답 할 수 없음을 의미 + SERVICE_UNAVAILABLE: 503, // 현재 서버가 유지보수 등의 이유로 일시적인 사용 불가함을 의미 + DB_ERROR: 600, +}; diff --git a/week7/src/constants/tokenType.ts b/week7/src/constants/tokenType.ts new file mode 100644 index 0000000..23cde90 --- /dev/null +++ b/week7/src/constants/tokenType.ts @@ -0,0 +1,4 @@ +export default { + TOKEN_EXPIRED: -3, + TOKEN_INVALID: -2, +}; diff --git a/week7/src/controller/imageController.ts b/week7/src/controller/imageController.ts new file mode 100644 index 0000000..8de830f --- /dev/null +++ b/week7/src/controller/imageController.ts @@ -0,0 +1,31 @@ +import { Request, Response } from "express"; +import { rm, sc } from "../constants"; +import { fail, success } from "../constants/response"; +import { imageService } from "../service"; + +// 이미지 업로드 API +const uploadImage = async (req: Request, res: Response) => { + // Express에서 지원하는 타입 + const image: Express.MulterS3.File = req.file as Express.MulterS3.File; + const { location } = image; + + if (!location) { + res.status(sc.BAD_REQUEST).send(fail(sc.BAD_REQUEST, rm.NO_IMAGE)); + } + + // 이미지만 전송받을 것이니 이 file을 imageService로 그대로 던져줌 + const data = await imageService.uploadImage(location); + + if (!data) { + res.status(sc.BAD_REQUEST).send(fail(sc.CREATED, rm.CREATE_IMAGE_FAIL)); + } + return res + .status(sc.CREATED) + .send(success(sc.CREATED, rm.CREATE_IMAGE_SUCCESS, data)); +}; + +const imageController = { + uploadImage, +}; + +export default imageController; diff --git a/week7/src/controller/index.ts b/week7/src/controller/index.ts new file mode 100644 index 0000000..ab9f8d5 --- /dev/null +++ b/week7/src/controller/index.ts @@ -0,0 +1,2 @@ +export { default as userController } from "./userController"; +export { default as imageController } from "./imageController"; diff --git a/week7/src/controller/userController.ts b/week7/src/controller/userController.ts new file mode 100644 index 0000000..d09e8cc --- /dev/null +++ b/week7/src/controller/userController.ts @@ -0,0 +1,149 @@ +import { UserCreateDTO } from "./../../../week4/src/interfaces/UserCreateDTO"; +import { validationResult } from "express-validator"; +import { Request, Response } from "express"; +import { userService } from "../service"; +import { rm, sc } from "../constants"; +import { fail, success } from "../constants/response"; +import jwtHandler from "../modules/jwtHandler"; +import { UserSignInDTO } from "../interfaces/UserSignInDTO"; + +// 유저 생성 +const createUser = async (req: Request, res: Response) => { + // validation의 결과를 바탕으로 분기 처리 + const error = validationResult(req); + if (!error.isEmpty()) { + return res + .status(sc.BAD_REQUEST) + .send(fail(sc.BAD_REQUEST, rm.BAD_REQUEST)); + } + + // 기존 비구조화 할당 방식 -> DTO의 형태 + const UserCreateDto: UserCreateDTO = req.body; + const data = await userService.createUser(UserCreateDto); + + if (!data) { + return res + .status(sc.BAD_REQUEST) + .send(fail(sc.BAD_REQUEST, rm.SIGNUP_FAIL)); + } + + // jwtHandler 내 sign 함수를 이용해 accessToken 생성 + const accessToken = jwtHandler.sign(data.id); + + const result = { + id: data.id, + name: data.userName, + accessToken, + }; + + return res + .status(sc.CREATED) + .send(success(sc.CREATED, rm.SIGNUP_SUCCESS, result)); +}; + +// 로그인 +const signInUser = async (req: Request, res: Response) => { + const error = validationResult(req); + if (!error.isEmpty()) { + return res + .status(sc.BAD_REQUEST) + .send(fail(sc.BAD_REQUEST, rm.BAD_REQUEST)); + } + + const userSignInDto: UserSignInDTO = req.body; + + try { + const userId = await userService.signIn(userSignInDto); + + if (!userId) + return res.status(sc.NOT_FOUND).send(fail(sc.NOT_FOUND, rm.NOT_FOUND)); + else if (userId === sc.UNAUTHORIZED) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.INVALID_PASSWORD)); + + const accessToken = jwtHandler.sign(userId); + + const result = { + id: userId, + accessToken, + }; + + res.status(sc.OK).send(success(sc.OK, rm.SIGNIN_SUCCESS, result)); + } catch (e) { + console.log(error); + // 서버 내부에서 오류 발생 + res + .status(sc.INTERNAL_SERVER_ERROR) + .send(fail(sc.INTERNAL_SERVER_ERROR, rm.INTERNAL_SERVER_ERROR)); + } +}; + +// 유저 전체 조회 +const getAllUser = async (req: Request, res: Response) => { + const { page, limit } = req.query; + const data = await userService.getAllUser(Number(page), Number(limit)); + return res + .status(200) + .json({ status: 200, message: "유저 전체 조회 성공", data }); +}; + +// 유저 정보 업데이트 +const updateUser = async (req: Request, res: Response) => { + const { userName } = req.body; + const { userId } = req.params; + + if (!userName) + return res + .status(400) + .json({ status: 400, message: "유저 업데이트 실패 " }); + + const updatedUser = await userService.updateUser(+userId, userName); // path parameter로 받으면 string이니까 꼼수써주기! + return res + .status(200) + .json({ status: 200, message: "유저 업데이트 성공", updatedUser }); +}; + +// 유저 삭제 +const deleteUser = async (req: Request, res: Response) => { + const { userId } = req.params; + + await userService.deleteUser(+userId); + return res.status(200).json({ status: 200, message: "유저 삭제 성공" }); +}; + +// 특정 유저 조회 +const getUserById = async (req: Request, res: Response) => { + const { userId } = req.params; + + const data = await userService.getUserById(+userId); + + if (!data) { + return res.status(404).json({ status: 404, message: "NOT_FOUND" }); + } + return res.status(200).json({ status: 200, message: "유저 조회 성공", data }); +}; + +// GET ~/api/user?keyword=한빛 +const searchUserByName = async (req: Request, res: Response) => { + const { keyword, option } = req.query; // 한빛 + + const data = await userService.searchUserByName(keyword as string, option); + + if (!data) { + return res.status(sc.BAD_REQUEST).send(fail(sc.BAD_REQUEST, rm.SEARCH_USER_FAIL)) + } + return res.status(sc.OK).send(success(sc.OK, rm.SEARCH_USER_SUCCESS, data)); +}; + +const userController = { + createUser, + signInUser, + getAllUser, + updateUser, + deleteUser, + getUserById, + searchUserByName, +}; + +export default userController; diff --git a/week7/src/index.ts b/week7/src/index.ts new file mode 100644 index 0000000..e7a0809 --- /dev/null +++ b/week7/src/index.ts @@ -0,0 +1,24 @@ +import express, { NextFunction, Request, Response } from "express"; +import router from "./router"; + +const app = express(); // express 객체 받아옴 +const PORT = 3000; // 사용할 port를 3000번으로 설정 + +app.use(express.json()); // express 에서 request body를 json 으로 받아오겠다. + +app.use("/api", router); // use -> 모든 요청 +// localhost:8000/api -> api 폴더 +// localhost:8000/api/user -> user.ts + +//* HTTP method - GET +app.get("/", (req: Request, res: Response, next: NextFunction) => { + res.send("마! 이게 서버다!!!!!!!!!!!!!!!!!!!!"); +}); + +app.listen(PORT, () => { + console.log(` + ############################################# + 🛡️ Server listening on port: ${PORT} 🛡️ + ############################################# + `); +}); // 8000 번 포트에서 서버를 실행하겠다! diff --git a/week7/src/interfaces/UserCreateDTO.ts b/week7/src/interfaces/UserCreateDTO.ts new file mode 100644 index 0000000..17d77c9 --- /dev/null +++ b/week7/src/interfaces/UserCreateDTO.ts @@ -0,0 +1,6 @@ +export interface UserCreateDTO { + name: string; + age: number; + email: string; + password: string; +} diff --git a/week7/src/interfaces/UserSignInDTO.ts b/week7/src/interfaces/UserSignInDTO.ts new file mode 100644 index 0000000..47fde5a --- /dev/null +++ b/week7/src/interfaces/UserSignInDTO.ts @@ -0,0 +1,4 @@ +export interface UserSignInDTO { + email: string; + password: string; +} diff --git a/week7/src/interfaces/image/ImageCreateResponseDTO.ts b/week7/src/interfaces/image/ImageCreateResponseDTO.ts new file mode 100644 index 0000000..afd4fca --- /dev/null +++ b/week7/src/interfaces/image/ImageCreateResponseDTO.ts @@ -0,0 +1,4 @@ +export interface ImageCreateResponseDTO{ + id: number; + image: string; +}; \ No newline at end of file diff --git a/week7/src/middlewares/auth.ts b/week7/src/middlewares/auth.ts new file mode 100644 index 0000000..dc70d90 --- /dev/null +++ b/week7/src/middlewares/auth.ts @@ -0,0 +1,44 @@ +import { NextFunction, Request, Response } from "express"; +import { JwtPayload } from "jsonwebtoken"; +import { rm, sc } from "../constants"; +import { fail } from "../constants/response"; +import tokenType from "../constants/tokenType"; +import jwtHandler from "../modules/jwtHandler"; + +export default async (req: Request, res: Response, next: NextFunction) => { + const token = req.headers.authorization?.split(" ").reverse()[0]; // Bearer ~~ 에서 토큰만 파싱 + if (!token) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.EMPTY_TOKEN)); + + try { + const decoded = jwtHandler.verify(token); // jwtHandler에서 만들어둔 verify로 토큰 검사 + + // 토큰 에러 분기 처리 + if (decoded === tokenType.TOKEN_EXPIRED) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.EXPIRED_TOKEN)); + if (decoded === tokenType.TOKEN_INVALID) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.INVALID_TOKEN)); + + // decode한 후 담겨있는 userId를 꺼내옴 + const userId: number = (decoded as JwtPayload).userId; + if (!userId) + return res + .status(sc.UNAUTHORIZED) + .send(fail(sc.UNAUTHORIZED, rm.VALID_TOKEN)); + + // 얻어낸 userId를 Request Body 내 userId 필드에 담고, 다음 미들웨어로 넘김 ( next() ) + req.body.userId = userId; + next(); + } catch (error) { + console.log(error); + res + .status(sc.INTERNAL_SERVER_ERROR) + .send(fail(sc.INTERNAL_SERVER_ERROR, rm.INTERNAL_SERVER_ERROR)); + } +}; diff --git a/week7/src/middlewares/index.ts b/week7/src/middlewares/index.ts new file mode 100644 index 0000000..e0204a5 --- /dev/null +++ b/week7/src/middlewares/index.ts @@ -0,0 +1,2 @@ +export { default as auth } from "./auth"; +export { ad, default, upload } from "./upload"; \ No newline at end of file diff --git a/week7/src/middlewares/upload.ts b/week7/src/middlewares/upload.ts new file mode 100644 index 0000000..ce10e1a --- /dev/null +++ b/week7/src/middlewares/upload.ts @@ -0,0 +1,22 @@ +import multer from "multer"; +import multerS3 from "multer-s3"; +import config from "../config"; +import s3 from "../config/s3Config"; + +//? 미들웨어로 사용할 multer 모듈 +const upload = multer({ + //? 실질적인 storage 는 multerS3 이용해 aws s3 로 설정 + storage: multerS3({ + s3: s3, + bucket: config.bucketName, //? s3 bucket name 지정 + contentType: multerS3.AUTO_CONTENT_TYPE, //? mimetype 은 자동으로 설정 + acl: "public-read", // Access control for the file + + //? key는 파일 이름을 지정. 버킷 내 같은 이름의 파일은 같은 파일로 인식하기 때문에 Unique하도록! + key: function (req: Express.Request, file: Express.MulterS3.File, cb) { + cb(null, `${Date.now()}_${file.originalname}`); + }, + }), +}); + +export default upload; diff --git a/week7/src/modules/jwtHandler.ts b/week7/src/modules/jwtHandler.ts new file mode 100644 index 0000000..564a27b --- /dev/null +++ b/week7/src/modules/jwtHandler.ts @@ -0,0 +1,38 @@ +import jwt from "jsonwebtoken"; +import { tokenType } from "../constants"; + +// 받아온 userId를 담는 access token 생성 +const sign = (userId: number) => { + const payload = { + userId, + }; + + const accessToken = jwt.sign(payload, process.env.JWT_SECRET as string, { + expiresIn: "2h", + }); + return accessToken; +}; + +// token 검사! +const verify = (token: string) => { + let decoded: string | jwt.JwtPayload; + + try { + decoded = jwt.verify(token, process.env.JWT_SECRET as string); + } catch (error: any) { + if (error.message === "jwt expired") { + return tokenType.TOKEN_EXPIRED; + } else if (error.message === "invalid token") { + return tokenType.TOKEN_INVALID; + } else { + return tokenType.TOKEN_INVALID; + } + } + + return decoded; +}; + +export default { + sign, + verify, +}; diff --git a/week7/src/router/imageRouter.ts b/week7/src/router/imageRouter.ts new file mode 100644 index 0000000..097624a --- /dev/null +++ b/week7/src/router/imageRouter.ts @@ -0,0 +1,10 @@ +import { Router } from "express"; +import { imageController } from "../controller"; +import { upload } from "../middlewares"; + +const router: Router = Router(); + +// 단일 파일 가져올 때 single +router.post("/", upload.single("file"), imageController.uploadImage); + +export default router; diff --git a/week7/src/router/index.ts b/week7/src/router/index.ts new file mode 100644 index 0000000..1ff2894 --- /dev/null +++ b/week7/src/router/index.ts @@ -0,0 +1,11 @@ +import { Router } from "express"; +import userRouter from "./userRouter"; +import imageRouter from "./imageRouter" + +const router: Router = Router(); + +router.use("/user", userRouter); +router.use("/image", imageRouter); + + +export default router; diff --git a/week7/src/router/userRouter.ts b/week7/src/router/userRouter.ts new file mode 100644 index 0000000..4682d81 --- /dev/null +++ b/week7/src/router/userRouter.ts @@ -0,0 +1,45 @@ +import { Router } from "express"; +import { body } from "express-validator"; +import { userController } from "../controller"; +import { auth } from "../middlewares"; + +const router: Router = Router(); + +router.get("/:userId", auth, userController.getUserById); + +//* 로그인 - POST api/user/signin +router.post( + "/signin", + [ + body("email").notEmpty(), + body("email").isEmail(), + body("password").notEmpty(), + body("password").isLength({ min: 6 }), + ], + userController.signInUser +); + +//* 유저 생성 - POST api/user +router.post( + "/", + [ + body("name").notEmpty(), + body("email").notEmpty(), + body("password").isLength({ min: 6 }), + ], + userController.createUser +); + +// 전체 유저 조회 - GET api/user +router.get("/", userController.getAllUser); + +// 유저 정보 업데이트 - PATCH api/user/:userId +router.patch("/:userId", userController.updateUser); + +// 유저 삭제 - DELETE api/user/:userId +router.delete("/:userId", userController.deleteUser); + +// 이름으로 유저 검색 - GET api/user/search?keyword={}&option={} +router.get("/search", userController.searchUserByName); + +export default router; diff --git a/week7/src/service/imageService.ts b/week7/src/service/imageService.ts new file mode 100644 index 0000000..b45dd73 --- /dev/null +++ b/week7/src/service/imageService.ts @@ -0,0 +1,26 @@ +import { ImageCreateResponseDTO } from "./../interfaces/image/ImageCreateResponseDTO"; +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +// 이미지 업로드 +const uploadImage = async (location: string): Promise => { + const data = await prisma.image.create({ + data: { + image: location, + }, + }); + + const result: ImageCreateResponseDTO = { + id: data.id, + image: data.image as string, + }; + + return result; +}; + +const imageService = { + uploadImage, +}; + +export default imageService; diff --git a/week7/src/service/index.ts b/week7/src/service/index.ts new file mode 100644 index 0000000..ba3cb1e --- /dev/null +++ b/week7/src/service/index.ts @@ -0,0 +1,2 @@ +export { default as userService } from "./userService"; +export { default as imageService } from "./imageService"; diff --git a/week7/src/service/userService.ts b/week7/src/service/userService.ts new file mode 100644 index 0000000..8ccc762 --- /dev/null +++ b/week7/src/service/userService.ts @@ -0,0 +1,154 @@ +import { PrismaClient } from "@prisma/client"; +import bcrypt from "bcryptjs"; +import { sc } from "../constants"; +import { UserCreateDTO } from "../interfaces/UserCreateDTO"; +import { UserSignInDTO } from "../interfaces/UserSignInDTO"; + +const prisma = new PrismaClient(); + +//* 로그인 +const signIn = async (userSignInDto: UserSignInDTO) => { + try { + const user = await prisma.user.findFirst({ + where: { + email: userSignInDto.email, + }, + }); + if (!user) return null; + + //? bcrypt가 DB에 저장된 기존 password와 넘겨 받은 password를 대조하고, + //? match false시 401을 리턴 + const isMatch = await bcrypt.compare(userSignInDto.password, user.password); + if (!isMatch) return sc.UNAUTHORIZED; + + return user.user_id; + } catch (error) { + console.log(error); + throw error; + } +}; + +// 유저 생성 +const createUser = async (userCreateDto: UserCreateDTO) => { + //? 넘겨받은 password를 bcrypt의 도움을 받아 암호화 + const salt = await bcrypt.genSalt(10); //^ 매우 작은 임의의 랜덤 텍스트 salt + const password = await bcrypt.hash(userCreateDto.password, salt); //^ 위에서 랜덤을 생성한 salt를 이용해 암호화 + + const data = await prisma.user.create({ + data: { + userName: userCreateDto?.name, + age: userCreateDto?.age, + email: userCreateDto.email, + password, + }, + }); + + return data; +}; + +// 유저 전체 조회 +const getAllUser = async (page: number, limit: number) => { + const data = await prisma.user.findMany({ + skip: (page - 1) * limit, // 얼마나 건너뛸지 설정 가능 + take: limit, + }); + + return data; +}; + +// 유저 정보 업데이트 +const updateUser = async (userId: number, name: string) => { + const data = await prisma.user.update({ + where: { + // 어디를 (??) + user_id: userId, // 내가 마음대로 정한 userId라는 이름으로 받은 값을 DB의 id 필드에 담는다. + }, + data: { + // 어떻게 바꿀건지 (??맞나..) + userName: name, + }, + }); +}; + +// 유저 삭제 +const deleteUser = async (userId: number) => { + await prisma.user.delete({ + where: { + user_id: userId, + }, + }); +}; + +//* userId로 유저 조회 +const getUserById = async (userId: number) => { + const user = await prisma.user.findUnique({ + // id는 PK -> unique + where: { + user_id: userId, // where : 일종의 필터. 조건. id가 userId인 경우만 조회 + }, + }); + + return user; +}; + +// 이름으로 유저 조회 ( query ) +const searchUserByName = async (keyword: string, option: string) => { + // 유저 최신순 + if (option === "desc") { + const data = await prisma.user.findMany({ + where: { + userName: { + contains: keyword, + }, + }, + orderBy: { + createdAt: "desc", + }, + }); + + return data; + } else if (option == "asc") { + // 유저 오래된 순 + const data = await prisma.user.findMany({ + where: { + userName: { + contains: keyword, + }, + }, + orderBy: { + createdAt: "asc", + }, + }); + return data; + } else if (option === "nameDesc") { + // 이름 알파벳으로 정렬 + const data = await prisma.user.findMany({ + where: { + userName: { + contains: keyword, + }, + }, + orderBy: { + userName: "desc", + }, + }); + return data; + } +}; + +// 이름 + 옵션으로 유저 조회 ( query ) + + +// 조회 시 페이지네이션 + +const userService = { + signIn, + createUser, + getAllUser, + updateUser, + deleteUser, + getUserById, + searchUserByName +}; + +export default userService; diff --git a/week7/tsconfig.json b/week7/tsconfig.json new file mode 100644 index 0000000..8075b2f --- /dev/null +++ b/week7/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es6", //? 어떤 버전으로 컴파일 + "allowSyntheticDefaultImports": true, //? default export가 없는 모듈에서 default imports를 허용 + "experimentalDecorators": true, //? decorator 실험적 허용 + "emitDecoratorMetadata": true, //? 데코레이터가 있는 선언에 대해 특정 타입의 메타 데이터를 내보내는 실험적인 지원 + "skipLibCheck": true, //? 정의 파일 타입 체크 여부 + "moduleResolution": "node", //? commonJS -> node 에서 동작 + "module": "commonjs", //? import 문법 + "strict": true, //? 타입 검사 엄격하게 + "pretty": true, //? error 메시지 예쁘게 + "sourceMap": true, //? 소스맵 파일 생성 -> .ts가 .js 파일로 트랜스 시 .js.map 생성 + "outDir": "./dist", //? 트랜스 파일 (.js) 저장 경로 + "allowJs": true, //? js 파일 ts에서 import 허용 + "esModuleInterop": true, //? ES6 모듈 사양을 준수하여 CommonJS 모듈을 가져올 수 있게 허용 + "typeRoots": [ + "./src/types/express.d.ts", //? 타입(*.d.ts)파일을 가져올 디렉토리 설정 + "./node_modules/@types" //? 설정 안할시 기본적으로 ./node_modules/@types + ] + }, + "include": [ + "./src/**/*" //? build 시 포함 + ], + "exclude": [ + "node_modules", //? build 시 제외 + "tests" + ] +} diff --git a/week7/yarn.lock b/week7/yarn.lock new file mode 100644 index 0000000..bbee89a --- /dev/null +++ b/week7/yarn.lock @@ -0,0 +1,2049 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aws-crypto/crc32@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-2.0.0.tgz#4ad432a3c03ec3087c5540ff6e41e6565d2dc153" + integrity sha512-TvE1r2CUueyXOuHdEigYjIZVesInd9KN+K/TFFNfkkxRThiNxO6i4ZqqAVMoEjAamZZ1AA8WXJkjCz7YShHPQA== + dependencies: + "@aws-crypto/util" "^2.0.0" + "@aws-sdk/types" "^3.1.0" + tslib "^1.11.1" + +"@aws-crypto/crc32c@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32c/-/crc32c-2.0.0.tgz#4235336ef78f169f6a05248906703b9b78da676e" + integrity sha512-vF0eMdMHx3O3MoOXUfBZry8Y4ZDtcuskjjKgJz8YfIDjLStxTZrYXk+kZqtl6A0uCmmiN/Eb/JbC/CndTV1MHg== + dependencies: + "@aws-crypto/util" "^2.0.0" + "@aws-sdk/types" "^3.1.0" + tslib "^1.11.1" + +"@aws-crypto/ie11-detection@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz#9c39f4a5558196636031a933ec1b4792de959d6a" + integrity sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/sha1-browser@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha1-browser/-/sha1-browser-2.0.0.tgz#71e735df20ea1d38f59259c4b1a2e00ca74a0eea" + integrity sha512-3fIVRjPFY8EG5HWXR+ZJZMdWNRpwbxGzJ9IH9q93FpbgCH8u8GHRi46mZXp3cYD7gealmyqpm3ThZwLKJjWJhA== + dependencies: + "@aws-crypto/ie11-detection" "^2.0.0" + "@aws-crypto/supports-web-crypto" "^2.0.0" + "@aws-sdk/types" "^3.1.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-browser@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz#741c9024df55ec59b51e5b1f5d806a4852699fb5" + integrity sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A== + dependencies: + "@aws-crypto/ie11-detection" "^2.0.0" + "@aws-crypto/sha256-js" "^2.0.0" + "@aws-crypto/supports-web-crypto" "^2.0.0" + "@aws-crypto/util" "^2.0.0" + "@aws-sdk/types" "^3.1.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-js@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz#f1f936039bdebd0b9e2dd834d65afdc2aac4efcb" + integrity sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig== + dependencies: + "@aws-crypto/util" "^2.0.0" + "@aws-sdk/types" "^3.1.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-js@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-2.0.2.tgz#c81e5d378b8a74ff1671b58632779986e50f4c99" + integrity sha512-iXLdKH19qPmIC73fVCrHWCSYjN/sxaAvZ3jNNyw6FclmHyjLKg0f69WlC9KTnyElxCR5MO9SKaG00VwlJwyAkQ== + dependencies: + "@aws-crypto/util" "^2.0.2" + "@aws-sdk/types" "^3.110.0" + tslib "^1.11.1" + +"@aws-crypto/supports-web-crypto@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz#9f02aafad8789cac9c0ab5faaebb1ab8aa841338" + integrity sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/util@^2.0.0", "@aws-crypto/util@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-2.0.2.tgz#adf5ff5dfbc7713082f897f1d01e551ce0edb9c0" + integrity sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA== + dependencies: + "@aws-sdk/types" "^3.110.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/abort-controller@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/abort-controller/-/abort-controller-3.222.0.tgz#7a93065dd3cbb6013b00ccb380d59ae9589d9942" + integrity sha512-Ric2vJQEWrzz915wBeZlYLWAnIsnywOcZpzroPVTY/TNKRvM0GcSPVuD9vv1lOwybVnDHsipukzwQBAZXkNWVA== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/chunked-blob-reader-native@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.208.0.tgz#cdbd12c89a4f3ddd91bf707da8bb4af311487cc5" + integrity sha512-JeOZ95PW+fJ6bbuqPySYqLqHk1n4+4ueEEraJsiUrPBV0S1ZtyvOGHcnGztKUjr2PYNaiexmpWuvUve9K12HRA== + dependencies: + "@aws-sdk/util-base64" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/chunked-blob-reader@3.188.0": + version "3.188.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.188.0.tgz#18181b27511ab512e56b9f2cef30d2abbef639dc" + integrity sha512-zkPRFZZPL3eH+kH86LDYYXImiClA1/sW60zYOjse9Pgka+eDJlvBN6hcYxwDEKjcwATYiSRR1aVQHcfCinlGXg== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/client-s3@^3.0.0", "@aws-sdk/client-s3@^3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.222.0.tgz#849a3e624941e6d2879266203613e6adc4bf6d2b" + integrity sha512-QHTZ6vt6t0gsX5lM/ylybj2FKtfJsjV9nbx1Q9QhLfAe6e3vb7mOpMS8eTVAs6al+OaweCV0+blgPT8dhEXI3g== + dependencies: + "@aws-crypto/sha1-browser" "2.0.0" + "@aws-crypto/sha256-browser" "2.0.0" + "@aws-crypto/sha256-js" "2.0.0" + "@aws-sdk/client-sts" "3.222.0" + "@aws-sdk/config-resolver" "3.222.0" + "@aws-sdk/credential-provider-node" "3.222.0" + "@aws-sdk/eventstream-serde-browser" "3.222.0" + "@aws-sdk/eventstream-serde-config-resolver" "3.222.0" + "@aws-sdk/eventstream-serde-node" "3.222.0" + "@aws-sdk/fetch-http-handler" "3.222.0" + "@aws-sdk/hash-blob-browser" "3.222.0" + "@aws-sdk/hash-node" "3.222.0" + "@aws-sdk/hash-stream-node" "3.222.0" + "@aws-sdk/invalid-dependency" "3.222.0" + "@aws-sdk/md5-js" "3.222.0" + "@aws-sdk/middleware-bucket-endpoint" "3.222.0" + "@aws-sdk/middleware-content-length" "3.222.0" + "@aws-sdk/middleware-endpoint" "3.222.0" + "@aws-sdk/middleware-expect-continue" "3.222.0" + "@aws-sdk/middleware-flexible-checksums" "3.222.0" + "@aws-sdk/middleware-host-header" "3.222.0" + "@aws-sdk/middleware-location-constraint" "3.222.0" + "@aws-sdk/middleware-logger" "3.222.0" + "@aws-sdk/middleware-recursion-detection" "3.222.0" + "@aws-sdk/middleware-retry" "3.222.0" + "@aws-sdk/middleware-sdk-s3" "3.222.0" + "@aws-sdk/middleware-serde" "3.222.0" + "@aws-sdk/middleware-signing" "3.222.0" + "@aws-sdk/middleware-ssec" "3.222.0" + "@aws-sdk/middleware-stack" "3.222.0" + "@aws-sdk/middleware-user-agent" "3.222.0" + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/node-http-handler" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/signature-v4-multi-region" "3.222.0" + "@aws-sdk/smithy-client" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/url-parser" "3.222.0" + "@aws-sdk/util-base64" "3.208.0" + "@aws-sdk/util-body-length-browser" "3.188.0" + "@aws-sdk/util-body-length-node" "3.208.0" + "@aws-sdk/util-defaults-mode-browser" "3.222.0" + "@aws-sdk/util-defaults-mode-node" "3.222.0" + "@aws-sdk/util-endpoints" "3.222.0" + "@aws-sdk/util-retry" "3.222.0" + "@aws-sdk/util-stream-browser" "3.222.0" + "@aws-sdk/util-stream-node" "3.222.0" + "@aws-sdk/util-user-agent-browser" "3.222.0" + "@aws-sdk/util-user-agent-node" "3.222.0" + "@aws-sdk/util-utf8-browser" "3.188.0" + "@aws-sdk/util-utf8-node" "3.208.0" + "@aws-sdk/util-waiter" "3.222.0" + "@aws-sdk/xml-builder" "3.201.0" + fast-xml-parser "4.0.11" + tslib "^2.3.1" + +"@aws-sdk/client-sso-oidc@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.222.0.tgz#cda07e09da74e8dbed0b3e35aeba2c582d837d60" + integrity sha512-qC4SOKojOWCixvtma3/pwumRzkqHd19FL17ImR+p3C6J0CsSIzjBsKOxLjQMfaE0usAdqStxjULxJDAvWLElJA== + dependencies: + "@aws-crypto/sha256-browser" "2.0.0" + "@aws-crypto/sha256-js" "2.0.0" + "@aws-sdk/config-resolver" "3.222.0" + "@aws-sdk/fetch-http-handler" "3.222.0" + "@aws-sdk/hash-node" "3.222.0" + "@aws-sdk/invalid-dependency" "3.222.0" + "@aws-sdk/middleware-content-length" "3.222.0" + "@aws-sdk/middleware-endpoint" "3.222.0" + "@aws-sdk/middleware-host-header" "3.222.0" + "@aws-sdk/middleware-logger" "3.222.0" + "@aws-sdk/middleware-recursion-detection" "3.222.0" + "@aws-sdk/middleware-retry" "3.222.0" + "@aws-sdk/middleware-serde" "3.222.0" + "@aws-sdk/middleware-stack" "3.222.0" + "@aws-sdk/middleware-user-agent" "3.222.0" + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/node-http-handler" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/smithy-client" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/url-parser" "3.222.0" + "@aws-sdk/util-base64" "3.208.0" + "@aws-sdk/util-body-length-browser" "3.188.0" + "@aws-sdk/util-body-length-node" "3.208.0" + "@aws-sdk/util-defaults-mode-browser" "3.222.0" + "@aws-sdk/util-defaults-mode-node" "3.222.0" + "@aws-sdk/util-endpoints" "3.222.0" + "@aws-sdk/util-retry" "3.222.0" + "@aws-sdk/util-user-agent-browser" "3.222.0" + "@aws-sdk/util-user-agent-node" "3.222.0" + "@aws-sdk/util-utf8-browser" "3.188.0" + "@aws-sdk/util-utf8-node" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/client-sso@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.222.0.tgz#92dbee1889ec86b9734e3184e263f66aab653d74" + integrity sha512-ISJRxT7DLaBwUJSdQoLS/7rWLoYGv6b3C7vTm4hQwDz83+JcdfDODir4iR0REhZfisce8Er6S06WtwAIyokzpQ== + dependencies: + "@aws-crypto/sha256-browser" "2.0.0" + "@aws-crypto/sha256-js" "2.0.0" + "@aws-sdk/config-resolver" "3.222.0" + "@aws-sdk/fetch-http-handler" "3.222.0" + "@aws-sdk/hash-node" "3.222.0" + "@aws-sdk/invalid-dependency" "3.222.0" + "@aws-sdk/middleware-content-length" "3.222.0" + "@aws-sdk/middleware-endpoint" "3.222.0" + "@aws-sdk/middleware-host-header" "3.222.0" + "@aws-sdk/middleware-logger" "3.222.0" + "@aws-sdk/middleware-recursion-detection" "3.222.0" + "@aws-sdk/middleware-retry" "3.222.0" + "@aws-sdk/middleware-serde" "3.222.0" + "@aws-sdk/middleware-stack" "3.222.0" + "@aws-sdk/middleware-user-agent" "3.222.0" + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/node-http-handler" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/smithy-client" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/url-parser" "3.222.0" + "@aws-sdk/util-base64" "3.208.0" + "@aws-sdk/util-body-length-browser" "3.188.0" + "@aws-sdk/util-body-length-node" "3.208.0" + "@aws-sdk/util-defaults-mode-browser" "3.222.0" + "@aws-sdk/util-defaults-mode-node" "3.222.0" + "@aws-sdk/util-endpoints" "3.222.0" + "@aws-sdk/util-retry" "3.222.0" + "@aws-sdk/util-user-agent-browser" "3.222.0" + "@aws-sdk/util-user-agent-node" "3.222.0" + "@aws-sdk/util-utf8-browser" "3.188.0" + "@aws-sdk/util-utf8-node" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/client-sts@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.222.0.tgz#b8e986f63724072ea155d6df695b2357a9dc7c83" + integrity sha512-CZ2eY6aM5YnMzNIvy8t03tr2/iMljkWA4YbMV4lc8HN9qGEh/zUQcNQU2og8nVuo8KjL/4fXXllyUCS8odPnDQ== + dependencies: + "@aws-crypto/sha256-browser" "2.0.0" + "@aws-crypto/sha256-js" "2.0.0" + "@aws-sdk/config-resolver" "3.222.0" + "@aws-sdk/credential-provider-node" "3.222.0" + "@aws-sdk/fetch-http-handler" "3.222.0" + "@aws-sdk/hash-node" "3.222.0" + "@aws-sdk/invalid-dependency" "3.222.0" + "@aws-sdk/middleware-content-length" "3.222.0" + "@aws-sdk/middleware-endpoint" "3.222.0" + "@aws-sdk/middleware-host-header" "3.222.0" + "@aws-sdk/middleware-logger" "3.222.0" + "@aws-sdk/middleware-recursion-detection" "3.222.0" + "@aws-sdk/middleware-retry" "3.222.0" + "@aws-sdk/middleware-sdk-sts" "3.222.0" + "@aws-sdk/middleware-serde" "3.222.0" + "@aws-sdk/middleware-signing" "3.222.0" + "@aws-sdk/middleware-stack" "3.222.0" + "@aws-sdk/middleware-user-agent" "3.222.0" + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/node-http-handler" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/smithy-client" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/url-parser" "3.222.0" + "@aws-sdk/util-base64" "3.208.0" + "@aws-sdk/util-body-length-browser" "3.188.0" + "@aws-sdk/util-body-length-node" "3.208.0" + "@aws-sdk/util-defaults-mode-browser" "3.222.0" + "@aws-sdk/util-defaults-mode-node" "3.222.0" + "@aws-sdk/util-endpoints" "3.222.0" + "@aws-sdk/util-retry" "3.222.0" + "@aws-sdk/util-user-agent-browser" "3.222.0" + "@aws-sdk/util-user-agent-node" "3.222.0" + "@aws-sdk/util-utf8-browser" "3.188.0" + "@aws-sdk/util-utf8-node" "3.208.0" + fast-xml-parser "4.0.11" + tslib "^2.3.1" + +"@aws-sdk/config-resolver@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.222.0.tgz#60a7a24659d121ce7d035a88fa541aac9851cd02" + integrity sha512-rG/Yh0R+GQe86ofEb24QAjQ19tHb4HMCyCuMZUZCsIdgNmUfcaH21Ug5s7pJrAfEy/F2gwxs+VfBeXKjT0MqSQ== + dependencies: + "@aws-sdk/signature-v4" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-config-provider" "3.208.0" + "@aws-sdk/util-middleware" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-env@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.222.0.tgz#1398c2818ef107a7f08ded3dd52233b98ef6f5e1" + integrity sha512-xV6cmJ9zMi8nWySqBv1ze/EFlzXEfazu3i/T/5MpOufPvuGpXTQ3/PDEbC6mKBtvomoQ0fonc/cZrix7YcJV0Q== + dependencies: + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-imds@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.222.0.tgz#a4d31b5d59b9e7cb443cdd094ed69712d249a2d9" + integrity sha512-n090ouw5AFhb0EfzRElUTmqCNOQ1zjlxau30oVM7+qKtXH85hEGMQOoRQAl9ch/pXcbjKLh1mbUhmonR97/Kvw== + dependencies: + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/url-parser" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-ini@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.222.0.tgz#54fbb4b325ea409ba63e3a2d8b26d676c7fa8146" + integrity sha512-KtOYx0nGwu8466G7oWtFU2u3uKZziwV14xeoYNysnMn77nPE7PtlC3WOzE2p3tSGwfVnaGlmYqWEN4+QrY1zpQ== + dependencies: + "@aws-sdk/credential-provider-env" "3.222.0" + "@aws-sdk/credential-provider-imds" "3.222.0" + "@aws-sdk/credential-provider-sso" "3.222.0" + "@aws-sdk/credential-provider-web-identity" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/shared-ini-file-loader" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.222.0.tgz#593de7523e2aaff4cc65cc1941f53c8ce3321763" + integrity sha512-aWolcqDLgxL7ugyF5954/DrqcAl81PzwZ+ik2IMPCHOGWmsIWoecxMmXXbukrhzIegmVc7DwmN1qmT8KsURj0Q== + dependencies: + "@aws-sdk/credential-provider-env" "3.222.0" + "@aws-sdk/credential-provider-imds" "3.222.0" + "@aws-sdk/credential-provider-ini" "3.222.0" + "@aws-sdk/credential-provider-process" "3.222.0" + "@aws-sdk/credential-provider-sso" "3.222.0" + "@aws-sdk/credential-provider-web-identity" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/shared-ini-file-loader" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-process@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.222.0.tgz#cda2c37323cf451cb0157a08ce1644be2e7632bf" + integrity sha512-IgEk8Tne1b2v2k/wVjuddKi+HEAFJWUoEcvLCnYRdlVX5l+Nnatw8vGYb+gTi9X7nKNqEGfMbifKCFoePKjC0Q== + dependencies: + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/shared-ini-file-loader" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-sso@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.222.0.tgz#2deb84ae5d8915be05773b0e001216a8ad612bf4" + integrity sha512-2bl4lapUNDk95tVyTvbaYYSczxpC5WCFW7mmf8HGxTau4a6oELRsFaKeNzyuaL/IQ8hYhaVWR7nUCxIEqVngWw== + dependencies: + "@aws-sdk/client-sso" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/shared-ini-file-loader" "3.222.0" + "@aws-sdk/token-providers" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/credential-provider-web-identity@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.222.0.tgz#3af44d133c9976320aebf0a52b1ddf467798aa59" + integrity sha512-dImqTEWt38nVcDe/wQqHWJ+R2zyNqVKwejfslgbH2YilUnDU43xq2KJhNe4s+YhCB6tHOTkbNnpZo7vPV5Zxog== + dependencies: + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/eventstream-codec@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.222.0.tgz#ae57b2877eccf24f6335ce65fbc6a14c7a69e14c" + integrity sha512-sxLpo3NYrvj8CnTkpLsb2uXvUU8jnAG5q22HIBxBrpeFzgvUA9uIfPD7yPZhe4+/C7v+ER19ysXetKjiAOrQMA== + dependencies: + "@aws-crypto/crc32" "2.0.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-hex-encoding" "3.201.0" + tslib "^2.3.1" + +"@aws-sdk/eventstream-serde-browser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.222.0.tgz#36630955cf9f0b076ebaed57d87fb04f2d0e3445" + integrity sha512-owwgmkpuLM7UtNPRZjvCOp5fo6MKY8avygQA0VMsbQSCq1DJFpmDsk7yTRB+n7jQuoDGn8uVxER3S0oS/Y/xVQ== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/eventstream-serde-config-resolver@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.222.0.tgz#c480fd9178710ff257f84eae88b7360b394221e5" + integrity sha512-zb8vMSbBEjUrHKpA2bZdAqfYp8oCsWgeBPOt0XJx+y6lzy67zyADs97Grl+lyZAoswao/zc2sxgm9yqcMDt7lQ== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/eventstream-serde-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.222.0.tgz#fb2452fe24f6df4426a2c2a42b94bf25af8a1406" + integrity sha512-rfDrTxcsYL0ZKc5MnoqbDTa0oQFiK7qTJOnQ7sASooexqoKTn3wVq68J7TZddbImmH/ENpkU+O0hcGuiwE9Ucg== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/eventstream-serde-universal@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.222.0.tgz#acae53e01d81b1f3f75874ab003cc54fb25ec4a8" + integrity sha512-+/Fc7+ZPuD6SwphYcuLJ/GU0RmVzG/M0dUYs1JL/JQJ8dkJ0AlH1fH3L5Fhm2RO/ACkE28kXAuyZ40TLeRLRNA== + dependencies: + "@aws-sdk/eventstream-codec" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/fetch-http-handler@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.222.0.tgz#84af5e3f6f8e2468d935cd11f53413f979c650dd" + integrity sha512-0PWnOp47mNfwBFEZhuBpz5A+66jbvb2ySidnM5vWHRxu5yN7rCJEdEMSJKDzR6nH3GLZ9dHoOxTzQy21NoDTtA== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/querystring-builder" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-base64" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/hash-blob-browser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.222.0.tgz#92d44e2234700ebd09b05a923a8a836665bef658" + integrity sha512-Z6y3JZPNp+os9vZdvsNkM6mIjDzeZNr9MYkQslANhGZ9WgQrzuI7xZN6XAyR83OGRCrDCorZdX+nnl5mzY1VwQ== + dependencies: + "@aws-sdk/chunked-blob-reader" "3.188.0" + "@aws-sdk/chunked-blob-reader-native" "3.208.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/hash-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-node/-/hash-node-3.222.0.tgz#ebe88b774230cb4f09bdb913c8759af29f79b5bd" + integrity sha512-Fw0acblG0LQT9tfD2/4j98QHNq+Crotig/M1/zPDcVoGb8OBHd2442zpeA0fYYjGnGGhy9psRHdJrjZGj1vDUw== + dependencies: + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-buffer-from" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/hash-stream-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-stream-node/-/hash-stream-node-3.222.0.tgz#da5b2012a2a9cbc3c8a8c48a9ee85a9943dd9b8f" + integrity sha512-PO/N0PsgJjRiH9WKSOnGjDP9tWNjwSvUezicT8ItWgkk7npd278MAe7G692TLACgf6sJr2jGQbs6xzZHq0/3Zg== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/invalid-dependency@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/invalid-dependency/-/invalid-dependency-3.222.0.tgz#ae81e031c09333f0ce13de7b29f04b285b8b725e" + integrity sha512-tWJWWTcL7DrhFiDmPBvLaw2lopHJMsF4Uj52yIQJskwd2IeBOxjl30zLo/oidmk73IFUB7TCObc85zJrtt/KcQ== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/is-array-buffer@3.201.0": + version "3.201.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/is-array-buffer/-/is-array-buffer-3.201.0.tgz#06e557adc284fac2f26071c2944ae01f61b95854" + integrity sha512-UPez5qLh3dNgt0DYnPD/q0mVJY84rA17QE26hVNOW3fAji8W2wrwrxdacWOxyXvlxWsVRcKmr+lay1MDqpAMfg== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/lib-storage@^3.46.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.222.0.tgz#3627de83ecc88d5e460e1daa33a38313461a90e8" + integrity sha512-f5bAtkT+FqPrYNAT6ZcVj8yXEFdCY6/Pf9buOz/3xqICn5oJzFotkXel7lrFptKfnzVtbwZvrti38h/tl89Erg== + dependencies: + "@aws-sdk/middleware-endpoint" "3.222.0" + "@aws-sdk/smithy-client" "3.222.0" + buffer "5.6.0" + events "3.3.0" + stream-browserify "3.0.0" + tslib "^2.3.1" + +"@aws-sdk/md5-js@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/md5-js/-/md5-js-3.222.0.tgz#61999d6776667cdcb3af0ca898566e290fa6455d" + integrity sha512-LI44dy+ECCL+vsIYJ/Ot4rNOl3Vpa4Nv8zxireKcQGmn547Cb6i3n/bEi/DkcfgHv6R84qOtOXsxt/ILuWNQ/g== + dependencies: + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-utf8-browser" "3.188.0" + "@aws-sdk/util-utf8-node" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-bucket-endpoint@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.222.0.tgz#a4312025b90a3f98d7ac4ea32b57a91773e9b01d" + integrity sha512-TP4mjEWsQ/JsACAFDUlltl/0sAe5dxqdhBDAPO6LHRHvROz2oYVjZwvcaK4F9x8QLWh09H0Sw501SndFK2+o3w== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-arn-parser" "3.208.0" + "@aws-sdk/util-config-provider" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-content-length@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.222.0.tgz#0c074d3aaf106cc69056946ab38bf913c522c6c3" + integrity sha512-Wlah+nrPhcq5qcwHiK1ymVRAvcKjV2py2RXhJsNZWgYwphdt5RHaZHPDKoodI27alrDJVyBBQWGzIm/Ag1bypQ== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-endpoint@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.222.0.tgz#7494bde024f05d88810408b41f51a87c91b626c1" + integrity sha512-e1bM+CvuUWmBdydQpV5sF8cxZrXQ++0G5s1M7pLimKdWXQvCQ1ZEwA3LLi2IWomXmS9a3BaH3iKAf87RTWjIXw== + dependencies: + "@aws-sdk/middleware-serde" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/signature-v4" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/url-parser" "3.222.0" + "@aws-sdk/util-config-provider" "3.208.0" + "@aws-sdk/util-middleware" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-expect-continue@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.222.0.tgz#a4764898c72f58d2968ca79ae063ca800e01773f" + integrity sha512-/nTCLXrau8jEyehsD7QM49gJQ6kmzQGw7plPDJzdFakfAwb2b/jLJ/Hj/ZSaaLWWEXAtZBiPzVXUJltPDoXv5g== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-flexible-checksums@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.222.0.tgz#605d60970027cc4374feaac3d4dcd4362e85b4c7" + integrity sha512-P900+KLMUg0eOf75FK/wH/Gjz3rkNtB6iBfAG2Xg4DY5+78qh40deG0y0ZvtkHQP8YOqjLF3QMbEA90YXo4x9Q== + dependencies: + "@aws-crypto/crc32" "2.0.0" + "@aws-crypto/crc32c" "2.0.0" + "@aws-sdk/is-array-buffer" "3.201.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-host-header@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.222.0.tgz#9ab9f70cbc4883a827ea4382d4c9258f77ca9275" + integrity sha512-R4STwHkWgdxMRqOy6riYfXepsQURR5YhK6psPFZHkBYByIRc9JxJdLA0qZcfLRriQIAGmqEO2WWsqRmr8nkbBw== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-location-constraint@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.222.0.tgz#2578b3cba6735b245d90bf013fa9eb5862cf7a11" + integrity sha512-srrAkOHuvpXeaMG9a6kvfYrhzFFX/plBaZATy8iW6ethgvG1qdPeFj4ZVS9Eisx+13NbGFtydc1WkBZfx2nUWg== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-logger@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.222.0.tgz#73e1fe235f26f733d1218c1b05dba8db58b4241a" + integrity sha512-eAxGCcNXl1APMOFbkUaAC6pNBPUbajyGqsDf6GLdlrYHrMVAtJdYd988ov6C52h7k6iDZ+OPHwv8dwUz+PRfpw== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-recursion-detection@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.222.0.tgz#838ef2113df278cb705456cd9d0fd682e987e11f" + integrity sha512-4JRVs7y5JDXXjc5fkz0FCZJt/0HTP2vh3QyZsWRbCYesw2cWVqQlp/fUXp8w5KGqm5nYkTF4e5SQ7Ca8powJNA== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-retry@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.222.0.tgz#bd29d7c858d42985716d1077f73d747f30011f59" + integrity sha512-8FZpGuJDtntjXZ/mfJ9EdP5mYiUunQHEmk6OERk3h4XW3D/e97denwDAcBBIK8iYYGic5PoWF4KgTFJWs1YOcw== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/service-error-classification" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-middleware" "3.222.0" + tslib "^2.3.1" + uuid "^8.3.2" + +"@aws-sdk/middleware-sdk-s3@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.222.0.tgz#15e2afe2dde591c19a17a3b48cc81f6dad130b00" + integrity sha512-GCgbzWy3Dn9+dz/ZZjS5OiJ+feighHfMt461r1zjHNUXnb2tEf5kU+P80d3WqG8er4RRQg+Ao49SatOKgPcrlA== + dependencies: + "@aws-sdk/middleware-bucket-endpoint" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-arn-parser" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-sdk-sts@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.222.0.tgz#c61e6f553b8517e9a1afdd92b03b1683d185af7c" + integrity sha512-YbL4lTBFgqyL2Ob+dMyw/UNd5K9IOnZHHxjpwWlYKMrfT+pp2bvrr7XUbRHnxSoDsOg9bf6IyTSRVnVxP4psJg== + dependencies: + "@aws-sdk/middleware-signing" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/signature-v4" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-serde@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.222.0.tgz#b4decb3bbb8e373d393e0c607b5af175cbfc2396" + integrity sha512-UoeLbgCJB07dX8tRByR0KzZaOwCoIyXj/SfFTuOhBUjkpKwqFCam/hofDlK3FR6kvl+xiURv57W/FtKV/9TDHg== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-signing@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.222.0.tgz#8bb645b4943bc13ec0517a7cb019a1d0b0a6eacb" + integrity sha512-MwMw2Lz7SBOniAc0slWXt65ocqL+E956bdW+LOvBin6OgkVWaLRbWI9nOzA6B2d8b65fCGEc+N15i0UdrEf+MQ== + dependencies: + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/signature-v4" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-middleware" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-ssec@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.222.0.tgz#3e1fe2a4f675a15e69c5bb0c3e4684c430baeca4" + integrity sha512-WThCx/+UG4gIyqx0G3QKD1RM71+adh9Jv3Sh/KiS07Jjm+pb71wW+RRzBuNyhdjwB3aoKC/YKW8eFQg6M7eaQg== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/middleware-stack@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.222.0.tgz#c55b4f8408e6b111f25ca3a5ce24118e54968dfd" + integrity sha512-ASKbstAKbOBUZhFhst6/NCr11x94BDBiQn2zDs2Lvjo89n2efMeb4wEr17VCMZVeKI6ojtPFa1ZVLsH8AOn4Yw== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/middleware-user-agent@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.222.0.tgz#3a891abf3eab3db8dc7df7f9ca36d70d240a2d44" + integrity sha512-fjdxCRIAhOTsI9OcEKwJp4lhsvyCSXoeYV49mO/bdG6pFyFRm3Jezx7TNVNeLTGuMHTTTvRrCTF8sgE5t17Pzw== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/node-config-provider@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.222.0.tgz#1eae0219266c656006c902b730480727a47f39c5" + integrity sha512-hrbw90LlVa4xJJc4WiyAfaPMY/sJubSeTwuxTChLsFOavr6hSMCwLASrWmOiKRIj5hKdSfEA87n/q+DnKHlA8A== + dependencies: + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/shared-ini-file-loader" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/node-http-handler@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.222.0.tgz#920fc5bacfcc5e0b901d425e4f9779228a93ebaa" + integrity sha512-k3WqxUgZzGbiCQt1HyzDGlRzq8muGIOWZs9T3HtCa5LtACvl0qlNmiwCc+C/o7GRLyC9FuWkP3lOW6MiAFQUcA== + dependencies: + "@aws-sdk/abort-controller" "3.222.0" + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/querystring-builder" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/property-provider@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/property-provider/-/property-provider-3.222.0.tgz#fa889a31277cf3a91bd3e8ac4f618db4fdb122ed" + integrity sha512-rEqAgQ7itmB7GB+WWLgyT7/YWJkjEBCfggxycccChWAeqg+gjpstIiGX2BjP2K/wnzwE0D91JsozSXcQIDOtNQ== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/protocol-http@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/protocol-http/-/protocol-http-3.222.0.tgz#c5f82957d304bb2eb31a117c9a5d86a7772b4f86" + integrity sha512-Zj+ytEgrOagCE7yczjdDan7W+1a0OL5DPAx69Z00NxGoBI2h0GRZD28dRYb3Pzs5/Ft4KbCedH/RUnyaYjaZxw== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/querystring-builder@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-builder/-/querystring-builder-3.222.0.tgz#6e0c93db85ecfa3038258511f47c67e6978218b2" + integrity sha512-qrNUGDyDp9yVQMnBbz1T5YBQkA/u6D5o0PPzSwfZ9azdAcBLjHOEfsBrKhxP+K92L/nilbnmY89KrjMR8+BNtw== + dependencies: + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-uri-escape" "3.201.0" + tslib "^2.3.1" + +"@aws-sdk/querystring-parser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-parser/-/querystring-parser-3.222.0.tgz#2b53b529d8c3ce347ac1900bcf16e728fe4e28b7" + integrity sha512-3KfkCA/753PlF5QqhGuQ7u+NOgLyiBFeV8R8ut/pfBmG8fF6l3RKrkbcu+87QpqXntRzG+RLHDqS7ryT3B2ICg== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/service-error-classification@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.222.0.tgz#6ffeea922f17a0b6e91e8bda9f74f1a04385f499" + integrity sha512-Dn/WGtm+v5nney0CaYZjdOtJmdEuI8EQiQ5J3eQ3G0jjT6mr1/tCajsNpq3ZqHXiwLtydwaVvsL3AKXn+oxFVA== + +"@aws-sdk/shared-ini-file-loader@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.222.0.tgz#2ddf077e3b81639cbb1bf550122946bf86d26230" + integrity sha512-2dowzMXjvIf5gwX5gNCwpv/TzAbbXxrId3zYJgPdEtApsa7NxyFs5MfnHt1zZI6P3YORGheRnNUK9RUYOPKHgA== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/signature-v4-multi-region@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.222.0.tgz#d4b4d9ab0cea9d9f38a3bc791aa3e2f67d0d977b" + integrity sha512-SF6Qi0KW69OzgLbA9q6AsZNFQCA+DI66SnAjW774sAE6aQyJmCbUsxETk37XodSymXzDOEDDC6QoY64HUoSoVw== + dependencies: + "@aws-sdk/protocol-http" "3.222.0" + "@aws-sdk/signature-v4" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-arn-parser" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/signature-v4@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.222.0.tgz#1c96d67d172eb68a89240eed834489d2ed79700b" + integrity sha512-2qQZuKqx56b2uN2rdjdKL6u0Cvk82uTGNtIuetmySY9xPEAljSBdriaxTqNqK9Gs3M4obG22alUK4a85uwqS3g== + dependencies: + "@aws-sdk/is-array-buffer" "3.201.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-hex-encoding" "3.201.0" + "@aws-sdk/util-middleware" "3.222.0" + "@aws-sdk/util-uri-escape" "3.201.0" + tslib "^2.3.1" + +"@aws-sdk/smithy-client@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/smithy-client/-/smithy-client-3.222.0.tgz#c7dddbd82e9da4d3fc1416c98169593635873bd9" + integrity sha512-4dnU7TvwKxVuOWduvFGClYe0EgNov5Ke1ef7O1bdKaj5MmlH6wBDgGJM4NKREBFapC2dUXkoPtwsihtYBci1Bw== + dependencies: + "@aws-sdk/middleware-stack" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/token-providers@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.222.0.tgz#4871761c63b1ed06d2db864e7a959ff63d89b82d" + integrity sha512-VlLQDWjwKm6WezheyZ+wxfEw+X05s1NSZLY5N5HYE6+MSPcqllKCp0ArLcK1MUs68s/4TIOVKQrNeeJm/bLEPw== + dependencies: + "@aws-sdk/client-sso-oidc" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/shared-ini-file-loader" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/types@3.222.0", "@aws-sdk/types@^3.1.0", "@aws-sdk/types@^3.110.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.222.0.tgz#e61eb257f0ad2eaa65f7a72b9a2882f914fbcbb5" + integrity sha512-yXRYptInkfEFaOvWFxlRXsRh9jWOmQc1sZeKqjfx2UCtzNJ7ebedN0VfCz4SaDotcw9Q4JWuN66qhRMJjDx7/w== + +"@aws-sdk/url-parser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.222.0.tgz#74118f3d824d2bb7415fe909c4db62aff5f42667" + integrity sha512-1+QbVdT/phYDb5JDQRJWoZeCujkXaI5m8z3bIiPxcRRY3NPuluDGrfX3kfnFen5s9QGByLvJxWKWZS+i+iUFRg== + dependencies: + "@aws-sdk/querystring-parser" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/util-arn-parser@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.208.0.tgz#56b6ae4699c3140bb27dcede5146876fef04e823" + integrity sha512-QV4af+kscova9dv4VuHOgH8wEr/IIYHDGcnyVtkUEqahCejWr1Kuk+SBK0xMwnZY5LSycOtQ8aeqHOn9qOjZtA== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-base64@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64/-/util-base64-3.208.0.tgz#36b430e5396251f761590f7c2f0c5c12193f353c" + integrity sha512-PQniZph5A6N7uuEOQi+1hnMz/FSOK/8kMFyFO+4DgA1dZ5pcKcn5wiFwHkcTb/BsgVqQa3Jx0VHNnvhlS8JyTg== + dependencies: + "@aws-sdk/util-buffer-from" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/util-body-length-browser@3.188.0": + version "3.188.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.188.0.tgz#e1d949318c10a621b38575a9ef01e39f9857ddb0" + integrity sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-body-length-node@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-node/-/util-body-length-node-3.208.0.tgz#baabd1fa1206ff2bd4ce3785122d86eb3258dd20" + integrity sha512-3zj50e5g7t/MQf53SsuuSf0hEELzMtD8RX8C76f12OSRo2Bca4FLLYHe0TZbxcfQHom8/hOaeZEyTyMogMglqg== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-buffer-from@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-buffer-from/-/util-buffer-from-3.208.0.tgz#285e86f6dc9030148a4147d65239e75cb254a1b0" + integrity sha512-7L0XUixNEFcLUGPeBF35enCvB9Xl+K6SQsmbrPk1P3mlV9mguWSDQqbOBwY1Ir0OVbD6H/ZOQU7hI/9RtRI0Zw== + dependencies: + "@aws-sdk/is-array-buffer" "3.201.0" + tslib "^2.3.1" + +"@aws-sdk/util-config-provider@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-config-provider/-/util-config-provider-3.208.0.tgz#c485fd83fbac051337e5f6be60ea3f9fa61c0139" + integrity sha512-DSRqwrERUsT34ug+anlMBIFooBEGwM8GejC7q00Y/9IPrQy50KnG5PW2NiTjuLKNi7pdEOlwTSEocJE15eDZIg== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-defaults-mode-browser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.222.0.tgz#6b9e34903fa4bf1efb159c9531b0ea113baf2db0" + integrity sha512-+dGsp59lrEkDmK7OO5ecMYasrTGIKacFHjqZ6aqmbn1xtcUd/o3Qe7g5YSRXMGwtZ6xhvBD+NJLkEERI7U7cMw== + dependencies: + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/types" "3.222.0" + bowser "^2.11.0" + tslib "^2.3.1" + +"@aws-sdk/util-defaults-mode-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.222.0.tgz#71fc2d52c9f564c689823f8cd337abde99d70406" + integrity sha512-W/duYMtmCCWdzHP+yscBB6yrARgAqWpFdxgBvMSlT8TjOTrh/F+aj4NPamiNMeUfqfMFGnboYfyWRr1avkcAGQ== + dependencies: + "@aws-sdk/config-resolver" "3.222.0" + "@aws-sdk/credential-provider-imds" "3.222.0" + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/property-provider" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/util-endpoints@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.222.0.tgz#3deb963da8bec939dc2a08cb7f52b66900da28d4" + integrity sha512-qujJQv8lFysAr1lOlBTJhz7949NZyq5cj74Q9dR99AcAMXXeI9CQayPKH7477AnXRGOTMahZ3mV0HZ1bCJoNTw== + dependencies: + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/util-hex-encoding@3.201.0": + version "3.201.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.201.0.tgz#21d7ec319240ee68c33d938e71cb79830bea315d" + integrity sha512-7t1vR1pVxKx0motd3X9rI3m/xNp78p3sHtP5yo4NP4ARpxyJ0fokBomY8ScaH2D/B+U5o9ARxldJUdMqyBlJcA== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-locate-window@^3.0.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.208.0.tgz#0f598fc238a1256e4bcb64d01459f03a922dd4c3" + integrity sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-middleware@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-middleware/-/util-middleware-3.222.0.tgz#e23a5109081769762492890672b15ea54297bd0e" + integrity sha512-Y4BPtSa+6+qvg6OVW6RrdDx0OADfWa2Uxsxqdozpdnx2OQY0q+1diqsNgFMV+FIvdXqffE147KG7roG+/AfPeA== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-retry@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-retry/-/util-retry-3.222.0.tgz#1e9546fe46c6a709dd7c09fe3996d57becac4efb" + integrity sha512-poiWqhiTjExUYKxgN5tRAvKNN23lGHn9ZJAGOu8sY2GHb6gatMfj46k31om3KrM3YGRuyXAo8YXRhA+QZ5CX0g== + dependencies: + "@aws-sdk/service-error-classification" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/util-stream-browser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream-browser/-/util-stream-browser-3.222.0.tgz#96ea5269020dbd91edcc2be4382166670dbfb17e" + integrity sha512-GW9Y1/pLHS7WYHHdswcDd4vaM9mzxDwewcDVujCd/L9MRbG1nA/wfCL7hAAXT1AN2GbGfbfT+jjHQqzexpKBnA== + dependencies: + "@aws-sdk/fetch-http-handler" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-base64" "3.208.0" + "@aws-sdk/util-hex-encoding" "3.201.0" + "@aws-sdk/util-utf8-browser" "3.188.0" + tslib "^2.3.1" + +"@aws-sdk/util-stream-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream-node/-/util-stream-node-3.222.0.tgz#7479188dff293b25d4eadfba38e03bfb95268bc5" + integrity sha512-iMwKG+RaGVAjzXDuzmMl63SnN6qVc+0VbbfaKW1eIK9Ihr5mko3GuYAFqKaECSQ+XdMNuMSVXzphveKw6t2zwg== + dependencies: + "@aws-sdk/node-http-handler" "3.222.0" + "@aws-sdk/types" "3.222.0" + "@aws-sdk/util-buffer-from" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/util-uri-escape@3.201.0": + version "3.201.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-uri-escape/-/util-uri-escape-3.201.0.tgz#5e708d4cde001a4558ee616f889ceacfadd2ab03" + integrity sha512-TeTWbGx4LU2c5rx0obHeDFeO9HvwYwQtMh1yniBz00pQb6Qt6YVOETVQikRZ+XRQwEyCg/dA375UplIpiy54mA== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-user-agent-browser@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.222.0.tgz#a9f220475a11a705ae82eac10f3b422122c6ee4f" + integrity sha512-DREMeL0XHl4QIS2GVSHFwVH4mJZ+Dr04R3U8WfiMktXdA93j5tDMJpU3+PNaCZPeaqz2QNwrVSBWKwbwA357zQ== + dependencies: + "@aws-sdk/types" "3.222.0" + bowser "^2.11.0" + tslib "^2.3.1" + +"@aws-sdk/util-user-agent-node@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.222.0.tgz#235a5f415bf830f937bf50e04d1d26381e964f9d" + integrity sha512-BMRMrPXL/HS3dSha9vcABkoANluKjB0pH78bc659EY2WUj9wCZdbUNQpACiYx8bwm7xKSxugCkmPd6NLWXUURw== + dependencies: + "@aws-sdk/node-config-provider" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/util-utf8-browser@3.188.0", "@aws-sdk/util-utf8-browser@^3.0.0": + version "3.188.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz#484762bd600401350e148277731d6744a4a92225" + integrity sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-utf8-node@3.208.0": + version "3.208.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-node/-/util-utf8-node-3.208.0.tgz#eba17de0f92f87b98481c2e2d0ceaa05c7994d67" + integrity sha512-jKY87Acv0yWBdFxx6bveagy5FYjz+dtV8IPT7ay1E2WPWH1czoIdMAkc8tSInK31T6CRnHWkLZ1qYwCbgRfERQ== + dependencies: + "@aws-sdk/util-buffer-from" "3.208.0" + tslib "^2.3.1" + +"@aws-sdk/util-waiter@3.222.0": + version "3.222.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-waiter/-/util-waiter-3.222.0.tgz#19bdd77937b245ab319ed95a1cd751b59bf55982" + integrity sha512-/07RkfxvDncsMeQ+GhigPdiSRd2v/1FJoCV4a5e9XDI1ZSMvUKm36wFqw5Bzts+AUY8f4HOPpGI9ZQeNb7u27Q== + dependencies: + "@aws-sdk/abort-controller" "3.222.0" + "@aws-sdk/types" "3.222.0" + tslib "^2.3.1" + +"@aws-sdk/xml-builder@3.201.0": + version "3.201.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.201.0.tgz#acf0869855460528114bec17f290b224fe19a3e2" + integrity sha512-brRdB1wwMgjWEnOQsv7zSUhIQuh7DEicrfslAqHop4S4FtSI3GQAShpQqgOpMTNFYcpaWKmE/Y1MJmNY7xLCnw== + dependencies: + tslib "^2.3.1" + +"@prisma/client@^4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.6.1.tgz#e8e1d347ecbff44158d21b6591bb99650c8503a8" + integrity sha512-M1+NNrMzqaOIxT7PBGcTs3IZo7d1EW/+gVQd4C4gUgWBDGgD9AcIeZnUSidgWClmpMSgVUdnVORjsWWGUameYA== + dependencies: + "@prisma/engines-version" "4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32" + +"@prisma/engines-version@4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32": + version "4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32.tgz#90a71bbdfd5172fc674009346a6ad6b84410cc0a" + integrity sha512-HUCmkXAU2jqp2O1RvNtbE+seLGLyJGEABZS/R38rZjSAafAy0WzBuHq+tbZMnD+b5OSCsTVtIPVcuvx1ySxcWQ== + +"@prisma/engines@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.6.1.tgz#ae31309cc0f600f2da22708697b3be4eb1e46f9e" + integrity sha512-3u2/XxvxB+Q7cMXHnKU0CpBiUK1QWqpgiBv28YDo1zOIJE3FCF8DI2vrp6vuwjGt5h0JGXDSvmSf4D4maVjJdw== + +"@types/bcryptjs@^2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae" + integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@^4.17.18": + version "4.17.31" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express-validator@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/express-validator/-/express-validator-3.0.0.tgz#e6f3cab842e5ae376a1cfa11295202ec380b68d1" + integrity sha512-LusnB0YhTXpBT25PXyGPQlK7leE1e41Vezq1hHEUwjfkopM1Pkv2X2Ppxqh9c+w/HZ6Udzki8AJotKNjDTGdkQ== + dependencies: + express-validator "*" + +"@types/express@*", "@types/express@^4.17.14": + version "4.17.14" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/jsonwebtoken@^8.5.9": + version "8.5.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586" + integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg== + dependencies: + "@types/node" "*" + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/multer-s3@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/multer-s3/-/multer-s3-3.0.0.tgz#db798a5335d095b8944861237167d91e2c840ac5" + integrity sha512-s8dZjVsLBdaOaCzWjmn6x7WA1LjWgfhCgc2cIK21EI0pgrROFvooAJSrULdD+8qiW51DnYWAY8pOanBe6LLXzg== + dependencies: + "@aws-sdk/client-s3" "^3.0.0" + "@types/multer" "*" + +"@types/multer@*", "@types/multer@^1.4.7": + version "1.4.7" + resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.7.tgz#89cf03547c28c7bbcc726f029e2a76a7232cc79e" + integrity sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA== + dependencies: + "@types/express" "*" + +"@types/node@*", "@types/node@^18.11.9": + version "18.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/serve-static@*": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +busboy@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +dotenv@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +events@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +express-validator@*, express-validator@^6.14.2: + version "6.14.2" + resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-6.14.2.tgz#6147893f7bec0e14162c3a88b3653121afc4678f" + integrity sha512-8XfAUrQ6Y7dIIuy9KcUPCfG/uCbvREctrxf5EeeME+ulanJ4iiW71lWmm9r4YcKKYOCBMan0WpVg7FtHu4Z4Wg== + dependencies: + lodash "^4.17.21" + validator "^13.7.0" + +express@^4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-xml-parser@4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz#42332a9aca544520631c8919e6ea871c0185a985" + integrity sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA== + dependencies: + strnum "^1.0.5" + +file-type@^3.3.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +html-comment-regex@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + +mkdirp@^0.5.4: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multer-s3@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/multer-s3/-/multer-s3-3.0.1.tgz#4ba7eb8c1eb94a7a64f0de37d414a88c4876d5d8" + integrity sha512-BFwSO80a5EW4GJRBdUuSHblz2jhVSAze33ZbnGpcfEicoT0iRolx4kWR+AJV07THFRCQ78g+kelKFdjkCCaXeQ== + dependencies: + "@aws-sdk/lib-storage" "^3.46.0" + file-type "^3.3.0" + html-comment-regex "^1.1.2" + run-parallel "^1.1.6" + +multer@^1.4.5-lts.1: + version "1.4.5-lts.1" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.5-lts.1.tgz#803e24ad1984f58edffbc79f56e305aec5cfd1ac" + integrity sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ== + dependencies: + append-field "^1.0.0" + busboy "^1.0.0" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + type-is "^1.6.4" + xtend "^4.0.0" + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +nodemon@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.20.tgz#e3537de768a492e8d74da5c5813cb0c7486fc701" + integrity sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prisma@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.6.1.tgz#6c85fb667abed006a6b849c9c1ddd81d3f071b87" + integrity sha512-BR4itMCuzrDV4tn3e2TF+nh1zIX/RVU0isKtKoN28ADeoJ9nYaMhiuRRkFd2TZN8+l/XfYzoRKyHzUFXLQhmBQ== + dependencies: + "@prisma/engines" "4.6.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.2.2: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +run-parallel@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.6.0, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +simple-update-notifier@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" + integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== + dependencies: + semver "~7.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + +supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.3.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + +type-is@^1.6.4, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==