import { createRouter } from '../../create-router'; import { mkdir } from 'node:fs/promises'; import { join } from 'node:path'; import { getTmpAttachmentsDir, getAttachmentsDir } from '@@/data-path'; const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB export const uploadRouter = createRouter(); uploadRouter.post('/', async (ctx) => { const user = ctx.get('user'); const body = ctx.get('body') as Record; const file = body.file as File | null; const sessionId = (body.sessionId as string) || null; if (!file || !(file instanceof File)) { return ctx.json({ error: 'file is required' }, 400); } if (!file.type.startsWith('image/')) { return ctx.json({ error: 'Only image files are allowed' }, 400); } if (file.size > MAX_FILE_SIZE) { return ctx.json({ error: 'File exceeds 5 MB limit' }, 400); } try { const buffer = Buffer.from(await file.arrayBuffer()); const ext = file.name.split('.').pop() || 'png'; const filename = `${crypto.randomUUID()}.${ext}`; let saveDir: string; if (sessionId) { saveDir = getAttachmentsDir(user.email, sessionId); } else { saveDir = getTmpAttachmentsDir(user.email); } await mkdir(saveDir, { recursive: true }); await Bun.write(join(saveDir, filename), buffer); const base64 = buffer.toString('base64'); const dataUrl = `data:${file.type};base64,${base64}`; return ctx.json({ filename: file.name, dataUrl, attachmentId: filename }); } catch (err) { const message = err instanceof Error ? err.message : 'Upload failed'; return ctx.json({ error: message }, 500); } });