import { Router } from "@oak/oak"; import { APIErrorCode, APIException, type APIResponse, type Category, type Dump, isCreateCategoryRequest, isUpdateCategoryRequest, type PaginatedData, } from "../model/interfaces.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, total } = listDumpsByCategory( ctx.params.slug, page, limit, requestingUserId, ); const responseBody: APIResponse> = { success: true, data: { items, total, hasMore: page * limit < total }, }; ctx.response.body = responseBody; }); router.post( "/", authMiddleware, requirePermission("category:manage"), async (ctx) => { const body = 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 = 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;