import crypto from 'node:crypto' import fs from 'node:fs' import path from 'node:path' export function safeImageExt(filename) { const ext = path.extname(String(filename || '')).toLowerCase() const allowed = new Set(['.png', '.jpg', '.jpeg', '.webp']) return allowed.has(ext) ? ext : null } export function uploadError(message, statusCode = 400) { const err = new Error(message) err.statusCode = statusCode return err } export async function persistMultipartImages(request, { maxFiles = 10 } = {}) { if (!request.isMultipart()) { throw uploadError('Ожидается multipart/form-data') } const uploadsDir = path.join(process.cwd(), 'uploads') await fs.promises.mkdir(uploadsDir, { recursive: true }) const urls = [] const parts = request.parts() for await (const part of parts) { if (part.type !== 'file') continue if (urls.length >= maxFiles) { throw uploadError(`Можно загрузить не более ${maxFiles} файл(ов)`) } const ext = safeImageExt(part.filename) if (!ext) { throw uploadError('Разрешены только файлы: png, jpg, jpeg, webp') } const fileName = `${crypto.randomUUID()}${ext}` const fullPath = path.join(uploadsDir, fileName) await fs.promises.writeFile(fullPath, await part.toBuffer()) urls.push(`/uploads/${fileName}`) } return urls }