mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-27 12:44:13 +00:00
96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import { defineConfig } from "vite";
|
|
import react from "@vitejs/plugin-react";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
import mdx from "@mdx-js/rollup";
|
|
import remarkGfm from "remark-gfm";
|
|
import rehypeSlug from "rehype-slug";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import type { Plugin } from "vite";
|
|
|
|
/**
|
|
* Vite plugin that generates a search index from MDX heading markers.
|
|
* Exposes a virtual module `virtual:docs-search-index` containing all
|
|
* h2 sections extracted from `src/docs/` MDX files at build time.
|
|
*/
|
|
function docsSearchIndexPlugin(): Plugin {
|
|
const virtualId = "virtual:docs-search-index";
|
|
const resolvedId = "\0" + virtualId;
|
|
|
|
return {
|
|
name: "docs-search-index",
|
|
resolveId(id) {
|
|
if (id === virtualId) return resolvedId;
|
|
},
|
|
load(id) {
|
|
if (id !== resolvedId) return;
|
|
|
|
const docsDir = path.resolve(__dirname, "src/docs");
|
|
const entries: {
|
|
pageTitle: string;
|
|
pageSlug: string;
|
|
sectionTitle: string;
|
|
sectionId: string;
|
|
persona: string;
|
|
}[] = [];
|
|
|
|
function walk(dir: string) {
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
if (entry.isDirectory()) {
|
|
walk(path.join(dir, entry.name));
|
|
} else if (entry.name.endsWith(".mdx")) {
|
|
const fullPath = path.join(dir, entry.name);
|
|
const relative = path.relative(docsDir, fullPath);
|
|
const slug = relative.replace(/\.mdx$/, "");
|
|
const raw = fs.readFileSync(fullPath, "utf-8");
|
|
|
|
let persona = "developer";
|
|
if (slug.startsWith("operator/")) persona = "operator";
|
|
else if (slug.startsWith("contributor/")) persona = "contributor";
|
|
|
|
const titleMatch = raw.match(/^#\s+(.+)$/m);
|
|
const pageTitle = titleMatch?.[1] ?? slug;
|
|
|
|
const h2Regex = /^##\s+(.+)$/gm;
|
|
let match;
|
|
while ((match = h2Regex.exec(raw)) !== null) {
|
|
const sectionTitle = match[1];
|
|
const sectionId = sectionTitle
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "-")
|
|
.replace(/(^-|-$)/g, "");
|
|
entries.push({
|
|
pageTitle,
|
|
pageSlug: slug,
|
|
sectionTitle,
|
|
sectionId,
|
|
persona,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
walk(docsDir);
|
|
|
|
return `export const SECTION_INDEX = ${JSON.stringify(entries)};`;
|
|
},
|
|
};
|
|
}
|
|
|
|
export default defineConfig({
|
|
plugins: [
|
|
docsSearchIndexPlugin(),
|
|
{
|
|
enforce: 'pre' as const,
|
|
...mdx({
|
|
providerImportSource: '@mdx-js/react',
|
|
remarkPlugins: [remarkGfm],
|
|
rehypePlugins: [rehypeSlug],
|
|
}),
|
|
},
|
|
react({ include: /\.(jsx|tsx|mdx)$/ }),
|
|
tailwindcss(),
|
|
],
|
|
});
|