fumadocs-core 9.0.0 → 9.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,4 +1,4 @@
1
- import { R as Root } from './page-tree-izSPERQk.js';
1
+ import { R as Root } from './page-tree-mLHMYx2B.js';
2
2
  import 'react';
3
3
 
4
4
  interface BreadcrumbItem {
@@ -20,6 +20,7 @@ interface Folder {
20
20
  type: 'folder';
21
21
  name: string;
22
22
  root?: boolean;
23
+ defaultOpen?: boolean;
23
24
  index?: Item;
24
25
  icon?: ReactElement;
25
26
  children: Node[];
@@ -1,7 +1,7 @@
1
1
  import { T as TableOfContents } from '../get-toc-YF_TdazL.js';
2
2
  export { a as TOCItemType, g as getTableOfContents } from '../get-toc-YF_TdazL.js';
3
- import { N as Node, I as Item, R as Root } from '../page-tree-izSPERQk.js';
4
- export { p as PageTree } from '../page-tree-izSPERQk.js';
3
+ import { N as Node, I as Item, R as Root } from '../page-tree-mLHMYx2B.js';
4
+ export { p as PageTree } from '../page-tree-mLHMYx2B.js';
5
5
  import 'react';
6
6
 
7
7
  /**
@@ -1,5 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
- import { R as Root } from '../page-tree-izSPERQk.js';
2
+ import { R as Root } from '../page-tree-mLHMYx2B.js';
3
3
 
4
4
  interface LoadOptions {
5
5
  files: VirtualFile[];
@@ -93,6 +93,7 @@ interface MetaData {
93
93
  title?: string;
94
94
  root?: boolean;
95
95
  pages?: string[];
96
+ defaultOpen?: boolean;
96
97
  }
97
98
  interface PageData {
98
99
  icon?: string;
@@ -119,7 +120,7 @@ interface Folder<MD extends MetaData = MetaData, PD extends PageData = PageData>
119
120
  file: FileInfo;
120
121
  children: Node<MD, PD>[];
121
122
  }
122
- type Node<MD extends MetaData = MetaData, PD extends PageData = PageData> = Meta<MD> | Page<PD> | Folder;
123
+ type Node<MD extends MetaData = MetaData, PD extends PageData = PageData> = Meta<MD> | Page<PD> | Folder<MD, PD>;
123
124
  /**
124
125
  * A virtual file system that solves inconsistent behaviours
125
126
  *
@@ -131,10 +132,17 @@ declare class Storage {
131
132
  private rootFolder;
132
133
  constructor();
133
134
  /**
134
- * Read a file, it doesn't need an extension
135
135
  * @param path - flattened path
136
136
  */
137
- read(path: string): Page | Meta | undefined;
137
+ private read;
138
+ /**
139
+ * @param path - flattened path
140
+ */
141
+ readPage(path: string): Page | undefined;
142
+ /**
143
+ * @param path - flattened path
144
+ */
145
+ readMeta(path: string): Meta | undefined;
138
146
  readDir(path: string): Folder | undefined;
139
147
  root(): Folder;
140
148
  write(path: string, file: Omit<Page, 'file'> | Omit<Meta, 'file'>): void;
@@ -3,50 +3,41 @@ import {
3
3
  } from "../chunk-UWEEHUJV.js";
4
4
  import {
5
5
  __export,
6
- __spreadProps,
7
6
  __spreadValues
8
7
  } from "../chunk-WEAGW6MQ.js";
9
8
 
10
9
  // src/source/path.ts
11
10
  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]);
11
+ function parseFilePath(path2) {
12
+ const slashedPath = slash(path2);
13
+ const parsed = parse(slashedPath);
14
+ const flattenedPath = joinPaths([parsed.dir, parsed.name]);
16
15
  const [name, locale] = parsed.name.split(".");
17
16
  return {
18
- dirname: dir,
17
+ dirname: parsed.dir,
19
18
  name,
20
19
  flattenedPath,
21
20
  locale,
22
- path
21
+ path: slashedPath
23
22
  };
24
23
  }
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 = slash(parsed.dir);
24
+ function parseFolderPath(path2) {
25
+ const slashedPath = slash(path2);
26
+ const parsed = parse(slashedPath);
36
27
  const [name, locale] = parsed.base.split(".");
37
28
  return {
38
- dirname: dir,
29
+ dirname: parsed.dir,
39
30
  name,
40
- flattenedPath: path,
31
+ flattenedPath: slashedPath,
41
32
  locale,
42
- path
33
+ path: slashedPath
43
34
  };
44
35
  }
45
- function splitPath(path) {
46
- return path.split("/").filter((p) => p.length > 0);
36
+ function splitPath(path2) {
37
+ return path2.split("/").filter((p) => p.length > 0);
47
38
  }
48
39
  function joinPaths(paths, slashMode = "none") {
49
- const joined = paths.flatMap((path) => splitPath(path)).join("/");
40
+ const joined = paths.flatMap((path2) => splitPath(path2)).join("/");
50
41
  switch (slashMode) {
51
42
  case "leading":
52
43
  return `/${joined}`;
@@ -78,58 +69,62 @@ function buildAll(nodes, ctx, skipIndex) {
78
69
  output.push(treeNode);
79
70
  }
80
71
  if (node.type === "folder") {
81
- output.push(buildFolderNode(node, ctx));
72
+ output.push(buildFolderNode(node, false, ctx));
82
73
  }
83
74
  }
84
75
  return output;
85
76
  }
86
77
  function getFolderMeta(folder, ctx) {
87
78
  var _a;
88
- let meta = ctx.storage.read(joinPaths([folder.file.path, "meta"]));
79
+ let meta = ctx.storage.readMeta(joinPaths([folder.file.path, "meta"]));
89
80
  if (ctx.lang) {
90
- meta = (_a = ctx.storage.read(joinPaths([folder.file.path, `meta.${ctx.lang}`]))) != null ? _a : meta;
81
+ meta = (_a = ctx.storage.readMeta(joinPaths([folder.file.path, `meta.${ctx.lang}`]))) != null ? _a : meta;
82
+ }
83
+ return meta;
84
+ }
85
+ function resolveFolderItem(folder, item, ctx, addedNodePaths) {
86
+ var _a, _b, _c;
87
+ if (item === rest)
88
+ return "...";
89
+ const separateResult = separator.exec(item);
90
+ if (separateResult == null ? void 0 : separateResult.groups) {
91
+ return [
92
+ {
93
+ type: "separator",
94
+ name: separateResult.groups.name
95
+ }
96
+ ];
97
+ }
98
+ const extractResult = extractor.exec(item);
99
+ const path2 = joinPaths([
100
+ folder.file.path,
101
+ (_b = (_a = extractResult == null ? void 0 : extractResult.groups) == null ? void 0 : _a.name) != null ? _b : item
102
+ ]);
103
+ const itemNode = (_c = ctx.storage.readDir(path2)) != null ? _c : ctx.storage.readPage(path2);
104
+ if (!itemNode)
105
+ return [];
106
+ addedNodePaths.add(itemNode.file.path);
107
+ if (itemNode.type === "folder") {
108
+ const node = buildFolderNode(itemNode, false, ctx);
109
+ return (extractResult == null ? void 0 : extractResult.groups) ? node.children : [node];
91
110
  }
92
- if ((meta == null ? void 0 : meta.type) === "meta")
93
- return meta;
111
+ return [buildFileNode(itemNode, ctx)];
94
112
  }
95
- function buildFolderNode(folder, ctx, root = false) {
113
+ function buildFolderNode(folder, defaultIsRoot, ctx) {
96
114
  var _a, _b, _c, _d, _e;
97
- const indexNode = folder.children.find(
98
- (node) => node.type === "page" && node.file.name === "index"
115
+ const indexFile = ctx.storage.readPage(
116
+ joinPaths([folder.file.flattenedPath, "index"])
99
117
  );
100
- const index = indexNode ? buildFileNode(indexNode, ctx) : void 0;
118
+ const index = indexFile ? buildFileNode(indexFile, ctx) : void 0;
101
119
  const meta = (_a = getFolderMeta(folder, ctx)) == null ? void 0 : _a.data;
102
120
  let children;
103
121
  if (!meta) {
104
- children = buildAll(folder.children, ctx, !root);
122
+ children = buildAll(folder.children, ctx, !defaultIsRoot);
105
123
  } else {
106
- const isRoot = (_b = meta.root) != null ? _b : root;
124
+ const isRoot = (_b = meta.root) != null ? _b : defaultIsRoot;
107
125
  const addedNodePaths = /* @__PURE__ */ new Set();
108
126
  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 [];
127
+ return resolveFolderItem(folder, item, ctx, addedNodePaths);
133
128
  });
134
129
  const restNodes = buildAll(
135
130
  folder.children.filter((node) => !addedNodePaths.has(node.file.path)),
@@ -149,6 +144,7 @@ function buildFolderNode(folder, ctx, root = false) {
149
144
  name: (_e = (_d = meta == null ? void 0 : meta.title) != null ? _d : index == null ? void 0 : index.name) != null ? _e : pathToName(folder.file.name),
150
145
  icon: ctx.resolveIcon(meta == null ? void 0 : meta.icon),
151
146
  root: meta == null ? void 0 : meta.root,
147
+ defaultOpen: meta == null ? void 0 : meta.defaultOpen,
152
148
  index,
153
149
  children
154
150
  };
@@ -156,8 +152,10 @@ function buildFolderNode(folder, ctx, root = false) {
156
152
  function buildFileNode(page, ctx) {
157
153
  let localePage = page;
158
154
  if (ctx.lang) {
159
- const result = ctx.storage.read(`${page.file.flattenedPath}.${ctx.lang}`);
160
- if ((result == null ? void 0 : result.type) === "page")
155
+ const result = ctx.storage.readPage(
156
+ `${page.file.flattenedPath}.${ctx.lang}`
157
+ );
158
+ if (result)
161
159
  localePage = result;
162
160
  }
163
161
  return {
@@ -169,7 +167,7 @@ function buildFileNode(page, ctx) {
169
167
  }
170
168
  function build(ctx) {
171
169
  const root = ctx.storage.root();
172
- const folder = buildFolderNode(root, ctx, true);
170
+ const folder = buildFolderNode(root, true, ctx);
173
171
  return {
174
172
  name: folder.name,
175
173
  children: folder.children
@@ -179,33 +177,38 @@ function createPageTreeBuilder({
179
177
  storage,
180
178
  resolveIcon = () => void 0
181
179
  }) {
182
- const context = {
183
- storage,
184
- resolveIcon(icon) {
185
- if (!icon)
186
- return;
187
- return resolveIcon(icon);
188
- }
189
- };
180
+ function getContext(builder, locale) {
181
+ return {
182
+ storage,
183
+ lang: locale,
184
+ resolveIcon(icon) {
185
+ if (!icon)
186
+ return;
187
+ return resolveIcon(icon);
188
+ },
189
+ builder
190
+ };
191
+ }
190
192
  return {
191
193
  build() {
192
- return build(context);
194
+ return build(getContext(this));
193
195
  },
194
196
  buildI18n({ languages = [] } = {}) {
195
197
  const entries = languages.map((lang) => {
196
- const tree = build(__spreadProps(__spreadValues({}, context), {
197
- lang
198
- }));
198
+ const tree = build(getContext(this, lang));
199
199
  return [lang, tree];
200
200
  });
201
201
  return Object.fromEntries(entries);
202
202
  }
203
203
  };
204
204
  }
205
- function pathToName(path) {
206
- return path.slice(0, 1).toUpperCase() + path.slice(1);
205
+ function pathToName(path2) {
206
+ return path2.slice(0, 1).toUpperCase() + path2.slice(1);
207
207
  }
208
208
 
209
+ // src/source/load.ts
210
+ import * as path from "path";
211
+
209
212
  // src/source/file-system.ts
210
213
  var file_system_exports = {};
211
214
  __export(file_system_exports, {
@@ -223,33 +226,50 @@ var Storage = class {
223
226
  this.folders.set("", this.rootFolder);
224
227
  }
225
228
  /**
226
- * Read a file, it doesn't need an extension
227
229
  * @param path - flattened path
228
230
  */
229
- read(path) {
230
- return this.files.get(path);
231
+ read(path2, type) {
232
+ return this.files.get(`${path2}.${type}`);
233
+ }
234
+ /**
235
+ * @param path - flattened path
236
+ */
237
+ readPage(path2) {
238
+ const result = this.read(path2, "page");
239
+ if ((result == null ? void 0 : result.type) !== "page")
240
+ return;
241
+ return result;
231
242
  }
232
- readDir(path) {
233
- return this.folders.get(path);
243
+ /**
244
+ * @param path - flattened path
245
+ */
246
+ readMeta(path2) {
247
+ const result = this.read(path2, "meta");
248
+ if ((result == null ? void 0 : result.type) !== "meta")
249
+ return;
250
+ return result;
251
+ }
252
+ readDir(path2) {
253
+ return this.folders.get(path2);
234
254
  }
235
255
  root() {
236
256
  return this.rootFolder;
237
257
  }
238
- write(path, file) {
258
+ write(path2, file) {
239
259
  var _a;
240
260
  const node = __spreadValues({
241
- file: parseFilePath(path)
261
+ file: parseFilePath(path2)
242
262
  }, file);
243
263
  this.makeDir(node.file.dirname);
244
264
  (_a = this.readDir(node.file.dirname)) == null ? void 0 : _a.children.push(node);
245
- this.files.set(node.file.flattenedPath, node);
265
+ this.files.set(`${node.file.flattenedPath}.${node.type}`, node);
246
266
  }
247
267
  list() {
248
268
  return [...this.files.values()];
249
269
  }
250
- makeDir(path) {
270
+ makeDir(path2) {
251
271
  var _a;
252
- const segments = splitPath(path);
272
+ const segments = splitPath(path2);
253
273
  for (let i = 0; i < segments.length; i++) {
254
274
  const segment = segments.slice(0, i + 1).join("/");
255
275
  if (this.folders.has(segment))
@@ -283,13 +303,17 @@ function load(options) {
283
303
  function buildStorage(options) {
284
304
  const storage = new Storage();
285
305
  for (const file of options.files) {
286
- if (!isRelative(file.path, options.rootDir))
306
+ const relativePath = path.join(
307
+ path.relative(options.rootDir, path.join("./", path.dirname(file.path))),
308
+ path.basename(file.path)
309
+ );
310
+ const isRelative = !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
311
+ if (!isRelative)
287
312
  continue;
288
- const path = getRelativePath(file.path, options.rootDir);
289
313
  if (file.type === "page") {
290
- const parsedPath = parseFilePath(path);
314
+ const parsedPath = parseFilePath(relativePath);
291
315
  const slugs = options.getSlugs(parsedPath);
292
- storage.write(path, {
316
+ storage.write(relativePath, {
293
317
  slugs,
294
318
  url: options.getUrl(slugs, parsedPath.locale),
295
319
  type: file.type,
@@ -297,7 +321,7 @@ function buildStorage(options) {
297
321
  });
298
322
  }
299
323
  if (file.type === "meta") {
300
- storage.write(path, {
324
+ storage.write(relativePath, {
301
325
  type: file.type,
302
326
  data: file.data
303
327
  });
@@ -338,6 +362,10 @@ function createGetUrl(baseUrl) {
338
362
  return joinPaths(paths, "leading");
339
363
  };
340
364
  }
365
+ function getSlugs(info) {
366
+ const result = [...splitPath(info.dirname), info.name];
367
+ return result[result.length - 1] === "index" ? result.slice(0, -1) : result;
368
+ }
341
369
  function loader(options) {
342
370
  return createOutput(options);
343
371
  }
@@ -348,10 +376,7 @@ function createOutput({
348
376
  rootDir = "",
349
377
  transformers,
350
378
  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
- },
379
+ slugs = getSlugs,
355
380
  url = createGetUrl(baseUrl)
356
381
  }) {
357
382
  const result = load({
@@ -376,8 +401,8 @@ function createOutput({
376
401
  },
377
402
  getPage(slugs_ = [], language = "") {
378
403
  var _a;
379
- const path = slugs_.join("/");
380
- return (_a = i18nMap.get(language)) == null ? void 0 : _a.find((page) => page.slugs.join("/") === path);
404
+ const path2 = slugs_.join("/");
405
+ return (_a = i18nMap.get(language)) == null ? void 0 : _a.find((page) => page.slugs.join("/") === path2);
381
406
  }
382
407
  };
383
408
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "9.0.0",
3
+ "version": "9.1.0",
4
4
  "description": "The library for building a documentation website in Next.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -116,8 +116,8 @@
116
116
  ],
117
117
  "dependencies": {
118
118
  "@formatjs/intl-localematcher": "^0.5.0",
119
- "@shikijs/rehype": "1.1.5",
120
- "@shikijs/transformers": "1.1.5",
119
+ "@shikijs/rehype": "1.1.7",
120
+ "@shikijs/transformers": "1.1.7",
121
121
  "flexsearch": "0.7.21",
122
122
  "github-slugger": "^2.0.0",
123
123
  "hast-util-to-estree": "^3.1.0",
@@ -127,7 +127,7 @@
127
127
  "remark-gfm": "^4.0.0",
128
128
  "remark-mdx": "^3.0.0",
129
129
  "scroll-into-view-if-needed": "^3.1.0",
130
- "shiki": "1.1.5",
130
+ "shiki": "1.1.7",
131
131
  "swr": "^2.2.2",
132
132
  "unist-util-visit": "^5.0.0"
133
133
  },