38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import type { APIContext } from 'astro';
|
|
import { promises as fs } from 'fs';
|
|
import { join } from 'path';
|
|
import { randomBytes } from 'crypto';
|
|
import { httpResponse } from '../../../utils/response';
|
|
import 'dotenv/config'
|
|
|
|
const uploadDir = process.env.UPLOAD_DIR!;
|
|
|
|
|
|
export async function POST({ request }: APIContext) {
|
|
try {
|
|
const formData = await request.formData();
|
|
const file = formData.get('image');
|
|
|
|
if (!file || !(file instanceof File)) {
|
|
return httpResponse({ error: 'No image provided' }, 400);
|
|
}
|
|
|
|
if (!file.type.match(/^image\/(jpeg|jpg|png)$/)) {
|
|
return httpResponse({ error: 'Only JPG and PNG allowed' }, 400);
|
|
}
|
|
|
|
const ext = file.name.split('.').pop();
|
|
const filename = `${randomBytes(16).toString('hex')}.${ext}`;
|
|
const filepath = join(uploadDir, filename);
|
|
|
|
// Save file
|
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
await fs.writeFile(filepath, buffer);
|
|
|
|
return httpResponse({ filename, success: true }, 201);
|
|
|
|
} catch (error) {
|
|
return httpResponse({ error: `Failed to upload image, ${error}` }, 500);
|
|
}
|
|
}
|