Spaces:
Running
Running
File size: 2,290 Bytes
992a8de bbbed00 07eb9f0 bbbed00 07eb9f0 992a8de 07eb9f0 992a8de 07eb9f0 992a8de bbbed00 992a8de bbbed00 992a8de |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
import ChatThumbnail from "./ChatThumbnail.svelte";
import { collections } from "$lib/server/database";
import { error, type RequestHandler } from "@sveltejs/kit";
import { ObjectId } from "mongodb";
import type { SvelteComponent } from "svelte";
import { Resvg } from "@resvg/resvg-js";
import satori from "satori";
import { html } from "satori-html";
import InterRegular from "../../../../../static/fonts/Inter-Regular.ttf";
import InterBold from "../../../../../static/fonts/Inter-Bold.ttf";
import sharp from "sharp";
export const GET: RequestHandler = (async ({ params }) => {
const assistant = await collections.assistants.findOne({
_id: new ObjectId(params.assistantId),
});
if (!assistant) {
throw error(404, "Assistant not found.");
}
let avatar = "";
const fileId = collections.bucket.find({ filename: assistant._id.toString() });
const file = await fileId.next();
if (file) {
avatar = await (async () => {
const fileStream = collections.bucket.openDownloadStream(file?._id);
const fileBuffer = await new Promise<Buffer>((resolve, reject) => {
const chunks: Uint8Array[] = [];
fileStream.on("data", (chunk) => chunks.push(chunk));
fileStream.on("error", reject);
fileStream.on("end", () => resolve(Buffer.concat(chunks)));
});
return fileBuffer;
})()
.then(async (buf) => sharp(buf).jpeg().toBuffer()) // convert to jpeg bc satori png is really slow
.then(async (buf) => "data:image/jpeg;base64," + buf.toString("base64"));
}
const renderedComponent = (ChatThumbnail as unknown as SvelteComponent).render({
name: assistant.name,
description: assistant.description,
createdByName: assistant.createdByName,
avatar,
});
const reactLike = html(
"<style>" + renderedComponent.css.code + "</style>" + renderedComponent.html
);
const svg = await satori(reactLike, {
width: 1200,
height: 648,
fonts: [
{
name: "Inter",
data: InterRegular as unknown as ArrayBuffer,
weight: 500,
},
{
name: "Inter",
data: InterBold as unknown as ArrayBuffer,
weight: 700,
},
],
});
const png = new Resvg(svg, {
fitTo: { mode: "original" },
})
.render()
.asPng();
return new Response(png, {
headers: {
"Content-Type": "image/png",
},
});
}) satisfies RequestHandler;
|