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