96 lines
2.4 KiB
TypeScript
96 lines
2.4 KiB
TypeScript
import rss, { type RSSFeedItem } from '@astrojs/rss'
|
|
import type { APIRoute } from 'astro'
|
|
import {
|
|
getBlog,
|
|
listBlogs,
|
|
type ListBlogItemType,
|
|
} from '../lib/apis/legacy/blog'
|
|
import { ensureShikiEngine } from '../lib/markdown'
|
|
// import { toMarkdocTree } from '../lib/markdoc'
|
|
import Markdoc from '@markdoc/markdoc'
|
|
import KeyV from 'keyv'
|
|
import { createHash } from 'node:crypto'
|
|
|
|
export const prerender = false
|
|
|
|
const renderCache = new KeyV<string>({
|
|
namespace: 'markdoc-rss',
|
|
})
|
|
|
|
const _render = async (content: string) => {
|
|
const key = 'html:' + createHash('sha256').update(content).digest('hex')
|
|
const cached = await renderCache.get(key)
|
|
|
|
if (cached) {
|
|
return cached
|
|
}
|
|
|
|
const blogTree = Markdoc.transform(Markdoc.parse(content))
|
|
const html = Markdoc.renderers.html(blogTree)
|
|
|
|
await renderCache.set(key, html, 1000 * 60 * 60 * 24)
|
|
return html
|
|
}
|
|
|
|
const _getBlog = async (blogId: number) => {
|
|
const key = `raw:blog-${blogId}`
|
|
const cached = await renderCache.get(key)
|
|
|
|
if (cached) {
|
|
return cached
|
|
}
|
|
|
|
const content = (await getBlog(blogId))?.content
|
|
if (content) {
|
|
await renderCache.set(key, content, 1000 * 60 * 60 * 12)
|
|
}
|
|
return content
|
|
}
|
|
|
|
export const GET = (async (context) => {
|
|
let blogs: ListBlogItemType[] = []
|
|
let pid = 0
|
|
|
|
let newBlogs = []
|
|
|
|
while (pid == 0 || newBlogs.length > 0) {
|
|
newBlogs = await listBlogs({
|
|
page: ++pid,
|
|
limit: 100,
|
|
})
|
|
blogs = [...blogs, ...newBlogs]
|
|
}
|
|
|
|
const site = context.site || 'https://passthem.top'
|
|
await ensureShikiEngine()
|
|
|
|
return rss({
|
|
title: '小帕的小窝',
|
|
description: '小帕和他朋友们的博客',
|
|
site,
|
|
items: await Promise.all(
|
|
blogs.map(async (blog) => {
|
|
const blogContent = (await _getBlog(blog.id)) || '博客内容暂不可用'
|
|
const rssItem: RSSFeedItem = {
|
|
title: blog.title,
|
|
description: `一篇由 ${blog.author.nickname} 写的博客`,
|
|
link: `${site}/blogs/${blog.id}`,
|
|
pubDate: new Date(blog.created_at),
|
|
content: await _render(blogContent),
|
|
author: blog.author.nickname,
|
|
enclosure: blog.featured_image
|
|
? {
|
|
url: blog.featured_image.image_url,
|
|
length: 0,
|
|
type: 'image/jpeg',
|
|
}
|
|
: undefined,
|
|
}
|
|
|
|
return rssItem
|
|
}),
|
|
),
|
|
customData: `<language>zh-hans</language>`,
|
|
})
|
|
}) satisfies APIRoute
|