import { render } from 'svelte/server'; export interface Metadata { title: string; date: string; categories?: string[]; draft?: boolean; } export interface Section { poetry: 'poetry'; thoughts: 'thoughts'; all: 'all'; } type SectionKey = keyof Section; export interface Post { meta: Metadata; content: string; section: string; filename: string; id: string; } interface Data { metadata: Metadata; // eslint-disable-next-line @typescript-eslint/no-explicit-any default: any; } function isData(obj: unknown): obj is Data { if (typeof obj !== 'object' || obj === null) { return false; } const dataObj = obj as Data; return ( 'metadata' in dataObj && typeof dataObj.metadata.title === 'string' && typeof dataObj.metadata.date === 'string' ); } export const fetchMarkdownPosts = async ( section: SectionKey, limit?: number, offset?: number ): Promise<{ posts: Post[]; total: number }> => { let posts: Record Promise>; switch (section) { case 'all': posts = import.meta.glob('/src/posts/**/*.md'); break; case 'poetry': posts = import.meta.glob('/src/posts/poetry/*.md'); break; case 'thoughts': posts = import.meta.glob('/src/posts/thoughts/*.md'); break; default: throw new Error('Could not find this section'); } const iterablePostFiles = Object.entries(posts); const postsWithErrors: string[] = []; const allPosts = await Promise.all( iterablePostFiles.map(async ([path, resolver]) => { try { const data = await resolver(); if (isData(data)) { if (data.metadata.draft) { return undefined; } const { metadata } = data; const { body } = render(data.default, {}); const content = body.replace(/<[^>]*>/g, ''); const section = path.split('/')[3]; const filename = path.split('/').pop()?.slice(0, -3); return { meta: { ...metadata }, content, section, filename, id: data.metadata.title }; } else { console.error('Could not properly parse this post'); postsWithErrors.push(path); } } catch (error) { console.error(`Error parsing post at ${path}: ${error}`); postsWithErrors.push(path); } }) ); console.log('Files that could not be properly parsed:', postsWithErrors); const sortedPosts: Post[] = allPosts .filter((post): post is Post => post !== undefined) .sort( (b, a) => new Date(a?.meta.date || '').getTime() - new Date(b?.meta.date || '').getTime() ); if (limit === undefined || offset === undefined) { return { posts: sortedPosts, total: allPosts.length }; } const paginatedPosts = sortedPosts.slice(offset, offset + limit); return { posts: paginatedPosts, total: allPosts.length }; };