diff --git a/src/index.ts b/src/index.ts index 147b272..f3f0d7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { Elysia, t } from "elysia" +import { Elysia, redirect, t } from "elysia" import ExifReader from "exifreader" import { exists, mkdir } from "fs/promises" @@ -52,18 +52,10 @@ async function saveMetadata(data: PhotoMetadata[]): Promise { * Extracts EXIF data from an uploaded file. */ async function getExifData(file: File): Promise { - try { - const buffer = await file.arrayBuffer() - // Set options to not parse maker notes or unknown tags for speed - const tags = ExifReader.load(buffer, { - expanded: true, - includeUnknown: false, - }) - return tags - } catch (e) { - console.error(`Error parsing EXIF for ${file.name}:`, e) - return { error: "Could not parse EXIF data." } - } + return ExifReader.load(await file.arrayBuffer(), { + expanded: true, + includeUnknown: false, + }) } // --- Elysia Server --- @@ -80,8 +72,6 @@ function checkHeaderKey(headers: Record, expectList: } export const app = new Elysia() - .get("/", () => "Running!") - // Error handling: Return status code and message .onError(({ error, status }) => { if (error instanceof HttpError) { @@ -91,16 +81,17 @@ export const app = new Elysia() // else return status(500, { error: "Internal Server Error" }) else throw error }) + .get("/", ({ redirect }) => redirect("https://aza.moe/photo")) .post("/upload", async ({ body, headers, status }) => { - const { id, owner_key, photo, edited_photo } = body + const { owner_key, photo, edited_photo } = body checkHeaderKey(headers) - // 2. Check for existing ID - const metadata = await getMetadata() - if (metadata.find((m) => m.id === id)) done(409, "This ID already exists") + // Generate an ID of 8 characters + const id = Math.random().toString(36).substring(2, 10) + let metadata = await getMetadata() - // 3. Process and save files + // Process and save files // We use {id}-1 and {id}-2 as requested by "{id}-{number}" const originalExt = photo.name.split(".").pop() || "jpg" const editedExt = edited_photo.name.split(".").pop() || "jpg" @@ -119,8 +110,7 @@ export const app = new Elysia() // 4. Create new metadata entry const newEntry: PhotoMetadata = { - id: id, - owner_key: owner_key, + id, owner_key, upload_time: new Date().toISOString(), original_photo: { filename: photo.name, @@ -142,7 +132,6 @@ export const app = new Elysia() }, { // --- Validation Schema --- body: t.Object({ - id: t.String(), owner_key: t.String(), photo: t.File({ type: ["image/jpeg", "image/png", "image/webp", "image/avif", "image/heic", "image/heif"], @@ -217,6 +206,19 @@ export const app = new Elysia() body: t.Object({ id: t.String(), key: t.String(), field: t.String(), value: t.Any() }) }) + // Redirect for short links. ID can be either ID or owner_key + .get("/:id", async ({ params, redirect }) => { + const { id } = params + const metadata = await getMetadata() + + const photo = metadata.find((p) => p.id === id) || metadata.find((p) => p.owner_key === id) + if (!photo || photo.hide === true) done(404, "Photo not found") + + return redirect(`https://aza.moe/photo/${photo.id}`) + }, { + params: t.Object({ id: t.String() }) + }) + .listen(3000) console.log(`🦊 Elysia server running at http://${app.server?.hostname}:${app.server?.port}`)