From 760b2feb16907d5687f635e687fd427b055ec80e Mon Sep 17 00:00:00 2001 From: June Date: Mon, 12 Jan 2026 18:48:58 +1300 Subject: [PATCH] decent image storage api --- src/pages/api/image/index.ts | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/pages/api/image/index.ts diff --git a/src/pages/api/image/index.ts b/src/pages/api/image/index.ts new file mode 100644 index 0000000..acaa066 --- /dev/null +++ b/src/pages/api/image/index.ts @@ -0,0 +1,49 @@ +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 GET() { + try { + const files = await fs.readdir(uploadDir); + const images = files.filter(file => + /\.(jpg|jpeg|png)$/i.test(file) + ); + + return httpResponse({ images }, 200); + } catch (error) { + return httpResponse({ error: `Failed to read images ${error}` }, 500); + } +} + +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); + } +}