PronounsPage/server/routes/blog.atom.get.ts
2024-12-28 00:03:28 +01:00

65 lines
2.4 KiB
TypeScript

import fs from 'node:fs/promises';
import { Feed } from 'feed';
import marked from 'marked';
import type { Translations } from '~/locale/translations.ts';
import { getPosts } from '~/server/blog.ts';
import { loadSuml, loadSumlFromBase } from '~/server/loader.ts';
import { rootDir } from '~/server/paths.ts';
import parseMarkdown from '~/src/parseMarkdown.ts';
import { Translator } from '~/src/translator.ts';
const config = global.config;
const translations = loadSuml('translations') as Translations;
const baseTranslations = loadSumlFromBase('locale/_base/translations') as Translations;
const translator = new Translator(translations, baseTranslations, config);
export default defineCachedEventHandler(async () => {
const runtimeConfig = useRuntimeConfig();
const posts = await getPosts();
const feed = new Feed({
title: `${translator.translate('title')}${translator.translate('links.blog')}`,
description: translator.translate('description'),
id: runtimeConfig.public.baseUrl,
link: `${runtimeConfig.public.baseUrl}/blog.atom`,
language: config.locale,
image: `${runtimeConfig.public.baseUrl}/icon.png`,
favicon: `${runtimeConfig.public.baseUrl}/icon.png`,
updated: new Date(posts[0].date),
copyright: '',
});
for (const post of posts) {
const markdownContent = await fs.readFile(`${rootDir}/data/blog/${post.slug}.md`, 'utf-8');
const markdown = marked(markdownContent);
const parsed = await parseMarkdown(markdown, translator);
feed.addItem({
title: post.title,
id: `${runtimeConfig.public.baseUrl}/${config.links.blogRoute}/${post.slug}`,
link: `${runtimeConfig.public.baseUrl}/${config.links.blogRoute}/${post.slug}`,
description: parsed.intro ?? undefined,
content: parsed.content ?? undefined,
author: post.authors.map((author) => ({
name: author,
link: author.startsWith('@') ? `${runtimeConfig.public.baseUrl}/${author}` : undefined,
})),
date: new Date(post.date),
image: post.hero ? `${runtimeConfig.public.baseUrl}${post.hero.src}` : undefined,
});
}
return new Response(feed.atom1(), {
headers: {
'Content-Type': 'application/rss+xml; charset=utf-8',
},
});
}, {
maxAge: Infinity,
});