redirecter for ao3 that adds opengraph metadata
1import { getSeries, getUser, getWork } from "@fujocoded/ao3.js"; 2import { Hono } from "hono"; 3import PageSkeleton from "./pages/PageSkeleton.jsx"; 4import Home from "./pages/Home.jsx"; 5import Image from "./pages/Image.jsx"; 6 7const app = new Hono(); 8 9app.get("/", (c) => { 10 return c.html(<Home />); 11}); 12 13app.get("/works/:workId", async (c) => { 14 const workId = c.req.param("workId"); 15 const work = await getWork({ 16 workId: c.req.param("workId"), 17 chapterId: c.req.param("chapterId"), 18 }); 19 const authorsFormatted = work.authors.map((a) => { 20 if (a.anonymous) return "Anonymous"; 21 if (a.pseud !== a.username) return `${a.pseud} (${a.username})`; 22 return a.username; 23 }); 24 const authors = authorsFormatted.length > 1 25 ? authorsFormatted.slice(0, -1).join(", ") + " & " + 26 authorsFormatted.slice(-1) 27 : authorsFormatted[0]; 28 const title = `${work.title} by ${authors} - ${work.fandoms.join(", ")}`; 29 const desc = `Rating: ${work.rating} | ${work.category} | Updated ${ 30 work.updatedAt ? work.updatedAt : work.publishedAt 31 } | Words: ${work.words} | ${ 32 work.complete ? "Complete | " : "" 33 } ${work.summary}`; 34 return c.html( 35 <PageSkeleton title={title} description={desc} addr={`works/${workId}`} />, 36 ); 37}); 38 39app.get("/works/:workId/chapters/:chapterId", async (c) => { 40 const workId = c.req.param("workId"); 41 const chapterId = c.req.param("chapterId"); 42 const work = await getWork({ 43 workId: c.req.param("workId"), 44 chapterId: c.req.param("chapterId"), 45 }); 46 const authorsFormatted = work.authors.map((a) => { 47 if (a.anonymous) return "Anonymous"; 48 if (a.pseud !== a.username) return `${a.pseud} (${a.username})`; 49 return a.username; 50 }); 51 const authors = authorsFormatted.length > 1 52 ? authorsFormatted.slice(0, -1).join(", ") + " & " + 53 authorsFormatted.slice(-1) 54 : authorsFormatted[0]; 55 const title = 56 `${work.title} by ${authors}, Chapter ${work.chapterInfo.index}${ 57 work.chapterInfo.name ? `: ${work.chapterInfo.name}` : "" 58 } - ${work.fandoms.join(", ")}`; 59 const desc = `Rating: ${work.rating} | ${work.category} | Updated ${ 60 work.updatedAt ? work.updatedAt : work.publishedAt 61 } | Words: ${work.words} | ${work.complete ? "Complete | " : ""} ${ 62 work.chapterInfo.summary ? work.chapterInfo.summary : work.summary 63 }`; 64 return c.html( 65 <PageSkeleton 66 title={title} 67 description={desc} 68 addr={`works/${workId}/chapters/${chapterId}`} 69 />, 70 ); 71}); 72 73app.get("/series/:seriesId", async (c) => { 74 const seriesId = c.req.param("seriesId"); 75 const series = await getSeries({ seriesId: seriesId }); 76 const authorsFormatted = series.authors.map((a) => { 77 if (a.anonymous) return "Anonymous"; 78 if (a.pseud !== a.username) return `${a.pseud} (${a.username})`; 79 return a.username; 80 }); 81 const authors = authorsFormatted.length > 1 82 ? authorsFormatted.slice(0, -1).join(", ") + " & " + 83 authorsFormatted.slice(-1) 84 : authorsFormatted[0]; 85 const title = `${series.name} by ${authors}`; 86 const desc = ` Updated ${ 87 series.updatedAt ? series.updatedAt : series.publishedAt 88 } | Works: ${series.worksCount} | ${ 89 series.complete ? "Complete | " : "" 90 } ${series.notes}`; 91 return c.html( 92 <PageSkeleton 93 title={title} 94 description={desc} 95 addr={`series/${seriesId}`} 96 />, 97 ); 98}); 99 100app.get("/users/:username", async (c) => { 101 const username = c.req.param("username"); 102 const user = await getUser({ username: username }); 103 return c.html( 104 <PageSkeleton 105 title={`${username}`} 106 description={user.header} 107 addr={`users/${username}`} 108 />, 109 ); 110}); 111 112app.get("/users/:username/pseuds/:pseud", async (c) => { 113 const username = c.req.param("username"); 114 const pseud = c.req.param("pseud"); 115 const user = await getUser({ username: username }); 116 return c.html( 117 <PageSkeleton 118 title={`${pseud} (${username})`} 119 description={user.header} 120 addr={`users/${username}`} 121 />, 122 ); 123}); 124 125app.get("/preview/works/:workId", async (c) => { 126 const workId = c.req.param("workId"); 127 const work = await getWork({ 128 workId: workId, 129 }); 130 const addr = `works/${workId}`; 131 return Image({ data: work, addr: addr }); 132}); 133 134app.get("/preview/works/:workId/chapters/:chapterId", async (c) => { 135 const workId = c.req.param("workId"); 136 const chapterId = c.req.param("chapterId"); 137 const work = await getWork({ 138 workId: workId, 139 chapterId: chapterId, 140 }); 141 const addr = `works/${workId}/chapters/${chapterId}`; 142 return Image({ data: work, addr: addr }) 143}) 144 145export default app;