import { jsonError } from "@/lib/server/api"; import { authenticatePublicApiRequest } from "@/lib/server/public-api-auth"; import { getPublicApiAsset } from "@/lib/server/public-api-assets"; import { publicApiError } from "@/lib/server/public-api-response"; import { readAssetForDownload } from "@/lib/server/storage"; export const runtime = "nodejs"; export async function GET(request: Request, context: { params: Promise<{ id: string }> }) { try { const client = authenticatePublicApiRequest(request); const { id } = await context.params; const asset = await getPublicApiAsset(client.id, id); if (!asset) return jsonError("Asset not found.", 404); const file = await readAssetForDownload(asset); if (!file) return jsonError("Asset file is not downloadable.", 404); return new Response(new Uint8Array(file.bytes), { headers: { "Content-Type": file.contentType, "Content-Length": String(file.bytes.length), "Content-Disposition": contentDisposition(asset.name), "Cache-Control": "private, no-store" } }); } catch (error) { return publicApiError(error); } } function contentDisposition(fileName: string): string { const clean = fileName.replace(/[\r\n/\\]/g, "_").trim() || "download"; const ascii = clean.replace(/[^\x20-\x7E]/g, "_").replace(/"/g, "_"); return `attachment; filename="${ascii}"; filename*=UTF-8''${encodeURIComponent(clean)}`; }