48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
import { readFile } from "fs/promises";
|
|
import { NextResponse } from "next/server";
|
|
import path from "path";
|
|
|
|
import { resolveMediaUploadPath } from "@/lib/media-storage";
|
|
|
|
type MediaFileRouteProps = {
|
|
params: Promise<{
|
|
segments: string[];
|
|
}>;
|
|
};
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
const CONTENT_TYPES: Record<string, string> = {
|
|
".ico": "image/x-icon",
|
|
".jpg": "image/jpeg",
|
|
".jpeg": "image/jpeg",
|
|
".png": "image/png",
|
|
".webp": "image/webp",
|
|
".svg": "image/svg+xml",
|
|
".pdf": "application/pdf",
|
|
};
|
|
|
|
export async function GET(_: Request, { params }: MediaFileRouteProps) {
|
|
const { segments } = await params;
|
|
const relativePath = segments.join("/");
|
|
const publicPath = `/uploads/media/${relativePath}`;
|
|
|
|
try {
|
|
const absolutePath = resolveMediaUploadPath(publicPath);
|
|
const fileBuffer = await readFile(absolutePath);
|
|
const contentType = CONTENT_TYPES[path.extname(absolutePath).toLowerCase()] ?? "application/octet-stream";
|
|
|
|
return new NextResponse(fileBuffer, {
|
|
status: 200,
|
|
headers: {
|
|
"Content-Type": contentType,
|
|
"Cache-Control": "public, max-age=31536000, immutable",
|
|
},
|
|
});
|
|
} catch {
|
|
return new NextResponse("Not Found", {
|
|
status: 404,
|
|
});
|
|
}
|
|
}
|