forked from creations/profilePage
merge from
creations/profilePage#1 change route and change a couple things
This commit is contained in:
parent
ab0a5c6c09
commit
2c91a8dcc9
2 changed files with 69 additions and 37 deletions
69
src/routes/api/colors.ts
Normal file
69
src/routes/api/colors.ts
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import { fetch } from "bun";
|
||||||
|
import { Vibrant } from "node-vibrant/node";
|
||||||
|
|
||||||
|
type Palette = Awaited<ReturnType<typeof Vibrant.prototype.getPalette>>;
|
||||||
|
|
||||||
|
const routeDef: RouteDef = {
|
||||||
|
method: "GET",
|
||||||
|
accepts: "*/*",
|
||||||
|
returns: "application/json",
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handler(request: ExtendedRequest): Promise<Response> {
|
||||||
|
const { url } = request.query;
|
||||||
|
|
||||||
|
if (!url) {
|
||||||
|
return Response.json({ error: "URL is required" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof url !== "string" || !url.startsWith("http")) {
|
||||||
|
return Response.json({ error: "Invalid URL" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let res: Response;
|
||||||
|
try {
|
||||||
|
res = await fetch(url);
|
||||||
|
} catch {
|
||||||
|
return Response.json(
|
||||||
|
{ error: "Failed to fetch image" },
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
return Response.json(
|
||||||
|
{ error: "Image fetch returned error" },
|
||||||
|
{ status: res.status },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const type: string | null = res.headers.get("content-type");
|
||||||
|
if (!type?.startsWith("image/")) {
|
||||||
|
return Response.json({ error: "Not an image" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const buffer: Buffer = Buffer.from(await res.arrayBuffer());
|
||||||
|
const base64: string = buffer.toString("base64");
|
||||||
|
const colors: Palette = await Vibrant.from(buffer).getPalette();
|
||||||
|
|
||||||
|
const payload: {
|
||||||
|
img: string;
|
||||||
|
colors: Palette;
|
||||||
|
} = {
|
||||||
|
img: `data:${type};base64,${base64}`,
|
||||||
|
colors,
|
||||||
|
};
|
||||||
|
|
||||||
|
const compressed: Uint8Array = Bun.gzipSync(JSON.stringify(payload));
|
||||||
|
|
||||||
|
return new Response(compressed, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Content-Encoding": "gzip",
|
||||||
|
"Cache-Control": "public, max-age=31536000, immutable",
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export { handler, routeDef };
|
|
@ -1,37 +0,0 @@
|
||||||
import { Vibrant } from "node-vibrant/node";
|
|
||||||
|
|
||||||
const routeDef: RouteDef = {
|
|
||||||
method: "GET",
|
|
||||||
accepts: "*/*",
|
|
||||||
returns: "application/json",
|
|
||||||
};
|
|
||||||
|
|
||||||
async function handler(request: ExtendedRequest): Promise<Response> {
|
|
||||||
const req = await fetch(request.query.url);
|
|
||||||
|
|
||||||
if (!req.ok) {
|
|
||||||
return Response.json({ error: "Failed to fetch image" }, { status: 500 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = req.headers.get("content-type")
|
|
||||||
if (!type?.includes("image/")) {
|
|
||||||
return Response.json({ error: "Not an image" }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageBuffer = await req.arrayBuffer()
|
|
||||||
|
|
||||||
const colors = await Vibrant.from(Buffer.from(imageBuffer)).getPalette();
|
|
||||||
|
|
||||||
return new Response(Bun.gzipSync(JSON.stringify({
|
|
||||||
img: `data:${type};base64,${Buffer.from(imageBuffer).toString("base64")}`,
|
|
||||||
colors,
|
|
||||||
})), {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Content-Encoding": "gzip",
|
|
||||||
"Cache-Control": "public, max-age=31536000, immutable",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export { handler, routeDef };
|
|
Loading…
Add table
Reference in a new issue