redirecter for ao3 that adds opengraph metadata

fixc the fucking images

Changed files
+17 -16
src
app
api
works
[workId]
lib
+2 -2
src/app/api/works/[workId]/route.js
···
const { workId } = await ctx.params
const params = await req.nextUrl.searchParams
const domain = await req.nextUrl.hostname
-
const subdomain = domain.split(".").length > 1 ? domain.split(".")[0] : null
-
const archive = params.get('archive')
+
const subdomain = (domain.split(".").length > 1) ? domain.split(".")[0] : null
+
const archive = params ? params.get('archive') : null
if (subdomain) setArchiveBaseUrl('https://'+siteMap[subdomain])
if (archive) setArchiveBaseUrl(archive)
const work = await getWork({workId: workId})
+1
src/lib/ogimage.js
···
import ChoseNotToWarn from "@/icons/chosenottowarn.js"
export default async function OGImage ({ theme, baseFont, titleFont, image, addr, opts }) {
+
console.log(image)
return new ImageResponse(
(
<div
+14 -14
src/lib/sanitizeData.js
···
import titleFonts from '@/lib/titleFonts.js'
const getWork = async (workId, archive = null) => {
-
const domainParam = archive ? `?archive=${archive}` : ''
+
const domainParam = (archive && archive !== process.env.ARCHIVE) ? `?archive=${archive}` : ''
const data = await fetch(`http://${process.env.DOMAIN}/api/works/${workId}${domainParam}`)
const work = await data.json()
return work
···
}
export default async function sanitizeData ({ type, data, props}) {
-
const propsParsed = sanitizeProps(querystring.parse(props ? props.toString() : ''))
-
const archive = props && props.has('archive') ? props.get('archive') : 'https://archiveofourown.org'
-
const baseFont = propsParsed.baseFont ? propsParsed.baseFont : process.env.DEFAULT_BASE_FONT
+
const archive = props && props.archive ? props.archive : process.env.ARCHIVE
+
const baseFont = props.baseFont ? props.baseFont : process.env.DEFAULT_BASE_FONT
const baseFontData = baseFonts[baseFont]
-
const titleFont = propsParsed.titleFont ? propsParsed.titleFont : process.env.DEFAULT_TITLE_FONT
+
const titleFont = props.titleFont ? props.titleFont : process.env.DEFAULT_TITLE_FONT
const titleFontData = titleFonts[titleFont]
-
const themeData = propsParsed.theme ? themes[propsParsed.theme] : themes[process.env.DEFAULT_THEME]
+
const themeData = props.theme ? themes[props.theme] : themes[process.env.DEFAULT_THEME]
const parentWork = type === 'work' && data.chapterInfo ? await getWork(data.id, archive) : null
const bfs = await Promise.all(baseFontData.defs.map(async (bf) => {
return {
···
return a.username
})
: []
-
const rating = type === 'work' ? await getHighestRating([data], archive) : await getHighestRating(data.works, archive)
+
const rating = type === 'work' ? data.rating : await getHighestRating(data.works, archive)
const warning = type === 'work' ? await getHighestWarning([data], archive) : await getHighestWarning(data.works, archive)
const category = type === 'work' ? await getCategory([data], archive) : await getCategory(data.works, archive)
-
const authorString = authorsFormatted.length > 1
+
const authorString = (authorsFormatted.length > 1
? authorsFormatted.slice(0, -1).join(", ") + " & " +
authorsFormatted.slice(-1)[0]
-
: authorsFormatted[0]
+
: authorsFormatted[0])
const summaryContent = type === 'work'
-
? (propsParsed.summaryType === 'chapter' && data.chapterInfo && data.chapterInfo.summary ? data.chapterInfo.summary : (propsParsed.summaryType === 'custom' && propsParsed.customSummary !== '' ? propsParsed.customSummary : (data.summary ? data.summary : (parentWork ? parentWork.summary : ''))))
-
: (propsParsed.summaryType === 'custom' && propsParsed.customSummary !== '' ? propsParsed.customSummary : data.notes)
+
? (props.summaryType === 'chapter' && data.chapterInfo && data.chapterInfo.summary ? data.chapterInfo.summary : (props.summaryType === 'custom' && props.customSummary !== '' ? props.customSummary : (data.summary ? data.summary : (parentWork ? parentWork.summary : ''))))
+
: (props.summaryType === 'custom' && props.customSummary !== '' ? props.customSummary : data.notes)
const formatter = new Intl.NumberFormat('en-US')
const words = formatter.format(data.words)
-
const summaryDOM = new DOM(summaryContent, {decodeEntities: true});
+
const summaryDOM = new DOM(summaryContent, {decodeEntities: true})
const summaryFormatted = summaryDOM.innerHTML.replace(/\<br(?: \/)?\>/g, "\n").replace(
/(<([^>]+)>)/ig,
"",
···
const freeTags = type === 'work' ? data.tags.additional : data.works.map(w => w.tags.additional).reduce((a, b) => { return b ? (a ? a.concat(b) : []) : (a ? a : []) }).filter((w, i) => { return i === data.works.indexOf(w) })
const warnings = type === 'work' ? data.tags.warnings : data.works.map(w => w.tags.warnings).reduce((a, b) => { return b ? (a ? a.concat(b) : []) : (a ? a : []) }).filter((w, i) => { return i === data.works.indexOf(w) })
-
return {
+
const ret = {
topLine: fandomString,
titleLine: titleString,
authorLine: authorString,
···
updatedAt: data.updatedAt,
baseFont: baseFont,
titleFont: titleFont,
-
props: propsParsed,
+
props: props,
opts: {
fonts: bfs.concat(tfs)
}
}
+
return ret;
}