refactor
This commit is contained in:
@@ -103,7 +103,7 @@ export default async function AdminPage() {
|
||||
</div>
|
||||
|
||||
<h2 className="my-1 text-xl font-semibold">Request Logs</h2>
|
||||
<LogsTable userId={user.id} target={"/api/scraping/admin/logs"} />
|
||||
<LogsTable userId={user.id} target={"/api/v1/scraping/admin/logs"} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -44,7 +44,7 @@ export default async function DashboardScrapeCharts({ id }: { id: string }) {
|
||||
</div>
|
||||
|
||||
<h2 className="my-1 text-xl font-semibold">Request Logs</h2>
|
||||
<LogsTable userId={id} target={"/api/scraping/logs"} />
|
||||
<LogsTable userId={id} target={"/api/v1/scraping/logs"} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ export function ScreenshotScraping({
|
||||
const handleScrapingScreenshot = async () => {
|
||||
if (currentScreenshotLink) {
|
||||
setIsShoting(true);
|
||||
const payload = `/api/scraping/screenshot?url=${protocol}${currentScreenshotLink}&key=${user.apiKey}`;
|
||||
const payload = `/api/v1/scraping/screenshot?url=${protocol}${currentScreenshotLink}&key=${user.apiKey}`;
|
||||
const res = await fetch(payload);
|
||||
if (!res.ok || res.status !== 200) {
|
||||
const data = await res.json();
|
||||
@@ -84,7 +84,7 @@ export function ScreenshotScraping({
|
||||
|
||||
return (
|
||||
<>
|
||||
<CodeLight content={`https://wr.do/api/scraping/screenshot`} />
|
||||
<CodeLight content={`https://wr.do/api/v1/scraping/screenshot`} />
|
||||
<Card className="bg-gray-50 dark:bg-gray-900">
|
||||
<CardHeader>
|
||||
<CardTitle>Playground</CardTitle>
|
||||
@@ -184,7 +184,7 @@ export function MetaScraping({
|
||||
if (currentLink) {
|
||||
setIsScraping(true);
|
||||
const res = await fetch(
|
||||
`/api/scraping/meta?url=${protocol}${currentLink}&key=${user.apiKey}`,
|
||||
`/api/v1/scraping/meta?url=${protocol}${currentLink}&key=${user.apiKey}`,
|
||||
);
|
||||
if (!res.ok || res.status !== 200) {
|
||||
const data = await res.json();
|
||||
@@ -200,7 +200,7 @@ export function MetaScraping({
|
||||
|
||||
return (
|
||||
<>
|
||||
<CodeLight content={`https://wr.do/api/scraping/meta`} />
|
||||
<CodeLight content={`https://wr.do/api/v1/scraping/meta`} />
|
||||
<Card className="bg-gray-50 dark:bg-gray-900">
|
||||
<CardHeader>
|
||||
<CardTitle>Playground</CardTitle>
|
||||
@@ -280,7 +280,7 @@ export function MarkdownScraping({
|
||||
if (currentLink) {
|
||||
setIsScraping(true);
|
||||
const res = await fetch(
|
||||
`/api/scraping/markdown?url=${protocol}${currentLink}&key=${user.apiKey}`,
|
||||
`/api/v1/scraping/markdown?url=${protocol}${currentLink}&key=${user.apiKey}`,
|
||||
);
|
||||
if (!res.ok || res.status !== 200) {
|
||||
const data = await res.json();
|
||||
@@ -296,7 +296,7 @@ export function MarkdownScraping({
|
||||
|
||||
return (
|
||||
<>
|
||||
<CodeLight content={`https://wr.do/api/scraping/markdown`} />
|
||||
<CodeLight content={`https://wr.do/api/v1/scraping/markdown`} />
|
||||
<Card className="bg-gray-50 dark:bg-gray-900">
|
||||
<CardHeader>
|
||||
<CardTitle>Markdown</CardTitle>
|
||||
@@ -375,7 +375,7 @@ export function TextScraping({
|
||||
if (currentLink) {
|
||||
setIsScraping(true);
|
||||
const res = await fetch(
|
||||
`/api/scraping/text?url=${protocol}${currentLink}&key=${user.apiKey}`,
|
||||
`/api/v1/scraping/text?url=${protocol}${currentLink}&key=${user.apiKey}`,
|
||||
);
|
||||
if (!res.ok || res.status !== 200) {
|
||||
const data = await res.json();
|
||||
@@ -391,7 +391,7 @@ export function TextScraping({
|
||||
|
||||
return (
|
||||
<>
|
||||
<CodeLight content={`https://wr.do/api/scraping/text`} />
|
||||
<CodeLight content={`https://wr.do/api/v1/scraping/text`} />
|
||||
<Card className="bg-gray-50 dark:bg-gray-900">
|
||||
<CardHeader>
|
||||
<CardTitle>Text</CardTitle>
|
||||
@@ -468,7 +468,7 @@ export function QrCodeScraping({
|
||||
const handleScrapingScreenshot = async () => {
|
||||
if (currentScreenshotLink) {
|
||||
setIsShoting(true);
|
||||
const payload = `/api/scraping/qrcode?url=${protocol}${currentScreenshotLink}&key=${user.apiKey}`;
|
||||
const payload = `/api/v1/scraping/qrcode?url=${protocol}${currentScreenshotLink}&key=${user.apiKey}`;
|
||||
const res = await fetch(payload);
|
||||
if (!res.ok || res.status !== 200) {
|
||||
toast.error(res.statusText);
|
||||
@@ -487,7 +487,7 @@ export function QrCodeScraping({
|
||||
|
||||
return (
|
||||
<>
|
||||
<CodeLight content={`https://wr.do/api/scraping/qrcode`} />
|
||||
<CodeLight content={`https://wr.do/api/v1/scraping/qrcode`} />
|
||||
<Card className="bg-gray-50 dark:bg-gray-900">
|
||||
<CardHeader>
|
||||
<CardTitle>Playground</CardTitle>
|
||||
@@ -576,7 +576,7 @@ export const CodeLight = ({ content }: { content: string }) => {
|
||||
{i + 1}
|
||||
</span>
|
||||
{/* Code content */}
|
||||
<span className="text-green-400">
|
||||
<span className="text-blue-400">
|
||||
{line
|
||||
.replace(
|
||||
/function/,
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import Icon from "lucide-static";
|
||||
|
||||
import { toCamelCase } from "@/lib/utils";
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const { searchParams: sp } = new URL(req.url);
|
||||
|
||||
const iconInfo = {
|
||||
type: sp.get("type") === "svg" ? "svg" : "text",
|
||||
value: sp.get("value") || `sparkles`,
|
||||
width: Number(sp.get("w") || "128"),
|
||||
height: Number(sp.get("h") || "64"),
|
||||
animate: Boolean(sp.get("animate") === "true"),
|
||||
fillStyle: {
|
||||
fillType: sp.get("fillType") === "Solid" ? "Solid" : "Linear",
|
||||
primaryColor: sp.get("primaryColor") || "#FC466B",
|
||||
secondaryColor: sp.get("secondaryColor") || "#3F5EFB",
|
||||
angle: sp.get("angle") || "45",
|
||||
clip: Boolean(sp.get("clip") === "true"),
|
||||
},
|
||||
background: {
|
||||
radialGlare: Boolean(sp.get("radialGlare") === "true"),
|
||||
noiseTexture: false, // TODO
|
||||
noiseOpacity: Number(sp.get("noiseOpacity") || "50"),
|
||||
radius: sp.get("radius") || "12",
|
||||
strokeSize: Number(sp.get("strokeSize") || "0"),
|
||||
strokeColor: sp.get("strokeColor") || "#FFFFFF",
|
||||
strokeOpacity: sp.get("strokeOpacity") || "100",
|
||||
},
|
||||
icon: {
|
||||
color: sp.get("color") || "#FFFFFF",
|
||||
size: Number(sp.get("size") || "32"),
|
||||
family: sp.get("family") || "sans-serif",
|
||||
},
|
||||
};
|
||||
|
||||
let svgString = "";
|
||||
let svgClipString = "";
|
||||
if (iconInfo.type === "svg") {
|
||||
const iconD = (Icon as { [key: string]: any })[
|
||||
toCamelCase(iconInfo.value)
|
||||
];
|
||||
|
||||
const regex = /<svg.*?>(.*?)<\/svg>/;
|
||||
const match = iconD.match(regex);
|
||||
|
||||
svgString = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="${iconInfo.icon.size}"
|
||||
height="${iconInfo.icon.size}"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="${iconInfo.icon.color}"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
alignment-baseline="middle"
|
||||
x="${(iconInfo.width - iconInfo.icon.size) / 2}"
|
||||
y="${(iconInfo.height - iconInfo.icon.size) / 2}">
|
||||
${match?.[1]}
|
||||
</svg>
|
||||
`;
|
||||
svgClipString = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="${iconInfo.icon.size}"
|
||||
height="${iconInfo.icon.size}"
|
||||
viewBox="0 0 24 24"
|
||||
fill="black"
|
||||
stroke="black"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
alignment-baseline="middle"
|
||||
x="${(iconInfo.width - iconInfo.icon.size) / 2}"
|
||||
y="${(iconInfo.height - iconInfo.icon.size) / 2}">
|
||||
${match?.[1]}
|
||||
</svg>
|
||||
`;
|
||||
}
|
||||
|
||||
let noiseImage = "";
|
||||
if (iconInfo.background.noiseTexture) {
|
||||
// getImageData("http://localhost:3000/noise.png").then((data) => {
|
||||
// noiseImage = data as string;
|
||||
// });
|
||||
}
|
||||
|
||||
return new Response(
|
||||
`<svg
|
||||
id="iconce.com"
|
||||
width="${iconInfo.width}"
|
||||
height="${iconInfo.height}"
|
||||
viewBox="0 0 ${iconInfo.width} ${iconInfo.height}"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="r5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="rotate(${iconInfo.fillStyle.angle})"
|
||||
style="transform-origin:center center"
|
||||
>
|
||||
${
|
||||
iconInfo.animate
|
||||
? `<animateTransform
|
||||
attributeName="gradientTransform"
|
||||
type="rotate"
|
||||
values="0;360"
|
||||
dur="5s"
|
||||
repeatCount="indefinite"
|
||||
/>`
|
||||
: ""
|
||||
}
|
||||
<stop stop-color="${iconInfo.fillStyle.primaryColor}">
|
||||
${
|
||||
iconInfo.animate
|
||||
? `<animate
|
||||
attributeName="stop-color"
|
||||
values="${iconInfo.fillStyle.primaryColor};${iconInfo.fillStyle.secondaryColor};${iconInfo.fillStyle.primaryColor}"
|
||||
dur="3s"
|
||||
repeatCount="indefinite"
|
||||
/>`
|
||||
: ""
|
||||
}
|
||||
</stop>
|
||||
<stop offset="1" stop-color="${iconInfo.fillStyle.secondaryColor}">
|
||||
${
|
||||
iconInfo.animate
|
||||
? `<animate
|
||||
attributeName="stop-color"
|
||||
values="${iconInfo.fillStyle.secondaryColor};${iconInfo.fillStyle.primaryColor};${iconInfo.fillStyle.secondaryColor}"
|
||||
dur="3s"
|
||||
repeatCount="indefinite"
|
||||
/>`
|
||||
: ""
|
||||
}
|
||||
</stop>
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="r6"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(256) rotate(90) scale(512)"
|
||||
>
|
||||
<stop stop-color="white"></stop>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"></stop>
|
||||
</radialGradient>
|
||||
${
|
||||
iconInfo.type === "svg" && iconInfo.fillStyle.clip
|
||||
? `<mask id="mask">
|
||||
<rect
|
||||
id="r4"
|
||||
width="${iconInfo.width}"
|
||||
height="${iconInfo.height}"
|
||||
fill="white"
|
||||
/>
|
||||
${svgClipString}
|
||||
</mask>`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
iconInfo.background.noiseTexture
|
||||
? `<mask id="clipmask">
|
||||
<rect
|
||||
width="${iconInfo.width}"
|
||||
height="${iconInfo.height}"
|
||||
x="${iconInfo.background.strokeSize / 2}"
|
||||
y="${iconInfo.background.strokeSize / 2}"
|
||||
fill="white"
|
||||
rx="${iconInfo.background.radius}" // 设置圆角
|
||||
/>
|
||||
</mask>`
|
||||
: ""
|
||||
}
|
||||
</defs>
|
||||
<rect
|
||||
id="r4"
|
||||
width="${iconInfo.width - iconInfo.background.strokeSize}"
|
||||
height="${iconInfo.height - iconInfo.background.strokeSize}"
|
||||
x="${iconInfo.background.strokeSize / 2}"
|
||||
y="${iconInfo.background.strokeSize / 2}"
|
||||
rx="${iconInfo.background.radius}"
|
||||
fill="${
|
||||
iconInfo.fillStyle.fillType === "Linear"
|
||||
? "url(#r5)"
|
||||
: iconInfo.fillStyle.primaryColor
|
||||
}"
|
||||
stroke="${iconInfo.background.strokeColor}"
|
||||
stroke-width="${iconInfo.background.strokeSize}"
|
||||
stroke-opacity="${iconInfo.background.strokeOpacity}%"
|
||||
paint-order="stroke"
|
||||
mask="${
|
||||
iconInfo.type === "svg" && iconInfo.fillStyle.clip
|
||||
? "url(#mask)"
|
||||
: undefined
|
||||
}"
|
||||
></rect>
|
||||
${
|
||||
iconInfo.background.radialGlare
|
||||
? `<rect
|
||||
width="${iconInfo.width - iconInfo.background.strokeSize}"
|
||||
height="${iconInfo.height - iconInfo.background.strokeSize}"
|
||||
x="${iconInfo.background.strokeSize / 2}"
|
||||
y="${iconInfo.background.strokeSize / 2}"
|
||||
fill="url(#r6)"
|
||||
rx="${iconInfo.background.radius}"
|
||||
style="mix-blend-mode: overlay"
|
||||
></rect>`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
iconInfo.background.noiseTexture
|
||||
? `<image
|
||||
href="${noiseImage}"
|
||||
width="${iconInfo.width}"
|
||||
height="${iconInfo.height}"
|
||||
x="0"
|
||||
y="0"
|
||||
mask="url(#clipmask)"
|
||||
clipPath="url(#clip)"
|
||||
opacity="${iconInfo.background.noiseOpacity ?? 50}%"></image>`
|
||||
: ""
|
||||
}
|
||||
${iconInfo.type === "svg" ? svgString : ""}
|
||||
${
|
||||
iconInfo.type === "text"
|
||||
? `<text
|
||||
x="50%"
|
||||
y="50%"
|
||||
font-size="${iconInfo.icon.size}"
|
||||
font-family="${iconInfo.icon.family}"
|
||||
font-weight="600"
|
||||
fill="${iconInfo.icon.color}"
|
||||
text-anchor="middle"
|
||||
dy="0.35em">
|
||||
${iconInfo.value}
|
||||
</text>`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
iconInfo.type === "gif"
|
||||
? `<image
|
||||
href="${iconInfo.value}"
|
||||
x="${(iconInfo.width - iconInfo.icon.size) / 2}"
|
||||
y="${(iconInfo.height - iconInfo.icon.size) / 2}"
|
||||
height="${iconInfo.icon.size}"
|
||||
width="${iconInfo.icon.size}"
|
||||
crossOrigin="anonymous"
|
||||
/>`
|
||||
: ""
|
||||
}
|
||||
</svg>`,
|
||||
{
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "image/svg+xml",
|
||||
},
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
return NextResponse.json({ message: "Something error" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ export async function GET(req: Request) {
|
||||
content: markdown,
|
||||
format: "markdown",
|
||||
timestamp: Date.now(),
|
||||
payload: `https://wr.do/api/scraping/markdown?url=${link}&key=${custom_apiKey}`,
|
||||
payload: `https://wr.do/api/v1/scraping/markdown?url=${link}&key=${custom_apiKey}`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@@ -112,7 +112,7 @@ export async function GET(req: Request) {
|
||||
lang,
|
||||
author,
|
||||
timestamp: Date.now(),
|
||||
payload: `https://wr.do/api/scraping/meta?url=${link}&key=${custom_apiKey}`,
|
||||
payload: `https://wr.do/api/v1/scraping/meta?url=${link}&key=${custom_apiKey}`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@@ -86,7 +86,7 @@ export async function GET(req: Request) {
|
||||
content: text,
|
||||
format: "text",
|
||||
timestamp: Date.now(),
|
||||
payload: `https://wr.do/api/scraping/text?url=${link}&key=${custom_apiKey}`,
|
||||
payload: `https://wr.do/api/v1/scraping/text?url=${link}&key=${custom_apiKey}`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@@ -28,7 +28,7 @@ export function LinkPreviewer({
|
||||
const handleScrapingScreenshot = async () => {
|
||||
if (url) {
|
||||
const res = await fetch(
|
||||
`/api/scraping/screenshot?url=${url}&key=${apiKey}&width=1200&height=750&viewportWidth=1200&viewportHeight=750`,
|
||||
`/api/v1/scraping/screenshot?url=${url}&key=${apiKey}&width=1200&height=750&viewportWidth=1200&viewportHeight=750`,
|
||||
);
|
||||
if (!res.ok || res.status !== 200) {
|
||||
} else {
|
||||
|
||||
@@ -77,6 +77,11 @@ export const docsConfig: DocsConfig = {
|
||||
href: "/docs/open-api/qrcode",
|
||||
icon: "page",
|
||||
},
|
||||
{
|
||||
title: "Svg Icon API",
|
||||
href: "/docs/open-api/icon",
|
||||
icon: "page",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Svg Icon API
|
||||
description: Simple way to generate your svg icon
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
https://wr.do/api/v1/icon
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
|
||||
- `type` (optional): The type of the icon. Default is `text`.
|
||||
- `w` (optional): The width of the icon. Default is `128`.
|
||||
- `h` (optional): The height of the icon. Default is `64`.
|
||||
- `value`: The value of the icon.
|
||||
- `animate` (optional): Whether to animate the icon. Default is `false`.
|
||||
- `fillType` (optional): The fill type of the icon. Default is `Linear`.
|
||||
- `primaryColor` (optional): The primary color of the icon. Default is `#FC466B`.
|
||||
- `secondaryColor` (optional): The secondary color of the icon. Default is `#3F5EFB`.
|
||||
- `angle` (optional): The angle of the icon. Default is `45`.
|
||||
- `radialGlare` (optional): Whether to apply radial glare to the icon. Default is `false`.
|
||||
- `radius` (optional): The radius of the icon. Default is `12`.
|
||||
- `strokeSize` (optional): The stroke size of the icon. Default is `0`.
|
||||
- `strokeColor` (optional): The stroke color of the icon. Default is `#FFFFFF`.
|
||||
- `strokeOpacity` (optional): The stroke opacity of the icon. Default is `100`.
|
||||
- `color` (optional): The color of the icon. Default is `#FFFFFF`.
|
||||
- `size` (optional): The size of the icon. Default is `15`.
|
||||
- `family` (optional): The font family of the icon. Default is `sans-serif`.
|
||||
|
||||
### Example
|
||||
|
||||
Use in markdown:
|
||||
|
||||

|
||||
|
||||
```bash
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
```bash
|
||||

|
||||
```
|
||||
|
||||
Use in your HTML:
|
||||
|
||||
```html
|
||||
<img
|
||||
src="https://wr.do/api/v1/icon?type=text&w=400&h=35&value=🥰你做出一个很酷的东西出来,想给他起什么名都可以&animate=true&fillType=Linear&primaryColor=%23FC466B&secondaryColor=%233F5EFB&angle=45&radialGlare=false&radius=8&strokeSize=0&strokeColor=%23FFFFFF&strokeOpacity=100&color=%23FFFFFF&size=15&family=cursive"
|
||||
alt="Your SVG Icon"
|
||||
/>
|
||||
```
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ description: Extract website meta information
|
||||
|
||||
API URL:
|
||||
```bash
|
||||
https://wr.do/api/scraping/meta?url=https://www.example.com&key=your_api_key
|
||||
https://wr.do/api/v1/scraping/meta?url=https://www.example.com&key=your_api_key
|
||||
```
|
||||
|
||||
API Response:
|
||||
@@ -27,4 +27,4 @@ API Response:
|
||||
|
||||
Example:
|
||||
|
||||
[https://wr.do/api/scraping/meta?url=https://vmail.dev&key=example_key](https://wr.do/api/scraping/meta?url=https://vmail.dev&key=b6e1c218-c090-434d-ba3f-97fb48fbccd9)
|
||||
[https://wr.do/api/v1/scraping/meta?url=https://vmail.dev&key=example_key](https://wr.do/api/v1/scraping/meta?url=https://vmail.dev&key=b6e1c218-c090-434d-ba3f-97fb48fbccd9)
|
||||
|
||||
@@ -7,7 +7,7 @@ description: Capture website screenshots
|
||||
|
||||
API URL:
|
||||
```bash
|
||||
https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=your_api_key
|
||||
https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=your_api_key
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
@@ -24,22 +24,22 @@ https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=your_api_key
|
||||
|
||||
### Example:
|
||||
|
||||
[https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=example_key](https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=b6e1c218-c090-434d-ba3f-97fb48fbccd9)
|
||||
[https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=example_key](https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=b6e1c218-c090-434d-ba3f-97fb48fbccd9)
|
||||
|
||||
Here are some example combinations of query parameters:
|
||||
|
||||
```bash
|
||||
https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=example_key
|
||||
https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=example_key&width=500&height=500
|
||||
https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=example_key&viewportWidth=1920&viewportHeight=1080&isFullPage=true
|
||||
https://wr.do/api/scraping/screenshot?url=https://vmail.dev&key=example_key&viewportWidth=1920&viewportHeight=1080&isFullPage=true&isDarkMode=true
|
||||
https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=example_key
|
||||
https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=example_key&width=500&height=500
|
||||
https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=example_key&viewportWidth=1920&viewportHeight=1080&isFullPage=true
|
||||
https://wr.do/api/v1/scraping/screenshot?url=https://vmail.dev&key=example_key&viewportWidth=1920&viewportHeight=1080&isFullPage=true&isDarkMode=true
|
||||
```
|
||||
|
||||
Use in your HTML
|
||||
|
||||
```html
|
||||
<img
|
||||
src="https://wr.do/api/scraping/screenshot?url=https://oiov.dev&key=example_key"
|
||||
src="https://wr.do/api/v1/scraping/screenshot?url=https://oiov.dev&key=example_key"
|
||||
alt="Oiov's personal home page screenshot"
|
||||
/>
|
||||
```
|
||||
|
||||
@@ -254,3 +254,10 @@ export function getIpInfo(req: Request) {
|
||||
browser: browser.name || "Unknown",
|
||||
};
|
||||
}
|
||||
|
||||
export function toCamelCase(str: string) {
|
||||
return str
|
||||
.split("-")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join("");
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"crypto": "^1.0.1",
|
||||
"date-fns": "^3.6.0",
|
||||
"lucide-react": "^0.414.0",
|
||||
"lucide-static": "^0.460.0",
|
||||
"minimist": "^1.2.8",
|
||||
"ms": "^2.1.3",
|
||||
"next": "14.2.10",
|
||||
|
||||
Generated
+38
-6
@@ -161,6 +161,9 @@ importers:
|
||||
lucide-react:
|
||||
specifier: ^0.414.0
|
||||
version: 0.414.0(react@18.3.1)
|
||||
lucide-static:
|
||||
specifier: ^0.460.0
|
||||
version: 0.460.0
|
||||
minimist:
|
||||
specifier: ^1.2.8
|
||||
version: 1.2.8
|
||||
@@ -1392,72 +1395,84 @@ packages:
|
||||
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.2':
|
||||
resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
|
||||
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.2':
|
||||
resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
|
||||
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.2':
|
||||
resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
|
||||
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.2':
|
||||
resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
|
||||
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.2':
|
||||
resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
|
||||
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.4':
|
||||
resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.33.4':
|
||||
resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==}
|
||||
engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.4':
|
||||
resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==}
|
||||
engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.33.4':
|
||||
resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.4':
|
||||
resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==}
|
||||
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.4':
|
||||
resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==}
|
||||
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.33.4':
|
||||
resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==}
|
||||
@@ -1605,48 +1620,56 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-arm64-gnu@14.2.10':
|
||||
resolution: {integrity: sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-arm64-musl@14.1.4':
|
||||
resolution: {integrity: sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-linux-arm64-musl@14.2.10':
|
||||
resolution: {integrity: sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-linux-x64-gnu@14.1.4':
|
||||
resolution: {integrity: sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-x64-gnu@14.2.10':
|
||||
resolution: {integrity: sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-x64-musl@14.1.4':
|
||||
resolution: {integrity: sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-linux-x64-musl@14.2.10':
|
||||
resolution: {integrity: sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@14.1.4':
|
||||
resolution: {integrity: sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==}
|
||||
@@ -2853,24 +2876,28 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.3.101':
|
||||
resolution: {integrity: sha512-OGjYG3H4BMOTnJWJyBIovCez6KiHF30zMIu4+lGJTCrxRI2fAjGLml3PEXj8tC3FMcud7U2WUn6TdG0/te2k6g==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.3.101':
|
||||
resolution: {integrity: sha512-/kBMcoF12PRO/lwa8Z7w4YyiKDcXQEiLvM+S3G9EvkoKYGgkkz4Q6PSNhF5rwg/E3+Hq5/9D2R+6nrkF287ihg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-x64-musl@1.3.101':
|
||||
resolution: {integrity: sha512-kDN8lm4Eew0u1p+h1l3JzoeGgZPQ05qDE0czngnjmfpsH2sOZxVj1hdiCwS5lArpy7ktaLu5JdRnx70MkUzhXw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.3.101':
|
||||
resolution: {integrity: sha512-9Wn8TTLWwJKw63K/S+jjrZb9yoJfJwCE2RV5vPCCWmlMf3U1AXj5XuWOLUX+Rp2sGKau7wZKsvywhheWm+qndQ==}
|
||||
@@ -5375,6 +5402,9 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
lucide-static@0.460.0:
|
||||
resolution: {integrity: sha512-X6pIdg7jVxv7YQ/uR241hwhNiztcAfmj181TbcX7HCxxk/3mGaRtAc6b2ftUvQBufbJE6ehgyzO2uVsa604tWg==}
|
||||
|
||||
magic-string@0.25.9:
|
||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||
|
||||
@@ -12070,7 +12100,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)
|
||||
@@ -12106,8 +12136,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
|
||||
@@ -12118,7 +12148,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:
|
||||
@@ -12129,7 +12159,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
|
||||
@@ -12139,7 +12169,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
|
||||
@@ -13216,6 +13246,8 @@ snapshots:
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
lucide-static@0.460.0: {}
|
||||
|
||||
magic-string@0.25.9:
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user