fumadocs-mdx 13.0.8 → 14.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 (104) hide show
  1. package/dist/bin.cjs +924 -901
  2. package/dist/bin.js +3 -3
  3. package/dist/build-mdx-6UAK5FF5.js +8 -0
  4. package/dist/bun/index.cjs +578 -471
  5. package/dist/bun/index.d.cts +3 -2
  6. package/dist/bun/index.d.ts +3 -2
  7. package/dist/bun/index.js +12 -12
  8. package/dist/chunk-4JSFLXXT.js +8 -0
  9. package/dist/chunk-5UMZCWKV.js +17 -0
  10. package/dist/chunk-5YXP7JLN.js +138 -0
  11. package/dist/{chunk-2E2JCOSO.js → chunk-6NISOLQ6.js} +16 -44
  12. package/dist/chunk-7L2KNF6B.js +180 -0
  13. package/dist/chunk-E5DJTSIM.js +86 -0
  14. package/dist/{chunk-K5ZLPEIQ.js → chunk-FBLMK4RS.js} +9 -6
  15. package/dist/{chunk-QXHN25N3.js → chunk-OXSRIWQW.js} +7 -8
  16. package/dist/chunk-PKI7ZDA5.js +29 -0
  17. package/dist/{chunk-3J3WL7WN.js → chunk-SLY7WXTX.js} +71 -58
  18. package/dist/{chunk-5FTSWCB4.js → chunk-SRSRFOVI.js} +8 -10
  19. package/dist/chunk-TYJDYTKH.js +85 -0
  20. package/dist/chunk-XHJCLBZ4.js +406 -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 +2 -1
  24. package/dist/config/index.d.ts +2 -1
  25. package/dist/config/index.js +5 -5
  26. package/dist/index-BlVBvy-z.d.ts +8 -0
  27. package/dist/{core-DB7TdlyC.d.cts → index-D7JdSMpp.d.cts} +99 -61
  28. package/dist/{core-DB7TdlyC.d.ts → index-D7JdSMpp.d.ts} +99 -61
  29. package/dist/index-P2NNUkHn.d.cts +8 -0
  30. package/dist/index.d.cts +3 -74
  31. package/dist/index.d.ts +3 -74
  32. package/dist/load-from-file-I3ALLIVB.js +8 -0
  33. package/dist/next/index.cjs +698 -476
  34. package/dist/next/index.d.cts +11 -1
  35. package/dist/next/index.d.ts +11 -1
  36. package/dist/next/index.js +78 -281
  37. package/dist/node/loader.cjs +704 -602
  38. package/dist/node/loader.js +10 -11
  39. package/dist/plugins/index-file.cjs +471 -0
  40. package/dist/plugins/index-file.d.cts +29 -0
  41. package/dist/plugins/index-file.d.ts +29 -0
  42. package/dist/plugins/index-file.js +8 -0
  43. package/dist/plugins/json-schema.d.cts +3 -2
  44. package/dist/plugins/json-schema.d.ts +3 -2
  45. package/dist/plugins/last-modified.cjs +75 -0
  46. package/dist/plugins/last-modified.d.cts +27 -0
  47. package/dist/plugins/last-modified.d.ts +27 -0
  48. package/dist/plugins/last-modified.js +44 -0
  49. package/dist/runtime/{vite/browser.cjs → browser.cjs} +40 -53
  50. package/dist/runtime/browser.d.cts +50 -0
  51. package/dist/runtime/browser.d.ts +50 -0
  52. package/dist/runtime/browser.js +68 -0
  53. package/dist/runtime/dynamic.cjs +985 -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 +78 -0
  57. package/dist/runtime/server.cjs +173 -0
  58. package/dist/runtime/server.d.cts +161 -0
  59. package/dist/runtime/server.d.ts +161 -0
  60. package/dist/runtime/server.js +8 -0
  61. package/dist/vite/index.cjs +934 -638
  62. package/dist/vite/index.d.cts +12 -22
  63. package/dist/vite/index.d.ts +12 -22
  64. package/dist/vite/index.js +30 -221
  65. package/dist/webpack/mdx.cjs +613 -515
  66. package/dist/webpack/mdx.d.cts +9 -1
  67. package/dist/webpack/mdx.d.ts +9 -1
  68. package/dist/webpack/mdx.js +12 -17
  69. package/dist/webpack/meta.cjs +327 -233
  70. package/dist/webpack/meta.d.cts +9 -1
  71. package/dist/webpack/meta.d.ts +9 -1
  72. package/dist/webpack/meta.js +13 -15
  73. package/package.json +15 -32
  74. package/dist/build-mdx-BjXOmv0b.d.cts +0 -53
  75. package/dist/build-mdx-CY5UldCO.d.ts +0 -53
  76. package/dist/chunk-2AQRQXSO.js +0 -119
  77. package/dist/chunk-CXA4JO4Z.js +0 -45
  78. package/dist/chunk-DMJ6I4C3.js +0 -76
  79. package/dist/chunk-FSZMKRVH.js +0 -80
  80. package/dist/chunk-II3H5ZVZ.js +0 -77
  81. package/dist/chunk-KILFIBVW.js +0 -75
  82. package/dist/chunk-NVRDCY6Z.js +0 -30
  83. package/dist/chunk-VUEZTR2H.js +0 -26
  84. package/dist/index-D7s7kCc2.d.cts +0 -7
  85. package/dist/index-D7s7kCc2.d.ts +0 -7
  86. package/dist/load-from-file-AVYOFOI7.js +0 -7
  87. package/dist/preset-ZMP6U62C.js +0 -6
  88. package/dist/runtime/next/async.cjs +0 -760
  89. package/dist/runtime/next/async.d.cts +0 -19
  90. package/dist/runtime/next/async.d.ts +0 -19
  91. package/dist/runtime/next/async.js +0 -86
  92. package/dist/runtime/next/index.cjs +0 -136
  93. package/dist/runtime/next/index.d.cts +0 -33
  94. package/dist/runtime/next/index.d.ts +0 -33
  95. package/dist/runtime/next/index.js +0 -11
  96. package/dist/runtime/vite/browser.d.cts +0 -59
  97. package/dist/runtime/vite/browser.d.ts +0 -59
  98. package/dist/runtime/vite/browser.js +0 -11
  99. package/dist/runtime/vite/server.cjs +0 -243
  100. package/dist/runtime/vite/server.d.cts +0 -30
  101. package/dist/runtime/vite/server.d.ts +0 -30
  102. package/dist/runtime/vite/server.js +0 -111
  103. package/dist/types-Bnh9n7mj.d.cts +0 -45
  104. package/dist/types-ey1AZqrg.d.ts +0 -45
@@ -30,320 +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/loaders/mdx/preset.ts
34
- var preset_exports = {};
35
- __export(preset_exports, {
36
- getDefaultMDXOptions: () => getDefaultMDXOptions
37
- });
38
- function pluginOption(def, options = []) {
39
- const list = def(Array.isArray(options) ? options : []).filter(
40
- Boolean
41
- );
42
- if (typeof options === "function") {
43
- return options(list);
44
- }
45
- return list;
46
- }
47
- function getDefaultMDXOptions({
48
- valueToExport = [],
49
- rehypeCodeOptions,
50
- remarkImageOptions,
51
- remarkHeadingOptions,
52
- remarkStructureOptions,
53
- remarkCodeTabOptions,
54
- remarkNpmOptions,
55
- _withoutBundler = false,
56
- ...mdxOptions
57
- }) {
58
- const remarkPlugins = pluginOption(
59
- (v) => [
60
- plugins.remarkGfm,
61
- [
62
- plugins.remarkHeading,
63
- {
64
- generateToc: false,
65
- ...remarkHeadingOptions
66
- }
67
- ],
68
- remarkImageOptions !== false && [
69
- plugins.remarkImage,
70
- {
71
- ...remarkImageOptions,
72
- useImport: _withoutBundler ? false : remarkImageOptions?.useImport
73
- }
74
- ],
75
- "remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
76
- plugins.remarkCodeTab,
77
- remarkCodeTabOptions
78
- ],
79
- "remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
80
- ...v,
81
- remarkStructureOptions !== false && [
82
- plugins.remarkStructure,
83
- remarkStructureOptions
84
- ],
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
- }
94
- ],
95
- mdxOptions.remarkPlugins
96
- );
97
- const rehypePlugins = pluginOption(
98
- (v) => [
99
- rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
100
- ...v,
101
- plugins.rehypeToc
102
- ],
103
- mdxOptions.rehypePlugins
104
- );
105
- return {
106
- ...mdxOptions,
107
- outputFormat: _withoutBundler ? "function-body" : mdxOptions.outputFormat,
108
- remarkPlugins,
109
- rehypePlugins
110
- };
111
- }
112
- var plugins;
113
- var init_preset = __esm({
114
- "src/loaders/mdx/preset.ts"() {
115
- "use strict";
116
- plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
117
- }
118
- });
119
-
120
- // src/config/build.ts
121
- function buildCollection(name, config) {
122
- if (config.type === "docs") {
123
- return {
124
- ...config,
125
- name,
126
- meta: buildPrimitiveCollection(name, config.meta),
127
- docs: buildPrimitiveCollection(name, config.docs)
128
- };
129
- }
130
- return buildPrimitiveCollection(name, config);
131
- }
132
- function buildPrimitiveCollection(name, { files, ...config }) {
133
- const supportedFormats = SupportedFormats[config.type];
134
- const patterns = files ?? [`**/*.{${supportedFormats.join(",")}}`];
135
- let matchers;
136
- return {
137
- ...config,
138
- name,
139
- patterns,
140
- isFileSupported(filePath) {
141
- return supportedFormats.some((format) => filePath.endsWith(`.${format}`));
142
- },
143
- hasFile(filePath) {
144
- matchers ??= (Array.isArray(config.dir) ? config.dir : [config.dir]).map(
145
- (dir) => (0, import_picomatch.default)(patterns, {
146
- cwd: dir
147
- })
148
- );
149
- return this.isFileSupported(filePath) && matchers.some((matcher) => matcher(filePath));
150
- }
151
- };
152
- }
153
- function buildConfig(config) {
154
- const collections = /* @__PURE__ */ new Map();
155
- const loaded = {};
156
- for (const [k, v] of Object.entries(config)) {
157
- if (!v) {
158
- continue;
159
- }
160
- if (typeof v === "object" && "type" in v) {
161
- if (v.type === "docs") {
162
- collections.set(k, buildCollection(k, v));
163
- continue;
164
- }
165
- if (v.type === "doc" || v.type === "meta") {
166
- collections.set(
167
- k,
168
- buildCollection(k, v)
169
- );
170
- continue;
171
- }
172
- }
173
- if (k === "default" && v) {
174
- Object.assign(loaded, v);
175
- continue;
176
- }
177
- throw new Error(
178
- `Unknown export "${k}", you can only export collections from source configuration file.`
179
- );
180
- }
181
- if (loaded.collections) {
182
- for (const [k, v] of Object.entries(loaded.collections)) {
183
- collections.set(k, buildCollection(k, v));
184
- }
185
- }
186
- const mdxOptionsCache = /* @__PURE__ */ new Map();
187
- return {
188
- global: loaded,
189
- collectionList: Array.from(collections.values()),
190
- getCollection(name) {
191
- return collections.get(name);
192
- },
193
- async getDefaultMDXOptions(mode = "default") {
194
- const cached = mdxOptionsCache.get(mode);
195
- if (cached) return cached;
196
- const input = this.global.mdxOptions;
197
- async function uncached() {
198
- const options = typeof input === "function" ? await input() : input;
199
- const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_preset(), preset_exports));
200
- if (options?.preset === "minimal") return options;
201
- return getDefaultMDXOptions2({
202
- ...options,
203
- _withoutBundler: mode === "remote"
204
- });
205
- }
206
- const result = uncached();
207
- mdxOptionsCache.set(mode, result);
208
- return result;
209
- }
210
- };
211
- }
212
- var import_picomatch, SupportedFormats;
213
- var init_build = __esm({
214
- "src/config/build.ts"() {
215
- "use strict";
216
- import_picomatch = __toESM(require("picomatch"), 1);
217
- SupportedFormats = {
218
- doc: ["mdx", "md"],
219
- meta: ["json", "yaml"]
220
- };
221
- }
222
- });
223
-
224
- // src/config/load-from-file.ts
225
- var load_from_file_exports = {};
226
- __export(load_from_file_exports, {
227
- loadConfig: () => loadConfig
228
- });
229
- async function compileConfig(configPath, outDir) {
230
- const { build } = await import("esbuild");
231
- const transformed = await build({
232
- entryPoints: [{ in: configPath, out: "source.config" }],
233
- bundle: true,
234
- outdir: outDir,
235
- target: "node20",
236
- write: true,
237
- platform: "node",
238
- format: "esm",
239
- packages: "external",
240
- outExtension: {
241
- ".js": ".mjs"
242
- },
243
- allowOverwrite: true
244
- });
245
- if (transformed.errors.length > 0) {
246
- throw new Error("failed to compile configuration file");
247
- }
248
- }
249
- async function loadConfig(configPath, outDir, build = false) {
250
- if (build) await compileConfig(configPath, outDir);
251
- const url = (0, import_node_url2.pathToFileURL)(path6.resolve(outDir, "source.config.mjs"));
252
- url.searchParams.set("hash", Date.now().toString());
253
- const config = import(url.href).then(
254
- (loaded) => buildConfig(loaded)
255
- );
256
- return await config;
257
- }
258
- var path6, import_node_url2;
259
- var init_load_from_file = __esm({
260
- "src/config/load-from-file.ts"() {
261
- "use strict";
262
- path6 = __toESM(require("path"), 1);
263
- import_node_url2 = require("url");
264
- init_build();
265
- }
266
- });
267
-
268
- // src/node/loader.ts
269
- var loader_exports = {};
270
- __export(loader_exports, {
271
- load: () => load3
272
- });
273
- module.exports = __toCommonJS(loader_exports);
274
-
275
- // src/core.ts
276
- var import_node_path = __toESM(require("path"), 1);
277
- var import_promises = __toESM(require("fs/promises"), 1);
278
- function findConfigFile() {
279
- return import_node_path.default.resolve("source.config.ts");
280
- }
281
- function createCore(options, defaultPlugins = []) {
282
- let config;
283
- let plugins2;
284
- return {
285
- _options: options,
286
- getPluginContext() {
287
- return {
288
- core: this,
289
- ...options
290
- };
291
- },
292
- /**
293
- * Convenient cache store, reset when config changes
294
- */
295
- cache: /* @__PURE__ */ new Map(),
296
- async init({ config: newConfig }) {
297
- config = await newConfig;
298
- this.cache.clear();
299
- plugins2 = [];
300
- for await (const option of [
301
- ...defaultPlugins,
302
- ...config.global.plugins ?? []
303
- ]) {
304
- if (!option) continue;
305
- if (Array.isArray(option)) plugins2.push(...option);
306
- else plugins2.push(option);
307
- }
308
- for (const plugin of plugins2) {
309
- const out = await plugin.config?.call(this.getPluginContext(), config);
310
- if (out) config = out;
311
- }
312
- return this;
313
- },
314
- getConfig() {
315
- return config;
316
- },
317
- async initServer(server) {
318
- for (const plugin of plugins2) {
319
- await plugin.configureServer?.call(this.getPluginContext(), server);
320
- }
321
- },
322
- async emitAndWrite({
323
- filterPlugin = () => true
324
- } = {}) {
325
- const start = performance.now();
326
- const out = await Promise.all(
327
- plugins2.map((plugin) => {
328
- if (!filterPlugin(plugin) || !plugin.emit) return [];
329
- return plugin.emit.call(this.getPluginContext());
330
- })
331
- );
332
- await Promise.all(
333
- out.flat().map(async (entry) => {
334
- const file = import_node_path.default.join(options.outDir, entry.path);
335
- await import_promises.default.mkdir(import_node_path.default.dirname(file), { recursive: true });
336
- await import_promises.default.writeFile(file, entry.content);
337
- })
338
- );
339
- console.log(`[MDX] generated files in ${performance.now() - start}ms`);
340
- }
341
- };
342
- }
343
-
344
33
  // src/utils/fuma-matter.ts
345
- var import_js_yaml = require("js-yaml");
346
- var regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
347
34
  function fumaMatter(input) {
348
35
  const output = { matter: "", data: {}, content: input };
349
36
  const match = regex.exec(input);
@@ -356,80 +43,16 @@ function fumaMatter(input) {
356
43
  output.data = loaded ?? {};
357
44
  return output;
358
45
  }
359
-
360
- // src/utils/validation.ts
361
- var import_picocolors = __toESM(require("picocolors"), 1);
362
- var ValidationError = class extends Error {
363
- constructor(message, issues) {
364
- super(
365
- `${message}:
366
- ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
367
- );
368
- this.title = message;
369
- this.issues = issues;
370
- }
371
- toStringFormatted() {
372
- return [
373
- import_picocolors.default.bold(`[MDX] ${this.title}:`),
374
- ...this.issues.map(
375
- (issue) => import_picocolors.default.redBright(
376
- `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
377
- )
378
- )
379
- ].join("\n");
380
- }
381
- };
382
- async function validate(schema, data, context, errorMessage) {
383
- if (typeof schema === "function" && !("~standard" in schema)) {
384
- schema = schema(context);
385
- }
386
- if ("~standard" in schema) {
387
- const result = await schema["~standard"].validate(
388
- data
389
- );
390
- if (result.issues) {
391
- throw new ValidationError(errorMessage, result.issues);
392
- }
393
- return result.value;
394
- }
395
- return data;
396
- }
397
-
398
- // src/utils/git-timestamp.ts
399
- var import_node_path2 = __toESM(require("path"), 1);
400
- var import_tinyexec = require("tinyexec");
401
- var cache = /* @__PURE__ */ new Map();
402
- async function getGitTimestamp(file) {
403
- const cached = cache.get(file);
404
- if (cached) return cached;
405
- try {
406
- const out = await (0, import_tinyexec.x)(
407
- "git",
408
- ["log", "-1", '--pretty="%ai"', import_node_path2.default.relative(process.cwd(), file)],
409
- {
410
- throwOnError: true
411
- }
412
- );
413
- const time = new Date(out.stdout);
414
- cache.set(file, time);
415
- return time;
416
- } catch {
417
- return;
46
+ var import_js_yaml, regex;
47
+ var init_fuma_matter = __esm({
48
+ "src/utils/fuma-matter.ts"() {
49
+ "use strict";
50
+ import_js_yaml = require("js-yaml");
51
+ regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
418
52
  }
419
- }
420
-
421
- // src/loaders/mdx/build-mdx.ts
422
- var import_mdx = require("@mdx-js/mdx");
423
-
424
- // src/loaders/mdx/remark-include.ts
425
- var import_unified = require("unified");
426
- var import_unist_util_visit2 = require("unist-util-visit");
427
- var path3 = __toESM(require("path"), 1);
428
- var fs2 = __toESM(require("fs/promises"), 1);
429
- var import_mdx_plugins = require("fumadocs-core/mdx-plugins");
53
+ });
430
54
 
431
55
  // src/loaders/mdx/remark-unravel.ts
432
- var import_unist_util_visit = require("unist-util-visit");
433
56
  function remarkMarkAndUnravel() {
434
57
  return (tree) => {
435
58
  (0, import_unist_util_visit.visit)(tree, function(node, index, parent) {
@@ -471,15 +94,28 @@ function remarkMarkAndUnravel() {
471
94
  });
472
95
  };
473
96
  }
97
+ var import_unist_util_visit;
98
+ var init_remark_unravel = __esm({
99
+ "src/loaders/mdx/remark-unravel.ts"() {
100
+ "use strict";
101
+ import_unist_util_visit = require("unist-util-visit");
102
+ }
103
+ });
104
+
105
+ // src/loaders/mdx/mdast-utils.ts
106
+ function flattenNode(node) {
107
+ if ("children" in node)
108
+ return node.children.map((child) => flattenNode(child)).join("");
109
+ if ("value" in node) return node.value;
110
+ return "";
111
+ }
112
+ var init_mdast_utils = __esm({
113
+ "src/loaders/mdx/mdast-utils.ts"() {
114
+ "use strict";
115
+ }
116
+ });
474
117
 
475
118
  // src/loaders/mdx/remark-include.ts
476
- var ElementLikeTypes = [
477
- "mdxJsxFlowElement",
478
- "mdxJsxTextElement",
479
- "containerDirective",
480
- "textDirective",
481
- "leafDirective"
482
- ];
483
119
  function isElementLike(node) {
484
120
  return ElementLikeTypes.includes(node.type);
485
121
  }
@@ -495,12 +131,6 @@ function parseElementAttributes(element) {
495
131
  }
496
132
  return element.attributes ?? {};
497
133
  }
498
- function flattenNode(node) {
499
- if ("children" in node)
500
- return node.children.map((child) => flattenNode(child)).join("");
501
- if ("value" in node) return node.value;
502
- return "";
503
- }
504
134
  function parseSpecifier(specifier) {
505
135
  const idx = specifier.lastIndexOf("#");
506
136
  if (idx === -1) return { file: specifier };
@@ -547,7 +177,7 @@ function remarkInclude() {
547
177
  const embedContent = async (file, heading, params, data) => {
548
178
  let content;
549
179
  try {
550
- content = (await fs2.readFile(file)).toString();
180
+ content = (await fs3.readFile(file)).toString();
551
181
  } catch (e) {
552
182
  throw new Error(
553
183
  `failed to read file ${file}
@@ -620,160 +250,646 @@ ${e instanceof Error ? e.message : String(e)}`,
620
250
  await update(tree, path3.dirname(file.path), file.data);
621
251
  };
622
252
  }
253
+ var import_unified, import_unist_util_visit2, path3, fs3, import_mdx_plugins, ElementLikeTypes;
254
+ var init_remark_include = __esm({
255
+ "src/loaders/mdx/remark-include.ts"() {
256
+ "use strict";
257
+ import_unified = require("unified");
258
+ import_unist_util_visit2 = require("unist-util-visit");
259
+ path3 = __toESM(require("path"), 1);
260
+ fs3 = __toESM(require("fs/promises"), 1);
261
+ init_fuma_matter();
262
+ import_mdx_plugins = require("fumadocs-core/mdx-plugins");
263
+ init_remark_unravel();
264
+ init_mdast_utils();
265
+ ElementLikeTypes = [
266
+ "mdxJsxFlowElement",
267
+ "mdxJsxTextElement",
268
+ "containerDirective",
269
+ "textDirective",
270
+ "leafDirective"
271
+ ];
272
+ }
273
+ });
623
274
 
624
275
  // src/loaders/mdx/remark-postprocess.ts
625
- var import_unist_util_visit3 = require("unist-util-visit");
626
- var import_mdast_util_to_markdown = require("mdast-util-to-markdown");
627
- var import_estree_util_value_to_estree = require("estree-util-value-to-estree");
628
- var import_unist_util_remove_position = require("unist-util-remove-position");
629
- var import_remark_mdx = __toESM(require("remark-mdx"), 1);
630
276
  function remarkPostprocess({
631
277
  _format,
632
278
  includeProcessedMarkdown = false,
633
279
  includeMDAST = false,
280
+ extractLinkReferences = false,
634
281
  valueToExport = []
635
282
  }) {
636
283
  let _stringifyProcessor;
637
284
  const getStringifyProcessor = () => {
638
- if (_format === "mdx") return this;
639
- return _stringifyProcessor ??= this().use(import_remark_mdx.default).freeze();
285
+ return _stringifyProcessor ??= _format === "mdx" ? this : (
286
+ // force Markdown processor to stringify MDX nodes
287
+ this().use(import_remark_mdx.default).freeze()
288
+ );
640
289
  };
641
290
  return (tree, file) => {
642
- let title;
643
- const urls = [];
644
- (0, import_unist_util_visit3.visit)(tree, ["heading", "link"], (node) => {
645
- if (node.type === "heading" && node.depth === 1) {
646
- title = flattenNode2(node);
647
- }
648
- if (node.type !== "link") return;
649
- urls.push({
650
- href: node.url
291
+ const frontmatter = file.data.frontmatter ??= {};
292
+ if (!frontmatter.title) {
293
+ (0, import_unist_util_visit3.visit)(tree, "heading", (node) => {
294
+ if (node.depth === 1) {
295
+ frontmatter.title = flattenNode(node);
296
+ return false;
297
+ }
298
+ });
299
+ }
300
+ file.data["mdx-export"] ??= [];
301
+ if (extractLinkReferences) {
302
+ const urls = [];
303
+ (0, import_unist_util_visit3.visit)(tree, "link", (node) => {
304
+ urls.push({
305
+ href: node.url
306
+ });
307
+ return "skip";
308
+ });
309
+ file.data["mdx-export"].push({
310
+ name: "extractedReferences",
311
+ value: urls
651
312
  });
652
- return "skip";
653
- });
654
- if (title) {
655
- file.data.frontmatter ??= {};
656
- if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
657
313
  }
658
- file.data.extractedReferences = urls;
659
314
  if (includeProcessedMarkdown) {
660
315
  const processor = getStringifyProcessor();
661
- file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
316
+ const markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
662
317
  ...processor.data("settings"),
663
318
  // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
664
319
  extensions: processor.data("toMarkdownExtensions") || []
665
320
  });
321
+ file.data["mdx-export"].push({
322
+ name: "_markdown",
323
+ value: markdown
324
+ });
666
325
  }
667
326
  if (includeMDAST) {
668
327
  const options = includeMDAST === true ? {} : includeMDAST;
669
- file.data._mdast = JSON.stringify(
328
+ const mdast = JSON.stringify(
670
329
  options.removePosition ? (0, import_unist_util_remove_position.removePosition)(structuredClone(tree)) : tree
671
330
  );
331
+ file.data["mdx-export"].push({
332
+ name: "_mdast",
333
+ value: mdast
334
+ });
672
335
  }
673
- for (const { name, value } of file.data["mdx-export"] ?? []) {
336
+ for (const { name, value } of file.data["mdx-export"]) {
674
337
  tree.children.unshift(getMdastExport(name, value));
675
338
  }
339
+ file.data["mdx-export"] = [];
676
340
  for (const name of valueToExport) {
677
341
  if (!(name in file.data)) continue;
678
342
  tree.children.unshift(getMdastExport(name, file.data[name]));
679
343
  }
680
- };
681
- }
682
- function getMdastExport(name, value) {
344
+ };
345
+ }
346
+ function getMdastExport(name, value) {
347
+ return {
348
+ type: "mdxjsEsm",
349
+ value: "",
350
+ data: {
351
+ estree: {
352
+ type: "Program",
353
+ sourceType: "module",
354
+ body: [
355
+ {
356
+ type: "ExportNamedDeclaration",
357
+ attributes: [],
358
+ specifiers: [],
359
+ source: null,
360
+ declaration: {
361
+ type: "VariableDeclaration",
362
+ kind: "let",
363
+ declarations: [
364
+ {
365
+ type: "VariableDeclarator",
366
+ id: {
367
+ type: "Identifier",
368
+ name
369
+ },
370
+ init: (0, import_estree_util_value_to_estree.valueToEstree)(value)
371
+ }
372
+ ]
373
+ }
374
+ }
375
+ ]
376
+ }
377
+ }
378
+ };
379
+ }
380
+ var import_unist_util_visit3, import_mdast_util_to_markdown, import_estree_util_value_to_estree, import_unist_util_remove_position, import_remark_mdx;
381
+ var init_remark_postprocess = __esm({
382
+ "src/loaders/mdx/remark-postprocess.ts"() {
383
+ "use strict";
384
+ import_unist_util_visit3 = require("unist-util-visit");
385
+ import_mdast_util_to_markdown = require("mdast-util-to-markdown");
386
+ import_estree_util_value_to_estree = require("estree-util-value-to-estree");
387
+ import_unist_util_remove_position = require("unist-util-remove-position");
388
+ import_remark_mdx = __toESM(require("remark-mdx"), 1);
389
+ init_mdast_utils();
390
+ }
391
+ });
392
+
393
+ // src/loaders/mdx/build-mdx.ts
394
+ var build_mdx_exports = {};
395
+ __export(build_mdx_exports, {
396
+ buildMDX: () => buildMDX
397
+ });
398
+ async function buildMDX(core2, collection, {
399
+ filePath,
400
+ frontmatter,
401
+ source,
402
+ _compiler,
403
+ environment,
404
+ isDevelopment
405
+ }) {
406
+ const mdxOptions = await core2.getConfig().getMDXOptions(collection, environment);
407
+ function getProcessor(format) {
408
+ const cache = core2.cache;
409
+ const key = `build-mdx:${collection?.name ?? "global"}:${format}`;
410
+ let processor = cache.get(key);
411
+ if (!processor) {
412
+ const postprocessOptions = {
413
+ _format: format,
414
+ ...collection?.postprocess,
415
+ valueToExport: [
416
+ ...collection?.postprocess?.valueToExport ?? [],
417
+ "structuredData",
418
+ "frontmatter"
419
+ ]
420
+ };
421
+ processor = (0, import_mdx.createProcessor)({
422
+ outputFormat: "program",
423
+ development: isDevelopment,
424
+ ...mdxOptions,
425
+ remarkPlugins: [
426
+ remarkInclude,
427
+ ...mdxOptions.remarkPlugins ?? [],
428
+ [remarkPostprocess, postprocessOptions]
429
+ ],
430
+ format
431
+ });
432
+ cache.set(key, processor);
433
+ }
434
+ return processor;
435
+ }
436
+ let vfile = new import_vfile.VFile({
437
+ value: source,
438
+ path: filePath,
439
+ data: { frontmatter, _compiler, _getProcessor: getProcessor }
440
+ });
441
+ if (collection) {
442
+ vfile = await core2.transformVFile({ collection, filePath, source }, vfile);
443
+ }
444
+ return getProcessor(filePath.endsWith(".mdx") ? "mdx" : "md").process(vfile);
445
+ }
446
+ var import_mdx, import_vfile;
447
+ var init_build_mdx = __esm({
448
+ "src/loaders/mdx/build-mdx.ts"() {
449
+ "use strict";
450
+ import_mdx = require("@mdx-js/mdx");
451
+ import_vfile = require("vfile");
452
+ init_remark_include();
453
+ init_remark_postprocess();
454
+ }
455
+ });
456
+
457
+ // src/config/preset.ts
458
+ function pluginOption(def, options = []) {
459
+ const list = def(Array.isArray(options) ? options : []).filter(
460
+ Boolean
461
+ );
462
+ if (typeof options === "function") {
463
+ return options(list);
464
+ }
465
+ return list;
466
+ }
467
+ function applyMdxPreset(options = {}) {
468
+ return async (environment = "bundler") => {
469
+ if (options.preset === "minimal") return options;
470
+ const plugins = await import("fumadocs-core/mdx-plugins");
471
+ const {
472
+ valueToExport = [],
473
+ rehypeCodeOptions,
474
+ remarkImageOptions,
475
+ remarkHeadingOptions,
476
+ remarkStructureOptions,
477
+ remarkCodeTabOptions,
478
+ remarkNpmOptions,
479
+ ...mdxOptions
480
+ } = options;
481
+ const remarkPlugins = pluginOption(
482
+ (v) => [
483
+ plugins.remarkGfm,
484
+ [
485
+ plugins.remarkHeading,
486
+ {
487
+ generateToc: false,
488
+ ...remarkHeadingOptions
489
+ }
490
+ ],
491
+ remarkImageOptions !== false && [
492
+ plugins.remarkImage,
493
+ {
494
+ ...remarkImageOptions,
495
+ useImport: remarkImageOptions?.useImport ?? environment === "bundler"
496
+ }
497
+ ],
498
+ "remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
499
+ plugins.remarkCodeTab,
500
+ remarkCodeTabOptions
501
+ ],
502
+ "remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
503
+ ...v,
504
+ remarkStructureOptions !== false && [
505
+ plugins.remarkStructure,
506
+ remarkStructureOptions
507
+ ],
508
+ valueToExport.length > 0 && (() => {
509
+ return (_, file) => {
510
+ file.data["mdx-export"] ??= [];
511
+ for (const name of valueToExport) {
512
+ if (!(name in file.data)) continue;
513
+ file.data["mdx-export"].push({
514
+ name,
515
+ value: file.data[name]
516
+ });
517
+ }
518
+ };
519
+ })
520
+ ],
521
+ mdxOptions.remarkPlugins
522
+ );
523
+ const rehypePlugins = pluginOption(
524
+ (v) => [
525
+ rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
526
+ ...v,
527
+ plugins.rehypeToc
528
+ ],
529
+ mdxOptions.rehypePlugins
530
+ );
531
+ return {
532
+ ...mdxOptions,
533
+ outputFormat: environment === "runtime" ? "function-body" : mdxOptions.outputFormat,
534
+ remarkPlugins,
535
+ rehypePlugins
536
+ };
537
+ };
538
+ }
539
+ var init_preset = __esm({
540
+ "src/config/preset.ts"() {
541
+ "use strict";
542
+ }
543
+ });
544
+
545
+ // src/config/build.ts
546
+ function buildCollection(name, config) {
547
+ if (config.type === "docs") {
548
+ return {
549
+ ...config,
550
+ name,
551
+ meta: buildPrimitiveCollection(name, config.meta),
552
+ docs: buildPrimitiveCollection(name, config.docs),
553
+ hasFile(filePath) {
554
+ return this.docs.hasFile(filePath) || this.meta.hasFile(filePath);
555
+ }
556
+ };
557
+ }
558
+ return buildPrimitiveCollection(name, config);
559
+ }
560
+ function buildPrimitiveCollection(name, { files, ...config }) {
561
+ const supportedFormats = SupportedFormats[config.type];
562
+ const patterns = files ?? [`**/*.{${supportedFormats.join(",")}}`];
563
+ let matchers;
564
+ return {
565
+ ...config,
566
+ name,
567
+ patterns,
568
+ isFileSupported(filePath) {
569
+ return supportedFormats.some((format) => filePath.endsWith(`.${format}`));
570
+ },
571
+ hasFile(filePath) {
572
+ matchers ??= (Array.isArray(config.dir) ? config.dir : [config.dir]).map(
573
+ (dir) => (0, import_picomatch.default)(patterns, {
574
+ cwd: dir
575
+ })
576
+ );
577
+ return this.isFileSupported(filePath) && matchers.some((matcher) => matcher(filePath));
578
+ }
579
+ };
580
+ }
581
+ function buildConfig(config) {
582
+ const collections = /* @__PURE__ */ new Map();
583
+ const loaded = {};
584
+ for (const [k, v] of Object.entries(config)) {
585
+ if (!v) {
586
+ continue;
587
+ }
588
+ if (typeof v === "object" && "type" in v) {
589
+ if (v.type === "docs") {
590
+ collections.set(k, buildCollection(k, v));
591
+ continue;
592
+ }
593
+ if (v.type === "doc" || v.type === "meta") {
594
+ collections.set(
595
+ k,
596
+ buildCollection(k, v)
597
+ );
598
+ continue;
599
+ }
600
+ }
601
+ if (k === "default" && v) {
602
+ Object.assign(loaded, v);
603
+ continue;
604
+ }
605
+ throw new Error(
606
+ `Unknown export "${k}", you can only export collections from source configuration file.`
607
+ );
608
+ }
609
+ const mdxOptionsCache = /* @__PURE__ */ new Map();
683
610
  return {
684
- type: "mdxjsEsm",
685
- value: "",
686
- data: {
687
- estree: {
688
- type: "Program",
689
- sourceType: "module",
690
- body: [
691
- {
692
- type: "ExportNamedDeclaration",
693
- attributes: [],
694
- specifiers: [],
695
- source: null,
696
- declaration: {
697
- type: "VariableDeclaration",
698
- kind: "let",
699
- declarations: [
700
- {
701
- type: "VariableDeclarator",
702
- id: {
703
- type: "Identifier",
704
- name
705
- },
706
- init: (0, import_estree_util_value_to_estree.valueToEstree)(value)
707
- }
708
- ]
709
- }
710
- }
711
- ]
611
+ global: loaded,
612
+ collectionList: Array.from(collections.values()),
613
+ getCollection(name) {
614
+ return collections.get(name);
615
+ },
616
+ getMDXOptions(collection, environment = "bundler") {
617
+ const key = collection ? `${environment}:${collection.name}` : environment;
618
+ const cached = mdxOptionsCache.get(key);
619
+ if (cached) return cached;
620
+ let result;
621
+ if (collection?.mdxOptions) {
622
+ const optionsFn = collection.mdxOptions;
623
+ result = typeof optionsFn === "function" ? optionsFn(environment) : optionsFn;
624
+ } else {
625
+ result = (async () => {
626
+ const optionsFn = this.global.mdxOptions;
627
+ const options = typeof optionsFn === "function" ? await optionsFn() : optionsFn;
628
+ return applyMdxPreset(options)(environment);
629
+ })();
712
630
  }
631
+ mdxOptionsCache.set(key, result);
632
+ return result;
713
633
  }
714
634
  };
715
635
  }
716
- function flattenNode2(node) {
717
- if ("children" in node)
718
- return node.children.map((child) => flattenNode2(child)).join("");
719
- if ("value" in node) return node.value;
720
- return "";
636
+ var import_picomatch, SupportedFormats;
637
+ var init_build = __esm({
638
+ "src/config/build.ts"() {
639
+ "use strict";
640
+ import_picomatch = __toESM(require("picomatch"), 1);
641
+ init_preset();
642
+ SupportedFormats = {
643
+ doc: ["mdx", "md"],
644
+ meta: ["json", "yaml"]
645
+ };
646
+ }
647
+ });
648
+
649
+ // src/config/load-from-file.ts
650
+ var load_from_file_exports = {};
651
+ __export(load_from_file_exports, {
652
+ loadConfig: () => loadConfig
653
+ });
654
+ async function compileConfig(core2) {
655
+ const { build } = await import("esbuild");
656
+ const transformed = await build({
657
+ entryPoints: [{ in: core2._options.configPath, out: "source.config" }],
658
+ bundle: true,
659
+ outdir: core2._options.outDir,
660
+ target: "node20",
661
+ write: true,
662
+ platform: "node",
663
+ format: "esm",
664
+ packages: "external",
665
+ outExtension: {
666
+ ".js": ".mjs"
667
+ },
668
+ allowOverwrite: true
669
+ });
670
+ if (transformed.errors.length > 0) {
671
+ throw new Error("failed to compile configuration file");
672
+ }
673
+ }
674
+ async function loadConfig(core2, build = false) {
675
+ if (build) await compileConfig(core2);
676
+ const url = (0, import_node_url2.pathToFileURL)(core2.getCompiledConfigPath());
677
+ url.searchParams.set("hash", Date.now().toString());
678
+ const config = import(url.href).then(
679
+ (loaded) => buildConfig(loaded)
680
+ );
681
+ return await config;
721
682
  }
683
+ var import_node_url2;
684
+ var init_load_from_file = __esm({
685
+ "src/config/load-from-file.ts"() {
686
+ "use strict";
687
+ import_node_url2 = require("url");
688
+ init_build();
689
+ }
690
+ });
722
691
 
723
- // src/loaders/mdx/build-mdx.ts
724
- var cache2 = /* @__PURE__ */ new Map();
725
- async function buildMDX(cacheKey, source, options) {
726
- const { filePath, frontmatter, data, _compiler, ...rest } = options;
727
- function getProcessor(format) {
728
- const key = `${cacheKey}:${format}`;
729
- let processor = cache2.get(key);
730
- if (!processor) {
731
- processor = (0, import_mdx.createProcessor)({
732
- outputFormat: "program",
733
- ...rest,
734
- remarkPlugins: [
735
- remarkInclude,
736
- ...rest.remarkPlugins ?? [],
737
- [
738
- remarkPostprocess,
739
- {
740
- _format: format,
741
- ...options.postprocess,
742
- valueToExport: [
743
- ...options.postprocess?.valueToExport ?? [],
744
- "structuredData",
745
- "extractedReferences",
746
- "frontmatter",
747
- "lastModified",
748
- "_markdown",
749
- "_mdast"
750
- ]
751
- }
752
- ]
753
- ],
754
- format
755
- });
756
- cache2.set(key, processor);
692
+ // src/node/loader.ts
693
+ var loader_exports = {};
694
+ __export(loader_exports, {
695
+ load: () => load3
696
+ });
697
+ module.exports = __toCommonJS(loader_exports);
698
+
699
+ // src/core.ts
700
+ var import_node_path2 = __toESM(require("path"), 1);
701
+ var import_promises2 = __toESM(require("fs/promises"), 1);
702
+
703
+ // src/utils/codegen/cache.ts
704
+ var import_lru_cache = require("lru-cache");
705
+ var import_promises = __toESM(require("fs/promises"), 1);
706
+ var import_node_path = __toESM(require("path"), 1);
707
+ var map = new import_lru_cache.LRUCache({
708
+ max: 100
709
+ });
710
+ function toFullPath(file) {
711
+ if (import_node_path.default.isAbsolute(file)) {
712
+ return import_node_path.default.relative(process.cwd(), file);
713
+ }
714
+ return file;
715
+ }
716
+ function removeFileCache(file) {
717
+ map.delete(toFullPath(file));
718
+ }
719
+
720
+ // src/utils/validation.ts
721
+ var ValidationError = class extends Error {
722
+ constructor(message, issues) {
723
+ super(
724
+ `${message}:
725
+ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
726
+ );
727
+ this.title = message;
728
+ this.issues = issues;
729
+ }
730
+ async toStringFormatted() {
731
+ const picocolors = await import("picocolors");
732
+ return [
733
+ picocolors.bold(`[MDX] ${this.title}:`),
734
+ ...this.issues.map(
735
+ (issue) => picocolors.redBright(
736
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
737
+ )
738
+ )
739
+ ].join("\n");
740
+ }
741
+ };
742
+ async function validate(schema, data, context, errorMessage) {
743
+ if (typeof schema === "function" && !("~standard" in schema)) {
744
+ schema = schema(context);
745
+ }
746
+ if ("~standard" in schema) {
747
+ const result = await schema["~standard"].validate(
748
+ data
749
+ );
750
+ if (result.issues) {
751
+ throw new ValidationError(errorMessage, result.issues);
757
752
  }
758
- return processor;
753
+ return result.value;
759
754
  }
760
- return getProcessor(
761
- options.format ?? (filePath.endsWith(".mdx") ? "mdx" : "md")
762
- ).process({
763
- value: source,
764
- path: filePath,
765
- data: {
766
- ...data,
767
- frontmatter,
768
- _compiler,
769
- _getProcessor: getProcessor
755
+ return data;
756
+ }
757
+
758
+ // src/core.ts
759
+ var _Defaults = {
760
+ configPath: "source.config.ts",
761
+ outDir: ".source"
762
+ };
763
+ async function getPlugins(pluginOptions) {
764
+ const plugins = [];
765
+ for await (const option of pluginOptions) {
766
+ if (!option) continue;
767
+ if (Array.isArray(option)) plugins.push(...await getPlugins(option));
768
+ else plugins.push(option);
769
+ }
770
+ return plugins;
771
+ }
772
+ function createCore(options, defaultPlugins = []) {
773
+ let config;
774
+ let plugins;
775
+ async function transformMetadata({
776
+ collection,
777
+ filePath,
778
+ source
779
+ }, data) {
780
+ if (collection.schema) {
781
+ data = await validate(
782
+ collection.schema,
783
+ data,
784
+ { path: filePath, source },
785
+ collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
786
+ );
770
787
  }
771
- });
788
+ return data;
789
+ }
790
+ const core2 = {
791
+ _options: options,
792
+ /**
793
+ * Convenient cache store, reset when config changes
794
+ */
795
+ cache: /* @__PURE__ */ new Map(),
796
+ async init({ config: newConfig }) {
797
+ config = await newConfig;
798
+ this.cache.clear();
799
+ plugins = await getPlugins([
800
+ ...defaultPlugins,
801
+ ...config.global.plugins ?? []
802
+ ]);
803
+ for (const plugin of plugins) {
804
+ const out = await plugin.config?.call(pluginContext, config);
805
+ if (out) config = out;
806
+ }
807
+ return this;
808
+ },
809
+ getConfig() {
810
+ return config;
811
+ },
812
+ /**
813
+ * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
814
+ */
815
+ getCompiledConfigPath() {
816
+ return import_node_path2.default.join(options.outDir, "source.config.mjs");
817
+ },
818
+ async initServer(server) {
819
+ server.watcher?.on("all", async (event, file) => {
820
+ if (event === "change") removeFileCache(file);
821
+ });
822
+ for (const plugin of plugins) {
823
+ await plugin.configureServer?.call(pluginContext, server);
824
+ }
825
+ },
826
+ async emit({ filterPlugin = () => true } = {}) {
827
+ return (await Promise.all(
828
+ plugins.map((plugin) => {
829
+ if (!filterPlugin(plugin) || !plugin.emit) return [];
830
+ return plugin.emit.call(pluginContext);
831
+ })
832
+ )).flat();
833
+ },
834
+ async emitAndWrite(emitOptions) {
835
+ const start = performance.now();
836
+ const out = await this.emit(emitOptions);
837
+ await Promise.all(
838
+ out.map(async (entry) => {
839
+ const file = import_node_path2.default.join(options.outDir, entry.path);
840
+ await import_promises2.default.mkdir(import_node_path2.default.dirname(file), { recursive: true });
841
+ await import_promises2.default.writeFile(file, entry.content);
842
+ })
843
+ );
844
+ console.log(`[MDX] generated files in ${performance.now() - start}ms`);
845
+ },
846
+ async transformMeta(options2, data) {
847
+ const ctx = {
848
+ ...pluginContext,
849
+ ...options2
850
+ };
851
+ data = await transformMetadata(options2, data);
852
+ for (const plugin of plugins) {
853
+ if (plugin.meta?.transform)
854
+ data = await plugin.meta.transform.call(ctx, data) ?? data;
855
+ }
856
+ return data;
857
+ },
858
+ async transformFrontmatter(options2, data) {
859
+ const ctx = {
860
+ ...pluginContext,
861
+ ...options2
862
+ };
863
+ data = await transformMetadata(options2, data);
864
+ for (const plugin of plugins) {
865
+ if (plugin.doc?.frontmatter)
866
+ data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
867
+ }
868
+ return data;
869
+ },
870
+ async transformVFile(options2, file) {
871
+ const ctx = {
872
+ ...pluginContext,
873
+ ...options2
874
+ };
875
+ for (const plugin of plugins) {
876
+ if (plugin.doc?.vfile)
877
+ file = await plugin.doc.vfile.call(ctx, file) ?? file;
878
+ }
879
+ return file;
880
+ }
881
+ };
882
+ const pluginContext = {
883
+ core: core2,
884
+ ...options
885
+ };
886
+ return core2;
772
887
  }
773
888
 
774
889
  // src/loaders/mdx/index.ts
890
+ init_fuma_matter();
775
891
  var import_zod = require("zod");
776
- var import_promises2 = __toESM(require("fs/promises"), 1);
892
+ var import_promises3 = __toESM(require("fs/promises"), 1);
777
893
  var import_node_path3 = __toESM(require("path"), 1);
778
894
  var import_node_crypto = require("crypto");
779
895
 
@@ -801,19 +917,19 @@ function createMdxLoader(configLoader2) {
801
917
  compiler,
802
918
  filePath
803
919
  }) {
920
+ const config = await configLoader2.getConfig();
804
921
  const value = await getSource();
805
922
  const matter = fumaMatter(value);
806
923
  const parsed = querySchema.parse(query);
807
- const config = await configLoader2.getConfig();
808
924
  let after;
809
925
  if (!isDevelopment && config.global.experimentalBuildCache) {
810
926
  const cacheDir = config.global.experimentalBuildCache;
811
927
  const cacheKey = `${parsed.hash}_${parsed.collection ?? "global"}_${generateCacheHash(filePath)}`;
812
- const cached = await import_promises2.default.readFile(import_node_path3.default.join(cacheDir, cacheKey)).then((content) => cacheEntry.parse(JSON.parse(content.toString()))).catch(() => null);
928
+ const cached = await import_promises3.default.readFile(import_node_path3.default.join(cacheDir, cacheKey)).then((content) => cacheEntry.parse(JSON.parse(content.toString()))).catch(() => null);
813
929
  if (cached && cached.hash === generateCacheHash(value)) return cached;
814
930
  after = async () => {
815
- await import_promises2.default.mkdir(cacheDir, { recursive: true });
816
- await import_promises2.default.writeFile(
931
+ await import_promises3.default.mkdir(cacheDir, { recursive: true });
932
+ await import_promises3.default.writeFile(
817
933
  import_node_path3.default.join(cacheDir, cacheKey),
818
934
  JSON.stringify({
819
935
  ...out,
@@ -832,15 +948,10 @@ function createMdxLoader(configLoader2) {
832
948
  docCollection = collection.docs;
833
949
  break;
834
950
  }
835
- if (docCollection?.schema) {
836
- matter.data = await validate(
837
- docCollection.schema,
838
- matter.data,
839
- {
840
- source: value,
841
- path: filePath
842
- },
843
- `invalid frontmatter in ${filePath}`
951
+ if (docCollection) {
952
+ matter.data = await configLoader2.core.transformFrontmatter(
953
+ { collection: docCollection, filePath, source: value },
954
+ matter.data
844
955
  );
845
956
  }
846
957
  if (parsed.only === "frontmatter") {
@@ -849,24 +960,16 @@ function createMdxLoader(configLoader2) {
849
960
  map: null
850
961
  };
851
962
  }
852
- const data = {};
853
- if (config.global.lastModifiedTime === "git") {
854
- data.lastModified = (await getGitTimestamp(filePath))?.getTime();
855
- }
856
963
  const lineOffset = isDevelopment ? countLines(matter.matter) : 0;
857
- const compiled = await buildMDX(
858
- `${getConfigHash(config)}:${parsed.collection ?? "global"}`,
859
- "\n".repeat(lineOffset) + matter.content,
860
- {
861
- development: isDevelopment,
862
- ...docCollection?.mdxOptions ?? await config.getDefaultMDXOptions(),
863
- postprocess: docCollection?.postprocess,
864
- data,
865
- filePath,
866
- frontmatter: matter.data,
867
- _compiler: compiler
868
- }
869
- );
964
+ const { buildMDX: buildMDX2 } = await Promise.resolve().then(() => (init_build_mdx(), build_mdx_exports));
965
+ const compiled = await buildMDX2(configLoader2.core, docCollection, {
966
+ isDevelopment,
967
+ source: "\n".repeat(lineOffset) + matter.content,
968
+ filePath,
969
+ frontmatter: matter.data,
970
+ _compiler: compiler,
971
+ environment: "bundler"
972
+ });
870
973
  const out = {
871
974
  code: String(compiled.value),
872
975
  map: compiled.map
@@ -876,14 +979,6 @@ function createMdxLoader(configLoader2) {
876
979
  }
877
980
  };
878
981
  }
879
- var hashes = /* @__PURE__ */ new WeakMap();
880
- function getConfigHash(config) {
881
- let hash = hashes.get(config);
882
- if (hash) return hash;
883
- hash = Date.now().toString();
884
- hashes.set(config, hash);
885
- return hash;
886
- }
887
982
  function generateCacheHash(input) {
888
983
  return (0, import_node_crypto.createHash)("md5").update(input).digest("hex");
889
984
  }
@@ -897,7 +992,7 @@ function countLines(s) {
897
992
 
898
993
  // src/loaders/adapter.ts
899
994
  var import_node_url = require("url");
900
- var import_promises3 = __toESM(require("fs/promises"), 1);
995
+ var import_promises4 = __toESM(require("fs/promises"), 1);
901
996
  var import_node_querystring = require("querystring");
902
997
  var import_node_path4 = __toESM(require("path"), 1);
903
998
  var import_node_fs = require("fs");
@@ -910,7 +1005,7 @@ function toNode(loader) {
910
1005
  filePath,
911
1006
  query: Object.fromEntries(parsedUrl.searchParams.entries()),
912
1007
  async getSource() {
913
- return (await import_promises3.default.readFile(filePath)).toString();
1008
+ return (await import_promises4.default.readFile(filePath)).toString();
914
1009
  },
915
1010
  development: false,
916
1011
  compiler: {
@@ -931,16 +1026,16 @@ function toNode(loader) {
931
1026
  }
932
1027
 
933
1028
  // src/loaders/config.ts
934
- var import_promises4 = __toESM(require("fs/promises"), 1);
1029
+ var import_promises5 = __toESM(require("fs/promises"), 1);
935
1030
  function createStandaloneConfigLoader({
936
1031
  core: core2,
937
1032
  buildConfig: buildConfig2,
938
1033
  mode
939
1034
  }) {
940
1035
  let loaded;
941
- async function getConfigHash2() {
1036
+ async function getConfigHash() {
942
1037
  if (mode === "production") return "static";
943
- const stats = await import_promises4.default.stat(core2._options.configPath).catch(() => {
1038
+ const stats = await import_promises5.default.stat(core2._options.configPath).catch(() => {
944
1039
  throw new Error("Cannot find config file");
945
1040
  });
946
1041
  return stats.mtime.getTime().toString();
@@ -948,17 +1043,14 @@ function createStandaloneConfigLoader({
948
1043
  async function newConfig() {
949
1044
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_load_from_file(), load_from_file_exports));
950
1045
  await core2.init({
951
- config: loadConfig2(
952
- core2._options.configPath,
953
- core2._options.outDir,
954
- buildConfig2
955
- )
1046
+ config: loadConfig2(core2, buildConfig2)
956
1047
  });
957
1048
  return core2.getConfig();
958
1049
  }
959
1050
  return {
1051
+ core: core2,
960
1052
  async getConfig() {
961
- const hash = await getConfigHash2();
1053
+ const hash = await getConfigHash();
962
1054
  if (loaded && loaded.hash === hash) return loaded.config;
963
1055
  loaded = {
964
1056
  hash,
@@ -975,63 +1067,73 @@ var import_zod2 = require("zod");
975
1067
  var querySchema2 = import_zod2.z.object({
976
1068
  collection: import_zod2.z.string().optional()
977
1069
  }).loose();
978
- function createMetaLoader(configLoader2, resolve3 = {}) {
979
- const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve3;
980
- function stringifyOutput(isJson, data) {
981
- if (isJson) {
982
- return resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}`;
983
- } else {
984
- return resolveYaml === "yaml" ? (0, import_js_yaml2.dump)(data) : `export default ${JSON.stringify(data)}`;
1070
+ function createMetaLoader(configLoader2, resolve2 = {}) {
1071
+ const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve2;
1072
+ function parse2(filePath, source) {
1073
+ try {
1074
+ if (filePath.endsWith(".json")) return JSON.parse(source);
1075
+ if (filePath.endsWith(".yaml")) return (0, import_js_yaml2.load)(source);
1076
+ } catch (e) {
1077
+ throw new Error(`invalid data in ${filePath}`, { cause: e });
985
1078
  }
1079
+ throw new Error("Unknown file type " + filePath);
986
1080
  }
987
- return {
988
- test: metaLoaderGlob,
989
- async load({ filePath, query, getSource }) {
990
- const parsed = querySchema2.parse(query);
991
- const collection = parsed.collection ? (await configLoader2.getConfig()).getCollection(parsed.collection) : void 0;
992
- if (!collection) return null;
993
- const isJson = filePath.endsWith(".json");
994
- const source = await getSource();
995
- let data;
996
- try {
997
- data = isJson ? JSON.parse(source) : (0, import_js_yaml2.load)(source);
998
- } catch (e) {
999
- throw new Error(`invalid data in ${filePath}`, { cause: e });
1000
- }
1001
- let schema;
1081
+ function onMeta(source, { filePath, query }) {
1082
+ const parsed = querySchema2.safeParse(query);
1083
+ if (!parsed.success || !parsed.data.collection) return null;
1084
+ const collectionName = parsed.data.collection;
1085
+ return async () => {
1086
+ const config = await configLoader2.getConfig();
1087
+ const collection = config.getCollection(collectionName);
1088
+ let metaCollection;
1002
1089
  switch (collection?.type) {
1003
1090
  case "meta":
1004
- schema = collection.schema;
1091
+ metaCollection = collection;
1005
1092
  break;
1006
1093
  case "docs":
1007
- schema = collection.meta.schema;
1094
+ metaCollection = collection.meta;
1008
1095
  break;
1009
1096
  }
1010
- if (schema) {
1011
- data = await validate(
1012
- schema,
1013
- data,
1014
- { path: filePath, source },
1015
- `invalid data in ${filePath}`
1016
- );
1097
+ const data = parse2(filePath, source);
1098
+ if (!metaCollection) return data;
1099
+ return configLoader2.core.transformMeta(
1100
+ {
1101
+ collection: metaCollection,
1102
+ filePath,
1103
+ source
1104
+ },
1105
+ data
1106
+ );
1107
+ };
1108
+ }
1109
+ return {
1110
+ test: metaLoaderGlob,
1111
+ async load(input) {
1112
+ const result = onMeta(await input.getSource(), input);
1113
+ if (result === null) return null;
1114
+ const data = await result();
1115
+ if (input.filePath.endsWith(".json")) {
1116
+ return {
1117
+ code: resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}`
1118
+ };
1119
+ } else {
1120
+ return {
1121
+ code: resolveYaml === "yaml" ? (0, import_js_yaml2.dump)(data) : `export default ${JSON.stringify(data)}`
1122
+ };
1017
1123
  }
1018
- return {
1019
- code: stringifyOutput(isJson, data)
1020
- };
1021
1124
  },
1022
1125
  bun: {
1023
- loadSync(source, { filePath }) {
1024
- const isJson = filePath.endsWith(".json");
1025
- let data;
1026
- try {
1027
- data = isJson ? JSON.parse(source) : (0, import_js_yaml2.load)(source);
1028
- } catch (e) {
1029
- throw new Error(`invalid data in ${filePath}`, { cause: e });
1030
- }
1031
- return {
1126
+ load(source, input) {
1127
+ const result = onMeta(source, input);
1128
+ if (result === null)
1129
+ return {
1130
+ loader: "object",
1131
+ exports: parse2(input.filePath, source)
1132
+ };
1133
+ return result().then((data) => ({
1032
1134
  loader: "object",
1033
- exports: data
1034
- };
1135
+ exports: { default: data }
1136
+ }));
1035
1137
  }
1036
1138
  }
1037
1139
  };
@@ -1040,8 +1142,8 @@ function createMetaLoader(configLoader2, resolve3 = {}) {
1040
1142
  // src/node/loader.ts
1041
1143
  var core = createCore({
1042
1144
  environment: "node",
1043
- configPath: findConfigFile(),
1044
- outDir: ".source"
1145
+ configPath: _Defaults.configPath,
1146
+ outDir: _Defaults.outDir
1045
1147
  });
1046
1148
  var configLoader = createStandaloneConfigLoader({
1047
1149
  core,