feat(api): normalize logo name

This commit is contained in:
2026-02-22 14:06:15 +01:00
parent 5733342619
commit 3d53660319
3 changed files with 59 additions and 21 deletions

View File

@@ -1,4 +1,8 @@
import { resolve } from "path";
import type { Canvas } from "skia-canvas";
import { getLogoNames } from "../utils/logos";
const normalize = (s: string) => s.toLowerCase().replace(/\s+/g, "");
export default defineEventHandler(async (event) => {
const { format, logo, content } = await getValidatedQuery(
@@ -6,8 +10,26 @@ export default defineEventHandler(async (event) => {
settingsSchema.parse,
);
const logoUrl = logo ? resolve("public", `logos/${logo}.png`) : undefined;
const canvas = await renderQRCodeToCanvas(content, logoUrl);
let canvas: Canvas;
if (logo) {
const names = await getLogoNames();
if (!names)
throw createError({
statusCode: 500,
message: "Could not retrieve logos",
});
const match = names.find((n) => normalize(n) === normalize(logo));
const resolvedLogo = match ?? logo;
canvas = await renderQRCodeToCanvas(
content,
resolve("public", `logos/${resolvedLogo}.png`),
);
} else {
canvas = await renderQRCodeToCanvas(content, undefined);
}
const image = canvas.toBuffer(format);
event.node.res.setHeader("Content-Type", `image/${format}`);

View File

@@ -1,22 +1,9 @@
import { readdir } from "fs/promises";
import { join } from "path";
import { createHash } from "crypto";
import { getLogoNames } from "../utils/logos";
const logosDir = import.meta.dev
? join(process.cwd(), "public/logos")
: join(process.cwd(), ".output/public/logos");
export default defineEventHandler(async () => {
const names = await getLogoNames();
if (!names)
throw createError({ statusCode: 500, message: "Could not retrieve logos" });
export default defineCachedEventHandler(async () => {
const files = await readdir(logosDir);
return files
.filter((f) => f.endsWith(".png"))
.map((f) => f.replace(/\.png$/, ""))
.sort();
}, {
maxAge: 60 * 60 * 24,
getKey: async () => {
const files = await readdir(logosDir);
const key = files.filter((f) => f.endsWith(".png")).sort().join(",");
return createHash("sha256").update(key).digest("hex");
},
return names;
});

29
server/utils/logos.ts Normal file
View File

@@ -0,0 +1,29 @@
import { readdir } from "fs/promises";
import { join } from "path";
import { createHash } from "crypto";
const logosDir = import.meta.dev
? join(process.cwd(), "public/logos")
: join(process.cwd(), ".output/public/logos");
export const getLogoNames = cachedFunction(
async () => {
const files = await readdir(logosDir);
return files
.filter((f) => f.endsWith(".png"))
.map((f) => f.replace(/\.png$/, ""))
.sort();
},
{
maxAge: 60 * 60 * 24,
name: "logoNames",
getKey: async () => {
const files = await readdir(logosDir);
const key = files
.filter((f) => f.endsWith(".png"))
.sort()
.join(",");
return createHash("sha256").update(key).digest("hex");
},
},
);