mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-28 07:20:49 -04:00

the #shared alias used by Nuxt cannot be easily disabled and to prevent breackage with jiti, we make use of it
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import fs from 'node:fs/promises';
|
|
|
|
import { defineCachedFunction } from 'nitropack/runtime';
|
|
import SQL from 'sql-template-strings';
|
|
|
|
import { extractMetadata } from '#shared/blog/metadata.ts';
|
|
import type { PostWithContent } from '#shared/blog/metadata.ts';
|
|
import type { BlogReactions } from '#shared/blog/reactions.ts';
|
|
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';
|
|
|
|
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 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;
|
|
};
|