mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-20 22:03:48 +00:00
7bf0f71f86
Replace the history-driven lib/ + utils/ split with DDD layers: - domain/: aggregate, repositories, value objects, pure parsers/format - application/: feed-service, email-processor, feed-fetcher, stats - infrastructure/: logging, auth, KV/R2 adapters, HTTP, framework glue Pure file relocation; imports updated mechanically. Behaviour unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import { Context } from "hono";
|
|
import { Env } from "../types";
|
|
import { getAttachmentBucket } from "../infrastructure/attachments";
|
|
|
|
export async function handle(c: Context<{ Bindings: Env }>): Promise<Response> {
|
|
const bucket = getAttachmentBucket(c.env);
|
|
if (!bucket) {
|
|
return new Response("Attachment storage not configured", { status: 404 });
|
|
}
|
|
|
|
const attachmentId = c.req.param("attachmentId");
|
|
const filename = c.req.param("filename");
|
|
|
|
if (!attachmentId || !filename) {
|
|
return new Response("Not found", { status: 404 });
|
|
}
|
|
|
|
const object = await bucket.get(attachmentId);
|
|
|
|
if (!object) {
|
|
return new Response("Not found", { status: 404 });
|
|
}
|
|
|
|
const headers = new Headers();
|
|
object.writeHttpMetadata(headers);
|
|
headers.set("etag", object.httpEtag);
|
|
headers.set("Cache-Control", "public, max-age=31536000, immutable");
|
|
|
|
if (!headers.get("Content-Disposition")) {
|
|
headers.set(
|
|
"Content-Disposition",
|
|
`attachment; filename="${decodeURIComponent(filename)}"`,
|
|
);
|
|
}
|
|
|
|
return new Response(object.body, { headers });
|
|
}
|