mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-03 11:07:00 -04:00
75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
import fs from 'node:fs/promises';
|
|
|
|
import { defineCachedFunction } from 'nitropack/runtime';
|
|
import SQL from 'sql-template-strings';
|
|
|
|
import type { Config } from '~/locale/config.ts';
|
|
import type { Database } from '~/server/db.ts';
|
|
import type { UserRow } from '~/server/express/user.ts';
|
|
import { rootDir } from '~/server/paths.ts';
|
|
import { extractMetadata } from '~/src/blog/metadata.ts';
|
|
import type { PostWithContent } from '~/src/blog/metadata.ts';
|
|
|
|
export const getPosts = defineCachedFunction(async (config: Config): Promise<PostWithContent[]> => {
|
|
const dir = `${rootDir}/locale/${config.locale}/blog`;
|
|
const posts: PostWithContent[] = [];
|
|
|
|
for (const file of await fs.readdir(dir)) {
|
|
if (!file.endsWith('.md')) {
|
|
continue;
|
|
}
|
|
const content = await fs.readFile(`${dir}/${file}`, 'utf-8');
|
|
|
|
const slug = file.substring(0, file.length - 3);
|
|
const metadata = extractMetadata(config, content);
|
|
if (metadata !== undefined) {
|
|
posts.push({ slug, content, ...metadata });
|
|
}
|
|
}
|
|
|
|
posts.sort((a, b) => {
|
|
if (a.date < b.date) {
|
|
return 1;
|
|
}
|
|
if (a.date > b.date) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
return posts;
|
|
}, {
|
|
name: 'blog',
|
|
getKey: (config) => config.locale,
|
|
maxAge: Infinity,
|
|
});
|
|
|
|
export interface BlogReactions {
|
|
total: Record<string, number>;
|
|
user?: string[];
|
|
}
|
|
|
|
export const getPostReactions = async (
|
|
db: Database,
|
|
locale: string,
|
|
slug: string,
|
|
userId: UserRow['id'] | undefined,
|
|
): Promise<BlogReactions> => {
|
|
const totalReactions = await db.all<{ c: number; emoji: string }>(SQL`SELECT COUNT(*) as c, emoji
|
|
FROM blog_reactions
|
|
WHERE locale = ${locale} AND slug = ${slug}
|
|
GROUP BY emoji`);
|
|
|
|
const reactions: BlogReactions = {
|
|
total: Object.fromEntries(totalReactions.map((row) => [row.emoji, row.c])),
|
|
};
|
|
|
|
if (userId !== undefined) {
|
|
const userReactions = await db.all<{ emoji: string }>(SQL`SELECT emoji FROM blog_reactions
|
|
WHERE locale = ${locale} AND slug = ${slug} AND user_id = ${userId}`);
|
|
reactions.user = userReactions.map((row) => row.emoji);
|
|
}
|
|
|
|
return reactions;
|
|
};
|