fumadocs-mdx 12.0.2 → 13.0.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.
Files changed (80) hide show
  1. package/dist/bin.cjs +1033 -308
  2. package/dist/bin.js +4 -4
  3. package/dist/build-mdx-BHG-_uxo.d.cts +53 -0
  4. package/dist/build-mdx-CzrQDBRZ.d.ts +53 -0
  5. package/dist/bun/index.cjs +92 -28
  6. package/dist/bun/index.js +6 -7
  7. package/dist/{chunk-QAUWMR5D.js → chunk-3J3WL7WN.js} +23 -5
  8. package/dist/chunk-4MAYA5QX.js +44 -0
  9. package/dist/{chunk-RMDXSZYE.js → chunk-CEA6MYJU.js} +13 -8
  10. package/dist/{chunk-IQAEAI4P.js → chunk-HI62EXSB.js} +63 -2
  11. package/dist/{chunk-46UPKP5R.js → chunk-II3H5ZVZ.js} +5 -5
  12. package/dist/{chunk-LGYVNESJ.js → chunk-JVZFH6ND.js} +6 -22
  13. package/dist/{chunk-LMG6UWCL.js → chunk-K5ZLPEIQ.js} +56 -16
  14. package/dist/{chunk-AUOOMFAI.js → chunk-KILFIBVW.js} +4 -13
  15. package/dist/chunk-NVRDCY6Z.js +30 -0
  16. package/dist/{chunk-VXEBLM4X.js → chunk-XV5Z4BFL.js} +1 -1
  17. package/dist/config/index.cjs +56 -16
  18. package/dist/config/index.d.cts +2 -1
  19. package/dist/config/index.d.ts +2 -1
  20. package/dist/config/index.js +1 -1
  21. package/dist/{define-DJbJduHy.d.ts → define-BCNh3n4O.d.cts} +40 -16
  22. package/dist/{define-DJbJduHy.d.cts → define-bck_EB4t.d.ts} +40 -16
  23. package/dist/index.cjs +0 -109
  24. package/dist/index.d.cts +73 -12
  25. package/dist/index.d.ts +73 -12
  26. package/dist/index.js +0 -11
  27. package/dist/{load-UUXLUBHL.js → load-MNG3CLET.js} +1 -3
  28. package/dist/loader-mdx.cjs +153 -60
  29. package/dist/loader-mdx.d.cts +1 -0
  30. package/dist/loader-mdx.d.ts +1 -0
  31. package/dist/loader-mdx.js +23 -9
  32. package/dist/next/index.cjs +213 -181
  33. package/dist/next/index.d.cts +2 -11
  34. package/dist/next/index.d.ts +2 -11
  35. package/dist/next/index.js +145 -117
  36. package/dist/node/loader.cjs +128 -70
  37. package/dist/node/loader.js +14 -9
  38. package/dist/plugins/index.cjs +78 -0
  39. package/dist/plugins/index.d.cts +7 -0
  40. package/dist/plugins/index.d.ts +7 -0
  41. package/dist/plugins/index.js +6 -0
  42. package/dist/plugins/json-schema.cjs +61 -0
  43. package/dist/plugins/json-schema.d.cts +16 -0
  44. package/dist/plugins/json-schema.d.ts +16 -0
  45. package/dist/plugins/json-schema.js +40 -0
  46. package/dist/remark-postprocess-K233ZVBK.d.cts +22 -0
  47. package/dist/remark-postprocess-K233ZVBK.d.ts +22 -0
  48. package/dist/runtime/next/async.cjs +109 -71
  49. package/dist/runtime/next/async.d.cts +9 -6
  50. package/dist/runtime/next/async.d.ts +9 -6
  51. package/dist/runtime/next/async.js +9 -19
  52. package/dist/runtime/next/index.cjs +26 -15
  53. package/dist/runtime/next/index.d.cts +11 -8
  54. package/dist/runtime/next/index.d.ts +11 -8
  55. package/dist/runtime/next/index.js +2 -2
  56. package/dist/runtime/vite/browser.cjs +7 -3
  57. package/dist/runtime/vite/browser.d.cts +56 -7
  58. package/dist/runtime/vite/browser.d.ts +56 -7
  59. package/dist/runtime/vite/browser.js +2 -1
  60. package/dist/runtime/vite/server.cjs +46 -36
  61. package/dist/runtime/vite/server.d.cts +13 -10
  62. package/dist/runtime/vite/server.d.ts +13 -10
  63. package/dist/runtime/vite/server.js +14 -25
  64. package/dist/{types-Ci6BA1tA.d.ts → types-1cCFEzWt.d.ts} +3 -10
  65. package/dist/{types-CbLt05Gc.d.cts → types-D5NhXTJY.d.cts} +3 -10
  66. package/dist/vite/index.cjs +387 -220
  67. package/dist/vite/index.d.cts +29 -10
  68. package/dist/vite/index.d.ts +29 -10
  69. package/dist/vite/index.js +212 -33
  70. package/dist/{watcher-HGOH3APP.js → watcher-WXJDWRZY.js} +1 -1
  71. package/package.json +29 -16
  72. package/dist/browser-BupUnhpC.d.ts +0 -98
  73. package/dist/browser-R0x9IPaQ.d.cts +0 -98
  74. package/dist/chunk-ADR6R7HM.js +0 -29
  75. package/dist/chunk-XMFLD5J6.js +0 -30
  76. package/dist/chunk-ZLCSVXCD.js +0 -10
  77. package/dist/chunk-ZX7TM4AR.js +0 -127
  78. package/dist/postinstall-SCSXM4IM.js +0 -10
  79. package/dist/shared-Cnm1afPW.d.cts +0 -71
  80. package/dist/shared-DpXxElc1.d.ts +0 -71
@@ -175,7 +175,6 @@ var init_build = __esm({
175
175
  // src/loaders/config/load.ts
176
176
  var load_exports = {};
177
177
  __export(load_exports, {
178
- getConfigHash: () => getConfigHash,
179
178
  loadConfig: () => loadConfig
180
179
  });
181
180
  async function compileConfig(configPath, outDir) {
@@ -198,37 +197,22 @@ async function compileConfig(configPath, outDir) {
198
197
  throw new Error("failed to compile configuration file");
199
198
  }
200
199
  }
201
- async function loadConfig(configPath, outDir, hash, build = false) {
202
- if (cache3 && cache3.hash === hash) {
203
- return await cache3.config;
204
- }
200
+ async function loadConfig(configPath, outDir, build = false) {
205
201
  if (build) await compileConfig(configPath, outDir);
206
202
  const url = (0, import_node_url.pathToFileURL)(path4.resolve(outDir, "source.config.mjs"));
207
- const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
208
- return buildConfig(
209
- // every call to `loadConfig` will cause the previous cache to be ignored
210
- loaded
211
- );
212
- });
213
- if (hash) cache3 = { config, hash };
203
+ url.searchParams.set("hash", Date.now().toString());
204
+ const config = import(url.href).then(
205
+ (loaded) => buildConfig(loaded)
206
+ );
214
207
  return await config;
215
208
  }
216
- async function getConfigHash(configPath) {
217
- const stats = await fs3.stat(configPath).catch(() => void 0);
218
- if (stats) {
219
- return stats.mtime.getTime().toString();
220
- }
221
- throw new Error("Cannot find config file");
222
- }
223
- var fs3, path4, import_node_url, cache3;
209
+ var path4, import_node_url;
224
210
  var init_load = __esm({
225
211
  "src/loaders/config/load.ts"() {
226
212
  "use strict";
227
- fs3 = __toESM(require("fs/promises"), 1);
228
213
  path4 = __toESM(require("path"), 1);
229
214
  import_node_url = require("url");
230
215
  init_build();
231
- cache3 = null;
232
216
  }
233
217
  });
234
218
 
@@ -321,12 +305,56 @@ var import_mdx = require("@mdx-js/mdx");
321
305
 
322
306
  // src/loaders/mdx/remark-include.ts
323
307
  var import_unified = require("unified");
324
- var import_unist_util_visit = require("unist-util-visit");
308
+ var import_unist_util_visit2 = require("unist-util-visit");
325
309
  var path2 = __toESM(require("path"), 1);
326
310
  var fs = __toESM(require("fs/promises"), 1);
327
- var import_remark_parse = __toESM(require("remark-parse"), 1);
328
- var import_remark_mdx = __toESM(require("remark-mdx"), 1);
329
311
  var import_mdx_plugins = require("fumadocs-core/mdx-plugins");
312
+
313
+ // src/loaders/mdx/remark-unravel.ts
314
+ var import_unist_util_visit = require("unist-util-visit");
315
+ function remarkMarkAndUnravel() {
316
+ return (tree) => {
317
+ (0, import_unist_util_visit.visit)(tree, function(node, index, parent) {
318
+ let offset = -1;
319
+ let all = true;
320
+ let oneOrMore = false;
321
+ if (parent && typeof index === "number" && node.type === "paragraph") {
322
+ const children = node.children;
323
+ while (++offset < children.length) {
324
+ const child = children[offset];
325
+ if (child.type === "mdxJsxTextElement" || child.type === "mdxTextExpression") {
326
+ oneOrMore = true;
327
+ } else if (child.type === "text" && child.value.trim().length === 0) {
328
+ } else {
329
+ all = false;
330
+ break;
331
+ }
332
+ }
333
+ if (all && oneOrMore) {
334
+ offset = -1;
335
+ const newChildren = [];
336
+ while (++offset < children.length) {
337
+ const child = children[offset];
338
+ if (child.type === "mdxJsxTextElement") {
339
+ child.type = "mdxJsxFlowElement";
340
+ }
341
+ if (child.type === "mdxTextExpression") {
342
+ child.type = "mdxFlowExpression";
343
+ }
344
+ if (child.type === "text" && /^[\t\r\n ]+$/.test(String(child.value))) {
345
+ } else {
346
+ newChildren.push(child);
347
+ }
348
+ }
349
+ parent.children.splice(index, 1, ...newChildren);
350
+ return index;
351
+ }
352
+ }
353
+ });
354
+ };
355
+ }
356
+
357
+ // src/loaders/mdx/remark-include.ts
330
358
  var ElementLikeTypes = [
331
359
  "mdxJsxFlowElement",
332
360
  "mdxJsxTextElement",
@@ -366,7 +394,7 @@ function parseSpecifier(specifier) {
366
394
  function extractSection(root, section) {
367
395
  let nodes;
368
396
  let capturingHeadingContent = false;
369
- (0, import_unist_util_visit.visit)(root, (node) => {
397
+ (0, import_unist_util_visit2.visit)(root, (node) => {
370
398
  if (node.type === "heading") {
371
399
  if (capturingHeadingContent) {
372
400
  return false;
@@ -398,7 +426,7 @@ function extractSection(root, section) {
398
426
  }
399
427
  function remarkInclude() {
400
428
  const TagName = "include";
401
- async function embedContent(file, heading, params, data) {
429
+ const embedContent = async (file, heading, params, data) => {
402
430
  let content;
403
431
  try {
404
432
  content = (await fs.readFile(file)).toString();
@@ -421,18 +449,17 @@ ${e instanceof Error ? e.message : String(e)}`,
421
449
  data: {}
422
450
  };
423
451
  }
424
- const parser = (data._getProcessor ?? getDefaultProcessor)(
425
- ext === ".mdx" ? "mdx" : "md"
426
- );
452
+ const parser = data._getProcessor ? data._getProcessor(ext === ".mdx" ? "mdx" : "md") : this;
427
453
  const parsed = fumaMatter(content);
428
454
  let mdast = parser.parse({
429
455
  path: file,
430
456
  value: parsed.content,
431
457
  data: { frontmatter: parsed.data }
432
458
  });
459
+ const baseProcessor = (0, import_unified.unified)().use(remarkMarkAndUnravel);
433
460
  if (heading) {
434
461
  const extracted = extractSection(
435
- await (0, import_unified.unified)().use(import_mdx_plugins.remarkHeading).run(mdast),
462
+ await baseProcessor.use(import_mdx_plugins.remarkHeading).run(mdast),
436
463
  heading
437
464
  );
438
465
  if (!extracted)
@@ -440,13 +467,15 @@ ${e instanceof Error ? e.message : String(e)}`,
440
467
  `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.`
441
468
  );
442
469
  mdast = extracted;
470
+ } else {
471
+ mdast = await baseProcessor.run(mdast);
443
472
  }
444
473
  await update(mdast, path2.dirname(file), data);
445
474
  return mdast;
446
- }
475
+ };
447
476
  async function update(tree, directory, data) {
448
477
  const queue = [];
449
- (0, import_unist_util_visit.visit)(tree, ElementLikeTypes, (_node, _, parent) => {
478
+ (0, import_unist_util_visit2.visit)(tree, ElementLikeTypes, (_node, _, parent) => {
450
479
  const node = _node;
451
480
  if (node.name !== TagName) return;
452
481
  const specifier = flattenNode(node);
@@ -473,24 +502,28 @@ ${e instanceof Error ? e.message : String(e)}`,
473
502
  await update(tree, path2.dirname(file.path), file.data);
474
503
  };
475
504
  }
476
- function getDefaultProcessor(format) {
477
- const mdProcessor = (0, import_unified.unified)().use(import_remark_parse.default);
478
- if (format === "md") return mdProcessor;
479
- return mdProcessor.use(import_remark_mdx.default);
480
- }
481
505
 
482
506
  // src/loaders/mdx/remark-postprocess.ts
483
- var import_unist_util_visit2 = require("unist-util-visit");
507
+ var import_unist_util_visit3 = require("unist-util-visit");
484
508
  var import_mdast_util_to_markdown = require("mdast-util-to-markdown");
485
509
  var import_estree_util_value_to_estree = require("estree-util-value-to-estree");
510
+ var import_unist_util_remove_position = require("unist-util-remove-position");
511
+ var import_remark_mdx = __toESM(require("remark-mdx"), 1);
486
512
  function remarkPostprocess({
513
+ _format,
487
514
  includeProcessedMarkdown = false,
515
+ includeMDAST = false,
488
516
  valueToExport = []
489
- } = {}) {
517
+ }) {
518
+ let _stringifyProcessor;
519
+ const getStringifyProcessor = () => {
520
+ if (_format === "mdx") return this;
521
+ return _stringifyProcessor ??= this().use(import_remark_mdx.default).freeze();
522
+ };
490
523
  return (tree, file) => {
491
524
  let title;
492
525
  const urls = [];
493
- (0, import_unist_util_visit2.visit)(tree, ["heading", "link"], (node) => {
526
+ (0, import_unist_util_visit3.visit)(tree, ["heading", "link"], (node) => {
494
527
  if (node.type === "heading" && node.depth === 1) {
495
528
  title = flattenNode2(node);
496
529
  }
@@ -506,12 +539,19 @@ function remarkPostprocess({
506
539
  }
507
540
  file.data.extractedReferences = urls;
508
541
  if (includeProcessedMarkdown) {
542
+ const processor = getStringifyProcessor();
509
543
  file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
510
- ...this.data("settings"),
544
+ ...processor.data("settings"),
511
545
  // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
512
- extensions: this.data("toMarkdownExtensions") || []
546
+ extensions: processor.data("toMarkdownExtensions") || []
513
547
  });
514
548
  }
549
+ if (includeMDAST) {
550
+ const options = includeMDAST === true ? {} : includeMDAST;
551
+ file.data._mdast = JSON.stringify(
552
+ options.removePosition ? (0, import_unist_util_remove_position.removePosition)(structuredClone(tree)) : tree
553
+ );
554
+ }
515
555
  for (const { name, value } of file.data["mdx-export"] ?? []) {
516
556
  tree.children.unshift(getMdastExport(name, value));
517
557
  }
@@ -579,6 +619,7 @@ async function buildMDX(cacheKey, source, options) {
579
619
  [
580
620
  remarkPostprocess,
581
621
  {
622
+ _format: format,
582
623
  ...options.postprocess,
583
624
  valueToExport: [
584
625
  ...options.postprocess?.valueToExport ?? [],
@@ -586,7 +627,8 @@ async function buildMDX(cacheKey, source, options) {
586
627
  "extractedReferences",
587
628
  "frontmatter",
588
629
  "lastModified",
589
- "_markdown"
630
+ "_markdown",
631
+ "_mdast"
590
632
  ]
591
633
  }
592
634
  ]
@@ -618,16 +660,21 @@ var import_node_path2 = __toESM(require("path"), 1);
618
660
  var import_node_crypto = require("crypto");
619
661
  var querySchema = import_zod.z.object({
620
662
  only: import_zod.z.literal(["frontmatter", "all"]).default("all"),
621
- collection: import_zod.z.string().optional(),
622
- hash: import_zod.z.string().describe(
623
- "the hash of config, used for revalidation on Turbopack/Webpack."
624
- ).optional()
663
+ collection: import_zod.z.string().optional()
625
664
  }).loose();
626
665
  var cacheEntry = import_zod.z.object({
627
666
  code: import_zod.z.string(),
628
667
  map: import_zod.z.any().optional(),
629
668
  hash: import_zod.z.string().optional()
630
669
  });
670
+ var hashes = /* @__PURE__ */ new WeakMap();
671
+ function getConfigHash(config) {
672
+ let hash = hashes.get(config);
673
+ if (hash) return hash;
674
+ hash = Date.now().toString();
675
+ hashes.set(config, hash);
676
+ return hash;
677
+ }
631
678
  function createMdxLoader(configLoader) {
632
679
  return async ({
633
680
  source: value,
@@ -638,7 +685,7 @@ function createMdxLoader(configLoader) {
638
685
  }) => {
639
686
  const matter = fumaMatter(value);
640
687
  const parsed = querySchema.parse(query);
641
- const loaded = await configLoader.getConfig(parsed.hash);
688
+ const loaded = await configLoader.getConfig();
642
689
  const cacheDir = isDevelopment ? void 0 : loaded.global.experimentalBuildCache;
643
690
  const cacheKey = `${parsed.hash}_${parsed.collection ?? "global"}_${generateCacheHash(filePath)}`;
644
691
  if (cacheDir) {
@@ -678,7 +725,7 @@ function createMdxLoader(configLoader) {
678
725
  }
679
726
  const lineOffset = isDevelopment ? countLines(matter.matter) : 0;
680
727
  const compiled = await buildMDX(
681
- `${parsed.hash ?? ""}:${parsed.collection ?? "global"}`,
728
+ `${getConfigHash(loaded)}:${parsed.collection ?? "global"}`,
682
729
  "\n".repeat(lineOffset) + matter.content,
683
730
  {
684
731
  development: isDevelopment,
@@ -720,22 +767,54 @@ function countLines(s) {
720
767
 
721
768
  // src/loaders/config/index.ts
722
769
  var import_node_path3 = __toESM(require("path"), 1);
723
- function dynamicConfig(configPath, outDir) {
770
+ var import_promises2 = __toESM(require("fs/promises"), 1);
771
+ function staticConfig({
772
+ outDir,
773
+ configPath,
774
+ buildConfig: buildConfig2
775
+ }) {
776
+ let cached;
724
777
  return {
725
- async getConfig(hash) {
726
- const { loadConfig: loadConfig2, getConfigHash: getConfigHash2 } = await Promise.resolve().then(() => (init_load(), load_exports));
727
- return loadConfig2(
728
- configPath,
729
- outDir,
730
- hash ?? await getConfigHash2(configPath)
778
+ async getConfig() {
779
+ if (cached) return cached;
780
+ cached = Promise.resolve().then(() => (init_load(), load_exports)).then(
781
+ (mod) => mod.loadConfig(configPath, outDir, buildConfig2)
731
782
  );
783
+ return cached;
784
+ }
785
+ };
786
+ }
787
+ function dynamicConfig({
788
+ outDir,
789
+ configPath,
790
+ buildConfig: buildConfig2
791
+ }) {
792
+ let loaded;
793
+ async function getConfigHash2() {
794
+ const stats = await import_promises2.default.stat(configPath).catch(() => void 0);
795
+ if (stats) {
796
+ return stats.mtime.getTime().toString();
797
+ }
798
+ throw new Error("Cannot find config file");
799
+ }
800
+ return {
801
+ async getConfig() {
802
+ const hash = await getConfigHash2();
803
+ if (loaded && loaded.hash === hash) return loaded.config;
804
+ loaded = {
805
+ hash,
806
+ config: Promise.resolve().then(() => (init_load(), load_exports)).then(
807
+ (mod) => mod.loadConfig(configPath, outDir, buildConfig2)
808
+ )
809
+ };
810
+ return loaded.config;
732
811
  }
733
812
  };
734
813
  }
735
814
 
736
815
  // src/loaders/adapter.ts
737
816
  var import_node_url2 = require("url");
738
- var import_promises2 = __toESM(require("fs/promises"), 1);
817
+ var import_promises3 = __toESM(require("fs/promises"), 1);
739
818
  var import_node_querystring = require("querystring");
740
819
  var import_node_path4 = __toESM(require("path"), 1);
741
820
  function toWebpack(loader2) {
@@ -764,8 +843,22 @@ function toWebpack(loader2) {
764
843
  // src/loader-mdx.ts
765
844
  var instance;
766
845
  async function loader(source, callback) {
846
+ const { isDev, outDir, configPath } = this.getOptions();
767
847
  this.cacheable(true);
768
- const { configPath, outDir } = this.getOptions();
769
- instance ??= toWebpack(createMdxLoader(dynamicConfig(configPath, outDir)));
848
+ this.addDependency(configPath);
849
+ instance ??= toWebpack(
850
+ createMdxLoader(
851
+ // the config is built on dev server
852
+ isDev ? dynamicConfig({
853
+ outDir,
854
+ configPath,
855
+ buildConfig: false
856
+ }) : staticConfig({
857
+ outDir,
858
+ configPath,
859
+ buildConfig: false
860
+ })
861
+ )
862
+ );
770
863
  await instance.call(this, source, callback);
771
864
  }
@@ -3,6 +3,7 @@ import { LoaderContext } from 'webpack';
3
3
  interface Options {
4
4
  configPath: string;
5
5
  outDir: string;
6
+ isDev: boolean;
6
7
  }
7
8
  /**
8
9
  * Load MDX/markdown files
@@ -3,6 +3,7 @@ import { LoaderContext } from 'webpack';
3
3
  interface Options {
4
4
  configPath: string;
5
5
  outDir: string;
6
+ isDev: boolean;
6
7
  }
7
8
  /**
8
9
  * Load MDX/markdown files
@@ -1,23 +1,37 @@
1
1
  import {
2
2
  toWebpack
3
- } from "./chunk-VXEBLM4X.js";
3
+ } from "./chunk-XV5Z4BFL.js";
4
4
  import {
5
5
  createMdxLoader
6
- } from "./chunk-RMDXSZYE.js";
7
- import "./chunk-QAUWMR5D.js";
8
- import "./chunk-LMG6UWCL.js";
9
- import "./chunk-IQAEAI4P.js";
6
+ } from "./chunk-CEA6MYJU.js";
7
+ import "./chunk-3J3WL7WN.js";
8
+ import "./chunk-K5ZLPEIQ.js";
10
9
  import {
11
- dynamicConfig
12
- } from "./chunk-XMFLD5J6.js";
10
+ dynamicConfig,
11
+ staticConfig
12
+ } from "./chunk-HI62EXSB.js";
13
13
  import "./chunk-VWJKRQZR.js";
14
14
 
15
15
  // src/loader-mdx.ts
16
16
  var instance;
17
17
  async function loader(source, callback) {
18
+ const { isDev, outDir, configPath } = this.getOptions();
18
19
  this.cacheable(true);
19
- const { configPath, outDir } = this.getOptions();
20
- instance ??= toWebpack(createMdxLoader(dynamicConfig(configPath, outDir)));
20
+ this.addDependency(configPath);
21
+ instance ??= toWebpack(
22
+ createMdxLoader(
23
+ // the config is built on dev server
24
+ isDev ? dynamicConfig({
25
+ outDir,
26
+ configPath,
27
+ buildConfig: false
28
+ }) : staticConfig({
29
+ outDir,
30
+ configPath,
31
+ buildConfig: false
32
+ })
33
+ )
34
+ );
21
35
  await instance.call(this, source, callback);
22
36
  }
23
37
  export {