fumadocs-core 15.7.13 → 15.8.1

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.
@@ -13,36 +13,6 @@ import {
13
13
  } from "../chunk-PFNP6PEB.js";
14
14
  import "../chunk-JSBRDJBE.js";
15
15
 
16
- // src/source/page-tree/legacy.ts
17
- function legacyTransformer(transformer) {
18
- return {
19
- file(node, file) {
20
- if (!transformer.attachFile) return node;
21
- const content = file ? this.storage.read(file) : void 0;
22
- return transformer.attachFile(
23
- node,
24
- content?.format === "page" ? content : void 0
25
- );
26
- },
27
- folder(node, folderPath, metaPath) {
28
- if (!transformer.attachFolder) return node;
29
- const files = this.storage.readDir(folderPath) ?? [];
30
- const meta = metaPath ? this.storage.read(metaPath) : void 0;
31
- return transformer.attachFolder(
32
- node,
33
- {
34
- children: files.flatMap((file) => this.storage.read(file) ?? [])
35
- },
36
- meta?.format === "meta" ? meta : void 0
37
- );
38
- },
39
- separator(node) {
40
- if (!transformer.attachSeparator) return node;
41
- return transformer.attachSeparator(node);
42
- }
43
- };
44
- }
45
-
46
16
  // src/source/page-tree/transformer-fallback.ts
47
17
  function transformerFallback() {
48
18
  const addedFiles = /* @__PURE__ */ new Set();
@@ -105,13 +75,13 @@ function buildAll(paths, ctx, reversed = false) {
105
75
  }
106
76
  function resolveFolderItem(folderPath, item, ctx, idx) {
107
77
  if (item === rest || item === restReversed) return item;
108
- const { options, resolveName } = ctx;
78
+ const { resolveName } = ctx;
109
79
  let match = separator.exec(item);
110
80
  if (match?.groups) {
111
81
  let node = {
112
82
  $id: `${folderPath}#${idx}`,
113
83
  type: "separator",
114
- icon: options.resolveIcon?.(match.groups.icon),
84
+ icon: match.groups.icon,
115
85
  name: match.groups.name
116
86
  };
117
87
  for (const transformer of ctx.transformers) {
@@ -126,7 +96,7 @@ function resolveFolderItem(folderPath, item, ctx, idx) {
126
96
  const isRelative = url.startsWith("/") || url.startsWith("#") || url.startsWith(".");
127
97
  let node = {
128
98
  type: "page",
129
- icon: options.resolveIcon?.(icon),
99
+ icon,
130
100
  name,
131
101
  url,
132
102
  external: !isRelative
@@ -203,7 +173,7 @@ function buildFolderNode(folderPath, isGlobalRoot, ctx) {
203
173
  let node = {
204
174
  type: "folder",
205
175
  name,
206
- icon: options.resolveIcon?.(meta?.data.icon) ?? index?.icon,
176
+ icon: meta?.data.icon ?? index?.icon,
207
177
  root: meta?.data.root,
208
178
  defaultOpen: meta?.data.defaultOpen,
209
179
  description: meta?.data.description,
@@ -230,7 +200,7 @@ function buildFileNode(path, ctx) {
230
200
  type: "page",
231
201
  name: title ?? pathToName(basename(path, extname(path))),
232
202
  description,
233
- icon: options.resolveIcon?.(icon),
203
+ icon,
234
204
  url: getUrl(page.slugs, locale),
235
205
  $ref: !options.noRef ? {
236
206
  file: path
@@ -246,7 +216,7 @@ function build(id, ctx) {
246
216
  const folder = buildFolderNode("", true, ctx);
247
217
  let root = {
248
218
  $id: id,
249
- name: folder.name,
219
+ name: folder.name || "Docs",
250
220
  children: folder.children
251
221
  };
252
222
  for (const transformer of ctx.transformers) {
@@ -257,9 +227,9 @@ function build(id, ctx) {
257
227
  }
258
228
  function createPageTreeBuilder(getUrl) {
259
229
  function getTransformers(options, generateFallback) {
260
- const transformers = [legacyTransformer(options)];
261
- if (options.transformers) {
262
- transformers.push(...options.transformers);
230
+ const transformers = [];
231
+ for (const plugin of options.plugins ?? []) {
232
+ if (plugin.transformPageTree) transformers.push(plugin.transformPageTree);
263
233
  }
264
234
  if (generateFallback) {
265
235
  transformers.push(transformerFallback());
@@ -401,7 +371,7 @@ var parsers = {
401
371
  }
402
372
  };
403
373
  function loadFiles(files, options, i18n) {
404
- const { buildFile, transformers = [] } = options;
374
+ const { buildFile, plugins = [] } = options;
405
375
  const parser = parsers[i18n.parser ?? "dot"];
406
376
  const storages = {};
407
377
  const normalized = files.map(
@@ -424,11 +394,11 @@ function loadFiles(files, options, i18n) {
424
394
  const [path, locale = i18n.defaultLanguage] = parser(item.path);
425
395
  if (locale === lang) storage.write(path, item);
426
396
  }
427
- for (const transformer of transformers) {
428
- transformer({
429
- storage,
430
- options
431
- });
397
+ const context = {
398
+ storage
399
+ };
400
+ for (const plugin of plugins) {
401
+ plugin.transformStorage?.(context);
432
402
  }
433
403
  storages[lang] = storage;
434
404
  }
@@ -442,6 +412,114 @@ function normalizePath(path) {
442
412
  return segments.join("/");
443
413
  }
444
414
 
415
+ // src/source/plugins/index.ts
416
+ function buildPlugins(plugins) {
417
+ return plugins;
418
+ }
419
+
420
+ // src/source/plugins/slugs.ts
421
+ function slugsPlugin(slugsFn) {
422
+ function isIndex(file) {
423
+ return basename(file, extname(file)) === "index";
424
+ }
425
+ return {
426
+ transformStorage({ storage }) {
427
+ const indexFiles = /* @__PURE__ */ new Set();
428
+ const taken = /* @__PURE__ */ new Set();
429
+ const autoIndex = slugsFn === void 0;
430
+ for (const path of storage.getFiles()) {
431
+ const file = storage.read(path);
432
+ if (!file || file.format !== "page" || file.slugs) continue;
433
+ if (isIndex(path) && autoIndex) {
434
+ indexFiles.add(path);
435
+ continue;
436
+ }
437
+ file.slugs = slugsFn ? slugsFn(parseFilePath(path)) : getSlugs(path);
438
+ const key = file.slugs.join("/");
439
+ if (taken.has(key)) throw new Error("Duplicated slugs");
440
+ taken.add(key);
441
+ }
442
+ for (const path of indexFiles) {
443
+ const file = storage.read(path);
444
+ if (file?.format !== "page") continue;
445
+ file.slugs = getSlugs(path);
446
+ if (taken.has(file.slugs.join("/"))) file.slugs.push("index");
447
+ }
448
+ }
449
+ };
450
+ }
451
+
452
+ // src/source/plugins/compat.ts
453
+ function compatPlugin(loader2, {
454
+ attachFile,
455
+ attachSeparator,
456
+ attachFolder,
457
+ transformers
458
+ }) {
459
+ const chunk = [];
460
+ chunk.push({
461
+ transformPageTree: {
462
+ file(node, file) {
463
+ if (!attachFile) return node;
464
+ const content = file ? this.storage.read(file) : void 0;
465
+ return attachFile(
466
+ node,
467
+ content?.format === "page" ? content : void 0
468
+ );
469
+ },
470
+ folder(node, folderPath, metaPath) {
471
+ if (!attachFolder) return node;
472
+ const files = this.storage.readDir(folderPath) ?? [];
473
+ const meta = metaPath ? this.storage.read(metaPath) : void 0;
474
+ return attachFolder(
475
+ node,
476
+ {
477
+ children: files.flatMap((file) => this.storage.read(file) ?? [])
478
+ },
479
+ meta?.format === "meta" ? meta : void 0
480
+ );
481
+ },
482
+ separator(node) {
483
+ if (!attachSeparator) return node;
484
+ return attachSeparator(node);
485
+ }
486
+ }
487
+ });
488
+ for (const transformer of loader2.transformers ?? []) {
489
+ chunk.push(fromStorageTransformer(transformer));
490
+ }
491
+ for (const transformer of transformers ?? []) {
492
+ chunk.push(fromPageTreeTransformer(transformer));
493
+ }
494
+ return chunk;
495
+ }
496
+ function fromPageTreeTransformer(transformer) {
497
+ return {
498
+ transformPageTree: transformer
499
+ };
500
+ }
501
+ function fromStorageTransformer(transformer) {
502
+ return {
503
+ transformStorage: transformer
504
+ };
505
+ }
506
+
507
+ // src/source/plugins/icon.ts
508
+ function iconPlugin(resolveIcon) {
509
+ function replaceIcon(node) {
510
+ if (node.icon === void 0 || typeof node.icon === "string")
511
+ node.icon = resolveIcon(node.icon);
512
+ return node;
513
+ }
514
+ return {
515
+ transformPageTree: {
516
+ file: replaceIcon,
517
+ folder: replaceIcon,
518
+ separator: replaceIcon
519
+ }
520
+ };
521
+ }
522
+
445
523
  // src/source/loader.ts
446
524
  function indexPages(storages, getUrl) {
447
525
  const result = {
@@ -500,40 +578,20 @@ function createOutput(options) {
500
578
  if (!options.url && !options.baseUrl) {
501
579
  console.warn("`loader()` now requires a `baseUrl` option to be defined.");
502
580
  }
503
- const {
504
- source,
505
- baseUrl = "/",
506
- i18n,
507
- slugs: slugsFn,
508
- url: urlFn,
509
- transformers = []
510
- } = options;
581
+ const { source, baseUrl = "/", i18n, slugs: slugsFn, url: urlFn } = options;
511
582
  const getUrl = urlFn ? (...args) => normalizeUrl(urlFn(...args)) : createGetUrl(baseUrl, i18n);
512
583
  const defaultLanguage = i18n?.defaultLanguage ?? "";
513
584
  const files = loadSource(source);
514
- const transformerSlugs = ({ storage }) => {
515
- const indexFiles = /* @__PURE__ */ new Set();
516
- const taken = /* @__PURE__ */ new Set();
517
- const autoIndex = slugsFn === void 0;
518
- for (const path of storage.getFiles()) {
519
- const file = storage.read(path);
520
- if (!file || file.format !== "page" || file.slugs) continue;
521
- if (isIndex(path) && autoIndex) {
522
- indexFiles.add(path);
523
- continue;
524
- }
525
- file.slugs = slugsFn ? slugsFn(parseFilePath(path)) : getSlugs(path);
526
- const key = file.slugs.join("/");
527
- if (taken.has(key)) throw new Error("Duplicated slugs");
528
- taken.add(key);
529
- }
530
- for (const path of indexFiles) {
531
- const file = storage.read(path);
532
- if (file?.format !== "page") continue;
533
- file.slugs = getSlugs(path);
534
- if (taken.has(file.slugs.join("/"))) file.slugs.push("index");
535
- }
536
- };
585
+ const plugins = [slugsPlugin(slugsFn)];
586
+ if (options.icon) {
587
+ plugins.push(iconPlugin(options.icon));
588
+ }
589
+ if (options.plugins) {
590
+ plugins.push(...buildPlugins(options.plugins));
591
+ }
592
+ if (options.pageTree) {
593
+ plugins.push(...compatPlugin(options, options.pageTree));
594
+ }
537
595
  const storages = loadFiles(
538
596
  files,
539
597
  {
@@ -554,7 +612,7 @@ function createOutput(options) {
554
612
  data: file.data
555
613
  };
556
614
  },
557
- transformers: [transformerSlugs, ...transformers]
615
+ plugins
558
616
  },
559
617
  i18n ?? {
560
618
  defaultLanguage,
@@ -570,7 +628,7 @@ function createOutput(options) {
570
628
  get pageTree() {
571
629
  pageTree ??= builder.buildI18n({
572
630
  storages,
573
- resolveIcon: options.icon,
631
+ plugins,
574
632
  ...options.pageTree
575
633
  });
576
634
  return i18n ? pageTree : pageTree[defaultLanguage];
@@ -599,10 +657,12 @@ function createOutput(options) {
599
657
  hash
600
658
  };
601
659
  },
602
- getPages(language = defaultLanguage) {
660
+ getPages(language) {
603
661
  const pages = [];
604
662
  for (const [key, value] of walker.pages.entries()) {
605
- if (key.startsWith(`${language}.`)) pages.push(value);
663
+ if (language === void 0 || key.startsWith(`${language}.`)) {
664
+ pages.push(value);
665
+ }
606
666
  }
607
667
  return pages;
608
668
  },
@@ -676,9 +736,6 @@ function fileToPage(file, getUrl, locale) {
676
736
  };
677
737
  }
678
738
  var GroupRegex = /^\(.+\)$/;
679
- function isIndex(file) {
680
- return basename(file, extname(file)) === "index";
681
- }
682
739
  function getSlugs(file) {
683
740
  if (typeof file !== "string") return getSlugs(file.path);
684
741
  const dir = dirname(file);
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  searchAdvanced,
3
3
  searchSimple
4
- } from "./chunk-XMAVUWLD.js";
4
+ } from "./chunk-XOFXGHS4.js";
5
5
  import "./chunk-ZMWYLUDP.js";
6
- import "./chunk-CNWEGOUF.js";
6
+ import "./chunk-OTD7MV33.js";
7
7
  import "./chunk-JSBRDJBE.js";
8
8
 
9
9
  // src/search/client/static.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "15.7.13",
3
+ "version": "15.8.1",
4
4
  "description": "The library for building a documentation website in Next.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -32,6 +32,10 @@
32
32
  "import": "./dist/hide-if-empty.js",
33
33
  "types": "./dist/hide-if-empty.d.ts"
34
34
  },
35
+ "./search": {
36
+ "import": "./dist/search/index.js",
37
+ "types": "./dist/search/index.d.ts"
38
+ },
35
39
  "./search/*": {
36
40
  "import": "./dist/search/*.js",
37
41
  "types": "./dist/search/*.d.ts"
@@ -91,9 +95,9 @@
91
95
  ],
92
96
  "dependencies": {
93
97
  "@formatjs/intl-localematcher": "^0.6.1",
94
- "@orama/orama": "^3.1.13",
95
- "@shikijs/rehype": "^3.12.2",
96
- "@shikijs/transformers": "^3.12.2",
98
+ "@orama/orama": "^3.1.14",
99
+ "@shikijs/rehype": "^3.13.0",
100
+ "@shikijs/transformers": "^3.13.0",
97
101
  "github-slugger": "^2.0.0",
98
102
  "hast-util-to-estree": "^3.1.3",
99
103
  "hast-util-to-jsx-runtime": "^2.3.6",
@@ -105,26 +109,26 @@
105
109
  "remark-gfm": "^4.0.1",
106
110
  "remark-rehype": "^11.1.2",
107
111
  "scroll-into-view-if-needed": "^3.1.0",
108
- "shiki": "^3.12.2",
112
+ "shiki": "^3.13.0",
109
113
  "unist-util-visit": "^5.0.0"
110
114
  },
111
115
  "devDependencies": {
112
116
  "@mdx-js/mdx": "^3.1.1",
113
- "@mixedbread/sdk": "^0.28.1",
117
+ "@mixedbread/sdk": "^0.29.0",
114
118
  "@oramacloud/client": "^2.1.4",
115
- "@tanstack/react-router": "^1.131.41",
119
+ "@tanstack/react-router": "^1.132.7",
116
120
  "@types/estree-jsx": "^1.0.5",
117
121
  "@types/hast": "^3.0.4",
118
122
  "@types/mdast": "^4.0.3",
119
123
  "@types/negotiator": "^0.6.4",
120
- "@types/node": "24.3.3",
121
- "@types/react": "^19.1.13",
124
+ "@types/node": "24.5.2",
125
+ "@types/react": "^19.1.14",
122
126
  "@types/react-dom": "^19.1.9",
123
- "algoliasearch": "5.37.0",
127
+ "algoliasearch": "5.39.0",
124
128
  "mdast-util-mdx-jsx": "^3.2.0",
125
129
  "mdast-util-mdxjs-esm": "^2.0.1",
126
- "next": "^15.5.3",
127
- "react-router": "^7.9.1",
130
+ "next": "^15.5.4",
131
+ "react-router": "^7.9.3",
128
132
  "remark-mdx": "^3.1.1",
129
133
  "remove-markdown": "^0.6.2",
130
134
  "typescript": "^5.9.2",
@@ -1,19 +0,0 @@
1
- interface SortedResult {
2
- id: string;
3
- url: string;
4
- type: 'page' | 'heading' | 'text';
5
- content: string;
6
- contentWithHighlights?: HighlightedText[];
7
- }
8
- type HighlightedText = {
9
- type: 'text';
10
- content: string;
11
- styles?: {
12
- highlight?: boolean;
13
- };
14
- };
15
- declare function createContentHighlighter(query: string | RegExp): {
16
- highlight(content: string): HighlightedText[];
17
- };
18
-
19
- export { type HighlightedText as H, type SortedResult as S, createContentHighlighter as c };