From 9806e3a2959aceaab831141be4504d516de44cd9 Mon Sep 17 00:00:00 2001 From: Rimaru06 Date: Tue, 21 May 2024 11:40:08 +0530 Subject: [PATCH 1/2] login and signup api created --- client/package-lock.json | 11 +++- package-lock.json | 6 ++ server/.env.example | 3 + server/.gitignore | 2 + server/controller/userController.js | 87 +++++++++++++++++++++++++++ server/dbConfig/dbConnection.js | 2 + server/middleware/jwtverfiy.js | 32 ++++++++++ server/models/userModel.js | 22 +++---- server/package-lock.json | 43 ++++++++++--- server/package.json | 5 +- server/routes/UserRoutes.js | 22 +++++++ server/server.js | 3 + server/validation/userValidation.js | 10 +++ server/validation/validationSchema.js | 15 +++++ server/validation/validator.js | 32 ++++++++++ 15 files changed, 272 insertions(+), 23 deletions(-) create mode 100644 package-lock.json create mode 100644 server/.env.example create mode 100644 server/.gitignore create mode 100644 server/controller/userController.js create mode 100644 server/middleware/jwtverfiy.js create mode 100644 server/routes/UserRoutes.js create mode 100644 server/validation/userValidation.js create mode 100644 server/validation/validationSchema.js create mode 100644 server/validation/validator.js diff --git a/client/package-lock.json b/client/package-lock.json index bd270af..b149e18 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -17,7 +17,8 @@ "react-hook-form": "^7.45.1", "react-icons": "^4.10.1", "react-redux": "^8.1.1", - "react-router-dom": "^6.14.1" + "react-router-dom": "^6.14.1", + "zod": "^3.23.8" }, "devDependencies": { "@types/react": "^18.2.14", @@ -4510,6 +4511,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c3a177b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "Kaam-Do", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/server/.env.example b/server/.env.example new file mode 100644 index 0000000..d36021e --- /dev/null +++ b/server/.env.example @@ -0,0 +1,3 @@ +MONGODB_URL=mongodb://localhost:27017/contribute # This is the URL to connect to the MongoDB database +JWT_SECRET=secret # This is the secret key used to sign the JWT tokens +PORT=3000 # This is the port the server will run on \ No newline at end of file diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..1dcef2d --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,2 @@ +node_modules +.env \ No newline at end of file diff --git a/server/controller/userController.js b/server/controller/userController.js new file mode 100644 index 0000000..e3822f1 --- /dev/null +++ b/server/controller/userController.js @@ -0,0 +1,87 @@ +import bcrypt from "bcryptjs"; +import jwt from "jsonwebtoken"; +import User from "../models/userModel.js"; +import dotenv from "dotenv"; +dotenv.config(); + +export const loginUser = async (req, res) => { + const { email, password } = req.body; + + try { + const userexist = await User.findOne({ + email, + }); + + if (!userexist) { + return res.status(422).json({ + message: "User does not exist", + }); + } + + const isPasswordCorrect = await bcrypt.compare( + password, + userexist.password + ); + if (!isPasswordCorrect) { + return res.status(422).json({ + message: "Invalid Password", + }); + } + + const token = jwt.sign( + { email: userexist.email, id: userexist._id }, + process.env.JWT_SECRET, + { expiresIn: "7d" } + ); + return res.status(200).json({ + message: "Login Successfull", + token, + user: { + email: userexist.email, + id: userexist._id, + }, + }); + } catch (error) { + console.log(error); + + return res.status(500).json({ + message: "internal Server Error", + }); + } +}; + +export const signupUser = async (req, res) => { + const { email, password, firstName, lastName } = req.body; + + try { + const userexist = await User.findOne({ + email, + }); + + if (userexist) { + return res.status(422).json({ + message: "User already exist", + }); + } + + console.log(req.body); + + const hashedPassword = await bcrypt.hash(password, 8); + console.log(hashedPassword); + const user = await User.create({ + email, + password: hashedPassword, + firstName, + lastName, + }); + res.status(200).json({ + message: "User Created Successfully", + user, + }); + } catch (error) { + console.log(error); + return res.status(500).json({ + message: "Signup Failed", + }); + } +}; diff --git a/server/dbConfig/dbConnection.js b/server/dbConfig/dbConnection.js index 92148ec..90d759a 100644 --- a/server/dbConfig/dbConnection.js +++ b/server/dbConfig/dbConnection.js @@ -1,4 +1,6 @@ import mongoose from "mongoose"; +import dotenv from "dotenv"; +dotenv.config(); const dbConnection = async () => { try { diff --git a/server/middleware/jwtverfiy.js b/server/middleware/jwtverfiy.js new file mode 100644 index 0000000..abcdbb0 --- /dev/null +++ b/server/middleware/jwtverfiy.js @@ -0,0 +1,32 @@ +import jwt from "jsonwebtoken"; + + +const jwtVerfy = async (req,res,next) => { + const token = req.headers.authorization; + + if(!token){ + return res.status(401).json({ + message: "token not found" + }) + } + + const authToken = token.split(" ")[1]; + + try { + const decoded = jwt.verify(authToken, process.env.JWT_SECRET); + if(decoded){ + req.user = decoded; + next(); + } + else + { + throw new Error("invalid token or expired token"); + } + } catch (error) { + console.error("jwt error", error.message); + return res.status(401).json({ + message: "invalid token or expired token" + }) + } +} +export default jwtVerfy; \ No newline at end of file diff --git a/server/models/userModel.js b/server/models/userModel.js index f666d9c..0aaa162 100644 --- a/server/models/userModel.js +++ b/server/models/userModel.js @@ -1,27 +1,22 @@ import mongoose from "mongoose"; -import validator from "validator"; -import bcrypt from "bcryptjs"; -import JWT from "jsonwebtoken" - const userSchema = new mongoose.Schema({ firstName:{ type:String, - required :[true, "First Name is required"] + required :true }, lastName:{ type:String, - required :[true, "Last Name is required"] + required :true }, email:{ type:String, - required :[true, "Email Name is required"], + required :true, unique: true, //checks if the email already exists in database or not - validate: validator.isEmail }, password:{ type:String, - required :[true, "Password is required"], - minlength: [6, "Password must be at least"], + required :true, + minlength: 6, select: true, }, @@ -29,4 +24,9 @@ const userSchema = new mongoose.Schema({ type: String, default:"seeker" } -}); \ No newline at end of file +}); + + +const User = mongoose.model("User", userSchema); + +export default User; \ No newline at end of file diff --git a/server/package-lock.json b/server/package-lock.json index d111179..a2c1dee 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -12,17 +12,19 @@ "bcryptjs": "^2.4.3", "body-parser": "^1.20.2", "cors": "^2.8.5", - "dotenv": "^16.4.1", + "dotenv": "^16.4.5", "express": "^4.18.2", "express-async-errors": "^3.1.1", "express-mongo-sanitize": "^2.2.0", "express-rate-limit": "^7.1.5", + "http-error": "^0.0.6", "jsonwebtoken": "^9.0.2", "mongoose": "^8.1.1", "morgan": "^1.10.0", "nodemon": "^3.0.3", "validator": "^13.11.0", - "xss-clean": "^0.1.4" + "xss-clean": "^0.1.4", + "zod": "^3.23.8" } }, "node_modules/@mongodb-js/saslprep": { @@ -305,14 +307,14 @@ } }, "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/ecdsa-sig-formatter": { @@ -610,6 +612,11 @@ "node": ">= 0.4" } }, + "node_modules/http-error": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/http-error/-/http-error-0.0.6.tgz", + "integrity": "sha512-1okadUMOfkA8o9mvatq5dopVrPdIsKw3K9JL2izosTqFJVa+ID8Siw4ichfW7AvXRVHVvpfQpEekPvrjZ3bqSg==" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -1502,6 +1509,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } }, "dependencies": { @@ -1726,9 +1741,9 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==" + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" }, "ecdsa-sig-formatter": { "version": "1.0.11", @@ -1946,6 +1961,11 @@ "function-bind": "^1.1.2" } }, + "http-error": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/http-error/-/http-error-0.0.6.tgz", + "integrity": "sha512-1okadUMOfkA8o9mvatq5dopVrPdIsKw3K9JL2izosTqFJVa+ID8Siw4ichfW7AvXRVHVvpfQpEekPvrjZ3bqSg==" + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -2589,6 +2609,11 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" } } } diff --git a/server/package.json b/server/package.json index 56c9c0d..d16ed7f 100644 --- a/server/package.json +++ b/server/package.json @@ -14,7 +14,7 @@ "bcryptjs": "^2.4.3", "body-parser": "^1.20.2", "cors": "^2.8.5", - "dotenv": "^16.4.1", + "dotenv": "^16.4.5", "express": "^4.18.2", "express-async-errors": "^3.1.1", "express-mongo-sanitize": "^2.2.0", @@ -24,6 +24,7 @@ "morgan": "^1.10.0", "nodemon": "^3.0.3", "validator": "^13.11.0", - "xss-clean": "^0.1.4" + "xss-clean": "^0.1.4", + "zod": "^3.23.8" } } diff --git a/server/routes/UserRoutes.js b/server/routes/UserRoutes.js new file mode 100644 index 0000000..390dc40 --- /dev/null +++ b/server/routes/UserRoutes.js @@ -0,0 +1,22 @@ +import { Router } from "express"; +import { loginUser , signupUser } from "../controller/userController.js"; +import { signupValidator , loginValidator } from "../validation/userValidation.js"; +import jwtVerfy from "../middleware/jwtverfiy.js"; + + +const router = Router(); + + + +router.post("/login", loginValidator, loginUser); +router.post("/signup", signupValidator, signupUser); + +// test route for jwt middleware +router.get("/test", jwtVerfy, (req, res) => { + res.json({ + message: "Test route for jwtverificaiton middleware", + }); +}); + + +export default router; \ No newline at end of file diff --git a/server/server.js b/server/server.js index 5f895eb..6c788bf 100644 --- a/server/server.js +++ b/server/server.js @@ -8,6 +8,8 @@ import xss from'xss-clean'; import ExpressMongoSanitize from 'express-mongo-sanitize'; import dbConnection from './dbConfig/dbConnection.js'; +import UserRoutes from './routes/UserRoutes.js'; + dotenv.config(); const app = express(); @@ -30,6 +32,7 @@ app.use(express.urlencoded({extended: true})); app.use(morgan("dev")); +app.use("/api/v1/user" , UserRoutes) // Listen app.listen(PORT, ()=>{ console.log(`Development server running on port: ${PORT}`); diff --git a/server/validation/userValidation.js b/server/validation/userValidation.js new file mode 100644 index 0000000..4d19cbc --- /dev/null +++ b/server/validation/userValidation.js @@ -0,0 +1,10 @@ +import validator from "./validator.js"; + +import { SignupValidationSchema , loginValidationSchema } from "./validationSchema.js"; + +export const signupValidator = (req, res, next) => { + validator(SignupValidationSchema, req.body, next , res); +} +export const loginValidator = (req, res, next) => { + validator(loginValidationSchema, req.body, next , res); +} diff --git a/server/validation/validationSchema.js b/server/validation/validationSchema.js new file mode 100644 index 0000000..20be4e9 --- /dev/null +++ b/server/validation/validationSchema.js @@ -0,0 +1,15 @@ +import zod from "zod"; + + +export const SignupValidationSchema = zod.object({ + email: zod.string().email(), + password: zod.string().min(6), + firstName: zod.string(), + lastName: zod.string(), + accountType: zod.string().optional() +}) + +export const loginValidationSchema = zod.object({ + email: zod.string().email(), + password: zod.string().min(6) +}) \ No newline at end of file diff --git a/server/validation/validator.js b/server/validation/validator.js new file mode 100644 index 0000000..79ca816 --- /dev/null +++ b/server/validation/validator.js @@ -0,0 +1,32 @@ +import zod, { Schema } from "zod"; + +const validator = async (Schema , body , next , res ) => { + try { + const value = Schema.safeParse(body); + console.log(value.success); + if(value.success){ + next(); + } + else{ + res.status(400).json({ + error: value.error.errors + }) + } + } catch (error) { + if(error instanceof zod.ZodError) + { + res.status(400).json({ + error: error.errors + }) + } + else{ + res.status(500).json({ + error: "Internal Server Error" + }) + } + + + } +} + +export default validator; // Path: server/validation/validator.js \ No newline at end of file From 6c1e53ced6c2d602eaf783ab1a0e845240c5c743 Mon Sep 17 00:00:00 2001 From: Rimaru06 Date: Wed, 22 May 2024 17:20:26 +0530 Subject: [PATCH 2/2] login and sign up api --- client/index.html | 4 +- client/package-lock.json | 362 --------------------------------------- 2 files changed, 3 insertions(+), 363 deletions(-) diff --git a/client/index.html b/client/index.html index ea10153..f653c6c 100644 --- a/client/index.html +++ b/client/index.html @@ -10,7 +10,9 @@
- + + + \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index 84bdccd..86ba219 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -23,11 +23,7 @@ "react-icons": "^4.10.1", "react-redux": "^8.1.1", "react-router-dom": "^6.14.1", -<<<<<<< HEAD - "zod": "^3.23.8" -======= "styled-components": "^6.1.11" ->>>>>>> efc725b0d1811a7e4c224a4a0372032f25d5e002 }, "devDependencies": { "@types/react": "^18.2.14", @@ -555,342 +551,6 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.13.tgz", - "integrity": "sha512-KwqFhxRFMKZINHzCqf8eKxE0XqWlAVPRxwy6rc7CbVFxzUWB2sA/s3hbMZeemPdhN3fKBkqOaFhTbS8xJXYIWQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.13.tgz", - "integrity": "sha512-j7NhycJUoUAG5kAzGf4fPWfd17N6SM3o1X6MlXVqfHvs2buFraCJzos9vbeWjLxOyBKHyPOnuCuipbhvbYtTAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.13.tgz", - "integrity": "sha512-M2eZkRxR6WnWfVELHmv6MUoHbOqnzoTVSIxgtsyhm/NsgmL+uTmag/VVzdXvmahak1I6sOb1K/2movco5ikDJg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.13.tgz", - "integrity": "sha512-f5goG30YgR1GU+fxtaBRdSW3SBG9pZW834Mmhxa6terzcboz7P2R0k4lDxlkP7NYRIIdBbWp+VgwQbmMH4yV7w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.13.tgz", - "integrity": "sha512-RIrxoKH5Eo+yE5BtaAIMZaiKutPhZjw+j0OCh8WdvKEKJQteacq0myZvBDLU+hOzQOZWJeDnuQ2xgSScKf1Ovw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.13.tgz", - "integrity": "sha512-AfRPhHWmj9jGyLgW/2FkYERKmYR+IjYxf2rtSLmhOrPGFh0KCETFzSjx/JX/HJnvIqHt/DRQD/KAaVsUKoI3Xg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.13.tgz", - "integrity": "sha512-pGzWWZJBInhIgdEwzn8VHUBang8UvFKsvjDkeJ2oyY5gZtAM6BaxK0QLCuZY+qoj/nx/lIaItH425rm/hloETA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.13.tgz", - "integrity": "sha512-4iMxLRMCxGyk7lEvkkvrxw4aJeC93YIIrfbBlUJ062kilUUnAiMb81eEkVvCVoh3ON283ans7+OQkuy1uHW+Hw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.13.tgz", - "integrity": "sha512-hCzZbVJEHV7QM77fHPv2qgBcWxgglGFGCxk6KfQx6PsVIdi1u09X7IvgE9QKqm38OpkzaAkPnnPqwRsltvLkIQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.13.tgz", - "integrity": "sha512-I3OKGbynl3AAIO6onXNrup/ttToE6Rv2XYfFgLK/wnr2J+1g+7k4asLrE+n7VMhaqX+BUnyWkCu27rl+62Adug==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.13.tgz", - "integrity": "sha512-8pcKDApAsKc6WW51ZEVidSGwGbebYw2qKnO1VyD8xd6JN0RN6EUXfhXmDk9Vc4/U3Y4AoFTexQewQDJGsBXBpg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.13.tgz", - "integrity": "sha512-6GU+J1PLiVqWx8yoCK4Z0GnfKyCGIH5L2KQipxOtbNPBs+qNDcMJr9euxnyJ6FkRPyMwaSkjejzPSISD9hb+gg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.13.tgz", - "integrity": "sha512-pfn/OGZ8tyR8YCV7MlLl5hAit2cmS+j/ZZg9DdH0uxdCoJpV7+5DbuXrR+es4ayRVKIcfS9TTMCs60vqQDmh+w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.13.tgz", - "integrity": "sha512-aIbhU3LPg0lOSCfVeGHbmGYIqOtW6+yzO+Nfv57YblEK01oj0mFMtvDJlOaeAZ6z0FZ9D13oahi5aIl9JFphGg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.13.tgz", - "integrity": "sha512-Pct1QwF2sp+5LVi4Iu5Y+6JsGaV2Z2vm4O9Dd7XZ5tKYxEHjFtb140fiMcl5HM1iuv6xXO8O1Vrb1iJxHlv8UA==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.13.tgz", - "integrity": "sha512-zTrIP0KzYP7O0+3ZnmzvUKgGtUvf4+piY8PIO3V8/GfmVd3ZyHJGz7Ht0np3P1wz+I8qJ4rjwJKqqEAbIEPngA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.13.tgz", - "integrity": "sha512-I6zs10TZeaHDYoGxENuksxE1sxqZpCp+agYeW039yqFwh3MgVvdmXL5NMveImOC6AtpLvE4xG5ujVic4NWFIDQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.13.tgz", - "integrity": "sha512-W5C5nczhrt1y1xPG5bV+0M12p2vetOGlvs43LH8SopQ3z2AseIROu09VgRqydx5qFN7y9qCbpgHLx0kb0TcW7g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.13.tgz", - "integrity": "sha512-X/xzuw4Hzpo/yq3YsfBbIsipNgmsm8mE/QeWbdGdTTeZ77fjxI2K0KP3AlhZ6gU3zKTw1bKoZTuKLnqcJ537qw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.13.tgz", - "integrity": "sha512-4CGYdRQT/ILd+yLLE5i4VApMPfGE0RPc/wFQhlluDQCK09+b4JDbxzzjpgQqTPrdnP7r5KUtGVGZYclYiPuHrw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.13", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.13.tgz", - "integrity": "sha512-D+wKZaRhQI+MUGMH+DbEr4owC2D7XnF+uyGiZk38QbgzLcofFqIOwFs7ELmIeU45CQgfHNy9Q+LKW3cE8g37Kg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/win32-x64": { "version": "0.18.13", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.13.tgz", @@ -2851,20 +2511,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5198,14 +4844,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } }