fumadocs-mdx 12.0.0 → 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 (40) hide show
  1. package/dist/bin.cjs +102 -84
  2. package/dist/bin.js +1 -1
  3. package/dist/bun/index.cjs +156 -130
  4. package/dist/bun/index.js +8 -8
  5. package/dist/chunk-ADR6R7HM.js +29 -0
  6. package/dist/{chunk-3M4SHY6K.js → chunk-FSZMKRVH.js} +1 -1
  7. package/dist/{chunk-POXTQZ4D.js → chunk-LGYVNESJ.js} +2 -6
  8. package/dist/chunk-LMG6UWCL.js +167 -0
  9. package/dist/{chunk-SWNOXPYJ.js → chunk-QAUWMR5D.js} +6 -6
  10. package/dist/{chunk-KGUBBRL6.js → chunk-SP7CHRTS.js} +9 -37
  11. package/dist/{chunk-YC25YEBF.js → chunk-U4MQ44TS.js} +1 -1
  12. package/dist/chunk-XMFLD5J6.js +30 -0
  13. package/dist/{chunk-TLD6JMT6.js → chunk-ZX7TM4AR.js} +4 -2
  14. package/dist/config/index.cjs +84 -56
  15. package/dist/config/index.js +2 -2
  16. package/dist/load-UUXLUBHL.js +9 -0
  17. package/dist/loader-mdx.cjs +217 -174
  18. package/dist/loader-mdx.js +7 -7
  19. package/dist/next/index.cjs +128 -108
  20. package/dist/next/index.js +39 -53
  21. package/dist/node/loader.cjs +152 -109
  22. package/dist/node/loader.js +6 -7
  23. package/dist/postinstall-SCSXM4IM.js +10 -0
  24. package/dist/{preset-WFEORCAB.js → preset-ZMP6U62C.js} +1 -1
  25. package/dist/runtime/next/async.cjs +117 -65
  26. package/dist/runtime/next/async.d.cts +1 -1
  27. package/dist/runtime/next/async.d.ts +1 -1
  28. package/dist/runtime/next/async.js +15 -8
  29. package/dist/runtime/next/index.d.cts +2 -2
  30. package/dist/runtime/next/index.d.ts +2 -2
  31. package/dist/{types-DLIAvrgC.d.ts → types-CFlQxTN8.d.ts} +4 -5
  32. package/dist/{types-Dl8HLbm5.d.cts → types-DkGjw-Uo.d.cts} +4 -5
  33. package/dist/vite/index.cjs +177 -145
  34. package/dist/vite/index.d.cts +1 -0
  35. package/dist/vite/index.d.ts +1 -0
  36. package/dist/vite/index.js +14 -19
  37. package/dist/{watcher-4NDMOH4R.js → watcher-HGOH3APP.js} +1 -1
  38. package/package.json +15 -11
  39. package/dist/chunk-KTDVTBMH.js +0 -139
  40. package/dist/postinstall-U7VROOY7.js +0 -9
@@ -30,7 +30,7 @@ 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/preset.ts
33
+ // src/loaders/mdx/preset.ts
34
34
  var preset_exports = {};
35
35
  __export(preset_exports, {
36
36
  getDefaultMDXOptions: () => getDefaultMDXOptions
@@ -111,12 +111,127 @@ function getDefaultMDXOptions({
111
111
  }
112
112
  var plugins;
113
113
  var init_preset = __esm({
114
- "src/mdx/preset.ts"() {
114
+ "src/loaders/mdx/preset.ts"() {
115
115
  "use strict";
116
116
  plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
117
117
  }
118
118
  });
119
119
 
120
+ // src/config/build.ts
121
+ function buildConfig(config) {
122
+ const collections = /* @__PURE__ */ new Map();
123
+ let globalConfig = {};
124
+ for (const [k, v] of Object.entries(config)) {
125
+ if (!v) {
126
+ continue;
127
+ }
128
+ if (typeof v === "object" && "type" in v) {
129
+ if (v.type === "docs") {
130
+ collections.set(k, v);
131
+ continue;
132
+ }
133
+ if (v.type === "doc" || v.type === "meta") {
134
+ collections.set(k, v);
135
+ continue;
136
+ }
137
+ }
138
+ if (k === "default" && v) {
139
+ globalConfig = v;
140
+ continue;
141
+ }
142
+ throw new Error(
143
+ `Unknown export "${k}", you can only export collections from source configuration file.`
144
+ );
145
+ }
146
+ const mdxOptionsCache = /* @__PURE__ */ new Map();
147
+ return {
148
+ global: globalConfig,
149
+ collections,
150
+ async getDefaultMDXOptions(mode = "default") {
151
+ const cached = mdxOptionsCache.get(mode);
152
+ if (cached) return cached;
153
+ const input = this.global.mdxOptions;
154
+ async function uncached() {
155
+ const options = typeof input === "function" ? await input() : input;
156
+ const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_preset(), preset_exports));
157
+ if (options?.preset === "minimal") return options;
158
+ return getDefaultMDXOptions2({
159
+ ...options,
160
+ _withoutBundler: mode === "remote"
161
+ });
162
+ }
163
+ const result = uncached();
164
+ mdxOptionsCache.set(mode, result);
165
+ return result;
166
+ }
167
+ };
168
+ }
169
+ var init_build = __esm({
170
+ "src/config/build.ts"() {
171
+ "use strict";
172
+ }
173
+ });
174
+
175
+ // src/loaders/config/load.ts
176
+ var load_exports = {};
177
+ __export(load_exports, {
178
+ getConfigHash: () => getConfigHash,
179
+ loadConfig: () => loadConfig
180
+ });
181
+ async function compileConfig(configPath, outDir) {
182
+ const { build } = await import("esbuild");
183
+ const transformed = await build({
184
+ entryPoints: [{ in: configPath, out: "source.config" }],
185
+ bundle: true,
186
+ outdir: outDir,
187
+ target: "node20",
188
+ write: true,
189
+ platform: "node",
190
+ format: "esm",
191
+ packages: "external",
192
+ outExtension: {
193
+ ".js": ".mjs"
194
+ },
195
+ allowOverwrite: true
196
+ });
197
+ if (transformed.errors.length > 0) {
198
+ throw new Error("failed to compile configuration file");
199
+ }
200
+ }
201
+ async function loadConfig(configPath, outDir, hash, build = false) {
202
+ if (cache3 && cache3.hash === hash) {
203
+ return await cache3.config;
204
+ }
205
+ if (build) await compileConfig(configPath, outDir);
206
+ 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 };
214
+ return await config;
215
+ }
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;
224
+ var init_load = __esm({
225
+ "src/loaders/config/load.ts"() {
226
+ "use strict";
227
+ fs3 = __toESM(require("fs/promises"), 1);
228
+ path4 = __toESM(require("path"), 1);
229
+ import_node_url = require("url");
230
+ init_build();
231
+ cache3 = null;
232
+ }
233
+ });
234
+
120
235
  // src/loader-mdx.ts
121
236
  var loader_mdx_exports = {};
122
237
  __export(loader_mdx_exports, {
@@ -201,19 +316,10 @@ async function getGitTimestamp(file) {
201
316
  }
202
317
  }
203
318
 
204
- // src/utils/count-lines.ts
205
- function countLines(s) {
206
- let num = 0;
207
- for (const c of s) {
208
- if (c === "\n") num++;
209
- }
210
- return num;
211
- }
212
-
213
- // src/mdx/build-mdx.ts
319
+ // src/loaders/mdx/build-mdx.ts
214
320
  var import_mdx = require("@mdx-js/mdx");
215
321
 
216
- // src/mdx/remark-include.ts
322
+ // src/loaders/mdx/remark-include.ts
217
323
  var import_unified = require("unified");
218
324
  var import_unist_util_visit = require("unist-util-visit");
219
325
  var path2 = __toESM(require("path"), 1);
@@ -221,7 +327,28 @@ var fs = __toESM(require("fs/promises"), 1);
221
327
  var import_remark_parse = __toESM(require("remark-parse"), 1);
222
328
  var import_remark_mdx = __toESM(require("remark-mdx"), 1);
223
329
  var import_mdx_plugins = require("fumadocs-core/mdx-plugins");
224
- var baseProcessor = (0, import_unified.unified)().use(import_mdx_plugins.remarkHeading);
330
+ var ElementLikeTypes = [
331
+ "mdxJsxFlowElement",
332
+ "mdxJsxTextElement",
333
+ "containerDirective",
334
+ "textDirective",
335
+ "leafDirective"
336
+ ];
337
+ function isElementLike(node) {
338
+ return ElementLikeTypes.includes(node.type);
339
+ }
340
+ function parseElementAttributes(element) {
341
+ if (Array.isArray(element.attributes)) {
342
+ const attributes = {};
343
+ for (const attr of element.attributes) {
344
+ if (attr.type === "mdxJsxAttribute" && (typeof attr.value === "string" || attr.value === null)) {
345
+ attributes[attr.name] = attr.value;
346
+ }
347
+ }
348
+ return attributes;
349
+ }
350
+ return element.attributes ?? {};
351
+ }
225
352
  function flattenNode(node) {
226
353
  if ("children" in node)
227
354
  return node.children.map((child) => flattenNode(child)).join("");
@@ -238,21 +365,31 @@ function parseSpecifier(specifier) {
238
365
  }
239
366
  function extractSection(root, section) {
240
367
  let nodes;
241
- for (const node of root.children) {
242
- if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
243
- (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
244
- )) {
245
- nodes = node.children;
246
- break;
368
+ let capturingHeadingContent = false;
369
+ (0, import_unist_util_visit.visit)(root, (node) => {
370
+ if (node.type === "heading") {
371
+ if (capturingHeadingContent) {
372
+ return false;
373
+ }
374
+ if (node.data?.hProperties?.id === section) {
375
+ capturingHeadingContent = true;
376
+ nodes = [node];
377
+ return "skip";
378
+ }
379
+ return;
247
380
  }
248
- if (node.type === "heading" && node.data?.hProperties?.id === section) {
249
- nodes = [node];
250
- continue;
381
+ if (capturingHeadingContent) {
382
+ nodes?.push(node);
383
+ return "skip";
251
384
  }
252
- if (!nodes) continue;
253
- if (node.type === "heading") break;
254
- nodes.push(node);
255
- }
385
+ if (isElementLike(node) && node.name === "section") {
386
+ const attributes = parseElementAttributes(node);
387
+ if (attributes.id === section) {
388
+ nodes = node.children;
389
+ return false;
390
+ }
391
+ }
392
+ });
256
393
  if (nodes)
257
394
  return {
258
395
  type: "root",
@@ -284,55 +421,52 @@ ${e instanceof Error ? e.message : String(e)}`,
284
421
  data: {}
285
422
  };
286
423
  }
287
- const processor = (data._getProcessor ?? getDefaultProcessor)(
424
+ const parser = (data._getProcessor ?? getDefaultProcessor)(
288
425
  ext === ".mdx" ? "mdx" : "md"
289
426
  );
290
- let parsed = await baseProcessor.run(
291
- processor.parse(fumaMatter(content).content)
292
- );
427
+ const parsed = fumaMatter(content);
428
+ let mdast = parser.parse({
429
+ path: file,
430
+ value: parsed.content,
431
+ data: { frontmatter: parsed.data }
432
+ });
293
433
  if (heading) {
294
- const extracted = extractSection(parsed, heading);
434
+ const extracted = extractSection(
435
+ await (0, import_unified.unified)().use(import_mdx_plugins.remarkHeading).run(mdast),
436
+ heading
437
+ );
295
438
  if (!extracted)
296
439
  throw new Error(
297
- `Cannot find section ${heading} in ${file}, make sure you have encapsulated the section in a <section id="${heading}"> tag.`
440
+ `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.`
298
441
  );
299
- parsed = extracted;
442
+ mdast = extracted;
300
443
  }
301
- await update(parsed, path2.dirname(file), data);
302
- return parsed;
444
+ await update(mdast, path2.dirname(file), data);
445
+ return mdast;
303
446
  }
304
447
  async function update(tree, directory, data) {
305
448
  const queue = [];
306
- (0, import_unist_util_visit.visit)(
307
- tree,
308
- ["mdxJsxFlowElement", "mdxJsxTextElement"],
309
- (_node, _, parent) => {
310
- const node = _node;
311
- if (node.name !== TagName) return;
312
- const params = {};
313
- const specifier = flattenNode(node);
314
- if (specifier.length === 0) return "skip";
315
- for (const attr of node.attributes) {
316
- if (attr.type === "mdxJsxAttribute" && (typeof attr.value === "string" || attr.value === null)) {
317
- params[attr.name] = attr.value;
318
- }
319
- }
320
- const { file: relativePath, section } = parseSpecifier(specifier);
321
- const file = path2.resolve(
322
- "cwd" in params ? process.cwd() : directory,
323
- relativePath
324
- );
325
- queue.push(
326
- embedContent(file, section, params, data).then((replace) => {
327
- Object.assign(
328
- parent && parent.type === "paragraph" ? parent : node,
329
- replace
330
- );
331
- })
332
- );
333
- return "skip";
334
- }
335
- );
449
+ (0, import_unist_util_visit.visit)(tree, ElementLikeTypes, (_node, _, parent) => {
450
+ const node = _node;
451
+ if (node.name !== TagName) return;
452
+ const specifier = flattenNode(node);
453
+ if (specifier.length === 0) return "skip";
454
+ const attributes = parseElementAttributes(node);
455
+ const { file: relativePath, section } = parseSpecifier(specifier);
456
+ const file = path2.resolve(
457
+ "cwd" in attributes ? process.cwd() : directory,
458
+ relativePath
459
+ );
460
+ queue.push(
461
+ embedContent(file, section, attributes, data).then((replace) => {
462
+ Object.assign(
463
+ parent && parent.type === "paragraph" ? parent : node,
464
+ replace
465
+ );
466
+ })
467
+ );
468
+ return "skip";
469
+ });
336
470
  await Promise.all(queue);
337
471
  }
338
472
  return async (tree, file) => {
@@ -345,7 +479,7 @@ function getDefaultProcessor(format) {
345
479
  return mdProcessor.use(import_remark_mdx.default);
346
480
  }
347
481
 
348
- // src/mdx/remark-postprocess.ts
482
+ // src/loaders/mdx/remark-postprocess.ts
349
483
  var import_unist_util_visit2 = require("unist-util-visit");
350
484
  var import_mdast_util_to_markdown = require("mdast-util-to-markdown");
351
485
  var import_estree_util_value_to_estree = require("estree-util-value-to-estree");
@@ -374,7 +508,7 @@ function remarkPostprocess({
374
508
  if (includeProcessedMarkdown) {
375
509
  file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
376
510
  ...this.data("settings"),
377
- // @ts-expect-error - from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
511
+ // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
378
512
  extensions: this.data("toMarkdownExtensions") || []
379
513
  });
380
514
  }
@@ -428,7 +562,7 @@ function flattenNode2(node) {
428
562
  return "";
429
563
  }
430
564
 
431
- // src/mdx/build-mdx.ts
565
+ // src/loaders/mdx/build-mdx.ts
432
566
  var cache2 = /* @__PURE__ */ new Map();
433
567
  async function buildMDX(cacheKey, source, options) {
434
568
  const { filePath, frontmatter, data, _compiler, ...rest } = options;
@@ -464,7 +598,7 @@ async function buildMDX(cacheKey, source, options) {
464
598
  return processor;
465
599
  }
466
600
  return getProcessor(
467
- options.format ?? filePath.endsWith(".mdx") ? "mdx" : "md"
601
+ options.format ?? (filePath.endsWith(".mdx") ? "mdx" : "md")
468
602
  ).process({
469
603
  value: source,
470
604
  path: filePath,
@@ -477,7 +611,7 @@ async function buildMDX(cacheKey, source, options) {
477
611
  });
478
612
  }
479
613
 
480
- // src/loaders/mdx.ts
614
+ // src/loaders/mdx/index.ts
481
615
  var import_zod = require("zod");
482
616
  var import_promises = __toESM(require("fs/promises"), 1);
483
617
  var import_node_path2 = __toESM(require("path"), 1);
@@ -576,115 +710,24 @@ function createMdxLoader(configLoader) {
576
710
  function generateCacheHash(input) {
577
711
  return (0, import_node_crypto.createHash)("md5").update(input).digest("hex");
578
712
  }
579
-
580
- // src/utils/config.ts
581
- var fs3 = __toESM(require("fs/promises"), 1);
582
- var path4 = __toESM(require("path"), 1);
583
- var import_node_url = require("url");
584
-
585
- // src/config/build.ts
586
- function buildConfig(config) {
587
- const collections = /* @__PURE__ */ new Map();
588
- let globalConfig = {};
589
- for (const [k, v] of Object.entries(config)) {
590
- if (!v) {
591
- continue;
592
- }
593
- if (typeof v === "object" && "type" in v) {
594
- if (v.type === "docs") {
595
- collections.set(k, v);
596
- continue;
597
- }
598
- if (v.type === "doc" || v.type === "meta") {
599
- collections.set(k, v);
600
- continue;
601
- }
602
- }
603
- if (k === "default" && v) {
604
- globalConfig = v;
605
- continue;
606
- }
607
- throw new Error(
608
- `Unknown export "${k}", you can only export collections from source configuration file.`
609
- );
610
- }
611
- const mdxOptionsCache = /* @__PURE__ */ new Map();
612
- return {
613
- global: globalConfig,
614
- collections,
615
- async getDefaultMDXOptions(mode = "default") {
616
- const cached = mdxOptionsCache.get(mode);
617
- if (cached) return cached;
618
- const input = this.global.mdxOptions;
619
- async function uncached() {
620
- const options = typeof input === "function" ? await input() : input;
621
- const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_preset(), preset_exports));
622
- if (options?.preset === "minimal") return options;
623
- return getDefaultMDXOptions2({
624
- ...options,
625
- _withoutBundler: mode === "remote"
626
- });
627
- }
628
- const result = uncached();
629
- mdxOptionsCache.set(mode, result);
630
- return result;
631
- }
632
- };
633
- }
634
-
635
- // src/utils/config.ts
636
- var cache3 = null;
637
- async function compileConfig(configPath, outDir) {
638
- const { build } = await import("esbuild");
639
- const transformed = await build({
640
- entryPoints: [{ in: configPath, out: "source.config" }],
641
- bundle: true,
642
- outdir: outDir,
643
- target: "node20",
644
- write: true,
645
- platform: "node",
646
- format: "esm",
647
- packages: "external",
648
- outExtension: {
649
- ".js": ".mjs"
650
- },
651
- allowOverwrite: true
652
- });
653
- if (transformed.errors.length > 0) {
654
- throw new Error("failed to compile configuration file");
655
- }
656
- }
657
- async function loadConfig(configPath, outDir, hash, build = false) {
658
- if (cache3 && cache3.hash === hash) {
659
- return await cache3.config;
660
- }
661
- if (build) await compileConfig(configPath, outDir);
662
- const url = (0, import_node_url.pathToFileURL)(path4.resolve(outDir, "source.config.mjs"));
663
- const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
664
- return buildConfig(
665
- // every call to `loadConfig` will cause the previous cache to be ignored
666
- loaded
667
- );
668
- });
669
- if (hash) cache3 = { config, hash };
670
- return await config;
671
- }
672
- async function getConfigHash(configPath) {
673
- const stats = await fs3.stat(configPath).catch(() => void 0);
674
- if (stats) {
675
- return stats.mtime.getTime().toString();
713
+ function countLines(s) {
714
+ let num = 0;
715
+ for (const c of s) {
716
+ if (c === "\n") num++;
676
717
  }
677
- throw new Error("Cannot find config file");
718
+ return num;
678
719
  }
679
720
 
680
- // src/loaders/config-loader.ts
721
+ // src/loaders/config/index.ts
722
+ var import_node_path3 = __toESM(require("path"), 1);
681
723
  function dynamicConfig(configPath, outDir) {
682
724
  return {
683
725
  async getConfig(hash) {
684
- return loadConfig(
726
+ const { loadConfig: loadConfig2, getConfigHash: getConfigHash2 } = await Promise.resolve().then(() => (init_load(), load_exports));
727
+ return loadConfig2(
685
728
  configPath,
686
729
  outDir,
687
- hash ?? await getConfigHash(configPath)
730
+ hash ?? await getConfigHash2(configPath)
688
731
  );
689
732
  }
690
733
  };
@@ -694,7 +737,7 @@ function dynamicConfig(configPath, outDir) {
694
737
  var import_node_url2 = require("url");
695
738
  var import_promises2 = __toESM(require("fs/promises"), 1);
696
739
  var import_node_querystring = require("querystring");
697
- var import_node_path3 = __toESM(require("path"), 1);
740
+ var import_node_path4 = __toESM(require("path"), 1);
698
741
  function toWebpack(loader2) {
699
742
  return async function(source, callback) {
700
743
  try {
@@ -711,7 +754,7 @@ function toWebpack(loader2) {
711
754
  return callback(new Error(error.toStringFormatted()));
712
755
  }
713
756
  if (!(error instanceof Error)) throw error;
714
- const fpath = import_node_path3.default.relative(this.context, this.resourcePath);
757
+ const fpath = import_node_path4.default.relative(this.context, this.resourcePath);
715
758
  error.message = `${fpath}:${error.name}: ${error.message}`;
716
759
  callback(error);
717
760
  }
@@ -2,14 +2,14 @@ import {
2
2
  toWebpack
3
3
  } from "./chunk-VXEBLM4X.js";
4
4
  import {
5
- createMdxLoader,
6
- dynamicConfig
7
- } from "./chunk-KGUBBRL6.js";
5
+ createMdxLoader
6
+ } from "./chunk-SP7CHRTS.js";
8
7
  import "./chunk-IQAEAI4P.js";
9
- import "./chunk-POXTQZ4D.js";
10
- import "./chunk-SWNOXPYJ.js";
11
- import "./chunk-KTDVTBMH.js";
12
- import "./chunk-YC25YEBF.js";
8
+ import {
9
+ dynamicConfig
10
+ } from "./chunk-XMFLD5J6.js";
11
+ import "./chunk-QAUWMR5D.js";
12
+ import "./chunk-LMG6UWCL.js";
13
13
  import "./chunk-VWJKRQZR.js";
14
14
 
15
15
  // src/loader-mdx.ts