fumadocs-core 16.0.14 → 16.1.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.
@@ -1,8 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { Framework } from './index.js';
2
3
  import { ReactNode } from 'react';
4
+ import 'next/dist/shared/lib/get-img-props';
3
5
 
4
- declare function NextProvider({ children }: {
6
+ declare function NextProvider({ children, Link: CustomLink, Image: CustomImage, }: {
5
7
  children: ReactNode;
8
+ Link?: Framework['Link'];
9
+ Image?: Framework['Image'];
6
10
  }): react_jsx_runtime.JSX.Element;
7
11
 
8
12
  export { NextProvider };
@@ -9,15 +9,19 @@ import { useParams, usePathname, useRouter } from "next/navigation";
9
9
  import Link from "next/link";
10
10
  import Image from "next/image";
11
11
  import { jsx } from "react/jsx-runtime";
12
- function NextProvider({ children }) {
12
+ function NextProvider({
13
+ children,
14
+ Link: CustomLink,
15
+ Image: CustomImage
16
+ }) {
13
17
  return /* @__PURE__ */ jsx(
14
18
  FrameworkProvider,
15
19
  {
16
20
  usePathname,
17
21
  useRouter,
18
22
  useParams,
19
- Link,
20
- Image,
23
+ Link: CustomLink ?? Link,
24
+ Image: CustomImage ?? Image,
21
25
  children
22
26
  }
23
27
  );
@@ -1,8 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
+ import { Framework } from './index.js';
4
+ import 'next/dist/shared/lib/get-img-props';
3
5
 
4
- declare function ReactRouterProvider({ children }: {
6
+ declare function ReactRouterProvider({ children, Link: CustomLink, Image: CustomImage, }: {
5
7
  children: ReactNode;
8
+ Link?: Framework['Link'];
9
+ Image?: Framework['Image'];
6
10
  }): react_jsx_runtime.JSX.Element;
7
11
 
8
12
  export { ReactRouterProvider };
@@ -39,8 +39,20 @@ var framework = {
39
39
  return /* @__PURE__ */ jsx(Link, { to: href, prefetch: prefetch ? "intent" : "none", ...props, children: props.children });
40
40
  }
41
41
  };
42
- function ReactRouterProvider({ children }) {
43
- return /* @__PURE__ */ jsx(FrameworkProvider, { ...framework, children });
42
+ function ReactRouterProvider({
43
+ children,
44
+ Link: CustomLink,
45
+ Image: CustomImage
46
+ }) {
47
+ return /* @__PURE__ */ jsx(
48
+ FrameworkProvider,
49
+ {
50
+ ...framework,
51
+ Link: CustomLink ?? framework.Link,
52
+ Image: CustomImage ?? framework.Image,
53
+ children
54
+ }
55
+ );
44
56
  }
45
57
  export {
46
58
  ReactRouterProvider
@@ -1,11 +1,15 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
+ import { Framework } from './index.js';
4
+ import 'next/dist/shared/lib/get-img-props';
3
5
 
4
6
  /**
5
7
  * Fumadocs adapter for Tanstack Router/Start
6
8
  */
7
- declare function TanstackProvider({ children }: {
9
+ declare function TanstackProvider({ children, Link: CustomLink, Image: CustomImage, }: {
8
10
  children: ReactNode;
11
+ Link?: Framework['Link'];
12
+ Image?: Framework['Image'];
9
13
  }): react_jsx_runtime.JSX.Element;
10
14
 
11
15
  export { TanstackProvider };
@@ -52,8 +52,20 @@ var framework = {
52
52
  return useParams({ strict: false });
53
53
  }
54
54
  };
55
- function TanstackProvider({ children }) {
56
- return /* @__PURE__ */ jsx(FrameworkProvider, { ...framework, children });
55
+ function TanstackProvider({
56
+ children,
57
+ Link: CustomLink,
58
+ Image: CustomImage
59
+ }) {
60
+ return /* @__PURE__ */ jsx(
61
+ FrameworkProvider,
62
+ {
63
+ ...framework,
64
+ Link: CustomLink ?? framework.Link,
65
+ Image: CustomImage ?? framework.Image,
66
+ children
67
+ }
68
+ );
57
69
  }
58
70
  export {
59
71
  TanstackProvider
@@ -1,8 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
+ import { Framework } from './index.js';
4
+ import 'next/dist/shared/lib/get-img-props';
3
5
 
4
- declare function WakuProvider({ children }: {
6
+ declare function WakuProvider({ children, Link: CustomLink, Image: CustomImage, }: {
5
7
  children: ReactNode;
8
+ Link?: Framework['Link'];
9
+ Image?: Framework['Image'];
6
10
  }): react_jsx_runtime.JSX.Element;
7
11
 
8
12
  export { WakuProvider };
@@ -39,12 +39,24 @@ var framework = {
39
39
  [router]
40
40
  );
41
41
  },
42
- Link({ href, prefetch: _prefetch, ...props }) {
43
- return /* @__PURE__ */ jsx(WakuLink, { to: href, ...props, children: props.children });
42
+ Link({ href, prefetch = true, ...props }) {
43
+ return /* @__PURE__ */ jsx(WakuLink, { to: href, unstable_prefetchOnEnter: prefetch, ...props, children: props.children });
44
44
  }
45
45
  };
46
- function WakuProvider({ children }) {
47
- return /* @__PURE__ */ jsx(FrameworkProvider, { ...framework, children });
46
+ function WakuProvider({
47
+ children,
48
+ Link: CustomLink,
49
+ Image: CustomImage
50
+ }) {
51
+ return /* @__PURE__ */ jsx(
52
+ FrameworkProvider,
53
+ {
54
+ ...framework,
55
+ Link: CustomLink ?? framework.Link,
56
+ Image: CustomImage ?? framework.Image,
57
+ children
58
+ }
59
+ );
48
60
  }
49
61
  export {
50
62
  WakuProvider
@@ -2,7 +2,164 @@ import { R as Root, I as Item, F as Folder, S as Separator } from './definitions
2
2
  import { I18nConfig } from './i18n/index.js';
3
3
  import { ReactNode } from 'react';
4
4
 
5
- interface LoaderPlugin<Config extends SourceConfig = SourceConfig> {
5
+ interface Source<Config extends SourceConfig = SourceConfig> {
6
+ files: VirtualFile<Config>[];
7
+ }
8
+ interface SourceConfig {
9
+ pageData: PageData;
10
+ metaData: MetaData;
11
+ }
12
+ interface MetaData {
13
+ icon?: string | undefined;
14
+ title?: string | undefined;
15
+ root?: boolean | undefined;
16
+ pages?: string[] | undefined;
17
+ defaultOpen?: boolean | undefined;
18
+ description?: string | undefined;
19
+ }
20
+ interface PageData {
21
+ icon?: string | undefined;
22
+ title?: string;
23
+ description?: string | undefined;
24
+ }
25
+ type VirtualFile<Config extends SourceConfig = SourceConfig> = VirtualPage<Config['pageData']> | VirtualMeta<Config['metaData']>;
26
+ interface BaseVirtualFile {
27
+ /**
28
+ * Virtualized path (relative to content directory)
29
+ *
30
+ * @example `docs/page.mdx`
31
+ */
32
+ path: string;
33
+ /**
34
+ * Absolute path of the file
35
+ */
36
+ absolutePath?: string;
37
+ }
38
+ interface VirtualPage<Data extends PageData> extends BaseVirtualFile {
39
+ type: 'page';
40
+ /**
41
+ * Specified Slugs for page
42
+ */
43
+ slugs?: string[];
44
+ data: Data;
45
+ }
46
+ interface VirtualMeta<Data extends MetaData> extends BaseVirtualFile {
47
+ type: 'meta';
48
+ data: Data;
49
+ }
50
+ type _ConfigUnion_<T extends Record<string, Source>> = {
51
+ [K in keyof T]: T[K] extends Source<infer Config> ? {
52
+ pageData: Config['pageData'] & {
53
+ type: K;
54
+ };
55
+ metaData: Config['metaData'] & {
56
+ type: K;
57
+ };
58
+ } : never;
59
+ }[keyof T];
60
+ declare function multiple<T extends Record<string, Source>>(sources: T): Source<_ConfigUnion_<T>>;
61
+ /**
62
+ * map virtual files in source
63
+ */
64
+ declare function map<Config extends SourceConfig>(source: Source<Config>): {
65
+ page<$Page extends PageData>(fn: (entry: VirtualPage<Config["pageData"]>) => VirtualPage<$Page>): Source<{
66
+ pageData: $Page;
67
+ metaData: Config["metaData"];
68
+ }>;
69
+ meta<$Meta extends MetaData>(fn: (entry: VirtualMeta<Config["metaData"]>) => VirtualMeta<$Meta>): Source<{
70
+ pageData: Config["pageData"];
71
+ metaData: $Meta;
72
+ }>;
73
+ };
74
+
75
+ /**
76
+ * In memory file system.
77
+ */
78
+ declare class FileSystem<File> {
79
+ files: Map<string, File>;
80
+ folders: Map<string, string[]>;
81
+ constructor(inherit?: FileSystem<File>);
82
+ read(path: string): File | undefined;
83
+ /**
84
+ * get the direct children of folder (in virtual file path)
85
+ */
86
+ readDir(path: string): string[] | undefined;
87
+ write(path: string, file: File): void;
88
+ /**
89
+ * Delete files at specified path.
90
+ *
91
+ * @param path - the target path.
92
+ * @param [recursive=false] - if set to `true`, it will also delete directories.
93
+ */
94
+ delete(path: string, recursive?: boolean): boolean;
95
+ getFiles(): string[];
96
+ makeDir(path: string): void;
97
+ }
98
+
99
+ type ContentStorage<Config extends SourceConfig = SourceConfig> = FileSystem<ContentStorageFile<Config>>;
100
+ type ContentStorageFile<Config extends SourceConfig = SourceConfig> = {
101
+ path: string;
102
+ absolutePath?: string;
103
+ format: 'meta';
104
+ data: Config['metaData'];
105
+ } | {
106
+ path: string;
107
+ absolutePath?: string;
108
+ format: 'page';
109
+ slugs: string[];
110
+ data: Config['pageData'];
111
+ };
112
+ /**
113
+ * @param defaultLanguage - language to use when i18n is not configured.
114
+ * @returns a map of locale and its content storage.
115
+ *
116
+ * in the storage, locale codes are removed from file paths, hence the same file will have same file paths in every storage.
117
+ */
118
+ declare function buildContentStorage(loaderConfig: ResolvedLoaderConfig, defaultLanguage: string): Record<string, ContentStorage>;
119
+
120
+ interface PageTreeBuilderContext<Config extends SourceConfig = SourceConfig> {
121
+ rootId: string;
122
+ generateNodeId: () => string;
123
+ options: PageTreeOptions;
124
+ transformers: PageTreeTransformer<Config>[];
125
+ builder: PageTreeBuilder;
126
+ storage: ContentStorage<Config>;
127
+ getUrl: ResolvedLoaderConfig['url'];
128
+ storages?: Record<string, ContentStorage<Config>>;
129
+ locale?: string;
130
+ }
131
+ interface PageTreeTransformer<Config extends SourceConfig = SourceConfig> {
132
+ file?: (this: PageTreeBuilderContext<Config>, node: Item, filePath?: string) => Item;
133
+ folder?: (this: PageTreeBuilderContext<Config>, node: Folder, folderPath: string, metaPath?: string) => Folder;
134
+ separator?: (this: PageTreeBuilderContext<Config>, node: Separator) => Separator;
135
+ root?: (this: PageTreeBuilderContext<Config>, node: Root) => Root;
136
+ }
137
+ interface PageTreeOptions<Config extends LoaderConfig = LoaderConfig> {
138
+ id?: string;
139
+ /**
140
+ * Remove references to the file path of original nodes (`$ref`)
141
+ *
142
+ * @defaultValue false
143
+ */
144
+ noRef?: boolean;
145
+ /**
146
+ * generate fallback page tree
147
+ *
148
+ * @defaultValue true
149
+ */
150
+ generateFallback?: boolean;
151
+ /**
152
+ * Additional page tree transformers to apply
153
+ */
154
+ transformers?: PageTreeTransformer<Config['source']>[];
155
+ }
156
+ interface PageTreeBuilder {
157
+ build: (storage: ContentStorage, options?: PageTreeOptions) => Root;
158
+ buildI18n: (storages: Record<string, ContentStorage>, options?: PageTreeOptions) => Record<string, Root>;
159
+ }
160
+ declare function createPageTreeBuilder(loaderConfig: ResolvedLoaderConfig): PageTreeBuilder;
161
+
162
+ interface LoaderPlugin<Config extends LoaderConfig = LoaderConfig> {
6
163
  name?: string;
7
164
  /**
8
165
  * Change the order of plugin:
@@ -18,14 +175,15 @@ interface LoaderPlugin<Config extends SourceConfig = SourceConfig> {
18
175
  * transform the storage after loading
19
176
  */
20
177
  transformStorage?: (context: {
21
- storage: ContentStorage<Config['pageData'], Config['metaData']>;
178
+ storage: ContentStorage<Config['source']>;
22
179
  }) => void;
23
180
  /**
24
181
  * transform the generated page tree
25
182
  */
26
- transformPageTree?: PageTreeTransformer<Config['pageData'], Config['metaData']>;
183
+ transformPageTree?: PageTreeTransformer<Config['source']>;
27
184
  }
28
- declare function buildPlugins(plugins: (LoaderPlugin | LoaderPlugin[] | undefined)[]): LoaderPlugin[];
185
+ type LoaderPluginOption<Config extends LoaderConfig = LoaderConfig> = LoaderPlugin<Config> | LoaderPluginOption<Config>[] | undefined;
186
+ declare function buildPlugins(plugins: LoaderPluginOption[], sort?: boolean): LoaderPlugin[];
29
187
 
30
188
  type IconResolver = (icon: string | undefined) => ReactNode;
31
189
 
@@ -33,19 +191,17 @@ interface LoaderConfig {
33
191
  source: SourceConfig;
34
192
  i18n: I18nConfig | undefined;
35
193
  }
36
- interface SourceConfig {
37
- pageData: PageData;
38
- metaData: MetaData;
39
- }
40
- interface LoaderOptions<S extends SourceConfig = SourceConfig, I18n extends I18nConfig | undefined = I18nConfig | undefined> {
194
+ interface LoaderOptions<C extends LoaderConfig = LoaderConfig> {
41
195
  baseUrl: string;
42
- i18n?: I18n;
43
- url?: UrlFn;
196
+ i18n?: C['i18n'];
197
+ url?: (slugs: string[], locale?: string) => string;
44
198
  /**
45
199
  * Additional options for page tree builder
46
200
  */
47
- pageTree?: PageTreeOptions<S>;
48
- plugins?: (LoaderPlugin<S> | LoaderPlugin<S>[] | undefined)[];
201
+ pageTree?: PageTreeOptions<C>;
202
+ plugins?: LoaderPluginOption[] | ((context: {
203
+ typedPlugin: (plugin: LoaderPlugin<C>) => LoaderPlugin;
204
+ }) => LoaderPluginOption[]);
49
205
  icon?: IconResolver;
50
206
  slugs?: (info: {
51
207
  path: string;
@@ -53,14 +209,11 @@ interface LoaderOptions<S extends SourceConfig = SourceConfig, I18n extends I18n
53
209
  }
54
210
  interface ResolvedLoaderConfig {
55
211
  source: Source;
56
- url: UrlFn;
212
+ url: (slugs: string[], locale?: string) => string;
57
213
  plugins?: LoaderPlugin[];
58
214
  pageTree?: PageTreeOptions;
59
215
  i18n?: I18nConfig | undefined;
60
216
  }
61
- interface Source<Config extends SourceConfig = SourceConfig> {
62
- files: VirtualFile<Config>[];
63
- }
64
217
  interface SharedFileInfo {
65
218
  /**
66
219
  * Virtualized file path (relative to content directory)
@@ -69,9 +222,9 @@ interface SharedFileInfo {
69
222
  */
70
223
  path: string;
71
224
  /**
72
- * Absolute path of the file (can be empty)
225
+ * Absolute path of the file
73
226
  */
74
- absolutePath: string;
227
+ absolutePath?: string;
75
228
  }
76
229
  interface Page<Data = PageData> extends SharedFileInfo {
77
230
  slugs: string[];
@@ -113,7 +266,7 @@ interface LoaderOutput<Config extends LoaderConfig> {
113
266
  pages: Page<Config['source']['pageData']>[];
114
267
  }[];
115
268
  /**
116
- * Get page with slugs
269
+ * Get page with slugs, the slugs can also be URI encoded.
117
270
  *
118
271
  * @param language - If empty, the default language will be used
119
272
  */
@@ -128,166 +281,24 @@ interface LoaderOutput<Config extends LoaderConfig> {
128
281
  */
129
282
  generateParams: <TSlug extends string = 'slug', TLang extends string = 'lang'>(slug?: TSlug, lang?: TLang) => (Record<TSlug, string[]> & Record<TLang, string>)[];
130
283
  }
131
- declare function createGetUrl(baseUrl: string, i18n?: I18nConfig): UrlFn;
132
- declare function loader<Config extends SourceConfig, I18n extends I18nConfig | undefined = undefined>(source: Source<Config>, options: LoaderOptions<NoInfer<Config>, I18n>): LoaderOutput<{
284
+ declare function createGetUrl(baseUrl: string, i18n?: I18nConfig): ResolvedLoaderConfig['url'];
285
+ declare function loader<Config extends SourceConfig, I18n extends I18nConfig | undefined = undefined>(source: Source<Config>, options: LoaderOptions<{
286
+ source: NoInfer<Config>;
287
+ i18n: I18n;
288
+ }>): LoaderOutput<{
133
289
  source: Config;
134
290
  i18n: I18n;
135
291
  }>;
136
- declare function loader<Config extends SourceConfig, I18n extends I18nConfig | undefined = undefined>(options: LoaderOptions<NoInfer<Config>, I18n> & {
292
+ declare function loader<Config extends SourceConfig, I18n extends I18nConfig | undefined = undefined>(options: LoaderOptions<{
293
+ source: NoInfer<Config>;
294
+ i18n: I18n;
295
+ }> & {
137
296
  source: Source<Config>;
138
297
  }): LoaderOutput<{
139
298
  source: Config;
140
299
  i18n: I18n;
141
300
  }>;
142
- type _ConfigUnion_<T extends Record<string, Source>> = {
143
- [K in keyof T]: T[K] extends Source<infer Config> ? {
144
- pageData: Config['pageData'] & {
145
- type: K;
146
- };
147
- metaData: Config['metaData'] & {
148
- type: K;
149
- };
150
- } : never;
151
- }[keyof T];
152
- declare function multiple<T extends Record<string, Source>>(sources: T): Source<_ConfigUnion_<T>>;
153
- /**
154
- * map virtual files in source
155
- */
156
- declare function map<Config extends SourceConfig>(source: Source<Config>): {
157
- page<$Page extends PageData>(fn: (entry: VirtualPage<Config["pageData"]>) => VirtualPage<$Page>): Source<{
158
- pageData: $Page;
159
- metaData: Config["metaData"];
160
- }>;
161
- meta<$Meta extends MetaData>(fn: (entry: VirtualMeta<Config["metaData"]>) => VirtualMeta<$Meta>): Source<{
162
- pageData: Config["pageData"];
163
- metaData: $Meta;
164
- }>;
165
- };
166
-
167
- interface MetaData {
168
- icon?: string | undefined;
169
- title?: string | undefined;
170
- root?: boolean | undefined;
171
- pages?: string[] | undefined;
172
- defaultOpen?: boolean | undefined;
173
- description?: string | undefined;
174
- }
175
- interface PageData {
176
- icon?: string | undefined;
177
- title?: string;
178
- description?: string | undefined;
179
- }
180
- interface BaseVirtualFile {
181
- /**
182
- * Virtualized path (relative to content directory)
183
- *
184
- * @example `docs/page.mdx`
185
- */
186
- path: string;
187
- /**
188
- * Absolute path of the file
189
- */
190
- absolutePath?: string;
191
- }
192
- interface VirtualPage<Data extends PageData> extends BaseVirtualFile {
193
- type: 'page';
194
- /**
195
- * Specified Slugs for page
196
- */
197
- slugs?: string[];
198
- data: Data;
199
- }
200
- interface VirtualMeta<Data extends MetaData> extends BaseVirtualFile {
201
- type: 'meta';
202
- data: Data;
203
- }
204
- type VirtualFile<Config extends SourceConfig = SourceConfig> = VirtualPage<Config['pageData']> | VirtualMeta<Config['metaData']>;
205
301
  type InferPageType<Utils extends LoaderOutput<any>> = Utils extends LoaderOutput<infer Config> ? Page<Config['source']['pageData']> : never;
206
302
  type InferMetaType<Utils extends LoaderOutput<any>> = Utils extends LoaderOutput<infer Config> ? Meta<Config['source']['metaData']> : never;
207
- /**
208
- * @internal
209
- */
210
- type UrlFn = (slugs: string[], locale?: string) => string;
211
-
212
- /**
213
- * In memory file system.
214
- */
215
- declare class FileSystem<File> {
216
- files: Map<string, File>;
217
- folders: Map<string, string[]>;
218
- constructor(inherit?: FileSystem<File>);
219
- read(path: string): File | undefined;
220
- /**
221
- * get the direct children of folder (in virtual file path)
222
- */
223
- readDir(path: string): string[] | undefined;
224
- write(path: string, file: File): void;
225
- /**
226
- * Delete files at specified path.
227
- *
228
- * @param path - the target path.
229
- * @param [recursive=false] - if set to `true`, it will also delete directories.
230
- */
231
- delete(path: string, recursive?: boolean): boolean;
232
- getFiles(): string[];
233
- makeDir(path: string): void;
234
- }
235
-
236
- type ContentStorage<Page extends PageData = PageData, Meta extends MetaData = MetaData> = FileSystem<MetaFile<Meta> | PageFile<Page>>;
237
- interface MetaFile<Data extends MetaData = MetaData> {
238
- path: string;
239
- absolutePath: string;
240
- format: 'meta';
241
- data: Data;
242
- }
243
- interface PageFile<Data extends PageData = PageData> {
244
- path: string;
245
- absolutePath: string;
246
- format: 'page';
247
- slugs: string[];
248
- data: Data;
249
- }
250
-
251
- interface PageTreeBuilderContext<Page extends PageData = PageData, Meta extends MetaData = MetaData> {
252
- rootId: string;
253
- generateNodeId: () => string;
254
- options: PageTreeOptions;
255
- transformers: PageTreeTransformer<Page, Meta>[];
256
- builder: PageTreeBuilder;
257
- storage: ContentStorage<Page, Meta>;
258
- getUrl: UrlFn;
259
- storages?: Record<string, ContentStorage<Page, Meta>>;
260
- locale?: string;
261
- }
262
- interface PageTreeTransformer<Page extends PageData = PageData, Meta extends MetaData = MetaData> {
263
- file?: (this: PageTreeBuilderContext<Page, Meta>, node: Item, filePath?: string) => Item;
264
- folder?: (this: PageTreeBuilderContext<Page, Meta>, node: Folder, folderPath: string, metaPath?: string) => Folder;
265
- separator?: (this: PageTreeBuilderContext<Page, Meta>, node: Separator) => Separator;
266
- root?: (this: PageTreeBuilderContext<Page, Meta>, node: Root) => Root;
267
- }
268
- interface PageTreeOptions<Config extends SourceConfig = SourceConfig> {
269
- id?: string;
270
- /**
271
- * Remove references to the file path of original nodes (`$ref`)
272
- *
273
- * @defaultValue false
274
- */
275
- noRef?: boolean;
276
- /**
277
- * generate fallback page tree
278
- *
279
- * @defaultValue true
280
- */
281
- generateFallback?: boolean;
282
- /**
283
- * Additional page tree transformers to apply
284
- */
285
- transformers?: PageTreeTransformer<Config['pageData'], Config['metaData']>[];
286
- }
287
- interface PageTreeBuilder {
288
- build: (storage: ContentStorage, options?: PageTreeOptions) => Root;
289
- buildI18n: (storages: Record<string, ContentStorage>, options?: PageTreeOptions) => Record<string, Root>;
290
- }
291
- declare function createPageTreeBuilder(getUrl: UrlFn, plugins?: LoaderPlugin[]): PageTreeBuilder;
292
303
 
293
- export { type ContentStorage as C, FileSystem as F, type InferPageType as I, type LoaderPlugin as L, type MetaFile as M, type PageTreeTransformer as P, type ResolvedLoaderConfig as R, type SourceConfig as S, type UrlFn as U, type VirtualPage as V, type _ConfigUnion_ as _, type PageTreeBuilder as a, type PageTreeBuilderContext as b, createPageTreeBuilder as c, type PageTreeOptions as d, type PageFile as e, type LoaderConfig as f, type LoaderOptions as g, type Source as h, type Page as i, type Meta as j, type LoaderOutput as k, createGetUrl as l, loader as m, multiple as n, map as o, type MetaData as p, type PageData as q, type VirtualMeta as r, type VirtualFile as s, type InferMetaType as t, buildPlugins as u };
304
+ export { type ContentStorage as C, FileSystem as F, type InferPageType as I, type LoaderPlugin as L, type MetaData as M, type PageData as P, type ResolvedLoaderConfig as R, type Source as S, type VirtualFile as V, type _ConfigUnion_ as _, type SourceConfig as a, map as b, type LoaderConfig as c, type LoaderOptions as d, type Page as e, type Meta as f, type LoaderOutput as g, createGetUrl as h, type InferMetaType as i, type PageTreeBuilderContext as j, type PageTreeTransformer as k, loader as l, multiple as m, type PageTreeOptions as n, type PageTreeBuilder as o, createPageTreeBuilder as p, type ContentStorageFile as q, buildContentStorage as r, type LoaderPluginOption as s, buildPlugins as t };
@@ -3,7 +3,7 @@ import { StructuredData } from '../mdx-plugins/remark-structure.js';
3
3
  import { SortedResult } from './index.js';
4
4
  export { HighlightedText, ReactSortedResult, createContentHighlighter } from './index.js';
5
5
  import { I18nConfig } from '../i18n/index.js';
6
- import { k as LoaderOutput, f as LoaderConfig, I as InferPageType } from '../builder-W853MYyx.js';
6
+ import { g as LoaderOutput, c as LoaderConfig, I as InferPageType } from '../loader-DgL6G4CA.js';
7
7
  import 'mdast';
8
8
  import 'unified';
9
9
  import 'mdast-util-mdx-jsx';
@@ -1,4 +1,4 @@
1
- export { C as ContentStorage, F as FileSystem, t as InferMetaType, I as InferPageType, f as LoaderConfig, g as LoaderOptions, k as LoaderOutput, L as LoaderPlugin, j as Meta, p as MetaData, M as MetaFile, i as Page, q as PageData, e as PageFile, a as PageTreeBuilder, b as PageTreeBuilderContext, d as PageTreeOptions, P as PageTreeTransformer, R as ResolvedLoaderConfig, h as Source, S as SourceConfig, U as UrlFn, s as VirtualFile, r as VirtualMeta, V as VirtualPage, _ as _ConfigUnion_, u as buildPlugins, l as createGetUrl, c as createPageTreeBuilder, m as loader, o as map, n as multiple } from '../builder-W853MYyx.js';
1
+ export { C as ContentStorage, q as ContentStorageFile, F as FileSystem, i as InferMetaType, I as InferPageType, c as LoaderConfig, d as LoaderOptions, g as LoaderOutput, L as LoaderPlugin, s as LoaderPluginOption, f as Meta, M as MetaData, e as Page, P as PageData, o as PageTreeBuilder, j as PageTreeBuilderContext, n as PageTreeOptions, k as PageTreeTransformer, R as ResolvedLoaderConfig, S as Source, a as SourceConfig, V as VirtualFile, _ as _ConfigUnion_, r as buildContentStorage, t as buildPlugins, h as createGetUrl, p as createPageTreeBuilder, l as loader, b as map, m as multiple } from '../loader-DgL6G4CA.js';
2
2
  import '../definitions-DbCug1P3.js';
3
3
  import 'react';
4
4
  import '../i18n/index.js';
@@ -15,6 +15,204 @@ import {
15
15
  } from "../chunk-PFNP6PEB.js";
16
16
  import "../chunk-U67V476Y.js";
17
17
 
18
+ // src/source/source.ts
19
+ function multiple(sources) {
20
+ const out = { files: [] };
21
+ for (const [type, source] of Object.entries(sources)) {
22
+ for (const file of source.files) {
23
+ out.files.push({
24
+ ...file,
25
+ data: {
26
+ ...file.data,
27
+ type
28
+ }
29
+ });
30
+ }
31
+ }
32
+ return out;
33
+ }
34
+ function map(source) {
35
+ return {
36
+ page(fn) {
37
+ return {
38
+ files: source.files.map(
39
+ (file) => file.type === "page" ? fn(file) : file
40
+ )
41
+ };
42
+ },
43
+ meta(fn) {
44
+ return {
45
+ files: source.files.map(
46
+ (file) => file.type === "meta" ? fn(file) : file
47
+ )
48
+ };
49
+ }
50
+ };
51
+ }
52
+
53
+ // src/source/storage/file-system.ts
54
+ var FileSystem = class {
55
+ constructor(inherit) {
56
+ this.files = /* @__PURE__ */ new Map();
57
+ this.folders = /* @__PURE__ */ new Map();
58
+ if (inherit) {
59
+ for (const [k, v] of inherit.folders) {
60
+ this.folders.set(k, v);
61
+ }
62
+ for (const [k, v] of inherit.files) {
63
+ this.files.set(k, v);
64
+ }
65
+ } else {
66
+ this.folders.set("", []);
67
+ }
68
+ }
69
+ read(path) {
70
+ return this.files.get(path);
71
+ }
72
+ /**
73
+ * get the direct children of folder (in virtual file path)
74
+ */
75
+ readDir(path) {
76
+ return this.folders.get(path);
77
+ }
78
+ write(path, file) {
79
+ if (!this.files.has(path)) {
80
+ const dir = dirname(path);
81
+ this.makeDir(dir);
82
+ this.readDir(dir)?.push(path);
83
+ }
84
+ this.files.set(path, file);
85
+ }
86
+ /**
87
+ * Delete files at specified path.
88
+ *
89
+ * @param path - the target path.
90
+ * @param [recursive=false] - if set to `true`, it will also delete directories.
91
+ */
92
+ delete(path, recursive = false) {
93
+ if (this.files.delete(path)) return true;
94
+ if (recursive) {
95
+ const folder = this.folders.get(path);
96
+ if (!folder) return false;
97
+ this.folders.delete(path);
98
+ for (const child of folder) {
99
+ this.delete(child);
100
+ }
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ getFiles() {
106
+ return Array.from(this.files.keys());
107
+ }
108
+ makeDir(path) {
109
+ const segments = splitPath(path);
110
+ for (let i = 0; i < segments.length; i++) {
111
+ const segment = segments.slice(0, i + 1).join("/");
112
+ if (this.folders.has(segment)) continue;
113
+ this.folders.set(segment, []);
114
+ this.folders.get(dirname(segment)).push(segment);
115
+ }
116
+ }
117
+ };
118
+
119
+ // src/source/storage/content.ts
120
+ function isLocaleValid(locale) {
121
+ return locale.length > 0 && !/\d+/.test(locale);
122
+ }
123
+ var parsers = {
124
+ dir(path) {
125
+ const [locale, ...segs] = path.split("/");
126
+ if (locale && segs.length > 0 && isLocaleValid(locale))
127
+ return [segs.join("/"), locale];
128
+ return [path];
129
+ },
130
+ dot(path) {
131
+ const dir = dirname(path);
132
+ const base = basename(path);
133
+ const parts = base.split(".");
134
+ if (parts.length < 3) return [path];
135
+ const [locale] = parts.splice(parts.length - 2, 1);
136
+ if (!isLocaleValid(locale)) return [path];
137
+ return [joinPath(dir, parts.join(".")), locale];
138
+ },
139
+ none(path) {
140
+ return [path];
141
+ }
142
+ };
143
+ function buildContentStorage(loaderConfig, defaultLanguage) {
144
+ const {
145
+ source,
146
+ plugins = [],
147
+ i18n = {
148
+ defaultLanguage,
149
+ parser: "none",
150
+ languages: [defaultLanguage]
151
+ }
152
+ } = loaderConfig;
153
+ const parser = parsers[i18n.parser ?? "dot"];
154
+ const storages = {};
155
+ const normalized = /* @__PURE__ */ new Map();
156
+ for (const inputFile of source.files) {
157
+ let file;
158
+ if (inputFile.type === "page") {
159
+ file = {
160
+ format: "page",
161
+ path: normalizePath(inputFile.path),
162
+ // will be generated by the slugs plugin if unspecified
163
+ slugs: inputFile.slugs,
164
+ data: inputFile.data,
165
+ absolutePath: inputFile.absolutePath
166
+ };
167
+ } else {
168
+ file = {
169
+ format: "meta",
170
+ path: normalizePath(inputFile.path),
171
+ absolutePath: inputFile.absolutePath,
172
+ data: inputFile.data
173
+ };
174
+ }
175
+ const [pathWithoutLocale, locale = i18n.defaultLanguage] = parser(
176
+ file.path
177
+ );
178
+ const list = normalized.get(locale) ?? [];
179
+ list.push({
180
+ pathWithoutLocale,
181
+ file
182
+ });
183
+ normalized.set(locale, list);
184
+ }
185
+ const fallbackLang = i18n.fallbackLanguage !== null ? i18n.fallbackLanguage ?? i18n.defaultLanguage : null;
186
+ function scan(lang) {
187
+ if (storages[lang]) return;
188
+ let storage;
189
+ if (fallbackLang && fallbackLang !== lang) {
190
+ scan(fallbackLang);
191
+ storage = new FileSystem(storages[fallbackLang]);
192
+ } else {
193
+ storage = new FileSystem();
194
+ }
195
+ for (const { pathWithoutLocale, file } of normalized.get(lang) ?? []) {
196
+ storage.write(pathWithoutLocale, file);
197
+ }
198
+ const context = {
199
+ storage
200
+ };
201
+ for (const plugin of plugins) {
202
+ plugin.transformStorage?.(context);
203
+ }
204
+ storages[lang] = storage;
205
+ }
206
+ for (const lang of i18n.languages) scan(lang);
207
+ return storages;
208
+ }
209
+ function normalizePath(path) {
210
+ const segments = splitPath(slash(path));
211
+ if (segments[0] === "." || segments[0] === "..")
212
+ throw new Error("It must not start with './' or '../'");
213
+ return segments.join("/");
214
+ }
215
+
18
216
  // src/source/page-tree/transformer-fallback.ts
19
217
  function transformerFallback() {
20
218
  const addedFiles = /* @__PURE__ */ new Set();
@@ -54,20 +252,21 @@ var rest = "...";
54
252
  var restReversed = "z...a";
55
253
  var extractPrefix = "...";
56
254
  var excludePrefix = "!";
57
- function createPageTreeBuilder(getUrl, plugins) {
255
+ function createPageTreeBuilder(loaderConfig) {
256
+ const { plugins = [], url, pageTree: defaultOptions = {} } = loaderConfig;
58
257
  return {
59
- build(storage, options) {
258
+ build(storage, options = defaultOptions) {
60
259
  const key = "";
61
260
  return this.buildI18n({ [key]: storage }, options)[key];
62
261
  },
63
- buildI18n(storages, options = {}) {
262
+ buildI18n(storages, options = defaultOptions) {
64
263
  let nextId = 0;
65
264
  const out = {};
66
265
  const transformers = [];
67
266
  if (options.transformers) {
68
267
  transformers.push(...options.transformers);
69
268
  }
70
- for (const plugin of plugins ?? []) {
269
+ for (const plugin of plugins) {
71
270
  if (plugin.transformPageTree)
72
271
  transformers.push(plugin.transformPageTree);
73
272
  }
@@ -82,7 +281,7 @@ function createPageTreeBuilder(getUrl, plugins) {
82
281
  transformers,
83
282
  builder: this,
84
283
  options,
85
- getUrl,
284
+ getUrl: url,
86
285
  locale,
87
286
  storage,
88
287
  storages,
@@ -300,152 +499,23 @@ function pathToName(name) {
300
499
  return result.join("");
301
500
  }
302
501
 
303
- // src/source/storage/file-system.ts
304
- var FileSystem = class {
305
- constructor(inherit) {
306
- this.files = /* @__PURE__ */ new Map();
307
- this.folders = /* @__PURE__ */ new Map();
308
- if (inherit) {
309
- for (const [k, v] of inherit.folders) {
310
- this.folders.set(k, v);
311
- }
312
- for (const [k, v] of inherit.files) {
313
- this.files.set(k, v);
314
- }
315
- } else {
316
- this.folders.set("", []);
317
- }
318
- }
319
- read(path) {
320
- return this.files.get(path);
321
- }
322
- /**
323
- * get the direct children of folder (in virtual file path)
324
- */
325
- readDir(path) {
326
- return this.folders.get(path);
327
- }
328
- write(path, file) {
329
- if (!this.files.has(path)) {
330
- const dir = dirname(path);
331
- this.makeDir(dir);
332
- this.readDir(dir)?.push(path);
333
- }
334
- this.files.set(path, file);
335
- }
336
- /**
337
- * Delete files at specified path.
338
- *
339
- * @param path - the target path.
340
- * @param [recursive=false] - if set to `true`, it will also delete directories.
341
- */
342
- delete(path, recursive = false) {
343
- if (this.files.delete(path)) return true;
344
- if (recursive) {
345
- const folder = this.folders.get(path);
346
- if (!folder) return false;
347
- this.folders.delete(path);
348
- for (const child of folder) {
349
- this.delete(child);
350
- }
351
- return true;
352
- }
353
- return false;
354
- }
355
- getFiles() {
356
- return Array.from(this.files.keys());
357
- }
358
- makeDir(path) {
359
- const segments = splitPath(path);
360
- for (let i = 0; i < segments.length; i++) {
361
- const segment = segments.slice(0, i + 1).join("/");
362
- if (this.folders.has(segment)) continue;
363
- this.folders.set(segment, []);
364
- this.folders.get(dirname(segment)).push(segment);
365
- }
366
- }
367
- };
368
-
369
- // src/source/storage/content.ts
370
- function isLocaleValid(locale) {
371
- return locale.length > 0 && !/\d+/.test(locale);
372
- }
373
- var parsers = {
374
- dir(path) {
375
- const [locale, ...segs] = path.split("/");
376
- if (locale && segs.length > 0 && isLocaleValid(locale))
377
- return [segs.join("/"), locale];
378
- return [path];
379
- },
380
- dot(path) {
381
- const dir = dirname(path);
382
- const base = basename(path);
383
- const parts = base.split(".");
384
- if (parts.length < 3) return [path];
385
- const [locale] = parts.splice(parts.length - 2, 1);
386
- if (!isLocaleValid(locale)) return [path];
387
- return [joinPath(dir, parts.join(".")), locale];
388
- },
389
- none(path) {
390
- return [path];
391
- }
392
- };
393
- function buildContentStorage(files, buildFile, plugins, i18n) {
394
- const parser = parsers[i18n.parser ?? "dot"];
395
- const storages = {};
396
- const normalized = files.map(
397
- (file) => buildFile({
398
- ...file,
399
- path: normalizePath(file.path)
400
- })
401
- );
402
- const fallbackLang = i18n.fallbackLanguage !== null ? i18n.fallbackLanguage ?? i18n.defaultLanguage : null;
403
- function scan(lang) {
404
- if (storages[lang]) return;
405
- let storage;
406
- if (fallbackLang && fallbackLang !== lang) {
407
- scan(fallbackLang);
408
- storage = new FileSystem(storages[fallbackLang]);
409
- } else {
410
- storage = new FileSystem();
411
- }
412
- for (const item of normalized) {
413
- const [path, locale = i18n.defaultLanguage] = parser(item.path);
414
- if (locale === lang) storage.write(path, item);
415
- }
416
- const context = {
417
- storage
418
- };
419
- for (const plugin of plugins) {
420
- plugin.transformStorage?.(context);
421
- }
422
- storages[lang] = storage;
423
- }
424
- for (const lang of i18n.languages) scan(lang);
425
- return storages;
426
- }
427
- function normalizePath(path) {
428
- const segments = splitPath(slash(path));
429
- if (segments[0] === "." || segments[0] === "..")
430
- throw new Error("It must not start with './' or '../'");
431
- return segments.join("/");
432
- }
433
-
434
502
  // src/source/plugins/index.ts
435
503
  var priorityMap = {
436
504
  pre: 1,
437
505
  default: 0,
438
506
  post: -1
439
507
  };
440
- function buildPlugins(plugins) {
508
+ function buildPlugins(plugins, sort = true) {
441
509
  const flatten = [];
442
510
  for (const plugin of plugins) {
443
- if (Array.isArray(plugin)) flatten.push(...plugin);
511
+ if (Array.isArray(plugin)) flatten.push(...buildPlugins(plugin, false));
444
512
  else if (plugin) flatten.push(plugin);
445
513
  }
446
- return flatten.sort(
447
- (a, b) => priorityMap[b.enforce ?? "default"] - priorityMap[a.enforce ?? "default"]
448
- );
514
+ if (sort)
515
+ return flatten.sort(
516
+ (a, b) => priorityMap[b.enforce ?? "default"] - priorityMap[a.enforce ?? "default"]
517
+ );
518
+ return flatten;
449
519
  }
450
520
 
451
521
  // src/source/plugins/slugs.ts
@@ -497,7 +567,7 @@ function getSlugs(file) {
497
567
  }
498
568
 
499
569
  // src/source/loader.ts
500
- function indexPages(storages, getUrl) {
570
+ function indexPages(storages, { url }) {
501
571
  const result = {
502
572
  // (locale.slugs -> page)
503
573
  pages: /* @__PURE__ */ new Map(),
@@ -511,10 +581,21 @@ function indexPages(storages, getUrl) {
511
581
  const item = storage.read(filePath);
512
582
  const path = `${lang}.${filePath}`;
513
583
  if (item.format === "meta") {
514
- result.pathToMeta.set(path, fileToMeta(item));
584
+ result.pathToMeta.set(path, {
585
+ path: item.path,
586
+ absolutePath: item.absolutePath,
587
+ data: item.data
588
+ });
515
589
  continue;
516
590
  }
517
- const page = fileToPage(item, getUrl, lang);
591
+ const page = {
592
+ absolutePath: item.absolutePath,
593
+ path: item.path,
594
+ url: url(item.slugs, lang),
595
+ slugs: item.slugs,
596
+ data: item.data,
597
+ locale: lang
598
+ };
518
599
  result.pathToPage.set(path, page);
519
600
  result.pages.set(`${lang}.${page.slugs.join("/")}`, page);
520
601
  }
@@ -541,15 +622,16 @@ function loader(...args) {
541
622
  return createOutput(resolved);
542
623
  }
543
624
  function resolveConfig(source, { slugs, icon, plugins = [], baseUrl, url, ...base }) {
544
- const getUrl = url ? (...args) => normalizeUrl(url(...args)) : createGetUrl(baseUrl, base.i18n);
545
625
  let config = {
546
626
  ...base,
547
- url: getUrl,
627
+ url: url ? (...args) => normalizeUrl(url(...args)) : createGetUrl(baseUrl, base.i18n),
548
628
  source,
549
629
  plugins: buildPlugins([
550
630
  slugsPlugin(slugs),
551
631
  icon && iconPlugin(icon),
552
- ...plugins
632
+ ...typeof plugins === "function" ? plugins({
633
+ typedPlugin: (plugin) => plugin
634
+ }) : plugins
553
635
  ])
554
636
  };
555
637
  for (const plugin of config.plugins ?? []) {
@@ -558,47 +640,17 @@ function resolveConfig(source, { slugs, icon, plugins = [], baseUrl, url, ...bas
558
640
  }
559
641
  return config;
560
642
  }
561
- function createOutput({
562
- source: { files },
563
- url: getUrl,
564
- i18n,
565
- plugins = [],
566
- pageTree: pageTreeConfig
567
- }) {
643
+ function createOutput(loaderConfig) {
644
+ const { i18n } = loaderConfig;
568
645
  const defaultLanguage = i18n?.defaultLanguage ?? "";
569
- const storages = buildContentStorage(
570
- files,
571
- (file) => {
572
- if (file.type === "page") {
573
- return {
574
- format: "page",
575
- path: file.path,
576
- slugs: file.slugs,
577
- data: file.data,
578
- absolutePath: file.absolutePath ?? ""
579
- };
580
- }
581
- return {
582
- format: "meta",
583
- path: file.path,
584
- absolutePath: file.absolutePath ?? "",
585
- data: file.data
586
- };
587
- },
588
- plugins,
589
- i18n ?? {
590
- defaultLanguage,
591
- parser: "none",
592
- languages: [defaultLanguage]
593
- }
594
- );
595
- const walker = indexPages(storages, getUrl);
596
- const builder = createPageTreeBuilder(getUrl, plugins);
646
+ const storages = buildContentStorage(loaderConfig, defaultLanguage);
647
+ const walker = indexPages(storages, loaderConfig);
648
+ const builder = createPageTreeBuilder(loaderConfig);
597
649
  let pageTree;
598
650
  return {
599
651
  _i18n: i18n,
600
652
  get pageTree() {
601
- pageTree ??= builder.buildI18n(storages, pageTreeConfig);
653
+ pageTree ??= builder.buildI18n(storages);
602
654
  return i18n ? pageTree : pageTree[defaultLanguage];
603
655
  },
604
656
  set pageTree(v) {
@@ -645,8 +697,13 @@ function createOutput({
645
697
  }
646
698
  return list;
647
699
  },
700
+ // the slugs plugin generates encoded slugs by default.
701
+ // we can assume page slugs are always URI encoded.
648
702
  getPage(slugs = [], language = defaultLanguage) {
649
- return walker.pages.get(`${language}.${slugs.join("/")}`);
703
+ let page = walker.pages.get(`${language}.${slugs.join("/")}`);
704
+ if (page) return page;
705
+ page = walker.pages.get(`${language}.${slugs.map(decodeURI).join("/")}`);
706
+ if (page) return page;
650
707
  },
651
708
  getNodeMeta(node, language = defaultLanguage) {
652
709
  const ref = node.$ref?.metaFile;
@@ -680,61 +737,10 @@ function createOutput({
680
737
  }
681
738
  };
682
739
  }
683
- function fileToMeta(file) {
684
- return {
685
- path: file.path,
686
- absolutePath: file.absolutePath,
687
- data: file.data
688
- };
689
- }
690
- function fileToPage(file, getUrl, locale) {
691
- return {
692
- absolutePath: file.absolutePath,
693
- path: file.path,
694
- url: getUrl(file.slugs, locale),
695
- slugs: file.slugs,
696
- data: file.data,
697
- locale
698
- };
699
- }
700
- function multiple(sources) {
701
- const out = { files: [] };
702
- for (const [type, source] of Object.entries(sources)) {
703
- for (const file of source.files) {
704
- out.files.push({
705
- ...file,
706
- data: {
707
- ...file.data,
708
- type
709
- }
710
- });
711
- }
712
- }
713
- return out;
714
- }
715
- function map(source) {
716
- return {
717
- page(fn) {
718
- return {
719
- files: source.files.map(
720
- (file) => file.type === "page" ? fn(file) : file
721
- )
722
- };
723
- },
724
- meta(fn) {
725
- return {
726
- files: source.files.map(
727
- (file) => file.type === "meta" ? fn(file) : file
728
- )
729
- };
730
- }
731
- };
732
- }
733
740
  export {
734
741
  FileSystem,
735
742
  path_exports as PathUtils,
736
743
  createGetUrl,
737
- createPageTreeBuilder,
738
744
  getSlugs,
739
745
  loader,
740
746
  map,
@@ -1,4 +1,4 @@
1
- import { L as LoaderPlugin } from '../../builder-W853MYyx.js';
1
+ import { L as LoaderPlugin } from '../../loader-DgL6G4CA.js';
2
2
  import { icons } from 'lucide-react';
3
3
  import '../../definitions-DbCug1P3.js';
4
4
  import 'react';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "16.0.14",
4
- "description": "The library for building a documentation website in any React.js framework",
3
+ "version": "16.1.0",
4
+ "description": "The React.js library for building a documentation website",
5
5
  "keywords": [
6
6
  "Fumadocs",
7
7
  "Docs"