Core: [Page Tree Builder] Inline folders without children

This commit is contained in:
Fuma Nama
2025-01-19 09:13:29 +08:00
parent 8d3dbca81b
commit 777188b028
4 changed files with 73 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-core': patch
---
[Page Tree Builder] Inline folders without children
+20 -8
View File
@@ -59,6 +59,10 @@ const rest = '...';
const extractPrefix = '...';
const excludePrefix = '!';
function isPageFile(node: Folder | File): node is PageFile {
return 'data' in node && node.format === 'page';
}
/**
* @param nodes - All nodes to be built
* @param ctx - Context
@@ -76,7 +80,7 @@ function buildAll(
for (const node of [...nodes].sort((a, b) =>
a.file.name.localeCompare(b.file.name),
)) {
if ('data' in node && node.format === 'page' && !node.file.locale) {
if (isPageFile(node) && !node.file.locale) {
const treeNode = buildFileNode(node, ctx);
if (node.file.name === 'index') {
@@ -88,7 +92,15 @@ function buildAll(
}
if ('children' in node) {
folders.push(buildFolderNode(node, false, ctx));
if (
node.children.length === 1 &&
node.children[0].file.name === 'index' &&
isPageFile(node.children[0])
) {
output.push(buildFileNode(node.children[0], ctx));
} else {
folders.push(buildFolderNode(node, false, ctx));
}
}
}
@@ -104,19 +116,19 @@ function resolveFolderItem(
): PageTree.Node[] | '...' {
if (item === rest) return '...';
const separateResult = separator.exec(item);
if (separateResult?.groups) {
let match = separator.exec(item);
if (match?.groups) {
const node: PageTree.Separator = {
type: 'separator',
name: separateResult.groups.name,
name: match.groups.name,
};
return [ctx.options.attachSeparator?.(node) ?? node];
}
const linkResult = link.exec(item);
if (linkResult?.groups) {
const { icon, url, name } = linkResult.groups;
match = link.exec(item);
if (match?.groups) {
const { icon, url, name } = match.groups;
const isRelative =
url.startsWith('/') || url.startsWith('#') || url.startsWith('.');
+3 -2
View File
@@ -1,8 +1,9 @@
export function removeUndefined<T extends object>(value: T): T {
const obj = value as Record<string, unknown>;
Object.keys(obj).forEach((key) => {
for (const key of Object.keys(obj)) {
if (obj[key] === undefined) delete obj[key];
});
}
return value;
}
+45
View File
@@ -411,3 +411,48 @@ test('Internationalized Routing: Hide Prefix', () => {
expect(result.getPage(['test'])?.url).toBe('/test');
expect(result.getPage(['test'], 'cn')?.url).toBe('/cn/test');
});
test('Loader: Without meta.json', () => {
const result = loader({
baseUrl: '/',
pageTree: {
noRef: true,
},
source: {
files: [
{
type: 'page',
path: 'test.mdx',
data: {
title: 'Hello',
},
},
{
type: 'page',
path: 'hello/index.mdx',
data: {
title: 'Hello',
},
},
],
},
});
expect(result.pageTree, 'Page Tree').toMatchInlineSnapshot(`
{
"children": [
{
"name": "Hello",
"type": "page",
"url": "/hello",
},
{
"name": "Hello",
"type": "page",
"url": "/test",
},
],
"name": "",
}
`);
});