fumadocs-mdx 13.0.8 → 14.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 (111) hide show
  1. package/dist/bin.cjs +985 -893
  2. package/dist/bin.js +3 -3
  3. package/dist/build-mdx-6UAK5FF5.js +8 -0
  4. package/dist/bun/index.cjs +613 -471
  5. package/dist/bun/index.d.cts +9 -2
  6. package/dist/bun/index.d.ts +9 -2
  7. package/dist/bun/index.js +15 -14
  8. package/dist/chunk-4JSFLXXT.js +8 -0
  9. package/dist/chunk-5OBUOALK.js +141 -0
  10. package/dist/{chunk-2E2JCOSO.js → chunk-6NISOLQ6.js} +16 -44
  11. package/dist/chunk-7UKSZSPY.js +331 -0
  12. package/dist/chunk-BEBCWQC7.js +224 -0
  13. package/dist/chunk-E5DJTSIM.js +86 -0
  14. package/dist/{chunk-K5ZLPEIQ.js → chunk-FBLMK4RS.js} +9 -6
  15. package/dist/chunk-IQGEFL2B.js +17 -0
  16. package/dist/{chunk-5FTSWCB4.js → chunk-K6HCOGOX.js} +9 -11
  17. package/dist/{chunk-QXHN25N3.js → chunk-MTTISKQJ.js} +6 -6
  18. package/dist/{chunk-3J3WL7WN.js → chunk-SLY7WXTX.js} +71 -58
  19. package/dist/chunk-TYJDYTKH.js +85 -0
  20. package/dist/chunk-WBIHDYMN.js +126 -0
  21. package/dist/{chunk-2HXTGJBI.js → chunk-ZY6UZ7NH.js} +22 -19
  22. package/dist/config/index.cjs +79 -71
  23. package/dist/config/index.d.cts +7 -1
  24. package/dist/config/index.d.ts +7 -1
  25. package/dist/config/index.js +5 -5
  26. package/dist/core-B9ZoS6sA.d.ts +341 -0
  27. package/dist/core-DTuP23zu.d.cts +341 -0
  28. package/dist/index-BD8Woo4m.d.cts +8 -0
  29. package/dist/index-CNOvhtOn.d.ts +8 -0
  30. package/dist/index.d.cts +38 -56
  31. package/dist/index.d.ts +38 -56
  32. package/dist/load-from-file-5HUQN36V.js +8 -0
  33. package/dist/next/index.cjs +763 -473
  34. package/dist/next/index.d.cts +16 -1
  35. package/dist/next/index.d.ts +16 -1
  36. package/dist/next/index.js +80 -281
  37. package/dist/node/loader.cjs +764 -627
  38. package/dist/node/loader.js +10 -11
  39. package/dist/plugins/index-file.cjs +495 -0
  40. package/dist/plugins/index-file.d.cts +14 -0
  41. package/dist/plugins/index-file.d.ts +14 -0
  42. package/dist/plugins/index-file.js +8 -0
  43. package/dist/plugins/json-schema.d.cts +9 -2
  44. package/dist/plugins/json-schema.d.ts +9 -2
  45. package/dist/plugins/last-modified.cjs +110 -0
  46. package/dist/plugins/last-modified.d.cts +37 -0
  47. package/dist/plugins/last-modified.d.ts +37 -0
  48. package/dist/plugins/last-modified.js +74 -0
  49. package/dist/runtime/browser.cjs +93 -0
  50. package/dist/runtime/browser.d.cts +53 -0
  51. package/dist/runtime/browser.d.ts +53 -0
  52. package/dist/runtime/browser.js +67 -0
  53. package/dist/runtime/dynamic.cjs +1023 -0
  54. package/dist/runtime/dynamic.d.cts +27 -0
  55. package/dist/runtime/dynamic.d.ts +27 -0
  56. package/dist/runtime/dynamic.js +79 -0
  57. package/dist/runtime/server.cjs +176 -0
  58. package/dist/runtime/server.d.cts +14 -0
  59. package/dist/runtime/server.d.ts +14 -0
  60. package/dist/runtime/server.js +8 -0
  61. package/dist/runtime/types.cjs +18 -0
  62. package/dist/runtime/types.d.cts +61 -0
  63. package/dist/runtime/types.d.ts +61 -0
  64. package/dist/runtime/types.js +0 -0
  65. package/dist/vite/index.cjs +984 -621
  66. package/dist/vite/index.d.cts +17 -22
  67. package/dist/vite/index.d.ts +17 -22
  68. package/dist/vite/index.js +32 -222
  69. package/dist/webpack/mdx.cjs +647 -514
  70. package/dist/webpack/mdx.d.cts +15 -1
  71. package/dist/webpack/mdx.d.ts +15 -1
  72. package/dist/webpack/mdx.js +12 -17
  73. package/dist/webpack/meta.cjs +360 -231
  74. package/dist/webpack/meta.d.cts +15 -1
  75. package/dist/webpack/meta.d.ts +15 -1
  76. package/dist/webpack/meta.js +13 -15
  77. package/package.json +15 -32
  78. package/dist/build-mdx-BjXOmv0b.d.cts +0 -53
  79. package/dist/build-mdx-CY5UldCO.d.ts +0 -53
  80. package/dist/chunk-2AQRQXSO.js +0 -119
  81. package/dist/chunk-CXA4JO4Z.js +0 -45
  82. package/dist/chunk-DMJ6I4C3.js +0 -76
  83. package/dist/chunk-FSZMKRVH.js +0 -80
  84. package/dist/chunk-II3H5ZVZ.js +0 -77
  85. package/dist/chunk-KILFIBVW.js +0 -75
  86. package/dist/chunk-NVRDCY6Z.js +0 -30
  87. package/dist/chunk-VUEZTR2H.js +0 -26
  88. package/dist/core-DB7TdlyC.d.cts +0 -234
  89. package/dist/core-DB7TdlyC.d.ts +0 -234
  90. package/dist/index-D7s7kCc2.d.cts +0 -7
  91. package/dist/index-D7s7kCc2.d.ts +0 -7
  92. package/dist/load-from-file-AVYOFOI7.js +0 -7
  93. package/dist/preset-ZMP6U62C.js +0 -6
  94. package/dist/runtime/next/async.cjs +0 -760
  95. package/dist/runtime/next/async.d.cts +0 -19
  96. package/dist/runtime/next/async.d.ts +0 -19
  97. package/dist/runtime/next/async.js +0 -86
  98. package/dist/runtime/next/index.cjs +0 -136
  99. package/dist/runtime/next/index.d.cts +0 -33
  100. package/dist/runtime/next/index.d.ts +0 -33
  101. package/dist/runtime/next/index.js +0 -11
  102. package/dist/runtime/vite/browser.cjs +0 -107
  103. package/dist/runtime/vite/browser.d.cts +0 -59
  104. package/dist/runtime/vite/browser.d.ts +0 -59
  105. package/dist/runtime/vite/browser.js +0 -11
  106. package/dist/runtime/vite/server.cjs +0 -243
  107. package/dist/runtime/vite/server.d.cts +0 -30
  108. package/dist/runtime/vite/server.d.ts +0 -30
  109. package/dist/runtime/vite/server.js +0 -111
  110. package/dist/types-Bnh9n7mj.d.cts +0 -45
  111. package/dist/types-ey1AZqrg.d.ts +0 -45
@@ -0,0 +1,224 @@
1
+ import {
2
+ ident
3
+ } from "./chunk-WBIHDYMN.js";
4
+
5
+ // src/utils/validation.ts
6
+ var ValidationError = class extends Error {
7
+ constructor(message, issues) {
8
+ super(
9
+ `${message}:
10
+ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
11
+ );
12
+ this.title = message;
13
+ this.issues = issues;
14
+ }
15
+ async toStringFormatted() {
16
+ const picocolors = await import("picocolors");
17
+ return [
18
+ picocolors.bold(`[MDX] ${this.title}:`),
19
+ ...this.issues.map(
20
+ (issue) => picocolors.redBright(
21
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
22
+ )
23
+ )
24
+ ].join("\n");
25
+ }
26
+ };
27
+ async function validate(schema, data, context, errorMessage) {
28
+ if (typeof schema === "function" && !("~standard" in schema)) {
29
+ schema = schema(context);
30
+ }
31
+ if ("~standard" in schema) {
32
+ const result = await schema["~standard"].validate(
33
+ data
34
+ );
35
+ if (result.issues) {
36
+ throw new ValidationError(errorMessage, result.issues);
37
+ }
38
+ return result.value;
39
+ }
40
+ return data;
41
+ }
42
+
43
+ // src/core.ts
44
+ import path from "path";
45
+ import fs from "fs/promises";
46
+ var _Defaults = {
47
+ configPath: "source.config.ts",
48
+ outDir: ".source"
49
+ };
50
+ async function getPlugins(pluginOptions) {
51
+ const plugins = [];
52
+ for await (const option of pluginOptions) {
53
+ if (!option) continue;
54
+ if (Array.isArray(option)) plugins.push(...await getPlugins(option));
55
+ else plugins.push(option);
56
+ }
57
+ return plugins;
58
+ }
59
+ function createCore(options, defaultPlugins = []) {
60
+ let config;
61
+ let plugins;
62
+ async function transformMetadata({
63
+ collection,
64
+ filePath,
65
+ source
66
+ }, data) {
67
+ if (collection.schema) {
68
+ data = await validate(
69
+ collection.schema,
70
+ data,
71
+ { path: filePath, source },
72
+ collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
73
+ );
74
+ }
75
+ return data;
76
+ }
77
+ const core = {
78
+ /**
79
+ * Convenient cache store, reset when config changes
80
+ */
81
+ cache: /* @__PURE__ */ new Map(),
82
+ async init({ config: newConfig }) {
83
+ config = await newConfig;
84
+ this.cache.clear();
85
+ plugins = await getPlugins([
86
+ postprocessPlugin(),
87
+ ...defaultPlugins,
88
+ ...config.global.plugins ?? []
89
+ ]);
90
+ for (const plugin of plugins) {
91
+ const out = await plugin.config?.call(pluginContext, config);
92
+ if (out) config = out;
93
+ }
94
+ },
95
+ getOptions() {
96
+ return options;
97
+ },
98
+ getConfig() {
99
+ return config;
100
+ },
101
+ /**
102
+ * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
103
+ */
104
+ getCompiledConfigPath() {
105
+ return path.join(options.outDir, "source.config.mjs");
106
+ },
107
+ getPlugins() {
108
+ return plugins;
109
+ },
110
+ getPluginContext() {
111
+ return pluginContext;
112
+ },
113
+ async initServer(server) {
114
+ for (const plugin of plugins) {
115
+ await plugin.configureServer?.call(pluginContext, server);
116
+ }
117
+ },
118
+ async emit({ filterPlugin = () => true } = {}) {
119
+ return (await Promise.all(
120
+ plugins.map((plugin) => {
121
+ if (!filterPlugin(plugin) || !plugin.emit) return [];
122
+ return plugin.emit.call(pluginContext);
123
+ })
124
+ )).flat();
125
+ },
126
+ async emitAndWrite(emitOptions) {
127
+ const start = performance.now();
128
+ const out = await this.emit(emitOptions);
129
+ await Promise.all(
130
+ out.map(async (entry) => {
131
+ const file = path.join(options.outDir, entry.path);
132
+ await fs.mkdir(path.dirname(file), { recursive: true });
133
+ await fs.writeFile(file, entry.content);
134
+ })
135
+ );
136
+ console.log(`[MDX] generated files in ${performance.now() - start}ms`);
137
+ },
138
+ async transformMeta(options2, data) {
139
+ const ctx = {
140
+ ...pluginContext,
141
+ ...options2
142
+ };
143
+ data = await transformMetadata(options2, data);
144
+ for (const plugin of plugins) {
145
+ if (plugin.meta?.transform)
146
+ data = await plugin.meta.transform.call(ctx, data) ?? data;
147
+ }
148
+ return data;
149
+ },
150
+ async transformFrontmatter(options2, data) {
151
+ const ctx = {
152
+ ...pluginContext,
153
+ ...options2
154
+ };
155
+ data = await transformMetadata(options2, data);
156
+ for (const plugin of plugins) {
157
+ if (plugin.doc?.frontmatter)
158
+ data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
159
+ }
160
+ return data;
161
+ },
162
+ async transformVFile(options2, file) {
163
+ const ctx = {
164
+ ...pluginContext,
165
+ ...options2
166
+ };
167
+ for (const plugin of plugins) {
168
+ if (plugin.doc?.vfile)
169
+ file = await plugin.doc.vfile.call(ctx, file) ?? file;
170
+ }
171
+ return file;
172
+ }
173
+ };
174
+ const pluginContext = {
175
+ core,
176
+ ...options
177
+ };
178
+ return core;
179
+ }
180
+ function postprocessPlugin() {
181
+ const LinkReferenceTypes = `{
182
+ /**
183
+ * extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
184
+ */
185
+ extractedReferences?: import('fumadocs-mdx').ExtractedReference[];
186
+ }`;
187
+ return {
188
+ "index-file": {
189
+ generateTypeConfig() {
190
+ const lines = [];
191
+ lines.push("{");
192
+ lines.push(" DocData: {");
193
+ for (const collection of this.core.getConfig().collectionList) {
194
+ let postprocessOptions;
195
+ switch (collection.type) {
196
+ case "doc":
197
+ postprocessOptions = collection.postprocess;
198
+ break;
199
+ case "docs":
200
+ postprocessOptions = collection.docs.postprocess;
201
+ break;
202
+ }
203
+ if (postprocessOptions?.extractLinkReferences) {
204
+ lines.push(ident(`${collection.name}: ${LinkReferenceTypes},`, 2));
205
+ }
206
+ }
207
+ lines.push(" }");
208
+ lines.push("}");
209
+ return lines.join("\n");
210
+ },
211
+ serverOptions(options) {
212
+ options.doc ??= {};
213
+ options.doc.passthroughs ??= [];
214
+ options.doc.passthroughs.push("extractedReferences");
215
+ }
216
+ }
217
+ };
218
+ }
219
+
220
+ export {
221
+ ValidationError,
222
+ _Defaults,
223
+ createCore
224
+ };
@@ -0,0 +1,86 @@
1
+ // src/config/preset.ts
2
+ function pluginOption(def, options = []) {
3
+ const list = def(Array.isArray(options) ? options : []).filter(
4
+ Boolean
5
+ );
6
+ if (typeof options === "function") {
7
+ return options(list);
8
+ }
9
+ return list;
10
+ }
11
+ function applyMdxPreset(options = {}) {
12
+ return async (environment = "bundler") => {
13
+ if (options.preset === "minimal") return options;
14
+ const plugins = await import("fumadocs-core/mdx-plugins");
15
+ const {
16
+ valueToExport = [],
17
+ rehypeCodeOptions,
18
+ remarkImageOptions,
19
+ remarkHeadingOptions,
20
+ remarkStructureOptions,
21
+ remarkCodeTabOptions,
22
+ remarkNpmOptions,
23
+ ...mdxOptions
24
+ } = options;
25
+ const remarkPlugins = pluginOption(
26
+ (v) => [
27
+ plugins.remarkGfm,
28
+ [
29
+ plugins.remarkHeading,
30
+ {
31
+ generateToc: false,
32
+ ...remarkHeadingOptions
33
+ }
34
+ ],
35
+ remarkImageOptions !== false && [
36
+ plugins.remarkImage,
37
+ {
38
+ ...remarkImageOptions,
39
+ useImport: remarkImageOptions?.useImport ?? environment === "bundler"
40
+ }
41
+ ],
42
+ "remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
43
+ plugins.remarkCodeTab,
44
+ remarkCodeTabOptions
45
+ ],
46
+ "remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
47
+ ...v,
48
+ remarkStructureOptions !== false && [
49
+ plugins.remarkStructure,
50
+ remarkStructureOptions
51
+ ],
52
+ valueToExport.length > 0 && (() => {
53
+ return (_, file) => {
54
+ file.data["mdx-export"] ??= [];
55
+ for (const name of valueToExport) {
56
+ if (!(name in file.data)) continue;
57
+ file.data["mdx-export"].push({
58
+ name,
59
+ value: file.data[name]
60
+ });
61
+ }
62
+ };
63
+ })
64
+ ],
65
+ mdxOptions.remarkPlugins
66
+ );
67
+ const rehypePlugins = pluginOption(
68
+ (v) => [
69
+ rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
70
+ ...v,
71
+ plugins.rehypeToc
72
+ ],
73
+ mdxOptions.rehypePlugins
74
+ );
75
+ return {
76
+ ...mdxOptions,
77
+ outputFormat: environment === "runtime" ? "function-body" : mdxOptions.outputFormat,
78
+ remarkPlugins,
79
+ rehypePlugins
80
+ };
81
+ };
82
+ }
83
+
84
+ export {
85
+ applyMdxPreset
86
+ };
@@ -53,6 +53,14 @@ function remarkMarkAndUnravel() {
53
53
  };
54
54
  }
55
55
 
56
+ // src/loaders/mdx/mdast-utils.ts
57
+ function flattenNode(node) {
58
+ if ("children" in node)
59
+ return node.children.map((child) => flattenNode(child)).join("");
60
+ if ("value" in node) return node.value;
61
+ return "";
62
+ }
63
+
56
64
  // src/loaders/mdx/remark-include.ts
57
65
  var ElementLikeTypes = [
58
66
  "mdxJsxFlowElement",
@@ -76,12 +84,6 @@ function parseElementAttributes(element) {
76
84
  }
77
85
  return element.attributes ?? {};
78
86
  }
79
- function flattenNode(node) {
80
- if ("children" in node)
81
- return node.children.map((child) => flattenNode(child)).join("");
82
- if ("value" in node) return node.value;
83
- return "";
84
- }
85
87
  function parseSpecifier(specifier) {
86
88
  const idx = specifier.lastIndexOf("#");
87
89
  if (idx === -1) return { file: specifier };
@@ -203,5 +205,6 @@ ${e instanceof Error ? e.message : String(e)}`,
203
205
  }
204
206
 
205
207
  export {
208
+ flattenNode,
206
209
  remarkInclude
207
210
  };
@@ -0,0 +1,17 @@
1
+ import {
2
+ createCore
3
+ } from "./chunk-BEBCWQC7.js";
4
+
5
+ // src/webpack/index.ts
6
+ var core;
7
+ function getCore(options) {
8
+ return core ??= createCore({
9
+ environment: "webpack",
10
+ outDir: options.outDir,
11
+ configPath: options.configPath
12
+ });
13
+ }
14
+
15
+ export {
16
+ getCore
17
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ValidationError
3
- } from "./chunk-2AQRQXSO.js";
3
+ } from "./chunk-BEBCWQC7.js";
4
4
 
5
5
  // src/loaders/adapter.ts
6
6
  import { fileURLToPath } from "url";
@@ -83,7 +83,7 @@ function toWebpack(loader) {
83
83
  }
84
84
  } catch (error) {
85
85
  if (error instanceof ValidationError) {
86
- return callback(new Error(error.toStringFormatted()));
86
+ return callback(new Error(await error.toStringFormatted()));
87
87
  }
88
88
  if (!(error instanceof Error)) throw error;
89
89
  const fpath = path.relative(this.context, this.resourcePath);
@@ -115,8 +115,8 @@ function toBun(loader) {
115
115
  }
116
116
  }
117
117
  };
118
- if (loader.bun?.loadSync) {
119
- return loader.bun.loadSync(readFileSync(filePath).toString(), input);
118
+ if (loader.bun?.load) {
119
+ return loader.bun.load(readFileSync(filePath).toString(), input);
120
120
  }
121
121
  const result = loader.load(input);
122
122
  if (result instanceof Promise) {
@@ -137,23 +137,20 @@ function createStandaloneConfigLoader({
137
137
  let loaded;
138
138
  async function getConfigHash() {
139
139
  if (mode === "production") return "static";
140
- const stats = await fs2.stat(core._options.configPath).catch(() => {
140
+ const stats = await fs2.stat(core.getOptions().configPath).catch(() => {
141
141
  throw new Error("Cannot find config file");
142
142
  });
143
143
  return stats.mtime.getTime().toString();
144
144
  }
145
145
  async function newConfig() {
146
- const { loadConfig } = await import("./load-from-file-AVYOFOI7.js");
146
+ const { loadConfig } = await import("./load-from-file-5HUQN36V.js");
147
147
  await core.init({
148
- config: loadConfig(
149
- core._options.configPath,
150
- core._options.outDir,
151
- buildConfig
152
- )
148
+ config: loadConfig(core, buildConfig)
153
149
  });
154
150
  return core.getConfig();
155
151
  }
156
152
  return {
153
+ core,
157
154
  async getConfig() {
158
155
  const hash = await getConfigHash();
159
156
  if (loaded && loaded.hash === hash) return loaded.config;
@@ -167,6 +164,7 @@ function createStandaloneConfigLoader({
167
164
  }
168
165
  function createIntegratedConfigLoader(core) {
169
166
  return {
167
+ core,
170
168
  getConfig() {
171
169
  return core.getConfig();
172
170
  }
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  buildConfig
3
- } from "./chunk-2HXTGJBI.js";
3
+ } from "./chunk-ZY6UZ7NH.js";
4
4
 
5
5
  // src/config/load-from-file.ts
6
- import * as path from "path";
7
6
  import { pathToFileURL } from "url";
8
- async function compileConfig(configPath, outDir) {
7
+ async function compileConfig(core) {
9
8
  const { build } = await import("esbuild");
9
+ const { configPath, outDir } = core.getOptions();
10
10
  const transformed = await build({
11
11
  entryPoints: [{ in: configPath, out: "source.config" }],
12
12
  bundle: true,
@@ -25,9 +25,9 @@ async function compileConfig(configPath, outDir) {
25
25
  throw new Error("failed to compile configuration file");
26
26
  }
27
27
  }
28
- async function loadConfig(configPath, outDir, build = false) {
29
- if (build) await compileConfig(configPath, outDir);
30
- const url = pathToFileURL(path.resolve(outDir, "source.config.mjs"));
28
+ async function loadConfig(core, build = false) {
29
+ if (build) await compileConfig(core);
30
+ const url = pathToFileURL(core.getCompiledConfigPath());
31
31
  url.searchParams.set("hash", Date.now().toString());
32
32
  const config = import(url.href).then(
33
33
  (loaded) => buildConfig(loaded)
@@ -1,9 +1,11 @@
1
1
  import {
2
+ flattenNode,
2
3
  remarkInclude
3
- } from "./chunk-K5ZLPEIQ.js";
4
+ } from "./chunk-FBLMK4RS.js";
4
5
 
5
6
  // src/loaders/mdx/build-mdx.ts
6
7
  import { createProcessor } from "@mdx-js/mdx";
8
+ import { VFile } from "vfile";
7
9
 
8
10
  // src/loaders/mdx/remark-postprocess.ts
9
11
  import { visit } from "unist-util-visit";
@@ -15,48 +17,66 @@ function remarkPostprocess({
15
17
  _format,
16
18
  includeProcessedMarkdown = false,
17
19
  includeMDAST = false,
20
+ extractLinkReferences = false,
18
21
  valueToExport = []
19
22
  }) {
20
23
  let _stringifyProcessor;
21
24
  const getStringifyProcessor = () => {
22
- if (_format === "mdx") return this;
23
- return _stringifyProcessor ??= this().use(remarkMdx).freeze();
25
+ return _stringifyProcessor ??= _format === "mdx" ? this : (
26
+ // force Markdown processor to stringify MDX nodes
27
+ this().use(remarkMdx).freeze()
28
+ );
24
29
  };
25
30
  return (tree, file) => {
26
- let title;
27
- const urls = [];
28
- visit(tree, ["heading", "link"], (node) => {
29
- if (node.type === "heading" && node.depth === 1) {
30
- title = flattenNode(node);
31
- }
32
- if (node.type !== "link") return;
33
- urls.push({
34
- href: node.url
31
+ const frontmatter = file.data.frontmatter ??= {};
32
+ if (!frontmatter.title) {
33
+ visit(tree, "heading", (node) => {
34
+ if (node.depth === 1) {
35
+ frontmatter.title = flattenNode(node);
36
+ return false;
37
+ }
38
+ });
39
+ }
40
+ file.data["mdx-export"] ??= [];
41
+ if (extractLinkReferences) {
42
+ const urls = [];
43
+ visit(tree, "link", (node) => {
44
+ urls.push({
45
+ href: node.url
46
+ });
47
+ return "skip";
48
+ });
49
+ file.data["mdx-export"].push({
50
+ name: "extractedReferences",
51
+ value: urls
35
52
  });
36
- return "skip";
37
- });
38
- if (title) {
39
- file.data.frontmatter ??= {};
40
- if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
41
53
  }
42
- file.data.extractedReferences = urls;
43
54
  if (includeProcessedMarkdown) {
44
55
  const processor = getStringifyProcessor();
45
- file.data._markdown = toMarkdown(tree, {
56
+ const markdown = toMarkdown(tree, {
46
57
  ...processor.data("settings"),
47
58
  // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
48
59
  extensions: processor.data("toMarkdownExtensions") || []
49
60
  });
61
+ file.data["mdx-export"].push({
62
+ name: "_markdown",
63
+ value: markdown
64
+ });
50
65
  }
51
66
  if (includeMDAST) {
52
67
  const options = includeMDAST === true ? {} : includeMDAST;
53
- file.data._mdast = JSON.stringify(
68
+ const mdast = JSON.stringify(
54
69
  options.removePosition ? removePosition(structuredClone(tree)) : tree
55
70
  );
71
+ file.data["mdx-export"].push({
72
+ name: "_mdast",
73
+ value: mdast
74
+ });
56
75
  }
57
- for (const { name, value } of file.data["mdx-export"] ?? []) {
76
+ for (const { name, value } of file.data["mdx-export"]) {
58
77
  tree.children.unshift(getMdastExport(name, value));
59
78
  }
79
+ file.data["mdx-export"] = [];
60
80
  for (const name of valueToExport) {
61
81
  if (!(name in file.data)) continue;
62
82
  tree.children.unshift(getMdastExport(name, file.data[name]));
@@ -97,43 +117,39 @@ function getMdastExport(name, value) {
97
117
  }
98
118
  };
99
119
  }
100
- function flattenNode(node) {
101
- if ("children" in node)
102
- return node.children.map((child) => flattenNode(child)).join("");
103
- if ("value" in node) return node.value;
104
- return "";
105
- }
106
120
 
107
121
  // src/loaders/mdx/build-mdx.ts
108
- var cache = /* @__PURE__ */ new Map();
109
- async function buildMDX(cacheKey, source, options) {
110
- const { filePath, frontmatter, data, _compiler, ...rest } = options;
122
+ async function buildMDX(core, collection, {
123
+ filePath,
124
+ frontmatter,
125
+ source,
126
+ _compiler,
127
+ environment,
128
+ isDevelopment
129
+ }) {
130
+ const mdxOptions = await core.getConfig().getMDXOptions(collection, environment);
111
131
  function getProcessor(format) {
112
- const key = `${cacheKey}:${format}`;
132
+ const cache = core.cache;
133
+ const key = `build-mdx:${collection?.name ?? "global"}:${format}`;
113
134
  let processor = cache.get(key);
114
135
  if (!processor) {
136
+ const postprocessOptions = {
137
+ _format: format,
138
+ ...collection?.postprocess,
139
+ valueToExport: [
140
+ ...collection?.postprocess?.valueToExport ?? [],
141
+ "structuredData",
142
+ "frontmatter"
143
+ ]
144
+ };
115
145
  processor = createProcessor({
116
146
  outputFormat: "program",
117
- ...rest,
147
+ development: isDevelopment,
148
+ ...mdxOptions,
118
149
  remarkPlugins: [
119
150
  remarkInclude,
120
- ...rest.remarkPlugins ?? [],
121
- [
122
- remarkPostprocess,
123
- {
124
- _format: format,
125
- ...options.postprocess,
126
- valueToExport: [
127
- ...options.postprocess?.valueToExport ?? [],
128
- "structuredData",
129
- "extractedReferences",
130
- "frontmatter",
131
- "lastModified",
132
- "_markdown",
133
- "_mdast"
134
- ]
135
- }
136
- ]
151
+ ...mdxOptions.remarkPlugins ?? [],
152
+ [remarkPostprocess, postprocessOptions]
137
153
  ],
138
154
  format
139
155
  });
@@ -141,18 +157,15 @@ async function buildMDX(cacheKey, source, options) {
141
157
  }
142
158
  return processor;
143
159
  }
144
- return getProcessor(
145
- options.format ?? (filePath.endsWith(".mdx") ? "mdx" : "md")
146
- ).process({
160
+ let vfile = new VFile({
147
161
  value: source,
148
162
  path: filePath,
149
- data: {
150
- ...data,
151
- frontmatter,
152
- _compiler,
153
- _getProcessor: getProcessor
154
- }
163
+ data: { frontmatter, _compiler, _getProcessor: getProcessor }
155
164
  });
165
+ if (collection) {
166
+ vfile = await core.transformVFile({ collection, filePath, source }, vfile);
167
+ }
168
+ return getProcessor(filePath.endsWith(".mdx") ? "mdx" : "md").process(vfile);
156
169
  }
157
170
 
158
171
  export {