45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import type { Article } from '#shared/types/blog'
|
|
|
|
interface AdminUser {
|
|
firstname: string | null
|
|
lastname: string | null
|
|
}
|
|
|
|
type RawArticle = Omit<Article, 'html' | 'summary' | 'author'> & {
|
|
content: string | null
|
|
createdBy?: AdminUser | null
|
|
}
|
|
|
|
/** Joins the admin user's name parts; returns null when neither is set. */
|
|
function byline(user: AdminUser | null | undefined): string | null {
|
|
const name = [user?.firstname, user?.lastname].filter(Boolean).join(' ').trim()
|
|
return name || null
|
|
}
|
|
|
|
export default defineEventHandler(async (event): Promise<Article> => {
|
|
const slug = getRouterParam(event, 'slug')
|
|
const locale = localeParam(getQuery(event).lang)
|
|
|
|
if (!slug) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Missing article slug' })
|
|
}
|
|
|
|
const response = await strapiFetch<StrapiList<RawArticle>>(
|
|
`/api/articles?${ARTICLE_DETAIL_QUERY}&locale=${locale}&filters[slug][$eq]=${encodeURIComponent(slug)}&pagination[pageSize]=1`
|
|
)
|
|
|
|
const article = response.data[0]
|
|
|
|
if (!article) {
|
|
throw createError({ statusCode: 404, statusMessage: 'Article not found' })
|
|
}
|
|
|
|
const { content, createdBy, ...rest } = article
|
|
return {
|
|
...rest,
|
|
html: renderMarkdown(content),
|
|
summary: summarise(content),
|
|
author: byline(createdBy),
|
|
}
|
|
})
|