mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: Always encode generated slugs for non-ASCII characters
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Always encode generated slugs for non-ASCII characters in `loader()`
|
||||
@@ -223,15 +223,22 @@ export function createGetUrl(baseUrl: string, i18n?: I18nConfig): UrlFn {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert file path into slugs, also encode non-ASCII characters, so they can work in pathname
|
||||
*/
|
||||
export function getSlugs(info: FileInfo): string[] {
|
||||
return [...info.dirname.split('/'), info.name].filter(
|
||||
// filter empty folder names and file groups like (group_name)
|
||||
(v, i, arr) => {
|
||||
if (v.length === 0) return false;
|
||||
const slugs: string[] = [];
|
||||
|
||||
return i === arr.length - 1 ? v !== 'index' : !/^\(.+\)$/.test(v);
|
||||
},
|
||||
);
|
||||
for (const seg of info.dirname.split('/')) {
|
||||
// filter empty names and file groups like (group_name)
|
||||
if (seg.length > 0 && !/^\(.+\)$/.test(seg)) slugs.push(encodeURI(seg));
|
||||
}
|
||||
|
||||
if (info.name !== 'index') {
|
||||
slugs.push(encodeURI(info.name));
|
||||
}
|
||||
|
||||
return slugs;
|
||||
}
|
||||
|
||||
export function loader<
|
||||
@@ -326,8 +333,8 @@ function createOutput(options: LoaderOptions): LoaderOutput<LoaderConfig> {
|
||||
getPages(language = defaultLanguage) {
|
||||
const pages: Page[] = [];
|
||||
|
||||
for (const key of walker.pages.keys()) {
|
||||
if (key.startsWith(`${language}.`)) pages.push(walker.pages.get(key)!);
|
||||
for (const [key, value] of walker.pages.entries()) {
|
||||
if (key.startsWith(`${language}.`)) pages.push(value);
|
||||
}
|
||||
|
||||
return pages;
|
||||
@@ -352,18 +359,14 @@ function createOutput(options: LoaderOptions): LoaderOutput<LoaderConfig> {
|
||||
const ref = node.$ref?.metaFile;
|
||||
if (!ref) return;
|
||||
|
||||
const file = storages[language]
|
||||
.list()
|
||||
.find((v) => v.format === 'meta' && v.file.path === ref);
|
||||
const file = storages[language].read(ref, 'meta');
|
||||
if (file) return walker.getResultFromFile(file) as Meta;
|
||||
},
|
||||
getNodePage(node, language = defaultLanguage) {
|
||||
const ref = node.$ref?.file;
|
||||
if (!ref) return;
|
||||
|
||||
const file = storages[language]
|
||||
.list()
|
||||
.find((v) => v.format === 'page' && v.file.path === ref);
|
||||
const file = storages[language].read(ref, 'page');
|
||||
if (file) return walker.getResultFromFile(file) as Page;
|
||||
},
|
||||
getPageTree(locale) {
|
||||
|
||||
@@ -257,35 +257,39 @@ function buildFolderNode(
|
||||
index,
|
||||
children,
|
||||
$id: folder.file.path,
|
||||
$ref: !options.noRef
|
||||
? {
|
||||
metaFile: meta?.file.path,
|
||||
}
|
||||
: undefined,
|
||||
$ref:
|
||||
!options.noRef && meta
|
||||
? {
|
||||
metaFile: metaPath,
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
|
||||
return options.attachFolder?.(node, folder, meta) ?? node;
|
||||
}
|
||||
|
||||
function buildFileNode(
|
||||
file: PageFile,
|
||||
page: PageFile,
|
||||
{ options, getUrl, locale }: PageTreeBuilderContext,
|
||||
): PageTree.Item {
|
||||
const file = page.file;
|
||||
const { slugs, data } = page.data;
|
||||
|
||||
const item: PageTree.Item = {
|
||||
$id: file.file.path,
|
||||
$id: file.path,
|
||||
type: 'page',
|
||||
name: file.data.data.title ?? pathToName(file.file.name),
|
||||
description: file.data.data.description,
|
||||
icon: options.resolveIcon?.(file.data.data.icon),
|
||||
url: getUrl(file.data.slugs, locale),
|
||||
name: data.title ?? pathToName(file.name),
|
||||
description: data.description,
|
||||
icon: options.resolveIcon?.(data.icon),
|
||||
url: getUrl(slugs, locale),
|
||||
$ref: !options.noRef
|
||||
? {
|
||||
file: file.file.path,
|
||||
file: joinPath(file.dirname, file.name),
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
|
||||
return options.attachFile?.(item, file) ?? item;
|
||||
return options.attachFile?.(item, page) ?? item;
|
||||
}
|
||||
|
||||
function build(ctx: PageTreeBuilderContext): PageTree.Root {
|
||||
|
||||
@@ -20,18 +20,16 @@ export function joinPath(...paths: string[]): string {
|
||||
const out = [];
|
||||
const parsed = paths.flatMap(splitPath);
|
||||
|
||||
while (parsed.length > 0) {
|
||||
switch (parsed[0]) {
|
||||
for (const seg of parsed) {
|
||||
switch (seg) {
|
||||
case '..':
|
||||
out.pop();
|
||||
break;
|
||||
case '.':
|
||||
break;
|
||||
default:
|
||||
out.push(parsed[0]);
|
||||
out.push(seg);
|
||||
}
|
||||
|
||||
parsed.shift();
|
||||
}
|
||||
|
||||
return out.join('/');
|
||||
|
||||
@@ -306,7 +306,7 @@ test('Internationalized Routing', () => {
|
||||
{
|
||||
"$id": "test.mdx",
|
||||
"$ref": {
|
||||
"file": "test.mdx",
|
||||
"file": "test",
|
||||
},
|
||||
"name": "Hello",
|
||||
"type": "page",
|
||||
@@ -314,12 +314,11 @@ test('Internationalized Routing', () => {
|
||||
},
|
||||
{
|
||||
"$id": "nested",
|
||||
"$ref": {},
|
||||
"children": [
|
||||
{
|
||||
"$id": "nested/test.mdx",
|
||||
"$ref": {
|
||||
"file": "nested/test.mdx",
|
||||
"file": "nested/test",
|
||||
},
|
||||
"name": "Nested Page",
|
||||
"type": "page",
|
||||
@@ -342,7 +341,7 @@ test('Internationalized Routing', () => {
|
||||
{
|
||||
"$id": "test.mdx",
|
||||
"$ref": {
|
||||
"file": "test.mdx",
|
||||
"file": "test",
|
||||
},
|
||||
"name": "Hello Chinese",
|
||||
"type": "page",
|
||||
@@ -351,13 +350,13 @@ test('Internationalized Routing', () => {
|
||||
{
|
||||
"$id": "nested",
|
||||
"$ref": {
|
||||
"metaFile": "nested/meta.json",
|
||||
"metaFile": "nested/meta",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"$id": "nested/test.mdx",
|
||||
"$ref": {
|
||||
"file": "nested/test.mdx",
|
||||
"file": "nested/test",
|
||||
},
|
||||
"name": "Nested Page Chinese",
|
||||
"type": "page",
|
||||
@@ -720,7 +719,7 @@ test('Internationalized Routing: dir', () => {
|
||||
{
|
||||
"$id": "test.mdx",
|
||||
"$ref": {
|
||||
"file": "test.mdx",
|
||||
"file": "test",
|
||||
},
|
||||
"name": "Hello",
|
||||
"type": "page",
|
||||
@@ -728,12 +727,11 @@ test('Internationalized Routing: dir', () => {
|
||||
},
|
||||
{
|
||||
"$id": "nested",
|
||||
"$ref": {},
|
||||
"children": [
|
||||
{
|
||||
"$id": "nested/test.mdx",
|
||||
"$ref": {
|
||||
"file": "nested/test.mdx",
|
||||
"file": "nested/test",
|
||||
},
|
||||
"name": "Nested Page",
|
||||
"type": "page",
|
||||
@@ -756,7 +754,7 @@ test('Internationalized Routing: dir', () => {
|
||||
{
|
||||
"$id": "test.mdx",
|
||||
"$ref": {
|
||||
"file": "test.mdx",
|
||||
"file": "test",
|
||||
},
|
||||
"name": "Hello Chinese",
|
||||
"type": "page",
|
||||
@@ -765,13 +763,13 @@ test('Internationalized Routing: dir', () => {
|
||||
{
|
||||
"$id": "nested",
|
||||
"$ref": {
|
||||
"metaFile": "nested/meta.json",
|
||||
"metaFile": "nested/meta",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"$id": "nested/test.mdx",
|
||||
"$ref": {
|
||||
"file": "nested/test.mdx",
|
||||
"file": "nested/test",
|
||||
},
|
||||
"name": "Nested Page Chinese",
|
||||
"type": "page",
|
||||
|
||||
Reference in New Issue
Block a user