import { v2 as cloudinary } from 'cloudinary' // Configure Cloudinary cloudinary.config({ cloud_name: process.env.CLOUDINARY_CLOUD_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET }) export default defineEventHandler(async (event) => { try { // Parse the multipart form data const formData = await readMultipartFormData(event) if (!formData || formData.length === 0) { throw createError({ statusCode: 400, statusMessage: 'No file provided' }) } // Find the file in the form data const fileData = formData.find(item => item.name === 'file') if (!fileData) { throw createError({ statusCode: 400, statusMessage: 'No file found in upload' }) } // Validate file type if (!fileData.type?.startsWith('image/')) { throw createError({ statusCode: 400, statusMessage: 'Invalid file type. Only images are allowed.' }) } // Convert buffer to base64 for Cloudinary upload const base64File = `data:${fileData.type};base64,${fileData.data.toString('base64')}` // Upload to Cloudinary const result = await cloudinary.uploader.upload(base64File, { folder: 'ghost-guild/events', transformation: [ { quality: 'auto', fetch_format: 'auto' }, { width: 1200, height: 630, crop: 'fill' } // Standard social media dimensions ], allowed_formats: ['jpg', 'png', 'webp', 'gif'], resource_type: 'image' }) return { success: true, secure_url: result.secure_url, public_id: result.public_id, width: result.width, height: result.height, format: result.format, bytes: result.bytes } } catch (error) { console.error('Image upload error:', error) throw createError({ statusCode: error.statusCode || 500, statusMessage: error.statusMessage || 'Image upload failed' }) } })