Created
November 12, 2025 13:25
-
-
Save zanderswai/c770f5e5b72f0b80894d0adf542d2cc5 to your computer and use it in GitHub Desktop.
Customized Payload Media Endpoints: path: api/media
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { NextRequest, NextResponse } from "next/server"; | |
| import { getPayload } from "payload"; | |
| import config from "../../payload.config"; | |
| import { | |
| handleS3Read, | |
| handleS3Upload, | |
| handleS3Delete, | |
| } from "../../storage/s3-adapter"; | |
| /** | |
| * POST /api/media | |
| * Create a new media document with S3 upload | |
| */ | |
| export async function POST(request: NextRequest) { | |
| try { | |
| const payload = await getPayload({ config }); | |
| const formData = await request.formData(); | |
| const id = formData.get("where[and][0][id][in][0]") as string; | |
| const depth = formData.get("depth") as string; | |
| const file = formData.get("file") as File; | |
| const alt = formData.get("alt") as string; | |
| let finalDoc: any; | |
| if (id || depth) { | |
| finalDoc = await FindMediaById(payload, id, depth); | |
| } else if (file || alt) { | |
| finalDoc = await UploadFileToS3(payload, file, alt); | |
| } | |
| return NextResponse.json({ doc: finalDoc }, { status: 201 }); | |
| } catch (error) { | |
| console.error("[Media API] POST error:", error); | |
| return NextResponse.json( | |
| { | |
| error: | |
| error instanceof Error ? error.message : "Failed to upload media", | |
| }, | |
| { status: 500 } | |
| ); | |
| } | |
| } | |
| async function FindMediaById(payload: any, id: string, depth: string) { | |
| const result = await payload.findByID({ | |
| collection: "media", | |
| id: id, | |
| limit: 1, | |
| depth, | |
| }); | |
| if (!result) { | |
| throw new Error("Media not found"); | |
| } | |
| // Apply S3 read to generate signed URLs | |
| const finalDoc = await handleS3Read(result); | |
| // Also process sizes if they exist | |
| if (finalDoc.sizes) { | |
| for (const sizeKey in finalDoc.sizes) { | |
| let size = finalDoc.sizes[sizeKey]; | |
| if (size) { | |
| size = await handleS3Read(size); | |
| finalDoc.sizes[sizeKey] = size; | |
| } | |
| } | |
| } | |
| return finalDoc; | |
| } | |
| async function UploadFileToS3(payload: any, file: File, alt: string) { | |
| if (!file) { | |
| return NextResponse.json({ error: "No file provided" }, { status: 400 }); | |
| } | |
| // Upload file to S3 | |
| const url = await handleS3Upload(file); | |
| // Create media document in database | |
| const mediaDoc = await payload.create({ | |
| collection: "media", | |
| data: { | |
| filename: file.name, | |
| url: url, | |
| alt: alt, | |
| }, | |
| overrideAccess: true, | |
| }); | |
| // Generate signed URL | |
| return await handleS3Read(mediaDoc); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment