Core: Support relative paths as root directory

This commit is contained in:
Fuma Nama
2024-02-23 21:13:14 +08:00
parent 5890a40678
commit 691f12aa93
4 changed files with 37 additions and 31 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-core': patch
---
Source API: Support relative paths as root directory
+14 -6
View File
@@ -1,5 +1,6 @@
import * as path from 'node:path';
import type { FileInfo, MetaData, PageData, Transformer } from './types';
import { getRelativePath, isRelative, parseFilePath } from './path';
import { parseFilePath } from './path';
import { Storage } from './file-system';
export interface LoadOptions {
@@ -46,14 +47,21 @@ function buildStorage(options: LoadOptions): Storage {
const storage = new Storage();
for (const file of options.files) {
if (!isRelative(file.path, options.rootDir)) continue;
const path = getRelativePath(file.path, options.rootDir);
const relativePath = path.join(
path.relative(options.rootDir, path.join('./', path.dirname(file.path))),
path.basename(file.path),
);
const isRelative =
!relativePath.startsWith('..') && !path.isAbsolute(relativePath);
if (!isRelative) continue;
if (file.type === 'page') {
const parsedPath = parseFilePath(path);
const parsedPath = parseFilePath(relativePath);
const slugs = options.getSlugs(parsedPath);
storage.write(path, {
storage.write(relativePath, {
slugs,
url: options.getUrl(slugs, parsedPath.locale),
type: file.type,
@@ -62,7 +70,7 @@ function buildStorage(options: LoadOptions): Storage {
}
if (file.type === 'meta') {
storage.write(path, {
storage.write(relativePath, {
type: file.type,
data: file.data as MetaData,
});
+10 -19
View File
@@ -3,40 +3,31 @@ import slash from '@/utils/slash';
import type { FileInfo } from './types';
export function parseFilePath(path: string): FileInfo {
const parsed = parse(path);
const dir = slash(parsed.dir);
const flattenedPath = joinPaths([dir, parsed.name]);
const slashedPath = slash(path);
const parsed = parse(slashedPath);
const flattenedPath = joinPaths([parsed.dir, parsed.name]);
const [name, locale] = parsed.name.split('.');
return {
dirname: dir,
dirname: parsed.dir,
name,
flattenedPath,
locale,
path,
path: slashedPath,
};
}
export function isRelative(path: string, root: string): boolean {
return path.startsWith(root);
}
export function getRelativePath(path: string, root: string): string {
if (!isRelative(path, root)) throw new Error('Invalid path');
return splitPath(path.substring(root.length)).join('/');
}
export function parseFolderPath(path: string): FileInfo {
const parsed = parse(path);
const dir = slash(parsed.dir);
const slashedPath = slash(path);
const parsed = parse(slashedPath);
const [name, locale] = parsed.base.split('.');
return {
dirname: dir,
dirname: parsed.dir,
name,
flattenedPath: path,
flattenedPath: slashedPath,
locale,
path,
path: slashedPath,
};
}
+8 -6
View File
@@ -1,5 +1,4 @@
import {
isRelative,
joinPaths,
parseFilePath,
parseFolderPath,
@@ -32,6 +31,10 @@ describe('Path utilities', () => {
locale: 'cn',
path: 'nested/test.cn.mdx',
});
expect(parseFilePath('nested\\test.cn.mdx')).toEqual(
parseFilePath('nested/test.cn.mdx'),
);
});
test('parse folder path', () => {
@@ -50,6 +53,10 @@ describe('Path utilities', () => {
locale: undefined,
path: 'nested/nested',
});
expect(parseFolderPath('nested\\nested')).toEqual(
parseFolderPath('nested/nested'),
);
});
test('join paths', () => {
@@ -67,9 +74,4 @@ describe('Path utilities', () => {
expect(splitPath('a//c')).toEqual(['a', 'c']);
expect(splitPath('/a/c')).toEqual(['a', 'c']);
});
test('is relative', () => {
expect(isRelative('nested/file.mdx', 'nested')).toBe(true);
expect(isRelative('file.mdx', 'nested')).toBe(false);
});
});