45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { listPosts } from '~~/server/utils/posts'
|
|
import { getSiteData } from '~~/server/utils/site'
|
|
|
|
const escape = (s: string) =>
|
|
s.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const base = useRuntimeConfig().public.siteUrl.replace(/\/+$/, '')
|
|
const posts = (await listPosts()).filter((p) => !p.draft).slice(0, 30)
|
|
const site = await getSiteData()
|
|
|
|
const items = posts
|
|
.map(
|
|
(post) => ` <item>
|
|
<title>${escape(post.title)}</title>
|
|
<link>${base}/blog/${post.slug}</link>
|
|
<guid isPermaLink="true">${base}/blog/${post.slug}</guid>
|
|
<pubDate>${new Date(post.date).toUTCString()}</pubDate>
|
|
<description>${escape(post.description)}</description>
|
|
${post.tags.map((t) => ` <category>${escape(t)}</category>`).join('\n')}
|
|
</item>`,
|
|
)
|
|
.join('\n')
|
|
|
|
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
<channel>
|
|
<title>${escape(site.domain)}</title>
|
|
<link>${base}</link>
|
|
<description>${escape(site.description)}</description>
|
|
<language>en</language>
|
|
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
|
|
<atom:link href="${base}/rss.xml" rel="self" type="application/rss+xml"/>
|
|
${items}
|
|
</channel>
|
|
</rss>`
|
|
|
|
setHeader(event, 'content-type', 'application/rss+xml; charset=utf-8')
|
|
setHeader(event, 'cache-control', 'public, max-age=600')
|
|
return xml
|
|
})
|