import { createHash } from 'node:crypto' import { eq } from 'drizzle-orm' import { linkPreviews } from '../db/schema' const CACHE_TTL_MS = 1000 * 60 * 60 * 24 export default defineEventHandler(async (event) => { const url = String(getQuery(event).url ?? '') if (!/^https?:\/\//i.test(url) || url.length > 2048) { throw createError({ statusCode: 400, statusMessage: 'Ungültige URL' }) } const urlHash = createHash('sha256').update(url).digest('hex') const db = useDb() const [cached] = await db .select() .from(linkPreviews) .where(eq(linkPreviews.urlHash, urlHash)) .limit(1) if (cached && Date.now() - cached.fetchedAt.getTime() < CACHE_TTL_MS) { return { image: cached.image, title: cached.title } } const preview = await fetchLinkPreview(url) // Vorschaubild lokal speichern — die Remote-URL ist nicht stabil const image = preview.image ? (await savePreviewImage(`links/${urlHash}`, preview.image)) ?? preview.image : null await db .insert(linkPreviews) .values({ urlHash, url, image, title: preview.title, fetchedAt: new Date() }) .onDuplicateKeyUpdate({ set: { image, title: preview.title, fetchedAt: new Date() }, }) return { image, title: preview.title } })