34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import { db } from '../utils/db';
|
|
|
|
function escapeXml(s: string): string {
|
|
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
}
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const config = useRuntimeConfig(event);
|
|
const base = String(config.public.siteUrl).replace(/\/$/, '');
|
|
const posts = await db.post.findMany({ where: { status: 'published' }, orderBy: [{ publishedAt: 'desc' }] });
|
|
const items = posts
|
|
.map((p) => {
|
|
const url = `${base}/blog/${p.slug}`;
|
|
const date = (p.publishedAt ?? p.createdAt).toUTCString();
|
|
return ` <item>
|
|
<title>${escapeXml(p.title)}</title>
|
|
<link>${url}</link>
|
|
<guid>${url}</guid>
|
|
<pubDate>${date}</pubDate>
|
|
<description>${escapeXml(p.excerpt)}</description>
|
|
</item>`;
|
|
})
|
|
.join('\n');
|
|
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<rss version="2.0"><channel>
|
|
<title>Acme Blog</title>
|
|
<link>${base}/blog</link>
|
|
<description>Release notes, guides and engineering notes from the Acme team.</description>
|
|
${items}
|
|
</channel></rss>`;
|
|
setHeader(event, 'content-type', 'application/rss+xml; charset=utf-8');
|
|
return xml;
|
|
});
|