fumadocs-core 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/breadcrumb.d.ts +11 -0
- package/dist/breadcrumb.js +47 -0
- package/dist/chunk-2ZGUSAWB.js +12 -0
- package/dist/chunk-AFKH746E.js +40 -0
- package/dist/chunk-GT3Y35O6.js +46 -0
- package/dist/chunk-WEAGW6MQ.js +63 -0
- package/dist/dynamic-link.d.ts +14 -0
- package/dist/dynamic-link.js +33 -0
- package/dist/get-toc-YF_TdazL.d.ts +14 -0
- package/dist/link.d.ts +24 -0
- package/dist/link.js +7 -0
- package/dist/mdx-plugins/index.d.ts +89 -0
- package/dist/mdx-plugins/index.js +353 -0
- package/dist/middleware.d.ts +10 -0
- package/dist/middleware.js +43 -0
- package/dist/page-tree-izSPERQk.d.ts +37 -0
- package/dist/remark-structure-RwYPDA6M.d.ts +34 -0
- package/dist/search/client.d.ts +13 -0
- package/dist/search/client.js +52 -0
- package/dist/search/server.d.ts +51 -0
- package/dist/search/server.js +209 -0
- package/dist/search/shared.d.ts +8 -0
- package/dist/search/shared.js +0 -0
- package/dist/search-algolia/client.d.ts +28 -0
- package/dist/search-algolia/client.js +68 -0
- package/dist/search-algolia/server.d.ts +45 -0
- package/dist/search-algolia/server.js +68 -0
- package/dist/server/index.d.ts +57 -0
- package/dist/server/index.js +148 -0
- package/dist/sidebar.d.ts +19 -0
- package/dist/sidebar.js +88 -0
- package/dist/source/index.d.ts +171 -0
- package/dist/source/index.js +389 -0
- package/dist/toc.d.ts +20 -0
- package/dist/toc.js +113 -0
- package/package.json +158 -0
package/dist/sidebar.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__objRest,
|
|
3
|
+
__spreadProps,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "./chunk-WEAGW6MQ.js";
|
|
6
|
+
|
|
7
|
+
// src/sidebar.tsx
|
|
8
|
+
import { usePathname } from "next/navigation";
|
|
9
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
10
|
+
import { RemoveScroll } from "react-remove-scroll";
|
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
|
12
|
+
var SidebarContext = createContext(void 0);
|
|
13
|
+
function useSidebarContext() {
|
|
14
|
+
const ctx = useContext(SidebarContext);
|
|
15
|
+
if (!ctx)
|
|
16
|
+
throw new Error("Missing sidebar provider");
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
function SidebarProvider(props) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
const [openInner, setOpenInner] = useState(false);
|
|
22
|
+
const [open, setOpen] = [
|
|
23
|
+
(_a = props.open) != null ? _a : openInner,
|
|
24
|
+
(_b = props.onOpenChange) != null ? _b : setOpenInner
|
|
25
|
+
];
|
|
26
|
+
const pathname = usePathname();
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setOpen(false);
|
|
29
|
+
}, [pathname]);
|
|
30
|
+
return /* @__PURE__ */ jsx(SidebarContext.Provider, { value: [open, setOpen], children: props.children });
|
|
31
|
+
}
|
|
32
|
+
function SidebarTrigger(_a) {
|
|
33
|
+
var _b = _a, {
|
|
34
|
+
as
|
|
35
|
+
} = _b, props = __objRest(_b, [
|
|
36
|
+
"as"
|
|
37
|
+
]);
|
|
38
|
+
const [open, setOpen] = useSidebarContext();
|
|
39
|
+
const As = as != null ? as : "button";
|
|
40
|
+
return /* @__PURE__ */ jsx(
|
|
41
|
+
As,
|
|
42
|
+
__spreadValues({
|
|
43
|
+
"data-open": open,
|
|
44
|
+
onClick: () => {
|
|
45
|
+
setOpen(!open);
|
|
46
|
+
}
|
|
47
|
+
}, props)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
function SidebarList(_a) {
|
|
51
|
+
var _b = _a, {
|
|
52
|
+
as,
|
|
53
|
+
minWidth
|
|
54
|
+
} = _b, props = __objRest(_b, [
|
|
55
|
+
"as",
|
|
56
|
+
"minWidth"
|
|
57
|
+
]);
|
|
58
|
+
const [open] = useSidebarContext();
|
|
59
|
+
const [isMobileLayout, setIsMobileLayout] = useState(false);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (minWidth === void 0)
|
|
62
|
+
return;
|
|
63
|
+
const mediaQueryList = window.matchMedia(`(min-width: ${minWidth}px)`);
|
|
64
|
+
const handleChange = () => {
|
|
65
|
+
setIsMobileLayout(!mediaQueryList.matches);
|
|
66
|
+
};
|
|
67
|
+
handleChange();
|
|
68
|
+
mediaQueryList.addEventListener("change", handleChange);
|
|
69
|
+
return () => {
|
|
70
|
+
mediaQueryList.removeEventListener("change", handleChange);
|
|
71
|
+
};
|
|
72
|
+
}, [minWidth]);
|
|
73
|
+
return /* @__PURE__ */ jsx(
|
|
74
|
+
RemoveScroll,
|
|
75
|
+
__spreadProps(__spreadValues({
|
|
76
|
+
as: as != null ? as : "aside",
|
|
77
|
+
"data-open": isMobileLayout ? open : false,
|
|
78
|
+
enabled: isMobileLayout ? open : false
|
|
79
|
+
}, props), {
|
|
80
|
+
children: props.children
|
|
81
|
+
})
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
SidebarList,
|
|
86
|
+
SidebarProvider,
|
|
87
|
+
SidebarTrigger
|
|
88
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { R as Root } from '../page-tree-izSPERQk.js';
|
|
3
|
+
|
|
4
|
+
interface LoadOptions {
|
|
5
|
+
files: VirtualFile[];
|
|
6
|
+
transformers?: Transformer[];
|
|
7
|
+
rootDir: string;
|
|
8
|
+
getSlugs: (info: FileInfo) => string[];
|
|
9
|
+
getUrl: (slugs: string[], locale?: string) => string;
|
|
10
|
+
}
|
|
11
|
+
interface VirtualFile {
|
|
12
|
+
path: string;
|
|
13
|
+
type: 'page' | 'meta';
|
|
14
|
+
data: unknown;
|
|
15
|
+
}
|
|
16
|
+
interface LoadResult {
|
|
17
|
+
storage: Storage;
|
|
18
|
+
getSlugs: (info: FileInfo) => string[];
|
|
19
|
+
getUrl: (slugs: string[], locale?: string) => string;
|
|
20
|
+
data: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
declare function load(options: LoadOptions): LoadResult;
|
|
23
|
+
|
|
24
|
+
interface LoaderConfig {
|
|
25
|
+
source: SourceConfig;
|
|
26
|
+
i18n: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface SourceConfig {
|
|
29
|
+
pageData: PageData;
|
|
30
|
+
metaData: MetaData;
|
|
31
|
+
}
|
|
32
|
+
interface LoaderOptions {
|
|
33
|
+
/**
|
|
34
|
+
* @defaultValue `''`
|
|
35
|
+
*/
|
|
36
|
+
rootDir?: string;
|
|
37
|
+
/**
|
|
38
|
+
* @defaultValue `'/'`
|
|
39
|
+
*/
|
|
40
|
+
baseUrl?: string;
|
|
41
|
+
languages?: string[];
|
|
42
|
+
icon?: NonNullable<CreatePageTreeBuilderOptions['resolveIcon']>;
|
|
43
|
+
slugs?: LoadOptions['getSlugs'];
|
|
44
|
+
url?: LoadOptions['getUrl'];
|
|
45
|
+
source: Source<any>;
|
|
46
|
+
transformers?: Transformer[];
|
|
47
|
+
}
|
|
48
|
+
interface Source<Config extends SourceConfig> {
|
|
49
|
+
/**
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
_config?: Config;
|
|
53
|
+
files: VirtualFile[] | ((rootDir: string) => VirtualFile[]);
|
|
54
|
+
}
|
|
55
|
+
interface LoaderOutput<Config extends LoaderConfig> {
|
|
56
|
+
pageTree: Config['i18n'] extends true ? Record<string, Root> : Root;
|
|
57
|
+
files: Node<Config['source']['metaData'], Config['source']['pageData']>[];
|
|
58
|
+
/**
|
|
59
|
+
* Get list of pages from language, empty if language hasn't specified
|
|
60
|
+
*
|
|
61
|
+
* @param language - If empty, the default language will be used
|
|
62
|
+
*/
|
|
63
|
+
getPages: (language?: string) => Page<Config['source']['pageData']>[];
|
|
64
|
+
/**
|
|
65
|
+
* @param language - If empty, the default language will be used
|
|
66
|
+
*/
|
|
67
|
+
getPage: (slugs: string[] | undefined, language?: string) => Page<Config['source']['pageData']> | undefined;
|
|
68
|
+
}
|
|
69
|
+
type InferSourceConfig<T> = T extends Source<infer Config> ? Config : never;
|
|
70
|
+
declare function loader<Options extends LoaderOptions>(options: Options): LoaderOutput<{
|
|
71
|
+
source: InferSourceConfig<Options['source']>;
|
|
72
|
+
i18n: Options['languages'] extends string[] ? true : false;
|
|
73
|
+
}>;
|
|
74
|
+
|
|
75
|
+
interface FileInfo {
|
|
76
|
+
locale?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Original path of file
|
|
79
|
+
*/
|
|
80
|
+
path: string;
|
|
81
|
+
/**
|
|
82
|
+
* File path without extension
|
|
83
|
+
*/
|
|
84
|
+
flattenedPath: string;
|
|
85
|
+
/**
|
|
86
|
+
* File name without locale and extension
|
|
87
|
+
*/
|
|
88
|
+
name: string;
|
|
89
|
+
dirname: string;
|
|
90
|
+
}
|
|
91
|
+
interface MetaData {
|
|
92
|
+
icon?: string;
|
|
93
|
+
title?: string;
|
|
94
|
+
root?: boolean;
|
|
95
|
+
pages?: string[];
|
|
96
|
+
}
|
|
97
|
+
interface PageData {
|
|
98
|
+
icon?: string;
|
|
99
|
+
title: string;
|
|
100
|
+
}
|
|
101
|
+
type InferPageType<Utils extends LoaderOutput<any>> = Utils extends LoaderOutput<infer Config> ? Page<Config['source']['pageData']> : never;
|
|
102
|
+
type InferMetaType<Utils extends LoaderOutput<any>> = Utils extends LoaderOutput<infer Config> ? Meta<Config['source']['metaData']> : never;
|
|
103
|
+
type Transformer = (context: LoadResult) => void;
|
|
104
|
+
|
|
105
|
+
interface Meta<Data extends MetaData = MetaData> {
|
|
106
|
+
type: 'meta';
|
|
107
|
+
file: FileInfo;
|
|
108
|
+
data: Data;
|
|
109
|
+
}
|
|
110
|
+
interface Page<Data extends PageData = PageData> {
|
|
111
|
+
type: 'page';
|
|
112
|
+
file: FileInfo;
|
|
113
|
+
slugs: string[];
|
|
114
|
+
url: string;
|
|
115
|
+
data: Data;
|
|
116
|
+
}
|
|
117
|
+
interface Folder<MD extends MetaData = MetaData, PD extends PageData = PageData> {
|
|
118
|
+
type: 'folder';
|
|
119
|
+
file: FileInfo;
|
|
120
|
+
children: Node<MD, PD>[];
|
|
121
|
+
}
|
|
122
|
+
type Node<MD extends MetaData = MetaData, PD extends PageData = PageData> = Meta<MD> | Page<PD> | Folder;
|
|
123
|
+
/**
|
|
124
|
+
* A virtual file system that solves inconsistent behaviours
|
|
125
|
+
*
|
|
126
|
+
* Some source providers may not provide the full file structure, this will cause inconsistent outputs for page builder and other transformers
|
|
127
|
+
*/
|
|
128
|
+
declare class Storage {
|
|
129
|
+
files: Map<string, Page<PageData> | Meta<MetaData>>;
|
|
130
|
+
folders: Map<string, Folder<MetaData, PageData>>;
|
|
131
|
+
private rootFolder;
|
|
132
|
+
constructor();
|
|
133
|
+
/**
|
|
134
|
+
* Read a file, it doesn't need an extension
|
|
135
|
+
* @param path - flattened path
|
|
136
|
+
*/
|
|
137
|
+
read(path: string): Page | Meta | undefined;
|
|
138
|
+
readDir(path: string): Folder | undefined;
|
|
139
|
+
root(): Folder;
|
|
140
|
+
write(path: string, file: Omit<Page, 'file'> | Omit<Meta, 'file'>): void;
|
|
141
|
+
list(): (Page | Meta)[];
|
|
142
|
+
makeDir(path: string): void;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type fileSystem_Folder<MD extends MetaData = MetaData, PD extends PageData = PageData> = Folder<MD, PD>;
|
|
146
|
+
type fileSystem_Meta<Data extends MetaData = MetaData> = Meta<Data>;
|
|
147
|
+
type fileSystem_Node<MD extends MetaData = MetaData, PD extends PageData = PageData> = Node<MD, PD>;
|
|
148
|
+
type fileSystem_Page<Data extends PageData = PageData> = Page<Data>;
|
|
149
|
+
type fileSystem_Storage = Storage;
|
|
150
|
+
declare const fileSystem_Storage: typeof Storage;
|
|
151
|
+
declare namespace fileSystem {
|
|
152
|
+
export { type fileSystem_Folder as Folder, type fileSystem_Meta as Meta, type fileSystem_Node as Node, type fileSystem_Page as Page, fileSystem_Storage as Storage };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
interface BuildPageTreeOptionsWithI18n {
|
|
156
|
+
languages: string[];
|
|
157
|
+
}
|
|
158
|
+
interface PageTreeBuilder {
|
|
159
|
+
build: () => Root;
|
|
160
|
+
/**
|
|
161
|
+
* Build page tree and fallback to the default language if the page doesn't exist
|
|
162
|
+
*/
|
|
163
|
+
buildI18n: (options?: Partial<BuildPageTreeOptionsWithI18n>) => Record<string, Root>;
|
|
164
|
+
}
|
|
165
|
+
interface CreatePageTreeBuilderOptions {
|
|
166
|
+
storage: Storage;
|
|
167
|
+
resolveIcon?: (icon: string) => ReactElement | undefined;
|
|
168
|
+
}
|
|
169
|
+
declare function createPageTreeBuilder({ storage, resolveIcon, }: CreatePageTreeBuilderOptions): PageTreeBuilder;
|
|
170
|
+
|
|
171
|
+
export { type BuildPageTreeOptionsWithI18n, type CreatePageTreeBuilderOptions, type FileInfo, fileSystem as FileSystem, type InferMetaType, type InferPageType, type LoadOptions, type LoadResult, type LoaderOptions, type LoaderOutput, type MetaData, type PageData, type PageTreeBuilder, type Source, type Transformer, type VirtualFile, createPageTreeBuilder, load, loader };
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import {
|
|
2
|
+
slash
|
|
3
|
+
} from "../chunk-2ZGUSAWB.js";
|
|
4
|
+
import {
|
|
5
|
+
__export,
|
|
6
|
+
__spreadProps,
|
|
7
|
+
__spreadValues
|
|
8
|
+
} from "../chunk-WEAGW6MQ.js";
|
|
9
|
+
|
|
10
|
+
// src/source/path.ts
|
|
11
|
+
import { parse } from "path";
|
|
12
|
+
function parseFilePath(path) {
|
|
13
|
+
const parsed = parse(path);
|
|
14
|
+
const dir = slash(parsed.dir);
|
|
15
|
+
const flattenedPath = joinPaths([dir, parsed.name]);
|
|
16
|
+
const [name, locale] = parsed.name.split(".");
|
|
17
|
+
return {
|
|
18
|
+
dirname: dir,
|
|
19
|
+
name,
|
|
20
|
+
flattenedPath,
|
|
21
|
+
locale,
|
|
22
|
+
path
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function isRelative(path, root) {
|
|
26
|
+
return path.startsWith(root);
|
|
27
|
+
}
|
|
28
|
+
function getRelativePath(path, root) {
|
|
29
|
+
if (!isRelative(path, root))
|
|
30
|
+
throw new Error("Invalid path");
|
|
31
|
+
return splitPath(path.substring(root.length)).join("/");
|
|
32
|
+
}
|
|
33
|
+
function parseFolderPath(path) {
|
|
34
|
+
const parsed = parse(path);
|
|
35
|
+
const dir = parsed.dir.replace("\\", "/");
|
|
36
|
+
const [name, locale] = parsed.base.split(".");
|
|
37
|
+
return {
|
|
38
|
+
dirname: dir,
|
|
39
|
+
name,
|
|
40
|
+
flattenedPath: path,
|
|
41
|
+
locale,
|
|
42
|
+
path
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function splitPath(path) {
|
|
46
|
+
return path.split("/").filter((p) => p.length > 0);
|
|
47
|
+
}
|
|
48
|
+
function joinPaths(paths, slashMode = "none") {
|
|
49
|
+
const joined = paths.flatMap((path) => splitPath(path)).join("/");
|
|
50
|
+
switch (slashMode) {
|
|
51
|
+
case "leading":
|
|
52
|
+
return `/${joined}`;
|
|
53
|
+
case "trailing":
|
|
54
|
+
return `${joined}/`;
|
|
55
|
+
default:
|
|
56
|
+
return joined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/source/page-tree-builder.ts
|
|
61
|
+
var separator = new RegExp("---(?<name>.*?)---");
|
|
62
|
+
var rest = "...";
|
|
63
|
+
var extractor = new RegExp("\\.\\.\\.(?<name>.+)");
|
|
64
|
+
function buildAll(nodes, ctx, skipIndex) {
|
|
65
|
+
const output = [];
|
|
66
|
+
for (const node of [...nodes].sort(
|
|
67
|
+
(a, b) => a.file.name.localeCompare(b.file.name)
|
|
68
|
+
)) {
|
|
69
|
+
if (node.type === "page") {
|
|
70
|
+
if (node.file.locale)
|
|
71
|
+
continue;
|
|
72
|
+
const treeNode = buildFileNode(node, ctx);
|
|
73
|
+
if (node.file.name === "index") {
|
|
74
|
+
if (!skipIndex)
|
|
75
|
+
output.unshift(treeNode);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
output.push(treeNode);
|
|
79
|
+
}
|
|
80
|
+
if (node.type === "folder") {
|
|
81
|
+
output.push(buildFolderNode(node, ctx));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return output;
|
|
85
|
+
}
|
|
86
|
+
function getFolderMeta(folder, ctx) {
|
|
87
|
+
var _a;
|
|
88
|
+
let meta = ctx.storage.read(joinPaths([folder.file.path, "meta"]));
|
|
89
|
+
if (ctx.lang) {
|
|
90
|
+
meta = (_a = ctx.storage.read(joinPaths([folder.file.path, `meta.${ctx.lang}`]))) != null ? _a : meta;
|
|
91
|
+
}
|
|
92
|
+
if ((meta == null ? void 0 : meta.type) === "meta")
|
|
93
|
+
return meta;
|
|
94
|
+
}
|
|
95
|
+
function buildFolderNode(folder, ctx, root = false) {
|
|
96
|
+
var _a, _b, _c, _d, _e;
|
|
97
|
+
const indexNode = folder.children.find(
|
|
98
|
+
(node) => node.type === "page" && node.file.name === "index"
|
|
99
|
+
);
|
|
100
|
+
const index = indexNode ? buildFileNode(indexNode, ctx) : void 0;
|
|
101
|
+
const meta = (_a = getFolderMeta(folder, ctx)) == null ? void 0 : _a.data;
|
|
102
|
+
let children;
|
|
103
|
+
if (!meta) {
|
|
104
|
+
children = buildAll(folder.children, ctx, !root);
|
|
105
|
+
} else {
|
|
106
|
+
const isRoot = (_b = meta.root) != null ? _b : root;
|
|
107
|
+
const addedNodePaths = /* @__PURE__ */ new Set();
|
|
108
|
+
const resolved = (_c = meta.pages) == null ? void 0 : _c.flatMap((item) => {
|
|
109
|
+
var _a2, _b2, _c2;
|
|
110
|
+
if (item === rest)
|
|
111
|
+
return "...";
|
|
112
|
+
const result = separator.exec(item);
|
|
113
|
+
if (result == null ? void 0 : result.groups) {
|
|
114
|
+
return {
|
|
115
|
+
type: "separator",
|
|
116
|
+
name: result.groups.name
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const extractResult = extractor.exec(item);
|
|
120
|
+
const extractName = (_b2 = (_a2 = extractResult == null ? void 0 : extractResult.groups) == null ? void 0 : _a2.name) != null ? _b2 : item;
|
|
121
|
+
const itemNode = (_c2 = ctx.storage.readDir(joinPaths([folder.file.path, extractName]))) != null ? _c2 : ctx.storage.read(joinPaths([folder.file.path, extractName]));
|
|
122
|
+
if (!itemNode)
|
|
123
|
+
return [];
|
|
124
|
+
addedNodePaths.add(itemNode.file.path);
|
|
125
|
+
if (itemNode.type === "folder") {
|
|
126
|
+
const node = buildFolderNode(itemNode, ctx);
|
|
127
|
+
return (extractResult == null ? void 0 : extractResult.groups) ? node.children : node;
|
|
128
|
+
}
|
|
129
|
+
if (itemNode.type === "page") {
|
|
130
|
+
return buildFileNode(itemNode, ctx);
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
});
|
|
134
|
+
const restNodes = buildAll(
|
|
135
|
+
folder.children.filter((node) => !addedNodePaths.has(node.file.path)),
|
|
136
|
+
ctx,
|
|
137
|
+
!isRoot
|
|
138
|
+
);
|
|
139
|
+
const nodes = resolved == null ? void 0 : resolved.flatMap((item) => {
|
|
140
|
+
if (item === "...") {
|
|
141
|
+
return restNodes;
|
|
142
|
+
}
|
|
143
|
+
return item;
|
|
144
|
+
});
|
|
145
|
+
children = nodes != null ? nodes : restNodes;
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
type: "folder",
|
|
149
|
+
name: (_e = (_d = meta == null ? void 0 : meta.title) != null ? _d : index == null ? void 0 : index.name) != null ? _e : pathToName(folder.file.name),
|
|
150
|
+
icon: ctx.resolveIcon(meta == null ? void 0 : meta.icon),
|
|
151
|
+
root: meta == null ? void 0 : meta.root,
|
|
152
|
+
index,
|
|
153
|
+
children
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function buildFileNode(page, ctx) {
|
|
157
|
+
let localePage = page;
|
|
158
|
+
if (ctx.lang) {
|
|
159
|
+
const result = ctx.storage.read(`${page.file.flattenedPath}.${ctx.lang}`);
|
|
160
|
+
if ((result == null ? void 0 : result.type) === "page")
|
|
161
|
+
localePage = result;
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
type: "page",
|
|
165
|
+
name: localePage.data.title,
|
|
166
|
+
icon: ctx.resolveIcon(localePage.data.icon),
|
|
167
|
+
url: localePage.url
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function build(ctx) {
|
|
171
|
+
const root = ctx.storage.root();
|
|
172
|
+
const folder = buildFolderNode(root, ctx, true);
|
|
173
|
+
return {
|
|
174
|
+
name: folder.name,
|
|
175
|
+
children: folder.children
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function createPageTreeBuilder({
|
|
179
|
+
storage,
|
|
180
|
+
resolveIcon = () => void 0
|
|
181
|
+
}) {
|
|
182
|
+
const context = {
|
|
183
|
+
storage,
|
|
184
|
+
resolveIcon(icon) {
|
|
185
|
+
if (!icon)
|
|
186
|
+
return;
|
|
187
|
+
return resolveIcon(icon);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
build() {
|
|
192
|
+
return build(context);
|
|
193
|
+
},
|
|
194
|
+
buildI18n({ languages = [] } = {}) {
|
|
195
|
+
const entries = languages.map((lang) => {
|
|
196
|
+
const tree = build(__spreadProps(__spreadValues({}, context), {
|
|
197
|
+
lang
|
|
198
|
+
}));
|
|
199
|
+
return [lang, tree];
|
|
200
|
+
});
|
|
201
|
+
return Object.fromEntries(entries);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function pathToName(path) {
|
|
206
|
+
return path.slice(0, 1).toUpperCase() + path.slice(1);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/source/file-system.ts
|
|
210
|
+
var file_system_exports = {};
|
|
211
|
+
__export(file_system_exports, {
|
|
212
|
+
Storage: () => Storage
|
|
213
|
+
});
|
|
214
|
+
var Storage = class {
|
|
215
|
+
constructor() {
|
|
216
|
+
this.files = /* @__PURE__ */ new Map();
|
|
217
|
+
this.folders = /* @__PURE__ */ new Map();
|
|
218
|
+
this.rootFolder = {
|
|
219
|
+
type: "folder",
|
|
220
|
+
file: parseFolderPath(""),
|
|
221
|
+
children: []
|
|
222
|
+
};
|
|
223
|
+
this.folders.set("", this.rootFolder);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Read a file, it doesn't need an extension
|
|
227
|
+
* @param path - flattened path
|
|
228
|
+
*/
|
|
229
|
+
read(path) {
|
|
230
|
+
return this.files.get(path);
|
|
231
|
+
}
|
|
232
|
+
readDir(path) {
|
|
233
|
+
return this.folders.get(path);
|
|
234
|
+
}
|
|
235
|
+
root() {
|
|
236
|
+
return this.rootFolder;
|
|
237
|
+
}
|
|
238
|
+
write(path, file) {
|
|
239
|
+
var _a;
|
|
240
|
+
const node = __spreadValues({
|
|
241
|
+
file: parseFilePath(path)
|
|
242
|
+
}, file);
|
|
243
|
+
this.makeDir(node.file.dirname);
|
|
244
|
+
(_a = this.readDir(node.file.dirname)) == null ? void 0 : _a.children.push(node);
|
|
245
|
+
this.files.set(node.file.flattenedPath, node);
|
|
246
|
+
}
|
|
247
|
+
list() {
|
|
248
|
+
return [...this.files.values()];
|
|
249
|
+
}
|
|
250
|
+
makeDir(path) {
|
|
251
|
+
var _a;
|
|
252
|
+
const segments = splitPath(path);
|
|
253
|
+
for (let i = 0; i < segments.length; i++) {
|
|
254
|
+
const segment = segments.slice(0, i + 1).join("/");
|
|
255
|
+
if (this.folders.has(segment))
|
|
256
|
+
continue;
|
|
257
|
+
const folder = {
|
|
258
|
+
type: "folder",
|
|
259
|
+
file: parseFolderPath(segment),
|
|
260
|
+
children: []
|
|
261
|
+
};
|
|
262
|
+
this.folders.set(folder.file.path, folder);
|
|
263
|
+
(_a = this.readDir(folder.file.dirname)) == null ? void 0 : _a.children.push(folder);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// src/source/load.ts
|
|
269
|
+
function load(options) {
|
|
270
|
+
const { transformers = [] } = options;
|
|
271
|
+
const storage = buildStorage(options);
|
|
272
|
+
const ctx = {
|
|
273
|
+
getSlugs: options.getSlugs,
|
|
274
|
+
getUrl: options.getUrl,
|
|
275
|
+
storage,
|
|
276
|
+
data: {}
|
|
277
|
+
};
|
|
278
|
+
for (const transformer of transformers) {
|
|
279
|
+
transformer(ctx);
|
|
280
|
+
}
|
|
281
|
+
return ctx;
|
|
282
|
+
}
|
|
283
|
+
function buildStorage(options) {
|
|
284
|
+
const storage = new Storage();
|
|
285
|
+
for (const file of options.files) {
|
|
286
|
+
if (!isRelative(file.path, options.rootDir))
|
|
287
|
+
continue;
|
|
288
|
+
const path = getRelativePath(file.path, options.rootDir);
|
|
289
|
+
if (file.type === "page") {
|
|
290
|
+
const parsedPath = parseFilePath(path);
|
|
291
|
+
const slugs = options.getSlugs(parsedPath);
|
|
292
|
+
storage.write(path, {
|
|
293
|
+
slugs,
|
|
294
|
+
url: options.getUrl(slugs, parsedPath.locale),
|
|
295
|
+
type: file.type,
|
|
296
|
+
data: file.data
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (file.type === "meta") {
|
|
300
|
+
storage.write(path, {
|
|
301
|
+
type: file.type,
|
|
302
|
+
data: file.data
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return storage;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/source/create.ts
|
|
310
|
+
function groupByLanguages(nodes, languages) {
|
|
311
|
+
var _a, _b, _c;
|
|
312
|
+
const pageMap = /* @__PURE__ */ new Map();
|
|
313
|
+
for (const node of nodes) {
|
|
314
|
+
if (node.type === "page")
|
|
315
|
+
pageMap.set(node.file.flattenedPath, node);
|
|
316
|
+
}
|
|
317
|
+
const langMap = /* @__PURE__ */ new Map();
|
|
318
|
+
langMap.set("", []);
|
|
319
|
+
for (const lang of languages) {
|
|
320
|
+
langMap.set(lang, []);
|
|
321
|
+
}
|
|
322
|
+
for (const [key, node] of pageMap) {
|
|
323
|
+
if (node.file.locale)
|
|
324
|
+
continue;
|
|
325
|
+
(_a = langMap.get("")) == null ? void 0 : _a.push(node);
|
|
326
|
+
for (const lang of languages) {
|
|
327
|
+
const v = (_b = pageMap.get(`${key}.${lang}`)) != null ? _b : node;
|
|
328
|
+
(_c = langMap.get(lang)) == null ? void 0 : _c.push(v);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return langMap;
|
|
332
|
+
}
|
|
333
|
+
function createGetUrl(baseUrl) {
|
|
334
|
+
return (slugs, locale) => {
|
|
335
|
+
let paths = [baseUrl, ...slugs];
|
|
336
|
+
if (locale)
|
|
337
|
+
paths = [baseUrl, locale, ...slugs];
|
|
338
|
+
return joinPaths(paths, "leading");
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function loader(options) {
|
|
342
|
+
return createOutput(options);
|
|
343
|
+
}
|
|
344
|
+
function createOutput({
|
|
345
|
+
source,
|
|
346
|
+
icon,
|
|
347
|
+
languages,
|
|
348
|
+
rootDir = "",
|
|
349
|
+
transformers,
|
|
350
|
+
baseUrl = "/",
|
|
351
|
+
slugs = (info) => {
|
|
352
|
+
const result = [...info.dirname.split("/"), info.name].filter(Boolean);
|
|
353
|
+
return result[result.length - 1] === "index" ? result.slice(0, -1) : result;
|
|
354
|
+
},
|
|
355
|
+
url = createGetUrl(baseUrl)
|
|
356
|
+
}) {
|
|
357
|
+
const result = load({
|
|
358
|
+
files: typeof source.files === "function" ? source.files(rootDir) : source.files,
|
|
359
|
+
transformers,
|
|
360
|
+
rootDir,
|
|
361
|
+
getSlugs: slugs,
|
|
362
|
+
getUrl: url
|
|
363
|
+
});
|
|
364
|
+
const i18nMap = groupByLanguages(result.storage.list(), languages != null ? languages : []);
|
|
365
|
+
const builder = createPageTreeBuilder({
|
|
366
|
+
storage: result.storage,
|
|
367
|
+
resolveIcon: icon
|
|
368
|
+
});
|
|
369
|
+
const pageTree = languages === void 0 ? builder.build() : builder.buildI18n({ languages });
|
|
370
|
+
return {
|
|
371
|
+
pageTree,
|
|
372
|
+
files: result.storage.list(),
|
|
373
|
+
getPages(language = "") {
|
|
374
|
+
var _a;
|
|
375
|
+
return (_a = i18nMap.get(language)) != null ? _a : [];
|
|
376
|
+
},
|
|
377
|
+
getPage(slugs_ = [], language = "") {
|
|
378
|
+
var _a;
|
|
379
|
+
const path = slugs_.join("/");
|
|
380
|
+
return (_a = i18nMap.get(language)) == null ? void 0 : _a.find((page) => page.slugs.join("/") === path);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
export {
|
|
385
|
+
file_system_exports as FileSystem,
|
|
386
|
+
createPageTreeBuilder,
|
|
387
|
+
load,
|
|
388
|
+
loader
|
|
389
|
+
};
|
package/dist/toc.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, AnchorHTMLAttributes } from 'react';
|
|
3
|
+
import { T as TableOfContents, a as TOCItemType } from './get-toc-YF_TdazL.js';
|
|
4
|
+
|
|
5
|
+
declare const useActiveAnchor: (url: string) => boolean;
|
|
6
|
+
declare const TOCProvider: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
|
|
7
|
+
toc: TableOfContents;
|
|
8
|
+
} & react.RefAttributes<HTMLDivElement>>;
|
|
9
|
+
type TOCItemProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
10
|
+
href: string;
|
|
11
|
+
/** @deprecated You don't need to pass this anymore */
|
|
12
|
+
item?: TOCItemType;
|
|
13
|
+
};
|
|
14
|
+
declare const TOCItem: react.ForwardRefExoticComponent<AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
15
|
+
href: string;
|
|
16
|
+
/** @deprecated You don't need to pass this anymore */
|
|
17
|
+
item?: TOCItemType | undefined;
|
|
18
|
+
} & react.RefAttributes<HTMLAnchorElement>>;
|
|
19
|
+
|
|
20
|
+
export { TOCItem, type TOCItemProps, TOCProvider, useActiveAnchor };
|