feat: add POST /api/images/from-url route
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,28 @@
|
|||||||
import { randomUUID } from "node:crypto";
|
import { randomUUID } from "node:crypto";
|
||||||
import { mkdir } from "node:fs/promises";
|
import { mkdir } from "node:fs/promises";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { fetchImageFromUrl } from "../services/image.service";
|
||||||
|
|
||||||
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp"];
|
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp"];
|
||||||
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
|
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
|
||||||
|
|
||||||
|
const fromUrlSchema = z.object({ url: z.string().url("Invalid URL") });
|
||||||
|
|
||||||
const app = new Hono();
|
const app = new Hono();
|
||||||
|
|
||||||
|
app.post("/from-url", zValidator("json", fromUrlSchema), async (c) => {
|
||||||
|
const { url } = c.req.valid("json");
|
||||||
|
try {
|
||||||
|
const result = await fetchImageFromUrl(url);
|
||||||
|
return c.json(result, 201);
|
||||||
|
} catch (err) {
|
||||||
|
return c.json({ error: (err as Error).message }, 400);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.post("/", async (c) => {
|
app.post("/", async (c) => {
|
||||||
const body = await c.req.parseBody();
|
const body = await c.req.parseBody();
|
||||||
const file = body.image;
|
const file = body.image;
|
||||||
|
|||||||
26
tests/routes/images.test.ts
Normal file
26
tests/routes/images.test.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { describe, expect, test } from "bun:test";
|
||||||
|
import { Hono } from "hono";
|
||||||
|
import { imageRoutes } from "../../src/server/routes/images";
|
||||||
|
|
||||||
|
const app = new Hono();
|
||||||
|
app.route("/api/images", imageRoutes);
|
||||||
|
|
||||||
|
describe("POST /api/images/from-url", () => {
|
||||||
|
test("returns 400 for missing URL", async () => {
|
||||||
|
const res = await app.request("/api/images/from-url", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
});
|
||||||
|
expect(res.status).toBe(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("returns 400 for invalid URL", async () => {
|
||||||
|
const res = await app.request("/api/images/from-url", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ url: "not-a-url" }),
|
||||||
|
});
|
||||||
|
expect(res.status).toBe(400);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user