v5/build-helpers/blogPostsPlugin.ts

53 lines
1.3 KiB
TypeScript

import type { Plugin } from "vite";
import { readSync } from "to-vfile";
import { matter } from "vfile-matter";
import { resolve, join } from "node:path";
import { readdirSync, statSync, writeFileSync } from "node:fs";
import { exec } from "node:child_process";
/*
* Code from andii.dev
*/
const processFiles = () => {
const outputFile = resolve("src/data/posts.json");
const blogDir = resolve("src/routes/blog");
const files = readdirSync(blogDir);
const blogPosts = files
.filter(
(file) => statSync(join(blogDir, file)).isFile() && file.endsWith(".mdx"),
)
.map((file) => {
const f = readSync(resolve("src/routes/blog", file));
matter(f);
return {
...(f.data.matter as object),
slug: file.replace(".mdx", ""),
} as { date: string; slug: string };
})
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
writeFileSync(outputFile, JSON.stringify(blogPosts, null, 2), "utf-8");
exec("bunx @biomejs/biome format --write ./src/data/posts.json");
};
export const blogPostsPlugin = (): Plugin => {
return {
name: "blog-posts-gen",
buildEnd() {
processFiles();
},
configureServer(server) {
server.watcher.on("change", (filePath) => {
if (
!filePath.includes("/src/routes/blog") &&
!filePath.includes("blogPostsPlugin.ts")
)
return;
processFiles();
});
},
};
};