diff --git a/.gitignore b/.gitignore
index 5ef6a52..1cdccac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,11 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+
+# reference files
+/reference/
+
+# claude skills/agents
+/.agents/
+/.claude/
+skills-lock.json
diff --git a/Dockerfile b/Dockerfile
index f917a6d..db41699 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,6 +3,7 @@ WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
+RUN npx prisma generate
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
diff --git a/app/api/manga/route.ts b/app/api/manga/route.ts
new file mode 100644
index 0000000..e36c28d
--- /dev/null
+++ b/app/api/manga/route.ts
@@ -0,0 +1,37 @@
+import { prisma } from "@/lib/db";
+import { NextRequest } from "next/server";
+
+export async function GET() {
+ const manga = await prisma.manga.findMany({
+ orderBy: { updatedAt: "desc" },
+ include: {
+ _count: { select: { chapters: true } },
+ },
+ });
+ return Response.json(manga);
+}
+
+export async function POST(request: NextRequest) {
+ const body = await request.json();
+
+ const { title, description, coverUrl, slug, status } = body;
+
+ if (!title || !description || !coverUrl || !slug) {
+ return Response.json(
+ { error: "Missing required fields: title, description, coverUrl, slug" },
+ { status: 400 }
+ );
+ }
+
+ const manga = await prisma.manga.create({
+ data: {
+ title,
+ description,
+ coverUrl,
+ slug,
+ status: status || "PUBLISHED",
+ },
+ });
+
+ return Response.json(manga, { status: 201 });
+}
diff --git a/app/api/search/route.ts b/app/api/search/route.ts
new file mode 100644
index 0000000..1c129bf
--- /dev/null
+++ b/app/api/search/route.ts
@@ -0,0 +1,27 @@
+import { prisma } from "@/lib/db";
+
+export async function GET(request: Request) {
+ const { searchParams } = new URL(request.url);
+ const q = searchParams.get("q")?.trim();
+
+ if (!q || q.length < 2) {
+ return Response.json([]);
+ }
+
+ const results = await prisma.manga.findMany({
+ where: {
+ status: "PUBLISHED",
+ title: { contains: q, mode: "insensitive" },
+ },
+ select: {
+ id: true,
+ title: true,
+ slug: true,
+ coverUrl: true,
+ },
+ take: 8,
+ orderBy: { title: "asc" },
+ });
+
+ return Response.json(results);
+}
diff --git a/app/api/upload/route.ts b/app/api/upload/route.ts
new file mode 100644
index 0000000..76106e5
--- /dev/null
+++ b/app/api/upload/route.ts
@@ -0,0 +1,19 @@
+import { NextRequest } from "next/server";
+import { getPresignedUploadUrl, getPublicUrl } from "@/lib/r2";
+
+export async function POST(request: NextRequest) {
+ const body = await request.json();
+ const { key } = body;
+
+ if (!key || typeof key !== "string") {
+ return Response.json(
+ { error: "Missing required field: key (e.g. manga/1/1/1.webp)" },
+ { status: 400 }
+ );
+ }
+
+ const uploadUrl = await getPresignedUploadUrl(key);
+ const publicUrl = getPublicUrl(key);
+
+ return Response.json({ uploadUrl, publicUrl });
+}
diff --git a/app/genre/page.tsx b/app/genre/page.tsx
new file mode 100644
index 0000000..0c0ec3b
--- /dev/null
+++ b/app/genre/page.tsx
@@ -0,0 +1,25 @@
+import { prisma } from "@/lib/db";
+import { GenreTabs } from "@/components/GenreTabs";
+import type { Metadata } from "next";
+
+export const dynamic = "force-dynamic";
+
+export const metadata: Metadata = {
+ title: "Genres",
+};
+
+export default async function GenrePage() {
+ const manga = await prisma.manga.findMany({
+ where: { status: "PUBLISHED" },
+ orderBy: { title: "asc" },
+ include: { _count: { select: { chapters: true } } },
+ });
+
+ const genres = [...new Set(manga.map((m) => m.genre))].sort();
+
+ return (
+
+
+
+ );
+}
diff --git a/app/globals.css b/app/globals.css
index a2dc41e..8379985 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,26 +1,71 @@
@import "tailwindcss";
:root {
- --background: #ffffff;
- --foreground: #171717;
+ --background: #0f0f14;
+ --foreground: #e8e6e3;
+ --surface: #1a1a24;
+ --surface-hover: #242433;
+ --border: #2a2a3c;
+ --accent: #7c5cfc;
+ --accent-hover: #9478ff;
+ --muted: #8b8b9e;
+ --card: #16161f;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
+ --color-surface: var(--surface);
+ --color-surface-hover: var(--surface-hover);
+ --color-border: var(--border);
+ --color-accent: var(--accent);
+ --color-accent-hover: var(--accent-hover);
+ --color-muted: var(--muted);
+ --color-card: var(--card);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
+* {
+ -webkit-tap-highlight-color: transparent;
}
body {
background: var(--background);
color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+ font-family: var(--font-sans), system-ui, sans-serif;
+ overflow-x: hidden;
+}
+
+/* Custom scrollbar for webkit */
+::-webkit-scrollbar {
+ width: 6px;
+}
+::-webkit-scrollbar-track {
+ background: var(--background);
+}
+::-webkit-scrollbar-thumb {
+ background: var(--border);
+ border-radius: 3px;
+}
+
+/* Smooth scroll for the whole page */
+html {
+ scroll-behavior: smooth;
+}
+
+/* Hide scrollbar for horizontal carousels */
+.no-scrollbar::-webkit-scrollbar {
+ display: none;
+}
+.no-scrollbar {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+}
+
+/* Safe area insets for mobile notches */
+@supports (padding: env(safe-area-inset-bottom)) {
+ .pb-safe {
+ padding-bottom: env(safe-area-inset-bottom);
+ }
}
diff --git a/app/layout.tsx b/app/layout.tsx
index 976eb90..290ff7d 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,5 +1,7 @@
-import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
+import type { Metadata, Viewport } from "next";
+import { Geist } from "next/font/google";
+import { Header } from "@/components/Header";
+import { BottomNav } from "@/components/BottomNav";
import "./globals.css";
const geistSans = Geist({
@@ -7,14 +9,26 @@ const geistSans = Geist({
subsets: ["latin"],
});
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
-
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: {
+ default: "SunnyMH — Free Manga Reader",
+ template: "%s | SunnyMH",
+ },
+ description:
+ "Read free public domain manga online. Beautiful reader optimized for mobile.",
+ metadataBase: new URL("https://manga.04080616.xyz"),
+ openGraph: {
+ type: "website",
+ siteName: "SunnyMH",
+ },
+};
+
+export const viewport: Viewport = {
+ width: "device-width",
+ initialScale: 1,
+ maximumScale: 1,
+ viewportFit: "cover",
+ themeColor: "#0f0f14",
};
export default function RootLayout({
@@ -23,11 +37,12 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
- {children}
+
+
+
+ {children}
+
+
);
}
diff --git a/app/loading.tsx b/app/loading.tsx
new file mode 100644
index 0000000..e2a630b
--- /dev/null
+++ b/app/loading.tsx
@@ -0,0 +1,12 @@
+export default function Loading() {
+ return (
+
+
+
+ {Array.from({ length: 12 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
diff --git a/app/manga/[slug]/[chapter]/layout.tsx b/app/manga/[slug]/[chapter]/layout.tsx
new file mode 100644
index 0000000..681cc92
--- /dev/null
+++ b/app/manga/[slug]/[chapter]/layout.tsx
@@ -0,0 +1,9 @@
+export default function ChapterLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ // The chapter reader has its own full-screen layout
+ // Override parent padding/nav by rendering children directly
+ return <>{children}>;
+}
diff --git a/app/manga/[slug]/[chapter]/page.tsx b/app/manga/[slug]/[chapter]/page.tsx
new file mode 100644
index 0000000..1824e25
--- /dev/null
+++ b/app/manga/[slug]/[chapter]/page.tsx
@@ -0,0 +1,67 @@
+import { notFound } from "next/navigation";
+import { prisma } from "@/lib/db";
+import { PageReader } from "@/components/PageReader";
+import type { Metadata } from "next";
+
+type Props = {
+ params: Promise<{ slug: string; chapter: string }>;
+};
+
+export async function generateMetadata({ params }: Props): Promise {
+ const { slug, chapter } = await params;
+ const chapterNum = parseInt(chapter, 10);
+ if (isNaN(chapterNum)) return { title: "Not Found" };
+
+ const manga = await prisma.manga.findUnique({ where: { slug } });
+ if (!manga) return { title: "Not Found" };
+
+ return {
+ title: `${manga.title} — Ch. ${chapterNum}`,
+ description: `Read chapter ${chapterNum} of ${manga.title}`,
+ };
+}
+
+export default async function ChapterReaderPage({ params }: Props) {
+ const { slug, chapter } = await params;
+ const chapterNum = parseInt(chapter, 10);
+ if (isNaN(chapterNum)) notFound();
+
+ const manga = await prisma.manga.findUnique({
+ where: { slug },
+ include: {
+ chapters: {
+ orderBy: { number: "asc" },
+ include: {
+ pages: { orderBy: { number: "asc" } },
+ },
+ },
+ },
+ });
+
+ if (!manga) notFound();
+
+ const currentChapter = manga.chapters.find((c) => c.number === chapterNum);
+ if (!currentChapter) notFound();
+
+ const chapterIndex = manga.chapters.findIndex(
+ (c) => c.number === chapterNum
+ );
+ const prevChapter =
+ chapterIndex > 0 ? manga.chapters[chapterIndex - 1].number : null;
+ const nextChapter =
+ chapterIndex < manga.chapters.length - 1
+ ? manga.chapters[chapterIndex + 1].number
+ : null;
+
+ return (
+
+ );
+}
diff --git a/app/manga/[slug]/page.tsx b/app/manga/[slug]/page.tsx
new file mode 100644
index 0000000..fc3ff98
--- /dev/null
+++ b/app/manga/[slug]/page.tsx
@@ -0,0 +1,91 @@
+import { notFound } from "next/navigation";
+import { prisma } from "@/lib/db";
+import { ChapterList } from "@/components/ChapterList";
+import type { Metadata } from "next";
+
+type Props = {
+ params: Promise<{ slug: string }>;
+};
+
+export async function generateMetadata({ params }: Props): Promise {
+ const { slug } = await params;
+ const manga = await prisma.manga.findUnique({ where: { slug } });
+ if (!manga) return { title: "Not Found" };
+ return {
+ title: manga.title,
+ description: manga.description,
+ openGraph: {
+ title: manga.title,
+ description: manga.description,
+ images: [manga.coverUrl],
+ },
+ };
+}
+
+export default async function MangaDetailPage({ params }: Props) {
+ const { slug } = await params;
+
+ const manga = await prisma.manga.findUnique({
+ where: { slug },
+ include: {
+ chapters: {
+ orderBy: { number: "asc" },
+ },
+ },
+ });
+
+ if (!manga) notFound();
+
+ return (
+
+ {/* Hero section */}
+
+
+
+

+
+
+
+
+ {manga.title}
+
+
+
+ {manga.genre}
+
+
+ {manga.status}
+
+
+ {manga.chapters.length} chapter
+ {manga.chapters.length !== 1 ? "s" : ""}
+
+
+
+ {manga.description}
+
+
+
+
+ {/* Continue reading button */}
+ {manga.chapters.length > 0 && (
+
+ Start Reading — Ch. {manga.chapters[0].number}
+
+ )}
+
+ {/* Chapters */}
+
+
Chapters
+
+
+
+ );
+}
diff --git a/app/not-found.tsx b/app/not-found.tsx
new file mode 100644
index 0000000..bda837d
--- /dev/null
+++ b/app/not-found.tsx
@@ -0,0 +1,19 @@
+import Link from "next/link";
+
+export default function NotFound() {
+ return (
+
+
404
+
Page not found
+
+ The page you're looking for doesn't exist.
+
+
+ Back to Home
+
+
+ );
+}
diff --git a/app/page.tsx b/app/page.tsx
index 2dd076a..249938f 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,14 +1,29 @@
-export default function Home() {
+import { prisma } from "@/lib/db";
+import { TrendingCarousel } from "@/components/TrendingCarousel";
+import { GenreTabs } from "@/components/GenreTabs";
+
+export const dynamic = "force-dynamic";
+
+export default async function Home() {
+ const manga = await prisma.manga.findMany({
+ where: { status: "PUBLISHED" },
+ orderBy: { updatedAt: "desc" },
+ include: { _count: { select: { chapters: true } } },
+ });
+
+ // Top 10 for trending
+ const trending = manga.slice(0, 10);
+
+ // Extract unique genres
+ const genres = [...new Set(manga.map((m) => m.genre))].sort();
+
return (
-
-
-
- SunnyMH Manga
-
-
- Hello World — Coming Soon
-
-
+
+ {/* Trending section — Webtoon-style ranked carousel */}
+
+
+ {/* Genre browsing section — horizontal tabs + filtered grid */}
+
);
}
diff --git a/app/search/page.tsx b/app/search/page.tsx
new file mode 100644
index 0000000..6e704b6
--- /dev/null
+++ b/app/search/page.tsx
@@ -0,0 +1,41 @@
+import { prisma } from "@/lib/db";
+import { MangaGrid } from "@/components/MangaGrid";
+import type { Metadata } from "next";
+
+export const metadata: Metadata = {
+ title: "Search",
+};
+
+type Props = {
+ searchParams: Promise<{ q?: string }>;
+};
+
+export default async function SearchPage({ searchParams }: Props) {
+ const { q } = await searchParams;
+
+ const manga = q
+ ? await prisma.manga.findMany({
+ where: {
+ status: "PUBLISHED",
+ title: { contains: q, mode: "insensitive" },
+ },
+ orderBy: { title: "asc" },
+ include: { _count: { select: { chapters: true } } },
+ })
+ : [];
+
+ return (
+
+
+ {q ? `Results for "${q}"` : "Search"}
+
+ {q ? (
+
+ ) : (
+
+ Use the search bar above to find manga
+
+ )}
+
+ );
+}
diff --git a/app/sitemap.ts b/app/sitemap.ts
new file mode 100644
index 0000000..e6839e6
--- /dev/null
+++ b/app/sitemap.ts
@@ -0,0 +1,28 @@
+import type { MetadataRoute } from "next";
+import { prisma } from "@/lib/db";
+
+export const dynamic = "force-dynamic";
+
+export default async function sitemap(): Promise
{
+ const manga = await prisma.manga.findMany({
+ where: { status: "PUBLISHED" },
+ select: { slug: true, updatedAt: true },
+ });
+
+ const mangaEntries: MetadataRoute.Sitemap = manga.map((m) => ({
+ url: `https://manga.04080616.xyz/manga/${m.slug}`,
+ lastModified: m.updatedAt,
+ changeFrequency: "weekly",
+ priority: 0.8,
+ }));
+
+ return [
+ {
+ url: "https://manga.04080616.xyz",
+ lastModified: new Date(),
+ changeFrequency: "daily",
+ priority: 1,
+ },
+ ...mangaEntries,
+ ];
+}
diff --git a/components/BottomNav.tsx b/components/BottomNav.tsx
new file mode 100644
index 0000000..acb4bfe
--- /dev/null
+++ b/components/BottomNav.tsx
@@ -0,0 +1,73 @@
+"use client";
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+
+const navItems = [
+ {
+ href: "/",
+ label: "Home",
+ icon: (active: boolean) => (
+
+ ),
+ },
+ {
+ href: "/genre",
+ label: "Genres",
+ icon: (active: boolean) => (
+
+ ),
+ },
+ {
+ href: "/search",
+ label: "Search",
+ icon: (active: boolean) => (
+
+ ),
+ },
+];
+
+export function BottomNav() {
+ const pathname = usePathname();
+
+ // Hide bottom nav on chapter reader for immersive reading
+ if (pathname.match(/^\/manga\/[^/]+\/\d+$/)) {
+ return null;
+ }
+
+ return (
+
+ );
+}
diff --git a/components/ChapterList.tsx b/components/ChapterList.tsx
new file mode 100644
index 0000000..1853b0d
--- /dev/null
+++ b/components/ChapterList.tsx
@@ -0,0 +1,49 @@
+import Link from "next/link";
+
+type Chapter = {
+ id: number;
+ number: number;
+ title: string;
+};
+
+export function ChapterList({
+ chapters,
+ mangaSlug,
+}: {
+ chapters: Chapter[];
+ mangaSlug: string;
+}) {
+ if (chapters.length === 0) {
+ return (
+ No chapters available yet
+ );
+ }
+
+ return (
+
+ {chapters.map((ch) => (
+
+
+
+ #{ch.number}
+
+ {ch.title}
+
+
+
+ ))}
+
+ );
+}
diff --git a/components/GenreTabs.tsx b/components/GenreTabs.tsx
new file mode 100644
index 0000000..598a7a8
--- /dev/null
+++ b/components/GenreTabs.tsx
@@ -0,0 +1,100 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+
+type MangaItem = {
+ slug: string;
+ title: string;
+ coverUrl: string;
+ genre: string;
+ _count?: { chapters: number };
+};
+
+export function GenreTabs({
+ manga,
+ genres,
+}: {
+ manga: MangaItem[];
+ genres: string[];
+}) {
+ const [activeGenre, setActiveGenre] = useState("All");
+ const allGenres = ["All", ...genres];
+
+ const filtered =
+ activeGenre === "All"
+ ? manga
+ : manga.filter((m) => m.genre === activeGenre);
+
+ return (
+
+ {/* Section header */}
+
+
+
Browse by Genre
+
+
+ {/* Horizontal scrollable genre tabs */}
+
+ {allGenres.map((genre) => (
+
+ ))}
+
+
+ {/* Filtered manga grid */}
+ {filtered.length > 0 ? (
+
+ {filtered.map((m) => (
+
+
+

+
+ {m._count && m._count.chapters > 0 && (
+
+ {m._count.chapters} ch
+
+ )}
+
+
+ {m.title}
+
+
{m.genre}
+
+
+
+ ))}
+
+ ) : (
+
+ No manga in this genre yet
+
+ )}
+
+ );
+}
diff --git a/components/Header.tsx b/components/Header.tsx
new file mode 100644
index 0000000..4951e33
--- /dev/null
+++ b/components/Header.tsx
@@ -0,0 +1,69 @@
+"use client";
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import { SearchBar } from "./SearchBar";
+
+const navLinks = [
+ { href: "/", label: "Home" },
+ { href: "/genre", label: "Genres" },
+];
+
+export function Header() {
+ const pathname = usePathname();
+
+ // Hide header on chapter reader for immersive reading
+ if (pathname.match(/^\/manga\/[^/]+\/\d+$/)) {
+ return null;
+ }
+
+ return (
+
+ );
+}
diff --git a/components/MangaCard.tsx b/components/MangaCard.tsx
new file mode 100644
index 0000000..b6af6f9
--- /dev/null
+++ b/components/MangaCard.tsx
@@ -0,0 +1,39 @@
+import Link from "next/link";
+
+type MangaCardProps = {
+ slug: string;
+ title: string;
+ coverUrl: string;
+ chapterCount?: number;
+};
+
+export function MangaCard({
+ slug,
+ title,
+ coverUrl,
+ chapterCount,
+}: MangaCardProps) {
+ return (
+
+
+

+
+ {chapterCount !== undefined && (
+
+ {chapterCount} ch
+
+ )}
+
+
+ {title}
+
+
+
+
+ );
+}
diff --git a/components/MangaGrid.tsx b/components/MangaGrid.tsx
new file mode 100644
index 0000000..d31a284
--- /dev/null
+++ b/components/MangaGrid.tsx
@@ -0,0 +1,44 @@
+import { MangaCard } from "./MangaCard";
+
+type Manga = {
+ slug: string;
+ title: string;
+ coverUrl: string;
+ _count?: { chapters: number };
+};
+
+export function MangaGrid({ manga }: { manga: Manga[] }) {
+ if (manga.length === 0) {
+ return (
+
+
+
No manga yet
+
+ Check back soon for new titles
+
+
+ );
+ }
+
+ return (
+
+ {manga.map((m) => (
+
+ ))}
+
+ );
+}
diff --git a/components/PageReader.tsx b/components/PageReader.tsx
new file mode 100644
index 0000000..d8268c1
--- /dev/null
+++ b/components/PageReader.tsx
@@ -0,0 +1,140 @@
+"use client";
+
+import { useState } from "react";
+import Link from "next/link";
+
+type PageData = {
+ number: number;
+ imageUrl: string;
+};
+
+type PageReaderProps = {
+ pages: PageData[];
+ mangaSlug: string;
+ mangaTitle: string;
+ chapterNumber: number;
+ chapterTitle: string;
+ prevChapter: number | null;
+ nextChapter: number | null;
+};
+
+export function PageReader({
+ pages,
+ mangaSlug,
+ mangaTitle,
+ chapterNumber,
+ chapterTitle,
+ prevChapter,
+ nextChapter,
+}: PageReaderProps) {
+ const [showUI, setShowUI] = useState(true);
+
+ return (
+
+ {/* Top bar */}
+
+
+
+
+
+
+
+ {mangaTitle}
+
+
+ Ch. {chapterNumber} — {chapterTitle}
+
+
+
+
+
+ {/* Pages - vertical scroll (webtoon style, best for mobile) */}
+
setShowUI(!showUI)}
+ >
+ {pages.map((page) => (
+
+

+
+ ))}
+
+
+ {/* Bottom navigation */}
+
+
+ {prevChapter ? (
+
+
+ Prev
+
+ ) : (
+
+ )}
+
+ {pages.length} pages
+
+ {nextChapter ? (
+
+ Next
+
+
+ ) : (
+
+ Done
+
+ )}
+
+
+
+ );
+}
diff --git a/components/SearchBar.tsx b/components/SearchBar.tsx
new file mode 100644
index 0000000..7953026
--- /dev/null
+++ b/components/SearchBar.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import { useState, useRef, useEffect } from "react";
+import Link from "next/link";
+
+type SearchResult = {
+ id: number;
+ title: string;
+ slug: string;
+ coverUrl: string;
+};
+
+export function SearchBar() {
+ const [query, setQuery] = useState("");
+ const [results, setResults] = useState([]);
+ const [open, setOpen] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const ref = useRef(null);
+ const debounceRef = useRef>(null);
+
+ useEffect(() => {
+ function handleClickOutside(e: MouseEvent) {
+ if (ref.current && !ref.current.contains(e.target as Node)) {
+ setOpen(false);
+ }
+ }
+ document.addEventListener("mousedown", handleClickOutside);
+ return () => document.removeEventListener("mousedown", handleClickOutside);
+ }, []);
+
+ function handleSearch(value: string) {
+ setQuery(value);
+ if (debounceRef.current) clearTimeout(debounceRef.current);
+ if (value.trim().length < 2) {
+ setResults([]);
+ setOpen(false);
+ return;
+ }
+ setLoading(true);
+ debounceRef.current = setTimeout(async () => {
+ try {
+ const res = await fetch(
+ `/api/search?q=${encodeURIComponent(value.trim())}`
+ );
+ const data = await res.json();
+ setResults(data);
+ setOpen(true);
+ } catch {
+ setResults([]);
+ } finally {
+ setLoading(false);
+ }
+ }, 300);
+ }
+
+ return (
+
+
+
+
handleSearch(e.target.value)}
+ onFocus={() => results.length > 0 && setOpen(true)}
+ placeholder="Search manga..."
+ className="w-full pl-10 pr-4 py-2 text-sm bg-surface border border-border rounded-xl focus:outline-none focus:border-accent focus:ring-1 focus:ring-accent placeholder:text-muted transition-colors"
+ />
+ {loading && (
+
+ )}
+
+
+ {open && results.length > 0 && (
+
+ {results.map((manga) => (
+
{
+ setOpen(false);
+ setQuery("");
+ }}
+ className="flex items-center gap-3 px-4 py-3 hover:bg-surface-hover transition-colors"
+ >
+

+
+ {manga.title}
+
+
+ ))}
+
+ )}
+
+ {open && query.trim().length >= 2 && results.length === 0 && !loading && (
+
+ )}
+
+ );
+}
diff --git a/components/TrendingCarousel.tsx b/components/TrendingCarousel.tsx
new file mode 100644
index 0000000..20bba87
--- /dev/null
+++ b/components/TrendingCarousel.tsx
@@ -0,0 +1,158 @@
+"use client";
+
+import { useRef, useState, useEffect, useCallback } from "react";
+import Link from "next/link";
+
+type TrendingManga = {
+ slug: string;
+ title: string;
+ coverUrl: string;
+ genre: string;
+};
+
+function RankNumber({ rank }: { rank: number }) {
+ // Webtoon-style large rank number
+ const colors =
+ rank === 1
+ ? "text-yellow-400"
+ : rank === 2
+ ? "text-slate-300"
+ : rank === 3
+ ? "text-amber-600"
+ : "text-white/70";
+
+ return (
+
+ {rank}
+
+ );
+}
+
+export function TrendingCarousel({ manga }: { manga: TrendingManga[] }) {
+ const scrollRef = useRef(null);
+ const [canScrollLeft, setCanScrollLeft] = useState(false);
+ const [canScrollRight, setCanScrollRight] = useState(true);
+
+ const checkScroll = useCallback(() => {
+ const el = scrollRef.current;
+ if (!el) return;
+ setCanScrollLeft(el.scrollLeft > 4);
+ setCanScrollRight(el.scrollLeft < el.scrollWidth - el.clientWidth - 4);
+ }, []);
+
+ useEffect(() => {
+ const el = scrollRef.current;
+ if (!el) return;
+ checkScroll();
+ el.addEventListener("scroll", checkScroll, { passive: true });
+ window.addEventListener("resize", checkScroll);
+ return () => {
+ el.removeEventListener("scroll", checkScroll);
+ window.removeEventListener("resize", checkScroll);
+ };
+ }, [checkScroll]);
+
+ function scroll(direction: "left" | "right") {
+ const el = scrollRef.current;
+ if (!el) return;
+ const amount = el.clientWidth * 0.8;
+ el.scrollBy({
+ left: direction === "left" ? -amount : amount,
+ behavior: "smooth",
+ });
+ }
+
+ if (manga.length === 0) return null;
+
+ return (
+
+ {/* Section header */}
+
+
+
+ {/* Desktop carousel arrows */}
+
+
+
+
+
+
+ {/* Carousel track */}
+
+ {manga.map((m, i) => (
+
+
+

+ {/* Gradient overlay */}
+
+
+ {/* Rank number - bottom left, Webtoon style */}
+
+
+
+
+
+ {m.title}
+
+
+ {m.genre}
+
+
+
+
+
+
+ ))}
+
+
+ {/* Mobile edge fades */}
+ {canScrollRight && (
+
+ )}
+
+ );
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index 89a4884..3133333 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,6 +17,8 @@ services:
manga-db:
image: postgres:16
+ ports:
+ - "5433:5432"
volumes:
- manga_pgdata:/var/lib/postgresql/data
environment:
diff --git a/lib/db.ts b/lib/db.ts
new file mode 100644
index 0000000..0426feb
--- /dev/null
+++ b/lib/db.ts
@@ -0,0 +1,7 @@
+import { PrismaClient } from "@prisma/client";
+
+const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
+
+export const prisma = globalForPrisma.prisma || new PrismaClient();
+
+if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
diff --git a/lib/r2.ts b/lib/r2.ts
new file mode 100644
index 0000000..a619f11
--- /dev/null
+++ b/lib/r2.ts
@@ -0,0 +1,24 @@
+import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
+import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
+
+const s3 = new S3Client({
+ region: "auto",
+ endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
+ credentials: {
+ accessKeyId: process.env.R2_ACCESS_KEY!,
+ secretAccessKey: process.env.R2_SECRET_KEY!,
+ },
+});
+
+export async function getPresignedUploadUrl(key: string) {
+ const command = new PutObjectCommand({
+ Bucket: process.env.R2_BUCKET!,
+ Key: key,
+ ContentType: "image/webp",
+ });
+ return getSignedUrl(s3, command, { expiresIn: 3600 });
+}
+
+export function getPublicUrl(key: string) {
+ return `${process.env.R2_PUBLIC_URL}/${key}`;
+}
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..b49e030 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,18 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "*.r2.dev",
+ },
+ {
+ protocol: "https",
+ hostname: "*.cloudflarestorage.com",
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
index cfcf2af..45e1bfb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,11 @@
"name": "manga-site",
"version": "0.1.0",
"dependencies": {
+ "@aws-sdk/client-s3": "^3.1015.0",
+ "@aws-sdk/s3-request-presigner": "^3.1015.0",
+ "@prisma/client": "^6.19.2",
"next": "16.2.1",
+ "prisma": "^6.19.2",
"react": "19.2.4",
"react-dom": "19.2.4"
},
@@ -20,6 +24,7 @@
"eslint": "^9",
"eslint-config-next": "16.2.1",
"tailwindcss": "^4",
+ "tsx": "^4.21.0",
"typescript": "^5"
}
},
@@ -36,6 +41,891 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@aws-crypto/crc32": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
+ "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/crc32c": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz",
+ "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/sha1-browser": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz",
+ "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/supports-web-crypto": "^5.2.0",
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "@aws-sdk/util-locate-window": "^3.0.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
+ "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/sha256-js": "^5.2.0",
+ "@aws-crypto/supports-web-crypto": "^5.2.0",
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "@aws-sdk/util-locate-window": "^3.0.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
+ "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/supports-web-crypto": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
+ "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
+ "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.222.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/client-s3": {
+ "version": "3.1015.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1015.0.tgz",
+ "integrity": "sha512-yo+Y+/fq5/E684SynTRO+VA3a+98MeE/hs7J52XpNI5SchOCSrLhLtcDKVASlGhHQdNLGLzblRgps1OZaf8sbA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/sha1-browser": "5.2.0",
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/credential-provider-node": "^3.972.25",
+ "@aws-sdk/middleware-bucket-endpoint": "^3.972.8",
+ "@aws-sdk/middleware-expect-continue": "^3.972.8",
+ "@aws-sdk/middleware-flexible-checksums": "^3.974.4",
+ "@aws-sdk/middleware-host-header": "^3.972.8",
+ "@aws-sdk/middleware-location-constraint": "^3.972.8",
+ "@aws-sdk/middleware-logger": "^3.972.8",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.8",
+ "@aws-sdk/middleware-sdk-s3": "^3.972.24",
+ "@aws-sdk/middleware-ssec": "^3.972.8",
+ "@aws-sdk/middleware-user-agent": "^3.972.25",
+ "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.12",
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/util-endpoints": "^3.996.5",
+ "@aws-sdk/util-user-agent-browser": "^3.972.8",
+ "@aws-sdk/util-user-agent-node": "^3.973.11",
+ "@smithy/config-resolver": "^4.4.13",
+ "@smithy/core": "^3.23.12",
+ "@smithy/eventstream-serde-browser": "^4.2.12",
+ "@smithy/eventstream-serde-config-resolver": "^4.3.12",
+ "@smithy/eventstream-serde-node": "^4.2.12",
+ "@smithy/fetch-http-handler": "^5.3.15",
+ "@smithy/hash-blob-browser": "^4.2.13",
+ "@smithy/hash-node": "^4.2.12",
+ "@smithy/hash-stream-node": "^4.2.12",
+ "@smithy/invalid-dependency": "^4.2.12",
+ "@smithy/md5-js": "^4.2.12",
+ "@smithy/middleware-content-length": "^4.2.12",
+ "@smithy/middleware-endpoint": "^4.4.27",
+ "@smithy/middleware-retry": "^4.4.44",
+ "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-stack": "^4.2.12",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/url-parser": "^4.2.12",
+ "@smithy/util-base64": "^4.3.2",
+ "@smithy/util-body-length-browser": "^4.2.2",
+ "@smithy/util-body-length-node": "^4.2.3",
+ "@smithy/util-defaults-mode-browser": "^4.3.43",
+ "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-endpoints": "^3.3.3",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-retry": "^4.2.12",
+ "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-utf8": "^4.2.2",
+ "@smithy/util-waiter": "^4.2.13",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/core": {
+ "version": "3.973.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.24.tgz",
+ "integrity": "sha512-vvf82RYQu2GidWAuQq+uIzaPz9V0gSCXVqdVzRosgl5rXcspXOpSD3wFreGGW6AYymPr97Z69kjVnLePBxloDw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/xml-builder": "^3.972.15",
+ "@smithy/core": "^3.23.12",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/signature-v4": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-base64": "^4.3.2",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/crc64-nvme": {
+ "version": "3.972.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.5.tgz",
+ "integrity": "sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-env": {
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.22.tgz",
+ "integrity": "sha512-cXp0VTDWT76p3hyK5D51yIKEfpf6/zsUvMfaB8CkyqadJxMQ8SbEeVroregmDlZbtG31wkj9ei0WnftmieggLg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-http": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.24.tgz",
+ "integrity": "sha512-h694K7+tRuepSRJr09wTvQfaEnjzsKZ5s7fbESrVds02GT/QzViJ94/HCNwM7bUfFxqpPXHxulZfL6Cou0dwPg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/fetch-http-handler": "^5.3.15",
+ "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-stream": "^4.5.20",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-ini": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.24.tgz",
+ "integrity": "sha512-O46fFmv0RDFWiWEA9/e6oW92BnsyAXuEgTTasxHligjn2RCr9L/DK773m/NoFaL3ZdNAUz8WxgxunleMnHAkeQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/credential-provider-env": "^3.972.22",
+ "@aws-sdk/credential-provider-http": "^3.972.24",
+ "@aws-sdk/credential-provider-login": "^3.972.24",
+ "@aws-sdk/credential-provider-process": "^3.972.22",
+ "@aws-sdk/credential-provider-sso": "^3.972.24",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.24",
+ "@aws-sdk/nested-clients": "^3.996.14",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/credential-provider-imds": "^4.2.12",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-login": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.24.tgz",
+ "integrity": "sha512-sIk8oa6AzDoUhxsR11svZESqvzGuXesw62Rl2oW6wguZx8i9cdGCvkFg+h5K7iucUZP8wyWibUbJMc+J66cu5g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/nested-clients": "^3.996.14",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-node": {
+ "version": "3.972.25",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.25.tgz",
+ "integrity": "sha512-m7dR0Dsva2P+VUpL+VkC0WwiDby5pgmWXkRVDB5rlwv0jXJrQJf7YMtCoM8Wjk0H9jPeCYOxOXXcIgp/qp5Alg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/credential-provider-env": "^3.972.22",
+ "@aws-sdk/credential-provider-http": "^3.972.24",
+ "@aws-sdk/credential-provider-ini": "^3.972.24",
+ "@aws-sdk/credential-provider-process": "^3.972.22",
+ "@aws-sdk/credential-provider-sso": "^3.972.24",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/credential-provider-imds": "^4.2.12",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-process": {
+ "version": "3.972.22",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.22.tgz",
+ "integrity": "sha512-Os32s8/4gTZjBk5BtoS/cuTILaj+K72d0dVG7TCJX/fC4598cxwLDmf1AEHEpER5oL3K//yETjvFaz0V8oO5Xw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-sso": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.24.tgz",
+ "integrity": "sha512-PaFv7snEfypU2yXkpvfyWgddEbDLtgVe51wdZlinhc2doubBjUzJZZpgwuF2Jenl1FBydMhNpMjD6SBUM3qdSA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/nested-clients": "^3.996.14",
+ "@aws-sdk/token-providers": "3.1015.0",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-web-identity": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.24.tgz",
+ "integrity": "sha512-J6H4R1nvr3uBTqD/EeIPAskrBtET4WFfNhpFySr2xW7bVZOXpQfPjrLSIx65jcNjBmLXzWq8QFLdVoGxiGG/SA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/nested-clients": "^3.996.14",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-bucket-endpoint": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.8.tgz",
+ "integrity": "sha512-WR525Rr2QJSETa9a050isktyWi/4yIGcmY3BQ1kpHqb0LqUglQHCS8R27dTJxxWNZvQ0RVGtEZjTCbZJpyF3Aw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/util-arn-parser": "^3.972.3",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-config-provider": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-expect-continue": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.8.tgz",
+ "integrity": "sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-flexible-checksums": {
+ "version": "3.974.4",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.4.tgz",
+ "integrity": "sha512-fhCbZXPAyy8btnNbnBlR7Cc1nD54cETSvGn2wey71ehsM89AKPO8Dpco9DBAAgvrUdLrdHQepBXcyX4vxC5OwA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/crc32": "5.2.0",
+ "@aws-crypto/crc32c": "5.2.0",
+ "@aws-crypto/util": "5.2.0",
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/crc64-nvme": "^3.972.5",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/is-array-buffer": "^4.2.2",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-host-header": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.8.tgz",
+ "integrity": "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-location-constraint": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.8.tgz",
+ "integrity": "sha512-KaUoFuoFPziIa98DSQsTPeke1gvGXlc5ZGMhy+b+nLxZ4A7jmJgLzjEF95l8aOQN2T/qlPP3MrAyELm8ExXucw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-logger": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.8.tgz",
+ "integrity": "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-recursion-detection": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.8.tgz",
+ "integrity": "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@aws/lambda-invoke-store": "^0.2.2",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-sdk-s3": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.24.tgz",
+ "integrity": "sha512-4sXxVC/enYgMkZefNMOzU6C6KtAXEvwVJLgNcUx1dvROH6GvKB5Sm2RGnGzTp0/PwkibIyMw4kOzF8tbLfaBAQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/util-arn-parser": "^3.972.3",
+ "@smithy/core": "^3.23.12",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/signature-v4": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-config-provider": "^4.2.2",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-ssec": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.8.tgz",
+ "integrity": "sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/middleware-user-agent": {
+ "version": "3.972.25",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.25.tgz",
+ "integrity": "sha512-QxiMPofvOt8SwSynTOmuZfvvPM1S9QfkESBxB22NMHTRXCJhR5BygLl8IXfC4jELiisQgwsgUby21GtXfX3f/g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/util-endpoints": "^3.996.5",
+ "@smithy/core": "^3.23.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-retry": "^4.2.12",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/nested-clients": {
+ "version": "3.996.14",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.14.tgz",
+ "integrity": "sha512-fSESKvh1VbfjtV3QMnRkCPZWkUbQof6T/DOpiLp33yP2wA+rbwwnZeG3XT3Ekljgw2I8X4XaQPnw+zSR8yxJ5Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/middleware-host-header": "^3.972.8",
+ "@aws-sdk/middleware-logger": "^3.972.8",
+ "@aws-sdk/middleware-recursion-detection": "^3.972.8",
+ "@aws-sdk/middleware-user-agent": "^3.972.25",
+ "@aws-sdk/region-config-resolver": "^3.972.9",
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/util-endpoints": "^3.996.5",
+ "@aws-sdk/util-user-agent-browser": "^3.972.8",
+ "@aws-sdk/util-user-agent-node": "^3.973.11",
+ "@smithy/config-resolver": "^4.4.13",
+ "@smithy/core": "^3.23.12",
+ "@smithy/fetch-http-handler": "^5.3.15",
+ "@smithy/hash-node": "^4.2.12",
+ "@smithy/invalid-dependency": "^4.2.12",
+ "@smithy/middleware-content-length": "^4.2.12",
+ "@smithy/middleware-endpoint": "^4.4.27",
+ "@smithy/middleware-retry": "^4.4.44",
+ "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/middleware-stack": "^4.2.12",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/url-parser": "^4.2.12",
+ "@smithy/util-base64": "^4.3.2",
+ "@smithy/util-body-length-browser": "^4.2.2",
+ "@smithy/util-body-length-node": "^4.2.3",
+ "@smithy/util-defaults-mode-browser": "^4.3.43",
+ "@smithy/util-defaults-mode-node": "^4.2.47",
+ "@smithy/util-endpoints": "^3.3.3",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-retry": "^4.2.12",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/region-config-resolver": {
+ "version": "3.972.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.9.tgz",
+ "integrity": "sha512-eQ+dFU05ZRC/lC2XpYlYSPlXtX3VT8sn5toxN2Fv7EXlMoA2p9V7vUBKqHunfD4TRLpxUq8Y8Ol/nCqiv327Ng==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/config-resolver": "^4.4.13",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/s3-request-presigner": {
+ "version": "3.1015.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1015.0.tgz",
+ "integrity": "sha512-N8Axxt3VNXPPnujakUfwm5SvyoE+4dqeIdfPr2EXLgV8vruerHuH9fb9/Dr1lGYeaRjM161ye2d3Ko4TB7oZLg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/signature-v4-multi-region": "^3.996.12",
+ "@aws-sdk/types": "^3.973.6",
+ "@aws-sdk/util-format-url": "^3.972.8",
+ "@smithy/middleware-endpoint": "^4.4.27",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/signature-v4-multi-region": {
+ "version": "3.996.12",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.12.tgz",
+ "integrity": "sha512-abRObSqjVeKUUHIZfAp78PTYrEsxCgVKDs/YET357pzT5C02eDDEvmWyeEC2wglWcYC4UTbBFk22gd2YJUlCQg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/middleware-sdk-s3": "^3.972.24",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/signature-v4": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/token-providers": {
+ "version": "3.1015.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1015.0.tgz",
+ "integrity": "sha512-3OSD4y110nisRhHzFOjoEeHU4GQL4KpzkX9PxzWaiZe0Yg2+thZKM0Pn9DjYwezH5JYfh/K++xK/SE0IHGrmCQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "^3.973.24",
+ "@aws-sdk/nested-clients": "^3.996.14",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/types": {
+ "version": "3.973.6",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.6.tgz",
+ "integrity": "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/util-arn-parser": {
+ "version": "3.972.3",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz",
+ "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/util-endpoints": {
+ "version": "3.996.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.5.tgz",
+ "integrity": "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/types": "^4.13.1",
+ "@smithy/url-parser": "^4.2.12",
+ "@smithy/util-endpoints": "^3.3.3",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/util-format-url": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.8.tgz",
+ "integrity": "sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/querystring-builder": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/util-locate-window": {
+ "version": "3.965.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz",
+ "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/util-user-agent-browser": {
+ "version": "3.972.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.8.tgz",
+ "integrity": "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/types": "^4.13.1",
+ "bowser": "^2.11.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-sdk/util-user-agent-node": {
+ "version": "3.973.11",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.11.tgz",
+ "integrity": "sha512-1qdXbXo2s5MMLpUvw00284LsbhtlQ4ul7Zzdn5n+7p4WVgCMLqhxImpHIrjSoc72E/fyc4Wq8dLtUld2Gsh+lA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/middleware-user-agent": "^3.972.25",
+ "@aws-sdk/types": "^3.973.6",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-config-provider": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "aws-crt": ">=1.0.0"
+ },
+ "peerDependenciesMeta": {
+ "aws-crt": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@aws-sdk/xml-builder": {
+ "version": "3.972.15",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.15.tgz",
+ "integrity": "sha512-PxMRlCFNiQnke9YR29vjFQwz4jq+6Q04rOVFeTDR2K7Qpv9h9FOWOxG+zJjageimYbWqE3bTuLjmryWHAWbvaA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "fast-xml-parser": "5.5.8",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@aws/lambda-invoke-store": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz",
+ "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
@@ -310,6 +1200,448 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz",
+ "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz",
+ "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz",
+ "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz",
+ "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz",
+ "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz",
+ "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz",
+ "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz",
+ "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz",
+ "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz",
+ "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz",
+ "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz",
+ "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz",
+ "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz",
+ "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz",
+ "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz",
+ "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz",
+ "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz",
+ "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz",
+ "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz",
+ "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz",
+ "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz",
+ "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz",
+ "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz",
+ "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz",
+ "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz",
+ "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
@@ -1227,6 +2559,85 @@
"node": ">=12.4.0"
}
},
+ "node_modules/@prisma/client": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.19.2.tgz",
+ "integrity": "sha512-gR2EMvfK/aTxsuooaDA32D8v+us/8AAet+C3J1cc04SW35FPdZYgLF+iN4NDLUgAaUGTKdAB0CYenu1TAgGdMg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "peerDependencies": {
+ "prisma": "*",
+ "typescript": ">=5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "prisma": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@prisma/config": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.2.tgz",
+ "integrity": "sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "c12": "3.1.0",
+ "deepmerge-ts": "7.1.5",
+ "effect": "3.18.4",
+ "empathic": "2.0.0"
+ }
+ },
+ "node_modules/@prisma/debug": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.2.tgz",
+ "integrity": "sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/engines": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.2.tgz",
+ "integrity": "sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "6.19.2",
+ "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7",
+ "@prisma/fetch-engine": "6.19.2",
+ "@prisma/get-platform": "6.19.2"
+ }
+ },
+ "node_modules/@prisma/engines-version": {
+ "version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7",
+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz",
+ "integrity": "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/fetch-engine": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.2.tgz",
+ "integrity": "sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "6.19.2",
+ "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7",
+ "@prisma/get-platform": "6.19.2"
+ }
+ },
+ "node_modules/@prisma/get-platform": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.2.tgz",
+ "integrity": "sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "6.19.2"
+ }
+ },
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@@ -1234,6 +2645,745 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@smithy/abort-controller": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.12.tgz",
+ "integrity": "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/chunked-blob-reader": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz",
+ "integrity": "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/chunked-blob-reader-native": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.3.tgz",
+ "integrity": "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-base64": "^4.3.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/config-resolver": {
+ "version": "4.4.13",
+ "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.13.tgz",
+ "integrity": "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-config-provider": "^4.2.2",
+ "@smithy/util-endpoints": "^3.3.3",
+ "@smithy/util-middleware": "^4.2.12",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/core": {
+ "version": "3.23.12",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.12.tgz",
+ "integrity": "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/url-parser": "^4.2.12",
+ "@smithy/util-base64": "^4.3.2",
+ "@smithy/util-body-length-browser": "^4.2.2",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-stream": "^4.5.20",
+ "@smithy/util-utf8": "^4.2.2",
+ "@smithy/uuid": "^1.1.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/credential-provider-imds": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.12.tgz",
+ "integrity": "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/url-parser": "^4.2.12",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/eventstream-codec": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.12.tgz",
+ "integrity": "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/crc32": "5.2.0",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-hex-encoding": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/eventstream-serde-browser": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.12.tgz",
+ "integrity": "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/eventstream-serde-universal": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/eventstream-serde-config-resolver": {
+ "version": "4.3.12",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.12.tgz",
+ "integrity": "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/eventstream-serde-node": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.12.tgz",
+ "integrity": "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/eventstream-serde-universal": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/eventstream-serde-universal": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.12.tgz",
+ "integrity": "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/eventstream-codec": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/fetch-http-handler": {
+ "version": "5.3.15",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.15.tgz",
+ "integrity": "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/querystring-builder": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-base64": "^4.3.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/hash-blob-browser": {
+ "version": "4.2.13",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.13.tgz",
+ "integrity": "sha512-YrF4zWKh+ghLuquldj6e/RzE3xZYL8wIPfkt0MqCRphVICjyyjH8OwKD7LLlKpVEbk4FLizFfC1+gwK6XQdR3g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/chunked-blob-reader": "^5.2.2",
+ "@smithy/chunked-blob-reader-native": "^4.2.3",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/hash-node": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.12.tgz",
+ "integrity": "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-buffer-from": "^4.2.2",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/hash-stream-node": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.12.tgz",
+ "integrity": "sha512-O3YbmGExeafuM/kP7Y8r6+1y0hIh3/zn6GROx0uNlB54K9oihAL75Qtc+jFfLNliTi6pxOAYZrRKD9A7iA6UFw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/invalid-dependency": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.12.tgz",
+ "integrity": "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/is-array-buffer": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz",
+ "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/md5-js": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.12.tgz",
+ "integrity": "sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/middleware-content-length": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.12.tgz",
+ "integrity": "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/middleware-endpoint": {
+ "version": "4.4.27",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.27.tgz",
+ "integrity": "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.23.12",
+ "@smithy/middleware-serde": "^4.2.15",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/url-parser": "^4.2.12",
+ "@smithy/util-middleware": "^4.2.12",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/middleware-retry": {
+ "version": "4.4.44",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.44.tgz",
+ "integrity": "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/service-error-classification": "^4.2.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-retry": "^4.2.12",
+ "@smithy/uuid": "^1.1.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/middleware-serde": {
+ "version": "4.2.15",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.15.tgz",
+ "integrity": "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.23.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/middleware-stack": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.12.tgz",
+ "integrity": "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/node-config-provider": {
+ "version": "4.3.12",
+ "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.12.tgz",
+ "integrity": "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/shared-ini-file-loader": "^4.4.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/node-http-handler": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.5.0.tgz",
+ "integrity": "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/abort-controller": "^4.2.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/querystring-builder": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/property-provider": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.12.tgz",
+ "integrity": "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/protocol-http": {
+ "version": "5.3.12",
+ "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.12.tgz",
+ "integrity": "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/querystring-builder": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.12.tgz",
+ "integrity": "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-uri-escape": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/querystring-parser": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.12.tgz",
+ "integrity": "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/service-error-classification": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.12.tgz",
+ "integrity": "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/shared-ini-file-loader": {
+ "version": "4.4.7",
+ "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.7.tgz",
+ "integrity": "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/signature-v4": {
+ "version": "5.3.12",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.12.tgz",
+ "integrity": "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^4.2.2",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-hex-encoding": "^4.2.2",
+ "@smithy/util-middleware": "^4.2.12",
+ "@smithy/util-uri-escape": "^4.2.2",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/smithy-client": {
+ "version": "4.12.7",
+ "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.7.tgz",
+ "integrity": "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/core": "^3.23.12",
+ "@smithy/middleware-endpoint": "^4.4.27",
+ "@smithy/middleware-stack": "^4.2.12",
+ "@smithy/protocol-http": "^5.3.12",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-stream": "^4.5.20",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/types": {
+ "version": "4.13.1",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.1.tgz",
+ "integrity": "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/url-parser": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.12.tgz",
+ "integrity": "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/querystring-parser": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-base64": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz",
+ "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^4.2.2",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-body-length-browser": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz",
+ "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-body-length-node": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz",
+ "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-buffer-from": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz",
+ "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-config-provider": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz",
+ "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-defaults-mode-browser": {
+ "version": "4.3.43",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.43.tgz",
+ "integrity": "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-defaults-mode-node": {
+ "version": "4.2.47",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.47.tgz",
+ "integrity": "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/config-resolver": "^4.4.13",
+ "@smithy/credential-provider-imds": "^4.2.12",
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/property-provider": "^4.2.12",
+ "@smithy/smithy-client": "^4.12.7",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-endpoints": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.3.tgz",
+ "integrity": "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/node-config-provider": "^4.3.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-hex-encoding": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz",
+ "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-middleware": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.12.tgz",
+ "integrity": "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-retry": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.12.tgz",
+ "integrity": "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/service-error-classification": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-stream": {
+ "version": "4.5.20",
+ "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.20.tgz",
+ "integrity": "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/fetch-http-handler": "^5.3.15",
+ "@smithy/node-http-handler": "^4.5.0",
+ "@smithy/types": "^4.13.1",
+ "@smithy/util-base64": "^4.3.2",
+ "@smithy/util-buffer-from": "^4.2.2",
+ "@smithy/util-hex-encoding": "^4.2.2",
+ "@smithy/util-utf8": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-uri-escape": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz",
+ "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-utf8": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz",
+ "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-waiter": {
+ "version": "4.2.13",
+ "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.13.tgz",
+ "integrity": "sha512-2zdZ9DTHngRtcYxJK1GUDxruNr53kv5W2Lupe0LMU+Imr6ohQg8M2T14MNkj1Y0wS3FFwpgpGQyvuaMF7CiTmQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/abort-controller": "^4.2.12",
+ "@smithy/types": "^4.13.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/uuid": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz",
+ "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@standard-schema/spec": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "license": "MIT"
+ },
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -2448,6 +4598,12 @@
"node": ">=6.0.0"
}
},
+ "node_modules/bowser": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
+ "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
+ "license": "MIT"
+ },
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
@@ -2507,6 +4663,34 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/c12": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz",
+ "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==",
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^4.0.3",
+ "confbox": "^0.2.2",
+ "defu": "^6.1.4",
+ "dotenv": "^16.6.1",
+ "exsolve": "^1.0.7",
+ "giget": "^2.0.0",
+ "jiti": "^2.4.2",
+ "ohash": "^2.0.11",
+ "pathe": "^2.0.3",
+ "perfect-debounce": "^1.0.0",
+ "pkg-types": "^2.2.0",
+ "rc9": "^2.1.2"
+ },
+ "peerDependencies": {
+ "magicast": "^0.3.5"
+ },
+ "peerDependenciesMeta": {
+ "magicast": {
+ "optional": true
+ }
+ }
+ },
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
@@ -2604,6 +4788,30 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/citty": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
+ "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==",
+ "license": "MIT",
+ "dependencies": {
+ "consola": "^3.2.3"
+ }
+ },
"node_modules/client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
@@ -2637,6 +4845,21 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/confbox": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
+ "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
+ "license": "MIT"
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -2752,6 +4975,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/deepmerge-ts": {
+ "version": "7.1.5",
+ "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz",
+ "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -2788,6 +5020,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/defu": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
+ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+ "license": "MIT"
+ },
+ "node_modules/destr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz",
+ "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==",
+ "license": "MIT"
+ },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -2811,6 +5055,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -2826,6 +5082,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/effect": {
+ "version": "3.18.4",
+ "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz",
+ "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==",
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "fast-check": "^3.23.1"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.322",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.322.tgz",
@@ -2840,6 +5106,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/empathic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
+ "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/enhanced-resolve": {
"version": "5.20.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
@@ -3032,6 +5307,48 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/esbuild": {
+ "version": "0.27.4",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz",
+ "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.4",
+ "@esbuild/android-arm": "0.27.4",
+ "@esbuild/android-arm64": "0.27.4",
+ "@esbuild/android-x64": "0.27.4",
+ "@esbuild/darwin-arm64": "0.27.4",
+ "@esbuild/darwin-x64": "0.27.4",
+ "@esbuild/freebsd-arm64": "0.27.4",
+ "@esbuild/freebsd-x64": "0.27.4",
+ "@esbuild/linux-arm": "0.27.4",
+ "@esbuild/linux-arm64": "0.27.4",
+ "@esbuild/linux-ia32": "0.27.4",
+ "@esbuild/linux-loong64": "0.27.4",
+ "@esbuild/linux-mips64el": "0.27.4",
+ "@esbuild/linux-ppc64": "0.27.4",
+ "@esbuild/linux-riscv64": "0.27.4",
+ "@esbuild/linux-s390x": "0.27.4",
+ "@esbuild/linux-x64": "0.27.4",
+ "@esbuild/netbsd-arm64": "0.27.4",
+ "@esbuild/netbsd-x64": "0.27.4",
+ "@esbuild/openbsd-arm64": "0.27.4",
+ "@esbuild/openbsd-x64": "0.27.4",
+ "@esbuild/openharmony-arm64": "0.27.4",
+ "@esbuild/sunos-x64": "0.27.4",
+ "@esbuild/win32-arm64": "0.27.4",
+ "@esbuild/win32-ia32": "0.27.4",
+ "@esbuild/win32-x64": "0.27.4"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -3247,6 +5564,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -3486,6 +5804,34 @@
"node": ">=0.10.0"
}
},
+ "node_modules/exsolve": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
+ "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
+ "license": "MIT"
+ },
+ "node_modules/fast-check": {
+ "version": "3.23.2",
+ "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz",
+ "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "pure-rand": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -3537,6 +5883,41 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-xml-builder": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
+ "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "path-expression-matcher": "^1.1.3"
+ }
+ },
+ "node_modules/fast-xml-parser": {
+ "version": "5.5.8",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz",
+ "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "fast-xml-builder": "^1.1.4",
+ "path-expression-matcher": "^1.2.0",
+ "strnum": "^2.2.0"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
"node_modules/fastq": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
@@ -3627,6 +6008,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -3758,6 +6154,23 @@
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
+ "node_modules/giget": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz",
+ "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==",
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.1.6",
+ "consola": "^3.4.0",
+ "defu": "^6.1.4",
+ "node-fetch-native": "^1.6.6",
+ "nypm": "^0.6.0",
+ "pathe": "^2.0.3"
+ },
+ "bin": {
+ "giget": "dist/cli.mjs"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -4435,7 +6848,6 @@
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
- "dev": true,
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
@@ -5090,6 +7502,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/node-fetch-native": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz",
+ "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==",
+ "license": "MIT"
+ },
"node_modules/node-releases": {
"version": "2.0.36",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
@@ -5097,6 +7515,29 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/nypm": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.5.tgz",
+ "integrity": "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.2.0",
+ "pathe": "^2.0.3",
+ "tinyexec": "^1.0.2"
+ },
+ "bin": {
+ "nypm": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/nypm/node_modules/citty": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.1.tgz",
+ "integrity": "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==",
+ "license": "MIT"
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -5220,6 +7661,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/ohash": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz",
+ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
+ "license": "MIT"
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -5311,6 +7758,21 @@
"node": ">=8"
}
},
+ "node_modules/path-expression-matcher": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz",
+ "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -5328,6 +7790,18 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "license": "MIT"
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "license": "MIT"
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -5347,6 +7821,17 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pkg-types": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
+ "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.2.2",
+ "exsolve": "^1.0.7",
+ "pathe": "^2.0.3"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -5396,6 +7881,32 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prisma": {
+ "version": "6.19.2",
+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.2.tgz",
+ "integrity": "sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@prisma/config": "6.19.2",
+ "@prisma/engines": "6.19.2"
+ },
+ "bin": {
+ "prisma": "build/index.js"
+ },
+ "engines": {
+ "node": ">=18.18"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -5418,6 +7929,22 @@
"node": ">=6"
}
},
+ "node_modules/pure-rand": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
+ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -5439,6 +7966,16 @@
],
"license": "MIT"
},
+ "node_modules/rc9": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz",
+ "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==",
+ "license": "MIT",
+ "dependencies": {
+ "defu": "^6.1.4",
+ "destr": "^2.0.3"
+ }
+ },
"node_modules/react": {
"version": "19.2.4",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
@@ -5469,6 +8006,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -6032,6 +8582,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strnum": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz",
+ "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/styled-jsx": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
@@ -6102,6 +8664,15 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/tinyexec": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz",
+ "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
@@ -6209,6 +8780,26 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
+ "node_modules/tsx": {
+ "version": "4.21.0",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
+ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.27.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -6304,7 +8895,7 @@
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
diff --git a/package.json b/package.json
index e3324e8..2b7b3e2 100644
--- a/package.json
+++ b/package.json
@@ -6,10 +6,18 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "eslint"
+ "lint": "eslint",
+ "seed": "npx tsx prisma/seed.ts"
+ },
+ "prisma": {
+ "seed": "npx tsx prisma/seed.ts"
},
"dependencies": {
+ "@aws-sdk/client-s3": "^3.1015.0",
+ "@aws-sdk/s3-request-presigner": "^3.1015.0",
+ "@prisma/client": "^6.19.2",
"next": "16.2.1",
+ "prisma": "^6.19.2",
"react": "19.2.4",
"react-dom": "19.2.4"
},
@@ -21,6 +29,7 @@
"eslint": "^9",
"eslint-config-next": "16.2.1",
"tailwindcss": "^4",
+ "tsx": "^4.21.0",
"typescript": "^5"
}
}
diff --git a/prisma/migrations/20260324150031_init/migration.sql b/prisma/migrations/20260324150031_init/migration.sql
new file mode 100644
index 0000000..c56872c
--- /dev/null
+++ b/prisma/migrations/20260324150031_init/migration.sql
@@ -0,0 +1,51 @@
+-- CreateEnum
+CREATE TYPE "Status" AS ENUM ('PUBLISHED', 'DRAFT');
+
+-- CreateTable
+CREATE TABLE "Manga" (
+ "id" SERIAL NOT NULL,
+ "title" TEXT NOT NULL,
+ "description" TEXT NOT NULL,
+ "coverUrl" TEXT NOT NULL,
+ "slug" TEXT NOT NULL,
+ "status" "Status" NOT NULL DEFAULT 'PUBLISHED',
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Manga_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Chapter" (
+ "id" SERIAL NOT NULL,
+ "mangaId" INTEGER NOT NULL,
+ "number" INTEGER NOT NULL,
+ "title" TEXT NOT NULL,
+
+ CONSTRAINT "Chapter_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Page" (
+ "id" SERIAL NOT NULL,
+ "chapterId" INTEGER NOT NULL,
+ "number" INTEGER NOT NULL,
+ "imageUrl" TEXT NOT NULL,
+
+ CONSTRAINT "Page_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Manga_slug_key" ON "Manga"("slug");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Chapter_mangaId_number_key" ON "Chapter"("mangaId", "number");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Page_chapterId_number_key" ON "Page"("chapterId", "number");
+
+-- AddForeignKey
+ALTER TABLE "Chapter" ADD CONSTRAINT "Chapter_mangaId_fkey" FOREIGN KEY ("mangaId") REFERENCES "Manga"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Page" ADD CONSTRAINT "Page_chapterId_fkey" FOREIGN KEY ("chapterId") REFERENCES "Chapter"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/prisma/migrations/20260325004730_add_genre/migration.sql b/prisma/migrations/20260325004730_add_genre/migration.sql
new file mode 100644
index 0000000..cc505ad
--- /dev/null
+++ b/prisma/migrations/20260325004730_add_genre/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "Manga" ADD COLUMN "genre" TEXT NOT NULL DEFAULT 'Drama';
diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml
new file mode 100644
index 0000000..044d57c
--- /dev/null
+++ b/prisma/migrations/migration_lock.toml
@@ -0,0 +1,3 @@
+# Please do not edit this file manually
+# It should be added in your version-control system (e.g., Git)
+provider = "postgresql"
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
new file mode 100644
index 0000000..b2a5059
--- /dev/null
+++ b/prisma/schema.prisma
@@ -0,0 +1,47 @@
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+model Manga {
+ id Int @id @default(autoincrement())
+ title String
+ description String
+ coverUrl String
+ slug String @unique
+ genre String @default("Drama")
+ status Status @default(PUBLISHED)
+ chapters Chapter[]
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+}
+
+model Chapter {
+ id Int @id @default(autoincrement())
+ mangaId Int
+ number Int
+ title String
+ pages Page[]
+ manga Manga @relation(fields: [mangaId], references: [id])
+
+ @@unique([mangaId, number])
+}
+
+model Page {
+ id Int @id @default(autoincrement())
+ chapterId Int
+ number Int
+ imageUrl String
+ chapter Chapter @relation(fields: [chapterId], references: [id])
+
+ @@unique([chapterId, number])
+}
+
+enum Status {
+ PUBLISHED
+ DRAFT
+}
diff --git a/prisma/seed.ts b/prisma/seed.ts
new file mode 100644
index 0000000..f878df7
--- /dev/null
+++ b/prisma/seed.ts
@@ -0,0 +1,118 @@
+import { PrismaClient } from "@prisma/client";
+
+const prisma = new PrismaClient();
+
+const mangaData = [
+ {
+ title: "Vice Versa",
+ slug: "vice-versa",
+ description:
+ "A tale of fate and desire intertwined. When two souls swap destinies, they discover the true meaning of living someone else's life.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20260129_96/1769683677999mNYO7_PNG/84__Thumb_Poster.png?type=q90",
+ genre: "Romance",
+ },
+ {
+ title: "Became a Sales Genius",
+ slug: "became-a-sales-genius",
+ description:
+ "Reborn with memories of his past life, a failed salesman returns to dominate the corporate world with knowledge no one else possesses.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20251105_137/1762317547495MfzIC_JPEG/Thumb_Poster.jpg?type=q90",
+ genre: "Drama",
+ },
+ {
+ title: "A Regressor's Tale of Cultivation",
+ slug: "regressors-tale-of-cultivation",
+ description:
+ "After countless regressions, a martial artist finally begins to unravel the deepest mysteries of cultivation and the heavenly dao.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20251114_103/1763091301425CY14H_JPEG/Thumb_Poster.jpg?type=q90",
+ genre: "Martial Arts",
+ },
+ {
+ title: "My Avatar's Path to Greatness",
+ slug: "my-avatars-path-to-greatness",
+ description:
+ "By splitting himself into multiple clones, one man sets out to conquer every path of power simultaneously.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20250425_176/1745558711155VySyE_JPEG/Thumb_Poster_7727.jpg?type=q90",
+ genre: "Fantasy",
+ },
+ {
+ title: "Sera",
+ slug: "sera",
+ description:
+ "The explosive school life of Gu Sera, a girl whose temper is as fierce as her sense of justice.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20250321_24/1742528056930xEbcJ_JPEG/Thumb_Poster.jpg?type=q90",
+ genre: "School",
+ },
+ {
+ title: "Revenge of the Real One",
+ slug: "revenge-of-the-real-one",
+ description:
+ "She was the true heiress all along. Now that the truth is out, it's time for the fake to pay.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20250811_6/1754909221289kEXyb_PNG/480x623.png?type=q90",
+ genre: "Fantasy",
+ },
+ {
+ title: "Kindergarten for Divine Beasts",
+ slug: "kindergarten-for-divine-beasts",
+ description:
+ "Running a daycare is hard enough. Running one for baby dragons, phoenixes, and ancient beasts? That's another story entirely.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20250613_186/1749801415006hU2Kf_JPEG/Thumb_Poster_8051.jpg?type=q90",
+ genre: "Fantasy",
+ },
+ {
+ title: "Dr. Kim of London",
+ slug: "dr-kim-of-london",
+ description:
+ "An Eastern medicine prodigy takes on the Western medical establishment in Victorian London.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20251016_11/1760587613431sbps4_JPEG/Thumb_Poster.jpg?type=q90",
+ genre: "Drama",
+ },
+ {
+ title: "The Returned C-Rank Tank Won't Die",
+ slug: "c-rank-tank-wont-die",
+ description:
+ "Everyone thought he was weak. But after returning from a dungeon break, this C-rank tank has become truly unkillable.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20250625_252/1750834745151JPG3l_JPEG/Thumb_Poster_8054.jpg?type=q90",
+ genre: "Fantasy",
+ },
+ {
+ title: "Violets Blooming in Garden",
+ slug: "violets-blooming-in-garden",
+ description:
+ "In the imperial court's most secluded garden, a quiet noblewoman hides secrets that could topple an empire.",
+ coverUrl:
+ "https://webtoon-phinf.pstatic.net/20250709_43/1752041143942ixO3h_PNG/垂直略縮圖480x623_Logo.png?type=q90",
+ genre: "Romance",
+ },
+];
+
+async function main() {
+ console.log("Seeding database...");
+
+ for (const data of mangaData) {
+ const manga = await prisma.manga.upsert({
+ where: { slug: data.slug },
+ update: data,
+ create: data,
+ });
+ console.log(` Upserted: ${manga.title} (id: ${manga.id})`);
+ }
+
+ console.log("Seed complete.");
+}
+
+main()
+ .catch((e) => {
+ console.error(e);
+ process.exit(1);
+ })
+ .finally(() => prisma.$disconnect());