From 4f50dca25df70c24bd91c7542483b6b6cb81548b Mon Sep 17 00:00:00 2001 From: oiov Date: Thu, 14 Nov 2024 17:26:39 +0800 Subject: [PATCH] upd --- app/(protected)/dashboard/records/loading.tsx | 2 +- app/(protected)/dashboard/scrape/charts.tsx | 16 +- .../dashboard/scrape/markdown/page.tsx | 2 +- .../dashboard/scrape/meta-info/page.tsx | 2 +- app/(protected)/dashboard/scrape/page.tsx | 2 +- .../dashboard/scrape/qrcode/loading.tsx | 11 ++ .../dashboard/scrape/qrcode/page.tsx | 30 ++++ app/(protected)/dashboard/scrape/scrapes.tsx | 114 ++++++++++++ .../dashboard/scrape/screenshot/page.tsx | 2 +- app/(protected)/dashboard/urls/loading.tsx | 2 +- app/api/scraping/qrcode/route.ts | 104 +++++++++++ config/dashboard.ts | 2 +- package.json | 2 + pnpm-lock.yaml | 164 +++++++++++++++++- 14 files changed, 438 insertions(+), 17 deletions(-) create mode 100644 app/(protected)/dashboard/scrape/qrcode/loading.tsx create mode 100644 app/(protected)/dashboard/scrape/qrcode/page.tsx create mode 100644 app/api/scraping/qrcode/route.ts diff --git a/app/(protected)/dashboard/records/loading.tsx b/app/(protected)/dashboard/records/loading.tsx index f8e3af8..bb440cf 100644 --- a/app/(protected)/dashboard/records/loading.tsx +++ b/app/(protected)/dashboard/records/loading.tsx @@ -5,7 +5,7 @@ export default function DashboardRecordsLoading() { return ( <> - + ); } diff --git a/app/(protected)/dashboard/scrape/charts.tsx b/app/(protected)/dashboard/scrape/charts.tsx index 5fd35b8..a80386c 100644 --- a/app/(protected)/dashboard/scrape/charts.tsx +++ b/app/(protected)/dashboard/scrape/charts.tsx @@ -20,8 +20,12 @@ export default async function DashboardScrapeCharts({ id }: { id: string }) { return ( <> -

Request Statistics

- {all_logs && all_logs.length > 0 && } + {all_logs && all_logs.length > 0 && ( + <> +

Request Statistics

+ + + )}
{(screenshot_stats.length > 0 || meta_stats.length > 0) && ( )}
-

Request Logs

- {all_logs && all_logs.length > 0 && } + {all_logs && all_logs.length > 0 && ( + <> +

Request Logs

+ + + )} ); } diff --git a/app/(protected)/dashboard/scrape/markdown/page.tsx b/app/(protected)/dashboard/scrape/markdown/page.tsx index 3684030..21e82ec 100644 --- a/app/(protected)/dashboard/scrape/markdown/page.tsx +++ b/app/(protected)/dashboard/scrape/markdown/page.tsx @@ -20,7 +20,7 @@ export default async function DashboardPage() { return ( <> + + + + ); +} diff --git a/app/(protected)/dashboard/scrape/qrcode/page.tsx b/app/(protected)/dashboard/scrape/qrcode/page.tsx new file mode 100644 index 0000000..c75f25c --- /dev/null +++ b/app/(protected)/dashboard/scrape/qrcode/page.tsx @@ -0,0 +1,30 @@ +import { redirect } from "next/navigation"; + +import { getCurrentUser } from "@/lib/session"; +import { constructMetadata } from "@/lib/utils"; +import { DashboardHeader } from "@/components/dashboard/header"; + +import { QrCodeScraping } from "../scrapes"; + +export const metadata = constructMetadata({ + title: "Url to QR Code API - WR.DO", + description: "Generate QR Code from URL", +}); + +export default async function DashboardPage() { + const user = await getCurrentUser(); + + if (!user?.id) redirect("/login"); + + return ( + <> + + + + ); +} diff --git a/app/(protected)/dashboard/scrape/scrapes.tsx b/app/(protected)/dashboard/scrape/scrapes.tsx index ec10dbe..e836650 100644 --- a/app/(protected)/dashboard/scrape/scrapes.tsx +++ b/app/(protected)/dashboard/scrape/scrapes.tsx @@ -449,6 +449,120 @@ export function TextScraping({ ); } +export function QrCodeScraping({ + user, +}: { + user: { id: string; apiKey: string }; +}) { + const { theme } = useTheme(); + const [protocol, setProtocol] = useState("https://"); + + const [isShoting, setIsShoting] = useState(false); + const [currentScreenshotLink, setCurrentScreenshotLink] = + useState("vmail.dev"); + const [screenshotInfo, setScreenshotInfo] = useState({ + tmp_url: "", + payload: "", + }); + + const handleScrapingScreenshot = async () => { + if (currentScreenshotLink) { + setIsShoting(true); + const payload = `/api/scraping/qrcode?url=${protocol}${currentScreenshotLink}&key=${user.apiKey}`; + const res = await fetch(payload); + if (!res.ok || res.status !== 200) { + const data = await res.json(); + toast.error(data.statusText); + } else { + const blob = await res.blob(); + const imageUrl = URL.createObjectURL(blob); + setScreenshotInfo({ + tmp_url: imageUrl, + payload: `${window.location.origin}${payload}`, + }); + toast.success("Success!"); + } + setIsShoting(false); + } + }; + + return ( + <> + + + + Playground + + Automate your website screenshots and turn them into stunning + visuals for your applications. + + + +
+ + setCurrentScreenshotLink(e.target.value)} + /> + +
+ +
+ + {screenshotInfo.tmp_url && ( + + )} +
+
+
+ + ); +} + export const CodeLight = ({ content }: { content: string }) => { const code = content.trim(); diff --git a/app/(protected)/dashboard/scrape/screenshot/page.tsx b/app/(protected)/dashboard/scrape/screenshot/page.tsx index 148b339..968e2f1 100644 --- a/app/(protected)/dashboard/scrape/screenshot/page.tsx +++ b/app/(protected)/dashboard/scrape/screenshot/page.tsx @@ -21,7 +21,7 @@ export default async function DashboardPage() { return ( <> - + ); } diff --git a/app/api/scraping/qrcode/route.ts b/app/api/scraping/qrcode/route.ts new file mode 100644 index 0000000..2835a32 --- /dev/null +++ b/app/api/scraping/qrcode/route.ts @@ -0,0 +1,104 @@ +import QRCode from "qrcode"; + +import { env } from "@/env.mjs"; +import { checkApiKey } from "@/lib/dto/api-key"; +import { createScrapeMeta } from "@/lib/dto/scrape"; +import { getIpInfo, isLink } from "@/lib/utils"; + +export const revalidate = 60; + +// export const runtime = "edge"; + +export async function GET(req: Request) { + try { + const url = new URL(req.url); + const link = url.searchParams.get("url"); + const width = parseInt(url.searchParams.get("width") || "200"); + const margin = parseInt(url.searchParams.get("margin") || "4"); + const dark = url.searchParams.get("dark") || "#000000"; + const light = url.searchParams.get("light") || "#ffffff"; + const type = url.searchParams.get("type") || "svg"; + + // Check if the url is valid + if (!link || !isLink(link)) { + return Response.json( + { statusText: "Url is required" }, + { + status: 400, + }, + ); + } + + // Get the API key from the request + const custom_apiKey = url.searchParams.get("key"); + if (!custom_apiKey) { + return Response.json( + { + statusText: + "API key is required. You can get your API key from Dashboard->Settings.", + }, + { status: 400 }, + ); + } + + // Check if the API key is valid + const user_apiKey = await checkApiKey(custom_apiKey); + if (!user_apiKey?.id) { + return Response.json( + { + statusText: + "Invalid API key. You can get your API key from Dashboard->Settings.", + }, + { status: 401 }, + ); + } + + const options = { + width, + margin, + color: { + dark, + light, + }, + errorCorrectionLevel: "H", // 可选值: L, M, Q, H + type: type === "svg" ? "svg" : "image/png", + }; + + const stats = getIpInfo(req); + await createScrapeMeta({ + ip: stats.ip, + type: "screenshot", + referer: stats.referer, + city: stats.city, + region: stats.region, + country: stats.country, + latitude: stats.latitude, + longitude: stats.longitude, + lang: stats.lang, + device: stats.device, + browser: stats.browser, + click: 1, + userId: user_apiKey.id, + apiKey: custom_apiKey, + link, + }); + + let qrResult; + // if (type === 'svg') { + // // 生成 SVG 格式的二维码 + // qrResult = await QRCode.toString(link, options); + // return new Response(qrResult, { + // status: 200, + // headers: { + // "Content-Type": "image/svg+xml", + // }, + // }); + // } else { + // // 生成 Base64 格式的二维码 + // qrResult = await QRCode.toDataURL(link, options); + // return new Response(qrResult); + // } + } catch (error) { + return Response.json({ statusText: "Server error" }, { status: 500 }); + } +} diff --git a/config/dashboard.ts b/config/dashboard.ts index 9a9329d..90d4be8 100644 --- a/config/dashboard.ts +++ b/config/dashboard.ts @@ -19,7 +19,7 @@ export const sidebarLinks: SidebarNavItem[] = [ { href: "/dashboard/scrape", icon: "bug", - title: "Scraping API", + title: "Overview", }, { href: "/dashboard/scrape/screenshot", diff --git a/package.json b/package.json index 67692fc..d430e69 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.13", "@types/node": "^20.14.11", + "@types/qrcode": "^1.5.5", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "@types/turndown": "^5.0.5", @@ -123,6 +124,7 @@ "prettier-plugin-tailwindcss": "^0.6.5", "pretty-quick": "^4.0.0", "prisma": "^5.17.0", + "qrcode": "^1.5.4", "rehype": "^13.0.1", "rehype-autolink-headings": "^7.1.0", "rehype-pretty-code": "^0.13.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4924865..9c27d96 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -264,6 +264,9 @@ importers: '@types/node': specifier: ^20.14.11 version: 20.14.11 + '@types/qrcode': + specifier: ^1.5.5 + version: 1.5.5 '@types/react': specifier: 18.3.3 version: 18.3.3 @@ -315,6 +318,9 @@ importers: prisma: specifier: ^5.17.0 version: 5.17.0 + qrcode: + specifier: ^1.5.4 + version: 1.5.4 rehype: specifier: ^13.0.1 version: 13.0.1 @@ -2622,6 +2628,9 @@ packages: '@types/prop-types@15.7.10': resolution: {integrity: sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==} + '@types/qrcode@1.5.5': + resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} + '@types/react-dom@18.3.0': resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} @@ -3068,6 +3077,10 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} @@ -3135,6 +3148,9 @@ packages: peerDependencies: typanion: '*' + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -3536,6 +3552,10 @@ packages: supports-color: optional: true + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} @@ -3580,6 +3600,9 @@ packages: didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -3955,6 +3978,10 @@ packages: find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -4577,6 +4604,10 @@ packages: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -5097,6 +5128,10 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -5105,6 +5140,10 @@ packages: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -5113,6 +5152,10 @@ packages: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -5211,6 +5254,10 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -5384,6 +5431,11 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -5577,6 +5629,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + resend@3.4.0: resolution: {integrity: sha512-F3PVHdTHeLonSnrU5V6k8643LJ9QacLu3uI9M+BAFkmBmB1ELM2x7fdsziYZoSm6DmU6TKwiQCK0jf8dcNomcQ==} engines: {node: '>=18'} @@ -5680,6 +5735,9 @@ packages: server-only@0.0.1: resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -6266,6 +6324,9 @@ packages: which-collection@1.0.1: resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -6279,6 +6340,10 @@ packages: engines: {node: '>= 8'} hasBin: true + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -6306,6 +6371,9 @@ packages: resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==} engines: {node: '>=0.4.0'} + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -6324,10 +6392,18 @@ packages: resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} engines: {node: '>= 14'} + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -8937,6 +9013,10 @@ snapshots: '@types/prop-types@15.7.10': {} + '@types/qrcode@1.5.5': + dependencies: + '@types/node': 20.14.11 + '@types/react-dom@18.3.0': dependencies: '@types/react': 18.3.3 @@ -9500,6 +9580,8 @@ snapshots: camelcase-css@2.0.1: {} + camelcase@5.3.1: {} + camelize@1.0.1: {} caniuse-lite@1.0.30001600: {} @@ -9576,6 +9658,12 @@ snapshots: dependencies: typanion: 3.14.0 + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -9995,6 +10083,8 @@ snapshots: dependencies: ms: 2.1.2 + decamelize@1.2.0: {} + decimal.js-light@2.5.1: {} decode-named-character-reference@1.0.2: @@ -10037,6 +10127,8 @@ snapshots: didyoumean@1.2.2: {} + dijkstrajs@1.0.3: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -10283,7 +10375,7 @@ snapshots: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) @@ -10319,8 +10411,8 @@ snapshots: debug: 4.3.4 enhanced-resolve: 5.15.0 eslint: 8.57.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -10331,7 +10423,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -10342,7 +10434,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.3 @@ -10352,7 +10444,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.20.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -10608,6 +10700,11 @@ snapshots: find-root@1.1.0: {} + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -11271,6 +11368,10 @@ snapshots: loader-runner@4.3.0: {} + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -12107,6 +12208,10 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -12115,6 +12220,10 @@ snapshots: dependencies: yocto-queue: 1.0.0 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 @@ -12123,6 +12232,8 @@ snapshots: dependencies: p-limit: 4.0.0 + p-try@2.2.0: {} + pako@0.2.9: {} parent-module@1.0.1: @@ -12219,6 +12330,8 @@ snapshots: pirates@4.0.6: {} + pngjs@5.0.0: {} + possible-typed-array-names@1.0.0: {} postcss-import@15.1.0(postcss@8.4.39): @@ -12348,6 +12461,12 @@ snapshots: punycode@2.3.1: {} + qrcode@1.5.4: + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + queue-microtask@1.2.3: {} quickselect@2.0.0: {} @@ -12703,6 +12822,8 @@ snapshots: require-from-string@2.0.2: {} + require-main-filename@2.0.0: {} + resend@3.4.0: dependencies: '@react-email/render': 0.0.15 @@ -12815,6 +12936,8 @@ snapshots: server-only@0.0.1: {} + set-blocking@2.0.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -13562,6 +13685,8 @@ snapshots: is-weakmap: 2.0.1 is-weakset: 2.0.2 + which-module@2.0.1: {} + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -13578,6 +13703,12 @@ snapshots: dependencies: isexe: 2.0.0 + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -13596,6 +13727,8 @@ snapshots: xmlhttprequest-ssl@2.0.0: {} + y18n@4.0.3: {} + y18n@5.0.8: {} yallist@3.1.1: {} @@ -13606,8 +13739,27 @@ snapshots: yaml@2.3.4: {} + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + yargs-parser@21.1.1: {} + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yargs@17.7.2: dependencies: cliui: 8.0.1