refactor: Migrate documentation content, rebuild UI components, and update core architecture.

This commit is contained in:
gitfromwildan
2026-03-10 01:38:58 +07:00
parent aac81dff8a
commit ab755844a3
132 changed files with 3947 additions and 12862 deletions

View File

@@ -6,7 +6,7 @@ import rehypePrism from "rehype-prism-plus";
import rehypeAutolinkHeadings from "rehype-autolink-headings";
import rehypeSlug from "rehype-slug";
import rehypeCodeTitles from "rehype-code-titles";
import { page_routes, ROUTES } from "./routes-config";
import { page_routes, ROUTES } from "./routes";
import { visit } from "unist-util-visit";
import type { Node, Parent } from "unist";
import matter from "gray-matter";
@@ -31,6 +31,7 @@ interface TextNode extends Node {
// custom components imports
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell } from "@/components/ui/table";
import Pre from "@/components/markdown/PreMdx";
import Note from "@/components/markdown/NoteMdx";
import { Stepper, StepperItem } from "@/components/markdown/StepperMdx";
@@ -54,20 +55,22 @@ const components = {
TabsContent,
TabsList,
TabsTrigger,
pre: Pre,
Note,
Stepper,
StepperItem,
img: Image,
a: Link,
Outlet,
Youtube,
Tooltip,
Card,
Button,
Accordion,
AccordionGroup,
CardGroup,
Kbd,
// Table Components
table: Table,
thead: TableHeader,
tbody: TableBody,
tfoot: TableFooter,
tr: TableRow,
th: TableHead,
td: TableCell,
// Release Note Components
Release,
Changes,
@@ -75,7 +78,13 @@ const components = {
File,
Files,
Folder,
AccordionGroup
pre: Pre,
Note,
Stepper,
StepperItem,
img: Image,
a: Link,
Outlet,
};
// helper function to handle rehype code titles, since by default we can't inject into the className of rehype-code-titles
@@ -154,38 +163,57 @@ export type BaseMdxFrontmatter = {
export async function getDocsForSlug(slug: string) {
try {
const contentPath = getDocsContentPath(slug);
const rawMdx = await fs.readFile(contentPath, "utf-8");
return await parseMdx<BaseMdxFrontmatter>(rawMdx);
const { content, filePath } = await getRawMdx(slug);
const mdx = await parseMdx<BaseMdxFrontmatter>(content);
return {
...mdx,
filePath,
};
} catch (err) {
console.log(err);
}
}
export async function getDocsTocs(slug: string) {
const contentPath = getDocsContentPath(slug);
const rawMdx = await fs.readFile(contentPath, "utf-8");
// captures between ## - #### can modify accordingly
const headingsRegex = /^(#{2,4})\s(.+)$/gm;
const { content } = await getRawMdx(slug);
const rawMdx = content;
// Regex to match code blocks (```...```), standard markdown headings (##), and <Release> tags
const combinedRegex = /(```[\s\S]*?```)|^(#{2,4})\s(.+)$|<Release[^>]*version="([^"]+)"/gm;
let match;
const extractedHeadings = [];
while ((match = headingsRegex.exec(rawMdx)) !== null) {
const headingLevel = match[1].length;
const headingText = match[2].trim();
const slug = sluggify(headingText);
extractedHeadings.push({
level: headingLevel,
text: headingText,
href: `#${slug}`,
});
while ((match = combinedRegex.exec(rawMdx)) !== null) {
// match[1] -> Code block content (ignore)
if (match[1]) continue;
// match[2] & match[3] -> Markdown headings
if (match[2]) {
const headingLevel = match[2].length;
const headingText = match[3].trim();
const slug = sluggify(headingText);
extractedHeadings.push({
level: headingLevel,
text: headingText,
href: `#${slug}`,
});
}
// match[4] -> Release component version
else if (match[4]) {
const version = match[4];
extractedHeadings.push({
level: 2,
text: `v${version}`,
href: `#${version}`,
});
}
}
return extractedHeadings;
}
export function getPreviousNext(path: string) {
// path comes in as "getting-started/introduction" but page_routes has "/docs/getting-started/introduction"
const fullPath = path ? `/docs/${path}` : "/docs";
const index = page_routes.findIndex(({ href }) => href === fullPath);
const index = page_routes.findIndex(({ href }) => href == `/${path}`);
return {
prev: page_routes[index - 1],
next: page_routes[index + 1],
@@ -197,8 +225,26 @@ function sluggify(text: string) {
return slug.replace(/[^a-z0-9-]/g, "");
}
function getDocsContentPath(slug: string) {
return path.join(process.cwd(), "/contents/docs/", `${slug}/index.mdx`);
async function getRawMdx(slug: string) {
const commonPath = path.join(process.cwd(), "/docs/");
const paths = [
path.join(commonPath, `${slug}.mdx`),
path.join(commonPath, slug, "index.mdx"),
];
for (const p of paths) {
try {
const content = await fs.readFile(p, "utf-8");
return {
content,
filePath: `docs/${path.relative(commonPath, p)}`,
};
} catch {
// ignore and try next
}
}
throw new Error(`Could not find mdx file for slug: ${slug}`);
}
function justGetFrontmatterFromMD<Frontmatter>(rawMd: string): Frontmatter {
@@ -220,16 +266,10 @@ export async function getAllChilds(pathString: string) {
return await Promise.all(
page_routes_copy.map(async (it) => {
const totalPath = path.join(
process.cwd(),
"/contents/docs/",
prevHref,
it.href,
"index.mdx"
);
const raw = await fs.readFile(totalPath, "utf-8");
const slug = path.join(prevHref, it.href);
const { content } = await getRawMdx(slug);
return {
...justGetFrontmatterFromMD<BaseMdxFrontmatter>(raw),
...justGetFrontmatterFromMD<BaseMdxFrontmatter>(content),
href: `/docs${prevHref}${it.href}`,
};
})