import { FastifyPluginAsync } from 'fastify' import { createWriteStream, mkdirSync } from 'fs' import { join, extname } from 'path' import { randomUUID } from 'crypto' import { pipeline } from 'stream/promises' const UPLOADS_DIR = process.env.UPLOADS_DIR ?? join(process.cwd(), 'uploads') // Ensure uploads directory exists mkdirSync(UPLOADS_DIR, { recursive: true }) const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'] const MAX_SIZE = 10 * 1024 * 1024 // 10MB const upload: FastifyPluginAsync = async (fastify) => { // POST /api/upload — upload a single image, returns { url } fastify.post( '/api/upload', { onRequest: [fastify.authenticate] }, async (request, reply) => { const data = await request.file({ limits: { fileSize: MAX_SIZE } }) if (!data) return reply.code(400).send({ error: 'No file provided' }) if (!ALLOWED_TYPES.includes(data.mimetype)) { return reply.code(400).send({ error: 'Only images allowed (jpg, png, webp, gif)' }) } const ext = extname(data.filename) || '.jpg' const filename = `${randomUUID()}${ext}` const filepath = join(UPLOADS_DIR, filename) await pipeline(data.file, createWriteStream(filepath)) const host = (request.headers['x-forwarded-proto'] ?? 'https') + '://' + (request.headers['x-forwarded-host'] ?? request.headers.host ?? 'api.hotelsync.ru') return { url: `${host}/uploads/${filename}` } }, ) } export default upload