import { Router } from "@oak/oak"; import { APIErrorCode, type APIResponse, type PaginatedData, } from "../../shared/api.ts"; import { APIException } from "../lib/api-exception.ts"; import type { Category } from "../../shared/category.ts"; import type { Dump } from "../../shared/dump.ts"; import { isCreateCategoryRequest, isUpdateCategoryRequest, } from "../validators/category.ts"; import { authMiddleware, requirePermission } from "../middleware/auth.ts"; import { parseOptionalAuth } from "../lib/auth.ts"; import { parsePagination } from "../lib/pagination.ts"; import { createCategory, deleteCategory, getCategoryBySlug, listCategories, listDumpsByCategory, updateCategory, } from "../services/category-service.ts"; const router = new Router({ prefix: "/api/categories" }); router.get("/", (ctx) => { const responseBody: APIResponse = { success: true, data: listCategories(), }; ctx.response.body = responseBody; }); router.get("/:slug", (ctx) => { const category = getCategoryBySlug(ctx.params.slug); const responseBody: APIResponse = { success: true, data: category, }; ctx.response.body = responseBody; }); router.get("/:slug/dumps", async (ctx) => { const requestingUserId = await parseOptionalAuth(ctx) ?? undefined; const { page, limit } = parsePagination(ctx.request.url.searchParams); const { items, hasMore } = listDumpsByCategory( ctx.params.slug, page, limit, requestingUserId, ); const responseBody: APIResponse> = { success: true, data: { items, hasMore }, }; ctx.response.body = responseBody; }); router.post( "/", authMiddleware, requirePermission("category:manage"), async (ctx) => { const body: unknown = await ctx.request.body.json(); if (!isCreateCategoryRequest(body)) { throw new APIException( APIErrorCode.VALIDATION_ERROR, 400, "Invalid category data", ); } const category = createCategory(body); const responseBody: APIResponse = { success: true, data: category, }; ctx.response.status = 201; ctx.response.body = responseBody; }, ); router.put( "/:id", authMiddleware, requirePermission("category:manage"), async (ctx) => { const body: unknown = await ctx.request.body.json(); if (!isUpdateCategoryRequest(body)) { throw new APIException( APIErrorCode.VALIDATION_ERROR, 400, "Invalid category data", ); } const category = updateCategory(ctx.params.id, body); const responseBody: APIResponse = { success: true, data: category, }; ctx.response.body = responseBody; }, ); router.delete( "/:id", authMiddleware, requirePermission("category:manage"), (ctx) => { deleteCategory(ctx.params.id); const responseBody: APIResponse = { success: true, data: null }; ctx.response.body = responseBody; }, ); export default router;