| import { |
| optimizeImage, |
| supportsWebpOptimization, |
| } from "./image-optimizer"; |
|
|
| |
| |
| |
| |
| |
| export async function uploadImage(file: File): Promise<string> { |
| |
| if (supportsWebpOptimization() && file.type.startsWith("image/")) { |
| try { |
| const optimized = await optimizeImage(file); |
| const urls: string[] = []; |
|
|
| for (const variant of optimized.variants) { |
| const ext = "webp"; |
| const name = file.name.replace(/\.[^.]+$/, ""); |
| const optimizedFile = new File( |
| [variant.blob], |
| `${name}-${variant.suffix}.${ext}`, |
| { type: "image/webp" } |
| ); |
|
|
| const url = await uploadSingleFile(optimizedFile); |
| urls.push(url); |
| } |
|
|
| |
| return urls[urls.length - 1]; |
| } catch (err) { |
| console.warn("[upload] Client-side optimization failed, uploading original:", err); |
| } |
| } |
|
|
| return uploadSingleFile(file); |
| } |
|
|
| async function uploadSingleFile(file: File): Promise<string> { |
| const form = new FormData(); |
| form.append("file", file); |
|
|
| const res = await fetch("/api/upload", { method: "POST", body: form }); |
|
|
| if (!res.ok) { |
| const text = await res.text(); |
| throw new Error(`Upload failed: ${text}`); |
| } |
|
|
| const { url } = await res.json(); |
| return url; |
| } |
|
|