Files
soroushasadi/app/api/admin/upload/route.ts
T
soroush.asadi add78d8460
ci / build (push) Failing after 23s
deploy / deploy (push) Failing after 10m12s
first commit
2026-05-31 12:47:02 +03:30

45 lines
1.4 KiB
TypeScript

import { NextResponse } from 'next/server';
import { mkdir, writeFile } from 'node:fs/promises';
import { extname, join } from 'node:path';
import { randomUUID } from 'node:crypto';
import { UPLOADS_DIR } from '@/lib/db/store';
export const runtime = 'nodejs';
const ALLOWED = new Set(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg', '.avif']);
const MAX_BYTES = 8 * 1024 * 1024; // 8 MB
export async function POST(req: Request) {
let form: FormData;
try {
form = await req.formData();
} catch {
return NextResponse.json({ error: 'expected multipart form' }, { status: 400 });
}
const file = form.get('file');
if (!(file instanceof File)) {
return NextResponse.json({ error: 'no file' }, { status: 400 });
}
if (file.size > MAX_BYTES) {
return NextResponse.json({ error: 'file too large (max 8MB)' }, { status: 413 });
}
const ext = extname(file.name).toLowerCase();
if (!ALLOWED.has(ext)) {
return NextResponse.json({ error: `unsupported type ${ext}` }, { status: 415 });
}
const name = `${Date.now()}-${randomUUID().slice(0, 8)}${ext}`;
const buffer = Buffer.from(await file.arrayBuffer());
try {
await mkdir(UPLOADS_DIR, { recursive: true });
await writeFile(join(UPLOADS_DIR, name), buffer);
} catch {
return NextResponse.json({ error: 'write failed' }, { status: 500 });
}
return NextResponse.json({ url: `/api/uploads/${name}`, name });
}