| 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; |
| 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; |
| 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; |
| 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; |
| "lint": "next lint" | "lint": "next lint" | ||||
| }, | }, | ||||
| "dependencies": { | "dependencies": { | ||||
| "@sendgrid/mail": "^7.7.0", | |||||
| "@types/bcryptjs": "^2.4.2", | |||||
| "@types/mongodb": "^4.0.7", | "@types/mongodb": "^4.0.7", | ||||
| "@types/validator": "^13.7.7", | |||||
| "bcryptjs": "^2.4.3", | |||||
| "mongoose": "^6.6.5", | |||||
| "next": "12.3.1", | "next": "12.3.1", | ||||
| "next-auth": "^4.13.0", | |||||
| "react": "18.2.0", | "react": "18.2.0", | ||||
| "react-dom": "18.2.0" | |||||
| "react-dom": "18.2.0", | |||||
| "validator": "^13.7.0" | |||||
| }, | }, | ||||
| "devDependencies": { | "devDependencies": { | ||||
| "@types/node": "18.8.3", | "@types/node": "18.8.3", |
| 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; | |||||
| }, | |||||
| }), | |||||
| ], | |||||
| }); |
| 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; |
| // 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' }) | |||||
| } |
| 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; |
| 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; |
| 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; |
| 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; |
| 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; |
| 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; |
| import apiEndpoints from '../apiEndpoints'; | 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( | const response = await fetch( | ||||
| `http://localhost:3000${apiEndpoints.order}?ownerID=${id}` | `http://localhost:3000${apiEndpoints.order}?ownerID=${id}` | ||||
| ); | ); | ||||
| const data: OrderResponse = await response.json(); | |||||
| const data: OrderResponseGet = await response.json(); | |||||
| if (!response.ok) { | if (!response.ok) { | ||||
| throw new Error(data.message || 'Something went wrong!'); | throw new Error(data.message || 'Something went wrong!'); |
| import apiEndpoints from '../apiEndpoints'; | 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 ( | export const postOrder = async ( | ||||
| orderData: OrderData | orderData: OrderData | ||||
| ): Promise<OrderResponse> => { | |||||
| ): Promise<OrderResponsePost> => { | |||||
| const response = await fetch(`http://localhost:3000${apiEndpoints.order}`, { | const response = await fetch(`http://localhost:3000${apiEndpoints.order}`, { | ||||
| method: 'POST', | method: 'POST', | ||||
| body: JSON.stringify(orderData), | body: JSON.stringify(orderData), | ||||
| }, | }, | ||||
| }); | }); | ||||
| const data: OrderResponse = await response.json(); | |||||
| const data: OrderResponsePost = await response.json(); | |||||
| if (!response.ok) { | if (!response.ok) { | ||||
| throw new Error(data.message || 'Something went wrong!'); | throw new Error(data.message || 'Something went wrong!'); |
| import { ProductData } from '../../utils/interface/productInterface'; | |||||
| import { FeaturedProductsResponse } from '../../utils/interface/productInterface'; | |||||
| import apiEndpoints from '../apiEndpoints'; | import apiEndpoints from '../apiEndpoints'; | ||||
| interface ProductDataDB extends ProductData { | |||||
| id: string; | |||||
| _id: string; | |||||
| __v: number; | |||||
| } | |||||
| interface FeaturedProductsResponse { | |||||
| message: string; | |||||
| featuredProducts: Array<ProductDataDB>; | |||||
| } | |||||
| export const getFeaturedProducts = | export const getFeaturedProducts = | ||||
| async (): Promise<FeaturedProductsResponse> => { | async (): Promise<FeaturedProductsResponse> => { | ||||
| const response = await fetch( | const response = await fetch( |
| import { SingleProductResponse } from '../../utils/interface/productInterface'; | |||||
| import apiEndpoints from '../apiEndpoints'; | import apiEndpoints from '../apiEndpoints'; | ||||
| interface SingleProductResponse { | |||||
| message: string; | |||||
| product: object; | |||||
| similarProducts: Array<object>; | |||||
| } | |||||
| export const getProductData = async ( | export const getProductData = async ( | ||||
| productId: string | productId: string | ||||
| ): Promise<SingleProductResponse> => { | ): Promise<SingleProductResponse> => { |
| import { ProductsResponse } from '../../utils/interface/productInterface'; | |||||
| import apiEndpoints from '../apiEndpoints'; | import apiEndpoints from '../apiEndpoints'; | ||||
| interface ProductsResponse { | |||||
| message: string; | |||||
| product: object; | |||||
| productCount: number; | |||||
| next: string; | |||||
| previous: string; | |||||
| } | |||||
| export const getAllProducts = async ( | export const getAllProducts = async ( | ||||
| pageIndex: number, | pageIndex: number, | ||||
| category = 'All', | category = 'All', |
| import apiEndpoints from '../apiEndpoints'; | 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 ( | export const postQuestion = async ( | ||||
| questionData: QuestionData | questionData: QuestionData |
| import apiEndpoints from '../apiEndpoints'; | 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 ( | export const updateUser = async ( | ||||
| userData: UserData, | userData: UserData, |
| 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; |
| 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; | |||||
| } |
| owner: ObjectId; | owner: ObjectId; | ||||
| stripeCheckoutId: string; | 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; |
| customID: string; | customID: string; | ||||
| stripeID: 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; |
| lastName: string; | lastName: string; | ||||
| message: 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; |
| fullName: string; | fullName: string; | ||||
| postcode: string; | postcode: string; | ||||
| } | } | ||||
| export interface IUser extends UserData { | |||||
| email: string; | |||||
| username: string; | |||||
| password: string; | |||||
| orders?: Array<object>; | |||||
| } | |||||
| export interface UpdateResponse { | |||||
| message: string; | |||||
| } |
| dependencies: | dependencies: | ||||
| regenerator-runtime "^0.13.4" | regenerator-runtime "^0.13.4" | ||||
| "@babel/runtime@^7.16.3": | |||||
| 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" | |||||
| "@eslint/eslintrc@^1.3.3": | "@eslint/eslintrc@^1.3.3": | ||||
| version "1.3.3" | version "1.3.3" | ||||
| resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" | ||||
| "@nodelib/fs.scandir" "2.1.5" | "@nodelib/fs.scandir" "2.1.5" | ||||
| fastq "^1.6.0" | fastq "^1.6.0" | ||||
| "@panva/hkdf@^1.0.1": | |||||
| version "1.0.2" | |||||
| resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.0.2.tgz#bab0f09d09de9fd83628220d496627681bc440d6" | |||||
| integrity sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA== | |||||
| "@rushstack/eslint-patch@^1.1.3": | "@rushstack/eslint-patch@^1.1.3": | ||||
| version "1.2.0" | version "1.2.0" | ||||
| resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" | resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" | ||||
| integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== | integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== | ||||
| "@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" | |||||
| "@swc/[email protected]": | "@swc/[email protected]": | ||||
| version "0.4.11" | version "0.4.11" | ||||
| resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.11.tgz#db23a376761b3d31c26502122f349a21b592c8de" | resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.11.tgz#db23a376761b3d31c26502122f349a21b592c8de" | ||||
| dependencies: | dependencies: | ||||
| tslib "^2.4.0" | tslib "^2.4.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== | |||||
| "@types/json5@^0.0.29": | "@types/json5@^0.0.29": | ||||
| version "0.0.29" | version "0.0.29" | ||||
| resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" | resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" | ||||
| resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" | resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" | ||||
| integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== | 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@*": | "@types/webidl-conversions@*": | ||||
| version "7.0.0" | version "7.0.0" | ||||
| resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7" | resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz#2b8e60e33906459219aa587e9d1a612ae994cfe7" | ||||
| resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" | resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" | ||||
| integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== | 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: | axobject-query@^2.2.0: | ||||
| version "2.2.0" | version "2.2.0" | ||||
| resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" | resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" | ||||
| resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" | ||||
| integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== | 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== | |||||
| brace-expansion@^1.1.7: | brace-expansion@^1.1.7: | ||||
| version "1.1.11" | version "1.1.11" | ||||
| resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" | ||||
| dependencies: | dependencies: | ||||
| fill-range "^7.0.1" | fill-range "^7.0.1" | ||||
| bson@^4.7.0: | |||||
| bson@^4.6.5, bson@^4.7.0: | |||||
| version "4.7.0" | version "4.7.0" | ||||
| resolved "https://registry.yarnpkg.com/bson/-/bson-4.7.0.tgz#7874a60091ffc7a45c5dd2973b5cad7cded9718a" | resolved "https://registry.yarnpkg.com/bson/-/bson-4.7.0.tgz#7874a60091ffc7a45c5dd2973b5cad7cded9718a" | ||||
| integrity sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA== | integrity sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA== | ||||
| resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" | ||||
| integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== | ||||
| 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-js-pure@^3.25.1: | core-js-pure@^3.25.1: | ||||
| version "3.25.5" | version "3.25.5" | ||||
| resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.5.tgz#79716ba54240c6aa9ceba6eee08cf79471ba184d" | resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.5.tgz#79716ba54240c6aa9ceba6eee08cf79471ba184d" | ||||
| resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" | resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" | ||||
| integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== | integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== | ||||
| [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: | debug@^2.6.9: | ||||
| version "2.6.9" | version "2.6.9" | ||||
| resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" | ||||
| dependencies: | dependencies: | ||||
| ms "^2.1.1" | ms "^2.1.1" | ||||
| 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" | |||||
| deep-is@^0.1.3: | deep-is@^0.1.3: | ||||
| version "0.1.4" | version "0.1.4" | ||||
| resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" | ||||
| integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== | ||||
| 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== | |||||
| define-properties@^1.1.3, define-properties@^1.1.4: | define-properties@^1.1.3, define-properties@^1.1.4: | ||||
| version "1.1.4" | version "1.1.4" | ||||
| resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" | ||||
| resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" | ||||
| integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== | integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== | ||||
| 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== | |||||
| fs.realpath@^1.0.0: | fs.realpath@^1.0.0: | ||||
| version "1.0.0" | version "1.0.0" | ||||
| resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" | ||||
| resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" | ||||
| integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== | ||||
| jose@^4.1.4, jose@^4.9.3: | |||||
| version "4.10.0" | |||||
| resolved "https://registry.yarnpkg.com/jose/-/jose-4.10.0.tgz#2e0b7bcc80dd0775f8a4588e55beb9460c37d60a" | |||||
| integrity sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw== | |||||
| js-sdsl@^4.1.4: | js-sdsl@^4.1.4: | ||||
| version "4.1.5" | version "4.1.5" | ||||
| resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" | resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" | ||||
| array-includes "^3.1.5" | array-includes "^3.1.5" | ||||
| object.assign "^4.1.3" | object.assign "^4.1.3" | ||||
| [email protected]: | |||||
| version "2.4.1" | |||||
| resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.4.1.tgz#7d81ec518204a48c1cb16554af126806c3cd82b0" | |||||
| integrity sha512-aJ9opVoXroQUPfovYP5kaj2lM7Jn02Gw13bL0lg9v0V7SaUc0qavPs0Eue7d2DcC3NjqI6QAUElXNsuZSeM+EA== | |||||
| language-subtag-registry@~0.3.2: | language-subtag-registry@~0.3.2: | ||||
| version "0.3.22" | version "0.3.22" | ||||
| resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" | resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" | ||||
| optionalDependencies: | optionalDependencies: | ||||
| saslprep "^1.0.3" | 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]: | [email protected]: | ||||
| version "2.0.0" | version "2.0.0" | ||||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | ||||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" | ||||
| integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== | ||||
| ms@^2.1.1: | |||||
| [email protected], ms@^2.1.1: | |||||
| version "2.1.3" | version "2.1.3" | ||||
| resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" | ||||
| integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== | ||||
| resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" | ||||
| integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== | ||||
| next-auth@^4.13.0: | |||||
| version "4.13.0" | |||||
| resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.13.0.tgz#93d312cec2513ac3c5eb583ee0665da50059a902" | |||||
| integrity sha512-FtkPpeb9Bax6yKDaxcaGIvZZjvr10JaU2AsBYv1yv4N6rP86Xa7/4Ro1Aq94YGwsYzk+YKS52CRjD2DqCcSmVA== | |||||
| dependencies: | |||||
| "@babel/runtime" "^7.16.3" | |||||
| "@panva/hkdf" "^1.0.1" | |||||
| cookie "^0.5.0" | |||||
| jose "^4.9.3" | |||||
| oauth "^0.9.15" | |||||
| openid-client "^5.1.0" | |||||
| preact "^10.6.3" | |||||
| preact-render-to-string "^5.1.19" | |||||
| uuid "^8.3.2" | |||||
| [email protected]: | [email protected]: | ||||
| version "12.3.1" | version "12.3.1" | ||||
| resolved "https://registry.yarnpkg.com/next/-/next-12.3.1.tgz#127b825ad2207faf869b33393ec8c75fe61e50f1" | resolved "https://registry.yarnpkg.com/next/-/next-12.3.1.tgz#127b825ad2207faf869b33393ec8c75fe61e50f1" | ||||
| "@next/swc-win32-ia32-msvc" "12.3.1" | "@next/swc-win32-ia32-msvc" "12.3.1" | ||||
| "@next/swc-win32-x64-msvc" "12.3.1" | "@next/swc-win32-x64-msvc" "12.3.1" | ||||
| oauth@^0.9.15: | |||||
| version "0.9.15" | |||||
| resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" | |||||
| integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== | |||||
| object-assign@^4.1.1: | object-assign@^4.1.1: | ||||
| version "4.1.1" | version "4.1.1" | ||||
| resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" | ||||
| integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== | ||||
| object-hash@^2.0.1: | |||||
| version "2.2.0" | |||||
| resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" | |||||
| integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== | |||||
| object-inspect@^1.12.2, object-inspect@^1.9.0: | object-inspect@^1.12.2, object-inspect@^1.9.0: | ||||
| version "1.12.2" | version "1.12.2" | ||||
| resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" | ||||
| define-properties "^1.1.3" | define-properties "^1.1.3" | ||||
| es-abstract "^1.19.1" | es-abstract "^1.19.1" | ||||
| oidc-token-hash@^5.0.1: | |||||
| version "5.0.1" | |||||
| resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz#ae6beec3ec20f0fd885e5400d175191d6e2f10c6" | |||||
| integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ== | |||||
| once@^1.3.0: | once@^1.3.0: | ||||
| version "1.4.0" | version "1.4.0" | ||||
| resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" | ||||
| dependencies: | dependencies: | ||||
| wrappy "1" | wrappy "1" | ||||
| openid-client@^5.1.0: | |||||
| version "5.1.10" | |||||
| resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.1.10.tgz#add6044878b9be75ffdd09abfcaae6feff376b1f" | |||||
| integrity sha512-KYAtkxTuUwTvjAmH0QMFFP3i9l0+XhP2/blct6Q9kn+DUJ/lu8/g/bI8ghSgxz9dJLm/9cpB/1uLVGTcGGY0hw== | |||||
| dependencies: | |||||
| jose "^4.1.4" | |||||
| lru-cache "^6.0.0" | |||||
| object-hash "^2.0.1" | |||||
| oidc-token-hash "^5.0.1" | |||||
| optionator@^0.9.1: | optionator@^0.9.1: | ||||
| version "0.9.1" | version "0.9.1" | ||||
| resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" | ||||
| picocolors "^1.0.0" | picocolors "^1.0.0" | ||||
| source-map-js "^1.0.2" | source-map-js "^1.0.2" | ||||
| preact-render-to-string@^5.1.19: | |||||
| version "5.2.5" | |||||
| resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.5.tgz#359b14a45bea2a7b5c0ed2a9c6eb7ea915cf7d5a" | |||||
| integrity sha512-rEBn42C3Wh+AjPxXUbDkb6xw0cTJQgxdYlp6ytUR1uBZF647Wn6ykkopMeQlRl7ggX+qnYYjZ4Hs1abZENl7ww== | |||||
| dependencies: | |||||
| pretty-format "^3.8.0" | |||||
| preact@^10.6.3: | |||||
| version "10.11.1" | |||||
| resolved "https://registry.yarnpkg.com/preact/-/preact-10.11.1.tgz#35fdad092de8b2ad29df3a0bef9af1f4fdd2256b" | |||||
| integrity sha512-1Wz5PCRm6Fg+6BTXWJHhX4wRK9MZbZBHuwBqfZlOdVm2NqPe8/rjYpufvYCwJSGb9layyzB2jTTXfpCTynLqFQ== | |||||
| prelude-ls@^1.2.1: | prelude-ls@^1.2.1: | ||||
| version "1.2.1" | version "1.2.1" | ||||
| resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" | ||||
| integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== | ||||
| pretty-format@^3.8.0: | |||||
| version "3.8.0" | |||||
| resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" | |||||
| integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew== | |||||
| prop-types@^15.8.1: | prop-types@^15.8.1: | ||||
| version "15.8.1" | version "15.8.1" | ||||
| resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" | ||||
| get-intrinsic "^1.0.2" | get-intrinsic "^1.0.2" | ||||
| object-inspect "^1.9.0" | object-inspect "^1.9.0" | ||||
| [email protected]: | |||||
| version "16.0.0" | |||||
| resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.0.tgz#447991577db61f1a8fab727a8a98a6db57a23eb8" | |||||
| integrity sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ== | |||||
| slash@^3.0.0: | slash@^3.0.0: | ||||
| version "3.0.0" | version "3.0.0" | ||||
| resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" | ||||
| resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" | 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== | integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== | ||||
| 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== | |||||
| webidl-conversions@^7.0.0: | webidl-conversions@^7.0.0: | ||||
| version "7.0.0" | version "7.0.0" | ||||
| resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" |