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
@@ -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 };
@@ -616,162 +246,683 @@ ${e instanceof Error ? e.message : String(e)}`,
616
246
  });
617
247
  await Promise.all(queue);
618
248
  }
619
- return async (tree, file) => {
620
- await update(tree, path3.dirname(file.path), file.data);
621
- };
249
+ return async (tree, file) => {
250
+ await update(tree, path3.dirname(file.path), file.data);
251
+ };
252
+ }
253
+ var import_unified, import_unist_util_visit2, path3, fs2, 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
+ fs2 = __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
+ });
274
+
275
+ // src/loaders/mdx/remark-postprocess.ts
276
+ function remarkPostprocess({
277
+ _format,
278
+ includeProcessedMarkdown = false,
279
+ includeMDAST = false,
280
+ extractLinkReferences = false,
281
+ valueToExport = []
282
+ }) {
283
+ let _stringifyProcessor;
284
+ const getStringifyProcessor = () => {
285
+ return _stringifyProcessor ??= _format === "mdx" ? this : (
286
+ // force Markdown processor to stringify MDX nodes
287
+ this().use(import_remark_mdx.default).freeze()
288
+ );
289
+ };
290
+ return (tree, file) => {
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
312
+ });
313
+ }
314
+ if (includeProcessedMarkdown) {
315
+ const processor = getStringifyProcessor();
316
+ const markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
317
+ ...processor.data("settings"),
318
+ // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
319
+ extensions: processor.data("toMarkdownExtensions") || []
320
+ });
321
+ file.data["mdx-export"].push({
322
+ name: "_markdown",
323
+ value: markdown
324
+ });
325
+ }
326
+ if (includeMDAST) {
327
+ const options = includeMDAST === true ? {} : includeMDAST;
328
+ const mdast = JSON.stringify(
329
+ options.removePosition ? (0, import_unist_util_remove_position.removePosition)(structuredClone(tree)) : tree
330
+ );
331
+ file.data["mdx-export"].push({
332
+ name: "_mdast",
333
+ value: mdast
334
+ });
335
+ }
336
+ for (const { name, value } of file.data["mdx-export"]) {
337
+ tree.children.unshift(getMdastExport(name, value));
338
+ }
339
+ file.data["mdx-export"] = [];
340
+ for (const name of valueToExport) {
341
+ if (!(name in file.data)) continue;
342
+ tree.children.unshift(getMdastExport(name, file.data[name]));
343
+ }
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();
610
+ return {
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
+ })();
630
+ }
631
+ mdxOptionsCache.set(key, result);
632
+ return result;
633
+ }
634
+ };
635
+ }
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 { configPath, outDir } = core2.getOptions();
657
+ const transformed = await build({
658
+ entryPoints: [{ in: configPath, out: "source.config" }],
659
+ bundle: true,
660
+ outdir: outDir,
661
+ target: "node20",
662
+ write: true,
663
+ platform: "node",
664
+ format: "esm",
665
+ packages: "external",
666
+ outExtension: {
667
+ ".js": ".mjs"
668
+ },
669
+ allowOverwrite: true
670
+ });
671
+ if (transformed.errors.length > 0) {
672
+ throw new Error("failed to compile configuration file");
673
+ }
674
+ }
675
+ async function loadConfig(core2, build = false) {
676
+ if (build) await compileConfig(core2);
677
+ const url = (0, import_node_url2.pathToFileURL)(core2.getCompiledConfigPath());
678
+ url.searchParams.set("hash", Date.now().toString());
679
+ const config = import(url.href).then(
680
+ (loaded) => buildConfig(loaded)
681
+ );
682
+ return await config;
622
683
  }
684
+ var import_node_url2;
685
+ var init_load_from_file = __esm({
686
+ "src/config/load-from-file.ts"() {
687
+ "use strict";
688
+ import_node_url2 = require("url");
689
+ init_build();
690
+ }
691
+ });
623
692
 
624
- // 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
- function remarkPostprocess({
631
- _format,
632
- includeProcessedMarkdown = false,
633
- includeMDAST = false,
634
- valueToExport = []
635
- }) {
636
- let _stringifyProcessor;
637
- const getStringifyProcessor = () => {
638
- if (_format === "mdx") return this;
639
- return _stringifyProcessor ??= this().use(import_remark_mdx.default).freeze();
640
- };
641
- 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
651
- });
652
- return "skip";
653
- });
654
- if (title) {
655
- file.data.frontmatter ??= {};
656
- if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
657
- }
658
- file.data.extractedReferences = urls;
659
- if (includeProcessedMarkdown) {
660
- const processor = getStringifyProcessor();
661
- file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
662
- ...processor.data("settings"),
663
- // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
664
- extensions: processor.data("toMarkdownExtensions") || []
665
- });
693
+ // src/node/loader.ts
694
+ var loader_exports = {};
695
+ __export(loader_exports, {
696
+ load: () => load3
697
+ });
698
+ module.exports = __toCommonJS(loader_exports);
699
+
700
+ // src/core.ts
701
+ var import_node_path2 = __toESM(require("path"), 1);
702
+ var import_promises = __toESM(require("fs/promises"), 1);
703
+
704
+ // src/utils/validation.ts
705
+ var ValidationError = class extends Error {
706
+ constructor(message, issues) {
707
+ super(
708
+ `${message}:
709
+ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
710
+ );
711
+ this.title = message;
712
+ this.issues = issues;
713
+ }
714
+ async toStringFormatted() {
715
+ const picocolors = await import("picocolors");
716
+ return [
717
+ picocolors.bold(`[MDX] ${this.title}:`),
718
+ ...this.issues.map(
719
+ (issue) => picocolors.redBright(
720
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
721
+ )
722
+ )
723
+ ].join("\n");
724
+ }
725
+ };
726
+ async function validate(schema, data, context, errorMessage) {
727
+ if (typeof schema === "function" && !("~standard" in schema)) {
728
+ schema = schema(context);
729
+ }
730
+ if ("~standard" in schema) {
731
+ const result = await schema["~standard"].validate(
732
+ data
733
+ );
734
+ if (result.issues) {
735
+ throw new ValidationError(errorMessage, result.issues);
666
736
  }
667
- if (includeMDAST) {
668
- const options = includeMDAST === true ? {} : includeMDAST;
669
- file.data._mdast = JSON.stringify(
670
- options.removePosition ? (0, import_unist_util_remove_position.removePosition)(structuredClone(tree)) : tree
737
+ return result.value;
738
+ }
739
+ return data;
740
+ }
741
+
742
+ // src/utils/codegen.ts
743
+ var import_node_path = __toESM(require("path"), 1);
744
+ var import_tinyglobby = require("tinyglobby");
745
+ function ident(code, tab = 1) {
746
+ return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
747
+ }
748
+
749
+ // src/core.ts
750
+ var _Defaults = {
751
+ configPath: "source.config.ts",
752
+ outDir: ".source"
753
+ };
754
+ async function getPlugins(pluginOptions) {
755
+ const plugins = [];
756
+ for await (const option of pluginOptions) {
757
+ if (!option) continue;
758
+ if (Array.isArray(option)) plugins.push(...await getPlugins(option));
759
+ else plugins.push(option);
760
+ }
761
+ return plugins;
762
+ }
763
+ function createCore(options, defaultPlugins = []) {
764
+ let config;
765
+ let plugins;
766
+ async function transformMetadata({
767
+ collection,
768
+ filePath,
769
+ source
770
+ }, data) {
771
+ if (collection.schema) {
772
+ data = await validate(
773
+ collection.schema,
774
+ data,
775
+ { path: filePath, source },
776
+ collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
671
777
  );
672
778
  }
673
- for (const { name, value } of file.data["mdx-export"] ?? []) {
674
- tree.children.unshift(getMdastExport(name, value));
675
- }
676
- for (const name of valueToExport) {
677
- if (!(name in file.data)) continue;
678
- tree.children.unshift(getMdastExport(name, file.data[name]));
779
+ return data;
780
+ }
781
+ const core2 = {
782
+ /**
783
+ * Convenient cache store, reset when config changes
784
+ */
785
+ cache: /* @__PURE__ */ new Map(),
786
+ async init({ config: newConfig }) {
787
+ config = await newConfig;
788
+ this.cache.clear();
789
+ plugins = await getPlugins([
790
+ postprocessPlugin(),
791
+ ...defaultPlugins,
792
+ ...config.global.plugins ?? []
793
+ ]);
794
+ for (const plugin of plugins) {
795
+ const out = await plugin.config?.call(pluginContext, config);
796
+ if (out) config = out;
797
+ }
798
+ },
799
+ getOptions() {
800
+ return options;
801
+ },
802
+ getConfig() {
803
+ return config;
804
+ },
805
+ /**
806
+ * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
807
+ */
808
+ getCompiledConfigPath() {
809
+ return import_node_path2.default.join(options.outDir, "source.config.mjs");
810
+ },
811
+ getPlugins() {
812
+ return plugins;
813
+ },
814
+ getPluginContext() {
815
+ return pluginContext;
816
+ },
817
+ async initServer(server) {
818
+ for (const plugin of plugins) {
819
+ await plugin.configureServer?.call(pluginContext, server);
820
+ }
821
+ },
822
+ async emit({ filterPlugin = () => true } = {}) {
823
+ return (await Promise.all(
824
+ plugins.map((plugin) => {
825
+ if (!filterPlugin(plugin) || !plugin.emit) return [];
826
+ return plugin.emit.call(pluginContext);
827
+ })
828
+ )).flat();
829
+ },
830
+ async emitAndWrite(emitOptions) {
831
+ const start = performance.now();
832
+ const out = await this.emit(emitOptions);
833
+ await Promise.all(
834
+ out.map(async (entry) => {
835
+ const file = import_node_path2.default.join(options.outDir, entry.path);
836
+ await import_promises.default.mkdir(import_node_path2.default.dirname(file), { recursive: true });
837
+ await import_promises.default.writeFile(file, entry.content);
838
+ })
839
+ );
840
+ console.log(`[MDX] generated files in ${performance.now() - start}ms`);
841
+ },
842
+ async transformMeta(options2, data) {
843
+ const ctx = {
844
+ ...pluginContext,
845
+ ...options2
846
+ };
847
+ data = await transformMetadata(options2, data);
848
+ for (const plugin of plugins) {
849
+ if (plugin.meta?.transform)
850
+ data = await plugin.meta.transform.call(ctx, data) ?? data;
851
+ }
852
+ return data;
853
+ },
854
+ async transformFrontmatter(options2, data) {
855
+ const ctx = {
856
+ ...pluginContext,
857
+ ...options2
858
+ };
859
+ data = await transformMetadata(options2, data);
860
+ for (const plugin of plugins) {
861
+ if (plugin.doc?.frontmatter)
862
+ data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
863
+ }
864
+ return data;
865
+ },
866
+ async transformVFile(options2, file) {
867
+ const ctx = {
868
+ ...pluginContext,
869
+ ...options2
870
+ };
871
+ for (const plugin of plugins) {
872
+ if (plugin.doc?.vfile)
873
+ file = await plugin.doc.vfile.call(ctx, file) ?? file;
874
+ }
875
+ return file;
679
876
  }
680
877
  };
878
+ const pluginContext = {
879
+ core: core2,
880
+ ...options
881
+ };
882
+ return core2;
681
883
  }
682
- function getMdastExport(name, value) {
884
+ function postprocessPlugin() {
885
+ const LinkReferenceTypes = `{
886
+ /**
887
+ * extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
888
+ */
889
+ extractedReferences?: import('fumadocs-mdx').ExtractedReference[];
890
+ }`;
683
891
  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
- }
892
+ "index-file": {
893
+ generateTypeConfig() {
894
+ const lines = [];
895
+ lines.push("{");
896
+ lines.push(" DocData: {");
897
+ for (const collection of this.core.getConfig().collectionList) {
898
+ let postprocessOptions;
899
+ switch (collection.type) {
900
+ case "doc":
901
+ postprocessOptions = collection.postprocess;
902
+ break;
903
+ case "docs":
904
+ postprocessOptions = collection.docs.postprocess;
905
+ break;
710
906
  }
711
- ]
907
+ if (postprocessOptions?.extractLinkReferences) {
908
+ lines.push(ident(`${collection.name}: ${LinkReferenceTypes},`, 2));
909
+ }
910
+ }
911
+ lines.push(" }");
912
+ lines.push("}");
913
+ return lines.join("\n");
914
+ },
915
+ serverOptions(options) {
916
+ options.doc ??= {};
917
+ options.doc.passthroughs ??= [];
918
+ options.doc.passthroughs.push("extractedReferences");
712
919
  }
713
920
  }
714
921
  };
715
922
  }
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 "";
721
- }
722
-
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);
757
- }
758
- return processor;
759
- }
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
770
- }
771
- });
772
- }
773
923
 
774
924
  // src/loaders/mdx/index.ts
925
+ init_fuma_matter();
775
926
  var import_zod = require("zod");
776
927
  var import_promises2 = __toESM(require("fs/promises"), 1);
777
928
  var import_node_path3 = __toESM(require("path"), 1);
@@ -801,10 +952,10 @@ function createMdxLoader(configLoader2) {
801
952
  compiler,
802
953
  filePath
803
954
  }) {
955
+ const config = await configLoader2.getConfig();
804
956
  const value = await getSource();
805
957
  const matter = fumaMatter(value);
806
958
  const parsed = querySchema.parse(query);
807
- const config = await configLoader2.getConfig();
808
959
  let after;
809
960
  if (!isDevelopment && config.global.experimentalBuildCache) {
810
961
  const cacheDir = config.global.experimentalBuildCache;
@@ -832,15 +983,10 @@ function createMdxLoader(configLoader2) {
832
983
  docCollection = collection.docs;
833
984
  break;
834
985
  }
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}`
986
+ if (docCollection) {
987
+ matter.data = await configLoader2.core.transformFrontmatter(
988
+ { collection: docCollection, filePath, source: value },
989
+ matter.data
844
990
  );
845
991
  }
846
992
  if (parsed.only === "frontmatter") {
@@ -849,24 +995,16 @@ function createMdxLoader(configLoader2) {
849
995
  map: null
850
996
  };
851
997
  }
852
- const data = {};
853
- if (config.global.lastModifiedTime === "git") {
854
- data.lastModified = (await getGitTimestamp(filePath))?.getTime();
855
- }
856
998
  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
- );
999
+ const { buildMDX: buildMDX2 } = await Promise.resolve().then(() => (init_build_mdx(), build_mdx_exports));
1000
+ const compiled = await buildMDX2(configLoader2.core, docCollection, {
1001
+ isDevelopment,
1002
+ source: "\n".repeat(lineOffset) + matter.content,
1003
+ filePath,
1004
+ frontmatter: matter.data,
1005
+ _compiler: compiler,
1006
+ environment: "bundler"
1007
+ });
870
1008
  const out = {
871
1009
  code: String(compiled.value),
872
1010
  map: compiled.map
@@ -876,14 +1014,6 @@ function createMdxLoader(configLoader2) {
876
1014
  }
877
1015
  };
878
1016
  }
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
1017
  function generateCacheHash(input) {
888
1018
  return (0, import_node_crypto.createHash)("md5").update(input).digest("hex");
889
1019
  }
@@ -938,9 +1068,9 @@ function createStandaloneConfigLoader({
938
1068
  mode
939
1069
  }) {
940
1070
  let loaded;
941
- async function getConfigHash2() {
1071
+ async function getConfigHash() {
942
1072
  if (mode === "production") return "static";
943
- const stats = await import_promises4.default.stat(core2._options.configPath).catch(() => {
1073
+ const stats = await import_promises4.default.stat(core2.getOptions().configPath).catch(() => {
944
1074
  throw new Error("Cannot find config file");
945
1075
  });
946
1076
  return stats.mtime.getTime().toString();
@@ -948,17 +1078,14 @@ function createStandaloneConfigLoader({
948
1078
  async function newConfig() {
949
1079
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_load_from_file(), load_from_file_exports));
950
1080
  await core2.init({
951
- config: loadConfig2(
952
- core2._options.configPath,
953
- core2._options.outDir,
954
- buildConfig2
955
- )
1081
+ config: loadConfig2(core2, buildConfig2)
956
1082
  });
957
1083
  return core2.getConfig();
958
1084
  }
959
1085
  return {
1086
+ core: core2,
960
1087
  async getConfig() {
961
- const hash = await getConfigHash2();
1088
+ const hash = await getConfigHash();
962
1089
  if (loaded && loaded.hash === hash) return loaded.config;
963
1090
  loaded = {
964
1091
  hash,
@@ -975,63 +1102,73 @@ var import_zod2 = require("zod");
975
1102
  var querySchema2 = import_zod2.z.object({
976
1103
  collection: import_zod2.z.string().optional()
977
1104
  }).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)}`;
1105
+ function createMetaLoader(configLoader2, resolve2 = {}) {
1106
+ const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve2;
1107
+ function parse2(filePath, source) {
1108
+ try {
1109
+ if (filePath.endsWith(".json")) return JSON.parse(source);
1110
+ if (filePath.endsWith(".yaml")) return (0, import_js_yaml2.load)(source);
1111
+ } catch (e) {
1112
+ throw new Error(`invalid data in ${filePath}`, { cause: e });
985
1113
  }
1114
+ throw new Error("Unknown file type " + filePath);
986
1115
  }
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;
1116
+ function onMeta(source, { filePath, query }) {
1117
+ const parsed = querySchema2.safeParse(query);
1118
+ if (!parsed.success || !parsed.data.collection) return null;
1119
+ const collectionName = parsed.data.collection;
1120
+ return async () => {
1121
+ const config = await configLoader2.getConfig();
1122
+ const collection = config.getCollection(collectionName);
1123
+ let metaCollection;
1002
1124
  switch (collection?.type) {
1003
1125
  case "meta":
1004
- schema = collection.schema;
1126
+ metaCollection = collection;
1005
1127
  break;
1006
1128
  case "docs":
1007
- schema = collection.meta.schema;
1129
+ metaCollection = collection.meta;
1008
1130
  break;
1009
1131
  }
1010
- if (schema) {
1011
- data = await validate(
1012
- schema,
1013
- data,
1014
- { path: filePath, source },
1015
- `invalid data in ${filePath}`
1016
- );
1132
+ const data = parse2(filePath, source);
1133
+ if (!metaCollection) return data;
1134
+ return configLoader2.core.transformMeta(
1135
+ {
1136
+ collection: metaCollection,
1137
+ filePath,
1138
+ source
1139
+ },
1140
+ data
1141
+ );
1142
+ };
1143
+ }
1144
+ return {
1145
+ test: metaLoaderGlob,
1146
+ async load(input) {
1147
+ const result = onMeta(await input.getSource(), input);
1148
+ if (result === null) return null;
1149
+ const data = await result();
1150
+ if (input.filePath.endsWith(".json")) {
1151
+ return {
1152
+ code: resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}`
1153
+ };
1154
+ } else {
1155
+ return {
1156
+ code: resolveYaml === "yaml" ? (0, import_js_yaml2.dump)(data) : `export default ${JSON.stringify(data)}`
1157
+ };
1017
1158
  }
1018
- return {
1019
- code: stringifyOutput(isJson, data)
1020
- };
1021
1159
  },
1022
1160
  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 {
1161
+ load(source, input) {
1162
+ const result = onMeta(source, input);
1163
+ if (result === null)
1164
+ return {
1165
+ loader: "object",
1166
+ exports: parse2(input.filePath, source)
1167
+ };
1168
+ return result().then((data) => ({
1032
1169
  loader: "object",
1033
- exports: data
1034
- };
1170
+ exports: { default: data }
1171
+ }));
1035
1172
  }
1036
1173
  }
1037
1174
  };
@@ -1040,8 +1177,8 @@ function createMetaLoader(configLoader2, resolve3 = {}) {
1040
1177
  // src/node/loader.ts
1041
1178
  var core = createCore({
1042
1179
  environment: "node",
1043
- configPath: findConfigFile(),
1044
- outDir: ".source"
1180
+ configPath: _Defaults.configPath,
1181
+ outDir: _Defaults.outDir
1045
1182
  });
1046
1183
  var configLoader = createStandaloneConfigLoader({
1047
1184
  core,