From 0e60901e3915dd66019e4f4080b112d73671d2c0 Mon Sep 17 00:00:00 2001 From: shrimbly Date: Wed, 18 Feb 2026 22:09:42 +1300 Subject: [PATCH] refactor: extract buildMediaResponse and capabilitiesForMediaType helpers Deduplicate the media response block (3d/video/audio/image) that was copy-pasted across all 4 provider branches, and the mediaType-to- capabilities ternary chain repeated 4 times. Co-Authored-By: Claude Opus 4.6 --- src/app/api/generate/route.ts | 225 +++++++++------------------------- 1 file changed, 61 insertions(+), 164 deletions(-) diff --git a/src/app/api/generate/route.ts b/src/app/api/generate/route.ts index e91e2f48..8195f8f3 100644 --- a/src/app/api/generate/route.ts +++ b/src/app/api/generate/route.ts @@ -37,6 +37,51 @@ interface MultiProviderGenerateRequest extends GenerateRequest { } +function buildMediaResponse(output: { type: string; data: string; url?: string }): NextResponse { + if (output.type === "3d") { + return NextResponse.json({ + success: true, + model3dUrl: output.url, + contentType: "3d", + }); + } + + if (output.type === "video") { + const isLarge = !output.data && output.url; + return NextResponse.json({ + success: true, + video: isLarge ? undefined : output.data, + videoUrl: isLarge ? output.url : undefined, + contentType: "video", + }); + } + + if (output.type === "audio") { + const isLarge = !output.data && output.url; + return NextResponse.json({ + success: true, + audio: isLarge ? undefined : output.data, + audioUrl: isLarge ? output.url : undefined, + contentType: "audio", + }); + } + + return NextResponse.json({ + success: true, + image: output.data, + contentType: "image", + }); +} + +function capabilitiesForMediaType(mediaType?: string): string[] { + const map: Record = { + audio: ["text-to-audio"], + video: ["text-to-video"], + "3d": ["text-to-3d"], + }; + return map[mediaType ?? ""] ?? ["text-to-image"]; +} + export async function POST(request: NextRequest) { const requestId = Math.random().toString(36).substring(7); console.log(`\n[API:${requestId}] ========== NEW GENERATE REQUEST ==========`); @@ -125,7 +170,7 @@ export async function POST(request: NextRequest) { id: selectedModel!.modelId, name: selectedModel!.displayName, provider: "replicate", - capabilities: mediaType === "audio" ? ["text-to-audio"] : mediaType === "video" ? ["text-to-video"] : mediaType === "3d" ? ["text-to-3d"] : ["text-to-image"], + capabilities: capabilitiesForMediaType(mediaType), description: null, }, prompt: prompt || "", @@ -146,53 +191,16 @@ export async function POST(request: NextRequest) { ); } - // Return first output (image or video) + // Return first output const output = result.outputs?.[0]; if (!output?.data && !output?.url) { return NextResponse.json( - { - success: false, - error: "No output in generation result", - }, + { success: false, error: "No output in generation result" }, { status: 500 } ); } - // Return appropriate fields based on output type - if (output.type === "3d") { - return NextResponse.json({ - success: true, - model3dUrl: output.url, - contentType: "3d", - }); - } - - if (output.type === "video") { - // Large videos have data="" with url set; normal videos have base64 data - const isLargeVideo = !output.data && output.url; - return NextResponse.json({ - success: true, - video: isLargeVideo ? undefined : output.data, - videoUrl: isLargeVideo ? output.url : undefined, - contentType: "video", - }); - } - - if (output.type === "audio") { - const isLargeAudio = !output.data && output.url; - return NextResponse.json({ - success: true, - audio: isLargeAudio ? undefined : output.data, - audioUrl: isLargeAudio ? output.url : undefined, - contentType: "audio", - }); - } - - return NextResponse.json({ - success: true, - image: output.data, - contentType: "image", - }); + return buildMediaResponse(output); } if (provider === "fal") { @@ -230,7 +238,7 @@ export async function POST(request: NextRequest) { id: selectedModel!.modelId, name: selectedModel!.displayName, provider: "fal", - capabilities: mediaType === "audio" ? ["text-to-audio"] : mediaType === "video" ? ["text-to-video"] : mediaType === "3d" ? ["text-to-3d"] : ["text-to-image"], + capabilities: capabilitiesForMediaType(mediaType), description: null, }, prompt: prompt || "", @@ -251,53 +259,16 @@ export async function POST(request: NextRequest) { ); } - // Return first output (image or video) + // Return first output const output = result.outputs?.[0]; if (!output?.data && !output?.url) { return NextResponse.json( - { - success: false, - error: "No output in generation result", - }, + { success: false, error: "No output in generation result" }, { status: 500 } ); } - // Return appropriate fields based on output type - if (output.type === "3d") { - return NextResponse.json({ - success: true, - model3dUrl: output.url, - contentType: "3d", - }); - } - - if (output.type === "video") { - // Large videos have data="" with url set; normal videos have base64 data - const isLargeVideo = !output.data && output.url; - return NextResponse.json({ - success: true, - video: isLargeVideo ? undefined : output.data, - videoUrl: isLargeVideo ? output.url : undefined, - contentType: "video", - }); - } - - if (output.type === "audio") { - const isLargeAudio = !output.data && output.url; - return NextResponse.json({ - success: true, - audio: isLargeAudio ? undefined : output.data, - audioUrl: isLargeAudio ? output.url : undefined, - contentType: "audio", - }); - } - - return NextResponse.json({ - success: true, - image: output.data, - contentType: "image", - }); + return buildMediaResponse(output); } if (provider === "kie") { @@ -339,7 +310,7 @@ export async function POST(request: NextRequest) { id: selectedModel!.modelId, name: selectedModel!.displayName, provider: "kie", - capabilities: mediaType === "audio" ? ["text-to-audio"] : mediaType === "video" ? ["text-to-video"] : mediaType === "3d" ? ["text-to-3d"] : ["text-to-image"], + capabilities: capabilitiesForMediaType(mediaType), description: null, }, prompt: prompt || "", @@ -360,53 +331,16 @@ export async function POST(request: NextRequest) { ); } - // Return first output (image or video) + // Return first output const output = result.outputs?.[0]; if (!output?.data && !output?.url) { return NextResponse.json( - { - success: false, - error: "No output in generation result", - }, + { success: false, error: "No output in generation result" }, { status: 500 } ); } - // Return appropriate fields based on output type - if (output.type === "3d") { - return NextResponse.json({ - success: true, - model3dUrl: output.url, - contentType: "3d", - }); - } - - if (output.type === "video") { - // Large videos have data="" with url set; normal videos have base64 data - const isLargeVideo = !output.data && output.url; - return NextResponse.json({ - success: true, - video: isLargeVideo ? undefined : output.data, - videoUrl: isLargeVideo ? output.url : undefined, - contentType: "video", - }); - } - - if (output.type === "audio") { - const isLargeAudio = !output.data && output.url; - return NextResponse.json({ - success: true, - audio: isLargeAudio ? undefined : output.data, - audioUrl: isLargeAudio ? output.url : undefined, - contentType: "audio", - }); - } - - return NextResponse.json({ - success: true, - image: output.data, - contentType: "image", - }); + return buildMediaResponse(output); } if (provider === "wavespeed") { @@ -448,7 +382,7 @@ export async function POST(request: NextRequest) { id: selectedModel!.modelId, name: selectedModel!.displayName, provider: "wavespeed", - capabilities: mediaType === "audio" ? ["text-to-audio"] : mediaType === "video" ? ["text-to-video"] : mediaType === "3d" ? ["text-to-3d"] : ["text-to-image"], + capabilities: capabilitiesForMediaType(mediaType), description: null, }, prompt: prompt || "", @@ -469,53 +403,16 @@ export async function POST(request: NextRequest) { ); } - // Return first output (image or video) + // Return first output const output = result.outputs?.[0]; if (!output?.data && !output?.url) { return NextResponse.json( - { - success: false, - error: "No output in generation result", - }, + { success: false, error: "No output in generation result" }, { status: 500 } ); } - // Return appropriate fields based on output type - if (output.type === "3d") { - return NextResponse.json({ - success: true, - model3dUrl: output.url, - contentType: "3d", - }); - } - - if (output.type === "video") { - // Large videos have data="" with url set; normal videos have base64 data - const isLargeVideo = !output.data && output.url; - return NextResponse.json({ - success: true, - video: isLargeVideo ? undefined : output.data, - videoUrl: isLargeVideo ? output.url : undefined, - contentType: "video", - }); - } - - if (output.type === "audio") { - const isLargeAudio = !output.data && output.url; - return NextResponse.json({ - success: true, - audio: isLargeAudio ? undefined : output.data, - audioUrl: isLargeAudio ? output.url : undefined, - contentType: "audio", - }); - } - - return NextResponse.json({ - success: true, - image: output.data, - contentType: "image", - }); + return buildMediaResponse(output); } // Default: Use Gemini