import { Handlers } from "$fresh/server.ts"; import { json } from "@lib/helpers.ts"; import { getBookDetails } from "@lib/hardcover.ts"; import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts"; import { formatDate, safeFileName, toUrlSafeString } from "@lib/string.ts"; import { AccessDeniedError } from "@lib/errors.ts"; import { createResource, fetchResource } from "@lib/marka/index.ts"; import { ReviewResource } from "@lib/marka/schema.ts"; export const handler: Handlers = { async GET(_, ctx) { const book = await fetchResource(`books/${ctx.params.name}`); return json(book?.content); }, async POST(_, ctx) { const session = ctx.state.session; if (!session) throw new AccessDeniedError(); const hardcoverId = ctx.params.name; if (!hardcoverId) throw new AccessDeniedError(); const bookDetails = await getBookDetails(hardcoverId); if (!bookDetails) { throw new Error("Book not found on Hardcover"); } const title = bookDetails.title || hardcoverId; const authorName = bookDetails.author_names?.[0] || ""; const isbn = bookDetails.isbn13 || bookDetails.isbn || ""; const releaseDate = bookDetails.release_year ? `${bookDetails.release_year}-01-01` : undefined; let finalPath = ""; if (bookDetails.image) { try { const response = await fetch(bookDetails.image); if (response.ok) { const buffer = await response.arrayBuffer(); const extension = fileExtension(bookDetails.image); finalPath = `books/images/${safeFileName(title)}_cover.${extension}`; await createResource(finalPath, buffer); } } catch { console.log("Failed to download book cover"); } } const book: ReviewResource["content"] = { _type: "Review", headline: title, subtitle: bookDetails.subtitle, bookBody: bookDetails.description || "", link: `https://hardcover.app/books/${bookDetails.slug}`, image: finalPath ? `resources/${finalPath}` : undefined, datePublished: formatDate(releaseDate), author: authorName ? { _type: "Person", name: authorName, } : undefined, itemReviewed: { name: title, }, }; console.log("Creating book resource:", JSON.stringify(book, null, 2)); const fileName = toUrlSafeString(title); await createResource(`books/${fileName}.md`, book); return json({ name: fileName }); }, };