import { NextResponse } from "next/server"; import fs from "fs/promises"; import path from "path"; import sharp from "sharp"; export async function GET(request, { params }) { const { searchParams } = new URL(request.url); const query = Object.fromEntries(searchParams.entries()); try { const paths = (await params).path.join("/"); const fullpath = path.join(process.cwd(), "public/media", paths); await fs.access(fullpath); const ext = path.extname(fullpath).toLowerCase(); const mimeTypes = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", ".webp": "image/webp", ".svg": "image/svg+xml", }; let imageBuffer = await fs.readFile(fullpath); if (ext !== ".svg") { const width = query.w ? parseInt(query.w) : null; const height = query.h ? parseInt(query.h) : null; imageBuffer = await sharp(imageBuffer).resize(width, height).toBuffer(); } const stat = await fs.stat(fullpath); return new NextResponse(imageBuffer, { status: 200, headers: { "Content-Type": mimeTypes[ext] || "application/octet-stream", "Access-Control-Allow-Origin": "*", "Content-Length": imageBuffer.length.toString(), "Cache-Control": "public, max-age=31536000, immutable", "Last-Modified": stat.mtime.toUTCString(), ETag: `"${stat.mtime.getTime()}-${imageBuffer.length}"`, }, }); } catch (error) { const width = query.w ? parseInt(query.w) : 400; const height = query.h ? parseInt(query.h) : 200; const text = searchParams.get("text") || "Not Found"; const bg = searchParams.get("bg") || "#eee"; const color = searchParams.get("color") || "#999"; let fontSize = searchParams.get("font-size") ? parseInt(searchParams.get("font-size")) : Math.floor(height * 0.3); const factor = 0.6; const estimatedTextWidth = text.length * fontSize * factor; if (estimatedTextWidth > width * 0.9) { fontSize = Math.floor((width * 0.9) / (text.length * factor)); } // langsung bikin SVG string const svgImage = ` ${text} `; return new NextResponse(svgImage, { status: 200, headers: { "Content-Type": "image/svg+xml", "Cache-Control": "no-store", }, }); } }