39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { isValidTripImageName, readTripImage } from "@/lib/trip-image-storage";
|
|
|
|
export const runtime = "nodejs";
|
|
|
|
interface RouteCtx {
|
|
params: Promise<{ name: string }>;
|
|
}
|
|
|
|
/**
|
|
* Sajikan gambar trip dari disk lokal. Publik — gambar trip memang tampil ke
|
|
* semua pengunjung. Di-cache `immutable` selama setahun: nama file
|
|
* content-addressed (hex acak), jadi konten untuk satu nama tidak pernah
|
|
* berubah. Beban render = baca file kecil dari disk, tanpa fetch eksternal.
|
|
*/
|
|
export async function GET(_req: NextRequest, ctx: RouteCtx) {
|
|
const { name } = await ctx.params;
|
|
if (!isValidTripImageName(name)) {
|
|
return NextResponse.json({ error: "Tidak ditemukan" }, { status: 404 });
|
|
}
|
|
|
|
let data: Buffer;
|
|
try {
|
|
data = await readTripImage(name);
|
|
} catch {
|
|
return NextResponse.json({ error: "Tidak ditemukan" }, { status: 404 });
|
|
}
|
|
|
|
return new NextResponse(new Uint8Array(data), {
|
|
status: 200,
|
|
headers: {
|
|
"Content-Type": "image/webp",
|
|
"Content-Length": String(data.length),
|
|
"Cache-Control": "public, max-age=31536000, immutable",
|
|
"X-Content-Type-Options": "nosniff",
|
|
},
|
|
});
|
|
}
|