62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
import { metadata } from '@/app/metadata'
|
|
import { getAllPostsMeta } from '@/lib/posts'
|
|
|
|
export const dynamic = "force-static"
|
|
|
|
const SITE_URL = process.env.SITE_URL || 'http://localhost:3000'
|
|
|
|
function escapeXml(str: string) {
|
|
return str
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
}
|
|
|
|
export async function GET(req: Request) {
|
|
const posts = getAllPostsMeta()
|
|
|
|
const updated =
|
|
posts.length > 0 ? new Date(posts[0].date).toISOString() : new Date().toISOString()
|
|
|
|
const entries = posts
|
|
.map((p) => {
|
|
const url = `${SITE_URL}/posts/${p.slug}`
|
|
const date = new Date(p.date).toISOString()
|
|
return `
|
|
<entry>
|
|
<title>${escapeXml(p.title)}</title>
|
|
<link href="${url}" rel="alternate" type="text/html" />
|
|
<id>${url}</id>
|
|
<published>${date}</published>
|
|
<updated>${date}</updated>
|
|
<content type="html" src="${url}" />
|
|
<summary>${escapeXml(p.description)}</summary>
|
|
</entry>`
|
|
})
|
|
.join('')
|
|
|
|
const feed = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
|
<id>${SITE_URL}/</id>
|
|
<title>${escapeXml(metadata.title!.toString())}</title>
|
|
<updated>${updated}</updated>
|
|
<author>
|
|
<name>${escapeXml(metadata.creator!.toString())}</name>
|
|
</author>
|
|
<link href="${SITE_URL}/feed" rel="self" type="application/atom+xml" />
|
|
<link href="${SITE_URL}" rel="alternate" type="text/html" />
|
|
<rights> © ${new Date().getFullYear()} Frank Borisjuk </rights>
|
|
${entries}
|
|
</feed>`
|
|
|
|
const accept = req.headers.get('accept') || ''
|
|
const contentType = accept.includes('application/atom+xml')
|
|
? 'application/atom+xml; charset=utf-8'
|
|
: 'application/xml; charset=utf-8'
|
|
|
|
return new Response(feed, {
|
|
headers: { 'Content-Type': contentType },
|
|
})
|
|
}
|