/** * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ import { readFileSync, readdirSync } from "node:fs"; import { join } from "node:path"; import matter from "gray-matter"; const postsDirectory = join(process.cwd(), "posts"); /** * Reads the posts directory and returns an array of post data. * @returns An array of parsed frontmatter and file contents. */ const getSortedPostsData = (): Array<{ content: string; data: { date: Date; summary: string; title: string }; slug: string; }> => { const fileNames = readdirSync(postsDirectory); const allPostsData = fileNames.map((fileName) => { const slug = fileName.replace(/\.md$/, ""); const fullPath = join(postsDirectory, fileName); const fileContents = readFileSync(fullPath, "utf8"); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- matter doesn't take a generic I guess? const matterResult = matter(fileContents) as unknown as { content: string; data: { title: string; date: string; summary: string }; }; return { content: matterResult.content, data: { date: new Date(matterResult.data.date), summary: matterResult.data.summary, title: matterResult.data.title, }, slug: slug, }; }); return allPostsData.sort((a, b) => { if (a.data.date < b.data.date) { return 1; } return -1; }); }; /** * Reads a single post file. * @param slug - The slug of the post to read. * @returns The parsed frontmatter and file contents. */ const getPostData = ( slug: string, ): { content: string; data: { date: Date; summary: string; title: string }; slug: string; } => { const fullPath = join(postsDirectory, `${slug}.md`); const fileContents = readFileSync(fullPath, "utf8"); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- matter doesn't take a generic I guess? const matterResult = matter(fileContents) as unknown as { content: string; data: { title: string; date: string; summary: string }; }; return { content: matterResult.content, data: { date: new Date(matterResult.data.date), summary: matterResult.data.summary, title: matterResult.data.title, }, slug: slug, }; }; export { getSortedPostsData, getPostData };