diff --git a/app/(apidocs)/apidocs/page.tsx b/app/(apidocs)/apidocs/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..dcd107ba20f624834e55009f077da0fcfb710cdc --- /dev/null +++ b/app/(apidocs)/apidocs/page.tsx @@ -0,0 +1,12 @@ +import { getApiDocs } from '@/lib/swagger' +import ReactSwagger from './react-swagger' + +export default async function IndexPage() { + const spec = await getApiDocs() + + return ( + <section className="container"> + <ReactSwagger spec={spec} /> + </section> + ) +} \ No newline at end of file diff --git a/app/(apidocs)/apidocs/react-swagger.tsx b/app/(apidocs)/apidocs/react-swagger.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8decb68dec0077f3c939e545e96ffdc6bbfafb41 --- /dev/null +++ b/app/(apidocs)/apidocs/react-swagger.tsx @@ -0,0 +1,14 @@ +'use client' + +import SwaggerUI from 'swagger-ui-react' +import 'swagger-ui-react/swagger-ui.css' + +type Props = { + spec: Record<string, any>, +} + +function ReactSwagger({ spec }: Props) { + return <SwaggerUI spec={spec} /> +} + +export default ReactSwagger \ No newline at end of file diff --git a/app/(content)/(community)/communities/page.tsx b/app/(content)/(community)/communities/page.tsx deleted file mode 100644 index 7a1e2cfa04c7c5585326afa281e80d9b89cc765d..0000000000000000000000000000000000000000 --- a/app/(content)/(community)/communities/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function CommunitiesPage() { - return ( - <div> - <h1>Community WIP</h1> - </div> - ) -} \ No newline at end of file diff --git a/app/(content)/(gaming)/games/[gameid]/page.tsx b/app/(content)/(gaming)/games/[gameid]/page.tsx index f344c53c85ff3637f45f4a596e2ca8daa00e12ad..cfded75d474797deba9d4f224db42628a6c3ca83 100644 --- a/app/(content)/(gaming)/games/[gameid]/page.tsx +++ b/app/(content)/(gaming)/games/[gameid]/page.tsx @@ -2,6 +2,7 @@ import AddGameDropdown from "@/components/add-game-dropdown" import AddGameToFavList from "@/components/addGameToFavList" import { BackHeader } from "@/components/back-header" import { GlobalLayout } from "@/components/global-layout" +import { TryAgain } from "@/components/try-again" import { AspectRatio } from "@/components/ui/aspect-ratio" import { Button } from "@/components/ui/button" import { Card } from "@/components/ui/card" @@ -15,6 +16,9 @@ import Image from "next/image" // renders a single game detail page export default async function GameDetail({ params }: { params: { gameid: string } }) { const data: IGame[] = await getGame(parseInt(params.gameid)) + + if (!data[0]) return <TryAgain /> + // TODO put to backend const date = formatDate(data[0].first_release_date * 1000) @@ -26,7 +30,7 @@ export default async function GameDetail({ params }: { params: { gameid: string }) const companies = data[0].involved_companies.map((company) => { - if (company !== data[0].involved_companies[0]) { + if (company !== data[0]?.involved_companies[0]) { return `, ${company.company.name}` } return company.company.name @@ -45,7 +49,7 @@ export default async function GameDetail({ params }: { params: { gameid: string <div className="h-64 overflow-hidden"> <AspectRatio ratio={889 / 500}> <Image - src={data[0].screenshots[0].url} + src={data[0].screenshots[0]?.url ?? ""} alt={data[0].name} fill priority @@ -113,7 +117,7 @@ export default async function GameDetail({ params }: { params: { gameid: string <Card key={i} className="aspect-[264/374] relative block"> <Image src={screenshot.url} - alt={data[0].name} + alt={data[0]?.name ?? ""} fill priority className="object-cover rounded-lg" /> diff --git a/app/(content)/(home)/home/page.tsx b/app/(content)/(home)/home/page.tsx index d159dec93d31a425d2d95cafcdb5c7c75e31e0e3..b7970be4f3db3b3072bd47797e64a6b733213891 100644 --- a/app/(content)/(home)/home/page.tsx +++ b/app/(content)/(home)/home/page.tsx @@ -1,11 +1,15 @@ import { CreateGweet } from "@/components/create-gweet/components/create-gweet" import { GlobalLayout } from "@/components/global-layout" import { Gweets } from "@/components/gweets/components/gweets" +import { Connect } from "@/components/profile/components/connect" import ScrollToTop from "@/components/scroll-to-top" import { Trends } from "@/components/trends/components/trends" import { Card } from "@/components/ui/card" +import { getCurrentUser } from "@/lib/session" export default async function HomePage() { + const session = await getCurrentUser() + return ( <GlobalLayout mainContent={ @@ -20,9 +24,16 @@ export default async function HomePage() { </> } sideContent={ - <Card className="p-5 bg-secondary"> - <Trends /> - </Card> + <> + <Card className="p-5 bg-secondary"> + <Trends /> + </Card> + + <Card className="p-6 bg-secondary"> + <Connect session={session} /> + </Card> + </> + } /> ) diff --git a/app/(content)/(home)/people/page.tsx b/app/(content)/(home)/people/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..03cf4264b68a558f098fc68676f0dbe4e116361f --- /dev/null +++ b/app/(content)/(home)/people/page.tsx @@ -0,0 +1,26 @@ +import { BackHeader } from "@/components/back-header" +import { GlobalLayout } from "@/components/global-layout" +import { Connect } from "@/components/profile/components/connect" +import { Card } from "@/components/ui/card" +import { getCurrentUser } from "@/lib/session" + +export default async function PeoplePage() { + const session = await getCurrentUser() + + return ( + <GlobalLayout + mainContent={ + <Card className="w-full overflow-hidden"> + <div className="p-3"> + <BackHeader> + <h1 className="font-bold">People</h1> + </BackHeader> + </div> + <div className="px-5"> + <Connect title="" session={session} /> + </div> + </Card> + } + /> + ) +} \ No newline at end of file diff --git a/app/(content)/(search)/search/page.tsx b/app/(content)/(search)/search/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cb8d68edd738d54202a2ea8066adcaf25b04772a --- /dev/null +++ b/app/(content)/(search)/search/page.tsx @@ -0,0 +1,19 @@ +import { GlobalLayout } from "@/components/global-layout" + +export default async function SearchPage() { + return ( + <GlobalLayout + mainContent={ + <> + Search Page + </> + } + + sideContent={ + <> + + </> + } + /> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[userid]/(profile)/followers/page.tsx b/app/(content)/(user)/[userid]/(profile)/followers/page.tsx deleted file mode 100644 index 4c4cc4597bb4c954f24bb86c4cb6a19a8f08dd35..0000000000000000000000000000000000000000 --- a/app/(content)/(user)/[userid]/(profile)/followers/page.tsx +++ /dev/null @@ -1,62 +0,0 @@ - -import { GlobalLayout } from "@/components/global-layout" -import { UserAvatar } from "@/components/user-avatar" -import { db } from "@/lib/db" -import { User } from "@prisma/client" -import Link from "next/link" - -export default async function UserFollowers({ params }: { params: { userid: string } }) { - - const fullUser = await db.user.findFirst({ - where: { - username: params.userid - }, - include: { - following: true, - followers: true - } - }) - - const followers = await db.user.findMany({ - where: { - following: { - every: { - followerId: { not: undefined } - } - }, - followers: { - every: { - followingId: fullUser?.id - } - } - } - }) - - return ( - <GlobalLayout - mainContent={ - <div className="flex flex-col w-full"> - {followers?.map((follower: User) => ( - <div className="flex items-center space-y-6" key={follower.id}> - <Link href={`/${follower.username}`} className="flex flex-row"> - <UserAvatar - user={{ username: follower.username, image: follower.image }} - className="h-10 w-10" - /> - - <div className="flex flex-col ml-3"> - <span className="font-bold">{follower.name}</span> - <span className="text-sky-500 text-sm">@{follower.username}</span> - </div> - </Link> - - <div className="ml-auto"> - {/* Followbutton */} - </div> - </div> - ))} - </div> - } - /> - ) -} \ No newline at end of file diff --git a/app/(content)/(user)/[userid]/(profile)/following/page.tsx b/app/(content)/(user)/[userid]/(profile)/following/page.tsx deleted file mode 100644 index 5ea8f4daa5c5fef29b079a07c60284b12ab27cba..0000000000000000000000000000000000000000 --- a/app/(content)/(user)/[userid]/(profile)/following/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default async function Following() { - return ( - <div> - <h1>Following Page WIP</h1> - </div> - ) -} \ No newline at end of file diff --git a/app/(content)/(user)/[userid]/(profile)/likes/page.tsx b/app/(content)/(user)/[userid]/(profile)/likes/page.tsx deleted file mode 100644 index d1050ff370eab7ae89abaf9012a3c9d499129093..0000000000000000000000000000000000000000 --- a/app/(content)/(user)/[userid]/(profile)/likes/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default async function Likes() { - return ( - <div> - <h1>Likes Page WIP</h1> - </div> - ) -} \ No newline at end of file diff --git a/app/(content)/(user)/[userid]/(profile)/page.tsx b/app/(content)/(user)/[userid]/(profile)/page.tsx deleted file mode 100644 index d60b12fe5162b14c03e21f932c9902ad9170be22..0000000000000000000000000000000000000000 --- a/app/(content)/(user)/[userid]/(profile)/page.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import FollowButton from "@/components/following-button" -import GameItem from "@/components/game-item" -import { GlobalLayout } from "@/components/global-layout" -import { AspectRatio } from "@/components/ui/aspect-ratio" -import { Card } from "@/components/ui/card" -import { Skeleton } from "@/components/ui/skeleton" -import { UserAvatar } from "@/components/user-avatar" -import { db } from "@/lib/db" -import { getFavoriteGames } from "@/lib/igdb" -import { getCurrentUser } from "@/lib/session" -import { IGame } from "@/types/igdb-types" -import { redirect } from "next/navigation" - - -export default async function User({ params }: { params: { userid: string } }) { - const user = await getCurrentUser() - - const sessionUser = await db.user.findFirst({ - where: { - id: user?.id - }, - include: { - following: true, - followers: true - } - }) - - const fullUser = await db.user.findFirst({ - where: { - username: params.userid - }, - include: { - following: true, - followers: true - } - }) - - if (!fullUser) { - redirect('/home') - } - - let favoritegames = undefined - let playingGames = undefined - let finishedGames = undefined - let planningGames = undefined - - if (fullUser?.favGameList?.length !== 0 && fullUser?.favGameList?.length != undefined) { - favoritegames = await getFavoriteGames(fullUser?.favGameList!) - } - if (fullUser?.playingGameList?.length !== 0) { - playingGames = await getFavoriteGames(fullUser?.playingGameList!) - } - if (fullUser?.finishedGameList?.length !== 0) { - finishedGames = await getFavoriteGames(fullUser?.finishedGameList!) - } - if (fullUser?.planningGameList?.length !== 0) { - planningGames = await getFavoriteGames(fullUser?.planningGameList!) - } - - return ( - <GlobalLayout - mainContent={ - <div className="space-y-6 w-full"> - <Card className="overflow-hidden"> - <div className="h-64 overflow-hidden"> - <AspectRatio ratio={889 / 500} className="bg-slate-600 dark:bg-slate-400"> - {/* profile banner */} - {/* <Image - src={ } - alt={ } - fill - priority - className="object-center" /> */} - </AspectRatio> - </div> - <div className="p-6 md:p-12 ss:flex"> - <UserAvatar - user={{ username: fullUser.username, image: fullUser.image || null }} - className="h-52 w-52 -mt-36" - /> - <div className="ml-6 md:ml-12 space-y-3"> - <h1 className="text-2xl font-bold">{fullUser.name}</h1> - <h1 className="text-md text-sky-500">@{fullUser.username}</h1> - {/* <h1 className="pt-3">{fullUser.bio}</h1> */} - </div> - <div className="flex justify-start ml-6 md:ml-12 space-y-3"> - <FollowButton user={sessionUser!} followingId={fullUser?.id!} /> - </div> - </div> - - <div className="px-6 md:px-12"> - {/* <div className="border-b border-gray-400 dark:border-gray-200" /> */} - {/* gweets */} - </div> - </Card > - - <Card className="overflow-hidden p-6 md:p-12" > - <h1 className="text-2xl font-bold pb-3">Favorite Games</h1> - <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> - {favoritegames ? favoritegames.map((game: IGame) => ( - <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> - )) - : - <p>No favorites currently...</p>} - </div> - </Card> - - <Card className="overflow-hidden p-6 md:p-12" > - <h1 className="text-2xl font-bold pb-3">Currently playing</h1> - <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> - {playingGames ? playingGames.map((game: IGame) => ( - <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> - )) - : - <p>Currently not playing any games...</p>} - </div> - </Card> - - <Card className="overflow-hidden p-6 md:p-12" > - <h1 className="text-2xl font-bold pb-3">Planning to play</h1> - <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> - {planningGames ? planningGames.map((game: IGame) => ( - <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> - )) - : - <p>Currently not planning to play any games...</p>} - </div> - </Card> - - <Card className="overflow-hidden p-6 md:p-12" > - <h1 className="text-2xl font-bold pb-3">Finished Games</h1> - <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> - {finishedGames ? finishedGames.map((game: IGame) => ( - <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> - )) - : - <p>No finished games...</p>} - </div> - </Card> - </div> - } - - sideContent={ - <Card className="p-6 grid items-start gap-2 bg-secondary"> - <h1>Media</h1> - <div className="grid grid-cols-1 gap-4"> - {Array.from({ length: 2 }, (_, i) => i + 1).map((i) => { - return ( - <Skeleton key={i} className="aspect-[264/374] bg-gray-300" /> - ) - })} - </div> - </Card> - } - /> - ) -} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/(profile)/games/page.tsx b/app/(content)/(user)/[username]/(profile)/games/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..802d5a5df55780ae74012fc3bb61b173eb9fe3e6 --- /dev/null +++ b/app/(content)/(user)/[username]/(profile)/games/page.tsx @@ -0,0 +1,10 @@ +import { UserGames } from "@/components/profile/components/user-games" +import { TabsContent } from "@/components/ui/tabs" + +export default async function Games({ params }: { params: { username: string } }) { + return ( + <TabsContent value="games"> + <UserGames username={params.username} /> + </TabsContent> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/(profile)/layout.tsx b/app/(content)/(user)/[username]/(profile)/layout.tsx new file mode 100644 index 0000000000000000000000000000000000000000..66445626fecee51e6e8507d795affad6ec202d46 --- /dev/null +++ b/app/(content)/(user)/[username]/(profile)/layout.tsx @@ -0,0 +1,41 @@ +import { GlobalLayout } from "@/components/global-layout" +import { ProfileNavbar } from "@/components/profile/components/profile-navbar" +import { ProfileSideContent } from "@/components/profile/components/profile-side-content" +import { ProfileUserInfo } from "@/components/profile/components/profile-user-info" +import { IUser } from "@/components/profile/types" +import { Card } from "@/components/ui/card" +import { UserNotFound } from "@/components/user-not-found" +import getURL from "@/lib/utils" + +// export const dynamic = 'force-dynamic' +// export const fetchCache = 'force-no-store' + +export default async function ProfileLayout({ + params, + children, +}: { + params: { username: string } + children: React.ReactNode +}) { + const user: IUser = await fetch(getURL(`/api/users/${params.username}`)).then((result) => result.json()) + + return ( + <GlobalLayout + mainContent={ + <Card className="overflow-hidden h-full w-full"> + {!user ? + <UserNotFound /> + : + <> + <ProfileUserInfo user={user} /> + <ProfileNavbar param={params.username}> + {children} + </ProfileNavbar> + </> + } + </Card> + } + sideContent={<ProfileSideContent user={user} />} + /> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/(profile)/likes/page.tsx b/app/(content)/(user)/[username]/(profile)/likes/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..4d506758e5217df9ca8db3d7605187210576891e --- /dev/null +++ b/app/(content)/(user)/[username]/(profile)/likes/page.tsx @@ -0,0 +1,13 @@ +import { UserGweets } from "@/components/profile/components/user-gweets" +import { TabsContent } from "@/components/ui/tabs" +import { getCurrentUser } from "@/lib/session" + +export default async function Likes({ params }: { params: { username: string } }) { + const session = await getCurrentUser() + + return ( + <TabsContent value="likes"> + <UserGweets username={params.username} sessionname={session?.username as string} /> + </TabsContent> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/(profile)/media/page.tsx b/app/(content)/(user)/[username]/(profile)/media/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..05724bd0ad11312382de9dd368b7fa59e7b61c81 --- /dev/null +++ b/app/(content)/(user)/[username]/(profile)/media/page.tsx @@ -0,0 +1,13 @@ +import { UserGweets } from "@/components/profile/components/user-gweets" +import { TabsContent } from "@/components/ui/tabs" +import { getCurrentUser } from "@/lib/session" + +export default async function Media({ params }: { params: { username: string } }) { + const session = await getCurrentUser() + + return ( + <TabsContent value="media"> + <UserGweets username={params.username} sessionname={session?.username as string} /> + </TabsContent> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/(profile)/page.tsx b/app/(content)/(user)/[username]/(profile)/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..35111b1f5f4208ad3223b38a8fce56d510054e8f --- /dev/null +++ b/app/(content)/(user)/[username]/(profile)/page.tsx @@ -0,0 +1,13 @@ +import { UserGweets } from "@/components/profile/components/user-gweets" +import { TabsContent } from "@/components/ui/tabs" +import { getCurrentUser } from "@/lib/session" + +export default async function Gweets({ params }: { params: { username: string } }) { + const session = await getCurrentUser() + + return ( + <TabsContent value="gweets"> + <UserGweets username={params.username} sessionname={session?.username as string} /> + </TabsContent> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/followers/page.tsx b/app/(content)/(user)/[username]/followers/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..861d82fdbfef3ccae10349c046538f3609a7f863 --- /dev/null +++ b/app/(content)/(user)/[username]/followers/page.tsx @@ -0,0 +1,26 @@ +import { BackHeader } from "@/components/back-header" +import { GlobalLayout } from "@/components/global-layout" +import { UserFollows } from "@/components/profile/components/user-follows" +import { Card } from "@/components/ui/card" +import { getCurrentUser } from "@/lib/session" + +export default async function Followers({ params }: { params: { username: string } }) { + const session = await getCurrentUser() + + return ( + <GlobalLayout + mainContent={ + <Card className="w-full overflow-hidden "> + <div className="p-3"> + <BackHeader> + <h1 className="font-bold">Followers</h1> + </BackHeader> + </div> + <div className="px-5"> + <UserFollows username={params.username} session={session} /> + </div> + </Card> + } + /> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[username]/following/page.tsx b/app/(content)/(user)/[username]/following/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2208842f94471ab149b0c9fa949de636e98236f3 --- /dev/null +++ b/app/(content)/(user)/[username]/following/page.tsx @@ -0,0 +1,26 @@ +import { BackHeader } from "@/components/back-header" +import { GlobalLayout } from "@/components/global-layout" +import { UserFollows } from "@/components/profile/components/user-follows" +import { Card } from "@/components/ui/card" +import { getCurrentUser } from "@/lib/session" + +export default async function Following({ params }: { params: { username: string } }) { + const session = await getCurrentUser() + + return ( + <GlobalLayout + mainContent={ + <Card className="w-full overflow-hidden "> + <div className="p-3"> + <BackHeader> + <h1 className="font-bold">Following</h1> + </BackHeader> + </div> + <div className="px-5"> + <UserFollows username={params.username} session={session} /> + </div> + </Card> + } + /> + ) +} \ No newline at end of file diff --git a/app/(content)/(user)/[userid]/status/[id]/page.tsx b/app/(content)/(user)/[username]/status/[id]/page.tsx similarity index 100% rename from app/(content)/(user)/[userid]/status/[id]/page.tsx rename to app/(content)/(user)/[username]/status/[id]/page.tsx diff --git a/app/(content)/layout.tsx b/app/(content)/layout.tsx index 9f3fedee59a59c10d952f8fde755d0f6d05d2e98..a868a706afdb2837acc0b38966bae28a5ec8f559 100644 --- a/app/(content)/layout.tsx +++ b/app/(content)/layout.tsx @@ -3,12 +3,11 @@ import { Sidebar } from "@/components/nav-sidebar" import { dashboardConfig } from "@/lib/config/dashboard" import { getCurrentUser } from "@/lib/session" -interface DashboardLayoutProps { - children?: React.ReactNode -} export default async function ContentLayout({ children, -}: DashboardLayoutProps) { +}: { + children: React.ReactNode +}) { const user = await getCurrentUser() return ( diff --git a/app/api/followers/route.ts b/app/api/followers/route.ts deleted file mode 100644 index cc327201fc2833606e01beb869bff9515f15ddb7..0000000000000000000000000000000000000000 --- a/app/api/followers/route.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { db } from "@/lib/db" -import { getCurrentUser } from "@/lib/session" -import { revalidatePath } from "next/cache" -import { NextRequest, NextResponse } from "next/server" - -export async function GET(req: NextRequest) { - const sessionUser = await getCurrentUser() - - if (!sessionUser) { - return NextResponse.json({ status: 401, message: 'Unauthorized' }) - } - let follows = undefined - - try { - follows = await db.follows.findMany({ - where: { - followerId: sessionUser.id - } - }) - } catch (error) { - console.log("error", error) - } - - return NextResponse.json({ status: 200, message: "fetched follows", follows }) -} - -export async function PUT(req: NextRequest) { - const sessionUser = await getCurrentUser() - - const data = await req.json() - - if (!sessionUser) { - return NextResponse.json({ status: 401, message: 'Unauthorized' }) - } - - try { - const dbUser = await db.user.findFirst({ - where: { - id: sessionUser.id - } - }) - - const follow = await db.follows.findFirst({ - where: { - followerId: sessionUser.id, - followingId: data.followingId - } - }) - console.log("follow", follow) - - if (follow) { - // User is already following, so unfollow - console.log("delete follow") - const delfollow = await db.follows.delete({ - where: { - followerId_followingId: { - followerId: sessionUser.id, - followingId: data.followingId - } - - } - }) - console.log("del follow:", delfollow) - } else { - // User is not following, so follow - console.log("create follow") - await db.follows.create({ - data: { - followerId: sessionUser.id, - followingId: data.followingId - }, - }) - - } - } catch (error) { - console.log("err", error) - } - const path = req.nextUrl.searchParams.get('path') || '/' - revalidatePath(path) - - return NextResponse.json({ status: 200, message: 'Follow handled' }) -} \ No newline at end of file diff --git a/app/api/games/route.ts b/app/api/games/route.ts index 04d0ee92cb77c31e5331e1d5a346d4e8d440e681..6aa3d6c0b7366aa49ef1e5589227c1545a2cc03f 100644 --- a/app/api/games/route.ts +++ b/app/api/games/route.ts @@ -5,6 +5,21 @@ import { IPlatformCategrory } from "@/types/igdb-types" import { NextRequest, NextResponse } from "next/server" +/** + * @swagger + * /api/games: + * get: + * description: Get Games through external API + * content: + * application/json: + * schema: + * responses: + * 200: + * description: list of games + * 500: + * description: error + */ + export async function GET(req: NextRequest) { const p = req.nextUrl.searchParams try { @@ -37,7 +52,7 @@ export async function GET(req: NextRequest) { sortby ? sortby : undefined, order ? order : undefined ) - return NextResponse.json(games) + return NextResponse.json(games, { status: 200 }) } catch (error) { return NextResponse.json(error, { status: 500 }) } diff --git a/app/api/gweets/[id]/route.ts b/app/api/gweets/[id]/route.ts index a9c706539844ac3becd0dc6549fb977d1e65391d..b3ead3b2b85e8f61221369120ac7334d2c4f8501 100644 --- a/app/api/gweets/[id]/route.ts +++ b/app/api/gweets/[id]/route.ts @@ -3,7 +3,33 @@ import { z } from "zod" import { db } from "@/lib/db" -// get a single gweet +/** + * @swagger + * /api/gweets/{id}: + * get: + * description: Gives back a List of Gweets + * parameters: + * - name: id + * in: path + * description: ID of Gweet that needs to be fetched + * required: true + * schema: + * type: integer + * format: int64 + * content: + * application/json: + * schema: + * responses: + * 200: + * description: fetched gweets! + * 400: + * description: Invalid request body! + * 404: + * description: Gweet not found! + * 500: + * description: Error + */ + export async function GET(request: Request, { params }: { params: { id: string } }) { const { id } = params @@ -12,12 +38,10 @@ export async function GET(request: Request, { params }: { params: { id: string } const zod = gweetIdSchema.safeParse(id) if (!zod.success) { - return NextResponse.json( - { - message: "Invalid request body", - error: zod.error.formErrors, - }, { status: 400 }, - ) + return NextResponse.json({ + message: "Invalid request body", + error: zod.error.formErrors, + }, { status: 400 }) } try { @@ -96,20 +120,16 @@ export async function GET(request: Request, { params }: { params: { id: string } }) if (!gweet) { - return NextResponse.json( - { - message: "Gweet not found", - }, { status: 404 }, - ) + return NextResponse.json({ + message: "Gweet not found", + }, { status: 404 }) } return NextResponse.json(gweet, { status: 200 }) } catch (error) { - return NextResponse.json( - { - message: "Something went wrong", - error, - }, { status: 500 }, - ) + return NextResponse.json({ + message: "Something went wrong", + error, + }, { status: 500 }) } } \ No newline at end of file diff --git a/app/api/gweets/likes/route.ts b/app/api/gweets/likes/route.ts index 6c298fed796a99885baa5826724286a7097b2550..2f22948db9234ff9281ab8be2b407ed3cca409ae 100644 --- a/app/api/gweets/likes/route.ts +++ b/app/api/gweets/likes/route.ts @@ -3,7 +3,36 @@ import { z } from "zod" import { db } from "@/lib/db" -// get likes from user +/** + * @swagger + * /api/gweets/likes: + * get: + * description: Gets back likeData + * content: + * application/json: + * schema: + * responses: + * 200: + * description: fetched like! + * 500: + * description: Error + * + * post: + * description: Creates Gweet + * responses: + * 200: + * description: Gweet unliked! + * 201: + * description: Gweet liked! + * 401: + * description: Unauthorized + * 404: + * description: Invalid request body ! + * 500: + * description: Error + * + */ + export async function GET(request: Request) { const { searchParams } = new URL(request.url) const user_id = searchParams.get("user_id") || undefined @@ -41,16 +70,13 @@ export async function GET(request: Request) { return NextResponse.json(gweets, { status: 200 }) } catch (error: any) { - return NextResponse.json( - { - message: "Something went wrong", - error: error.message, - }, { status: error.errorCode || 500 }, - ) + return NextResponse.json({ + message: "Something went wrong", + error: error.message, + }, { status: error.errorCode || 500 }) } } -// like and dislike export async function POST(request: Request) { const { gweet_id, user_id } = await request.json() @@ -64,12 +90,10 @@ export async function POST(request: Request) { const zod = likeSchema.safeParse({ gweet_id, user_id }) if (!zod.success) { - return NextResponse.json( - { - message: "Invalid request body", - error: zod.error.formErrors, - }, { status: 400 }, - ) + return NextResponse.json({ + message: "Invalid request body", + error: zod.error.formErrors, + }, { status: 400 }) } try { @@ -87,7 +111,7 @@ export async function POST(request: Request) { }, }) - return NextResponse.json({ message: "Gweet unliked" }) + return NextResponse.json({ message: "Gweet unliked" }, { status: 200 }) } else { await db.like.create({ data: { @@ -96,12 +120,12 @@ export async function POST(request: Request) { }, }) - return NextResponse.json({ message: "Gweet liked" }) + return NextResponse.json({ message: "Gweet liked" }, { status: 201 }) } } catch (error: any) { return NextResponse.json({ message: "Something went wrong", error: error.message, - }) + }, { status: 500 }) } } \ No newline at end of file diff --git a/app/api/gweets/regweets/route.ts b/app/api/gweets/regweets/route.ts index 1cc824193d6af5d418bb82692d660f6a01f709f8..cae8796f93f1be8da2ace7c2bb3627bf6c85f8c4 100644 --- a/app/api/gweets/regweets/route.ts +++ b/app/api/gweets/regweets/route.ts @@ -3,6 +3,24 @@ import { z } from "zod" import { db } from "@/lib/db" +/** + * @swagger + * /api/gweets/regweets: + * post: + * description: Creates Regweet + * responses: + * 200: + * description: Deleted gweet regweet! + * 201: + * description: Gweet regweeted! + * 400: + * description: Invalid request body + * 401: + * description: Unauthorized + * 500: + * description: Error + */ + export async function POST(request: Request) { const { gweet_id, user_id } = await request.json() @@ -16,12 +34,10 @@ export async function POST(request: Request) { const zod = regweetSchema.safeParse({ gweet_id, user_id }) if (!zod.success) { - return NextResponse.json( - { - message: "Invalid request body", - error: zod.error.formErrors, - }, { status: 400 }, - ) + return NextResponse.json({ + message: "Invalid request body", + error: zod.error.formErrors, + }, { status: 400 }) } try { @@ -39,7 +55,7 @@ export async function POST(request: Request) { }, }) - return NextResponse.json({ message: "Deleted gweet regweet" }) + return NextResponse.json({ message: "Deleted gweet regweet" }, { status: 200 }) } else { await db.regweet.create({ data: { @@ -48,7 +64,7 @@ export async function POST(request: Request) { }, }) - return NextResponse.json({ message: "Gweet regweeted" }) + return NextResponse.json({ message: "Gweet regweeted" }, { status: 201 }) } } catch (error: any) { return NextResponse.json({ error: error.message }, { status: 500 }) diff --git a/app/api/gweets/route.ts b/app/api/gweets/route.ts index cf5ae7257c9c264516e04c3eb90afe5d57ace20a..fd57494aeb959838878403c370133c0a7f60375f 100644 --- a/app/api/gweets/route.ts +++ b/app/api/gweets/route.ts @@ -4,7 +4,41 @@ import { z } from "zod" import { db } from "@/lib/db" import { utapi } from "uploadthing/server" -// get gweets +/** + * @swagger + * /api/gweets: + * get: + * description: Gives back a List of Gweets + * content: + * application/json: + * schema: + * responses: + * 200: + * description: fetched gweets! + * 500: + * description: Error + * + * post: + * description: Creates Gweet + * responses: + * 200: + * description: Gweet created! + * 401: + * description: Unauthorized + * 500: + * description: Error + * + * delete: + * description: Deletes Gweet + * responses: + * 200: + * description: deleted! + * 401: + * description: Unauthorized + * 500: + * description: Error + */ + export async function GET(request: Request) { const { searchParams } = new URL(request.url) @@ -30,9 +64,9 @@ export async function GET(request: Request) { // if (gweet && gweet.replyToGweetId) thread = await fetchThread(gweet.replyToGweetId) // } - // // logic correct TODO + // // logic correct TODO get all gweets above comment // const prevId = thread.length < 4 ? undefined : thread[thread.length - 1].id - // return NextResponse.json({ gweets: thread, prevId }) + // return NextResponse.json({ gweets: thread, prevId }, { status: 200 }) // } const gweets = await db.gweet.findMany({ @@ -53,20 +87,35 @@ export async function GET(request: Request) { }), ...(type === "user_gweets" && { - authorId: id, + author: { + username: id, + }, }), ...(type === "user_replies" && { - authorId: id, + author: { + username: id, + }, NOT: { replyToGweetId: null, }, }), + ...(type === "user_media" && { + author: { + username: id, + }, + media: { + some: {}, + }, + }), + ...(type === "user_likes" && { likes: { some: { - userId: id, + user: { + username: id, + }, }, }, }), @@ -111,15 +160,14 @@ export async function GET(request: Request) { }, }) - const nextId = gweets.length < take ? undefined : gweets[gweets.length - 1].id + const nextId = gweets.length < take ? undefined : gweets[gweets.length - 1]?.id - return NextResponse.json({ gweets, nextId }) + return NextResponse.json({ gweets, nextId }, { status: 200 }) } catch (error) { - return NextResponse.error() + return NextResponse.json(error, { status: 500 }) } } -// create gweet export async function POST(request: Request) { const { gweet, fileprops } = await request.json() @@ -144,12 +192,10 @@ export async function POST(request: Request) { ) if (!zodGweet.success) { - return NextResponse.json( - { - message: "Invalid request body", - error: zodGweet.error.formErrors, - }, { status: 400 }, - ) + return NextResponse.json({ + message: "Invalid request body", + error: zodGweet.error.formErrors, + }, { status: 400 }) } try { @@ -174,12 +220,10 @@ export async function POST(request: Request) { const zodMedia = mediaSchema.safeParse(mediaArray) if (!zodMedia.success) { - return NextResponse.json( - { - message: "Invalid media body", - error: zodMedia.error.formErrors, - }, { status: 400 }, - ) + return NextResponse.json({ + message: "Invalid media body", + error: zodMedia.error.formErrors, + }, { status: 400 }) } await db.media.createMany({ @@ -187,18 +231,15 @@ export async function POST(request: Request) { }) } - return NextResponse.json(created_gweet, { status: 200 }) + return NextResponse.json(created_gweet, { status: 201 }) } catch (error: any) { - return NextResponse.json( - { - message: "Something went wrong", - error: error.message, - }, { status: error.errorCode || 500 }, - ) + return NextResponse.json({ + message: "Something went wrong", + error: error.message, + }, { status: error.errorCode || 500 }) } } -// delete gweet export async function DELETE(request: Request) { const { searchParams } = new URL(request.url) const id = searchParams.get("id") as string @@ -232,14 +273,12 @@ export async function DELETE(request: Request) { }, }) - return NextResponse.json({ message: "Gweet deleted successfully", }) + return NextResponse.json({ message: "Gweet deleted" }, { status: 200 }) } catch (error: any) { - return NextResponse.json( - { - message: "Something went wrong", - error: error.message, - }, { status: error.errorCode || 500 }, - ) + return NextResponse.json({ + message: "Something went wrong", + error: error.message, + }, { status: error.errorCode || 500 }) } } diff --git a/app/api/hashtags/route.ts b/app/api/hashtags/route.ts index b4ffb8ef97ebee57128b889e83ab2264d6c5aefe..e1848debfe876be7640ef7376a4b0fed40ec19b9 100644 --- a/app/api/hashtags/route.ts +++ b/app/api/hashtags/route.ts @@ -3,6 +3,32 @@ import { z } from "zod" import { db } from "@/lib/db" +/** + * @swagger + * /api/hashtags: + * get: + * description: Gives back a List of Hashtags + * content: + * application/json: + * schema: + * responses: + * 200: + * description: fetched hashtags! + * 500: + * description: Error + * + * post: + * description: Creates Hashtag + * responses: + * 200: + * description: Hashtag created! + * 401: + * description: Unauthorized + * 500: + * description: Error + * + */ + export async function GET() { try { const hashtags = await db.hashtag.findMany({ @@ -57,18 +83,8 @@ export async function POST(request: Request) { } } - return NextResponse.json( - { - message: "Hashtag(s) created", - }, - { status: 200 }, - ) + return NextResponse.json({ message: "Hashtag(s) created", }, { status: 201 }) } catch (error: any) { - return NextResponse.json( - { - error: error.message, - }, - { status: 500 }, - ) + return NextResponse.json({ error: error.message, }, { status: 500 },) } } \ No newline at end of file diff --git a/app/api/route.ts b/app/api/route.ts index ae6ece829b02260a63fbd9add4bcd171f9e5a215..8672d2778c10343280dc3f6d89d28c530136c270 100644 --- a/app/api/route.ts +++ b/app/api/route.ts @@ -9,5 +9,5 @@ export async function GET() { return new NextResponse(JSON.stringify({ error: 'unauthorized' }), { status: 401 }) } - return NextResponse.json({ authenticated: !!session }) + return NextResponse.json({ authenticated: !!session }, { status: 200 }) } \ No newline at end of file diff --git a/app/api/signup/route.ts b/app/api/signup/route.ts index ffb9dbaa646337cc621f18ecf6cd6a80ce49d71b..01c2b83b700b695ca40570fe01e56215d89641d8 100644 --- a/app/api/signup/route.ts +++ b/app/api/signup/route.ts @@ -3,6 +3,22 @@ import { hash } from 'bcrypt' import { NextResponse } from 'next/server' import { normalize } from 'normalize-diacritics' +/** + * @swagger + * /api/signup: + * + * post: + * description: Creates Account after Email was verified + * responses: + * 200: + * description: Verification sent! + * 422: + * description: Email already used + * 500: + * description: Error! + * + */ + export async function POST(req: Request) { try { const { username, email, password } = await req.json() @@ -19,7 +35,7 @@ export async function POST(req: Request) { }) if (existingUser) { - throw new Error('email already exists') + return NextResponse.json({ error: 'Email already exists' }, { status: 422 }) } let isUnique = false @@ -46,21 +62,11 @@ export async function POST(req: Request) { } }) + return NextResponse.json({ usernameOrEmail: user.email }) + } catch (error) { return NextResponse.json({ - usernameOrEmail: user.email - }) - } catch (err: any) { - if (err.message === 'email already exists') { - return new NextResponse(JSON.stringify({ - error: err.message - }), { status: 422 } - ) - } - - return new NextResponse( - JSON.stringify({ - error: err.message - }), { status: 500 } - ) + message: "Something went wrong", + error, + }, { status: 500 }) } } \ No newline at end of file diff --git a/app/api/uploadthing/core.ts b/app/api/uploadthing/core.ts index 3652b13a059642ebb2aca3d32ea7e3ccf7d15291..fbb5b7f38f093a56544208c9935e4c0a846011ec 100644 --- a/app/api/uploadthing/core.ts +++ b/app/api/uploadthing/core.ts @@ -4,7 +4,27 @@ import { createUploadthing, type FileRouter } from "uploadthing/next" const f = createUploadthing() export const ourFileRouter = { - imageUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 4 } }) + mediaUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 4 } }) + .middleware(async ({ req }) => { + const user = await getCurrentUser() + + if (!user) throw new Error("Unauthorized") + + return { userId: user.id } + }) + .onUploadComplete(async ({ metadata, file }) => { }), + + imageUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 1 } }) + .middleware(async ({ req }) => { + const user = await getCurrentUser() + + if (!user) throw new Error("Unauthorized") + + return { userId: user.id } + }) + .onUploadComplete(async ({ metadata, file }) => { }), + + bannerUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 1 } }) .middleware(async ({ req }) => { const user = await getCurrentUser() diff --git a/app/api/users/[username]/route.ts b/app/api/users/[username]/route.ts new file mode 100644 index 0000000000000000000000000000000000000000..4e90df12e820bf1795c81e43e1eb12ad385cdf15 --- /dev/null +++ b/app/api/users/[username]/route.ts @@ -0,0 +1,117 @@ +import { db } from "@/lib/db" +import { NextResponse } from "next/server" +import { z } from "zod" + +export async function GET(request: Request, context: { params: { username: string } }) { + const { username } = context.params + + const idSchema = z.string() + const zod = idSchema.safeParse(username) + + if (!zod.success) { + return NextResponse.json(zod.error, { status: 400 }) + } + + try { + const user = await db.user.findUnique({ + where: { + username, + }, + + select: { + id: true, + name: true, + username: true, + email: true, + image: true, + banner: true, + + createdAt: true, + bio: true, + location: true, + website: true, + followers: true, + following: true, + + gweets: { + select: { + id: true, + media: true, + }, + orderBy: { + createdAt: "desc", + }, + }, + + _count: { + select: { + followers: true, + following: true, + }, + }, + }, + }) + + return NextResponse.json(user, { status: 200 }) + } catch (error: any) { + return NextResponse.json(error.message, { status: 500 }) + } +} + +export async function PUT(request: Request) { + const { + userId, + name, + bio, + location, + website, + banner, + image, + } = await request.json() + + const userSchema = z + .object({ + userId: z.string().cuid(), + name: z.string().min(1).max(50), + bio: z.string().max(160).optional(), + location: z.string().max(30).optional(), + website: z.string().max(100).optional(), + banner: z.string().optional(), + image: z.string().optional(), + }) + .strict() + + const zod = userSchema.safeParse({ + userId, + name, + bio, + location, + website, + banner, + image, + }) + + if (!zod.success) { + return NextResponse.json(zod.error, { status: 400 }) + } + + try { + const user = await db.user.update({ + where: { + id: userId, + }, + data: { + name, + bio, + location, + website, + banner, + image, + }, + }) + + return NextResponse.json(user, { status: 200 }) + } catch (error: any) { + return NextResponse.json(error.message, { status: 500 }) + } +} \ No newline at end of file diff --git a/app/api/users/favgameslist/route.ts b/app/api/users/favgameslist/route.ts index 7b06bead77749d765ee284b985b0063922027025..67bd79f2c75a37bc649488a92df2e41cefd8d826 100644 --- a/app/api/users/favgameslist/route.ts +++ b/app/api/users/favgameslist/route.ts @@ -4,13 +4,13 @@ import { revalidatePath } from "next/cache" import { NextRequest, NextResponse } from "next/server" export async function PUT(req: NextRequest) { - const user = await getCurrentUser() + const session = await getCurrentUser() - if (!user) { + if (!session) { return NextResponse.json({ status: 401, message: 'Unauthorized' }) } - const userId = user.id + const userId = session.id const data = await req.json() data.gameId = parseInt(data.gameId) @@ -51,9 +51,9 @@ export async function PUT(req: NextRequest) { const path = req.nextUrl.searchParams.get('path') || '/' revalidatePath(path) - return NextResponse.json({ status: 201, message: 'Game Hinzugefügt' }) + return NextResponse.json({ message: 'Game added' }, { status: 201 }) } catch (error: any) { - return NextResponse.json({ status: 500, message: error.message }) + return NextResponse.json({ message: error.message }, { status: 500 }) } } \ No newline at end of file diff --git a/app/api/users/follow/route.ts b/app/api/users/follow/route.ts new file mode 100644 index 0000000000000000000000000000000000000000..0d856615070aa3012d62ffbc31b81b8cd73734b1 --- /dev/null +++ b/app/api/users/follow/route.ts @@ -0,0 +1,170 @@ +import { db } from "@/lib/db" +import { getCurrentUser } from "@/lib/session" +import { NextResponse } from "next/server" +import { z } from "zod" + +/** + * @swagger + * /api/users/follow: + * get: + * description: Get Followers for signed in User + * responses: + * 200: + * description: fetched follows! + * 500: + * description: Error + * + * put: + * description: Creates Following Record from one User to another + * requestBody: + * content: + * application/json: + * schema: # Request body contents + * type: object + * properties: + * follwerid: + * type: string + * followingid: + * type: string + * example: # Sample object + * follwerid:: 10 + * followingid:: 12 + * responses: + * 200: + * description: Follow handled! + * 401: + * description: Unauthorized + * 500: + * description: Error + * + */ + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url) + const username = searchParams.get("userId") || undefined + const type = searchParams.get("type") || undefined + + const userIdSchema = z.string().optional() + const zod = userIdSchema.safeParse(username) + + if (!zod.success) { + return NextResponse.json(zod.error, { status: 400 }) + } + + try { + if (type === "followers") { + const followers = await db.user + .findUnique({ + where: { + username, + }, + }) + .followers({ + include: { + followers: true, + following: true, + }, + }) + return NextResponse.json(followers, { status: 200 }) + } else if (type === "following") { + const following = await db.user + .findUnique({ + where: { + username, + }, + }) + .following({ + include: { + followers: true, + following: true, + }, + }) + + return NextResponse.json(following, { status: 200 }) + } + } catch (error: any) { + return NextResponse.json(error.message, { status: 500 }) + } +} + +export async function PUT(request: Request) { + const session = await getCurrentUser() + const { userId } = await request.json() + + const followerIdSchema = z + .object({ + userId: z.string().cuid(), + }) + .strict() + + const zod = followerIdSchema.safeParse({ userId }) + + if (!zod.success) { + return NextResponse.json(zod.error, { status: 400 }) + } + + try { + await db.user.update({ + where: { + id: userId, + }, + + data: { + followers: { + connect: { + id: session?.id, + }, + }, + }, + }) + + return NextResponse.json( + { + message: "followed", + }, { status: 200 } + ) + } catch (error: any) { + return NextResponse.json(error.message, { status: 500 }) + } +} + +export async function DELETE(request: Request) { + const session = await getCurrentUser() + const { userId } = await request.json() + + const followerIdSchema = z + .object({ + userId: z.string().cuid(), + }) + .strict() + + const zod = followerIdSchema.safeParse({ userId }) + + if (!zod.success) { + return NextResponse.json(zod.error, { status: 400 }) + } + + try { + await db.user.update({ + where: { + id: userId, + }, + + data: { + followers: { + disconnect: { + id: session?.id, + }, + }, + }, + }) + + return NextResponse.json( + { + message: "unfollowed", + }, { status: 200 }, + ) + } catch (error: any) { + return NextResponse.json(error.message, { status: 500 }) + } +} \ No newline at end of file diff --git a/app/api/gamelists/route.ts b/app/api/users/gamelists/route.ts similarity index 68% rename from app/api/gamelists/route.ts rename to app/api/users/gamelists/route.ts index 7c578b3ef8e25ba5431237bbfe24b459b46b5dd6..2bf2c83a1dc3658d227bc7e31eac0eecc8def98c 100644 --- a/app/api/gamelists/route.ts +++ b/app/api/users/gamelists/route.ts @@ -4,15 +4,29 @@ import { User } from "@prisma/client" import { revalidatePath } from "next/cache" import { NextRequest, NextResponse } from "next/server" +/** + * @swagger + * /api/users/gamelists: + * put: + * description: Changes gamelists of a user + * id in body must match userid + * responses: + * 200: + * description: Request handled! + * 401: + * description: Unauthorized + * + */ + export async function PUT(req: NextRequest) { const sessionUser = await getCurrentUser() const data: User = await req.json() - console.log("userid", sessionUser!.id, "formdataid", data.id) + if (!sessionUser || sessionUser.id != data.id) { - return NextResponse.json({ status: 401, message: 'Unauthorized' }) + return NextResponse.json({ message: 'Unauthorized' }, { status: 401 }) } - console.log("put list") + try { const dbUser = await db.user.findFirst({ where: { @@ -41,11 +55,12 @@ export async function PUT(req: NextRequest) { } }) } - } catch (error) { - } - const path = req.nextUrl.searchParams.get('path') || '/' - revalidatePath(path) + const path = req.nextUrl.searchParams.get('path') || '/' + revalidatePath(path) - return NextResponse.json({ status: 201, message: 'Game Hinzugefügt' }) + return NextResponse.json({ message: 'Game added' }, { status: 201 }) + } catch (error: any) { + return NextResponse.json({ message: error.message }, { status: 500 }) + } } \ No newline at end of file diff --git a/app/api/users/route.ts b/app/api/users/route.ts new file mode 100644 index 0000000000000000000000000000000000000000..7f3814a20547512e139f8877290c2d958691fed8 --- /dev/null +++ b/app/api/users/route.ts @@ -0,0 +1,43 @@ +import { db } from "@/lib/db" +import { NextResponse } from "next/server" +import { z } from "zod" + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url) + const id = searchParams.get("id") || undefined + const idSchema = z.string().cuid().optional() + + const zod = idSchema.safeParse(id) + + if (!zod.success) { + return NextResponse.json(zod.error, { status: 400 }) + } + + try { + const users = await db.user.findMany({ + where: { + NOT: { + id, + }, + }, + + orderBy: { + createdAt: "desc", + }, + + select: { + id: true, + name: true, + username: true, + email: true, + image: true, + following: true, + followers: true, + }, + }) + + return NextResponse.json(users, { status: 200 }) + } catch (error: any) { + return NextResponse.json(error.message, { status: 500 }) + } +} \ No newline at end of file diff --git a/components/add-game-to-finished-list.tsx b/components/add-game-to-finished-list.tsx index bc37572a92fb214c02fa29e9ac094296782b856e..6f8ec4fec6592b7d0ef72a7b9c7fb5e990d99822 100644 --- a/components/add-game-to-finished-list.tsx +++ b/components/add-game-to-finished-list.tsx @@ -33,7 +33,7 @@ export default function AddGameToFinishedList(props: { gameId: string, user: Use formData.id = user.id formData.finishedGameList = props.user.finishedGameList.filter((id) => id !== gameId) console.log(formData.finishedGameList) - const response = await fetch('/api/gamelists', { + const response = await fetch('/api/users/gamelists', { method: 'PUT', body: JSON.stringify(formData) }) @@ -52,7 +52,7 @@ export default function AddGameToFinishedList(props: { gameId: string, user: Use formData.id = user.id props.user.finishedGameList.push(gameId) formData.finishedGameList = props.user.finishedGameList - const response = await fetch('/api/gamelists', { + const response = await fetch('/api/users/gamelists', { method: 'PUT', body: JSON.stringify(formData) }) diff --git a/components/add-game-to-plan-list.tsx b/components/add-game-to-plan-list.tsx index 61f62e85fa0c4ad352a0b7b680769904b34c91d4..9de2099cfc9a791adeeb582fa51f2951246130ea 100644 --- a/components/add-game-to-plan-list.tsx +++ b/components/add-game-to-plan-list.tsx @@ -33,7 +33,7 @@ export default function AddGameToPlanList(props: { gameId: string, user: User }) formData.id = user.id formData.planningGameList = props.user.planningGameList.filter((id) => id !== gameId) console.log(formData.planningGameList) - const response = await fetch('/api/gamelists', { + const response = await fetch('/api/users/gamelists', { method: 'PUT', body: JSON.stringify(formData) }) @@ -52,7 +52,7 @@ export default function AddGameToPlanList(props: { gameId: string, user: User }) formData.id = user.id props.user.planningGameList.push(gameId) formData.planningGameList = props.user.planningGameList - const response = await fetch('/api/gamelists', { + const response = await fetch('/api/users/gamelists', { method: 'PUT', body: JSON.stringify(formData) }) diff --git a/components/add-game-to-playing-list.tsx b/components/add-game-to-playing-list.tsx index 73e8067728687051a7b63e67640a5a5c014238d7..81232c6e72774bc9e86d07f90d7970f1fc070fd0 100644 --- a/components/add-game-to-playing-list.tsx +++ b/components/add-game-to-playing-list.tsx @@ -33,7 +33,7 @@ export default function AddGameToPlayingList(props: { gameId: string, user: User formData.id = user.id formData.playingGameList = props.user.playingGameList.filter((id) => id !== gameId) console.log(formData.playingGameList) - const response = await fetch('/api/gamelists', { + const response = await fetch('/api/users/gamelists', { method: 'PUT', body: JSON.stringify(formData) }) @@ -52,7 +52,7 @@ export default function AddGameToPlayingList(props: { gameId: string, user: User formData.id = user.id props.user.playingGameList.push(gameId) formData.playingGameList = props.user.playingGameList - const response = await fetch('/api/gamelists', { + const response = await fetch('/api/users/gamelists', { method: 'PUT', body: JSON.stringify(formData) }) diff --git a/components/create-gweet/api/post-gweet.ts b/components/create-gweet/api/post-gweet.ts index 76c02d36fcbeb61b585fa643da4bcb8bf334dc7e..9f10a8dce0a6907e68aa6d33c80f4b31b607b70c 100644 --- a/components/create-gweet/api/post-gweet.ts +++ b/components/create-gweet/api/post-gweet.ts @@ -25,7 +25,7 @@ export const postGweet = async ({ try { let fileprops: { fileUrl: string; fileKey: string }[] = [] if (files.length > 0) { - fileprops = await uploadFiles({ files, endpoint: 'imageUploader' }) + fileprops = await uploadFiles({ files, endpoint: 'mediaUploader' }) } const data = await fetch('/api/gweets', { diff --git a/components/create-gweet/components/create-gweet.tsx b/components/create-gweet/components/create-gweet.tsx index 1b00d96b7bdea89719c80e5a0293f12f4302f4bf..2788484cad964d1e7e038de583be1353f509653f 100644 --- a/components/create-gweet/components/create-gweet.tsx +++ b/components/create-gweet/components/create-gweet.tsx @@ -3,7 +3,7 @@ import { zodResolver } from "@hookform/resolvers/zod" import { useSession } from "next-auth/react" import Image from "next/image" -import { useRef, useState } from "react" +import { useEffect, useRef, useState } from "react" import { useForm } from "react-hook-form" import * as z from "zod" @@ -35,6 +35,10 @@ const FormSchema = z.object({ .max(240, { message: "Gweets cannot be more that 240 characters." }), }) +const ImagesArraySchema = z.array(z.custom<File>().refine((file) => file instanceof File, { message: "Expected a file" }) + .refine((file) => file?.size <= 4000000, { message: "Images must be less than 4MB" })) + .optional() + export const CreateGweet = ({ parent_gweet, quoted_gweet, @@ -52,12 +56,25 @@ export const CreateGweet = ({ const imageUploadRef = useRef<HTMLInputElement>(null) const { data: session } = useSession() - const { isLoading, mutate } = useCreateGweet() + const { isLoading, isSuccess, mutate } = useCreateGweet() const form = useForm<z.infer<typeof FormSchema>>({ resolver: zodResolver(FormSchema), }) + let disable = true + if (!isLoading && session?.user.username !== undefined) { + // console.log("form is valid", form.formState.isValid) + if (form.formState.isDirty && form.formState.isValid) { + if (chosenImages.length !== 0) { + disable = false + } else { + disable = true + } + disable = false + } + } + async function onGweet(formData: z.infer<typeof FormSchema>) { if (!session) return null @@ -69,19 +86,37 @@ export const CreateGweet = ({ quoteGweetId: quoted_gweet?.id || null, }) - toast({ - description: "Your gweet was send.", - }) - - form.setValue('gweet', '') - setChosenImages([]) + disable = true } + useEffect(() => { + form.formState.isValid // needs to be checked to trigger validation on first load (weird behavior) + if (isSuccess) { + toast({ + description: "Your gweet was send.", + }) + + form.reset() + form.setValue('gweet', '') + setChosenImages([]) + } + }, [form, isSuccess]) + const chooseImages = async ( event: React.ChangeEvent<HTMLInputElement>, setChosenImages: (images: IChosenImages[]) => void, ) => { const files = event.target.files + try { + const fileArray = Array.from(files?.length ? files : []) + ImagesArraySchema.parse(fileArray) + } catch (error: any) { + const err = error as z.ZodError + return toast({ + variant: "destructive", + description: err.issues[0]?.message, + }) + } if (files && files.length > 0) { const newImages: IChosenImages[] = [] @@ -98,16 +133,18 @@ export const CreateGweet = ({ const filePath = files[i] const reader = new FileReader() - reader.readAsDataURL(filePath) + if (filePath) { + reader.readAsDataURL(filePath) - reader.onload = () => { - newImages.push({ - url: reader.result, - file: filePath, - }) + reader.onload = () => { + newImages.push({ + url: reader.result, + file: filePath, + }) - if (newImages.length === files.length) { - setChosenImages([...chosenImages, ...newImages]) + if (newImages.length === files.length) { + setChosenImages([...chosenImages, ...newImages]) + } } } } @@ -185,7 +222,12 @@ export const CreateGweet = ({ <FormItem> <FormControl> <Textarea - placeholder={placeholder || "What's on your mind?"} + placeholder={placeholder || + chosenImages.length !== 0 ? + "Tell us something about your media." + : + "What's on your mind?" + } className="resize-none min-h-[100px]" disabled={isLoading || !session.user} {...field} @@ -222,19 +264,20 @@ export const CreateGweet = ({ {chosenImages.map((image, i) => { const isFirstImage = chosenImages.length === 3 && i === 0 return ( - <Card key={i} className={`relative max-h-[600px] overflow-hidden ${isFirstImage ? "row-span-2" : ""}`}> + <Card key={i} className={`relative max-h-[600px] overflow-hidden ${isFirstImage ? "row-span-2" : ""} ${isLoading ? "opacity-50" : ""}`}> <Button type="button" size="icon" variant="secondary" className="rounded-full absolute top-1 right-1 z-40" + disabled={isLoading} onClick={() => { setChosenImages( chosenImages.filter((img, j) => j !== i), ) }} > - <Icons.close className="w-6 h-6" /> + <Icons.close /> </Button> <Image src={image.url as string} @@ -252,7 +295,7 @@ export const CreateGweet = ({ </Card> <div className="flex justify-end"> - <Button type="submit" size="lg" className="w-20" disabled={isLoading || !session.user}> + <Button type="submit" size="lg" className="w-20" disabled={disable}> {isLoading ? ( <Icons.spinner className="h-4 w-4 animate-spin" /> ) : ( diff --git a/components/create-gweet/hooks/use-create-gweet.ts b/components/create-gweet/hooks/use-create-gweet.ts index 545aeeb262a2b41c71099897c114994dfea6f4eb..fde0e2321f1fa1e8d626687d4ef68b6a6eca2b91 100644 --- a/components/create-gweet/hooks/use-create-gweet.ts +++ b/components/create-gweet/hooks/use-create-gweet.ts @@ -33,7 +33,7 @@ export const useCreateGweet = () => { queryClient.invalidateQueries(["hashtags"]) }, onError: (error) => { - console.log("error", error) + if (process.env.NODE_ENV === "development") console.log(error) }, }, ) diff --git a/components/filter-sort-games.tsx b/components/filter-sort-games.tsx index 12ef0c9e5a3184add9d30ad75d8a87fd0106a8e0..1d209973b41afef083406dc9f0950c25b90b21ea 100644 --- a/components/filter-sort-games.tsx +++ b/components/filter-sort-games.tsx @@ -58,7 +58,7 @@ export default function Sort() { return ( <Card className="p-6 grid items-start gap-2 bg-secondary"> - <h1>Filter</h1> + <h1 className="font-bold">Filter</h1> <Select value={selectedCategory ? selectedCategory : undefined} key={selectedCategory[0]} onValueChange={(value) => setSelectedCategory(value)}> <SelectTrigger className={`bg-background border-none w-full ${selectedCategory[0] ? 'font-extrabold' : ''}`}> <SelectValue placeholder="By category..." /> @@ -123,7 +123,7 @@ export default function Sort() { </SelectContent> </Select> - <h1 className="pt-6">Sort by</h1> + <h1 className="pt-6 font-bold">Sort by</h1> <div className="flex space-x-2 pb-1"> <Select value={selectedSortMethod} onValueChange={(value) => setSelectedSortMethod(value)}> <SelectTrigger className="bg-background border-none w-full"> diff --git a/components/follow-button.tsx b/components/follow-button.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ed87a2975dc22480f794d14462f530777f66c7ee --- /dev/null +++ b/components/follow-button.tsx @@ -0,0 +1,83 @@ +"use client" + +import { useRouter } from "next/navigation" +import { useEffect, useState } from "react" +import { Icons } from "./icons" +import { useFollow } from "./profile/hooks/use-follow" +import { Button } from "./ui/button" +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog" + +export const FollowButton = ({ + userId, + username, + isFollowing = false, +}: { + userId: string + username: string + isFollowing?: boolean +}) => { + const followMutation = useFollow("follow") + const unfollowMutation = useFollow("unfollow") + + const [text, setText] = useState<"Following" | "Unfollow">("Following") + const [isHovered, setIsHovered] = useState(false) + const [open, setOpen] = useState(false) + + const router = useRouter() + + useEffect(() => { + if (followMutation.isSuccess) { + router.refresh() + } + if (unfollowMutation.isSuccess) { + setOpen(false) + router.refresh() + } + }, [router, followMutation.isSuccess, unfollowMutation.isSuccess]) + + return ( + <div onClick={(e) => { + e.preventDefault() + e.stopPropagation() + }}> + <Dialog open={open} onOpenChange={setOpen}> + {isFollowing ? ( + <DialogTrigger asChild > + <Button variant={`${isHovered ? "destructive" : "outline"}`} size="lg" + className="w-24" + onMouseEnter={() => { + setText("Unfollow") + setIsHovered(true) + }} + onMouseOut={() => { + setText("Following") + setIsHovered(false) + }}> + {text} + </Button> + </DialogTrigger> + ) : ( + <Button size="lg" onClick={() => followMutation.mutate({ userId })}> + Follow + </Button> + )} + <DialogContent> + <DialogHeader> + <DialogTitle>Unfollow @{username}?</DialogTitle> + <DialogDescription> + You can still view their profile, unless their Gweets are protected. + </DialogDescription> + </DialogHeader> + <DialogFooter> + <Button type="submit" onClick={() => unfollowMutation.mutate({ userId })} disabled={unfollowMutation.isLoading}> + {unfollowMutation.isLoading && ( + <Icons.spinner className="mr-2 h-4 w-4 animate-spin" /> + )} + Unfollow + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + </div> + ) +} \ No newline at end of file diff --git a/components/following-button.tsx b/components/following-button.tsx deleted file mode 100644 index b5eb3f4e51b564dad1cd30b38b77fecce04e4dd7..0000000000000000000000000000000000000000 --- a/components/following-button.tsx +++ /dev/null @@ -1,75 +0,0 @@ -"use client" - -import { Follows, Prisma } from '@prisma/client' -import { useSession } from 'next-auth/react' -import { usePathname } from "next/navigation" -import { useEffect, useState } from 'react' -import { Button } from './ui/button' - -// 1: Define a type that includes the relation to `Post` -const userWithFollows = Prisma.validator<Prisma.UserArgs>()({ - include: { followers: true, following: true }, -}) - -// 2: Define a type that only contains a subset of the scalar fields -const userPersonalData = Prisma.validator<Prisma.UserArgs>()({ - select: { email: true, name: true }, -}) - -// 3: This type will include a user and all their posts -type UserWithFollows = Prisma.UserGetPayload<typeof userWithFollows> - - -export default function FollowButton({ user, followingId }: { user: UserWithFollows; followingId: string }) { - const [isFollowing, setIsFollowing] = useState(false) - const [follows, setFollows] = useState([]) - const [buttonPressed, setButtonPress] = useState(false) - - const pathname = usePathname() - const { data: session } = useSession() - - async function fetchFollows() { - - try { - const response = await fetch('/api/followers') - - const data = await response.json() - setFollows(data.follows) - setIsFollowing(false) - data.follows?.forEach((f: Follows) => { - - if (f.followerId == user.id && f.followingId == followingId) { - setIsFollowing(true) - return - } - }) - } catch (error) { - - } - } - useEffect(() => { - fetchFollows() - // TODO: fix this warning - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [buttonPressed]) - - async function handleFollow(e: any) { - e.preventDefault() - - const response = await fetch('/api/followers', { - method: 'PUT', - body: JSON.stringify({ user, followingId }) - }) - - setButtonPress(!buttonPressed) - } - - return ( - <> - {pathname !== `/${session?.user.username}` && - <Button onClick={handleFollow}> - {isFollowing ? 'Unfollow' : 'Follow'} - </Button>} - </> - ) -} \ No newline at end of file diff --git a/components/global-layout.tsx b/components/global-layout.tsx index 8d669c2238cc5aa585982df6d731679ba88fe3cf..0fc932445287c4d7b75503578d51178fadfb3202 100644 --- a/components/global-layout.tsx +++ b/components/global-layout.tsx @@ -4,7 +4,7 @@ export const GlobalLayout = ({ mainContent, sideContent }: { mainContent: JSX.El <div className="col-span-3 flex justify-center"> {mainContent} </div> - <aside className="self-start sticky top-[89px] col-span-1"> + <aside className="self-start sticky top-[89px] col-span-1 space-y-6"> {sideContent} </aside> </div> diff --git a/components/gweets/api/get-gweet.ts b/components/gweets/api/get-gweet.ts index 8b36271cd8afe7b31ebb6d159c7d1b67c5e7457e..6c60829b1e207cae8a773b3f1a777ca233ff291e 100644 --- a/components/gweets/api/get-gweet.ts +++ b/components/gweets/api/get-gweet.ts @@ -1,8 +1,11 @@ export default async function getGweet(id: string | undefined) { try { - const data = await fetch(`/api/gweets/${id}`).then((result) => result.json()) + const data = await fetch(`/api/gweets/${id}`) + if (!data.ok) { + throw new Error('Network response was not ok') + } - return data + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/gweets/api/get-gweets.ts b/components/gweets/api/get-gweets.ts index 18bb683b6712058c19a5750f18a7b33ab3d56235..59b937a8a04a9228008fca464974809efd42a5fa 100644 --- a/components/gweets/api/get-gweets.ts +++ b/components/gweets/api/get-gweets.ts @@ -11,9 +11,12 @@ export const getGweets = async ({ }) => { try { const url = `/api/gweets?cursor=${pageParam}&limit=${limit}${type ? `&type=${type}` : ""}${id ? `&id=${id}` : ""}` - const data = await fetch(url).then((result) => result.json()) + const data = await fetch(url) + if (!data.ok) { + throw new Error('Network response was not ok') + } - return data + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/gweets/components/delete-gweet-modal.tsx b/components/gweets/components/delete-gweet-modal.tsx index 67996349a2559ece51dbcad3bc2bc916945e3619..b7fd3459fe7166a189af34ac720dcf916c03c044 100644 --- a/components/gweets/components/delete-gweet-modal.tsx +++ b/components/gweets/components/delete-gweet-modal.tsx @@ -15,14 +15,27 @@ import { DialogTitle, DialogTrigger, } from "@/components/ui/dialog" -import { useRouter } from "next/navigation" +import { usePathname, useRouter } from "next/navigation" export const DeleteGweetModal = ({ gweet, props, forwardedRef }: { gweet: IGweet, props: any, forwardedRef: any }) => { const { triggerChildren, onSelect, onOpenChange, ...itemProps } = props const { isLoading, mutate, isSuccess } = useDeleteGweet() + const pathname = usePathname() + const isDetail = pathname?.split("/")[2] || "" + const router = useRouter() - if (isSuccess) router.push("/home") + if (isSuccess) { + onOpenChange(false) + + setTimeout(() => { + if (isDetail === "status") { + router.push("/home") + } else { + router.refresh() + } + }, 150) + } return ( <Dialog onOpenChange={onOpenChange}> diff --git a/components/gweets/components/gweet-details.tsx b/components/gweets/components/gweet-details.tsx index 110c6f0c33996dca685d26eaf3c1f2319557368a..bdc93b742c7405aa7bc8dcba11c35cae1b321456 100644 --- a/components/gweets/components/gweet-details.tsx +++ b/components/gweets/components/gweet-details.tsx @@ -29,10 +29,6 @@ export const GweetDetails = () => { return <TryAgain /> } - if (!isLoading && !isError && !gweet) { - return <>Not Found!</> - } - return ( <div> {/* TODO needs handling of all gweets above and under the gweet */} diff --git a/components/gweets/components/gweet-options.tsx b/components/gweets/components/gweet-options.tsx index da121bd6596790b803a8d7b329c0ae2107b242ce..9ce0ff115aa9bea191b552129e0121ece0e80836 100644 --- a/components/gweets/components/gweet-options.tsx +++ b/components/gweets/components/gweet-options.tsx @@ -10,7 +10,6 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { toast } from "@/components/ui/use-toast" -import { env } from "@/env.mjs" import getURL from "@/lib/utils" import { useSession } from "next-auth/react" import { useRef, useState } from "react" diff --git a/components/gweets/components/gweet.tsx b/components/gweets/components/gweet.tsx index 40f1f27eb695af5deea42ebd913e2f55b40c8c4b..4136f5c3c414a200348706ad8ac25fac95c12ff6 100644 --- a/components/gweets/components/gweet.tsx +++ b/components/gweets/components/gweet.tsx @@ -34,6 +34,7 @@ export const Gweet = ({ gweet }: { gweet: IGweet }) => { <div className="flex flex-row h-auto w-full"> <Link href={`/${gweet.author.username}`} + className="h-fit" onClick={(e) => { e.stopPropagation() }}> diff --git a/components/gweets/components/infinite-gweets.tsx b/components/gweets/components/infinite-gweets.tsx index 2e8f73dd51094bb4dec000cd790196a93c6f4341..8952722cfe4c7ae68dcd00d6fd62dc4fb3d69d0c 100644 --- a/components/gweets/components/infinite-gweets.tsx +++ b/components/gweets/components/infinite-gweets.tsx @@ -49,9 +49,11 @@ export const InfiniteGweets = ({ key={gweet.id} > <Gweet gweet={gweet} /> - <div className="px-6"> - <Separator className="my-3" /> - </div> + {index !== page.gweets.length - 1 && ( + <div className="px-6"> + <Separator className="my-3" /> + </div> + )} </div> )) })} diff --git a/components/gweets/hooks/use-delete-gweet.ts b/components/gweets/hooks/use-delete-gweet.ts index 198d9924bf0cf975f017d9ca208472ca25f17373..0ff3a6962b8b4a2e2575210291790e75ff27978a 100644 --- a/components/gweets/hooks/use-delete-gweet.ts +++ b/components/gweets/hooks/use-delete-gweet.ts @@ -12,7 +12,7 @@ export const useDeleteGweet = () => { queryClient.invalidateQueries(["gweets"]) }, onError: (error) => { - console.log(error) + if (process.env.NODE_ENV === "development") console.log(error) }, }) } \ No newline at end of file diff --git a/components/gweets/hooks/use-like.ts b/components/gweets/hooks/use-like.ts index f0ab5591dd8e0e7b8c39a9b3e7c139fbd461a56b..c7159c01194259be7155a8f197f7dd73c5841abf 100644 --- a/components/gweets/hooks/use-like.ts +++ b/components/gweets/hooks/use-like.ts @@ -23,8 +23,8 @@ export const useLike = ({ queryClient.invalidateQueries(["users", gweetAuthorId]) }, onError: () => { - console.log("error") + if (process.env.NODE_ENV === "development") console.log("error") }, }, ) -} +} \ No newline at end of file diff --git a/components/gweets/hooks/use-regweet.ts b/components/gweets/hooks/use-regweet.ts index 82b5ef8468bc099f4f5d6280a464486142d22637..7181c4d0a375caa0467de477eb4c9b82ad1d5c9e 100644 --- a/components/gweets/hooks/use-regweet.ts +++ b/components/gweets/hooks/use-regweet.ts @@ -16,11 +16,9 @@ export const useRegweet = () => { QueryClient.invalidateQueries(["users"]) }, - onError: (error: any) => { - console.log(error) + onError: (error) => { + if (process.env.NODE_ENV === "development") console.log(error) }, - - onSettled: () => { }, }, ) } \ No newline at end of file diff --git a/components/icons.tsx b/components/icons.tsx index 52f4a7e8c3ba0bc159f46798508a44b08580c2be..e21aac5ca87c45bc50d9bb0432a5da54bd72a368 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -4,6 +4,7 @@ import { ArrowRight, ArrowUpToLine, BellRing, + CalendarRange, Check, ChevronLeft, ChevronRight, @@ -18,8 +19,10 @@ import { Image, Laptop, Link, + Link2, Loader2, LucideProps, + MapPin, MessageCircle, Moon, MoreHorizontal, @@ -29,6 +32,7 @@ import { Repeat2, Settings, SunMedium, + SwitchCamera, Trash, User, Users, @@ -36,13 +40,9 @@ import { type Icon as LucideIcon, } from "lucide-react" -export type IconsType = { - [key: string]: LucideIcon -} - export type Icon = LucideIcon -export const Icons: IconsType = { +export const Icons = { logo: ({ ...props }: LucideProps) => ( <svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}> <path d="M20.5603 25.7199V34C20.5603 35.1046 19.6649 36 18.5603 36H12.2803C11.1757 36 10.2803 35.1046 10.2803 34V25.7199L15.5127 20.5L20.5603 25.7199Z" fill="#16161A" /> @@ -87,6 +87,10 @@ export const Icons: IconsType = { trash: Trash, // Delete Button link: Link, // Link Button regweet: Repeat2, // Regweet Button + location: MapPin, // Location Button + website: Link2, // Website Button + calendar: CalendarRange, // Calendar Button + camera: SwitchCamera, // Change Image Button post: FileText, page: File, media: Image, diff --git a/components/nav-sidebar.tsx b/components/nav-sidebar.tsx index 7d5808ab9c5a591ec5d9da89f0b49989c0c9d604..382419d20e85e63beb8a84c03435612193be7059 100644 --- a/components/nav-sidebar.tsx +++ b/components/nav-sidebar.tsx @@ -1,6 +1,6 @@ "use client" -import { Icons, IconsType } from "@/components/icons" +import { Icons } from "@/components/icons" import { buttonVariants } from "@/components/ui/button" import { cn } from "@/lib/utils" import { SidebarNavItem } from "@/types" @@ -21,7 +21,7 @@ export const Sidebar = ({ items, user }: { items: SidebarNavItem[], user: User | return ( <nav className="grid items-start gap-2"> {visibleItems.map((item, index) => { - const Icon = Icons[item.icon as keyof IconsType || "arrowRight"] + const Icon = Icons[item.icon || "arrowRight"] if (item.title === "My Profile") { item.href = `/${user?.username}` } @@ -31,7 +31,7 @@ export const Sidebar = ({ items, user }: { items: SidebarNavItem[], user: User | <span className={cn( "group flex items-center rounded-md px-3 py-2 font-medium hover:bg-accent hover:text-accent-foreground", - path === item.href ? "bg-accent" : "transparent", + path.startsWith(item.href) ? "bg-accent" : "transparent", item.disabled && "cursor-not-allowed opacity-80" )} > diff --git a/components/profile/api/follow-user.ts b/components/profile/api/follow-user.ts new file mode 100644 index 0000000000000000000000000000000000000000..bfa5bf2593a412d570c745dcbf6e2ac3f5027886 --- /dev/null +++ b/components/profile/api/follow-user.ts @@ -0,0 +1,12 @@ +export const followUser = async (userId: string) => { + try { + const data = await fetch("/api/users/follow", { + method: "PUT", + body: JSON.stringify({ userId }), + }).then((result) => result.json()) + + return data + } catch (error: any) { + return error.message + } +} \ No newline at end of file diff --git a/components/profile/api/get-follows.ts b/components/profile/api/get-follows.ts new file mode 100644 index 0000000000000000000000000000000000000000..42144039686aa88c7d39c7759ad73ef7f0d09049 --- /dev/null +++ b/components/profile/api/get-follows.ts @@ -0,0 +1,12 @@ +export const getFollows = async (id: string | undefined, type: string | undefined) => { + try { + const data = await fetch(`/api/users/follow?type=${type}&userId=${id}`) + if (!data.ok) { + throw new Error('Network response was not ok') + } + + return data.json() + } catch (error: any) { + return error.message + } +} \ No newline at end of file diff --git a/components/profile/api/get-user-likes.ts b/components/profile/api/get-user-likes.ts new file mode 100644 index 0000000000000000000000000000000000000000..1a1ebd4dd3a14dfa0d5bf18823a772543771c8b4 --- /dev/null +++ b/components/profile/api/get-user-likes.ts @@ -0,0 +1,10 @@ +export const getUserLikes = async (id: string | undefined) => { + try { + const data = await fetch(`/api/tweets/likes?user_id=${id}`) + .then((result) => result.json()) + + return data + } catch (error: any) { + return error.message + } +} \ No newline at end of file diff --git a/components/profile/api/get-user.ts b/components/profile/api/get-user.ts new file mode 100644 index 0000000000000000000000000000000000000000..7942e09c24179c36a5b0f26146d34552920e20b7 --- /dev/null +++ b/components/profile/api/get-user.ts @@ -0,0 +1,25 @@ +export const getUser = async (username: string | undefined) => { + try { + const user = await fetch(`/api/users/${username}`) + .then((result) => result.json()) + + return user + } catch (error: any) { + if (error.response) { + // The request was made and the server responded with a status code + // that falls out of the range of 2xx + console.log(error.response.data) + console.log(error.response.status) + console.log(error.response.headers) + } else if (error.request) { + // The request was made but no response was received + // `error.request` is an instance of XMLHttpRequest in the browser and an instance of + // http.ClientRequest in node.js + console.log(error.request) + } else { + // Something happened in setting up the request that triggered an Error + console.log("Error", error.message) + } + console.log(error.config) + } +} \ No newline at end of file diff --git a/components/profile/api/get-users.ts b/components/profile/api/get-users.ts new file mode 100644 index 0000000000000000000000000000000000000000..b4f6009b6a981520d8208a82e82a41a2c1ec7990 --- /dev/null +++ b/components/profile/api/get-users.ts @@ -0,0 +1,12 @@ +export const getUsers = async (id?: string) => { + try { + const data = await fetch(`/api/users${id ? `?id=${id}` : ""}`) + if (!data.ok) { + throw new Error('Network response was not ok') + } + + return data.json() + } catch (error: any) { + return error.response.data + } +} \ No newline at end of file diff --git a/components/profile/api/unfollow-user.ts b/components/profile/api/unfollow-user.ts new file mode 100644 index 0000000000000000000000000000000000000000..1d23d10d70f67484e60bdaf1f8ef8f59f48bf422 --- /dev/null +++ b/components/profile/api/unfollow-user.ts @@ -0,0 +1,12 @@ +export const unfollowUser = async (userId: string) => { + try { + const data = await fetch(`/api/users/follow`, { + method: "DELETE", + body: JSON.stringify({ userId }), + }).then((result) => result.json()) + + return data + } catch (error: any) { + return error.message + } +} \ No newline at end of file diff --git a/components/profile/api/update-profile.ts b/components/profile/api/update-profile.ts new file mode 100644 index 0000000000000000000000000000000000000000..7fb9c7a923b88d6dab2a05b5df3fe71631b1d6fe --- /dev/null +++ b/components/profile/api/update-profile.ts @@ -0,0 +1,44 @@ +import { uploadFiles } from "@/lib/uploadthing" +import { IProfile } from "./../types/index" + +export const updateProfile = async ({ + profile, + userId, +}: { + profile: IProfile + userId: string +}) => { + if (!profile) return + + try { + let bannerfileprops: { fileUrl: string; fileKey: string } = { fileUrl: '', fileKey: '' } + let imagefileprops: { fileUrl: string; fileKey: string } = { fileUrl: '', fileKey: '' } + + if (profile.banner.file) { + [bannerfileprops = bannerfileprops ?? { fileUrl: '', fileKey: '' }] = + await uploadFiles({ files: [profile.banner.file], endpoint: 'mediaUploader' }) + } + + if (profile.image.file) { + [imagefileprops = imagefileprops ?? { fileUrl: '', fileKey: '' }] = + await uploadFiles({ files: [profile.image.file], endpoint: 'imageUploader' }) + } + + const data = await fetch(`/api/users/${userId}`, { + method: 'PUT', + body: JSON.stringify({ + userId, + name: profile.name, + bio: profile.bio, + location: profile.location, + website: profile.website, + banner: profile.banner.removed ? "" : bannerfileprops.fileUrl !== "" ? bannerfileprops.fileUrl : undefined, + image: imagefileprops.fileUrl !== "" ? imagefileprops.fileUrl : undefined, + }) + }).then((result) => result.json()) + + return data + } catch (error: any) { + return error.Message + } +} \ No newline at end of file diff --git a/components/profile/components/connect.tsx b/components/profile/components/connect.tsx new file mode 100644 index 0000000000000000000000000000000000000000..fe00a65e436833ac63dc075bb11d0e7a502498a3 --- /dev/null +++ b/components/profile/components/connect.tsx @@ -0,0 +1,37 @@ +"use client" + +import LoadingItem from "@/components/loading-item" +import { TryAgain } from "@/components/try-again" +import { Card } from "@/components/ui/card" +import { User } from "next-auth" +import Link from "next/link" +import { useUsers } from "../hooks/use-users" +import { UserItem } from "./user-item" + +export const Connect = ({ title = "Who to follow", session }: { title?: string, session: User | undefined }) => { + const { data: people, isLoading, isError, isSuccess } = useUsers() + + return ( + <div className="space-y-5 flex flex-col"> + {title && <h1 className="font-bold p-1">{title}</h1>} + {isLoading ? ( + <LoadingItem /> + ) : isError ? ( + <TryAgain /> + ) : people?.length <= 0 ? ( + <Card className="p-1"> + <h1 className="text-center">{"Empty :("}</h1> + </Card> + ) : isSuccess && + people?.slice(title ? 0 : undefined, title ? 3 : undefined).map((person) => { + return <UserItem + key={person?.id} + user={person} + sessionId={session?.id} + showBio={title ? false : true} /> + })} + + {title && <Link href={"/people"} className="self-end hover:bg-accent p-1 rounded-lg">Show more</Link>} + </div> + ) +} \ No newline at end of file diff --git a/components/profile/components/edit-profile-modal.tsx b/components/profile/components/edit-profile-modal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6039e781a8b2e4d8557b2f5c8c75dc1c8ffe9c36 --- /dev/null +++ b/components/profile/components/edit-profile-modal.tsx @@ -0,0 +1,359 @@ +"use client" + +import { Icons } from "@/components/icons" +import { AspectRatio } from "@/components/ui/aspect-ratio" +import { Button } from "@/components/ui/button" +import { Card } from "@/components/ui/card" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Textarea } from "@/components/ui/textarea" +import { toast } from "@/components/ui/use-toast" +import { UserAvatar } from "@/components/user-avatar" +import { zodResolver } from "@hookform/resolvers/zod" +import Image from "next/image" +import { useRouter } from "next/navigation" +import { use, useEffect, useRef, useState } from "react" +import { useForm } from "react-hook-form" +import { z } from "zod" +import { useUpdateProfile } from "../hooks/use-update-profile" +import { IProfile, IUser } from "../types" + +const FormSchema = z.object({ + name: z.string().min(1, "Name can't be blank").max(50, "Name can't be more than 50 characters"), + bio: z.string().max(160, "Bio can't be more than 160 characters").optional(), + location: z.string().max(30, "Location can't be more than 30 characters").optional(), + website: z.string().max(100, "Website can't be more than 100 characters").optional(), +}) + +const ImagesSchema = z.custom<File>().refine((file) => file instanceof File, { message: "Expected a file" }) + .refine((file) => file?.size <= 4000000, { message: "Images must be less than 4MB" }) + .optional() + +export const EditProfileModal = ({ user }: { user: IUser }) => { + const { isLoading, isSuccess, mutate } = useUpdateProfile() + + const form = useForm<z.infer<typeof FormSchema>>({ + resolver: zodResolver(FormSchema), + defaultValues: { + name: user.name, + bio: user.bio || "", + location: user.location || "", + website: user.website || "", + }, + }) + + const [open, setOpen] = useState(false) + const [imageErrorMessage, setImageErrorMessage] = useState("") + const [chosenBanner, setChosenBanner] = useState<Partial<IProfile>>({ + banner: { removed: false, url: user?.banner || "", file: undefined }, + }) + const [chosenImages, setChosenImages] = useState<Partial<IProfile>>({ + image: { url: user?.image || "", file: undefined }, + }) + + const bannerInputRef = useRef<HTMLInputElement>(null) + const imageInputRef = useRef<HTMLInputElement>(null) + + const router = useRouter() + + async function onSave(formData: z.infer<typeof FormSchema>) { + if (!user) return null + + const dirty = form.formState.dirtyFields + const profile: IProfile = { + name: formData.name, + bio: dirty.bio ? formData.bio : undefined, + location: dirty.location ? formData.location : undefined, + website: dirty.website ? formData.website : undefined, + banner: { removed: chosenBanner.banner?.removed, url: user?.banner || "", file: chosenBanner.banner?.file }, + image: { url: user?.image || "", file: chosenImages.image?.file }, + } + + mutate({ + profile, + userId: user.id, + }) + } + + let disable = true + if (!isLoading) { + if (chosenBanner.banner?.file !== undefined || chosenImages.image?.file !== undefined || form.formState.isDirty) { + disable = false + } + } + + useEffect(() => { + if (!open) { + form.reset() + form.setValue("name", user?.name) + form.setValue("bio", user?.bio || "") + form.setValue("location", user?.location || "") + form.setValue("website", user?.website || "") + + // wait 150ms for dialog to close before resetting image + setTimeout(() => { + setImageErrorMessage("") + setChosenBanner({ banner: { removed: false, url: user?.banner || "", file: undefined } }) + setChosenImages({ image: { url: user?.image || "", file: undefined } }) + }, 150) + } + }, [form, open, user]) + + useEffect(() => { + if (isSuccess) { + toast({ + description: "Successfully updated profile.", + }) + setOpen(false) + router.refresh() + } + }, [isSuccess, router]) + + const chooseImage = async (event: any, type: string) => { + const file = event.target.files[0] + if (!file) return + try { + ImagesSchema.parse(file) + setImageErrorMessage("") + } catch (error: any) { + const err = error as z.ZodError + setImageErrorMessage(err.issues[0]?.message || "Invalid image") + return + } + + const reader = new FileReader() + + if (type === "banner" && bannerInputRef.current) { + bannerInputRef.current.value = "" + reader.onloadend = () => { + setChosenBanner({ + ["banner"]: { removed: false, url: reader.result as string, file }, + }) + } + } + + if (type === "image" && imageInputRef.current) { + imageInputRef.current.value = "" + reader.onloadend = () => { + setChosenImages({ + ["image"]: { url: reader.result as string, file }, + }) + } + } + + reader.readAsDataURL(file) + } + + if (!user) return null + + return ( + <Dialog open={open} onOpenChange={setOpen}> + <DialogTrigger asChild> + <Button variant="outline">Edit Profile</Button> + </DialogTrigger> + <DialogContent className="sm:max-w-[600px]"> + <DialogHeader> + <DialogTitle>Edit profile</DialogTitle> + <DialogDescription> + Make changes to your profile here. Click save when you are done. + </DialogDescription> + </DialogHeader> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSave)}> + <div className="grid gap-3 py-3"> + <div className="space-y-2"> + <div className="grid grid-cols-4 items-center gap-4"> + <div className="col-span-1 relative w-full overflow-hidden items-center"> + <div className="object-center object-cover w-full h-full"> + {!chosenImages.image?.url ? + <UserAvatar + user={{ username: user.username, image: null }} + className="object-center object-cover w-full h-full aspect-square" + /> + : + <AspectRatio ratio={1 / 1} className="overflow-hidden rounded-full"> + <Image + src={chosenImages.image?.url} + alt={"user image"} + fill + priority + className="object-center object-cover w-full h-full" + /> + </AspectRatio> + } + </div> + <input + className="hidden resize-none" + type="file" + accept="image/*" + ref={imageInputRef} + onChange={(e) => chooseImage(e, "image")} + disabled={isLoading} + /> + <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 flex space-x-3"> + <Button + type="button" + variant="outline" + size="icon" + className="bg-opacity-50 dark:bg-opacity-50" + onClick={() => imageInputRef?.current?.click()} + disabled={isLoading} + > + <Icons.camera /> + </Button> + </div> + </div> + + <Card className="col-span-3 relative w-full overflow-hidden border-none"> + + <AspectRatio ratio={3 / 1} className="bg-muted overflow-hidden"> + {chosenBanner.banner?.url && + <Image + src={chosenBanner.banner?.url} + alt={"user banner image"} + fill + priority + className="object-center object-cover w-full h-full" + /> + } + </AspectRatio> + <input + className="hidden w-full resize-none" + type="file" + accept="image/*" + ref={bannerInputRef} + onChange={(e) => chooseImage(e, "banner")} + disabled={isLoading} + /> + <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 flex space-x-3"> + <Button + type="button" + variant="outline" + size="icon" + className="bg-opacity-50 dark:bg-opacity-50" + onClick={() => bannerInputRef.current?.click()} + disabled={isLoading} + > + <Icons.camera /> + </Button> + {chosenBanner.banner?.url && ( + <Button + type="button" + variant="outline" + size="icon" + className="bg-opacity-50 dark:bg-opacity-50" + onClick={() => setChosenBanner({ banner: { removed: true, url: "", file: undefined } })} + disabled={isLoading} + > + <Icons.close /> + </Button> + )} + </div> + </Card> + </div> + {imageErrorMessage && + <div className="grid grid-cols-4 items-center gap-4"> + <div className="col-span-1"></div> + <div className="col-span-3"> + <p className="text-sm font-medium text-destructive">{imageErrorMessage}</p> + </div> + </div> + } + </div> + + <div className="grid grid-cols-4 items-center gap-4"> + <Label htmlFor="name" className="text-right"> + Name + </Label> + <FormField + control={form.control} + name="name" + render={({ field }) => ( + <FormItem className="col-span-3"> + <FormControl> + <Input id="name" disabled={isLoading} {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </div> + + <div className="grid grid-cols-4 items-center gap-4"> + <Label htmlFor="bio" className="text-right"> + Bio + </Label> + <FormField + control={form.control} + name="bio" + render={({ field }) => ( + <FormItem className="col-span-3"> + <FormControl> + <Textarea id="bio" className="resize-none" disabled={isLoading} {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </div> + + <div className="grid grid-cols-4 items-center gap-4"> + <Label htmlFor="location" className="text-right"> + Location + </Label> + <FormField + control={form.control} + name="location" + render={({ field }) => ( + <FormItem className="col-span-3"> + <FormControl> + <Input id="location" disabled={isLoading} {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </div> + + <div className="grid grid-cols-4 items-center gap-4"> + <Label htmlFor="website" className="text-right"> + Website + </Label> + <FormField + control={form.control} + name="website" + render={({ field }) => ( + <FormItem className="col-span-3"> + <FormControl> + <Input id="website" disabled={isLoading} {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + </div> + </div> + <DialogFooter> + <Button type="submit" disabled={disable}> + {isLoading && ( + <Icons.spinner className="mr-2 h-4 w-4 animate-spin" /> + )} + Save changes + </Button> + </DialogFooter> + </form> + </Form> + </DialogContent> + </Dialog> + ) +} \ No newline at end of file diff --git a/components/profile/components/profile-navbar.tsx b/components/profile/components/profile-navbar.tsx new file mode 100644 index 0000000000000000000000000000000000000000..94a436a3597f9ad8d705427a24c2c06a87b95454 --- /dev/null +++ b/components/profile/components/profile-navbar.tsx @@ -0,0 +1,40 @@ +"use client" + +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" +import Link from "next/link" +import { usePathname } from "next/navigation" + +export const ProfileNavbar = ({ children, param }: { children: React.ReactNode, param: string }) => { + const pathValue = usePathname().split("/")[2] || "gweets" + + return ( + <Tabs defaultValue={"gweets"} value={pathValue} className="w-full h-full p-6 md:p-12 "> + <TabsList className="grid w-full grid-cols-4"> + <Link href={`/${param}`} scroll={false} className="w-full inline-flex items-center justify-center"> + <TabsTrigger value="gweets" className="w-full"> + Gweets + </TabsTrigger> + </Link> + + <Link href={`/${param}/games`} scroll={false} className="w-full inline-flex items-center justify-center"> + <TabsTrigger value="games" className="w-full"> + Games + </TabsTrigger> + </Link> + + <Link href={`/${param}/media`} scroll={false} className="w-full inline-flex items-center justify-center"> + <TabsTrigger value="media" className="w-full"> + Media + </TabsTrigger> + </Link> + + <Link href={`/${param}/likes`} scroll={false} className="w-full inline-flex items-center justify-center"> + <TabsTrigger value="likes" className="w-full"> + Likes + </TabsTrigger> + </Link> + </TabsList> + {children} + </Tabs> + ) +} \ No newline at end of file diff --git a/components/profile/components/profile-side-content.tsx b/components/profile/components/profile-side-content.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b273d8ade513a3ed6cfc26381a78f6139f387fac --- /dev/null +++ b/components/profile/components/profile-side-content.tsx @@ -0,0 +1,40 @@ +import { Card } from "@/components/ui/card" +import { getCurrentUser } from "@/lib/session" +import Image from "next/image" +import { IUser } from "../types" +import { Connect } from "./connect" + +export const ProfileSideContent = async ({ user }: { user: IUser }) => { + const session = await getCurrentUser() + const arrayOfUserMedia = user.gweets.slice(0, 4) + .flatMap((gweet) => gweet.media.slice(0, 4).map((media) => ({ id: gweet.id, url: media.url }))) + .slice(0, 4) + + return ( + <div className="space-y-6"> + {arrayOfUserMedia.length > 0 && + <Card className="p-6 bg-secondary"> + <div className={`grid object-cover ${arrayOfUserMedia.length === 1 ? "grid-cols-1" + : arrayOfUserMedia.length === 2 ? "grid-cols-2 gap-3" + : arrayOfUserMedia.length === 3 || 4 ? "grid-cols-2 grid-rows-2 gap-3" + : "" + }`} + > + {arrayOfUserMedia.map(({ id, url }, i) => { + const isFirstImage = arrayOfUserMedia.length === 3 && i === 0 + return ( + <Card key={id} className={`relative overflow-hidden ${isFirstImage ? "col-span-2 aspect-[2/1]" : "aspect-square"}`}> + <Image src={url} alt="gweet media" fill className="object-cover rounded-lg" /> + </Card> + ) + })} + </div> + </Card> + } + + <Card className="p-6 bg-secondary"> + <Connect session={session} /> + </Card> + </div> + ) +} \ No newline at end of file diff --git a/components/profile/components/profile-user-info.tsx b/components/profile/components/profile-user-info.tsx new file mode 100644 index 0000000000000000000000000000000000000000..914b6fdbf9a35359366fb785fefc7f95a9f2e0a1 --- /dev/null +++ b/components/profile/components/profile-user-info.tsx @@ -0,0 +1,95 @@ +import { FollowButton } from "@/components/follow-button" +import { Icons } from "@/components/icons" +import { AspectRatio } from "@/components/ui/aspect-ratio" +import { UserAvatar } from "@/components/user-avatar" +import { getCurrentUser } from "@/lib/session" +import Image from "next/image" +import Link from "next/link" +import { IUser } from "../types" +import { following } from "../utils/following" +import { EditProfileModal } from "./edit-profile-modal" +import { UserJoinDate } from "./user-join-date" + +export const ProfileUserInfo = async ({ user }: { user: IUser }) => { + const session = await getCurrentUser() + + const isFollowing = following({ + user, + sessionUserId: session ? session.id : "", + }) + + return ( + <> + <AspectRatio ratio={3 / 1} className="bg-muted w-full overflow-hidden"> + {user.banner && + <Image + src={user.banner} + alt={"user banner image"} + fill + priority + className="object-center object-cover w-full h-full" + /> + } + </AspectRatio> + <div className="relative"> + <div className="flex items-end justify-between p-6 md:px-12"> + <div> + <div className="absolute bottom-6 md:bottom-3"> + <UserAvatar + user={{ username: user.username, image: user.image || null }} + className="h-20 md:h-40 w-20 md:w-40" + /> + </div> + </div> + <div> + {session?.id === user.id ? ( + <EditProfileModal user={user} /> + ) : ( + <FollowButton + userId={user.id} + username={user.username ? user.username : ""} + isFollowing={isFollowing} + /> + )} + </div> + </div> + </div> + + <div className="px-6 md:px-12 flex flex-col space-y-3 w-full"> + <div className="pb-3 whitespace-nowrap items-center"> + <h1 className="text-2xl font-bold">{user.name}</h1> + <h1 className="text-md text-sky-500">@{user.username}</h1> + </div> + {user.bio && <h1 className="break-words">{user.bio}</h1>} + + <div className="flex whitespace-nowrap items-center space-x-6 text-muted-foreground"> + {user.location && + <div className="flex items-center"> + <Icons.location className="mr-1" /> + <div>{user.location}</div> + </div> + } + {user.website && + <div className="flex items-center"> + <Icons.website className="mr-1" /> + <div>{user.website}</div> + </div> + } + {user.createdAt && <UserJoinDate date={user.createdAt} />} + </div> + + <div className="flex whitespace-nowrap items-center space-x-6"> + <Link href={`/${user.username}/following`}> + <span className="font-bold">{user._count?.following}</span> + <span className="text-muted-foreground"> Following</span> + </Link> + + <Link href={`/${user.username}/followers`}> + <span className="font-bold">{user._count?.followers}</span> + <span className="text-muted-foreground"> Followers</span> + </Link> + </div> + </div> + </ > + ) +} \ No newline at end of file diff --git a/components/profile/components/user-follows.tsx b/components/profile/components/user-follows.tsx new file mode 100644 index 0000000000000000000000000000000000000000..69daa9abe1f780dfc4199a878671abe3c2298ed3 --- /dev/null +++ b/components/profile/components/user-follows.tsx @@ -0,0 +1,80 @@ +"use client" + +import LoadingItem from "@/components/loading-item" +import { TryAgain } from "@/components/try-again" +import { User } from "next-auth" +import { usePathname } from "next/navigation" +import { useGetFollows } from "../hooks/use-get-follows" +import { UserItem } from "./user-item" + +export const UserFollows = ({ username, session }: { username: string, session: User | undefined }) => { + const pathValue = usePathname().split("/")[2] || "" + + const { + data: following, + isLoading, + isError, + } = useGetFollows({ + id: username, + type: pathValue, + }) + + if (isLoading) { + return ( + <LoadingItem /> + ) + } + + if (isError || !following) { + return ( + <TryAgain /> + ) + } + + if (following?.length === 0) { + if (session?.username === username) { + return ( + <div className="m-6 flex justify-center"> + <div className="font-bold"> + {pathValue === "following" ? + <> + <h1>You are not following anyone.</h1> + <p>When you do, it'll show up here.</p> + </> + : + <> + <h1>You have no followers.</h1> + <p>When you do, they'll show up here.</p> + </> + } + </div> + </div> + ) + } + return ( + <div className="m-6 flex justify-center"> + <div className="font-bold"> + {pathValue === "following" ? + <> + <h1><span className="text-sky-500">@{username}</span> is not following anyone yet.</h1> + <p>When they do, it'll show up here.</p> + </> + : + <> + <h1><span className="text-sky-500">@{username}</span> has no followers.</h1> + <p>When they do, they'll show up here.</p> + </> + } + </div> + </div> + ) + } + + return ( + <div className="space-y-5 flex flex-col"> + {following?.map((user) => { + return <UserItem key={user?.id} user={user} sessionId={session?.id} /> + })} + </div> + ) +} \ No newline at end of file diff --git a/components/profile/components/user-games.tsx b/components/profile/components/user-games.tsx new file mode 100644 index 0000000000000000000000000000000000000000..df8e8fe1467ec1c43ad8b3ed244e9e540927f4a8 --- /dev/null +++ b/components/profile/components/user-games.tsx @@ -0,0 +1,106 @@ +import GameItem from "@/components/game-item" +import { db } from "@/lib/db" +import { getFavoriteGames } from "@/lib/igdb" +import { getCurrentUser } from "@/lib/session" +import { IGame } from "@/types/igdb-types" +import { redirect } from "next/navigation" + +export const UserGames = async ({ username }: { username: string }) => { + const user = await getCurrentUser() + + const sessionUser = await db.user.findFirst({ + where: { + id: user?.id + }, + include: { + following: true, + followers: true + } + }) + + const fullUser = await db.user.findFirst({ + where: { + username: username + }, + include: { + following: true, + followers: true + } + }) + + if (!fullUser) { + redirect('/home') + } + + let favoritegames = undefined + let playingGames = undefined + let finishedGames = undefined + let planningGames = undefined + + if (fullUser?.favGameList?.length !== 0 && fullUser?.favGameList?.length != undefined) { + favoritegames = await getFavoriteGames(fullUser?.favGameList!) + } + if (fullUser?.playingGameList?.length !== 0) { + playingGames = await getFavoriteGames(fullUser?.playingGameList!) + } + if (fullUser?.finishedGameList?.length !== 0) { + finishedGames = await getFavoriteGames(fullUser?.finishedGameList!) + } + if (fullUser?.planningGameList?.length !== 0) { + planningGames = await getFavoriteGames(fullUser?.planningGameList!) + } + + return ( + <div className="p-3 space-y-12"> + <div> + <h1 className="text-2xl font-bold pb-3">Favorite Games</h1> + {favoritegames ? + <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> + {favoritegames.map((game: IGame) => ( + <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> + ))} + </div> + : + <span>No favorites currently...</span> + } + </div> + + <div> + <h1 className="text-2xl font-bold pb-3">Currently playing</h1> + {playingGames ? + <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> + {playingGames.map((game: IGame) => ( + <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> + ))} + </div> + : + <p>Currently not playing any games...</p> + } + </div> + + <div> + <h1 className="text-2xl font-bold pb-3">Planning to play</h1> + {planningGames ? + <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> + {planningGames.map((game: IGame) => ( + <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> + ))} + </div> + : + <p>Currently not planning to play any games...</p>} + </div> + + <div> + <h1 className="text-2xl font-bold pb-3">Finished Games</h1> + {finishedGames ? + <div className="grid grid-cols-1 ss:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-4 lg:gap-8 items-center"> + {finishedGames.map((game: IGame) => ( + <GameItem id={game.id} name={game.name} cover={game.cover} key={game.id} /> + ))} + </div> + : + <p>No finished games...</p>} + </div> + </div > + ) +} \ No newline at end of file diff --git a/components/profile/components/user-gweets.tsx b/components/profile/components/user-gweets.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6f53a744151d74c4f4b02673f97e9f91f44c0e6f --- /dev/null +++ b/components/profile/components/user-gweets.tsx @@ -0,0 +1,69 @@ +"use client" + +import { InfiniteGweets } from "@/components/gweets/components/infinite-gweets" +import { useGweets } from "@/components/gweets/hooks/use-gweets" +import LoadingItem from "@/components/loading-item" +import { TryAgain } from "@/components/try-again" +import { usePathname } from "next/navigation" + +export const UserGweets = ({ username, sessionname }: { username: string, sessionname: string }) => { + const pathValue = usePathname().split("/")[2] || "gweets" + + const { + data: gweets, + isLoading, + isError, + isSuccess, + isFetchingNextPage, + fetchNextPage, + hasNextPage, + } = useGweets({ + queryKey: ["gweets", username, pathValue], + type: "user_" + pathValue, + id: username, + }) + + if (isLoading) { + return ( + <LoadingItem /> + ) + } + + if (isError) { + return ( + <TryAgain /> + ) + } + + if (gweets?.pages[0].gweets.length === 0) { + if (sessionname === username) { + return ( + <div className="m-6 flex justify-center"> + <div className="font-bold"> + <h1>You haven't gweeted anything yet.</h1> + <p>When you do, it'll show up here.</p> + </div> + </div> + ) + } else { + return ( + <div className="m-6 flex justify-center"> + <div className="font-bold"> + <h1><span className="text-sky-500">@{username}</span> hasn't gweeted anything yet.</h1> + <p>When they do, it'll show up here.</p> + </div> + </div> + ) + } + } + + return ( + <InfiniteGweets + gweets={gweets} + hasNextPage={hasNextPage} + fetchNextPage={fetchNextPage} + isFetchingNextPage={isFetchingNextPage} + isSuccess={isSuccess} + /> + ) +} \ No newline at end of file diff --git a/components/profile/components/user-item.tsx b/components/profile/components/user-item.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f49ed9c80549ec1acd51c91a0660a375714616f1 --- /dev/null +++ b/components/profile/components/user-item.tsx @@ -0,0 +1,44 @@ +import { FollowButton } from "@/components/follow-button" +import { UserAvatar } from "@/components/user-avatar" +import Link from "next/link" +import { IUser } from "../types" +import { following } from "../utils/following" + +export const UserItem = async ({ user, sessionId, showBio = true }: { user: IUser, sessionId: string | undefined, showBio?: Boolean }) => { + const isFollowing = following({ + user, + sessionUserId: sessionId ? sessionId : "", + }) + + return ( + <Link + href={`/${user?.username}`} + className="flex flex-row flex-shrink gap-3 hover:bg-accent active:bg-accent rounded-lg p-3 items-center"> + + <UserAvatar + user={{ username: user.username, image: user.image || null }} + className="h-12 w-12 aspect-square" + /> + + <div className="flex flex-col flex-shrink justify-center h-full w-full space-y-3 overflow-hidden"> + <div className="flex justify-between"> + <div className="whitespace-nowrap"> + <h1 className="font-bold">{user.name}</h1> + <h1 className="text-sm text-sky-500">@{user.username}</h1> + </div> + + {/* TODO does not refresh button when following or unfolling */} + {/* {sessionId && sessionId !== user.id && + <FollowButton + userId={user.id} + username={user.username ? user.username : ""} + isFollowing={isFollowing} + /> + } */} + </div> + + {showBio && (user.bio ? (<p className="truncate w-full">{user.bio}</p>) : <p> </p>)} + </div> + </Link> + ) +} diff --git a/components/profile/components/user-join-date.tsx b/components/profile/components/user-join-date.tsx new file mode 100644 index 0000000000000000000000000000000000000000..16706d98df60d7c109652d6122f9b5f435c1dd50 --- /dev/null +++ b/components/profile/components/user-join-date.tsx @@ -0,0 +1,19 @@ +import { Icons } from "@/components/icons" +import dayjs from "dayjs" + +export const UserJoinDate = ({ + date, + showIcon = true, +}: { + date: Date | undefined + showIcon?: boolean +}) => { + return ( + <div className="flex items-center"> + {showIcon && (<Icons.calendar className="mr-1" />)} + <div> + Joined {dayjs(date).format("MMMM YYYY")} + </div> + </div> + ) +} \ No newline at end of file diff --git a/components/profile/hooks/use-follow.ts b/components/profile/hooks/use-follow.ts new file mode 100644 index 0000000000000000000000000000000000000000..447bfe9c7d2f53cf4d970e587750ef598e1d88a5 --- /dev/null +++ b/components/profile/hooks/use-follow.ts @@ -0,0 +1,35 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query" + +import { followUser } from "../api/follow-user" +import { unfollowUser } from "../api/unfollow-user" + +export const useFollow = (type: "follow" | "unfollow") => { + const queryClient = useQueryClient() + + return useMutation( + ({ + userId, + }: { + userId: string + }) => { + return type === "follow" + ? followUser(userId) + : unfollowUser(userId) + }, + + { + onSuccess: () => { + if (process.env.NODE_ENV === "development") console.log("success") + }, + + onError: (error) => { + if (process.env.NODE_ENV === "development") console.log(error) + }, + + onSettled: ({ userId }) => { + queryClient.invalidateQueries(["users", userId]) + queryClient.invalidateQueries(["tweets"]) + }, + }, + ) +} \ No newline at end of file diff --git a/components/profile/hooks/use-get-follows.ts b/components/profile/hooks/use-get-follows.ts new file mode 100644 index 0000000000000000000000000000000000000000..4fe0b3eb91b61c5565b1014d49e67ac3b6e7a0dd --- /dev/null +++ b/components/profile/hooks/use-get-follows.ts @@ -0,0 +1,22 @@ +import { useQuery } from "@tanstack/react-query" + +import { getFollows } from "../api/get-follows" +import { IUser } from "../types" + +export const useGetFollows = ({ + id, + type, +}: { + id: string | undefined + type: string | undefined +}) => { + return useQuery<IUser[]>( + ["users", id, type], + async () => { + return getFollows(id, type) + }, + { + refetchOnWindowFocus: false, + }, + ) +} \ No newline at end of file diff --git a/components/profile/hooks/use-update-profile.ts b/components/profile/hooks/use-update-profile.ts new file mode 100644 index 0000000000000000000000000000000000000000..df79ee6ea97692e17fd6cf537c48cd89a6c2a279 --- /dev/null +++ b/components/profile/hooks/use-update-profile.ts @@ -0,0 +1,34 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query" + +import { updateProfile } from "../api/update-profile" +import { IProfile } from "../types" + +export const useUpdateProfile = () => { + const queryClient = useQueryClient() + + return useMutation( + ({ + profile, + userId, + }: { + profile: IProfile + userId: string + }) => { + return updateProfile({ profile, userId }) + }, + + { + onSuccess: () => { + if (process.env.NODE_ENV === "development") console.log("success") + }, + + onError: (error) => { + if (process.env.NODE_ENV === "development") console.log(error) + }, + + onSettled: ({ userId }) => { + queryClient.invalidateQueries(["users", userId]) + }, + }, + ) +} \ No newline at end of file diff --git a/components/profile/hooks/use-user-likes.ts b/components/profile/hooks/use-user-likes.ts new file mode 100644 index 0000000000000000000000000000000000000000..e78735258031065988b70a002975cbed0129bb0b --- /dev/null +++ b/components/profile/hooks/use-user-likes.ts @@ -0,0 +1,17 @@ +import { useQuery } from "@tanstack/react-query" + +import { ILike } from "@/components/gweets/types" + +import { getUserLikes } from "../api/get-user-likes" + +export const useUserLikes = (id: string | undefined) => { + return useQuery<ILike[]>( + ["likes", { userId: id }], + async () => { + return getUserLikes(id) + }, + { + refetchOnWindowFocus: false, + }, + ) +} \ No newline at end of file diff --git a/components/profile/hooks/use-user.ts b/components/profile/hooks/use-user.ts new file mode 100644 index 0000000000000000000000000000000000000000..79760e1f4496e2accedc93a6bc5f5761a333b912 --- /dev/null +++ b/components/profile/hooks/use-user.ts @@ -0,0 +1,20 @@ +import { useQuery, useQueryClient } from "@tanstack/react-query" + +import { getUser } from "../api/get-user" +import { IUser } from "../types" + +export const useUser = (username: string | undefined) => { + const queryClient = useQueryClient() + return useQuery<IUser>( + ["users", username], + async () => { + return getUser(username) + }, + { + refetchOnWindowFocus: false, + onSuccess: (data) => { + queryClient.setQueryData(["users", username], data) + }, + }, + ) +} \ No newline at end of file diff --git a/components/profile/hooks/use-users.ts b/components/profile/hooks/use-users.ts new file mode 100644 index 0000000000000000000000000000000000000000..e2e70b6ab95fb0c541991e32d6b6dc07cfb6909e --- /dev/null +++ b/components/profile/hooks/use-users.ts @@ -0,0 +1,23 @@ +import { useQuery, useQueryClient } from "@tanstack/react-query" +import { useSession } from "next-auth/react" + +import { getUsers } from "../api/get-users" +import { IUser } from "../types" + +export const useUsers = () => { + const { data: session } = useSession() + + const queryClient = useQueryClient() + return useQuery<IUser[]>( + ["users"], + async () => { + return getUsers(session?.user?.id) + }, + { + refetchOnWindowFocus: false, + onSuccess: (data) => { + queryClient.setQueryData(["users"], data) + }, + }, + ) +} \ No newline at end of file diff --git a/components/profile/types/index.ts b/components/profile/types/index.ts index fb812e3c3c2b0522d6bbf2f1ac5fe6c7f425e971..ae11567b9c5fd4034c6ed8ffa6f9672b5157e7e9 100644 --- a/components/profile/types/index.ts +++ b/components/profile/types/index.ts @@ -1,11 +1,11 @@ -import { Follows, Like, User } from "@prisma/client" +import { Like, User } from "@prisma/client" import { IGweet } from "@/components/gweets/types" export interface IUser extends User { gweets: IGweet[] - followers: IFollow[] - following: IFollow[] + followers: User[] + following: User[] likes: ILike[] _count?: { followers?: number @@ -16,19 +16,19 @@ export interface IUser extends User { export interface IProfile { name: string bio: string | undefined + location: string | undefined + website: string | undefined banner: { + removed: boolean | undefined url: string | undefined + file: File | undefined } - avatar: { + image: { url: string | undefined + file: File | undefined } } -export interface IFollow extends Follows { - follower: IUser - following: IUser -} - export interface ILike extends Like { user: IUser gweet: IGweet diff --git a/components/profile/utils/following.ts b/components/profile/utils/following.ts new file mode 100644 index 0000000000000000000000000000000000000000..4c6c83ca24a661d916e2f9ee6fa697a4a4de4867 --- /dev/null +++ b/components/profile/utils/following.ts @@ -0,0 +1,11 @@ +import { IUser } from "../types" + +export const following = ({ + user, + sessionUserId, +}: { + user: IUser + sessionUserId: string +}): boolean => { + return user?.followers?.some((follower) => follower.id === sessionUserId) +} \ No newline at end of file diff --git a/components/trends/api/get-hashtags.ts b/components/trends/api/get-hashtags.ts index d70c90a99b03115ffcf346eae8adf0ccfcf63867..493f8f5659a52beb0e3831e86564b6040f02a46d 100644 --- a/components/trends/api/get-hashtags.ts +++ b/components/trends/api/get-hashtags.ts @@ -1,7 +1,11 @@ export const getHashtags = async () => { try { - const data = await fetch(`/api/hashtags`).then((result) => result.json()) - return data + const data = await fetch(`/api/hashtags`) + if (!data.ok) { + throw new Error('Network response was not ok') + } + + return data.json() } catch (error: any) { return error.response.data } diff --git a/components/trends/components/trend.tsx b/components/trends/components/trend.tsx index 2ce19c9b8c18a64ec4a0bc9d7c194a5f1e8b7f2c..a13ae5718754d1ba58e43d2e42ae4d1b4900ca3a 100644 --- a/components/trends/components/trend.tsx +++ b/components/trends/components/trend.tsx @@ -7,12 +7,12 @@ export const Trend = ({ ranking = 1, title, gweets = 1 }: iTrendProps) => { return ( <Link href={`/search?query=${title.toLowerCase()}`} - className="flex flex-col justify-between hover:bg-accent active:bg-accent rounded-lg p-1"> + className="flex flex-col justify-between hover:bg-accent active:bg-accent rounded-lg p-1 overflow-hidden"> <div className="text-xs text-muted-foreground"> {ranking} · Trending </div> - <div>#{title}</div> + <div className="truncate">#{title}</div> <div className="text-xs text-muted-foreground"> {gweets} {gweets === 1 ? "gweet" : "gweets"} </div> diff --git a/components/trends/components/trends.tsx b/components/trends/components/trends.tsx index 2d1eb6d2fa78da22239916ba36f01593b90954b2..27fd41cd44729207658098104bba1dcb492708a0 100644 --- a/components/trends/components/trends.tsx +++ b/components/trends/components/trends.tsx @@ -10,8 +10,6 @@ import { Trend } from "./trend" export const Trends = ({ title = "Trends" }: { title?: string }) => { const { data: hashtags, isLoading, isError, isSuccess } = useHashtags() - if (hashtags && hashtags?.length <= 0) return null - return ( <div className="space-y-5 flex flex-col"> {title && <h1 className="font-bold p-1">{title}</h1>} @@ -19,8 +17,12 @@ export const Trends = ({ title = "Trends" }: { title?: string }) => { <LoadingItem /> ) : isError ? ( <TryAgain /> + ) : hashtags?.length <= 0 ? ( + <Card className="p-1"> + <h1 className="text-center">No trends yet</h1> + </Card> ) : isSuccess && - hashtags?.map((hashtag, index) => { + hashtags?.slice(title ? 0 : undefined, title ? 3 : undefined).map((hashtag, index) => { return ( <Trend key={hashtag.id} diff --git a/components/try-again.tsx b/components/try-again.tsx index 218a1b6f0e6358c277cda3ad5e79b6af29f64aad..13ef547000805e2f4d1f255807df177b3901423f 100644 --- a/components/try-again.tsx +++ b/components/try-again.tsx @@ -1,14 +1,14 @@ import { useRouter } from "next/navigation" +import { Button } from "./ui/button" export const TryAgain = () => { const router = useRouter() return ( - <div className="flex flex-col items-center gap-1.2 p-4"> - <h2 className="text-tertiary text-center">Something went wrong. Try reloading.</h2> - <button onClick={() => router.refresh} className="px-4 py-2 rounded-full bg-primary text-light font-medium flex items-center gap-1"> - <span>Retry</span> - </button> + <div className="flex flex-col items-center p-6 space-y-3"> + <h1 className="text-tertiary text-center">Huh. Couldn't find what you were looking for.</h1> + <h1 className="text-tertiary text-center pb-3">Let's go back to the homepage.</h1> + <Button size="lg" onClick={() => router.push("/home")}>Home</Button> </div> ) } \ No newline at end of file diff --git a/components/user-auth-form.tsx b/components/user-auth-form.tsx index b5cf80b338217ee9fecabcb9aedfaac599331198..48b9ea258ec082ad7e7c233112ecd99aad3e6020 100644 --- a/components/user-auth-form.tsx +++ b/components/user-auth-form.tsx @@ -58,6 +58,8 @@ export function UserAuthForm({ type, className, ...props }: UserAuthFormProps) { if (!res.ok) { if (res.status === 422) { setError('email', { type: 'manual', message: 'This email is already in use. Please choose another one.' }) + setIsLoading(false) + return } setIsLoading(false) diff --git a/components/user-not-found.tsx b/components/user-not-found.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f08a2ba9871320952c6853da4309ac6caeecd734 --- /dev/null +++ b/components/user-not-found.tsx @@ -0,0 +1,8 @@ +export const UserNotFound = () => { + return ( + <div className=""> + <h1>This account does not exist.</h1> + <p>Try searching for another.</p> + </div> + ) +} \ No newline at end of file diff --git a/jest.config.mjs b/jest.config.mjs index 7079cf9e9cbc60a00b78c174d0027a0baabf3246..4e300ffbfb6e86a75fc2793b565deca61097e895 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -1,4 +1,4 @@ -import nextJest from 'next/jest.js'; +import nextJest from 'next/jest.js' // Provide the path to your Next.js app to load next.config.js and .env files in your test environment const createJestConfig = nextJest({ dir: './' }) @@ -9,14 +9,14 @@ const clientTestConfig = { testPathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/__tests__/api/"], setupFilesAfterEnv: ["<rootDir>/jest.setup.js"], testEnvironment: "jest-environment-jsdom", -}; +} // Custom server config to be passed to Jest. const serverTestConfig = { displayName: "server", testMatch: ["**/__tests__/api/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"], testEnvironment: "jest-environment-node", -}; +} // Add any custom config to be passed to Jest /** @type {import('jest').Config} */ @@ -26,8 +26,8 @@ const config = { collectCoverageFrom: [ '**/app/api/**', '!**/node_modules/**', - '!**/vendor/**', - ] -}; + '!**/.*/**', + ], +} -export default config; \ No newline at end of file +export default config \ No newline at end of file diff --git a/lib/swagger.ts b/lib/swagger.ts new file mode 100644 index 0000000000000000000000000000000000000000..c26db79c660253f660b8df110e3c6a4ef57a539d --- /dev/null +++ b/lib/swagger.ts @@ -0,0 +1,25 @@ +import { createSwaggerSpec } from 'next-swagger-doc' + +export const getApiDocs = async () => { + const spec = createSwaggerSpec({ + apiFolder: 'app/api', // define api folder under app folder + definition: { + openapi: '3.0.0', + info: { + title: 'GameUnity Api Documentation', + version: '1.0', + }, + components: { + securitySchemes: { + BearerAuth: { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + }, + }, + }, + security: [], + }, + }) + return spec +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6088c092f82171bc0bb897feba006a1e3597de39..187e62fc629b8d868f8476227cc87c26870253b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "project_ss23_gameunity", "version": "0.2.0", + "hasInstallScript": true, "dependencies": { "@auth/prisma-adapter": "^1.0.0", "@hookform/resolvers": "^3.1.1", @@ -31,9 +32,10 @@ "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", "dayjs": "^1.11.9", - "lucide-react": "^0.258.0", - "next": "^13.4.8", + "lucide-react": "^0.259.0", + "next": "^13.4.9", "next-auth": "^4.22.1", + "next-swagger-doc": "^0.4.0", "next-themes": "^0.2.1", "nodemailer": "^6.9.3", "normalize-diacritics": "^4.0.0", @@ -43,6 +45,7 @@ "react-hook-form": "^7.45.1", "react-infinite-scroll-component": "^6.1.0", "react-intersection-observer": "^9.5.2", + "swagger-ui-react": "^5.1.0", "tailwind-merge": "^1.13.2", "tailwindcss-animate": "^1.0.6", "uploadthing": "^5.1.0", @@ -54,16 +57,17 @@ "@testing-library/react": "^14.0.0", "@types/bcrypt": "^5.0.0", "@types/jest": "^29.5.2", - "@types/node": "^20.3.3", + "@types/node": "^20.4.0", "@types/nodemailer": "^6.4.8", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", + "@types/swagger-ui-react": "^4.18.0", "autoprefixer": "10.4.14", "eslint": "^8.44.0", - "eslint-config-next": "^13.4.8", - "jest": "^29.6.0", - "jest-environment-jsdom": "^29.6.0", - "postcss": "8.4.24", + "eslint-config-next": "^13.4.9", + "jest": "^29.6.1", + "jest-environment-jsdom": "^29.6.1", + "postcss": "8.4.25", "prisma": "^4.16.2", "tailwindcss": "3.3.2", "typescript": "^5.1.6" @@ -108,6 +112,46 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, "node_modules/@auth/core": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.8.1.tgz", @@ -162,20 +206,20 @@ } }, "node_modules/@babel/core": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.6.tgz", - "integrity": "sha512-HPIyDa6n+HKw5dEuway3vVAhBboYCtREBMp+IWeseZy6TFtzn6MHkCH2KKYUOC/vKKwgSMHQW4htBOrmuRPXfw==", + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz", + "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", + "@babel/generator": "^7.22.7", "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-module-transforms": "^7.22.5", "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.6", + "@babel/parser": "^7.22.7", "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", + "@babel/traverse": "^7.22.8", "@babel/types": "^7.22.5", "@nicolo-ribaudo/semver-v6": "^6.3.3", "convert-source-map": "^1.7.0", @@ -198,9 +242,9 @@ "dev": true }, "node_modules/@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", + "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", "dev": true, "dependencies": { "@babel/types": "^7.22.5", @@ -456,9 +500,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", - "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -655,6 +699,18 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.22.6.tgz", + "integrity": "sha512-M+37LLIRBTEVjktoJjbw4KVhupF0U/3PYUCbBwgAd9k17hoKhRu1n935QiG7Tuxv0LJOMrb2vuKEeYUlv0iyiw==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", @@ -670,18 +726,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", - "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", + "version": "7.22.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", + "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", + "@babel/generator": "^7.22.7", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.6", + "@babel/parser": "^7.22.7", "@babel/types": "^7.22.5", "debug": "^4.1.0", "globals": "^11.1.0" @@ -719,6 +775,11 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz", + "integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -950,16 +1011,16 @@ } }, "node_modules/@jest/console": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.0.tgz", - "integrity": "sha512-anb6L1yg7uPQpytNVA5skRaXy3BmrsU8icRhTVNbWdjYWDDfy8M1Kq5HIVRpYoABdbpqsc5Dr+jtu4+qWRQBiQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.1.tgz", + "integrity": "sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.6.0", - "jest-util": "^29.6.0", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", "slash": "^3.0.0" }, "engines": { @@ -983,16 +1044,16 @@ } }, "node_modules/@jest/core": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.0.tgz", - "integrity": "sha512-5dbMHfY/5R9m8NbgmB3JlxQqooZ/ooPSOiwEQZZ+HODwJTbIu37seVcZNBK29aMdXtjvTRB3f6LCvkKq+r8uQA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.1.tgz", + "integrity": "sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==", "dev": true, "dependencies": { - "@jest/console": "^29.6.0", - "@jest/reporters": "^29.6.0", - "@jest/test-result": "^29.6.0", - "@jest/transform": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/console": "^29.6.1", + "@jest/reporters": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", @@ -1000,20 +1061,20 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-changed-files": "^29.5.0", - "jest-config": "^29.6.0", - "jest-haste-map": "^29.6.0", - "jest-message-util": "^29.6.0", + "jest-config": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.6.0", - "jest-resolve-dependencies": "^29.6.0", - "jest-runner": "^29.6.0", - "jest-runtime": "^29.6.0", - "jest-snapshot": "^29.6.0", - "jest-util": "^29.6.0", - "jest-validate": "^29.6.0", - "jest-watcher": "^29.6.0", + "jest-resolve": "^29.6.1", + "jest-resolve-dependencies": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "jest-watcher": "^29.6.1", "micromatch": "^4.0.4", - "pretty-format": "^29.6.0", + "pretty-format": "^29.6.1", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -1046,9 +1107,9 @@ } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -1078,37 +1139,37 @@ "dev": true }, "node_modules/@jest/environment": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.0.tgz", - "integrity": "sha512-bUZLYUxYlUIsslBbxII0fq0kr1+friI3Gty+cRLmocGB1jdcAHs7FS8QdCDqedE8q4DZE1g/AJHH6OJZBLGGsg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.1.tgz", + "integrity": "sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", - "jest-mock": "^29.6.0" + "jest-mock": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.0.tgz", - "integrity": "sha512-a7pISPW28Q3c0/pLwz4mQ6tbAI+hc8/0CJp9ix6e9U4dQ6TiHQX82CT5DV5BMWaw8bFH4E6zsfZxXdn6Ka23Bw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==", "dev": true, "dependencies": { - "expect": "^29.6.0", - "jest-snapshot": "^29.6.0" + "expect": "^29.6.1", + "jest-snapshot": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.0.tgz", - "integrity": "sha512-LLSQQN7oypMSETKoPWpsWYVKJd9LQWmSDDAc4hUQ4JocVC7LAMy9R3ZMhlnLwbcFvQORZnZR7HM893Px6cJhvA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", + "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", "dev": true, "dependencies": { "jest-get-type": "^29.4.3" @@ -1118,48 +1179,48 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.0.tgz", - "integrity": "sha512-nuCU46AsZoskthWSDS2Aj6LARgyNcp5Fjx2qxsO/fPl1Wp1CJ+dBDqs0OkEcJK8FBeV/MbjH5efe79M2sHcV+A==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.1.tgz", + "integrity": "sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.6.0", - "jest-mock": "^29.6.0", - "jest-util": "^29.6.0" + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.0.tgz", - "integrity": "sha512-IQQ3hZ2D/hwEwXSMv5GbfhzdH0nTQR3KPYxnuW6gYWbd6+7/zgMz7Okn6EgBbNtJNONq03k5EKA6HqGyzRbpeg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.1.tgz", + "integrity": "sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.0", - "@jest/expect": "^29.6.0", - "@jest/types": "^29.6.0", - "jest-mock": "^29.6.0" + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/types": "^29.6.1", + "jest-mock": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.0.tgz", - "integrity": "sha512-dWEq4HI0VvHcAD6XTtyBKKARLytyyWPIy1SvGOcU91106MfvHPdxZgupFwVHd8TFpZPpA3SebYjtwS5BUS76Rw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.1.tgz", + "integrity": "sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.6.0", - "@jest/test-result": "^29.6.0", - "@jest/transform": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/console": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", @@ -1172,9 +1233,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.6.0", - "jest-util": "^29.6.0", - "jest-worker": "^29.6.0", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1235,13 +1296,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.0.tgz", - "integrity": "sha512-9qLb7xITeyWhM4yatn2muqfomuoCTOhv0QV9i7XiIyYi3QLfnvPv5NeJp5u0PZeutAOROMLKakOkmoAisOr3YQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.1.tgz", + "integrity": "sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==", "dev": true, "dependencies": { - "@jest/console": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/console": "^29.6.1", + "@jest/types": "^29.6.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1250,14 +1311,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.0.tgz", - "integrity": "sha512-HYCS3LKRQotKWj2mnA3AN13PPevYZu8MJKm12lzYojpJNnn6kI/3PWmr1At/e3tUu+FHQDiOyaDVuR4EV3ezBw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz", + "integrity": "sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==", "dev": true, "dependencies": { - "@jest/test-result": "^29.6.0", + "@jest/test-result": "^29.6.1", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.0", + "jest-haste-map": "^29.6.1", "slash": "^3.0.0" }, "engines": { @@ -1265,22 +1326,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.0.tgz", - "integrity": "sha512-bhP/KxPo3e322FJ0nKAcb6WVK76ZYyQd1lWygJzoSqP8SYMSLdxHqP4wnPTI4WvbB8PKPDV30y5y7Tya4RHOBA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.1.tgz", + "integrity": "sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.0", + "jest-haste-map": "^29.6.1", "jest-regex-util": "^29.4.3", - "jest-util": "^29.6.0", + "jest-util": "^29.6.1", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1307,9 +1368,9 @@ } }, "node_modules/@jest/types": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.0.tgz", - "integrity": "sha512-8XCgL9JhqbJTFnMRjEAO+TuW251+MoMd5BSzLiE3vvzpQ8RlBxy8NoyNkDhs3K3OL3HeVinlOl9or5p7GTeOLg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -1387,6 +1448,11 @@ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", @@ -1407,23 +1473,23 @@ } }, "node_modules/@next/env": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.8.tgz", - "integrity": "sha512-twuSf1klb3k9wXI7IZhbZGtFCWvGD4wXTY2rmvzIgVhXhs7ISThrbNyutBx3jWIL8Y/Hk9+woytFz5QsgtcRKQ==" + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.9.tgz", + "integrity": "sha512-vuDRK05BOKfmoBYLNi2cujG2jrYbEod/ubSSyqgmEx9n/W3eZaJQdRNhTfumO+qmq/QTzLurW487n/PM/fHOkw==" }, "node_modules/@next/eslint-plugin-next": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.8.tgz", - "integrity": "sha512-cmfVHpxWjjcETFt2WHnoFU6EmY69QcPJRlRNAooQlNe53Ke90vg1Ci/dkPffryJZaxxiRziP9bQrV8lDVCn3Fw==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.9.tgz", + "integrity": "sha512-nDtGpa992tNyAkT/KmSMy7QkHfNZmGCBYhHtafU97DubqxzNdvLsqRtliQ4FU04CysRCtvP2hg8rRC1sAKUTUA==", "dev": true, "dependencies": { "glob": "7.1.7" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.8.tgz", - "integrity": "sha512-MSFplVM4dTWOuKAUv0XR9gY7AWtMSBu9os9f+kp+s5rWhM1I2CdR3obFttd6366nS/W/VZxbPM5oEIdlIa46zA==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.9.tgz", + "integrity": "sha512-TVzGHpZoVBk3iDsTOQA/R6MGmFp0+17SWXMEWd6zG30AfuELmSSMe2SdPqxwXU0gbpWkJL1KgfLzy5ReN0crqQ==", "cpu": [ "arm64" ], @@ -1436,9 +1502,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.8.tgz", - "integrity": "sha512-Reox+UXgonon9P0WNDE6w85DGtyBqGitl/ryznOvn6TvfxEaZIpTgeu3ZrJLU9dHSMhiK7YAM793mE/Zii2/Qw==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.9.tgz", + "integrity": "sha512-aSfF1fhv28N2e7vrDZ6zOQ+IIthocfaxuMWGReB5GDriF0caTqtHttAvzOMgJgXQtQx6XhyaJMozLTSEXeNN+A==", "cpu": [ "x64" ], @@ -1451,9 +1517,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.8.tgz", - "integrity": "sha512-kdyzYvAYtqQVgzIKNN7e1rLU8aZv86FDSRqPlOkKZlvqudvTO0iohuTPmnEEDlECeBM6qRPShNffotDcU/R2KA==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.9.tgz", + "integrity": "sha512-JhKoX5ECzYoTVyIy/7KykeO4Z2lVKq7HGQqvAH+Ip9UFn1MOJkOnkPRB7v4nmzqAoY+Je05Aj5wNABR1N18DMg==", "cpu": [ "arm64" ], @@ -1466,9 +1532,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.8.tgz", - "integrity": "sha512-oWxx4yRkUGcR81XwbI+T0zhZ3bDF6V1aVLpG+C7hSG50ULpV8gC39UxVO22/bv93ZlcfMY4zl8xkz9Klct6dpQ==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.9.tgz", + "integrity": "sha512-OOn6zZBIVkm/4j5gkPdGn4yqQt+gmXaLaSjRSO434WplV8vo2YaBNbSHaTM9wJpZTHVDYyjzuIYVEzy9/5RVZw==", "cpu": [ "arm64" ], @@ -1481,9 +1547,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.8.tgz", - "integrity": "sha512-anhtvuO6eE9YRhYnaEGTfbpH3L5gT/9qPFcNoi6xS432r/4DAtpJY8kNktqkTVevVIC/pVumqO8tV59PR3zbNg==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.9.tgz", + "integrity": "sha512-iA+fJXFPpW0SwGmx/pivVU+2t4zQHNOOAr5T378PfxPHY6JtjV6/0s1vlAJUdIHeVpX98CLp9k5VuKgxiRHUpg==", "cpu": [ "x64" ], @@ -1496,9 +1562,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.8.tgz", - "integrity": "sha512-aR+J4wWfNgH1DwCCBNjan7Iumx0lLtn+2/rEYuhIrYLY4vnxqSVGz9u3fXcgUwo6Q9LT8NFkaqK1vPprdq+BXg==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.9.tgz", + "integrity": "sha512-rlNf2WUtMM+GAQrZ9gMNdSapkVi3koSW3a+dmBVp42lfugWVvnyzca/xJlN48/7AGx8qu62WyO0ya1ikgOxh6A==", "cpu": [ "x64" ], @@ -1511,9 +1577,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.8.tgz", - "integrity": "sha512-OWBKIrJwQBTqrat0xhxEB/jcsjJR3+diD9nc/Y8F1mRdQzsn4bPsomgJyuqPVZs6Lz3K18qdIkvywmfSq75SsQ==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.9.tgz", + "integrity": "sha512-5T9ybSugXP77nw03vlgKZxD99AFTHaX8eT1ayKYYnGO9nmYhJjRPxcjU5FyYI+TdkQgEpIcH7p/guPLPR0EbKA==", "cpu": [ "arm64" ], @@ -1526,9 +1592,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.8.tgz", - "integrity": "sha512-agiPWGjUndXGTOn4ChbKipQXRA6/UPkywAWIkx7BhgGv48TiJfHTK6MGfBoL9tS6B4mtW39++uy0wFPnfD0JWg==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.9.tgz", + "integrity": "sha512-ojZTCt1lP2ucgpoiFgrFj07uq4CZsq4crVXpLGgQfoFq00jPKRPgesuGPaz8lg1yLfvafkU3Jd1i8snKwYR3LA==", "cpu": [ "ia32" ], @@ -1541,9 +1607,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.8.tgz", - "integrity": "sha512-UIRKoByVKbuR6SnFG4JM8EMFlJrfEGuUQ1ihxzEleWcNwRMMiVaCj1KyqfTOW8VTQhJ0u8P1Ngg6q1RwnIBTtw==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.9.tgz", + "integrity": "sha512-QbT03FXRNdpuL+e9pLnu+XajZdm/TtIXVYY4lA9t+9l0fLZbHXDYEKitAqxrOj37o3Vx5ufxiRAniaIebYDCgw==", "cpu": [ "x64" ], @@ -2591,6 +2657,359 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@swagger-api/apidom-ast": { + "version": "0.70.0", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-0.70.0.tgz", + "integrity": "sha512-zQ1RUkXjx5NPYv1bmkoXwlQi7oJC7DJqYi0syTQKswJZDbOkHCwz8cDP/YystOEOL+yyIN7i5EQBIHfy5yAMmA==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2", + "unraw": "^2.0.1" + } + }, + "node_modules/@swagger-api/apidom-core": { + "version": "0.70.1", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-0.70.1.tgz", + "integrity": "sha512-doE6escw5LYVxIp5/lfdeNC8jF39JohKeYQ/YuH5wbo5T06uy8nZ3VxcjPHymmQmLlHdEegUIiirp7dSZFZlIg==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^0.70.0", + "@types/ramda": "~0.29.1", + "minim": "~0.23.8", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "short-unique-id": "^4.4.4", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-json-pointer": { + "version": "0.70.1", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-0.70.1.tgz", + "integrity": "sha512-9NyeflCD0Vy8rce3Eag/Xdu2SGF4nr/mnQ6/vb4VbV9pID12z6EbBWvF9p9l0/sRdA6IePj39B3uBLcPl5b4Dg==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-ns-api-design-systems": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-0.70.3.tgz", + "integrity": "sha512-61qffrU0AX/7DxaQ6eFz+gSChlI/6dRU8YaBi4N38ZrwaMkRm/ksy8VWUoMcs2qHrqWh8vBijnpKBXi9JHNGKA==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-ns-asyncapi-2": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-0.70.3.tgz", + "integrity": "sha512-Z2xhws7MfclZ2IzFjsfohpRueTZBde6x0GGtWC3dmgq506IhYpA+cpGYUpGHgwzdwLJOzLdwXnafuuXIoVkvJw==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-json-schema-draft-7": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-0.70.3.tgz", + "integrity": "sha512-y/WJTQCzm59p8wVPb034AcydzgXNEOVdh+S/OGuHJ+HYUFmVT5NWvBGWC7Ikc9ixXN0v585dzq1QvE2T7H0ZfQ==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^0.70.0", + "@swagger-api/apidom-core": "^0.70.1", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-0.70.3.tgz", + "integrity": "sha512-6u6fB9LIM3z+K9miAAWsOT13LOCQc5G0d/lkRSpVSendvgAWpOCEx1BSgiIoURwkcBl2FB46vYyXefolxTOK7w==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-json-schema-draft-4": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-0.70.3.tgz", + "integrity": "sha512-fVTxhfuHieXyEL4BwoQidXNGAkXjO9N8QekfUpdYDKLxs7Sq80itPZxlq/fbagomS+Q1n5LYfB5h2n5lLOGJDQ==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-json-schema-draft-6": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-0": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-0.70.3.tgz", + "integrity": "sha512-ci5GNSf1cA/Xc2/1Kjlo2u78McevOYsH6+weEPW4JlHa3hMJyi6dlw16yHBRl7lzdxiO0D64+r0JVX0bOBhqyw==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-json-schema-draft-4": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-ns-openapi-3-1": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-0.70.3.tgz", + "integrity": "sha512-/AwVei3FJeC4wAnmNMywyK8zjKiP8CzuuA58G9xqWk2asOH2qjppYjaFAE6BeJ7of7juR5+BvdQg1wXYz8sutA==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^0.70.0", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { + "version": "0.70.4", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-0.70.4.tgz", + "integrity": "sha512-xo7mr8/UgVpqe1AMUbNPRnXM3CDgvIXktz7y1abAbRjJ/qhBWsRHBeqf8KQBJjKfJc58i+yMnDXC8hapZplHeA==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-api-design-systems": "^0.70.3", + "@swagger-api/apidom-parser-adapter-json": "^0.70.4", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-0.70.3.tgz", + "integrity": "sha512-DJJjwv3KuL5hnMfQgpD7S2tbwxalyTsjkaFF6uxcIMJRr9hdKKNDkvJkel/r56FE2pp9WCBhP6Wm1JK6PGI3Pg==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-api-design-systems": "^0.70.3", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { + "version": "0.70.4", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-0.70.4.tgz", + "integrity": "sha512-eaqQ/93xxVFM+138AL2z5jODyXJlpf5RNRXrE/HaG3PWLB+a7CN9eCy+czP1E6VgC0Wia1kuYf/Bx9aIgNQ6sQ==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-asyncapi-2": "^0.70.3", + "@swagger-api/apidom-parser-adapter-json": "^0.70.4", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-0.70.3.tgz", + "integrity": "sha512-UQxxPoxWcgp9laW8kOdzd7991/wgYJ2b7lb3XBhmVydRbPM1AD5L3G/zM5ItVBQZIZ398kDX/mfGTKAJr5pJrA==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-asyncapi-2": "^0.70.3", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-json": { + "version": "0.70.4", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-0.70.4.tgz", + "integrity": "sha512-Clr4VHocpdDi/bQ4ZSuhN3Ak3g8oLjKtCqjQO34YDrFrKPD2twznALBdVjIHa9D+g5YJYkAQ+5wOrK5uvo/5lQ==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^0.70.0", + "@swagger-api/apidom-core": "^0.70.1", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2", + "tree-sitter": "=0.20.4", + "tree-sitter-json": "=0.20.0", + "web-tree-sitter": "=0.20.3" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { + "version": "0.70.4", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-0.70.4.tgz", + "integrity": "sha512-VfSR/TkB7rN5qAm6nGBrJzGuwhvFH03wojPVtjQEUUlDfmiFK0Snhdzq/65qK8WxSYidIBVgWHEreYif28AhBQ==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", + "@swagger-api/apidom-parser-adapter-json": "^0.70.4", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { + "version": "0.70.4", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-0.70.4.tgz", + "integrity": "sha512-XB5owOAI7YtRi7lD1R5vI3zFn7EbjKn/FkSMjC0m4CfienX9f9EkromSWE5i5dQGpCfkpHp/iOJ00xODly1nUQ==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.70.3", + "@swagger-api/apidom-parser-adapter-json": "^0.70.4", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-0.70.3.tgz", + "integrity": "sha512-4vkN+jy4HKYQJc0M7sVD4pqT5n2a7nIwswtHujdMVR2YXXY8RTzBg4DO28qVUoAWUsE0C8Tp+hopDPeCtpYduA==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-0.70.3.tgz", + "integrity": "sha512-4xoyOYrG3YBdr/mjNLzDAIdOxFSYR0gh3lRx3/IVkwmhp0rSVrGdD2hFtgoVrj2MiKR60SUbzcnCXJ4MLVmUbQ==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@swagger-api/apidom-ns-openapi-3-1": "^0.70.3", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.70.3", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0" + } + }, + "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { + "version": "0.70.3", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-0.70.3.tgz", + "integrity": "sha512-e+lGfUfduduIT+nyJtxDFXLqoulvz2sWB9vt+4gmq/SMc0uvFBEcffAeBUOPw4J3d4pMux2eRRzA29YF7/lXng==", + "optional": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-ast": "^0.70.0", + "@swagger-api/apidom-core": "^0.70.1", + "@types/ramda": "~0.29.1", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2", + "tree-sitter": "=0.20.4", + "tree-sitter-yaml": "=0.5.0", + "web-tree-sitter": "=0.20.3" + } + }, + "node_modules/@swagger-api/apidom-reference": { + "version": "0.70.4", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-0.70.4.tgz", + "integrity": "sha512-+jrDtbJc7zVqHumyDu1rGXZD3BwrD8qu+FaC7+9iZThU2GAEOs4VvTcCkPQLfVtpIrv1fPvNkzean27MJZxpkw==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.7", + "@swagger-api/apidom-core": "^0.70.1", + "@types/ramda": "~0.29.1", + "axios": "^1.4.0", + "minimatch": "^7.4.3", + "process": "^0.11.10", + "ramda": "~0.29.0", + "ramda-adjunct": "^4.0.0", + "stampit": "^4.3.2" + }, + "optionalDependencies": { + "@swagger-api/apidom-json-pointer": "^0.70.1", + "@swagger-api/apidom-ns-asyncapi-2": "^0.70.3", + "@swagger-api/apidom-ns-openapi-3-0": "^0.70.3", + "@swagger-api/apidom-ns-openapi-3-1": "^0.70.3", + "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^0.70.4", + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^0.70.3", + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^0.70.4", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^0.70.3", + "@swagger-api/apidom-parser-adapter-json": "^0.70.4", + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^0.70.4", + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^0.70.4", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^0.70.3", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^0.70.3", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^0.70.3" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@swc/helpers": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", @@ -2823,6 +3242,23 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -2900,6 +3336,11 @@ "parse5": "^7.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2907,9 +3348,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.3.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", - "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==", + "version": "20.4.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.0.tgz", + "integrity": "sha512-jfT7iTf/4kOQ9S7CHV9BIyRaQqHu67mOjsIQBC3BKZvzvUB6zLxEwJ6sBE3ozcvP8kF6Uk5PXN0Q+c0dfhGX0g==", "dev": true }, "node_modules/@types/nodemailer": { @@ -2930,14 +3371,20 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "devOptional": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/ramda": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.3.tgz", + "integrity": "sha512-Yh/RHkjN0ru6LVhSQtTkCRo6HXkfL9trot/2elzM/yXLJmbLm2v6kJc8yftTnwv1zvUob6TEtqI2cYjdqG3U0Q==", + "dependencies": { + "types-ramda": "^0.29.4" + } }, "node_modules/@types/react": { "version": "18.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz", "integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==", - "devOptional": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -2956,8 +3403,7 @@ "node_modules/@types/scheduler": { "version": "0.16.3", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", - "devOptional": true + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, "node_modules/@types/stack-utils": { "version": "2.0.1", @@ -2965,6 +3411,20 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/swagger-jsdoc": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.1.tgz", + "integrity": "sha512-+MUpcbyxD528dECUBCEVm6abNuORdbuGjbrUdHDeAQ+rkPuo2a+L4N02WJHF3bonSSE6SJ3dUJwF2V6+cHnf0w==" + }, + "node_modules/@types/swagger-ui-react": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.0.tgz", + "integrity": "sha512-XtvFXmj46Zibe89tFQwSQknrq1NxEtOep2rZuxth7K88tyPEP00FnoA6H7ATYhocAEA4XUWaNHNFWFRl1KX8aQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.6", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.6.tgz", @@ -2980,6 +3440,16 @@ "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", "dev": true }, + "node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/yargs": { "version": "17.0.24", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", @@ -3128,6 +3598,11 @@ } } }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -3245,7 +3720,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3298,8 +3772,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-hidden": { "version": "1.2.3", @@ -3420,8 +3893,15 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } }, "node_modules/attr-accept": { "version": "2.2.2", @@ -3431,6 +3911,14 @@ "node": ">=4" } }, + "node_modules/autolinker": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", + "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", + "dependencies": { + "tslib": "^2.3.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.14", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", @@ -3485,6 +3973,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -3495,12 +3993,12 @@ } }, "node_modules/babel-jest": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.0.tgz", - "integrity": "sha512-Jj8Bq2yKsk11XLk06Nm8SdvYkAcecH+GuhxB8DnK5SncjHnJ88TQjSnGgE7jpajpnSvz9DZ6X8hXrDkD/6/TPQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.1.tgz", + "integrity": "sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==", "dev": true, "dependencies": { - "@jest/transform": "^29.6.0", + "@jest/transform": "^29.6.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.5.0", @@ -3606,6 +4104,25 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/bcrypt": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", @@ -3636,6 +4153,17 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -3709,6 +4237,30 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3745,7 +4297,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -3754,6 +4305,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3821,6 +4377,33 @@ "node": ">=10" } }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -3870,7 +4453,6 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true, "funding": [ { "type": "github", @@ -3898,6 +4480,23 @@ "url": "https://joebell.co.uk" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/cleye": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/cleye/-/cleye-1.3.2.tgz", + "integrity": "sha512-MngIC2izcCz07iRKr3Pe8Z6ZBv4zbKFl/YnQEN/aMHis6PpH+MxI2e6n0bMUAmSVlMoAyQkdBCSTbfDmtcSovQ==", + "dependencies": { + "terminal-columns": "^1.4.1", + "type-flag": "^3.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/cleye?sponsor=1" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -3936,16 +4535,15 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -3956,8 +4554,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color-support": { "version": "1.1.3", @@ -3971,7 +4568,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3979,6 +4575,15 @@ "node": ">= 0.8" } }, + "node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -4011,11 +4616,36 @@ "node": ">= 0.6" } }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-js-pure": { + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.1.tgz", + "integrity": "sha512-w+C62kvWti0EPs4KPMCMVv9DriHSXfQOCQ94bGGBiEW5rrbtt/Rz8n5Krhfw9cpFyzXBjf3DB3QnPdEzGDY4Fw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4028,8 +4658,7 @@ "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" }, "node_modules/cssesc": { "version": "3.0.0", @@ -4069,8 +4698,7 @@ "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "devOptional": true + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -4119,12 +4747,27 @@ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "dev": true }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "optional": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, "node_modules/deep-equal": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", @@ -4154,6 +4797,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4164,7 +4815,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4345,7 +4995,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -4421,7 +5070,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -4447,6 +5095,19 @@ "node": ">=12" } }, + "node_modules/dompurify": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.3.tgz", + "integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ==" + }, + "node_modules/drange": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", + "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", + "engines": { + "node": ">=4" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.444", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.444.tgz", @@ -4471,6 +5132,15 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -4713,12 +5383,12 @@ } }, "node_modules/eslint-config-next": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.8.tgz", - "integrity": "sha512-2hE0b6lHuhtHBX8VgEXi8v4G8PVrPUBMOSLCTq8qtcQ2qQOX7+uBOLK2kU4FD2qDZzyXNlhmuH+WLT5ptY4XLA==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.9.tgz", + "integrity": "sha512-0fLtKRR268NArpqeXXwnLgMXPvF64YESQvptVg+RMLCaijKm3FICN9Y7Jc1p2o+yrWwE4DufJXDM/Vo53D1L7g==", "dev": true, "dependencies": { - "@next/eslint-plugin-next": "13.4.8", + "@next/eslint-plugin-next": "13.4.9", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.42.0", "eslint-import-resolver-node": "^0.3.6", @@ -4726,7 +5396,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-react": "^7.31.7", - "eslint-plugin-react-hooks": "^4.5.0" + "eslint-plugin-react-hooks": "5.0.0-canary-7118f5dd7-20230705" }, "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0", @@ -4951,9 +5621,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", "dev": true, "engines": { "node": ">=10" @@ -5102,7 +5772,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5139,18 +5808,27 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/expect": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.0.tgz", - "integrity": "sha512-AV+HaBtnDJ2YEUhPPo25HyUHBLaetM+y/Dq6pEC8VPQyt1dK+k8MfGkMy46djy2bddcqESc1kl4/K1uLWSfk9g==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.6.0", + "@jest/expect-utils": "^29.6.1", "@types/node": "*", "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.6.0", - "jest-message-util": "^29.6.0", - "jest-util": "^29.6.0" + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5188,6 +5866,11 @@ "node": ">= 6" } }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5208,6 +5891,18 @@ "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -5267,6 +5962,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dependencies": { + "micromatch": "^4.0.2" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -5286,6 +5989,25 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5299,7 +6021,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5309,6 +6030,31 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.9.0.tgz", + "integrity": "sha512-rahaRMkN8P8d/tgK/BLPX+WBVM27NbvdXBxqQujBtkDAIFspaRqN7Od7lfdGQA6KAD+f82fYCLBq1ipvcu8qLw==" + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -5322,6 +6068,34 @@ "url": "https://www.patreon.com/infusion" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "optional": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -5440,7 +6214,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -5508,6 +6281,12 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "optional": true + }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -5640,7 +6419,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -5661,7 +6439,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5673,7 +6450,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5701,6 +6477,52 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "engines": { + "node": "*" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -5766,6 +6588,25 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -5775,6 +6616,14 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -5842,6 +6691,12 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "optional": true + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -5864,6 +6719,28 @@ "loose-envify": "^1.0.0" } }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -5977,6 +6854,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", @@ -6028,6 +6914,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-inside-container": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", @@ -6099,6 +6994,14 @@ "node": ">=8" } }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -6241,7 +7144,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -6253,7 +7155,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, "bin": { "is-docker": "cli.js" }, @@ -6267,14 +7168,12 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", @@ -6343,15 +7242,15 @@ } }, "node_modules/jest": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.0.tgz", - "integrity": "sha512-do1J9gGrQ68E4UfMz/4OM71p9qCqQxu32N/9ZfeYFSSlx0uUOuxeyZxtJZNaUTW12ZA11ERhmBjBhy1Ho96R4g==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz", + "integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==", "dev": true, "dependencies": { - "@jest/core": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/core": "^29.6.1", + "@jest/types": "^29.6.1", "import-local": "^3.0.2", - "jest-cli": "^29.6.0" + "jest-cli": "^29.6.1" }, "bin": { "jest": "bin/jest.js" @@ -6382,28 +7281,28 @@ } }, "node_modules/jest-circus": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.0.tgz", - "integrity": "sha512-LtG45qEKhse2Ws5zNR4DnZATReLGQXzBZGZnJ0DU37p6d4wDhu41vvczCQ3Ou+llR6CRYDBshsubV7H4jZvIkw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.1.tgz", + "integrity": "sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.0", - "@jest/expect": "^29.6.0", - "@jest/test-result": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.6.0", - "jest-matcher-utils": "^29.6.0", - "jest-message-util": "^29.6.0", - "jest-runtime": "^29.6.0", - "jest-snapshot": "^29.6.0", - "jest-util": "^29.6.0", + "jest-each": "^29.6.1", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", "p-limit": "^3.1.0", - "pretty-format": "^29.6.0", + "pretty-format": "^29.6.1", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -6429,9 +7328,9 @@ } }, "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6461,21 +7360,21 @@ "dev": true }, "node_modules/jest-cli": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.0.tgz", - "integrity": "sha512-WvZIaanK/abkw6s01924DQ2QLwM5Q4Y4iPbSDb9Zg6smyXGqqcPQ7ft9X8D7B0jICz312eSzM6UlQNxuZJBrMw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.1.tgz", + "integrity": "sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==", "dev": true, "dependencies": { - "@jest/core": "^29.6.0", - "@jest/test-result": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/core": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.6.0", - "jest-util": "^29.6.0", - "jest-validate": "^29.6.0", + "jest-config": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -6511,31 +7410,31 @@ } }, "node_modules/jest-config": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.0.tgz", - "integrity": "sha512-fKA4jM91PDqWVkMpb1FVKxIuhg3hC6hgaen57cr1rRZkR96dCatvJZsk3ik7/GNu9ERj9wgAspOmyvkFoGsZhA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.1.tgz", + "integrity": "sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.6.0", - "@jest/types": "^29.6.0", - "babel-jest": "^29.6.0", + "@jest/test-sequencer": "^29.6.1", + "@jest/types": "^29.6.1", + "babel-jest": "^29.6.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.6.0", - "jest-environment-node": "^29.6.0", + "jest-circus": "^29.6.1", + "jest-environment-node": "^29.6.1", "jest-get-type": "^29.4.3", "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.6.0", - "jest-runner": "^29.6.0", - "jest-util": "^29.6.0", - "jest-validate": "^29.6.0", + "jest-resolve": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.6.0", + "pretty-format": "^29.6.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -6572,9 +7471,9 @@ } }, "node_modules/jest-config/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6604,15 +7503,15 @@ "dev": true }, "node_modules/jest-diff": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.0.tgz", - "integrity": "sha512-ZRm7cd2m9YyZ0N3iMyuo1iUiprxQ/MFpYWXzEEj7hjzL3WnDffKW8192XBDcrAI8j7hnrM1wed3bL/oEnYF/8w==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", + "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.4.3", "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.0" + "pretty-format": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6635,9 +7534,9 @@ } }, "node_modules/jest-diff/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6679,16 +7578,16 @@ } }, "node_modules/jest-each": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.0.tgz", - "integrity": "sha512-d0Jem4RBAlFUyV6JSXPSHVUpNo5RleSj+iJEy1G3+ZCrzHDjWs/1jUfrbnJKHdJdAx5BCEce/Ju379WqHhQk4w==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.1.tgz", + "integrity": "sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "chalk": "^4.0.0", "jest-get-type": "^29.4.3", - "jest-util": "^29.6.0", - "pretty-format": "^29.6.0" + "jest-util": "^29.6.1", + "pretty-format": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6711,9 +7610,9 @@ } }, "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6743,18 +7642,18 @@ "dev": true }, "node_modules/jest-environment-jsdom": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.6.0.tgz", - "integrity": "sha512-/cOhoyv+uMbOh4nQPyqtkPas/uUxr5AbK6TPqMMFyj1qEJURY78RhqgBjOFIX02+Lvu5V0RWLq2qKY1dHubFOQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.6.1.tgz", + "integrity": "sha512-PoY+yLaHzVRhVEjcVKSfJ7wXmJW4UqPYNhR05h7u/TK0ouf6DmRNZFBL/Z00zgQMyWGMBXn69/FmOvhEJu8cIw==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.0", - "@jest/fake-timers": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.6.0", - "jest-util": "^29.6.0", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1", "jsdom": "^20.0.0" }, "engines": { @@ -6770,17 +7669,17 @@ } }, "node_modules/jest-environment-node": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.0.tgz", - "integrity": "sha512-BOf5Q2/nFCdBOnyBM5c5/6DbdQYgc+0gyUQ8l8qhUAB8O7pM+4QJXIXJsRZJaxd5SHV6y5VArTVhOfogoqcP8Q==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.1.tgz", + "integrity": "sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.0", - "@jest/fake-timers": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", - "jest-mock": "^29.6.0", - "jest-util": "^29.6.0" + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6796,20 +7695,20 @@ } }, "node_modules/jest-haste-map": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.0.tgz", - "integrity": "sha512-dY1DKufptj7hcJSuhpqlYPGcnN3XjlOy/g0jinpRTMsbb40ivZHiuIPzeminOZkrek8C+oDxC54ILGO3vMLojg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.1.tgz", + "integrity": "sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.4.3", - "jest-util": "^29.6.0", - "jest-worker": "^29.6.0", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -6821,13 +7720,13 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.0.tgz", - "integrity": "sha512-JdV6EZOPxHR1gd6ccxjNowuROkT2jtGU5G/g58RcJX1xe5mrtLj0g6/ZkyMoXF4cs+tTkHMFX6pcIrB1QPQwCw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz", + "integrity": "sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==", "dev": true, "dependencies": { "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.0" + "pretty-format": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6846,9 +7745,9 @@ } }, "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6866,15 +7765,15 @@ "dev": true }, "node_modules/jest-matcher-utils": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.0.tgz", - "integrity": "sha512-oSlqfGN+sbkB2Q5um/zL7z80w84FEAcLKzXBZIPyRk2F2Srg1ubhrHVKW68JCvb2+xKzAeGw35b+6gciS24PHw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", + "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.6.0", + "jest-diff": "^29.6.1", "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.0" + "pretty-format": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6897,9 +7796,9 @@ } }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6929,18 +7828,18 @@ "dev": true }, "node_modules/jest-message-util": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.0.tgz", - "integrity": "sha512-mkCp56cETbpoNtsaeWVy6SKzk228mMi9FPHSObaRIhbR2Ujw9PqjW/yqVHD2tN1bHbC8ol6h3UEo7dOPmIYwIA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", + "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.6.0", + "pretty-format": "^29.6.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -6965,9 +7864,9 @@ } }, "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -6997,14 +7896,14 @@ "dev": true }, "node_modules/jest-mock": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.0.tgz", - "integrity": "sha512-2Pb7R2w24Q0aUVn+2/vdRDL6CqGqpheDZy7zrXav8FotOpSGw/4bS2hyVoKHMEx4xzOn6EyCAGwc5czWxXeN7w==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.1.tgz", + "integrity": "sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@types/node": "*", - "jest-util": "^29.6.0" + "jest-util": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7037,17 +7936,17 @@ } }, "node_modules/jest-resolve": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.0.tgz", - "integrity": "sha512-+hrpY4LzAONoZA/rvB6rnZLkOSA6UgJLpdCWrOZNSgGxWMumzRLu7dLUSCabAHzoHIDQ9qXfr3th1zYNJ0E8sQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.1.tgz", + "integrity": "sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.0", + "jest-haste-map": "^29.6.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.6.0", - "jest-validate": "^29.6.0", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -7057,13 +7956,13 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.0.tgz", - "integrity": "sha512-eOfPog9K3hJdJk/3i6O6bQhXS+3uXhMDkLJGX+xmMPp7T1d/zdcFofbDnHgNoEkhD/mSimC5IagLEP7lpLLu/A==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz", + "integrity": "sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==", "dev": true, "dependencies": { "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.6.0" + "jest-snapshot": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7086,30 +7985,30 @@ } }, "node_modules/jest-runner": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.0.tgz", - "integrity": "sha512-4fZuGV2lOxS2BiqEG9/AI8E6O+jo+QZjMVcgi1x5E6aDql0Gd/EFIbUQ0pSS09y8cya1vJB/qC2xsE468jqtSg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.1.tgz", + "integrity": "sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==", "dev": true, "dependencies": { - "@jest/console": "^29.6.0", - "@jest/environment": "^29.6.0", - "@jest/test-result": "^29.6.0", - "@jest/transform": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/console": "^29.6.1", + "@jest/environment": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.6.0", - "jest-haste-map": "^29.6.0", - "jest-leak-detector": "^29.6.0", - "jest-message-util": "^29.6.0", - "jest-resolve": "^29.6.0", - "jest-runtime": "^29.6.0", - "jest-util": "^29.6.0", - "jest-watcher": "^29.6.0", - "jest-worker": "^29.6.0", + "jest-environment-node": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-leak-detector": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-resolve": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-util": "^29.6.1", + "jest-watcher": "^29.6.1", + "jest-worker": "^29.6.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -7134,31 +8033,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.0.tgz", - "integrity": "sha512-5FavYo3EeXLHIvnJf+r7Cj0buePAbe4mzRB9oeVxDS0uVmouSBjWeGgyRjZkw7ArxOoZI8gO6f8SGMJ2HFlwwg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.1.tgz", + "integrity": "sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.0", - "@jest/fake-timers": "^29.6.0", - "@jest/globals": "^29.6.0", + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/globals": "^29.6.1", "@jest/source-map": "^29.6.0", - "@jest/test-result": "^29.6.0", - "@jest/transform": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.0", - "jest-message-util": "^29.6.0", - "jest-mock": "^29.6.0", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.6.0", - "jest-snapshot": "^29.6.0", - "jest-util": "^29.6.0", + "jest-resolve": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -7183,9 +8082,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.0.tgz", - "integrity": "sha512-H3kUE9NwWDEDoutcOSS921IqdlkdjgnMdj1oMyxAHNflscdLc9dB8OudZHV6kj4OHJxbMxL8CdI5DlwYrs4wQg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.1.tgz", + "integrity": "sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -7193,21 +8092,21 @@ "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.6.0", - "@jest/transform": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/expect-utils": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.6.0", + "expect": "^29.6.1", "graceful-fs": "^4.2.9", - "jest-diff": "^29.6.0", + "jest-diff": "^29.6.1", "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.6.0", - "jest-message-util": "^29.6.0", - "jest-util": "^29.6.0", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", "natural-compare": "^1.4.0", - "pretty-format": "^29.6.0", + "pretty-format": "^29.6.1", "semver": "^7.5.3" }, "engines": { @@ -7231,9 +8130,9 @@ } }, "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -7263,12 +8162,12 @@ "dev": true }, "node_modules/jest-util": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.0.tgz", - "integrity": "sha512-S0USx9YwcvEm4pQ5suisVm/RVxBmi0GFR7ocJhIeaCuW5AXnAnffXbaVKvIFodyZNOc9ygzVtTxmBf40HsHXaA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", + "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -7296,17 +8195,17 @@ } }, "node_modules/jest-validate": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.0.tgz", - "integrity": "sha512-MLTrAJsb1+W7svbeZ+A7pAnyXMaQrjvPDKCy7OlfsfB6TMVc69v7WjUWfiR6r3snULFWZASiKgvNVDuATta1dg==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.1.tgz", + "integrity": "sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA==", "dev": true, "dependencies": { - "@jest/types": "^29.6.0", + "@jest/types": "^29.6.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.6.0" + "pretty-format": "^29.6.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7341,9 +8240,9 @@ } }, "node_modules/jest-validate/node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -7373,18 +8272,18 @@ "dev": true }, "node_modules/jest-watcher": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.0.tgz", - "integrity": "sha512-LdsQqFNX60mRdRRe+zsELnYRH1yX6KL+ukbh+u6WSQeTheZZe1TlLJNKRQiZ7e0VbvMkywmMWL/KV35noOJCcw==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.1.tgz", + "integrity": "sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==", "dev": true, "dependencies": { - "@jest/test-result": "^29.6.0", - "@jest/types": "^29.6.0", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.6.0", + "jest-util": "^29.6.1", "string-length": "^4.0.1" }, "engines": { @@ -7408,13 +8307,13 @@ } }, "node_modules/jest-worker": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.0.tgz", - "integrity": "sha512-oiQHH1SnKmZIwwPnpOrXTq4kHBk3lKGY/07DpnH0sAu+x7J8rXlbLDROZsU6vy9GwB0hPiZeZpu6YlJ48QoKcA==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.1.tgz", + "integrity": "sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.6.0", + "jest-util": "^29.6.1", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -7453,6 +8352,11 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-file-download": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", + "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7462,7 +8366,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -7557,6 +8460,25 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz", @@ -7572,6 +8494,14 @@ "node": ">=4.0" } }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -7649,8 +8579,22 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -7658,6 +8602,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7669,6 +8618,19 @@ "loose-envify": "cli.js" } }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -7679,9 +8641,9 @@ } }, "node_modules/lucide-react": { - "version": "0.258.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.258.0.tgz", - "integrity": "sha512-3evnpKadBrjLr2HHJ66eDZ1y0vPS6pm8NiNDaLqhddUUyJGnA+lfDPZfbVkuAFq7Xaa1TEy7Sg17sM7mHpMKrA==", + "version": "0.259.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.259.0.tgz", + "integrity": "sha512-dFBLc6jRDfcpD9NQ7NyFVa+YR3RHX6+bs+f/UiotvNPho+kd4WyeXWMCCchUf7i/pq3BAaHkbmtkbx/GxxHVUw==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } @@ -7748,7 +8710,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -7757,7 +8718,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -7774,6 +8734,18 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7783,6 +8755,17 @@ "node": ">=4" } }, + "node_modules/minim": { + "version": "0.23.8", + "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", + "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", + "dependencies": { + "lodash": "^4.15.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -7798,7 +8781,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7850,6 +8832,12 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "optional": true + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7865,6 +8853,12 @@ "thenify-all": "^1.0.0" } }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": true + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -7882,6 +8876,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7889,11 +8889,11 @@ "dev": true }, "node_modules/next": { - "version": "13.4.8", - "resolved": "https://registry.npmjs.org/next/-/next-13.4.8.tgz", - "integrity": "sha512-lxUjndYKjZHGK3CWeN2RI+/6ni6EUvjiqGWXAYPxUfGIdFGQ5XoisrqAJ/dF74aP27buAfs8MKIbIMMdxjqSBg==", + "version": "13.4.9", + "resolved": "https://registry.npmjs.org/next/-/next-13.4.9.tgz", + "integrity": "sha512-vtefFm/BWIi/eWOqf1GsmKG3cjKw1k3LjuefKRcL3iiLl3zWzFdPG3as6xtxrGO6gwTzzaO1ktL4oiHt/uvTjA==", "dependencies": { - "@next/env": "13.4.8", + "@next/env": "13.4.9", "@swc/helpers": "0.5.1", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -7909,15 +8909,15 @@ "node": ">=16.8.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "13.4.8", - "@next/swc-darwin-x64": "13.4.8", - "@next/swc-linux-arm64-gnu": "13.4.8", - "@next/swc-linux-arm64-musl": "13.4.8", - "@next/swc-linux-x64-gnu": "13.4.8", - "@next/swc-linux-x64-musl": "13.4.8", - "@next/swc-win32-arm64-msvc": "13.4.8", - "@next/swc-win32-ia32-msvc": "13.4.8", - "@next/swc-win32-x64-msvc": "13.4.8" + "@next/swc-darwin-arm64": "13.4.9", + "@next/swc-darwin-x64": "13.4.9", + "@next/swc-linux-arm64-gnu": "13.4.9", + "@next/swc-linux-arm64-musl": "13.4.9", + "@next/swc-linux-x64-gnu": "13.4.9", + "@next/swc-linux-x64-musl": "13.4.9", + "@next/swc-win32-arm64-msvc": "13.4.9", + "@next/swc-win32-ia32-msvc": "13.4.9", + "@next/swc-win32-x64-msvc": "13.4.9" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -7965,6 +8965,26 @@ } } }, + "node_modules/next-swagger-doc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/next-swagger-doc/-/next-swagger-doc-0.4.0.tgz", + "integrity": "sha512-5Wt19Av4tOHVdXPJ7xTVvDJuiWuP5OYnY13BSq5SIjMtktFfhX4/9yZyaMCXImbUECu26PALn9CpRQRplIXJ3w==", + "dependencies": { + "@types/swagger-jsdoc": "6.0.1", + "cleye": "1.3.2", + "isarray": "2.0.5", + "swagger-jsdoc": "6.2.8" + }, + "bin": { + "next-swagger-doc-cli": "dist/cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "next": ">=9" + } + }, "node_modules/next-themes": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz", @@ -7998,15 +9018,45 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/node-abi": { + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", + "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-addon-api": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8169,7 +9219,6 @@ "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8327,6 +9376,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "peer": true + }, "node_modules/openid-client": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.4.2.tgz", @@ -8374,6 +9429,14 @@ "node": ">= 0.8.0" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -8425,6 +9488,23 @@ "node": ">=6" } }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -8455,6 +9535,97 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/patch-package": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-7.0.0.tgz", + "integrity": "sha512-eYunHbnnB2ghjTNc5iL1Uo7TsGMuXk0vibX3RFcE/CdVdXzmdbMsG/4K4IgoSuIkLTI5oHrMQk4+NkFqSed0BQ==", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "ci-info": "^3.7.0", + "cross-spawn": "^7.0.3", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^9.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33", + "yaml": "^2.2.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=14", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/patch-package/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/patch-package/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/patch-package/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8476,7 +9647,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -8592,9 +9762,9 @@ } }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz", + "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==", "funding": [ { "type": "opencollective", @@ -8740,6 +9910,32 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8792,6 +9988,22 @@ "node": ">=14.17" } }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -8820,12 +10032,39 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -8851,11 +10090,24 @@ } ] }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -8876,6 +10128,74 @@ } ] }, + "node_modules/ramda": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", + "integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/ramda-adjunct": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-4.0.0.tgz", + "integrity": "sha512-W/NiJAlZdwZ/iUkWEQQgRdH5Szqqet1WoVH9cdqDVjFbVaZHuJfJRvsxqHhvq6tZse+yVbFatLDLdVa30wBlGQ==", + "engines": { + "node": ">=0.10.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda-adjunct" + }, + "peerDependencies": { + "ramda": ">= 0.29.0" + } + }, + "node_modules/randexp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", + "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", + "dependencies": { + "drange": "^1.0.2", + "ret": "^0.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -8887,6 +10207,30 @@ "node": ">=0.10.0" } }, + "node_modules/react-copy-to-clipboard": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", + "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, + "node_modules/react-debounce-input": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", + "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", + "dependencies": { + "lodash.debounce": "^4", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -8930,6 +10274,27 @@ "react": "^16.8.0 || ^17 || ^18" } }, + "node_modules/react-immutable-proptypes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", + "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", + "dependencies": { + "invariant": "^2.2.2" + }, + "peerDependencies": { + "immutable": ">=3.6.2" + } + }, + "node_modules/react-immutable-pure-component": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", + "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", + "peerDependencies": { + "immutable": ">= 2 || >= 4.0.0-rc", + "react": ">= 16.6", + "react-dom": ">= 16.6" + } + }, "node_modules/react-infinite-scroll-component": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz", @@ -8941,6 +10306,14 @@ "react": ">=16.0.0" } }, + "node_modules/react-inspector": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", + "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", + "peerDependencies": { + "react": "^16.8.4 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-intersection-observer": { "version": "9.5.2", "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.5.2.tgz", @@ -8955,6 +10328,49 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/react-redux": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.1.tgz", + "integrity": "sha512-5W0QaKtEhj+3bC0Nj0NkqkhIv8gLADH/2kYFMTHxCVqQILiWzLv6MaLuV5wJU3BQEdHKzTfcvPN0WMS6SC1oyA==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/react-remove-scroll": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", @@ -9022,6 +10438,21 @@ } } }, + "node_modules/react-syntax-highlighter": { + "version": "15.5.0", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", + "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -9067,6 +10498,44 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", + "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", + "peerDependencies": { + "immutable": "^3.8.1 || ^4.0.0-rc.1" + } + }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "engines": { + "node": ">=6" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -9089,6 +10558,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/remarkable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", + "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", + "dependencies": { + "argparse": "^1.0.10", + "autolinker": "^3.11.0" + }, + "bin": { + "remarkable": "bin/remarkable.js" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/remarkable/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -9101,8 +10601,12 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" }, "node_modules/resolve": { "version": "1.22.2", @@ -9168,6 +10672,14 @@ "node": ">=10" } }, + "node_modules/ret": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -9317,16 +10829,41 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9338,16 +10875,23 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/short-unique-id": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-4.4.4.tgz", + "integrity": "sha512-oLF1NCmtbiTWl2SqdXZQbo5KM1b7axdp0RgQLq8qCBBLoq+o3A5wmLrNM6bZIh54/a8BJ3l69kTXuxwZ+XCYuw==", + "bin": { + "short-unique-id": "bin/short-unique-id", + "suid": "bin/short-unique-id" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -9362,6 +10906,51 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -9404,11 +10993,19 @@ "source-map": "^0.6.0" } }, + "node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/stack-utils": { "version": "2.0.6", @@ -9431,6 +11028,11 @@ "node": ">=8" } }, + "node_modules/stampit": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stampit/-/stampit-4.3.2.tgz", + "integrity": "sha512-pE2org1+ZWQBnIxRPrBM2gVupkuDD0TTNIo1H6GdT/vO82NXli2z8lRE8cu/nBIHrcOCXFBAHpb9ZldrB2/qOA==" + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -9673,7 +11275,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -9692,6 +11293,140 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-client": { + "version": "3.19.10", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.19.10.tgz", + "integrity": "sha512-r+uGryGdxYQf7Aa9WzK226RigDaWAutDqP903O1QFA47jnJZ5RCkaV3X8nadXkNoZRlsZv8sEKOB8UoDY99BBA==", + "dependencies": { + "@babel/runtime-corejs3": "^7.20.13", + "@swagger-api/apidom-core": ">=0.70.1 <1.0.0", + "@swagger-api/apidom-json-pointer": ">=0.70.1 <1.0.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=0.70.2 <1.0.0", + "@swagger-api/apidom-reference": ">=0.70.2 <1.0.0", + "cookie": "~0.5.0", + "cross-fetch": "^3.1.5", + "deepmerge": "~4.3.0", + "fast-json-patch": "^3.0.0-1", + "form-data-encoder": "^1.4.3", + "formdata-node": "^4.0.0", + "is-plain-object": "^5.0.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "qs": "^6.10.2", + "traverse": "~0.6.6", + "url": "~0.11.0" + } + }, + "node_modules/swagger-jsdoc": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", + "integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==", + "dependencies": { + "commander": "6.2.0", + "doctrine": "3.0.0", + "glob": "7.1.6", + "lodash.mergewith": "^4.6.2", + "swagger-parser": "^10.0.3", + "yaml": "2.0.0-1" + }, + "bin": { + "swagger-jsdoc": "bin/swagger-jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/swagger-jsdoc/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/swagger-jsdoc/node_modules/yaml": { + "version": "2.0.0-1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", + "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==", + "dependencies": { + "@apidevtools/swagger-parser": "10.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swagger-ui-react": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.1.0.tgz", + "integrity": "sha512-ivbw72f6mUZ431H4OC3cMhJy+ONBlmQ81TNAt7DKkUCW6nG+GboHCpLF1SXPCstzUskbAuZq0hOk3BuKb20pSA==", + "dependencies": { + "@babel/runtime-corejs3": "^7.22.5", + "@braintree/sanitize-url": "=6.0.2", + "base64-js": "^1.5.1", + "classnames": "^2.3.1", + "css.escape": "1.5.1", + "deep-extend": "0.6.0", + "dompurify": "=3.0.3", + "ieee754": "^1.2.1", + "immutable": "^3.x.x", + "js-file-download": "^0.4.12", + "js-yaml": "=4.1.0", + "lodash": "^4.17.21", + "patch-package": "^7.0.0", + "prop-types": "^15.8.1", + "randexp": "^0.5.3", + "randombytes": "^2.1.0", + "react-copy-to-clipboard": "5.1.0", + "react-debounce-input": "=3.3.0", + "react-immutable-proptypes": "2.2.0", + "react-immutable-pure-component": "^2.2.0", + "react-inspector": "^6.0.1", + "react-redux": "^8.0.5", + "react-syntax-highlighter": "^15.5.0", + "redux": "^4.1.2", + "redux-immutable": "^4.0.0", + "remarkable": "^2.0.1", + "reselect": "^4.1.8", + "serialize-error": "^8.1.0", + "sha.js": "^2.4.11", + "swagger-client": "^3.19.10", + "url-parse": "^1.5.10", + "xml": "=1.0.1", + "xml-but-prettier": "^1.0.1", + "zenscroll": "^4.0.2" + }, + "peerDependencies": { + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -9801,11 +11536,53 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "optional": true + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/terminal-columns": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terminal-columns/-/terminal-columns-1.4.1.tgz", + "integrity": "sha512-IKVL/itiMy947XWVv4IHV7a0KQXvKjj4ptbi7Ew9MPMcOLzkiQeyx3Gyvh62hKrfJ0RZc4M1nbhzjNM39Kyujw==", + "funding": { + "url": "https://github.com/privatenumber/terminal-columns?sponsor=1" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -9865,6 +11642,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -9891,6 +11679,11 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", @@ -9918,11 +11711,55 @@ "node": ">=12" } }, + "node_modules/traverse": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tree-sitter": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.4.tgz", + "integrity": "sha512-rjfR5dc4knG3jnJNN/giJ9WOoN1zL/kZyrS0ILh+eqq8RNcIbiXA63JsMEgluug0aNvfQvK4BfCErN1vIzvKog==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "nan": "^2.17.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/tree-sitter-json": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.0.tgz", + "integrity": "sha512-PteOLH+Tx6Bz4ZA/d40/DbkiSXXRM/gKahhHI8hQ1lWNfFvdknnz9k3Mz84ol5srRyLboJ8wp8GSkhZ6ht9EGQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "nan": "^2.14.1" + } + }, + "node_modules/tree-sitter-yaml": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz", + "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "nan": "^2.14.0" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" + }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -9982,6 +11819,18 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -10007,7 +11856,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -10015,6 +11863,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/type-flag/-/type-flag-3.0.0.tgz", + "integrity": "sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==", + "funding": { + "url": "https://github.com/privatenumber/type-flag?sponsor=1" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -10029,6 +11885,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/types-ramda": { + "version": "0.29.4", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.4.tgz", + "integrity": "sha512-XO/820iRsCDwqLjE8XE+b57cVGPyk1h+U9lBGpDWvbEky+NQChvHVwaKM05WnW1c5z3EVQh8NhXFmh2E/1YazQ==", + "dependencies": { + "ts-toolbelt": "^9.6.0" + } + }, "node_modules/typescript": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", @@ -10065,6 +11929,11 @@ "node": ">= 4.0.0" } }, + "node_modules/unraw": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unraw/-/unraw-2.0.1.tgz", + "integrity": "sha512-tdOvLfRzHolwYcHS6HIX860MkK9LQ4+oLuNwFYL7bpgTEO64PZrcQxkisgwJYCfF8sKiWLwwu1c83DvMkbefIQ==" + }, "node_modules/untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -10122,16 +11991,29 @@ "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", + "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.0" + } + }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, "node_modules/use-callback-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", @@ -10214,6 +12096,14 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "node_modules/validator": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -10247,6 +12137,20 @@ "node": ">=10.13.0" } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/web-tree-sitter": { + "version": "0.20.3", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz", + "integrity": "sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==", + "optional": true + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -10294,7 +12198,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -10420,6 +12323,19 @@ } } }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" + }, + "node_modules/xml-but-prettier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", + "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", + "dependencies": { + "repeat-string": "^1.5.2" + } + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -10435,6 +12351,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -10497,6 +12421,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/zenscroll": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", + "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==" + }, "node_modules/zod": { "version": "3.21.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", diff --git a/package.json b/package.json index a158426b7129f4de3efb6ab67b26a3a855770be8..83f8580e0b4d22b26a3f81e96f0c88199f41f053 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,10 @@ "build": "next build", "start": "next start", "lint": "next lint", - "preview": "prisma generate && next build && next start", + "test": "jest --coverage", + "preview": "next build && next start", "vercel-build": "prisma generate && prisma migrate deploy && next build", - "test": "jest", - "coverage": "jest --coverage" + "postinstall": "prisma generate" }, "dependencies": { "@auth/prisma-adapter": "^1.0.0", @@ -37,9 +37,10 @@ "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", "dayjs": "^1.11.9", - "lucide-react": "^0.258.0", - "next": "^13.4.8", + "lucide-react": "^0.259.0", + "next": "^13.4.9", "next-auth": "^4.22.1", + "next-swagger-doc": "^0.4.0", "next-themes": "^0.2.1", "nodemailer": "^6.9.3", "normalize-diacritics": "^4.0.0", @@ -49,6 +50,7 @@ "react-hook-form": "^7.45.1", "react-infinite-scroll-component": "^6.1.0", "react-intersection-observer": "^9.5.2", + "swagger-ui-react": "^5.1.0", "tailwind-merge": "^1.13.2", "tailwindcss-animate": "^1.0.6", "uploadthing": "^5.1.0", @@ -60,16 +62,17 @@ "@testing-library/react": "^14.0.0", "@types/bcrypt": "^5.0.0", "@types/jest": "^29.5.2", - "@types/node": "^20.3.3", + "@types/node": "^20.4.0", "@types/nodemailer": "^6.4.8", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", + "@types/swagger-ui-react": "^4.18.0", "autoprefixer": "10.4.14", "eslint": "^8.44.0", - "eslint-config-next": "^13.4.8", - "jest": "^29.6.0", - "jest-environment-jsdom": "^29.6.0", - "postcss": "8.4.24", + "eslint-config-next": "^13.4.9", + "jest": "^29.6.1", + "jest-environment-jsdom": "^29.6.1", + "postcss": "8.4.25", "prisma": "^4.16.2", "tailwindcss": "3.3.2", "typescript": "^5.1.6" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b4bb00617a3b0c9ba6fc45839887b1c6cea6d8a0..e9596dd527b903bb2d93a0393ffec9121ee0ca67 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -81,8 +81,8 @@ model User { regweets Regweet[] likes Like[] - following Follows[] @relation("following") - followers Follows[] @relation("follower") + following User[] @relation("followers") + followers User[] @relation("followers") ActivationToken ActivationToken[] @@ -101,18 +101,6 @@ model ActivationToken { userId String } -model Follows { - followerId String - followingId String - createdAt DateTime @default(now()) @map("created_at") - - follower User @relation("following", fields: [followerId], references: [id]) - following User @relation("follower", fields: [followingId], references: [id]) - - @@id([followerId, followingId]) - @@map("follows") -} - model Gweet { id String @id @default(cuid()) authorId String @map("user_id") diff --git a/tsconfig.json b/tsconfig.json index 88c4dbac27487a5958bba8e191da2b3239fb3232..5fc1a977fc4d22412fcdb89724f67565a1cdb4f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,42 +1,43 @@ { - "compilerOptions": { - "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "paths": { - "@/*": [ - "./*" - ] + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + }, + "strictNullChecks": true }, - "strictNullChecks": true - }, - "include": [ - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - ".next/types/**/*.ts" - ], - "exclude": [ - "node_modules" - ] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } \ No newline at end of file