mgply09ox: Publish an image post through a server upload pipeline

This commit is contained in:
2026-10-19 14:46:13 -06:00
parent fe38682124
commit b4fb345f90
9 changed files with 581 additions and 31 deletions
+30 -4
View File
@@ -1,17 +1,43 @@
import { NextResponse, type NextRequest } from "next/server";
import { SESSION_COOKIE } from "@/lib/cookie";
import { createTextPost } from "@/lib/post-create";
import { createImagePost } from "@/lib/post-media";
// POST /api/posts { content }
// Creates a public text draft on the feed, then publishes it. Returns { id }.
// The create call can report status "draft" for a post already on the home
// feed, so the browser reloads the first page and confirms the id there.
// POST /api/posts
// - JSON { content } -> public text post
// - multipart/form-data content+file -> public image post (one file)
// Both create a public draft on the feed, then publish it, and return { id }.
// For an image the server also uploads the bytes to a presigned URL and confirms
// the upload; the browser never receives the feed token. The create call can
// report status "draft" for a post already on the home feed, so the browser
// reloads the first page and confirms the id there.
// 401 { error: "sign_in" } without a session.
export const runtime = "nodejs";
export async function POST(req: NextRequest) {
const sessionId = req.cookies.get(SESSION_COOKIE)?.value;
const contentType = req.headers.get("content-type") ?? "";
if (contentType.includes("multipart/form-data")) {
let content = "";
let file: File | null = null;
try {
const form = await req.formData();
const c = form.get("content");
content = typeof c === "string" ? c : "";
const f = form.get("file");
file = f instanceof File ? f : null;
} catch {
return NextResponse.json({ error: "bad_file" }, { status: 400 });
}
const result = await createImagePost(sessionId, content, file);
if (!result.ok) {
return NextResponse.json({ error: result.error }, { status: result.status });
}
return NextResponse.json({ id: result.id });
}
let content: unknown = null;
try {
content = ((await req.json()) as { content?: unknown }).content;