Files
nanami-web/src/app/api/software/download/[id]/route.ts
2026-03-18 17:13:27 +08:00

59 lines
1.5 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { readFile, stat } from "fs/promises";
import path from "path";
export async function GET(
_request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const sv = await prisma.softwareVersion.findUnique({
where: { id },
include: { software: { select: { slug: true } } },
});
if (!sv) {
return NextResponse.json({ error: "Version not found" }, { status: 404 });
}
await prisma.softwareVersion.update({
where: { id },
data: { downloadCount: { increment: 1 } },
});
if (sv.downloadType === "url" && sv.externalUrl) {
return new Response(null, {
status: 302,
headers: { Location: sv.externalUrl },
});
}
if (sv.filePath) {
const filePath = path.join(process.cwd(), sv.filePath);
try {
await stat(filePath);
} catch {
return NextResponse.json({ error: "File not found" }, { status: 404 });
}
const fileBuffer = await readFile(filePath);
const ext = path.extname(sv.filePath);
const fileName = `${sv.software.slug}-v${sv.version}${ext}`;
return new NextResponse(fileBuffer, {
headers: {
"Content-Type": "application/octet-stream",
"Content-Disposition": `attachment; filename="${fileName}"`,
"Content-Length": fileBuffer.length.toString(),
},
});
}
return NextResponse.json(
{ error: "No download source available" },
{ status: 404 }
);
}