| @@ -0,0 +1,92 @@ | |||
| const validator = require('validator'); | |||
| import { ProductData as IProduct } from '../utils/interface/productInterface'; | |||
| import { OrderData as IOrder } from '../utils/interface/orderInterface'; | |||
| import { Schema, model, Types } from 'mongoose'; | |||
| const OrderSchema = new Schema<IOrder>( | |||
| { | |||
| products: Array<IProduct>, | |||
| time: { | |||
| type: Date, | |||
| required: [true, 'Please provide a date.'], | |||
| validate(value: Date) { | |||
| if (!validator.isDate(value)) { | |||
| throw new Error('Not a date'); | |||
| } | |||
| }, | |||
| }, | |||
| shippingAddress: { | |||
| country: { | |||
| type: String, | |||
| required: [true, 'Please provide a country.'], | |||
| trim: true, | |||
| }, | |||
| city: { | |||
| type: String, | |||
| required: [true, 'Please provide a city.'], | |||
| trim: true, | |||
| }, | |||
| address: { | |||
| type: String, | |||
| required: [true, 'Please provide an address.'], | |||
| trim: true, | |||
| }, | |||
| address2: { | |||
| type: String, | |||
| trim: true, | |||
| }, | |||
| postcode: { | |||
| type: String, | |||
| required: [true, 'Please provide a postal code.'], | |||
| }, | |||
| email: { | |||
| type: String, | |||
| required: [true, 'Please provide an email.'], | |||
| }, | |||
| fullName: { | |||
| type: String, | |||
| required: [true, 'Please provide a name.'], | |||
| }, | |||
| }, | |||
| totalPrice: { | |||
| type: Number, | |||
| required: [true, 'Please provide a total price.'], | |||
| validate(value: number) { | |||
| if (value < 0) { | |||
| throw new Error('Total price must be a postive number'); | |||
| } | |||
| }, | |||
| }, | |||
| numberOfItems: { | |||
| type: Number, | |||
| required: [true, 'Please provide a total number of items.'], | |||
| validate(value: number) { | |||
| if (value < 0) { | |||
| throw new Error('Number of items must be a postive number'); | |||
| } | |||
| }, | |||
| }, | |||
| fulfilled: { | |||
| type: Boolean, | |||
| default: false, | |||
| }, | |||
| owner: { | |||
| type: Types.ObjectId, | |||
| required: [true, 'Please provide an owner.'], | |||
| ref: 'User', | |||
| }, | |||
| stripeCheckoutId: { | |||
| type: String, | |||
| required: [true, 'Please provide a stripe checkout id.'], | |||
| }, | |||
| }, | |||
| { | |||
| toJSON: { virtuals: true }, // So `res.json()` and other `JSON.stringify()` functions include virtuals | |||
| toObject: { virtuals: true }, // So `console.log()` and other functions that use `toObject()` include virtuals | |||
| } | |||
| ); | |||
| const Order = model<IOrder>('Order', OrderSchema, 'Order'); | |||
| module.exports = Order; | |||
| @@ -0,0 +1,73 @@ | |||
| import { ProductData as IProduct } from '../utils/interface/productInterface'; | |||
| import { Schema, model } from 'mongoose'; | |||
| const ProductSchema = new Schema<IProduct>({ | |||
| category: { | |||
| type: String, | |||
| required: [true, 'Please provide a category.'], | |||
| maxlength: 100, | |||
| trim: true, | |||
| }, | |||
| name: { | |||
| type: String, | |||
| required: [true, 'Please provide a name.'], | |||
| maxlength: 100, | |||
| trim: true, | |||
| }, | |||
| image: { | |||
| type: String, | |||
| required: [true, 'Please provide an image.'], | |||
| }, | |||
| description: { | |||
| type: String, | |||
| required: [true, 'Please provide a description.'], | |||
| trim: true, | |||
| }, | |||
| place: { | |||
| type: String, | |||
| trim: true, | |||
| }, | |||
| people: { | |||
| type: String, | |||
| trim: true, | |||
| }, | |||
| process: { | |||
| type: String, | |||
| trim: true, | |||
| }, | |||
| pairing: { | |||
| type: String, | |||
| trim: true, | |||
| }, | |||
| available: { | |||
| type: Boolean, | |||
| default: true, | |||
| }, | |||
| isFeatured: { | |||
| type: Boolean, | |||
| default: false, | |||
| }, | |||
| price: { | |||
| type: Number, | |||
| required: [true, 'Please provide a price.'], | |||
| validate(value: number) { | |||
| if (value < 0) { | |||
| throw new Error('Price must be a postive number'); | |||
| } | |||
| }, | |||
| }, | |||
| customID: { | |||
| type: String, | |||
| required: [true, 'Please provide a custom id.'], | |||
| unique: true, | |||
| }, | |||
| stripeID: { | |||
| type: String, | |||
| required: [true, 'Please provide a stripe id.'], | |||
| unique: true, | |||
| }, | |||
| }); | |||
| const Product = model<IProduct>('Product', ProductSchema); | |||
| module.exports = Product; | |||
| @@ -0,0 +1,39 @@ | |||
| import { Schema, model } from 'mongoose'; | |||
| import { QuestionData as IQusetion } from '../utils/interface/questionInterface'; | |||
| const validator = require('validator'); | |||
| const QuestionSchema = new Schema<IQusetion>({ | |||
| firstName: { | |||
| type: String, | |||
| required: [true, 'Please provide a name.'], | |||
| maxlength: [60, 'Name cannot be more than 60 characters'], | |||
| trim: true, | |||
| }, | |||
| lastName: { | |||
| type: String, | |||
| required: [true, 'Please provide a last name.'], | |||
| maxlength: [60, 'Name cannot be more than 60 characters'], | |||
| trim: true, | |||
| }, | |||
| email: { | |||
| type: String, | |||
| required: [true, 'Please provide an email.'], | |||
| trim: true, | |||
| lowercase: true, | |||
| unique: false, | |||
| validate(value: string) { | |||
| if (!validator.isEmail(value)) { | |||
| throw new Error('Email is invalid'); | |||
| } | |||
| }, | |||
| }, | |||
| message: { | |||
| type: String, | |||
| required: [true, 'Please provide a message/question.'], | |||
| trim: true, | |||
| }, | |||
| }); | |||
| const Question = model<IQusetion>('Question', QuestionSchema, 'Questions'); | |||
| module.exports = Question; | |||
| @@ -0,0 +1,128 @@ | |||
| import { Schema, model, Model } from 'mongoose'; | |||
| import { | |||
| hashPassword, | |||
| verifyPassword, | |||
| } from '../utils/helpers/hashPasswordHelpers'; | |||
| import { IUser } from '../utils/interface/userInterface'; | |||
| const validator = require('validator'); | |||
| interface UserModel extends Model<IUser, {}, {}> { | |||
| findByCredentials(username: string, password: string): object; | |||
| } | |||
| const UserSchema = new Schema<IUser, UserModel>( | |||
| { | |||
| fullName: { | |||
| type: String, | |||
| required: [true, 'Please provide a name.'], | |||
| maxlength: [60, 'Name cannot be more than 60 characters'], | |||
| trim: true, | |||
| }, | |||
| username: { | |||
| type: String, | |||
| required: [true, 'Please provide an username.'], | |||
| unique: true, | |||
| maxlength: [60, 'Name cannot be more than 60 characters'], | |||
| trim: true, | |||
| }, | |||
| email: { | |||
| type: String, | |||
| unique: true, | |||
| required: [true, 'Please provide an email.'], | |||
| trim: true, | |||
| lowercase: true, | |||
| validate(value: string) { | |||
| if (!validator.isEmail(value)) { | |||
| throw new Error('Email is invalid'); | |||
| } | |||
| }, | |||
| }, | |||
| password: { | |||
| type: String, | |||
| required: [true, 'Please provide a password.'], | |||
| minlength: 7, | |||
| trim: true, | |||
| validate(value: string) { | |||
| if (value.toLowerCase().includes('password')) { | |||
| throw new Error('Password cannot contain "password"'); | |||
| } | |||
| }, | |||
| }, | |||
| country: { | |||
| type: String, | |||
| required: [true, 'Please provide a country.'], | |||
| trim: true, | |||
| }, | |||
| city: { | |||
| type: String, | |||
| required: [true, 'Please provide a city.'], | |||
| trim: true, | |||
| }, | |||
| address: { | |||
| type: String, | |||
| required: [true, 'Please provide an address.'], | |||
| trim: true, | |||
| }, | |||
| address2: { | |||
| type: String, | |||
| trim: true, | |||
| }, | |||
| postcode: { | |||
| type: String, | |||
| required: [true, 'Please provide a postal code.'], | |||
| }, | |||
| }, | |||
| { | |||
| toJSON: { virtuals: true }, // So `res.json()` and other `JSON.stringify()` functions include virtuals | |||
| toObject: { virtuals: true }, // So `console.log()` and other functions that use `toObject()` include virtuals | |||
| } | |||
| ); | |||
| UserSchema.virtual('orders', { | |||
| ref: 'Order', | |||
| localField: '_id', | |||
| foreignField: 'owner', | |||
| }); | |||
| UserSchema.static( | |||
| 'findByCredentials', | |||
| async function findByCredentials(username: string, password: string) { | |||
| const user = await User.findOne({ username }); | |||
| if (!user) { | |||
| throw new Error('Unable to login'); | |||
| } | |||
| const isMatch = await verifyPassword(password, user.password); | |||
| if (!isMatch) { | |||
| throw new Error('Unable to login'); | |||
| } | |||
| const userData = { | |||
| fullName: user.fullName, | |||
| email: user.email, | |||
| address: user.address, | |||
| address2: user.address2, | |||
| city: user.city, | |||
| country: user.country, | |||
| postcode: user.postcode, | |||
| orders: user.orders, | |||
| _id: user._id, | |||
| }; | |||
| return userData; | |||
| } | |||
| ); | |||
| UserSchema.pre('save', async function (next) { | |||
| const user = this; | |||
| if (user.isModified('password')) { | |||
| user.password = await hashPassword(user.password); | |||
| } | |||
| next(); | |||
| }); | |||
| const User = model<IUser, UserModel>('User', UserSchema, 'User'); | |||
| module.exports = User; | |||
| @@ -25,7 +25,13 @@ | |||
| "react": "18.2.0", | |||
| "react-dom": "18.2.0", | |||
| "react-i18next": "^11.18.6", | |||
| "yup": "^0.32.11" | |||
| "yup": "^0.32.11", | |||
| "@sendgrid/mail": "^7.7.0", | |||
| "@types/bcryptjs": "^2.4.2", | |||
| "@types/validator": "^13.7.7", | |||
| "bcryptjs": "^2.4.3", | |||
| "mongoose": "^6.6.5", | |||
| "validator": "^13.7.0" | |||
| }, | |||
| "devDependencies": { | |||
| "@tanstack/react-query-devtools": "^4.11.0", | |||
| @@ -0,0 +1,40 @@ | |||
| import NextAuth from 'next-auth'; | |||
| import Credentials from 'next-auth/providers/credentials'; | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| const User = require('../../../models/user'); | |||
| export default NextAuth({ | |||
| session: { | |||
| strategy: 'jwt', | |||
| }, | |||
| callbacks: { | |||
| async jwt({ token, user, account, profile, isNewUser }) { | |||
| return { ...token, ...user }; | |||
| }, | |||
| async session({ session, token, user }) { | |||
| return session; | |||
| }, | |||
| }, | |||
| providers: [ | |||
| Credentials({ | |||
| name: 'Credentials', | |||
| credentials: { | |||
| username: { label: 'Username', type: 'text' }, | |||
| password: { label: 'Password', type: 'password' }, | |||
| }, | |||
| // @ts-ignore | |||
| async authorize(credentials) { | |||
| if (credentials) { | |||
| await dbConnect(); | |||
| const userData = await User.findByCredentials( | |||
| credentials.username, | |||
| credentials.password | |||
| ); | |||
| return { user: userData }; | |||
| } | |||
| return null; | |||
| }, | |||
| }), | |||
| ], | |||
| }); | |||
| @@ -0,0 +1,34 @@ | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| import { UpdateResponse, IUser } from '../../../utils/interface/userInterface'; | |||
| const User = require('../../../models/user'); | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<UpdateResponse> | |||
| ) { | |||
| const { method } = req; | |||
| await dbConnect(); | |||
| switch (method) { | |||
| case 'POST': { | |||
| try { | |||
| const user: IUser = await User.create(req.body); | |||
| res | |||
| .status(201) | |||
| .json({ message: `User (${user.fullName}) created sucessfully!` }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| res.status(405).json({ message: 'Method not allowed' }); | |||
| break; | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -1,13 +0,0 @@ | |||
| // Next.js API route support: https://nextjs.org/docs/api-routes/introduction | |||
| import type { NextApiRequest, NextApiResponse } from 'next' | |||
| type Data = { | |||
| name: string | |||
| } | |||
| export default function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<Data> | |||
| ) { | |||
| res.status(200).json({ name: 'John Doe' }) | |||
| } | |||
| @@ -0,0 +1,66 @@ | |||
| const Order = require('../../../models/order'); | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| import { Types } from 'mongoose'; | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import { | |||
| OrderResponse, | |||
| OrderDataDB, | |||
| } from '../../../utils/interface/orderInterface'; | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<OrderResponse> | |||
| ) { | |||
| const { method } = req; | |||
| const ownerID = req.query.ownerID as string; | |||
| await dbConnect(); | |||
| switch (method) { | |||
| case 'POST': { | |||
| try { | |||
| const order: OrderDataDB = await Order.create( | |||
| req.body | |||
| ); /* create a new model in the database */ | |||
| res | |||
| .status(201) | |||
| .json({ message: 'Your order was submitted successfully!', order }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| case 'GET': { | |||
| try { | |||
| const objectId = new Types.ObjectId(ownerID); | |||
| const orders: Array<OrderDataDB> = await Order.find({ | |||
| owner: objectId, | |||
| }); | |||
| if (!orders) { | |||
| res.status(200).json({ | |||
| message: | |||
| 'There are currently no orders in our database for the selected owner.', | |||
| orders: [], | |||
| }); | |||
| } | |||
| res.status(200).json({ | |||
| message: | |||
| 'All orders from our database for the selected owner were fetched successfully.', | |||
| orders, | |||
| }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| res.status(405).json({ message: 'Method not allowed' }); | |||
| break; | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -0,0 +1,57 @@ | |||
| const Product = require('../../../models/product'); | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import { | |||
| ProductDataDB, | |||
| SingleProductResponse, | |||
| } from '../../../utils/interface/productInterface'; | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<SingleProductResponse> | |||
| ) { | |||
| const { method } = req; | |||
| await dbConnect(); | |||
| switch (method) { | |||
| case 'GET': { | |||
| try { | |||
| const productId = req.query.productId; | |||
| const product: ProductDataDB = await Product.findOne({ | |||
| customID: productId, | |||
| }); | |||
| if (!product) { | |||
| throw new Error('The product with this id does not exist!'); | |||
| } | |||
| const similarProducts: Array<ProductDataDB> = await Product.find({ | |||
| category: product.category, | |||
| customID: { $ne: product.customID }, | |||
| }); | |||
| const shuffled = similarProducts | |||
| .sort(() => 0.5 - Math.random()) | |||
| .slice(0, 3); | |||
| res.status(200).json({ | |||
| message: 'The product you requested was fetched successfully.', | |||
| product, | |||
| similarProducts: shuffled, | |||
| }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| res.status(405).json({ message: 'Method not allowed' }); | |||
| break; | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -0,0 +1,48 @@ | |||
| const Product = require('../../../models/product'); | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import { | |||
| ProductDataDB, | |||
| FeaturedProductsResponse, | |||
| } from '../../../utils/interface/productInterface'; | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<FeaturedProductsResponse> | |||
| ) { | |||
| const { method } = req; | |||
| await dbConnect(); | |||
| switch (method) { | |||
| case 'GET': { | |||
| try { | |||
| const featuredProducts: Array<ProductDataDB> = await Product.find({ | |||
| isFeatured: true, | |||
| }); | |||
| if (!featuredProducts) { | |||
| res.status(200).json({ | |||
| message: 'There are no featured products right now.', | |||
| featuredProducts: [], | |||
| }); | |||
| } | |||
| res.status(200).json({ | |||
| message: 'Featured products were fetched successfully.', | |||
| featuredProducts, | |||
| }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| res.status(405).json({ message: 'Method not allowed' }); | |||
| break; | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -0,0 +1,103 @@ | |||
| const Product = require('../../../models/product'); | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import { | |||
| ProductDataDB, | |||
| ProductsResponse, | |||
| } from '../../../utils/interface/productInterface'; | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<ProductsResponse> | |||
| ) { | |||
| const { method } = req; | |||
| await dbConnect(); | |||
| const pageIndex = parseInt(req.query.pageIndex as string); | |||
| const category = req.query.category === 'All' ? '' : req.query.category; | |||
| const filterType = req.query.filterType; | |||
| if (pageIndex < 1) { | |||
| res.status(422).json({ | |||
| message: 'Page does not exist ', | |||
| }); | |||
| return; | |||
| } | |||
| switch (method) { | |||
| case 'GET': { | |||
| try { | |||
| const productCount: number = await Product.find({ | |||
| category: { $regex: category }, | |||
| }).countDocuments(); | |||
| if (productCount === 0) { | |||
| res.status(200).json({ | |||
| message: 'There are currently no products in our database.', | |||
| product: [], | |||
| productCount: 0, | |||
| next: '', | |||
| previous: '', | |||
| }); | |||
| break; | |||
| } | |||
| if ((pageIndex - 1) * 9 >= productCount) { | |||
| throw new Error('Page does not exist!'); | |||
| } | |||
| const product: Array<ProductDataDB> = await Product.find({ | |||
| category: { $regex: category }, | |||
| }) | |||
| .skip((pageIndex - 1) * 9) | |||
| .limit(9) | |||
| .sort(filterType === 'asc' ? 'name' : '-name '); | |||
| if (!product) { | |||
| throw new Error('There are currently no products in our database.'); | |||
| } | |||
| const previousUrl = | |||
| pageIndex > 1 | |||
| ? `https://localhost:3000/api/product?pageIndex=${pageIndex - 1}` | |||
| : ''; | |||
| const nextUrl = | |||
| pageIndex * 9 < productCount | |||
| ? `https://localhost:3000/api/product?pageIndex=${pageIndex + 1}` | |||
| : ''; | |||
| res.status(200).json({ | |||
| message: 'All products from our database were fetched successfully.', | |||
| product, | |||
| productCount, | |||
| next: nextUrl, | |||
| previous: previousUrl, | |||
| }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| case 'POST': { | |||
| try { | |||
| const product: ProductDataDB = await Product.create(req.body); | |||
| res | |||
| .status(201) | |||
| .json({ message: 'Your product was created and stored!', product }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| res.status(405).json({ message: 'Method not allowed' }); | |||
| break; | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -0,0 +1,54 @@ | |||
| const Question = require('../../../models/question'); | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| const sgMail = require('@sendgrid/mail'); | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import { | |||
| QuestionDataDB, | |||
| QuestionResponse, | |||
| } from '../../../utils/interface/questionInterface'; | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<QuestionResponse> | |||
| ) { | |||
| const { method } = req; | |||
| await dbConnect(); | |||
| switch (method) { | |||
| case 'POST': { | |||
| try { | |||
| const question: QuestionDataDB = await Question.create(req.body); | |||
| sgMail.setApiKey(process.env.NEXT_PUBLIC_SEND_GRID); | |||
| const msg = { | |||
| to: '[email protected]', //req.body.email, // Change to your recipient | |||
| from: '[email protected]', // Change to your verified sender | |||
| subject: 'Question submitted', | |||
| text: 'Your question was submitted successfully, we will contact you via email shortly. Thank you!', | |||
| html: '<strong>Your question was submitted successfully, we will contact you via email shortly. Thank you!</strong>', | |||
| }; | |||
| sgMail.send(msg).then(() => { | |||
| console.log('Email sent'); | |||
| }); | |||
| res.status(201).json({ | |||
| message: | |||
| 'Your message/question was submitted successfully, check your mail for confirmation.', | |||
| question, | |||
| }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| default: | |||
| res.status(405).json({ message: 'Method not allowed' }); | |||
| break; | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -0,0 +1,51 @@ | |||
| const User = require('../../../models/user'); | |||
| import dbConnect from '../../../utils/helpers/dbHelpers'; | |||
| import type { NextApiRequest, NextApiResponse } from 'next'; | |||
| import { UpdateResponse } from '../../../utils/interface/userInterface'; | |||
| async function handler( | |||
| req: NextApiRequest, | |||
| res: NextApiResponse<UpdateResponse> | |||
| ) { | |||
| const { method } = req; | |||
| await dbConnect(); | |||
| switch (method) { | |||
| case 'PATCH': { | |||
| const updates = Object.keys(req.body.userData); | |||
| const allowedUpdates = [ | |||
| 'fullName', | |||
| 'email', | |||
| 'address', | |||
| 'address2', | |||
| 'city', | |||
| 'country', | |||
| 'postcode', | |||
| ]; | |||
| const isValidOperation = updates.every((update) => | |||
| allowedUpdates.includes(update) | |||
| ); | |||
| if (!isValidOperation) { | |||
| return res.status(400).send({ message: 'Invalid updates!' }); | |||
| } | |||
| try { | |||
| const user = await User.findOne({ _id: req.body._id }); | |||
| updates.forEach((update) => (user[update] = req.body.userData[update])); | |||
| await user.save(); | |||
| res.send({ | |||
| message: 'User profile updated successfully.', | |||
| }); | |||
| } catch (error) { | |||
| if (error instanceof Error) | |||
| res.status(400).json({ message: error.message }); | |||
| else res.status(400).json({ message: 'Unexpected error' + error }); | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| export default handler; | |||
| @@ -1,23 +1,14 @@ | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| import { OrderData } from '../../utils/interface/orderInterface'; | |||
| import { OrderResponseGet } from '../../utils/interface/orderInterface'; | |||
| interface OrderDataDB extends OrderData { | |||
| id: string; | |||
| _id: string; | |||
| __v: number; | |||
| } | |||
| interface OrderResponse { | |||
| message: string; | |||
| orders: Array<OrderDataDB>; | |||
| } | |||
| export const getOrdersForOwner = async (id: string): Promise<OrderResponse> => { | |||
| export const getOrdersForOwner = async ( | |||
| id: string | |||
| ): Promise<OrderResponseGet> => { | |||
| const response = await fetch( | |||
| `http://localhost:3000${apiEndpoints.order}?ownerID=${id}` | |||
| ); | |||
| const data: OrderResponse = await response.json(); | |||
| const data: OrderResponseGet = await response.json(); | |||
| if (!response.ok) { | |||
| throw new Error(data.message || 'Something went wrong!'); | |||
| @@ -1,19 +1,12 @@ | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| import { OrderData } from '../../utils/interface/orderInterface'; | |||
| import { | |||
| OrderResponsePost, | |||
| OrderData, | |||
| } from '../../utils/interface/orderInterface'; | |||
| interface OrderDataDB extends OrderData { | |||
| id: string; | |||
| _id: string; | |||
| __v: number; | |||
| } | |||
| interface OrderResponse { | |||
| message: string; | |||
| order: OrderDataDB; | |||
| } | |||
| export const postOrder = async ( | |||
| orderData: OrderData | |||
| ): Promise<OrderResponse> => { | |||
| ): Promise<OrderResponsePost> => { | |||
| const response = await fetch(`http://localhost:3000${apiEndpoints.order}`, { | |||
| method: 'POST', | |||
| body: JSON.stringify(orderData), | |||
| @@ -22,7 +15,7 @@ export const postOrder = async ( | |||
| }, | |||
| }); | |||
| const data: OrderResponse = await response.json(); | |||
| const data: OrderResponsePost = await response.json(); | |||
| if (!response.ok) { | |||
| throw new Error(data.message || 'Something went wrong!'); | |||
| @@ -1,17 +1,6 @@ | |||
| import { ProductData } from '../../utils/interface/productInterface'; | |||
| import { FeaturedProductsResponse } from '../../utils/interface/productInterface'; | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| interface ProductDataDB extends ProductData { | |||
| id: string; | |||
| _id: string; | |||
| __v: number; | |||
| } | |||
| interface FeaturedProductsResponse { | |||
| message: string; | |||
| featuredProducts: Array<ProductDataDB>; | |||
| } | |||
| export const getFeaturedProducts = | |||
| async (): Promise<FeaturedProductsResponse> => { | |||
| const response = await fetch( | |||
| @@ -1,11 +1,6 @@ | |||
| import { SingleProductResponse } from '../../utils/interface/productInterface'; | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| interface SingleProductResponse { | |||
| message: string; | |||
| product: object; | |||
| similarProducts: Array<object>; | |||
| } | |||
| export const getProductData = async ( | |||
| productId: string | |||
| ): Promise<SingleProductResponse> => { | |||
| @@ -1,13 +1,6 @@ | |||
| import { ProductsResponse } from '../../utils/interface/productInterface'; | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| interface ProductsResponse { | |||
| message: string; | |||
| product: object; | |||
| productCount: number; | |||
| next: string; | |||
| previous: string; | |||
| } | |||
| export const getAllProducts = async ( | |||
| pageIndex: number, | |||
| category = 'All', | |||
| @@ -1,10 +1,8 @@ | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| import { QuestionData } from '../../utils/interface/questionInterface'; | |||
| interface QuestionResponse { | |||
| message: string; | |||
| question: { [key: string]: string }; | |||
| } | |||
| import { | |||
| QuestionData, | |||
| QuestionResponse, | |||
| } from '../../utils/interface/questionInterface'; | |||
| export const postQuestion = async ( | |||
| questionData: QuestionData | |||
| @@ -1,9 +1,5 @@ | |||
| import apiEndpoints from '../apiEndpoints'; | |||
| import { UserData } from '../../utils/interface/userInterface'; | |||
| interface UpdateResponse { | |||
| message: string; | |||
| } | |||
| import { UserData, UpdateResponse } from '../../utils/interface/userInterface'; | |||
| export const updateUser = async ( | |||
| userData: UserData, | |||
| @@ -0,0 +1,51 @@ | |||
| import { MongoClient } from 'mongodb'; | |||
| import mongoose from 'mongoose'; | |||
| export async function connectToDatabase() { | |||
| const client = await MongoClient.connect(process.env.MONGODB_URI!); | |||
| return client; | |||
| } | |||
| declare global { | |||
| var mongoose: any; | |||
| } | |||
| const MONGODB_URI = process.env.MONGODB_URI; | |||
| if (!MONGODB_URI) { | |||
| throw new Error( | |||
| 'Please define the MONGODB_URI environment variable inside .env.local' | |||
| ); | |||
| } | |||
| /** | |||
| * Global is used here to maintain a cached connection across hot reloads | |||
| * in development. This prevents connections growing exponentially | |||
| * during API Route usage. | |||
| */ | |||
| let cached = global.mongoose; | |||
| if (!cached) { | |||
| cached = global.mongoose = { conn: null, promise: null }; | |||
| } | |||
| async function dbConnect() { | |||
| if (cached.conn) { | |||
| return cached.conn; | |||
| } | |||
| if (!cached.promise) { | |||
| const opts = { | |||
| bufferCommands: false, | |||
| }; | |||
| cached.promise = mongoose.connect(MONGODB_URI!, opts).then((mongoose) => { | |||
| return mongoose; | |||
| }); | |||
| } | |||
| cached.conn = await cached.promise; | |||
| return cached.conn; | |||
| } | |||
| export default dbConnect; | |||
| @@ -0,0 +1,11 @@ | |||
| import { hash, compare } from 'bcryptjs'; | |||
| export async function hashPassword(password: string) { | |||
| const hashedPassword = await hash(password, 12); | |||
| return hashedPassword; | |||
| } | |||
| export async function verifyPassword(password: string, hashedPassword: string) { | |||
| const isValid = await compare(password, hashedPassword); | |||
| return isValid; | |||
| } | |||
| @@ -16,3 +16,28 @@ export interface OrderData { | |||
| owner: ObjectId; | |||
| stripeCheckoutId: string; | |||
| } | |||
| export interface OrderDataDB extends OrderData { | |||
| id: string; | |||
| _id: string; | |||
| __v: number; | |||
| } | |||
| export interface OrderResponseGet { | |||
| message: string; | |||
| orders: Array<OrderDataDB>; | |||
| } | |||
| export interface OrderResponsePost { | |||
| message: string; | |||
| order: OrderDataDB; | |||
| } | |||
| export interface OrderResponseError { | |||
| message: string; | |||
| } | |||
| export type OrderResponse = | |||
| | OrderResponseGet | |||
| | OrderResponsePost | |||
| | OrderResponseError; | |||
| @@ -13,3 +13,50 @@ export interface ProductData { | |||
| customID: string; | |||
| stripeID: string; | |||
| } | |||
| export interface ProductDataDB extends ProductData { | |||
| id: string; | |||
| _id: string; | |||
| __v: number; | |||
| } | |||
| export interface FeaturedProductsResponseGet { | |||
| message: string; | |||
| featuredProducts: Array<ProductDataDB>; | |||
| } | |||
| export interface ProductsResponseGet { | |||
| message: string; | |||
| product: Array<ProductData>; | |||
| productCount: number; | |||
| next: string; | |||
| previous: string; | |||
| } | |||
| export interface ProductsResponseError { | |||
| message: string; | |||
| } | |||
| export interface ProductsResponsePost { | |||
| message: string; | |||
| product: ProductData; | |||
| } | |||
| interface SingleProductResponseGet { | |||
| message: string; | |||
| product: ProductDataDB; | |||
| similarProducts: Array<ProductDataDB>; | |||
| } | |||
| export type SingleProductResponse = | |||
| | SingleProductResponseGet | |||
| | ProductsResponseError; | |||
| export type ProductsResponse = | |||
| | ProductsResponseGet | |||
| | ProductsResponsePost | |||
| | ProductsResponseError; | |||
| export type FeaturedProductsResponse = | |||
| | FeaturedProductsResponseGet | |||
| | ProductsResponseError; | |||
| @@ -4,3 +4,20 @@ export interface QuestionData { | |||
| lastName: string; | |||
| message: string; | |||
| } | |||
| export interface QuestionDataDB extends QuestionData { | |||
| id: string; | |||
| _id: string; | |||
| __v: number; | |||
| } | |||
| export interface QuestionResponsePost { | |||
| message: string; | |||
| question: QuestionData; | |||
| } | |||
| export interface QuestionError { | |||
| message: string; | |||
| } | |||
| export type QuestionResponse = QuestionResponsePost | QuestionError; | |||
| @@ -6,3 +6,14 @@ export interface UserData { | |||
| fullName: string; | |||
| postcode: string; | |||
| } | |||
| export interface IUser extends UserData { | |||
| email: string; | |||
| username: string; | |||
| password: string; | |||
| orders?: Array<object>; | |||
| } | |||
| export interface UpdateResponse { | |||
| message: string; | |||
| } | |||
| @@ -343,13 +343,18 @@ | |||
| dependencies: | |||
| regenerator-runtime "^0.13.4" | |||
| <<<<<<< HEAD | |||
| "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.19.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": | |||
| ======= | |||
| "@babel/runtime@^7.16.3": | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| version "7.19.4" | |||
| resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" | |||
| integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== | |||
| dependencies: | |||
| regenerator-runtime "^0.13.4" | |||
| <<<<<<< HEAD | |||
| "@babel/template@^7.18.10": | |||
| version "7.18.10" | |||
| resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" | |||
| @@ -492,6 +497,8 @@ | |||
| resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" | |||
| integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| "@eslint/eslintrc@^1.3.3": | |||
| version "1.3.3" | |||
| resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" | |||
| @@ -774,20 +781,48 @@ | |||
| resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.0.2.tgz#bab0f09d09de9fd83628220d496627681bc440d6" | |||
| integrity sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA== | |||
| <<<<<<< HEAD | |||
| "@popperjs/core@^2.11.6": | |||
| version "2.11.6" | |||
| resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" | |||
| integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| "@rushstack/eslint-patch@^1.1.3": | |||
| version "1.2.0" | |||
| resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" | |||
| integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== | |||
| <<<<<<< HEAD | |||
| "@stripe/stripe-js@^1.39.0": | |||
| version "1.39.0" | |||
| resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.39.0.tgz#b70d4d276862771c4b2c86558795358e08f0b77e" | |||
| integrity sha512-BR7yzewVSBQgRao3V4HsTldpO4HpJUKcIlMDmBQaHqXUvkMpXHgOMF8/CZgFVMACS+pqvZIMmGuy3YvZlLEA2w== | |||
| ======= | |||
| "@sendgrid/client@^7.7.0": | |||
| version "7.7.0" | |||
| resolved "https://registry.yarnpkg.com/@sendgrid/client/-/client-7.7.0.tgz#f8f67abd604205a0d0b1af091b61517ef465fdbf" | |||
| integrity sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA== | |||
| dependencies: | |||
| "@sendgrid/helpers" "^7.7.0" | |||
| axios "^0.26.0" | |||
| "@sendgrid/helpers@^7.7.0": | |||
| version "7.7.0" | |||
| resolved "https://registry.yarnpkg.com/@sendgrid/helpers/-/helpers-7.7.0.tgz#93fb4b6e2f0dc65080440d6a784cc93e8e148757" | |||
| integrity sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw== | |||
| dependencies: | |||
| deepmerge "^4.2.2" | |||
| "@sendgrid/mail@^7.7.0": | |||
| version "7.7.0" | |||
| resolved "https://registry.yarnpkg.com/@sendgrid/mail/-/mail-7.7.0.tgz#aba09f5ce2e9d8ceee92284c3ea8b4a90b0e38fe" | |||
| integrity sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw== | |||
| dependencies: | |||
| "@sendgrid/client" "^7.7.0" | |||
| "@sendgrid/helpers" "^7.7.0" | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| "@swc/[email protected]": | |||
| version "0.4.11" | |||
| @@ -796,6 +831,7 @@ | |||
| dependencies: | |||
| tslib "^2.4.0" | |||
| <<<<<<< HEAD | |||
| "@tanstack/match-sorter-utils@^8.1.1": | |||
| version "8.5.14" | |||
| resolved "https://registry.yarnpkg.com/@tanstack/match-sorter-utils/-/match-sorter-utils-8.5.14.tgz#12efcd536abe491d09521e0242bc4d51442f8a8a" | |||
| @@ -832,6 +868,12 @@ | |||
| dependencies: | |||
| "@types/react" "*" | |||
| hoist-non-react-statics "^3.3.0" | |||
| ======= | |||
| "@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== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| "@types/json5@^0.0.29": | |||
| version "0.0.29" | |||
| @@ -900,6 +942,11 @@ | |||
| resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" | |||
| integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== | |||
| "@types/validator@^13.7.7": | |||
| version "13.7.7" | |||
| resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.7.tgz#e87cf34dd08522d21acf30130fd8941f433b81b5" | |||
| integrity sha512-jiEw2kTUJ8Jsh4A1K4b5Pkjj9Xz6FktLLOQ36ZVLRkmxFbpTvAV2VRoKMojz8UlZxNg/2dZqzpigH4JYn1bkQg== | |||
| "@types/webidl-conversions@*": | |||
| version "7.0.0" | |||
| resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7" | |||
| @@ -1092,6 +1139,13 @@ axe-core@^4.4.3: | |||
| resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" | |||
| integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== | |||
| axios@^0.26.0: | |||
| version "0.26.1" | |||
| resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" | |||
| integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== | |||
| dependencies: | |||
| follow-redirects "^1.14.8" | |||
| axobject-query@^2.2.0: | |||
| version "2.2.0" | |||
| resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" | |||
| @@ -1128,6 +1182,7 @@ base64-js@^1.3.1: | |||
| resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" | |||
| integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== | |||
| <<<<<<< HEAD | |||
| base@^0.11.1: | |||
| version "0.11.2" | |||
| resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" | |||
| @@ -1140,6 +1195,12 @@ base@^0.11.1: | |||
| isobject "^3.0.1" | |||
| mixin-deep "^1.2.0" | |||
| pascalcase "^0.1.1" | |||
| ======= | |||
| 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== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| brace-expansion@^1.1.7: | |||
| version "1.1.11" | |||
| @@ -1172,6 +1233,7 @@ braces@^3.0.2: | |||
| dependencies: | |||
| fill-range "^7.0.1" | |||
| <<<<<<< HEAD | |||
| browserslist@^4.21.3: | |||
| version "4.21.4" | |||
| resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" | |||
| @@ -1183,6 +1245,9 @@ browserslist@^4.21.3: | |||
| update-browserslist-db "^1.0.9" | |||
| bson@^4.7.0: | |||
| ======= | |||
| bson@^4.6.5, bson@^4.7.0: | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| version "4.7.0" | |||
| resolved "https://registry.yarnpkg.com/bson/-/bson-4.7.0.tgz#7874a60091ffc7a45c5dd2973b5cad7cded9718a" | |||
| integrity sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA== | |||
| @@ -1332,6 +1397,7 @@ [email protected]: | |||
| resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" | |||
| integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== | |||
| <<<<<<< HEAD | |||
| convert-source-map@^1.5.0, convert-source-map@^1.7.0: | |||
| version "1.8.0" | |||
| resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" | |||
| @@ -1344,11 +1410,14 @@ cookie@^0.4.1: | |||
| resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" | |||
| integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| 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== | |||
| <<<<<<< HEAD | |||
| copy-anything@^3.0.2: | |||
| version "3.0.2" | |||
| resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.2.tgz#7189171ff5e1893b2287e8bf574b8cd448ed50b1" | |||
| @@ -1361,6 +1430,8 @@ copy-descriptor@^0.1.0: | |||
| resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" | |||
| integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| core-js-pure@^3.25.1: | |||
| version "3.25.5" | |||
| resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.5.tgz#79716ba54240c6aa9ceba6eee08cf79471ba184d" | |||
| @@ -1401,7 +1472,18 @@ damerau-levenshtein@^1.0.8: | |||
| resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" | |||
| integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== | |||
| <<<<<<< HEAD | |||
| debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: | |||
| ======= | |||
| [email protected], debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: | |||
| version "4.3.4" | |||
| resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" | |||
| integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== | |||
| dependencies: | |||
| ms "2.1.2" | |||
| debug@^2.6.9: | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| version "2.6.9" | |||
| resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" | |||
| integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== | |||
| @@ -1415,6 +1497,7 @@ debug@^3.2.7: | |||
| dependencies: | |||
| ms "^2.1.1" | |||
| <<<<<<< HEAD | |||
| debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: | |||
| version "4.3.4" | |||
| resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" | |||
| @@ -1427,15 +1510,24 @@ decode-uri-component@^0.2.0: | |||
| resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" | |||
| integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| deep-is@^0.1.3: | |||
| version "0.1.4" | |||
| resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" | |||
| integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== | |||
| <<<<<<< HEAD | |||
| deepmerge@^2.1.1: | |||
| version "2.2.1" | |||
| resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" | |||
| integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== | |||
| ======= | |||
| deepmerge@^4.2.2: | |||
| version "4.2.2" | |||
| resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" | |||
| integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| define-properties@^1.1.3, define-properties@^1.1.4: | |||
| version "1.1.4" | |||
| @@ -1936,6 +2028,7 @@ flatted@^3.1.0: | |||
| resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" | |||
| integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== | |||
| <<<<<<< HEAD | |||
| flow-parser@0.*: | |||
| version "0.188.2" | |||
| resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.188.2.tgz#cba2f8c8cdcf358d553cf89f0b9aaaa394fa6111" | |||
| @@ -1965,6 +2058,12 @@ fragment-cache@^0.2.1: | |||
| integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== | |||
| dependencies: | |||
| map-cache "^0.2.2" | |||
| ======= | |||
| follow-redirects@^1.14.8: | |||
| version "1.15.2" | |||
| resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" | |||
| integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| fs.realpath@^1.0.0: | |||
| version "1.0.0" | |||
| @@ -2449,6 +2548,7 @@ isexe@^2.0.0: | |||
| resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" | |||
| integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== | |||
| <<<<<<< HEAD | |||
| isobject@^2.0.0: | |||
| version "2.1.0" | |||
| resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" | |||
| @@ -2461,6 +2561,8 @@ isobject@^3.0.0, isobject@^3.0.1: | |||
| resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" | |||
| integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| jose@^4.1.4, jose@^4.9.3: | |||
| version "4.10.0" | |||
| resolved "https://registry.yarnpkg.com/jose/-/jose-4.10.0.tgz#2e0b7bcc80dd0775f8a4588e55beb9460c37d60a" | |||
| @@ -2561,6 +2663,7 @@ json5@^2.2.1: | |||
| array-includes "^3.1.5" | |||
| object.assign "^4.1.3" | |||
| <<<<<<< HEAD | |||
| kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: | |||
| version "3.2.2" | |||
| resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" | |||
| @@ -2584,6 +2687,12 @@ kind-of@^6.0.0, kind-of@^6.0.2: | |||
| version "6.0.3" | |||
| resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" | |||
| integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== | |||
| ======= | |||
| [email protected]: | |||
| version "2.4.1" | |||
| resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.4.1.tgz#7d81ec518204a48c1cb16554af126806c3cd82b0" | |||
| integrity sha512-aJ9opVoXroQUPfovYP5kaj2lM7Jn02Gw13bL0lg9v0V7SaUc0qavPs0Eue7d2DcC3NjqI6QAUElXNsuZSeM+EA== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| language-subtag-registry@~0.3.2: | |||
| version "0.3.22" | |||
| @@ -2751,6 +2860,43 @@ mongodb@*: | |||
| optionalDependencies: | |||
| saslprep "^1.0.3" | |||
| [email protected]: | |||
| version "4.9.1" | |||
| resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-4.9.1.tgz#0c769448228bcf9a6aa7d16daa3625b48312479e" | |||
| integrity sha512-ZhgI/qBf84fD7sI4waZBoLBNJYPQN5IOC++SBCiPiyhzpNKOxN/fi0tBHvH2dEC42HXtNEbFB0zmNz4+oVtorQ== | |||
| dependencies: | |||
| bson "^4.7.0" | |||
| denque "^2.1.0" | |||
| mongodb-connection-string-url "^2.5.3" | |||
| socks "^2.7.0" | |||
| optionalDependencies: | |||
| saslprep "^1.0.3" | |||
| mongoose@^6.6.5: | |||
| version "6.6.5" | |||
| resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-6.6.5.tgz#fcc7ba9594db711b3d4d7a1b3522c5dbc8f0bf52" | |||
| integrity sha512-iA/oDpWOc+K2QYzA4Eq7Z1oUBQOz9FGDmUwPLgw872Bfs/qizA5Db+gJorAn+TnnGu3VoCK8iP4Y+TECUelwjA== | |||
| dependencies: | |||
| bson "^4.6.5" | |||
| kareem "2.4.1" | |||
| mongodb "4.9.1" | |||
| mpath "0.9.0" | |||
| mquery "4.0.3" | |||
| ms "2.1.3" | |||
| sift "16.0.0" | |||
| [email protected]: | |||
| version "0.9.0" | |||
| resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904" | |||
| integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew== | |||
| [email protected]: | |||
| version "4.0.3" | |||
| resolved "https://registry.yarnpkg.com/mquery/-/mquery-4.0.3.tgz#4d15f938e6247d773a942c912d9748bd1965f89d" | |||
| integrity sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA== | |||
| dependencies: | |||
| debug "4.x" | |||
| [email protected]: | |||
| version "2.0.0" | |||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | |||
| @@ -2761,7 +2907,7 @@ [email protected]: | |||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" | |||
| integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== | |||
| ms@^2.1.1: | |||
| [email protected], 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== | |||
| @@ -2798,11 +2944,14 @@ natural-compare@^1.4.0: | |||
| resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" | |||
| integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== | |||
| <<<<<<< HEAD | |||
| neo-async@^2.5.0: | |||
| version "2.6.2" | |||
| resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" | |||
| integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| next-auth@^4.13.0: | |||
| version "4.13.0" | |||
| resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.13.0.tgz#93d312cec2513ac3c5eb583ee0665da50059a902" | |||
| @@ -2818,6 +2967,7 @@ next-auth@^4.13.0: | |||
| preact-render-to-string "^5.1.19" | |||
| uuid "^8.3.2" | |||
| <<<<<<< HEAD | |||
| next-i18next@^11.3.0: | |||
| version "11.3.0" | |||
| resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-11.3.0.tgz#bfce51d8df07fb5cd61097423eeb7d744e09ae25" | |||
| @@ -2831,6 +2981,8 @@ next-i18next@^11.3.0: | |||
| i18next-fs-backend "^1.1.4" | |||
| react-i18next "^11.18.0" | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| [email protected]: | |||
| version "12.3.1" | |||
| resolved "https://registry.yarnpkg.com/next/-/next-12.3.1.tgz#127b825ad2207faf869b33393ec8c75fe61e50f1" | |||
| @@ -2857,6 +3009,7 @@ [email protected]: | |||
| "@next/swc-win32-ia32-msvc" "12.3.1" | |||
| "@next/swc-win32-x64-msvc" "12.3.1" | |||
| <<<<<<< HEAD | |||
| node-dir@^0.1.17: | |||
| version "0.1.17" | |||
| resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" | |||
| @@ -2877,6 +3030,8 @@ nookies@^2.5.2: | |||
| cookie "^0.4.1" | |||
| set-cookie-parser "^2.4.6" | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| oauth@^0.9.15: | |||
| version "0.9.15" | |||
| resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" | |||
| @@ -2887,6 +3042,7 @@ object-assign@^4.1.1: | |||
| resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" | |||
| integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== | |||
| <<<<<<< HEAD | |||
| object-copy@^0.1.0: | |||
| version "0.1.0" | |||
| resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" | |||
| @@ -2896,6 +3052,8 @@ object-copy@^0.1.0: | |||
| define-property "^0.2.5" | |||
| kind-of "^3.0.3" | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| object-hash@^2.0.1: | |||
| version "2.2.0" | |||
| resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" | |||
| @@ -3152,7 +3310,11 @@ pretty-format@^3.8.0: | |||
| resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" | |||
| integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== | |||
| <<<<<<< HEAD | |||
| prop-types@^15.6.2, prop-types@^15.8.1: | |||
| ======= | |||
| prop-types@^15.8.1: | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| version "15.8.1" | |||
| resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" | |||
| integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== | |||
| @@ -3435,10 +3597,17 @@ side-channel@^1.0.4: | |||
| get-intrinsic "^1.0.2" | |||
| object-inspect "^1.9.0" | |||
| <<<<<<< HEAD | |||
| signal-exit@^3.0.2: | |||
| version "3.0.7" | |||
| resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" | |||
| integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== | |||
| ======= | |||
| [email protected]: | |||
| version "16.0.0" | |||
| resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.0.tgz#447991577db61f1a8fab727a8a98a6db57a23eb8" | |||
| integrity sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| slash@^3.0.0: | |||
| version "3.0.0" | |||
| @@ -3806,20 +3975,30 @@ [email protected], use-sync-external-store@^1.2.0: | |||
| resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" | |||
| integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== | |||
| <<<<<<< HEAD | |||
| use@^3.1.0: | |||
| version "3.1.1" | |||
| resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" | |||
| integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== | |||
| ======= | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| 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== | |||
| <<<<<<< HEAD | |||
| [email protected]: | |||
| version "3.1.0" | |||
| resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" | |||
| integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== | |||
| ======= | |||
| validator@^13.7.0: | |||
| version "13.7.0" | |||
| resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" | |||
| integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== | |||
| >>>>>>> 4aca4a676353cc0960b4a07d32765f32d366fedf | |||
| webidl-conversions@^7.0.0: | |||
| version "7.0.0" | |||