1 import type { CollectionEntry } from 'astro:content'
2 import { SITE } from '@/config'
3 import type { APIContext } from 'astro'
4 import { getSortedFilteredPosts } from '@/utils/draft'
5
6 export async function generateRSS(context: APIContext) {
7 const sortedPosts = await getSortedFilteredPosts()
8
9 const rss = `<?xml version="1.0" encoding="UTF-8" ?>
10 <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
11 <channel>
12 <title>${SITE.title}</title>
13 <link>${context.site}</link>
14 <description>${SITE.description}</description>
15 <language>zh-CN</language>
16 <lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
17 <atom:link href="${context.site}/rss.xml" rel="self" type="application/rss+xml" />
18 ${sortedPosts
19 .map(
20 (post: CollectionEntry<'posts'>) => `
21 <item>
22 <title><![CDATA[${post.data.title}]]></title>
23 <link>${context.site}/${post.id}/</link>
24 <guid>${context.site}/${post.id}/</guid>
25 <pubDate>${post.data.pubDate.toUTCString()}</pubDate>
26 <content:encoded><![CDATA[${post.body}]]></content:encoded>
27 </item>
28 `
29 )
30 .join('')}
31 </channel>
32 </rss>`
33
34 return new Response(rss, {
35 headers: {
36 'Content-Type': 'application/xml; charset=utf-8'
37 }
38 })
39 }
40
41 export async function generateAtom(context: APIContext) {
42 const sortedPosts = await getSortedFilteredPosts()
43
44 const atom = `<?xml version="1.0" encoding="utf-8"?>
45 <feed xmlns="http://www.w3.org/2005/Atom">
46 <title>${SITE.title}</title>
47 <subtitle>${SITE.description}</subtitle>
48 <link href="${context.site}/atom.xml" rel="self" type="application/atom+xml" />
49 <link href="${context.site}" />
50 <id>${context.site}</id>
51 <updated>${new Date().toISOString()}</updated>
52 ${sortedPosts
53 .map(
54 (post: CollectionEntry<'posts'>) => `
55 <entry>
56 <title>${post.data.title}</title>
57 <link href="${context.site}/${post.id}/" />
58 <id>${context.site}/${post.id}/</id>
59 <published>${post.data.pubDate.toISOString()}</published>
60 <content type="html"><![CDATA[${post.body}]]></content>
61 </entry>
62 `
63 )
64 .join('')}
65 </feed>`
66
67 return new Response(atom, {
68 headers: {
69 'Content-Type': 'application/xml; charset=utf-8'
70 }
71 })
72 }