'use server' import type { FileValidationConfig, UploadResult } from './types' import type { UploadedFile } from '@admin/types' import { createMedia } from '@admin/actions/media' import { saveUpload } from '@admin/actions/storage' import { requireRole, UserRole } from '@admin/auth/middleware' export async function uploadFiles( formData: FormData, config: FileValidationConfig = {} ): Promise { await requireRole([UserRole.ADMIN, UserRole.EDITOR]) try { const files: File[] = [] const prefix = formData.get('prefix')?.toString() || 'uploads' for (const [key, value] of formData.entries()) { if (value instanceof File && key.startsWith('file')) { files.push(value) } } if (files.length === 0) { return { success: false, error: 'No files provided' } } if (config.maxFiles && files.length > config.maxFiles) { return { success: false, error: `Too many files. Maximum is ${config.maxFiles}` } } const uploadedFiles: UploadedFile[] = [] for (const file of files) { if (config.maxSizeInBytes && file.size > config.maxSizeInBytes) { return { success: false, error: `File ${file.name} exceeds size limit` } } if (config.allowedTypes && !config.allowedTypes.includes(file.type)) { return { success: false, error: `File type ${file.type} is not allowed` } } const arrayBuffer = await file.arrayBuffer() const buffer = Buffer.from(arrayBuffer) const { key, url } = await saveUpload({ buffer, filename: file.name, contentType: file.type, contentLength: file.size, prefix }) const mediaResult = await createMedia({ url, filename: file.name, contentType: file.type, size: file.size, width: null, height: null, alt: null, tags: null }) if (!mediaResult.success || !mediaResult.media) { return { success: false, error: mediaResult.error ?? 'Failed to create media record' } } uploadedFiles.push({ id: mediaResult.media.id, key, url, filename: file.name, size: file.size, contentType: file.type }) } return { success: true, files: uploadedFiles } } catch (error) { const message = error instanceof Error ? error.message : 'Failed to upload files' return { success: false, error: message } } }