fumadocs-core 16.0.9 → 16.0.11

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,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { R as Root, N as Node } from './definitions-DQnHJeWn.js';
2
+ import { R as Root, N as Node } from './definitions-DbCug1P3.js';
3
3
 
4
4
  interface BreadcrumbItem {
5
5
  name: ReactNode;
@@ -1,4 +1,4 @@
1
- import { R as Root, I as Item, F as Folder, S as Separator } from './definitions-DQnHJeWn.js';
1
+ import { R as Root, I as Item, F as Folder, S as Separator } from './definitions-DbCug1P3.js';
2
2
  import { I18nConfig } from './i18n/index.js';
3
3
  import { ReactNode } from 'react';
4
4
 
@@ -249,10 +249,8 @@ interface PageFile<Data extends PageData = PageData> {
249
249
  }
250
250
 
251
251
  interface PageTreeBuilderContext<Page extends PageData = PageData, Meta extends MetaData = MetaData> {
252
- /**
253
- * @internal resolve paths without extensions
254
- */
255
- resolveName: (name: string, format: 'meta' | 'page') => string;
252
+ rootId: string;
253
+ generateNodeId: () => string;
256
254
  options: PageTreeOptions;
257
255
  transformers: PageTreeTransformer<Page, Meta>[];
258
256
  builder: PageTreeBuilder;
@@ -260,7 +258,6 @@ interface PageTreeBuilderContext<Page extends PageData = PageData, Meta extends
260
258
  getUrl: UrlFn;
261
259
  storages?: Record<string, ContentStorage<Page, Meta>>;
262
260
  locale?: string;
263
- visitedPaths: Set<string>;
264
261
  }
265
262
  interface PageTreeTransformer<Page extends PageData = PageData, Meta extends MetaData = MetaData> {
266
263
  file?: (this: PageTreeBuilderContext<Page, Meta>, node: Item, filePath?: string) => Item;
@@ -0,0 +1,74 @@
1
+ // src/mdx-plugins/remark-directive-admonition.ts
2
+ import { visit } from "unist-util-visit";
3
+ function remarkDirectiveAdmonition({
4
+ tags: {
5
+ CalloutContainer = "CalloutContainer",
6
+ CalloutTitle = "CalloutTitle",
7
+ CalloutDescription = "CalloutDescription"
8
+ } = {},
9
+ types = {
10
+ note: "info",
11
+ tip: "info",
12
+ info: "info",
13
+ warn: "warning",
14
+ warning: "warning",
15
+ danger: "error",
16
+ success: "success"
17
+ }
18
+ } = {}) {
19
+ return (tree) => {
20
+ visit(tree, "containerDirective", (node) => {
21
+ if (!(node.name in types)) return;
22
+ const attributes = [
23
+ {
24
+ type: "mdxJsxAttribute",
25
+ name: "type",
26
+ value: types[node.name]
27
+ }
28
+ ];
29
+ for (const [k, v] of Object.entries(node.attributes ?? {})) {
30
+ attributes.push({
31
+ type: "mdxJsxAttribute",
32
+ name: k,
33
+ value: v
34
+ });
35
+ }
36
+ const titleNodes = [];
37
+ const descriptionNodes = [];
38
+ for (const item of node.children) {
39
+ if (item.type === "paragraph" && item.data?.directiveLabel) {
40
+ titleNodes.push(...item.children);
41
+ } else {
42
+ descriptionNodes.push(item);
43
+ }
44
+ }
45
+ const children = [];
46
+ if (titleNodes.length > 0) {
47
+ children.push({
48
+ type: "mdxJsxFlowElement",
49
+ name: CalloutTitle,
50
+ attributes: [],
51
+ children: titleNodes
52
+ });
53
+ }
54
+ if (descriptionNodes.length > 0) {
55
+ children.push({
56
+ type: "mdxJsxFlowElement",
57
+ name: CalloutDescription,
58
+ attributes: [],
59
+ children: descriptionNodes
60
+ });
61
+ }
62
+ Object.assign(node, {
63
+ type: "mdxJsxFlowElement",
64
+ attributes,
65
+ name: CalloutContainer,
66
+ children
67
+ });
68
+ });
69
+ };
70
+ }
71
+
72
+ export {
73
+ remarkDirectiveAdmonition
74
+ };
@@ -1,12 +1,12 @@
1
1
  // src/framework/index.tsx
2
- import React from "react";
2
+ import { createContext, use, useMemo } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  var notImplemented = () => {
5
5
  throw new Error(
6
6
  "You need to wrap your application inside `FrameworkProvider`."
7
7
  );
8
8
  };
9
- var FrameworkContext = createContext("FrameworkContext", {
9
+ var FrameworkContext = createContext({
10
10
  useParams: notImplemented,
11
11
  useRouter: notImplemented,
12
12
  usePathname: notImplemented
@@ -19,7 +19,7 @@ function FrameworkProvider({
19
19
  Image: Image2,
20
20
  children
21
21
  }) {
22
- const framework = React.useMemo(
22
+ const framework = useMemo(
23
23
  () => ({
24
24
  usePathname: usePathname2,
25
25
  useRouter: useRouter2,
@@ -29,19 +29,19 @@ function FrameworkProvider({
29
29
  }),
30
30
  [Link2, usePathname2, useRouter2, useParams2, Image2]
31
31
  );
32
- return /* @__PURE__ */ jsx(FrameworkContext.Provider, { value: framework, children });
32
+ return /* @__PURE__ */ jsx(FrameworkContext, { value: framework, children });
33
33
  }
34
34
  function usePathname() {
35
- return FrameworkContext.use().usePathname();
35
+ return use(FrameworkContext).usePathname();
36
36
  }
37
37
  function useRouter() {
38
- return FrameworkContext.use().useRouter();
38
+ return use(FrameworkContext).useRouter();
39
39
  }
40
40
  function useParams() {
41
- return FrameworkContext.use().useParams();
41
+ return use(FrameworkContext).useParams();
42
42
  }
43
43
  function Image(props) {
44
- const { Image: Image2 } = FrameworkContext.use();
44
+ const { Image: Image2 } = use(FrameworkContext);
45
45
  if (!Image2) {
46
46
  const { src, alt, priority, ...rest } = props;
47
47
  return /* @__PURE__ */ jsx(
@@ -57,29 +57,13 @@ function Image(props) {
57
57
  return /* @__PURE__ */ jsx(Image2, { ...props });
58
58
  }
59
59
  function Link(props) {
60
- const { Link: Link2 } = FrameworkContext.use();
60
+ const { Link: Link2 } = use(FrameworkContext);
61
61
  if (!Link2) {
62
62
  const { href, prefetch: _, ...rest } = props;
63
63
  return /* @__PURE__ */ jsx("a", { href, ...rest });
64
64
  }
65
65
  return /* @__PURE__ */ jsx(Link2, { ...props });
66
66
  }
67
- function createContext(name, v) {
68
- const Context = React.createContext(v);
69
- return {
70
- Provider: (props) => {
71
- return /* @__PURE__ */ jsx(Context.Provider, { value: props.value, children: props.children });
72
- },
73
- use: (errorMessage) => {
74
- const value = React.useContext(Context);
75
- if (!value)
76
- throw new Error(
77
- errorMessage ?? `Provider of ${name} is required but missing.`
78
- );
79
- return value;
80
- }
81
- };
82
- }
83
67
 
84
68
  export {
85
69
  FrameworkProvider,
@@ -87,6 +71,5 @@ export {
87
71
  useRouter,
88
72
  useParams,
89
73
  Image,
90
- Link,
91
- createContext
74
+ Link
92
75
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Link
3
- } from "./chunk-BBP7MIO4.js";
3
+ } from "./chunk-K4WNLOVQ.js";
4
4
 
5
5
  // src/link.tsx
6
6
  import { forwardRef } from "react";
@@ -1,8 +1,6 @@
1
1
  // src/mdx-plugins/remark-image.ts
2
2
  import * as path from "path";
3
3
  import { visit } from "unist-util-visit";
4
- import { imageSize } from "image-size";
5
- import { imageSizeFromFile } from "image-size/fromFile";
6
4
  import { fileURLToPath } from "url";
7
5
  var VALID_BLUR_EXT = [".jpeg", ".png", ".webp", ".avif", ".jpg"];
8
6
  var EXTERNAL_URL_REGEX = /^https?:\/\//;
@@ -195,7 +193,10 @@ function parseSrc(src, publicDir, dir) {
195
193
  };
196
194
  }
197
195
  async function getImageSize(src, onExternal) {
198
- if (src.type === "file") return imageSizeFromFile(src.file);
196
+ if (src.type === "file") {
197
+ const { imageSizeFromFile } = await import("image-size/fromFile");
198
+ return imageSizeFromFile(src.file);
199
+ }
199
200
  if (onExternal === false) return;
200
201
  const { timeout } = typeof onExternal === "object" ? onExternal : {};
201
202
  const res = await fetch(src.url, {
@@ -206,6 +207,7 @@ async function getImageSize(src, onExternal) {
206
207
  `[Remark Image] Failed to fetch ${src.url} (${res.status}): ${await res.text()}`
207
208
  );
208
209
  }
210
+ const { imageSize } = await import("image-size");
209
211
  return imageSize(new Uint8Array(await res.arrayBuffer()));
210
212
  }
211
213
 
@@ -1,7 +1,12 @@
1
1
  import { ReactNode } from 'react';
2
2
 
3
- interface Root {
3
+ interface INode {
4
+ /**
5
+ * ID for the node, unique in all page trees (even across different locales)
6
+ */
4
7
  $id?: string;
8
+ }
9
+ interface Root extends INode {
5
10
  name: ReactNode;
6
11
  children: Node[];
7
12
  /**
@@ -10,8 +15,7 @@ interface Root {
10
15
  fallback?: Root;
11
16
  }
12
17
  type Node = Item | Separator | Folder;
13
- interface Item {
14
- $id?: string;
18
+ interface Item extends INode {
15
19
  /**
16
20
  * @internal
17
21
  */
@@ -30,14 +34,12 @@ interface Item {
30
34
  description?: ReactNode;
31
35
  icon?: ReactNode;
32
36
  }
33
- interface Separator {
34
- $id?: string;
37
+ interface Separator extends INode {
35
38
  type: 'separator';
36
39
  name?: ReactNode;
37
40
  icon?: ReactNode;
38
41
  }
39
- interface Folder {
40
- $id?: string;
42
+ interface Folder extends INode {
41
43
  /**
42
44
  * @internal
43
45
  */
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  Link
4
- } from "./chunk-N2ZQXKIX.js";
4
+ } from "./chunk-SH7BNTG7.js";
5
5
  import {
6
6
  useParams
7
- } from "./chunk-BBP7MIO4.js";
7
+ } from "./chunk-K4WNLOVQ.js";
8
8
  import "./chunk-U67V476Y.js";
9
9
 
10
10
  // src/dynamic-link.tsx
@@ -37,12 +37,5 @@ declare function useRouter(): Router;
37
37
  declare function useParams(): Record<string, string | string[]>;
38
38
  declare function Image(props: ImageProps): react_jsx_runtime.JSX.Element;
39
39
  declare function Link(props: LinkProps): react_jsx_runtime.JSX.Element;
40
- declare function createContext<T>(name: string, v?: T): {
41
- Provider: (props: {
42
- value: T;
43
- children: ReactNode;
44
- }) => react_jsx_runtime.JSX.Element;
45
- use: (errorMessage?: string) => Exclude<T, undefined | null>;
46
- };
47
40
 
48
- export { type Framework, FrameworkProvider, Image, type ImageProps, Link, type Router, createContext, useParams, usePathname, useRouter };
41
+ export { type Framework, FrameworkProvider, Image, type ImageProps, Link, type Router, useParams, usePathname, useRouter };
@@ -3,17 +3,15 @@ import {
3
3
  FrameworkProvider,
4
4
  Image,
5
5
  Link,
6
- createContext,
7
6
  useParams,
8
7
  usePathname,
9
8
  useRouter
10
- } from "../chunk-BBP7MIO4.js";
9
+ } from "../chunk-K4WNLOVQ.js";
11
10
  import "../chunk-U67V476Y.js";
12
11
  export {
13
12
  FrameworkProvider,
14
13
  Image,
15
14
  Link,
16
- createContext,
17
15
  useParams,
18
16
  usePathname,
19
17
  useRouter
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  FrameworkProvider
4
- } from "../chunk-BBP7MIO4.js";
4
+ } from "../chunk-K4WNLOVQ.js";
5
5
  import "../chunk-U67V476Y.js";
6
6
 
7
7
  // src/framework/next.tsx
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FrameworkProvider
3
- } from "../chunk-BBP7MIO4.js";
3
+ } from "../chunk-K4WNLOVQ.js";
4
4
  import "../chunk-U67V476Y.js";
5
5
 
6
6
  // src/framework/react-router.tsx
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FrameworkProvider
3
- } from "../chunk-BBP7MIO4.js";
3
+ } from "../chunk-K4WNLOVQ.js";
4
4
  import "../chunk-U67V476Y.js";
5
5
 
6
6
  // src/framework/tanstack.tsx
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  FrameworkProvider
4
- } from "../chunk-BBP7MIO4.js";
4
+ } from "../chunk-K4WNLOVQ.js";
5
5
  import "../chunk-U67V476Y.js";
6
6
 
7
7
  // src/framework/waku.tsx
package/dist/link.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import {
3
3
  Link
4
- } from "./chunk-N2ZQXKIX.js";
5
- import "./chunk-BBP7MIO4.js";
4
+ } from "./chunk-SH7BNTG7.js";
5
+ import "./chunk-K4WNLOVQ.js";
6
6
  import "./chunk-U67V476Y.js";
7
7
  export {
8
8
  Link as default
@@ -4,6 +4,7 @@ export { RemarkImageOptions, remarkImage } from './remark-image.js';
4
4
  export { StructureOptions, StructuredData, remarkStructure, structure } from './remark-structure.js';
5
5
  export { RemarkHeadingOptions, remarkHeading } from './remark-heading.js';
6
6
  export { RemarkAdmonitionOptions, remarkAdmonition } from './remark-admonition.js';
7
+ export { RemarkDirectiveAdmonitionOptions, remarkDirectiveAdmonition } from './remark-directive-admonition.js';
7
8
  export { RehypeTocOptions, rehypeToc } from './rehype-toc.js';
8
9
  export { RemarkCodeTabOptions, remarkCodeTab } from './remark-code-tab.js';
9
10
  export { RemarkStepsOptions, remarkSteps } from './remark-steps.js';
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-ONG4RVCR.js";
4
4
  import {
5
5
  remarkImage
6
- } from "../chunk-VW3XKOZZ.js";
6
+ } from "../chunk-YDNO7UZ6.js";
7
7
  import {
8
8
  remarkMdxFiles
9
9
  } from "../chunk-ADBHPKXG.js";
@@ -39,6 +39,9 @@ import {
39
39
  generateCodeBlockTabs,
40
40
  parseCodeBlockAttributes
41
41
  } from "../chunk-TWIDBWFG.js";
42
+ import {
43
+ remarkDirectiveAdmonition
44
+ } from "../chunk-APKPSBSB.js";
42
45
  import "../chunk-XN2LKXFZ.js";
43
46
  import {
44
47
  remarkHeading
@@ -53,6 +56,7 @@ export {
53
56
  rehypeToc,
54
57
  remarkAdmonition,
55
58
  remarkCodeTab,
59
+ remarkDirectiveAdmonition,
56
60
  default2 as remarkGfm,
57
61
  remarkHeading,
58
62
  remarkImage,
@@ -12,6 +12,8 @@ interface RemarkAdmonitionOptions {
12
12
  * Remark Plugin to support Admonition syntax
13
13
  *
14
14
  * Useful when Migrating from Docusaurus
15
+ *
16
+ * @deprecated Use `remarkDirectiveAdmonition` with `remark-directive` configured instead.
15
17
  */
16
18
  declare function remarkAdmonition(options?: RemarkAdmonitionOptions): Transformer<Root, Root>;
17
19
 
@@ -0,0 +1,27 @@
1
+ import { Root } from 'mdast';
2
+ import { Transformer } from 'unified';
3
+
4
+ interface RemarkDirectiveAdmonitionOptions {
5
+ /**
6
+ * the tag names of Callout component.
7
+ */
8
+ tags?: {
9
+ CalloutContainer?: string;
10
+ CalloutTitle?: string;
11
+ CalloutDescription?: string;
12
+ };
13
+ /**
14
+ * All supported admonition types and their linked Callout type.
15
+ *
16
+ * When specified, all defaults will be cleared.
17
+ */
18
+ types?: Record<string, string>;
19
+ }
20
+ /**
21
+ * Remark Plugin to support Admonition syntax in Docusaurus, useful for migrating from Docusaurus.
22
+ *
23
+ * Requires [`remark-directive`](https://github.com/remarkjs/remark-directive) to be configured.
24
+ */
25
+ declare function remarkDirectiveAdmonition({ tags: { CalloutContainer, CalloutTitle, CalloutDescription, }, types, }?: RemarkDirectiveAdmonitionOptions): Transformer<Root, Root>;
26
+
27
+ export { type RemarkDirectiveAdmonitionOptions, remarkDirectiveAdmonition };
@@ -0,0 +1,7 @@
1
+ import {
2
+ remarkDirectiveAdmonition
3
+ } from "../chunk-APKPSBSB.js";
4
+ import "../chunk-U67V476Y.js";
5
+ export {
6
+ remarkDirectiveAdmonition
7
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  remarkImage
3
- } from "../chunk-VW3XKOZZ.js";
3
+ } from "../chunk-YDNO7UZ6.js";
4
4
  import "../chunk-U67V476Y.js";
5
5
  export {
6
6
  remarkImage
@@ -1,5 +1,5 @@
1
- import { N as Node, I as Item, R as Root, F as Folder } from '../definitions-DQnHJeWn.js';
2
- export { S as Separator } from '../definitions-DQnHJeWn.js';
1
+ import { N as Node, I as Item, R as Root, F as Folder } from '../definitions-DbCug1P3.js';
2
+ export { S as Separator } from '../definitions-DbCug1P3.js';
3
3
  import 'react';
4
4
 
5
5
  /**
@@ -3,12 +3,12 @@ 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-BynMF2Pa.js';
6
+ import { k as LoaderOutput, f as LoaderConfig, I as InferPageType } from '../builder-DEvYXjy8.js';
7
7
  import 'mdast';
8
8
  import 'unified';
9
9
  import 'mdast-util-mdx-jsx';
10
10
  import 'react';
11
- import '../definitions-DQnHJeWn.js';
11
+ import '../definitions-DbCug1P3.js';
12
12
 
13
13
  type SimpleDocument = TypedDocument<Orama<typeof simpleSchema>>;
14
14
  declare const simpleSchema: {
@@ -1,5 +1,5 @@
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-BynMF2Pa.js';
2
- import '../definitions-DQnHJeWn.js';
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-DEvYXjy8.js';
2
+ import '../definitions-DbCug1P3.js';
3
3
  import 'react';
4
4
  import '../i18n/index.js';
5
5
 
@@ -54,217 +54,31 @@ var rest = "...";
54
54
  var restReversed = "z...a";
55
55
  var extractPrefix = "...";
56
56
  var excludePrefix = "!";
57
- function buildAll(paths, ctx, reversed = false) {
58
- const items = [];
59
- const folders = [];
60
- const sortedPaths = paths.sort(
61
- (a, b) => a.localeCompare(b) * (reversed ? -1 : 1)
62
- );
63
- for (const path of sortedPaths) {
64
- ctx.visitedPaths.add(path);
65
- const fileNode = buildFileNode(path, ctx);
66
- if (fileNode) {
67
- if (basename(path, extname(path)) === "index") items.unshift(fileNode);
68
- else items.push(fileNode);
69
- continue;
70
- }
71
- const dirNode = buildFolderNode(path, false, ctx);
72
- if (dirNode) folders.push(dirNode);
73
- }
74
- return [...items, ...folders];
75
- }
76
- function resolveFolderItem(folderPath, item, ctx, idx) {
77
- if (item === rest || item === restReversed) return item;
78
- const { resolveName } = ctx;
79
- let match = separator.exec(item);
80
- if (match?.groups) {
81
- let node = {
82
- $id: `${folderPath}#${idx}`,
83
- type: "separator",
84
- icon: match.groups.icon,
85
- name: match.groups.name
86
- };
87
- for (const transformer of ctx.transformers) {
88
- if (!transformer.separator) continue;
89
- node = transformer.separator.call(ctx, node);
90
- }
91
- return [node];
92
- }
93
- match = link.exec(item);
94
- if (match?.groups) {
95
- const { icon, url, name, external } = match.groups;
96
- let node = {
97
- type: "page",
98
- icon,
99
- name,
100
- url,
101
- external: external ? true : void 0
102
- };
103
- for (const transformer of ctx.transformers) {
104
- if (!transformer.file) continue;
105
- node = transformer.file.call(ctx, node);
106
- }
107
- return [node];
108
- }
109
- const isExcept = item.startsWith(excludePrefix);
110
- const isExtract = !isExcept && item.startsWith(extractPrefix);
111
- let filename = item;
112
- if (isExcept) {
113
- filename = item.slice(excludePrefix.length);
114
- } else if (isExtract) {
115
- filename = item.slice(extractPrefix.length);
116
- }
117
- const path = resolveName(joinPath(folderPath, filename), "page");
118
- ctx.visitedPaths.add(path);
119
- if (isExcept) return [];
120
- const dirNode = buildFolderNode(path, false, ctx);
121
- if (dirNode) {
122
- return isExtract ? dirNode.children : [dirNode];
123
- }
124
- const fileNode = buildFileNode(path, ctx);
125
- return fileNode ? [fileNode] : [];
126
- }
127
- function buildFolderNode(folderPath, isGlobalRoot, ctx) {
128
- const { storage, options, resolveName, transformers } = ctx;
129
- const files = storage.readDir(folderPath);
130
- if (!files) return;
131
- const metaPath = resolveName(joinPath(folderPath, "meta"), "meta");
132
- const indexPath = resolveName(joinPath(folderPath, "index"), "page");
133
- let meta = storage.read(metaPath);
134
- if (meta?.format !== "meta") {
135
- meta = void 0;
136
- }
137
- const isRoot = meta?.data.root ?? isGlobalRoot;
138
- let index;
139
- let children;
140
- function setIndexIfUnused() {
141
- if (isRoot || ctx.visitedPaths.has(indexPath)) return;
142
- ctx.visitedPaths.add(indexPath);
143
- index = buildFileNode(indexPath, ctx);
144
- }
145
- if (meta && meta.data.pages) {
146
- const resolved = meta.data.pages.flatMap((item, i) => resolveFolderItem(folderPath, item, ctx, i));
147
- setIndexIfUnused();
148
- for (let i = 0; i < resolved.length; i++) {
149
- const item = resolved[i];
150
- if (item !== rest && item !== restReversed) continue;
151
- const items = buildAll(
152
- files.filter((file) => !ctx.visitedPaths.has(file)),
153
- ctx,
154
- item === restReversed
155
- );
156
- resolved.splice(i, 1, ...items);
157
- break;
158
- }
159
- children = resolved;
160
- } else {
161
- setIndexIfUnused();
162
- children = buildAll(
163
- files.filter((file) => !ctx.visitedPaths.has(file)),
164
- ctx
165
- );
166
- }
167
- let name = meta?.data.title ?? index?.name;
168
- if (!name) {
169
- const folderName = basename(folderPath);
170
- name = pathToName(group.exec(folderName)?.[1] ?? folderName);
171
- }
172
- let node = {
173
- type: "folder",
174
- name,
175
- icon: meta?.data.icon ?? index?.icon,
176
- root: meta?.data.root,
177
- defaultOpen: meta?.data.defaultOpen,
178
- description: meta?.data.description,
179
- index,
180
- children,
181
- $id: folderPath,
182
- $ref: !options.noRef && meta ? {
183
- metaFile: metaPath
184
- } : void 0
185
- };
186
- for (const transformer of transformers) {
187
- if (!transformer.folder) continue;
188
- node = transformer.folder.call(ctx, node, folderPath, metaPath);
189
- }
190
- return node;
191
- }
192
- function buildFileNode(path, ctx) {
193
- const { options, getUrl, storage, locale, transformers } = ctx;
194
- const page = storage.read(path);
195
- if (page?.format !== "page") return;
196
- const { title, description, icon } = page.data;
197
- let item = {
198
- $id: path,
199
- type: "page",
200
- name: title ?? pathToName(basename(path, extname(path))),
201
- description,
202
- icon,
203
- url: getUrl(page.slugs, locale),
204
- $ref: !options.noRef ? {
205
- file: path
206
- } : void 0
207
- };
208
- for (const transformer of transformers) {
209
- if (!transformer.file) continue;
210
- item = transformer.file.call(ctx, item, path);
211
- }
212
- return item;
213
- }
214
- function build(id, ctx) {
215
- const folder = buildFolderNode("", true, ctx);
216
- let root = {
217
- $id: id,
218
- name: folder.name || "Docs",
219
- children: folder.children
220
- };
221
- for (const transformer of ctx.transformers) {
222
- if (!transformer.root) continue;
223
- root = transformer.root.call(ctx, root);
224
- }
225
- return root;
226
- }
227
57
  function createPageTreeBuilder(getUrl, plugins) {
228
- function getTransformers({
229
- generateFallback = true,
230
- ...options
231
- }) {
232
- const transformers = [];
233
- if (options.transformers) {
234
- transformers.push(...options.transformers);
235
- }
236
- for (const plugin of plugins ?? []) {
237
- if (plugin.transformPageTree) transformers.push(plugin.transformPageTree);
238
- }
239
- if (generateFallback) {
240
- transformers.push(transformerFallback());
241
- }
242
- return transformers;
243
- }
244
- function createFlattenPathResolver(storage) {
245
- const map2 = /* @__PURE__ */ new Map();
246
- const files = storage.getFiles();
247
- for (const file of files) {
248
- const content = storage.read(file);
249
- const flattenPath = file.substring(0, file.length - extname(file).length);
250
- map2.set(flattenPath + "." + content.format, file);
251
- }
252
- return (name, format) => {
253
- return map2.get(name + "." + format);
254
- };
255
- }
256
58
  return {
257
59
  build(storage, options) {
258
60
  const key = "";
259
61
  return this.buildI18n({ [key]: storage }, options)[key];
260
62
  },
261
63
  buildI18n(storages, options = {}) {
262
- const transformers = getTransformers(options);
64
+ let nextId = 0;
263
65
  const out = {};
66
+ const transformers = [];
67
+ if (options.transformers) {
68
+ transformers.push(...options.transformers);
69
+ }
70
+ for (const plugin of plugins ?? []) {
71
+ if (plugin.transformPageTree)
72
+ transformers.push(plugin.transformPageTree);
73
+ }
74
+ if (options.generateFallback ?? true) {
75
+ transformers.push(transformerFallback());
76
+ }
264
77
  for (const [locale, storage] of Object.entries(storages)) {
265
- const resolve = createFlattenPathResolver(storage);
266
- const branch = locale.length === 0 ? "root" : locale;
267
- out[locale] = build(options.id ? `${options.id}-${branch}` : branch, {
78
+ let rootId = locale.length === 0 ? "root" : locale;
79
+ if (options.id) rootId = `${options.id}-${rootId}`;
80
+ out[locale] = createPageTreeBuilderUtils({
81
+ rootId,
268
82
  transformers,
269
83
  builder: this,
270
84
  options,
@@ -272,16 +86,210 @@ function createPageTreeBuilder(getUrl, plugins) {
272
86
  locale,
273
87
  storage,
274
88
  storages,
275
- visitedPaths: /* @__PURE__ */ new Set(),
276
- resolveName(name, format) {
277
- return resolve(name, format) ?? name;
89
+ generateNodeId() {
90
+ return "_" + nextId++;
278
91
  }
279
- });
92
+ }).root();
280
93
  }
281
94
  return out;
282
95
  }
283
96
  };
284
97
  }
98
+ function createFlattenPathResolver(storage) {
99
+ const map2 = /* @__PURE__ */ new Map();
100
+ const files = storage.getFiles();
101
+ for (const file of files) {
102
+ const content = storage.read(file);
103
+ const flattenPath = file.substring(0, file.length - extname(file).length);
104
+ map2.set(flattenPath + "." + content.format, file);
105
+ }
106
+ return (name, format) => {
107
+ return map2.get(name + "." + format) ?? name;
108
+ };
109
+ }
110
+ function createPageTreeBuilderUtils(ctx) {
111
+ const resolveFlattenPath = createFlattenPathResolver(ctx.storage);
112
+ const visitedPaths = /* @__PURE__ */ new Set();
113
+ function nextNodeId(localId = ctx.generateNodeId()) {
114
+ return `${ctx.rootId}:${localId}`;
115
+ }
116
+ return {
117
+ buildPaths(paths, reversed = false) {
118
+ const items = [];
119
+ const folders = [];
120
+ const sortedPaths = paths.sort(
121
+ (a, b) => a.localeCompare(b) * (reversed ? -1 : 1)
122
+ );
123
+ for (const path of sortedPaths) {
124
+ const fileNode = this.file(path);
125
+ if (fileNode) {
126
+ if (basename(path, extname(path)) === "index")
127
+ items.unshift(fileNode);
128
+ else items.push(fileNode);
129
+ continue;
130
+ }
131
+ const dirNode = this.folder(path, false);
132
+ if (dirNode) folders.push(dirNode);
133
+ }
134
+ return [...items, ...folders];
135
+ },
136
+ resolveFolderItem(folderPath, item) {
137
+ if (item === rest || item === restReversed) return item;
138
+ let match = separator.exec(item);
139
+ if (match?.groups) {
140
+ let node = {
141
+ $id: nextNodeId(),
142
+ type: "separator",
143
+ icon: match.groups.icon,
144
+ name: match.groups.name
145
+ };
146
+ for (const transformer of ctx.transformers) {
147
+ if (!transformer.separator) continue;
148
+ node = transformer.separator.call(ctx, node);
149
+ }
150
+ return [node];
151
+ }
152
+ match = link.exec(item);
153
+ if (match?.groups) {
154
+ const { icon, url, name, external } = match.groups;
155
+ let node = {
156
+ $id: nextNodeId(),
157
+ type: "page",
158
+ icon,
159
+ name,
160
+ url,
161
+ external: external ? true : void 0
162
+ };
163
+ for (const transformer of ctx.transformers) {
164
+ if (!transformer.file) continue;
165
+ node = transformer.file.call(ctx, node);
166
+ }
167
+ return [node];
168
+ }
169
+ const isExcept = item.startsWith(excludePrefix);
170
+ const isExtract = !isExcept && item.startsWith(extractPrefix);
171
+ let filename = item;
172
+ if (isExcept) {
173
+ filename = item.slice(excludePrefix.length);
174
+ } else if (isExtract) {
175
+ filename = item.slice(extractPrefix.length);
176
+ }
177
+ const path = resolveFlattenPath(joinPath(folderPath, filename), "page");
178
+ if (isExcept) {
179
+ visitedPaths.add(path);
180
+ return [];
181
+ }
182
+ const dirNode = this.folder(path, false);
183
+ if (dirNode) {
184
+ return isExtract ? dirNode.children : [dirNode];
185
+ }
186
+ const fileNode = this.file(path);
187
+ return fileNode ? [fileNode] : [];
188
+ },
189
+ folder(folderPath, isGlobalRoot) {
190
+ const { storage, options, transformers } = ctx;
191
+ const files = storage.readDir(folderPath);
192
+ if (!files) return;
193
+ const metaPath = resolveFlattenPath(joinPath(folderPath, "meta"), "meta");
194
+ const indexPath = resolveFlattenPath(
195
+ joinPath(folderPath, "index"),
196
+ "page"
197
+ );
198
+ let meta = storage.read(metaPath);
199
+ if (meta?.format !== "meta") {
200
+ meta = void 0;
201
+ }
202
+ const isRoot = meta?.data.root ?? isGlobalRoot;
203
+ let index;
204
+ let children;
205
+ if (meta && meta.data.pages) {
206
+ const resolved = meta.data.pages.flatMap((item) => this.resolveFolderItem(folderPath, item));
207
+ if (!isRoot && !visitedPaths.has(indexPath)) {
208
+ index = this.file(indexPath);
209
+ }
210
+ for (let i = 0; i < resolved.length; i++) {
211
+ const item = resolved[i];
212
+ if (item !== rest && item !== restReversed) continue;
213
+ const items = this.buildPaths(
214
+ files.filter((file) => !visitedPaths.has(file)),
215
+ item === restReversed
216
+ );
217
+ resolved.splice(i, 1, ...items);
218
+ break;
219
+ }
220
+ children = resolved;
221
+ } else {
222
+ if (!isRoot && !visitedPaths.has(indexPath)) {
223
+ index = this.file(indexPath);
224
+ }
225
+ children = this.buildPaths(
226
+ files.filter((file) => !visitedPaths.has(file))
227
+ );
228
+ }
229
+ let name = meta?.data.title ?? index?.name;
230
+ if (!name) {
231
+ const folderName = basename(folderPath);
232
+ name = pathToName(group.exec(folderName)?.[1] ?? folderName);
233
+ }
234
+ let node = {
235
+ type: "folder",
236
+ name,
237
+ icon: meta?.data.icon ?? index?.icon,
238
+ root: meta?.data.root,
239
+ defaultOpen: meta?.data.defaultOpen,
240
+ description: meta?.data.description,
241
+ index,
242
+ children,
243
+ $id: nextNodeId(folderPath),
244
+ $ref: !options.noRef && meta ? {
245
+ metaFile: metaPath
246
+ } : void 0
247
+ };
248
+ visitedPaths.add(folderPath);
249
+ for (const transformer of transformers) {
250
+ if (!transformer.folder) continue;
251
+ node = transformer.folder.call(ctx, node, folderPath, metaPath);
252
+ }
253
+ return node;
254
+ },
255
+ file(path) {
256
+ const { options, getUrl, storage, locale, transformers } = ctx;
257
+ const page = storage.read(path);
258
+ if (page?.format !== "page") return;
259
+ const { title, description, icon } = page.data;
260
+ let item = {
261
+ $id: nextNodeId(path),
262
+ type: "page",
263
+ name: title ?? pathToName(basename(path, extname(path))),
264
+ description,
265
+ icon,
266
+ url: getUrl(page.slugs, locale),
267
+ $ref: !options.noRef ? {
268
+ file: path
269
+ } : void 0
270
+ };
271
+ visitedPaths.add(path);
272
+ for (const transformer of transformers) {
273
+ if (!transformer.file) continue;
274
+ item = transformer.file.call(ctx, item, path);
275
+ }
276
+ return item;
277
+ },
278
+ root() {
279
+ const folder = this.folder("", true);
280
+ let root = {
281
+ $id: ctx.rootId,
282
+ name: folder.name || "Docs",
283
+ children: folder.children
284
+ };
285
+ for (const transformer of ctx.transformers) {
286
+ if (!transformer.root) continue;
287
+ root = transformer.root.call(ctx, root);
288
+ }
289
+ return root;
290
+ }
291
+ };
292
+ }
285
293
  function pathToName(name) {
286
294
  const result = [];
287
295
  for (const c of name) {
@@ -1,6 +1,6 @@
1
- import { L as LoaderPlugin } from '../../builder-BynMF2Pa.js';
1
+ import { L as LoaderPlugin } from '../../builder-DEvYXjy8.js';
2
2
  import { icons } from 'lucide-react';
3
- import '../../definitions-DQnHJeWn.js';
3
+ import '../../definitions-DbCug1P3.js';
4
4
  import 'react';
5
5
  import '../../i18n/index.js';
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "16.0.9",
3
+ "version": "16.0.11",
4
4
  "description": "The library for building a documentation website in any React.js framework",
5
5
  "keywords": [
6
6
  "Fumadocs",
@@ -142,6 +142,7 @@
142
142
  "mdast-util-mdxjs-esm": "^2.0.1",
143
143
  "next": "16.0.1",
144
144
  "react-router": "^7.9.5",
145
+ "remark-directive": "^4.0.0",
145
146
  "remark-mdx": "^3.1.1",
146
147
  "remove-markdown": "^0.6.2",
147
148
  "typescript": "^5.9.3",