fumadocs-mdx 11.10.1 → 12.0.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.
Files changed (68) hide show
  1. package/dist/bin.cjs +126 -218
  2. package/dist/bin.js +1 -1
  3. package/dist/{browser-B2G8uAF2.d.cts → browser-D5lvL8vv.d.ts} +51 -4
  4. package/dist/{browser-DrH7tKRi.d.ts → browser-DjWADqp8.d.cts} +51 -4
  5. package/dist/bun/index.cjs +274 -230
  6. package/dist/bun/index.js +8 -8
  7. package/dist/chunk-ADR6R7HM.js +29 -0
  8. package/dist/{chunk-UOOPSLFY.js → chunk-AUOOMFAI.js} +27 -21
  9. package/dist/chunk-FSZMKRVH.js +80 -0
  10. package/dist/{chunk-766EAFX6.js → chunk-LGYVNESJ.js} +2 -36
  11. package/dist/chunk-LMG6UWCL.js +167 -0
  12. package/dist/chunk-QAUWMR5D.js +142 -0
  13. package/dist/{chunk-QJCCVMBJ.js → chunk-SP7CHRTS.js} +17 -47
  14. package/dist/{chunk-QVZ7JH4H.js → chunk-U4MQ44TS.js} +1 -1
  15. package/dist/{chunk-CNKI574E.js → chunk-VXEBLM4X.js} +1 -1
  16. package/dist/chunk-XMFLD5J6.js +30 -0
  17. package/dist/chunk-ZLCSVXCD.js +10 -0
  18. package/dist/{chunk-XXSKWWMB.js → chunk-ZX7TM4AR.js} +4 -2
  19. package/dist/config/index.cjs +97 -148
  20. package/dist/config/index.d.cts +1 -1
  21. package/dist/config/index.d.ts +1 -1
  22. package/dist/config/index.js +48 -9
  23. package/dist/{define-BH4bnHQl.d.ts → define--6HQ1ehX.d.cts} +18 -3
  24. package/dist/{define-BH4bnHQl.d.cts → define--6HQ1ehX.d.ts} +18 -3
  25. package/dist/load-UUXLUBHL.js +9 -0
  26. package/dist/loader-mdx.cjs +336 -305
  27. package/dist/loader-mdx.js +8 -8
  28. package/dist/next/index.cjs +152 -242
  29. package/dist/next/index.js +52 -66
  30. package/dist/node/loader.cjs +274 -243
  31. package/dist/node/loader.js +7 -8
  32. package/dist/postinstall-SCSXM4IM.js +10 -0
  33. package/dist/{mdx-options-T73E4LQB.js → preset-ZMP6U62C.js} +1 -1
  34. package/dist/runtime/next/async.cjs +304 -204
  35. package/dist/runtime/next/async.d.cts +3 -3
  36. package/dist/runtime/next/async.d.ts +3 -3
  37. package/dist/runtime/next/async.js +59 -32
  38. package/dist/runtime/next/index.cjs +32 -21
  39. package/dist/runtime/next/index.d.cts +11 -7
  40. package/dist/runtime/next/index.d.ts +11 -7
  41. package/dist/runtime/next/index.js +2 -1
  42. package/dist/runtime/vite/browser.d.cts +2 -3
  43. package/dist/runtime/vite/browser.d.ts +2 -3
  44. package/dist/runtime/vite/server.cjs +67 -21
  45. package/dist/runtime/vite/server.d.cts +14 -28
  46. package/dist/runtime/vite/server.d.ts +14 -28
  47. package/dist/runtime/vite/server.js +61 -21
  48. package/dist/shared-0QIuV0XZ.d.ts +70 -0
  49. package/dist/shared-CqgMnt9h.d.cts +70 -0
  50. package/dist/{types-DN9KrG7R.d.ts → types-CFlQxTN8.d.ts} +10 -37
  51. package/dist/{types-DT83Ijs6.d.cts → types-DkGjw-Uo.d.cts} +10 -37
  52. package/dist/vite/index.cjs +299 -279
  53. package/dist/vite/index.d.cts +1 -0
  54. package/dist/vite/index.d.ts +1 -0
  55. package/dist/vite/index.js +15 -20
  56. package/dist/{watcher-4NDMOH4R.js → watcher-HGOH3APP.js} +1 -1
  57. package/package.json +16 -16
  58. package/dist/build-mdx-DnC1jKvn.d.cts +0 -46
  59. package/dist/build-mdx-DnC1jKvn.d.ts +0 -46
  60. package/dist/chunk-GBMFGEC7.js +0 -57
  61. package/dist/chunk-QQWCBFFE.js +0 -40
  62. package/dist/chunk-SMSNZ6N5.js +0 -155
  63. package/dist/chunk-SVTXMVLQ.js +0 -139
  64. package/dist/config/zod-3.cjs +0 -422
  65. package/dist/config/zod-3.d.cts +0 -53
  66. package/dist/config/zod-3.d.ts +0 -53
  67. package/dist/config/zod-3.js +0 -40
  68. package/dist/postinstall-XV4WSHZP.js +0 -9
@@ -30,86 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // src/mdx-plugins/remark-postprocess.ts
34
- function remarkPostprocess({
35
- injectExports
36
- }) {
37
- return (tree, file) => {
38
- let title;
39
- const urls = [];
40
- (0, import_unist_util_visit.visit)(tree, ["heading", "link"], (node) => {
41
- if (node.type === "heading" && node.depth === 1) {
42
- title = flattenNode(node);
43
- }
44
- if (node.type !== "link") return;
45
- urls.push({
46
- href: node.url
47
- });
48
- return "skip";
49
- });
50
- if (title) {
51
- file.data.frontmatter ??= {};
52
- if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
53
- }
54
- file.data.extractedReferences = urls;
55
- for (const name of injectExports) {
56
- if (!(name in file.data)) continue;
57
- tree.children.unshift(getMdastExport(name, file.data[name]));
58
- }
59
- };
60
- }
61
- function flattenNode(node) {
62
- if ("children" in node)
63
- return node.children.map((child) => flattenNode(child)).join("");
64
- if ("value" in node) return node.value;
65
- return "";
66
- }
67
- function getMdastExport(name, value) {
68
- return {
69
- type: "mdxjsEsm",
70
- value: "",
71
- data: {
72
- estree: {
73
- type: "Program",
74
- sourceType: "module",
75
- body: [
76
- {
77
- type: "ExportNamedDeclaration",
78
- attributes: [],
79
- specifiers: [],
80
- source: null,
81
- declaration: {
82
- type: "VariableDeclaration",
83
- kind: "let",
84
- declarations: [
85
- {
86
- type: "VariableDeclarator",
87
- id: {
88
- type: "Identifier",
89
- name
90
- },
91
- init: (0, import_estree_util_value_to_estree.valueToEstree)(value)
92
- }
93
- ]
94
- }
95
- }
96
- ]
97
- }
98
- }
99
- };
100
- }
101
- var import_unist_util_visit, import_estree_util_value_to_estree;
102
- var init_remark_postprocess = __esm({
103
- "src/mdx-plugins/remark-postprocess.ts"() {
104
- "use strict";
105
- import_unist_util_visit = require("unist-util-visit");
106
- import_estree_util_value_to_estree = require("estree-util-value-to-estree");
107
- }
108
- });
109
-
110
- // src/utils/mdx-options.ts
111
- var mdx_options_exports = {};
112
- __export(mdx_options_exports, {
33
+ // src/loaders/mdx/preset.ts
34
+ var preset_exports = {};
35
+ __export(preset_exports, {
113
36
  getDefaultMDXOptions: () => getDefaultMDXOptions
114
37
  });
115
38
  function pluginOption(def, options = []) {
@@ -132,13 +55,6 @@ function getDefaultMDXOptions({
132
55
  _withoutBundler = false,
133
56
  ...mdxOptions
134
57
  }) {
135
- const mdxExports = [
136
- "structuredData",
137
- "extractedReferences",
138
- "frontmatter",
139
- "lastModified",
140
- ...valueToExport
141
- ];
142
58
  const remarkPlugins = pluginOption(
143
59
  (v) => [
144
60
  plugins.remarkGfm,
@@ -166,10 +82,15 @@ function getDefaultMDXOptions({
166
82
  plugins.remarkStructure,
167
83
  remarkStructureOptions
168
84
  ],
169
- [
170
- remarkPostprocess,
171
- { injectExports: mdxExports }
172
- ]
85
+ () => {
86
+ return (_, file) => {
87
+ file.data["mdx-export"] ??= [];
88
+ for (const name of valueToExport) {
89
+ if (name in file.data)
90
+ file.data["mdx-export"].push({ name, value: file.data[name] });
91
+ }
92
+ };
93
+ }
173
94
  ],
174
95
  mdxOptions.remarkPlugins
175
96
  );
@@ -189,23 +110,13 @@ function getDefaultMDXOptions({
189
110
  };
190
111
  }
191
112
  var plugins;
192
- var init_mdx_options = __esm({
193
- "src/utils/mdx-options.ts"() {
113
+ var init_preset = __esm({
114
+ "src/loaders/mdx/preset.ts"() {
194
115
  "use strict";
195
116
  plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
196
- init_remark_postprocess();
197
117
  }
198
118
  });
199
119
 
200
- // src/vite/index.ts
201
- var vite_exports = {};
202
- __export(vite_exports, {
203
- default: () => mdx,
204
- postInstall: () => postInstall
205
- });
206
- module.exports = __toCommonJS(vite_exports);
207
- var import_vite = require("vite");
208
-
209
120
  // src/config/build.ts
210
121
  function buildConfig(config) {
211
122
  const collections = /* @__PURE__ */ new Map();
@@ -242,7 +153,7 @@ function buildConfig(config) {
242
153
  const input = this.global.mdxOptions;
243
154
  async function uncached() {
244
155
  const options = typeof input === "function" ? await input() : input;
245
- const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_mdx_options(), mdx_options_exports));
156
+ const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_preset(), preset_exports));
246
157
  if (options?.preset === "minimal") return options;
247
158
  return getDefaultMDXOptions2({
248
159
  ...options,
@@ -255,8 +166,69 @@ function buildConfig(config) {
255
166
  }
256
167
  };
257
168
  }
169
+ var init_build = __esm({
170
+ "src/config/build.ts"() {
171
+ "use strict";
172
+ }
173
+ });
174
+
175
+ // src/loaders/config/load.ts
176
+ async function compileConfig(configPath, outDir) {
177
+ const { build } = await import("esbuild");
178
+ const transformed = await build({
179
+ entryPoints: [{ in: configPath, out: "source.config" }],
180
+ bundle: true,
181
+ outdir: outDir,
182
+ target: "node20",
183
+ write: true,
184
+ platform: "node",
185
+ format: "esm",
186
+ packages: "external",
187
+ outExtension: {
188
+ ".js": ".mjs"
189
+ },
190
+ allowOverwrite: true
191
+ });
192
+ if (transformed.errors.length > 0) {
193
+ throw new Error("failed to compile configuration file");
194
+ }
195
+ }
196
+ async function loadConfig(configPath, outDir, hash, build = false) {
197
+ if (cache3 && cache3.hash === hash) {
198
+ return await cache3.config;
199
+ }
200
+ if (build) await compileConfig(configPath, outDir);
201
+ const url = (0, import_node_url2.pathToFileURL)(path7.resolve(outDir, "source.config.mjs"));
202
+ const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
203
+ return buildConfig(
204
+ // every call to `loadConfig` will cause the previous cache to be ignored
205
+ loaded
206
+ );
207
+ });
208
+ if (hash) cache3 = { config, hash };
209
+ return await config;
210
+ }
211
+ var fs4, path7, import_node_url2, cache3;
212
+ var init_load = __esm({
213
+ "src/loaders/config/load.ts"() {
214
+ "use strict";
215
+ fs4 = __toESM(require("fs/promises"), 1);
216
+ path7 = __toESM(require("path"), 1);
217
+ import_node_url2 = require("url");
218
+ init_build();
219
+ cache3 = null;
220
+ }
221
+ });
258
222
 
259
223
  // src/vite/index.ts
224
+ var vite_exports = {};
225
+ __export(vite_exports, {
226
+ default: () => mdx,
227
+ postInstall: () => postInstall
228
+ });
229
+ module.exports = __toCommonJS(vite_exports);
230
+ var import_vite = require("vite");
231
+ init_build();
260
232
  var import_node_querystring2 = require("querystring");
261
233
 
262
234
  // src/utils/validation.ts
@@ -299,7 +271,7 @@ async function validate(schema, data, context, errorMessage) {
299
271
 
300
272
  // src/vite/index.ts
301
273
  var fs6 = __toESM(require("fs/promises"), 1);
302
- var path8 = __toESM(require("path"), 1);
274
+ var path9 = __toESM(require("path"), 1);
303
275
  var import_js_yaml2 = require("js-yaml");
304
276
 
305
277
  // src/utils/import-formatter.ts
@@ -473,30 +445,42 @@ async function getGitTimestamp(file) {
473
445
  }
474
446
  }
475
447
 
476
- // src/utils/count-lines.ts
477
- function countLines(s) {
478
- let num = 0;
479
- for (const c of s) {
480
- if (c === "\n") num++;
481
- }
482
- return num;
483
- }
484
-
485
- // src/utils/build-mdx.ts
448
+ // src/loaders/mdx/build-mdx.ts
486
449
  var import_mdx = require("@mdx-js/mdx");
487
450
 
488
- // src/mdx-plugins/remark-include.ts
451
+ // src/loaders/mdx/remark-include.ts
489
452
  var import_unified = require("unified");
490
- var import_unist_util_visit2 = require("unist-util-visit");
453
+ var import_unist_util_visit = require("unist-util-visit");
491
454
  var path3 = __toESM(require("path"), 1);
492
455
  var fs = __toESM(require("fs/promises"), 1);
493
456
  var import_remark_parse = __toESM(require("remark-parse"), 1);
494
457
  var import_remark_mdx = __toESM(require("remark-mdx"), 1);
495
458
  var import_mdx_plugins = require("fumadocs-core/mdx-plugins");
496
- var baseProcessor = (0, import_unified.unified)().use(import_mdx_plugins.remarkHeading);
497
- function flattenNode2(node) {
459
+ var ElementLikeTypes = [
460
+ "mdxJsxFlowElement",
461
+ "mdxJsxTextElement",
462
+ "containerDirective",
463
+ "textDirective",
464
+ "leafDirective"
465
+ ];
466
+ function isElementLike(node) {
467
+ return ElementLikeTypes.includes(node.type);
468
+ }
469
+ function parseElementAttributes(element) {
470
+ if (Array.isArray(element.attributes)) {
471
+ const attributes = {};
472
+ for (const attr of element.attributes) {
473
+ if (attr.type === "mdxJsxAttribute" && (typeof attr.value === "string" || attr.value === null)) {
474
+ attributes[attr.name] = attr.value;
475
+ }
476
+ }
477
+ return attributes;
478
+ }
479
+ return element.attributes ?? {};
480
+ }
481
+ function flattenNode(node) {
498
482
  if ("children" in node)
499
- return node.children.map((child) => flattenNode2(child)).join("");
483
+ return node.children.map((child) => flattenNode(child)).join("");
500
484
  if ("value" in node) return node.value;
501
485
  return "";
502
486
  }
@@ -510,21 +494,31 @@ function parseSpecifier(specifier) {
510
494
  }
511
495
  function extractSection(root, section) {
512
496
  let nodes;
513
- for (const node of root.children) {
514
- if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
515
- (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
516
- )) {
517
- nodes = node.children;
518
- break;
519
- }
520
- if (node.type === "heading" && node.data?.hProperties?.id === section) {
521
- nodes = [node];
522
- continue;
497
+ let capturingHeadingContent = false;
498
+ (0, import_unist_util_visit.visit)(root, (node) => {
499
+ if (node.type === "heading") {
500
+ if (capturingHeadingContent) {
501
+ return false;
502
+ }
503
+ if (node.data?.hProperties?.id === section) {
504
+ capturingHeadingContent = true;
505
+ nodes = [node];
506
+ return "skip";
507
+ }
508
+ return;
523
509
  }
524
- if (!nodes) continue;
525
- if (node.type === "heading") break;
526
- nodes.push(node);
527
- }
510
+ if (capturingHeadingContent) {
511
+ nodes?.push(node);
512
+ return "skip";
513
+ }
514
+ if (isElementLike(node) && node.name === "section") {
515
+ const attributes = parseElementAttributes(node);
516
+ if (attributes.id === section) {
517
+ nodes = node.children;
518
+ return false;
519
+ }
520
+ }
521
+ });
528
522
  if (nodes)
529
523
  return {
530
524
  type: "root",
@@ -556,55 +550,52 @@ ${e instanceof Error ? e.message : String(e)}`,
556
550
  data: {}
557
551
  };
558
552
  }
559
- const processor = (data._getProcessor ?? getDefaultProcessor)(
553
+ const parser = (data._getProcessor ?? getDefaultProcessor)(
560
554
  ext === ".mdx" ? "mdx" : "md"
561
555
  );
562
- let parsed = await baseProcessor.run(
563
- processor.parse(fumaMatter(content).content)
564
- );
556
+ const parsed = fumaMatter(content);
557
+ let mdast = parser.parse({
558
+ path: file,
559
+ value: parsed.content,
560
+ data: { frontmatter: parsed.data }
561
+ });
565
562
  if (heading) {
566
- const extracted = extractSection(parsed, heading);
563
+ const extracted = extractSection(
564
+ await (0, import_unified.unified)().use(import_mdx_plugins.remarkHeading).run(mdast),
565
+ heading
566
+ );
567
567
  if (!extracted)
568
568
  throw new Error(
569
- `Cannot find section ${heading} in ${file}, make sure you have encapsulated the section in a <section id="${heading}"> tag.`
569
+ `Cannot find section ${heading} in ${file}, make sure you have encapsulated the section in a <section id="${heading}"> tag, or a :::section directive with remark-directive configured.`
570
570
  );
571
- parsed = extracted;
571
+ mdast = extracted;
572
572
  }
573
- await update(parsed, path3.dirname(file), data);
574
- return parsed;
573
+ await update(mdast, path3.dirname(file), data);
574
+ return mdast;
575
575
  }
576
576
  async function update(tree, directory, data) {
577
577
  const queue = [];
578
- (0, import_unist_util_visit2.visit)(
579
- tree,
580
- ["mdxJsxFlowElement", "mdxJsxTextElement"],
581
- (_node, _, parent) => {
582
- const node = _node;
583
- if (node.name !== TagName) return;
584
- const params = {};
585
- const specifier = flattenNode2(node);
586
- if (specifier.length === 0) return "skip";
587
- for (const attr of node.attributes) {
588
- if (attr.type === "mdxJsxAttribute" && (typeof attr.value === "string" || attr.value === null)) {
589
- params[attr.name] = attr.value;
590
- }
591
- }
592
- const { file: relativePath, section } = parseSpecifier(specifier);
593
- const file = path3.resolve(
594
- "cwd" in params ? process.cwd() : directory,
595
- relativePath
596
- );
597
- queue.push(
598
- embedContent(file, section, params, data).then((replace) => {
599
- Object.assign(
600
- parent && parent.type === "paragraph" ? parent : node,
601
- replace
602
- );
603
- })
604
- );
605
- return "skip";
606
- }
607
- );
578
+ (0, import_unist_util_visit.visit)(tree, ElementLikeTypes, (_node, _, parent) => {
579
+ const node = _node;
580
+ if (node.name !== TagName) return;
581
+ const specifier = flattenNode(node);
582
+ if (specifier.length === 0) return "skip";
583
+ const attributes = parseElementAttributes(node);
584
+ const { file: relativePath, section } = parseSpecifier(specifier);
585
+ const file = path3.resolve(
586
+ "cwd" in attributes ? process.cwd() : directory,
587
+ relativePath
588
+ );
589
+ queue.push(
590
+ embedContent(file, section, attributes, data).then((replace) => {
591
+ Object.assign(
592
+ parent && parent.type === "paragraph" ? parent : node,
593
+ replace
594
+ );
595
+ })
596
+ );
597
+ return "skip";
598
+ });
608
599
  await Promise.all(queue);
609
600
  }
610
601
  return async (tree, file) => {
@@ -617,7 +608,90 @@ function getDefaultProcessor(format) {
617
608
  return mdProcessor.use(import_remark_mdx.default);
618
609
  }
619
610
 
620
- // src/utils/build-mdx.ts
611
+ // src/loaders/mdx/remark-postprocess.ts
612
+ var import_unist_util_visit2 = require("unist-util-visit");
613
+ var import_mdast_util_to_markdown = require("mdast-util-to-markdown");
614
+ var import_estree_util_value_to_estree = require("estree-util-value-to-estree");
615
+ function remarkPostprocess({
616
+ includeProcessedMarkdown = false,
617
+ valueToExport = []
618
+ } = {}) {
619
+ return (tree, file) => {
620
+ let title;
621
+ const urls = [];
622
+ (0, import_unist_util_visit2.visit)(tree, ["heading", "link"], (node) => {
623
+ if (node.type === "heading" && node.depth === 1) {
624
+ title = flattenNode2(node);
625
+ }
626
+ if (node.type !== "link") return;
627
+ urls.push({
628
+ href: node.url
629
+ });
630
+ return "skip";
631
+ });
632
+ if (title) {
633
+ file.data.frontmatter ??= {};
634
+ if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
635
+ }
636
+ file.data.extractedReferences = urls;
637
+ if (includeProcessedMarkdown) {
638
+ file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
639
+ ...this.data("settings"),
640
+ // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
641
+ extensions: this.data("toMarkdownExtensions") || []
642
+ });
643
+ }
644
+ for (const { name, value } of file.data["mdx-export"] ?? []) {
645
+ tree.children.unshift(getMdastExport(name, value));
646
+ }
647
+ for (const name of valueToExport) {
648
+ if (!(name in file.data)) continue;
649
+ tree.children.unshift(getMdastExport(name, file.data[name]));
650
+ }
651
+ };
652
+ }
653
+ function getMdastExport(name, value) {
654
+ return {
655
+ type: "mdxjsEsm",
656
+ value: "",
657
+ data: {
658
+ estree: {
659
+ type: "Program",
660
+ sourceType: "module",
661
+ body: [
662
+ {
663
+ type: "ExportNamedDeclaration",
664
+ attributes: [],
665
+ specifiers: [],
666
+ source: null,
667
+ declaration: {
668
+ type: "VariableDeclaration",
669
+ kind: "let",
670
+ declarations: [
671
+ {
672
+ type: "VariableDeclarator",
673
+ id: {
674
+ type: "Identifier",
675
+ name
676
+ },
677
+ init: (0, import_estree_util_value_to_estree.valueToEstree)(value)
678
+ }
679
+ ]
680
+ }
681
+ }
682
+ ]
683
+ }
684
+ }
685
+ };
686
+ }
687
+ function flattenNode2(node) {
688
+ if ("children" in node)
689
+ return node.children.map((child) => flattenNode2(child)).join("");
690
+ if ("value" in node) return node.value;
691
+ return "";
692
+ }
693
+
694
+ // src/loaders/mdx/build-mdx.ts
621
695
  var cache2 = /* @__PURE__ */ new Map();
622
696
  async function buildMDX(cacheKey, source, options) {
623
697
  const { filePath, frontmatter, data, _compiler, ...rest } = options;
@@ -628,7 +702,24 @@ async function buildMDX(cacheKey, source, options) {
628
702
  processor = (0, import_mdx.createProcessor)({
629
703
  outputFormat: "program",
630
704
  ...rest,
631
- remarkPlugins: [remarkInclude, ...rest.remarkPlugins ?? []],
705
+ remarkPlugins: [
706
+ remarkInclude,
707
+ ...rest.remarkPlugins ?? [],
708
+ [
709
+ remarkPostprocess,
710
+ {
711
+ ...options.postprocess,
712
+ valueToExport: [
713
+ ...options.postprocess?.valueToExport ?? [],
714
+ "structuredData",
715
+ "extractedReferences",
716
+ "frontmatter",
717
+ "lastModified",
718
+ "_markdown"
719
+ ]
720
+ }
721
+ ]
722
+ ],
632
723
  format
633
724
  });
634
725
  cache2.set(key, processor);
@@ -636,7 +727,7 @@ async function buildMDX(cacheKey, source, options) {
636
727
  return processor;
637
728
  }
638
729
  return getProcessor(
639
- options.format ?? filePath.endsWith(".mdx") ? "mdx" : "md"
730
+ options.format ?? (filePath.endsWith(".mdx") ? "mdx" : "md")
640
731
  ).process({
641
732
  value: source,
642
733
  path: filePath,
@@ -649,7 +740,7 @@ async function buildMDX(cacheKey, source, options) {
649
740
  });
650
741
  }
651
742
 
652
- // src/loaders/mdx.ts
743
+ // src/loaders/mdx/index.ts
653
744
  var import_zod = require("zod");
654
745
  var import_promises = __toESM(require("fs/promises"), 1);
655
746
  var import_node_path3 = __toESM(require("path"), 1);
@@ -684,21 +775,18 @@ function createMdxLoader(configLoader) {
684
775
  if (cached && cached.hash === generateCacheHash(value)) return cached;
685
776
  }
686
777
  const collection = parsed.collection ? loaded.collections.get(parsed.collection) : void 0;
687
- let schema;
688
- let mdxOptions;
778
+ let docCollection;
689
779
  switch (collection?.type) {
690
780
  case "doc":
691
- mdxOptions = collection.mdxOptions;
692
- schema = collection.schema;
781
+ docCollection = collection;
693
782
  break;
694
783
  case "docs":
695
- mdxOptions = collection.docs.mdxOptions;
696
- schema = collection.docs.schema;
784
+ docCollection = collection.docs;
697
785
  break;
698
786
  }
699
- if (schema) {
787
+ if (docCollection?.schema) {
700
788
  matter.data = await validate(
701
- schema,
789
+ docCollection.schema,
702
790
  matter.data,
703
791
  {
704
792
  source: value,
@@ -723,7 +811,8 @@ function createMdxLoader(configLoader) {
723
811
  "\n".repeat(lineOffset) + matter.content,
724
812
  {
725
813
  development: isDevelopment,
726
- ...mdxOptions ?? await loaded.getDefaultMDXOptions(),
814
+ ...docCollection?.mdxOptions ?? await loaded.getDefaultMDXOptions(),
815
+ postprocess: docCollection?.postprocess,
727
816
  data,
728
817
  filePath,
729
818
  frontmatter: matter.data,
@@ -750,82 +839,19 @@ function createMdxLoader(configLoader) {
750
839
  function generateCacheHash(input) {
751
840
  return (0, import_node_crypto.createHash)("md5").update(input).digest("hex");
752
841
  }
753
-
754
- // src/utils/config.ts
755
- var fs3 = __toESM(require("fs/promises"), 1);
756
- var path5 = __toESM(require("path"), 1);
757
- var import_node_url = require("url");
758
- function findConfigFile() {
759
- return path5.resolve("source.config.ts");
760
- }
761
- var cache3 = null;
762
- async function isZod3() {
763
- try {
764
- const content = JSON.parse(
765
- (await fs3.readFile("node_modules/zod/package.json")).toString()
766
- );
767
- const version = content.version;
768
- return typeof version === "string" && version.startsWith("3.");
769
- } catch {
770
- return false;
771
- }
772
- }
773
- function createCompatZodPlugin() {
774
- return {
775
- name: "replace-zod-import",
776
- async setup(build) {
777
- const usingZod3 = await isZod3();
778
- if (!usingZod3) return;
779
- console.warn(
780
- "[Fumadocs MDX] Noticed Zod v3 in your node_modules, we recommend upgrading to Zod v4 for better compatibility."
781
- );
782
- build.onResolve({ filter: /^fumadocs-mdx\/config$/ }, () => {
783
- return {
784
- path: "fumadocs-mdx/config/zod-3",
785
- external: true
786
- };
787
- });
788
- }
789
- };
790
- }
791
- async function compileConfig(configPath, outDir) {
792
- const { build } = await import("esbuild");
793
- const transformed = await build({
794
- entryPoints: [{ in: configPath, out: "source.config" }],
795
- bundle: true,
796
- outdir: outDir,
797
- target: "node20",
798
- write: true,
799
- platform: "node",
800
- format: "esm",
801
- packages: "external",
802
- plugins: [createCompatZodPlugin()],
803
- outExtension: {
804
- ".js": ".mjs"
805
- },
806
- allowOverwrite: true
807
- });
808
- if (transformed.errors.length > 0) {
809
- throw new Error("failed to compile configuration file");
810
- }
811
- }
812
- async function loadConfig(configPath, outDir, hash, build = false) {
813
- if (cache3 && cache3.hash === hash) {
814
- return await cache3.config;
842
+ function countLines(s) {
843
+ let num = 0;
844
+ for (const c of s) {
845
+ if (c === "\n") num++;
815
846
  }
816
- if (build) await compileConfig(configPath, outDir);
817
- const url = (0, import_node_url.pathToFileURL)(path5.resolve(outDir, "source.config.mjs"));
818
- const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
819
- return buildConfig(
820
- // every call to `loadConfig` will cause the previous cache to be ignored
821
- loaded
822
- );
823
- });
824
- if (hash) cache3 = { config, hash };
825
- return await config;
847
+ return num;
826
848
  }
827
849
 
828
- // src/loaders/config-loader.ts
850
+ // src/loaders/config/index.ts
851
+ var import_node_path4 = __toESM(require("path"), 1);
852
+ function findConfigFile() {
853
+ return import_node_path4.default.resolve("source.config.ts");
854
+ }
829
855
  function resolvedConfig(loaded) {
830
856
  return {
831
857
  getConfig() {
@@ -835,10 +861,10 @@ function resolvedConfig(loaded) {
835
861
  }
836
862
 
837
863
  // src/loaders/adapter.ts
838
- var import_node_url2 = require("url");
864
+ var import_node_url = require("url");
839
865
  var import_promises2 = __toESM(require("fs/promises"), 1);
840
866
  var import_node_querystring = require("querystring");
841
- var import_node_path4 = __toESM(require("path"), 1);
867
+ var import_node_path5 = __toESM(require("path"), 1);
842
868
  function toVite(loader) {
843
869
  return async function(file, query, value) {
844
870
  const result = await loader({
@@ -860,8 +886,9 @@ function toVite(loader) {
860
886
  }
861
887
 
862
888
  // src/vite/postinstall.ts
889
+ init_load();
863
890
  var import_promises3 = __toESM(require("fs/promises"), 1);
864
- var import_node_path5 = __toESM(require("path"), 1);
891
+ var import_node_path6 = __toESM(require("path"), 1);
865
892
  async function postInstall(configPath = findConfigFile(), outDir, addJsExtension = false) {
866
893
  const config = await loadConfig(configPath, "node_modules", void 0, true);
867
894
  const outFile = "source.generated.ts";
@@ -869,7 +896,7 @@ async function postInstall(configPath = findConfigFile(), outDir, addJsExtension
869
896
  await import_promises3.default.mkdir(outDir, { recursive: true });
870
897
  }
871
898
  await import_promises3.default.writeFile(
872
- outDir ? import_node_path5.default.join(outDir, outFile) : outFile,
899
+ outDir ? import_node_path6.default.join(outDir, outFile) : outFile,
873
900
  entry(configPath, config, outDir ?? process.cwd(), addJsExtension)
874
901
  );
875
902
  console.log("[MDX] types generated");
@@ -881,8 +908,8 @@ function mdx(config, options = {}) {
881
908
  const { generateIndexFile = true, configPath = "source.config.ts" } = options;
882
909
  const loaded = buildConfig(config);
883
910
  const mdxLoader = toVite(createMdxLoader(resolvedConfig(loaded)));
884
- async function transformMeta(path9, query, value) {
885
- const isJson = path9.endsWith(".json");
911
+ async function transformMeta(path10, query, value) {
912
+ const isJson = path10.endsWith(".json");
886
913
  const parsed = (0, import_node_querystring2.parse)(query);
887
914
  const collection = parsed.collection ? loaded.collections.get(parsed.collection) : void 0;
888
915
  if (!collection) return null;
@@ -905,8 +932,8 @@ function mdx(config, options = {}) {
905
932
  const out = await validate(
906
933
  schema,
907
934
  data,
908
- { path: path9, source: value },
909
- `invalid data in ${path9}`
935
+ { path: path10, source: value },
936
+ `invalid data in ${path10}`
910
937
  );
911
938
  return {
912
939
  code: isJson ? JSON.stringify(out) : `export default ${JSON.stringify(out)}`,
@@ -930,22 +957,15 @@ function mdx(config, options = {}) {
930
957
  },
931
958
  async buildStart() {
932
959
  if (!generateIndexFile) return;
960
+ const { out = "source.generated.ts", addJsExtension } = typeof generateIndexFile === "object" ? generateIndexFile : {};
933
961
  console.log("[Fumadocs MDX] Generating index files");
934
- const outDir = process.cwd();
935
- const outFile = "source.generated.ts";
936
- await fs6.writeFile(
937
- path8.join(outDir, outFile),
938
- entry(
939
- configPath,
940
- loaded,
941
- outDir,
942
- typeof generateIndexFile === "object" ? generateIndexFile.addJsExtension : void 0
943
- )
944
- );
962
+ const dir = path9.dirname(out);
963
+ await fs6.mkdir(dir, { recursive: true });
964
+ await fs6.writeFile(out, entry(configPath, loaded, dir, addJsExtension));
945
965
  },
946
966
  async transform(value, id) {
947
967
  const [file, query = ""] = id.split("?");
948
- const ext = path8.extname(file);
968
+ const ext = path9.extname(file);
949
969
  try {
950
970
  if ([".yaml", ".json"].includes(ext))
951
971
  return await transformMeta(file, query, value);