import { NextRequest, NextResponse } from 'next/server' export async function GET(req: NextRequest) { const url = req.nextUrl.searchParams.get('url') if (!url) { return NextResponse.json({ error: 'Missing url' }, { status: 400 }) } try { const parsed = new URL(url) if (!['http:', 'https:'].includes(parsed.protocol)) { return NextResponse.json({ error: 'Invalid protocol' }, { status: 400 }) } const controller = new AbortController() const timeout = setTimeout(() => controller.abort(), 8000) const res = await fetch(url, { signal: controller.signal, headers: { 'User-Agent': 'Mozilla/5.0 (compatible; MementoBot/1.0)', 'Accept': 'text/html', }, redirect: 'follow', }) clearTimeout(timeout) if (!res.ok) { return NextResponse.json({ error: 'Fetch failed' }, { status: 502 }) } const html = await res.text() const data = extractMetadata(html, parsed) return NextResponse.json(data, { headers: { 'Cache-Control': 'public, s-maxage=86400' }, }) } catch { return NextResponse.json({ error: 'Failed to fetch' }, { status: 502 }) } } function extractMetadata(html: string, url: URL) { const getMeta = (pattern: RegExp): string | null => { const m = html.match(pattern) return m?.[1]?.trim() || null } const getMetaProperty = (prop: string): string | null => { return getMeta(new RegExp(`]+(?:property|name)=["']${prop}["'][^>]+content=["']([^"']+)["']`, 'i')) || getMeta(new RegExp(`]+content=["']([^"']+)["'][^>]+(?:property|name)=["']${prop}["']`, 'i')) } const title = getMetaProperty('og:title') || getMeta(new RegExp('