This commit is contained in:
oiov
2024-11-14 17:26:39 +08:00
parent 4512c5810a
commit 4f50dca25d
14 changed files with 438 additions and 17 deletions
@@ -5,7 +5,7 @@ export default function DashboardRecordsLoading() {
return (
<>
<DashboardHeader heading="DNS Records" text="" />
<Skeleton className="h-[400px] w-full rounded-lg" />
<Skeleton className="h-full w-full rounded-lg" />
</>
);
}
+12 -4
View File
@@ -20,8 +20,12 @@ export default async function DashboardScrapeCharts({ id }: { id: string }) {
return (
<>
<h2 className="my-1 text-xl font-semibold">Request Statistics</h2>
{all_logs && all_logs.length > 0 && <DailyPVUVChart data={all_logs} />}
{all_logs && all_logs.length > 0 && (
<>
<h2 className="my-1 text-xl font-semibold">Request Statistics</h2>
<DailyPVUVChart data={all_logs} />
</>
)}
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
{(screenshot_stats.length > 0 || meta_stats.length > 0) && (
<LineChartMultiple
@@ -38,8 +42,12 @@ export default async function DashboardScrapeCharts({ id }: { id: string }) {
/>
)}
</div>
<h2 className="my-1 text-xl font-semibold">Request Logs</h2>
{all_logs && all_logs.length > 0 && <LogsTable userId={id} />}
{all_logs && all_logs.length > 0 && (
<>
<h2 className="my-1 text-xl font-semibold">Request Logs</h2>
<LogsTable userId={id} />
</>
)}
</>
);
}
@@ -20,7 +20,7 @@ export default async function DashboardPage() {
return (
<>
<DashboardHeader
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;Markdown&nbsp;&nbsp;API"
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;Markdown"
text="Quickly extract website content and convert it to Markdown format. It's free and unlimited to use!"
link="/docs/open-api/markdown"
linkText="Markdown API."
@@ -20,7 +20,7 @@ export default async function DashboardPage() {
return (
<>
<DashboardHeader
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;Meta&nbsp;&nbsp;API"
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;MetaInfo"
text="Quickly extract valuable structured website data. It's free and unlimited to use!"
link="/docs/open-api/meta-info"
linkText="Meta Info API."
+1 -1
View File
@@ -20,7 +20,7 @@ export default async function DashboardPage() {
return (
<>
<DashboardHeader
heading="Scraping&nbsp;&nbsp;API"
heading="Scraping&nbsp;&nbsp;API&nbsp;&nbsp;Overview"
text="Quickly extract valuable structured website data. It's free and unlimited to use!"
link="/docs/open-api"
linkText="Open API."
@@ -0,0 +1,11 @@
import { Skeleton } from "@/components/ui/skeleton";
import { DashboardHeader } from "@/components/dashboard/header";
export default function DashboardRecordsLoading() {
return (
<>
<DashboardHeader heading="Scraping API" text="" />
<Skeleton className="h-full w-full rounded-lg" />
</>
);
}
@@ -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 (
<>
<DashboardHeader
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;QR&nbsp;&nbsp;Code"
text="Generate QR Code from URL"
link="/docs/open-api/qr-code"
linkText="QR Code API."
/>
<QrCodeScraping user={{ id: user.id, apiKey: user.apiKey }} />
</>
);
}
@@ -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 (
<>
<CodeLight content={`https://wr.do/api/scraping/qrcode`} />
<Card className="bg-gray-50 dark:bg-gray-900">
<CardHeader>
<CardTitle>Playground</CardTitle>
<CardDescription>
Automate your website screenshots and turn them into stunning
visuals for your applications.
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center">
<Select
onValueChange={(value: string) => {
setProtocol(value);
}}
name="protocol"
defaultValue="https://"
>
<SelectTrigger className="h-10 w-24 rounded-r-none bg-transparent shadow-inner">
<SelectValue placeholder="Protocol" />
</SelectTrigger>
<SelectContent>
<SelectItem key="https" value="https://">
https://
</SelectItem>
<SelectItem key="http" value="http://">
http://
</SelectItem>
</SelectContent>
</Select>
<Input
type="text"
placeholder="www.example.com"
className="h-10 rounded-none border focus:border-primary active:border-primary"
value={currentScreenshotLink}
size={100}
onChange={(e) => setCurrentScreenshotLink(e.target.value)}
/>
<Button
variant="blue"
onClick={handleScrapingScreenshot}
disabled={isShoting}
className="rounded-l-none"
>
{isShoting ? "Scraping..." : "Send"}
</Button>
</div>
<div className="mt-4 rounded-md border p-3">
<JsonView
className="max-w-[400px] overflow-hidden"
style={theme === "dark" ? vscodeTheme : githubLightTheme}
value={screenshotInfo}
displayObjectSize={false}
displayDataTypes={false}
// shortenTextAfterLength={50}
/>
{screenshotInfo.tmp_url && (
<BlurImage
src={screenshotInfo.tmp_url}
alt="ligth preview landing"
className="my-4 flex rounded-md border object-contain object-center shadow-md"
width={1500}
height={750}
priority
// placeholder="blur"
/>
)}
</div>
</CardContent>
</Card>
</>
);
}
export const CodeLight = ({ content }: { content: string }) => {
const code = content.trim();
@@ -21,7 +21,7 @@ export default async function DashboardPage() {
return (
<>
<DashboardHeader
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;Screenshot&nbsp;&nbsp;API"
heading="Url&nbsp;&nbsp;to&nbsp;&nbsp;Screenshot"
text="Quickly extract website screenshots. It's free and unlimited to use!"
link="/docs/open-api/screenshot"
linkText="Screenshot API."
+1 -1
View File
@@ -5,7 +5,7 @@ export default function DashboardUrlsLoading() {
return (
<>
<DashboardHeader heading="Short Urls" text="" />
<Skeleton className="h-[400px] w-full rounded-lg" />
<Skeleton className="h-full w-full rounded-lg" />
</>
);
}
+104
View File
@@ -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 });
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ export const sidebarLinks: SidebarNavItem[] = [
{
href: "/dashboard/scrape",
icon: "bug",
title: "Scraping API",
title: "Overview",
},
{
href: "/dashboard/scrape/screenshot",
+2
View File
@@ -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",
+158 -6
View File
@@ -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