From 74efcf3adaade5bae795eef663b47fe3cefe7064 Mon Sep 17 00:00:00 2001 From: EdwinRoy Date: Mon, 27 Jul 2026 08:31:07 -0600 Subject: [PATCH] initial deploy: Nova Store --- .dockerignore | 8 + .gitignore | 8 + Dockerfile | 13 + app/api/login/route.js | 21 + app/api/logout/route.js | 7 + app/api/me/route.js | 12 + app/api/register/route.js | 28 + app/components/AuthNav.js | 41 ++ app/components/ThemeToggle.js | 25 + app/globals.css | 77 ++ app/layout.js | 24 + app/lib/auth.js | 40 ++ app/lib/db.js | 27 + app/lib/products.js | 9 + app/login/page.js | 49 ++ app/page.js | 31 + app/product/[id]/page.js | 28 + app/register/page.js | 53 ++ app/template.js | 3 + next.config.js | 3 + package-lock.json | 1275 +++++++++++++++++++++++++++++++++ package.json | 7 + 22 files changed, 1789 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 app/api/login/route.js create mode 100644 app/api/logout/route.js create mode 100644 app/api/me/route.js create mode 100644 app/api/register/route.js create mode 100644 app/components/AuthNav.js create mode 100644 app/components/ThemeToggle.js create mode 100644 app/globals.css create mode 100644 app/layout.js create mode 100644 app/lib/auth.js create mode 100644 app/lib/db.js create mode 100644 app/lib/products.js create mode 100644 app/login/page.js create mode 100644 app/page.js create mode 100644 app/product/[id]/page.js create mode 100644 app/register/page.js create mode 100644 app/template.js create mode 100644 next.config.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6054294 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +node_modules +.next +.git +data +__nm_old +.nm_trash* +*.log +npm-debug.log* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f2873d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules +.next +data +__nm_old +.nm_trash* +*.log +npm-debug.log* +.DS_Store diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1f08b14 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM node:22-alpine +WORKDIR /app +# better-sqlite3 es un módulo nativo: en Alpine (musl) hay que compilarlo. +RUN apk add --no-cache python3 make g++ +COPY package.json ./ +RUN npm install +COPY . . +RUN npm run build +EXPOSE 3000 +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 +CMD ["npm", "start"] diff --git a/app/api/login/route.js b/app/api/login/route.js new file mode 100644 index 0000000..7857529 --- /dev/null +++ b/app/api/login/route.js @@ -0,0 +1,21 @@ +import { NextResponse } from "next/server"; +import db from "../../lib/db"; +import { verifyPassword, signSession } from "../../lib/auth"; + +export async function POST(req) { + let body; + try { body = await req.json(); } catch { return NextResponse.json({ error: "Solicitud inválida" }, { status: 400 }); } + + const email = (body.email || "").trim().toLowerCase(); + const password = body.password || ""; + + const user = db.prepare("SELECT * FROM users WHERE email = ?").get(email); + if (!user || !verifyPassword(password, user.password)) + return NextResponse.json({ error: "Email o contraseña incorrectos" }, { status: 401 }); + + const res = NextResponse.json({ ok: true, user: { id: user.id, name: user.name, email: user.email } }); + res.cookies.set("session", signSession(user.id), { + httpOnly: true, sameSite: "lax", path: "/", maxAge: 60 * 60 * 24 * 7, + }); + return res; +} diff --git a/app/api/logout/route.js b/app/api/logout/route.js new file mode 100644 index 0000000..f91ece0 --- /dev/null +++ b/app/api/logout/route.js @@ -0,0 +1,7 @@ +import { NextResponse } from "next/server"; + +export async function POST() { + const res = NextResponse.json({ ok: true }); + res.cookies.set("session", "", { httpOnly: true, path: "/", maxAge: 0 }); + return res; +} diff --git a/app/api/me/route.js b/app/api/me/route.js new file mode 100644 index 0000000..46c00cb --- /dev/null +++ b/app/api/me/route.js @@ -0,0 +1,12 @@ +import { NextResponse } from "next/server"; +import { cookies } from "next/headers"; +import db from "../../lib/db"; +import { readSession } from "../../lib/auth"; + +export async function GET() { + const store = await cookies(); + const id = readSession(store.get("session")?.value); + if (!id) return NextResponse.json({ user: null }); + const user = db.prepare("SELECT id, name, email FROM users WHERE id = ?").get(id); + return NextResponse.json({ user: user || null }); +} diff --git a/app/api/register/route.js b/app/api/register/route.js new file mode 100644 index 0000000..9e8fde7 --- /dev/null +++ b/app/api/register/route.js @@ -0,0 +1,28 @@ +import { NextResponse } from "next/server"; +import db from "../../lib/db"; +import { hashPassword, signSession } from "../../lib/auth"; + +export async function POST(req) { + let body; + try { body = await req.json(); } catch { return NextResponse.json({ error: "Solicitud inválida" }, { status: 400 }); } + + const name = (body.name || "").trim(); + const email = (body.email || "").trim().toLowerCase(); + const password = body.password || ""; + + if (!email || !password) return NextResponse.json({ error: "Email y contraseña son obligatorios" }, { status: 400 }); + if (password.length < 6) return NextResponse.json({ error: "La contraseña debe tener al menos 6 caracteres" }, { status: 400 }); + + try { + const info = db.prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)") + .run(name, email, hashPassword(password)); + const res = NextResponse.json({ ok: true, user: { id: Number(info.lastInsertRowid), name, email } }); + res.cookies.set("session", signSession(info.lastInsertRowid), { + httpOnly: true, sameSite: "lax", path: "/", maxAge: 60 * 60 * 24 * 7, + }); + return res; + } catch (e) { + if (String(e).includes("UNIQUE")) return NextResponse.json({ error: "Ese email ya está registrado" }, { status: 409 }); + return NextResponse.json({ error: "No se pudo crear la cuenta" }, { status: 500 }); + } +} diff --git a/app/components/AuthNav.js b/app/components/AuthNav.js new file mode 100644 index 0000000..0f3acb6 --- /dev/null +++ b/app/components/AuthNav.js @@ -0,0 +1,41 @@ +"use client"; +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; + +export default function AuthNav() { + const [user, setUser] = useState(null); + const [ready, setReady] = useState(false); + const router = useRouter(); + + useEffect(() => { + fetch("/api/me") + .then((r) => r.json()) + .then((d) => { setUser(d.user); setReady(true); }) + .catch(() => setReady(true)); + }, []); + + async function logout() { + await fetch("/api/logout", { method: "POST" }); + setUser(null); + router.refresh(); + } + + if (!ready) return null; + + if (user) { + return ( +
+ Hola, {user.name || user.email} + +
+ ); + } + + return ( +
+ Ingresar + Crear cuenta +
+ ); +} diff --git a/app/components/ThemeToggle.js b/app/components/ThemeToggle.js new file mode 100644 index 0000000..9e12253 --- /dev/null +++ b/app/components/ThemeToggle.js @@ -0,0 +1,25 @@ +"use client"; +import { useEffect, useState } from "react"; + +export default function ThemeToggle() { + const [theme, setTheme] = useState("dark"); + + useEffect(() => { + const saved = localStorage.getItem("theme") || "dark"; + setTheme(saved); + document.documentElement.setAttribute("data-theme", saved); + }, []); + + function toggle() { + const next = theme === "dark" ? "light" : "dark"; + setTheme(next); + document.documentElement.setAttribute("data-theme", next); + localStorage.setItem("theme", next); + } + + return ( + + ); +} diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..ec1a4cc --- /dev/null +++ b/app/globals.css @@ -0,0 +1,77 @@ +:root{--bg:#0a0b12;--card:#151827;--line:#232741;--text:#eef0f7;--muted:#9aa0b5;--accent:#8b5cf6;--accent2:#ec4899;--header-bg:rgba(10,11,18,.72)} +[data-theme="light"]{--bg:#f6f7fb;--card:#ffffff;--line:#e6e8f0;--text:#12141f;--muted:#5a6172;--accent:#7c3aed;--accent2:#db2777;--header-bg:rgba(255,255,255,.78)} +*{box-sizing:border-box;margin:0;padding:0} +html{scroll-behavior:smooth} +body{background:var(--bg);color:var(--text);font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased;transition:background .35s ease,color .35s ease} +a{color:inherit;text-decoration:none} +.container{max-width:1120px;margin:0 auto;padding:0 24px} +.header{position:sticky;top:0;z-index:50;display:flex;align-items:center;justify-content:space-between;padding:16px 24px;background:var(--header-bg);backdrop-filter:blur(12px);border-bottom:1px solid var(--line);transition:background .35s ease,border-color .35s ease} +.logo{font-weight:800;letter-spacing:.14em;font-size:18px;background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;color:transparent} +.header nav{display:flex;gap:22px} +.header nav a{color:var(--muted);font-size:14px;transition:color .2s} +.header nav a:hover{color:var(--text)} +.cart{background:var(--card);border:1px solid var(--line);color:var(--text);border-radius:999px;padding:8px 14px;font-size:14px;cursor:pointer;display:flex;gap:6px;align-items:center} +.cart span{background:var(--accent);border-radius:999px;padding:0 7px;font-size:12px} +.theme-toggle{background:var(--card);border:1px solid var(--line);color:var(--text);border-radius:999px;padding:8px 14px;font-size:13px;cursor:pointer;transition:background .2s,border-color .2s,transform .15s} +.theme-toggle:hover{border-color:var(--accent);transform:translateY(-1px)} +.auth-nav{display:flex;align-items:center;gap:12px} +.auth-hi{color:var(--muted);font-size:14px} +.auth-link{color:var(--muted);font-size:14px;transition:color .2s} +.auth-link:hover{color:var(--text)} +.btn-mini{background:linear-gradient(90deg,var(--accent),var(--accent2));color:#fff;border-radius:999px;padding:8px 14px;font-size:13px;font-weight:600;transition:transform .15s,box-shadow .2s} +.btn-mini:hover{transform:translateY(-1px);box-shadow:0 8px 20px -8px var(--accent)} +.auth{min-height:70vh;display:flex;align-items:center;justify-content:center;padding:60px 0} +.auth-card{width:100%;max-width:400px;background:var(--card);border:1px solid var(--line);border-radius:20px;padding:34px 30px} +.auth-card h1{font-size:26px;font-weight:800;letter-spacing:-.01em} +.auth-sub{color:var(--muted);font-size:14px;margin:6px 0 24px} +.auth-form{display:grid;gap:16px} +.auth-form label{display:grid;gap:7px;font-size:13px;font-weight:600;color:var(--muted)} +.auth-form input{background:var(--bg);border:1px solid var(--line);color:var(--text);border-radius:11px;padding:12px 14px;font-size:15px;transition:border-color .2s} +.auth-form input:focus{outline:none;border-color:var(--accent)} +.auth-form .btn{margin-top:6px;width:100%} +.auth-error{color:#f87171;font-size:13px;background:rgba(248,113,113,.1);border:1px solid rgba(248,113,113,.25);padding:9px 12px;border-radius:10px} +.auth-alt{text-align:center;color:var(--muted);font-size:14px;margin-top:20px} +.auth-alt a{color:var(--accent2);font-weight:600} +@media(max-width:720px){.auth-nav .auth-hi{display:none}} +.hero{padding:88px 0 56px;text-align:center;max-width:760px;margin:0 auto} +.eyebrow{color:var(--accent2);font-weight:600;letter-spacing:.08em;text-transform:uppercase;font-size:13px;margin-bottom:14px} +.hero h1{font-size:clamp(38px,6vw,68px);line-height:1.04;font-weight:800;letter-spacing:-.02em} +.hero h1 span{background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;background-clip:text;color:transparent} +.hero .sub{color:var(--muted);font-size:18px;margin:20px auto 30px;max-width:560px} +.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:none;cursor:pointer;border-radius:12px;padding:13px 22px;font-size:15px;font-weight:600;transition:transform .15s,box-shadow .2s} +.btn-primary{background:linear-gradient(90deg,var(--accent),var(--accent2));color:#fff;box-shadow:0 8px 24px -8px var(--accent)} +.btn-primary:hover{transform:translateY(-2px);box-shadow:0 14px 30px -8px var(--accent)} +.btn-ghost{background:transparent;border:1px solid var(--line);color:var(--text)} +.btn-ghost:hover{background:var(--card)} +.grid-section{padding:26px 0 70px} +.section-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:22px} +.section-head h2{font-size:26px;font-weight:700} +.muted{color:var(--muted);font-size:14px} +.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:20px} +.card{background:var(--card);border:1px solid var(--line);border-radius:18px;overflow:hidden;transition:transform .2s,border-color .2s,box-shadow .3s;display:block} +.card:hover{transform:translateY(-6px);border-color:var(--accent);box-shadow:0 20px 40px -20px rgba(139,92,246,.6)} +.thumb{aspect-ratio:4/3;display:flex;align-items:flex-end;padding:16px;position:relative} +.thumb::after{content:"";position:absolute;inset:0;background:radial-gradient(120% 80% at 80% 0%,rgba(255,255,255,.25),transparent 60%)} +.thumb-name{position:relative;font-weight:700;font-size:15px;color:rgba(255,255,255,.92);text-shadow:0 1px 8px rgba(0,0,0,.3)} +.card-body{padding:16px} +.chip{display:inline-block;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--accent2);background:rgba(236,72,153,.1);border:1px solid rgba(236,72,153,.25);padding:3px 9px;border-radius:999px;margin-bottom:10px} +.card-body h3{font-size:16px;font-weight:600;margin-bottom:6px} +.price{color:var(--text);font-weight:700;font-size:18px} +.price.big{font-size:30px;margin:6px 0 16px} +.detail{padding:36px 0 80px} +.back{color:var(--muted);font-size:14px;display:inline-block;margin-bottom:22px;transition:color .2s} +.back:hover{color:var(--text)} +.detail-grid{display:grid;grid-template-columns:1.1fr 1fr;gap:40px;align-items:start} +.detail-thumb{aspect-ratio:1/1;border-radius:24px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:26px;color:rgba(255,255,255,.95);position:relative;overflow:hidden;text-align:center;padding:20px} +.detail-thumb::after{content:"";position:absolute;inset:0;background:radial-gradient(120% 80% at 70% 10%,rgba(255,255,255,.3),transparent 55%)} +.detail-thumb span{position:relative;text-shadow:0 2px 12px rgba(0,0,0,.35)} +.detail-info h1{font-size:34px;font-weight:800;letter-spacing:-.01em;margin:12px 0} +.desc{color:var(--muted);font-size:16px;margin-bottom:24px} +.actions{display:flex;gap:12px;margin-bottom:26px;flex-wrap:wrap} +.perks{list-style:none;display:grid;gap:10px} +.perks li{color:var(--muted);font-size:14px;padding-left:24px;position:relative} +.perks li::before{content:"\2713";position:absolute;left:0;color:var(--accent);font-weight:700} +.footer{border-top:1px solid var(--line);color:var(--muted);text-align:center;padding:28px;font-size:13px;margin-top:40px} +.page{animation:enter .45s cubic-bezier(.22,1,.36,1) both} +@keyframes enter{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}} +@media(max-width:720px){.detail-grid{grid-template-columns:1fr}.header nav{display:none}} diff --git a/app/layout.js b/app/layout.js new file mode 100644 index 0000000..87d404f --- /dev/null +++ b/app/layout.js @@ -0,0 +1,24 @@ +import "./globals.css"; +import Link from "next/link"; +import ThemeToggle from "./components/ThemeToggle"; +import AuthNav from "./components/AuthNav"; +export const metadata = { title: "Nova - Store", description: "Tienda de tecnologia moderna" }; +export default function RootLayout({ children }) { + return ( + + +
+ NOVA + +
+ + + +
+
+
{children}
+ + + + ); +} diff --git a/app/lib/auth.js b/app/lib/auth.js new file mode 100644 index 0000000..1e91d3c --- /dev/null +++ b/app/lib/auth.js @@ -0,0 +1,40 @@ +import crypto from "node:crypto"; + +const SECRET = process.env.AUTH_SECRET || "nova-store-dev-secret-change-me"; + +// --- Contraseñas: scrypt (nativo de Node, sin dependencias) --- +export function hashPassword(password) { + const salt = crypto.randomBytes(16).toString("hex"); + const hash = crypto.scryptSync(password, salt, 64).toString("hex"); + return `${salt}:${hash}`; +} + +export function verifyPassword(password, stored) { + const [salt, hash] = String(stored).split(":"); + if (!salt || !hash) return false; + const test = crypto.scryptSync(password, salt, 64).toString("hex"); + const a = Buffer.from(hash, "hex"); + const b = Buffer.from(test, "hex"); + return a.length === b.length && crypto.timingSafeEqual(a, b); +} + +// --- Sesión: cookie firmada con HMAC (sin dependencias) --- +export function signSession(userId) { + const value = String(userId); + const sig = crypto.createHmac("sha256", SECRET).update(value).digest("hex"); + return `${value}.${sig}`; +} + +export function readSession(cookieValue) { + if (!cookieValue) return null; + const i = cookieValue.lastIndexOf("."); + if (i < 0) return null; + const value = cookieValue.slice(0, i); + const sig = cookieValue.slice(i + 1); + const expected = crypto.createHmac("sha256", SECRET).update(value).digest("hex"); + const a = Buffer.from(sig); + const b = Buffer.from(expected); + if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return null; + const id = Number(value); + return Number.isFinite(id) ? id : null; +} diff --git a/app/lib/db.js b/app/lib/db.js new file mode 100644 index 0000000..cea6e26 --- /dev/null +++ b/app/lib/db.js @@ -0,0 +1,27 @@ +import Database from "better-sqlite3"; +import path from "node:path"; +import fs from "node:fs"; + +// Singleton: evita abrir múltiples conexiones durante el hot-reload de next dev. +function createDb() { + const dataDir = path.join(process.cwd(), "data"); + fs.mkdirSync(dataDir, { recursive: true }); + + const db = new Database(path.join(dataDir, "nova.db")); + db.pragma("journal_mode = WAL"); + db.exec(` + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL DEFAULT '', + email TEXT NOT NULL UNIQUE, + password TEXT NOT NULL, + created_at TEXT NOT NULL DEFAULT (datetime('now')) + ); + `); + return db; +} + +const g = globalThis; +const db = g.__novaDb ?? (g.__novaDb = createDb()); + +export default db; diff --git a/app/lib/products.js b/app/lib/products.js new file mode 100644 index 0000000..aa1cf19 --- /dev/null +++ b/app/lib/products.js @@ -0,0 +1,9 @@ +export const products = [ + { id: "aurora-headphones", name: "Aurora Headphones", price: 189, category: "Audio", from: "#7c3aed", to: "#ec4899", desc: "Auriculares inalambricos con cancelacion de ruido activa y 40h de bateria." }, + { id: "nova-watch", name: "Nova Smartwatch", price: 249, category: "Wearables", from: "#06b6d4", to: "#3b82f6", desc: "Reloj inteligente con GPS, monitor cardiaco y pantalla AMOLED. Resistente al agua." }, + { id: "lumen-lamp", name: "Lumen Desk Lamp", price: 79, category: "Hogar", from: "#f59e0b", to: "#ef4444", desc: "Lampara de escritorio con temperatura de color ajustable y carga inalambrica." }, + { id: "pulse-speaker", name: "Pulse Speaker", price: 129, category: "Audio", from: "#10b981", to: "#06b6d4", desc: "Parlante portatil resistente al agua con sonido envolvente 360 y 20h de reproduccion." }, + { id: "zen-keyboard", name: "Zen Keyboard", price: 159, category: "Setup", from: "#8b5cf6", to: "#6366f1", desc: "Teclado mecanico inalambrico con switches silenciosos y retroiluminacion RGB." }, + { id: "orbit-mouse", name: "Orbit Mouse", price: 69, category: "Setup", from: "#f43f5e", to: "#f59e0b", desc: "Mouse ergonomico de precision con scroll magnetico y bateria recargable." } +]; +export const getProduct = (id) => products.find((p) => p.id === id); diff --git a/app/login/page.js b/app/login/page.js new file mode 100644 index 0000000..7a0cd27 --- /dev/null +++ b/app/login/page.js @@ -0,0 +1,49 @@ +"use client"; +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import Link from "next/link"; + +export default function LoginPage() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); + const router = useRouter(); + + async function onSubmit(e) { + e.preventDefault(); + setError(""); setLoading(true); + try { + const r = await fetch("/api/login", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email, password }), + }); + const data = await r.json(); + if (!r.ok) { setError(data.error || "Error al iniciar sesión"); return; } + router.push("/"); + router.refresh(); + } catch { setError("Error de conexión"); } + finally { setLoading(false); } + } + + return ( +
+
+

Iniciar sesión

+

Bienvenido de nuevo a Nova Store.

+
+ + + {error &&

{error}

} + +
+

¿No tenés cuenta? Registrate

+
+
+ ); +} diff --git a/app/page.js b/app/page.js new file mode 100644 index 0000000..e1aeef1 --- /dev/null +++ b/app/page.js @@ -0,0 +1,31 @@ +import Link from "next/link"; +import { products } from "./lib/products"; +export default function Home() { + return ( + <> +
+

Nueva coleccion - 2026

+

Tecnologia que se siente.

+

Diseno minimalista, materiales premium y una experiencia que enamora.

+ Ver productos +
+
+

Destacados

{products.length} productos
+
+ {products.map((p) => ( + +
+ {p.name} +
+
+ {p.category} +

{p.name}

+

${p.price}

+
+ + ))} +
+
+ + ); +} diff --git a/app/product/[id]/page.js b/app/product/[id]/page.js new file mode 100644 index 0000000..24b9e4f --- /dev/null +++ b/app/product/[id]/page.js @@ -0,0 +1,28 @@ +import Link from "next/link"; +import { notFound } from "next/navigation"; +import { getProduct, products } from "../../lib/products"; +export function generateStaticParams() { return products.map((p) => ({ id: p.id })); } +export default async function ProductPage({ params }) { + const { id } = await params; + const p = getProduct(id); + if (!p) return notFound(); + return ( +
+ Volver +
+
{p.name}
+
+ {p.category} +

{p.name}

+

${p.price}

+

{p.desc}

+
+ + +
+
  • Envio gratis en 24-48h
  • Garantia de 2 anos
  • Devolucion sin costo 30 dias
+
+
+
+ ); +} diff --git a/app/register/page.js b/app/register/page.js new file mode 100644 index 0000000..4bf4dc8 --- /dev/null +++ b/app/register/page.js @@ -0,0 +1,53 @@ +"use client"; +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import Link from "next/link"; + +export default function RegisterPage() { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); + const router = useRouter(); + + async function onSubmit(e) { + e.preventDefault(); + setError(""); setLoading(true); + try { + const r = await fetch("/api/register", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ name, email, password }), + }); + const data = await r.json(); + if (!r.ok) { setError(data.error || "Error al registrarse"); return; } + router.push("/"); + router.refresh(); + } catch { setError("Error de conexión"); } + finally { setLoading(false); } + } + + return ( +
+
+

Crear cuenta

+

Unite a Nova Store en segundos.

+
+ + + + {error &&

{error}

} + +
+

¿Ya tenés cuenta? Iniciá sesión

+
+
+ ); +} diff --git a/app/template.js b/app/template.js new file mode 100644 index 0000000..81b5f27 --- /dev/null +++ b/app/template.js @@ -0,0 +1,3 @@ +export default function Template({ children }) { + return
{children}
; +} diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..d80b37c --- /dev/null +++ b/next.config.js @@ -0,0 +1,3 @@ +/** @type {import("next").NextConfig} */ +const nextConfig = { output: "standalone", serverExternalPackages: ["better-sqlite3"] }; +module.exports = nextConfig; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7b484c9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1275 @@ +{ + "name": "nova-store", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nova-store", + "version": "0.1.0", + "dependencies": { + "better-sqlite3": "^11.8.1", + "next": "^15.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@next/env": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.22.tgz", + "integrity": "sha512-O5BlKb3KtsHkvO0gjjV66PuJnAgCtIEIzwkt50HRAHsQkU1t77eksIXSZV84/WMtZJjWrnDUPKHVRi0D62nSAA==" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.22.tgz", + "integrity": "sha512-/VISwtffSg8+fVvBbXdglsvruCsdbBC4dG25iU6xascKVqfQKsj/OtjGnOEkIS7pX5GB9e9/r5QprpicsGL3gw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.22.tgz", + "integrity": "sha512-NiA9ve8hbiuhG/Q17a2mZDRVxMTtg3rTOgjLnDaLlE+AEPAQlkkuKrfePEbeOrgYmX0U2KGX4EVEn09hXU5GlQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.22.tgz", + "integrity": "sha512-vAPa9vltW+UW/KWtjXeSUFgV3wb1x9d/BeyC6WFI6eBpL0D2f70oGwtOp6193mNW3qusrpgBzMQferPf+Zh8Dw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.22.tgz", + "integrity": "sha512-iknK80pWlNDnkdSr13bd8mMuG3Z2oTxODwsZHvuMY7caMk77+rBLdHVWsy8v2EVa3ZojJ/+wJX5fnq8va6Gv8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.22.tgz", + "integrity": "sha512-penuEdkwU2OOAiS+n4LE8T/VIoCfAI01QcLZTJ2xc3+l4Q22L/DzURocmI2LU1b+8BMQoLAP1Sze3uYAZT05Bg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.22.tgz", + "integrity": "sha512-ZM0BKJm3FZ+guG6WT6PcyOLtp6paZ5tngcJC/uUKvLW4Y0TQnnVi1+UGdo8Q6Yxp5gaS82pmC1rD/oFlhkWB3g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.22.tgz", + "integrity": "sha512-rY/YaumrZaS0//94BnHLF5VSRp0GFUO4GvXNuoCBb0cGSci96yO+p1JaNL2aq9YZAYv9cuZRziV02x5IQH/wjg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.22.tgz", + "integrity": "sha512-s5IA4cyrbR2XK/5NWcu5dp8CfPBiKME+UhvNperia7uQybEgg5+LIhGMiY37WQE4rcI4owsDcU4IVUjLoTuDkA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/better-sqlite3": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", + "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/next": { + "version": "15.5.22", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.22.tgz", + "integrity": "sha512-mrtal1sRxO4YrlDS98sDuIvGZivKbFix8w7oAL9ZynfOgc3cADQOQgvwtMooc18Qr8bKzvQAcHwHZ0mbJ7zcfQ==", + "dependencies": { + "@next/env": "15.5.22", + "@swc/helpers": "0.5.15", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.5.22", + "@next/swc-darwin-x64": "15.5.22", + "@next/swc-linux-arm64-gnu": "15.5.22", + "@next/swc-linux-arm64-musl": "15.5.22", + "@next/swc-linux-x64-gnu": "15.5.22", + "@next/swc-linux-x64-musl": "15.5.22", + "@next/swc-win32-arm64-msvc": "15.5.22", + "@next/swc-win32-x64-msvc": "15.5.22", + "sharp": "^0.34.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/node-abi": { + "version": "3.94.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.94.0.tgz", + "integrity": "sha512-W5ZNO5KRPB5TkYmGVD9F6YqhsglXJzE6etpbmT+f6EQElhiX/UTG551cnsRGvLG3fyZEg9HwaDmNmj5nwJ4z9g==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==" + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tar-fs": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", + "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6279a3d --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "name": "nova-store", + "version": "0.1.0", + "private": true, + "scripts": { "dev": "next dev", "build": "next build", "start": "next start" }, + "dependencies": { "next": "^15.0.0", "react": "^19.0.0", "react-dom": "^19.0.0", "better-sqlite3": "^11.8.1" } +}