import fs from 'fs'; import path from 'path'; import matter from 'gray-matter'; const postsDirectory = path.join(process.cwd(), 'content/posts'); export type PostMetadata = { title: string; date: string; description: string; slug: string; tags?: string[]; }; export type Post = { metadata: PostMetadata; content: string; }; export function getPostSlugs() { if (!fs.existsSync(postsDirectory)) { return []; } return fs.readdirSync(postsDirectory); } export function getPostBySlug(slug: string): Post { const realSlug = slug.replace(/\.mdx$/, ''); if (/[\/\\]|\.\./.test(realSlug)) { throw new Error(`Invalid slug: ${realSlug}`); } const fullPath = path.join(postsDirectory, `${realSlug}.mdx`); let fileContents: string; try { fileContents = fs.readFileSync(fullPath, 'utf8'); } catch { throw new Error(`Post not found: ${realSlug}`); } const { data, content } = matter(fileContents); return { metadata: { ...data, slug: realSlug, } as PostMetadata, content, }; } export function getAllPosts(): PostMetadata[] { const slugs = getPostSlugs(); const posts = slugs .filter((slug) => slug.endsWith('.mdx')) .map((slug) => getPostBySlug(slug).metadata) // Sort posts by date in descending order .sort((post1, post2) => (post1.date > post2.date ? -1 : 1)); return posts; }