fumadocs-mdx 12.0.3 → 13.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 (80) hide show
  1. package/dist/bin.cjs +1116 -359
  2. package/dist/bin.js +4 -4
  3. package/dist/build-mdx-CCNr86q6.d.ts +53 -0
  4. package/dist/build-mdx-D-r3_eQL.d.cts +53 -0
  5. package/dist/bun/index.cjs +196 -52
  6. package/dist/bun/index.d.cts +8 -3
  7. package/dist/bun/index.d.ts +8 -3
  8. package/dist/bun/index.js +19 -10
  9. package/dist/{chunk-QAUWMR5D.js → chunk-3J3WL7WN.js} +23 -5
  10. package/dist/{chunk-6Y5JDZHD.js → chunk-CXA4JO4Z.js} +1 -21
  11. package/dist/chunk-EELYB2XC.js +207 -0
  12. package/dist/{chunk-46UPKP5R.js → chunk-II3H5ZVZ.js} +5 -5
  13. package/dist/{chunk-LGYVNESJ.js → chunk-JVZFH6ND.js} +6 -22
  14. package/dist/{chunk-LMG6UWCL.js → chunk-K5ZLPEIQ.js} +56 -16
  15. package/dist/{chunk-OMAMTKDE.js → chunk-KILFIBVW.js} +3 -12
  16. package/dist/chunk-NVRDCY6Z.js +30 -0
  17. package/dist/{chunk-RMDXSZYE.js → chunk-XQ5O7IPO.js} +31 -24
  18. package/dist/chunk-XZY2AWJI.js +81 -0
  19. package/dist/{chunk-VXEBLM4X.js → chunk-YVCR6FUH.js} +1 -1
  20. package/dist/config/index.cjs +56 -16
  21. package/dist/config/index.d.cts +2 -1
  22. package/dist/config/index.d.ts +2 -1
  23. package/dist/config/index.js +1 -1
  24. package/dist/{define-DJbJduHy.d.ts → core-B6j6Fxse.d.cts} +89 -2
  25. package/dist/{define-DJbJduHy.d.cts → core-B6j6Fxse.d.ts} +89 -2
  26. package/dist/index.cjs +0 -109
  27. package/dist/index.d.cts +75 -9
  28. package/dist/index.d.ts +75 -9
  29. package/dist/index.js +0 -11
  30. package/dist/{load-UUXLUBHL.js → load-MNG3CLET.js} +1 -3
  31. package/dist/next/index.cjs +298 -234
  32. package/dist/next/index.d.cts +2 -11
  33. package/dist/next/index.d.ts +2 -11
  34. package/dist/next/index.js +177 -141
  35. package/dist/node/loader.cjs +228 -85
  36. package/dist/node/loader.js +19 -9
  37. package/dist/plugins/json-schema.cjs +162 -0
  38. package/dist/plugins/json-schema.d.cts +24 -0
  39. package/dist/plugins/json-schema.d.ts +24 -0
  40. package/dist/plugins/json-schema.js +78 -0
  41. package/dist/runtime/next/async.cjs +108 -70
  42. package/dist/runtime/next/async.d.cts +9 -6
  43. package/dist/runtime/next/async.d.ts +9 -6
  44. package/dist/runtime/next/async.js +8 -18
  45. package/dist/runtime/next/index.cjs +25 -14
  46. package/dist/runtime/next/index.d.cts +11 -8
  47. package/dist/runtime/next/index.d.ts +11 -8
  48. package/dist/runtime/next/index.js +2 -2
  49. package/dist/runtime/vite/browser.cjs +7 -3
  50. package/dist/runtime/vite/browser.d.cts +56 -7
  51. package/dist/runtime/vite/browser.d.ts +56 -7
  52. package/dist/runtime/vite/browser.js +2 -1
  53. package/dist/runtime/vite/server.cjs +40 -34
  54. package/dist/runtime/vite/server.d.cts +13 -10
  55. package/dist/runtime/vite/server.d.ts +13 -10
  56. package/dist/runtime/vite/server.js +8 -23
  57. package/dist/{types-TeHjsmja.d.ts → types-AGzTfBmf.d.ts} +3 -10
  58. package/dist/{types-BRx1QsIJ.d.cts → types-DKGMoay5.d.cts} +3 -10
  59. package/dist/vite/index.cjs +443 -249
  60. package/dist/vite/index.d.cts +23 -10
  61. package/dist/vite/index.d.ts +23 -10
  62. package/dist/vite/index.js +213 -36
  63. package/dist/{loader-mdx.cjs → webpack/index.cjs} +268 -82
  64. package/dist/{loader-mdx.d.ts → webpack/index.d.cts} +1 -0
  65. package/dist/{loader-mdx.d.cts → webpack/index.d.ts} +1 -0
  66. package/dist/webpack/index.js +44 -0
  67. package/loader-mdx.cjs +1 -1
  68. package/package.json +30 -16
  69. package/dist/browser-BupUnhpC.d.ts +0 -98
  70. package/dist/browser-R0x9IPaQ.d.cts +0 -98
  71. package/dist/chunk-ADR6R7HM.js +0 -29
  72. package/dist/chunk-IQAEAI4P.js +0 -66
  73. package/dist/chunk-XMFLD5J6.js +0 -30
  74. package/dist/chunk-ZLCSVXCD.js +0 -10
  75. package/dist/chunk-ZX7TM4AR.js +0 -127
  76. package/dist/loader-mdx.js +0 -25
  77. package/dist/postinstall-SCSXM4IM.js +0 -10
  78. package/dist/shared-CfiiRctw.d.ts +0 -70
  79. package/dist/shared-fFqiuWJC.d.cts +0 -70
  80. package/dist/watcher-HGOH3APP.js +0 -22
@@ -193,67 +193,22 @@ async function compileConfig(configPath, outDir) {
193
193
  throw new Error("failed to compile configuration file");
194
194
  }
195
195
  }
196
- async function loadConfig(configPath, outDir, hash, build = false) {
197
- if (cache && cache.hash === hash) {
198
- return await cache.config;
199
- }
196
+ async function loadConfig(configPath, outDir, build = false) {
200
197
  if (build) await compileConfig(configPath, outDir);
201
- const url = (0, import_node_url.pathToFileURL)(path.resolve(outDir, "source.config.mjs"));
202
- const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
203
- return buildConfig(
204
- // every call to `loadConfig` will cause the previous cache to be ignored
205
- loaded
206
- );
207
- });
208
- if (hash) cache = { config, hash };
198
+ const url = (0, import_node_url.pathToFileURL)(path2.resolve(outDir, "source.config.mjs"));
199
+ url.searchParams.set("hash", Date.now().toString());
200
+ const config = import(url.href).then(
201
+ (loaded) => buildConfig(loaded)
202
+ );
209
203
  return await config;
210
204
  }
211
- async function getConfigHash(configPath) {
212
- const stats = await fs.stat(configPath).catch(() => void 0);
213
- if (stats) {
214
- return stats.mtime.getTime().toString();
215
- }
216
- throw new Error("Cannot find config file");
217
- }
218
- var fs, path, import_node_url, cache;
205
+ var path2, import_node_url;
219
206
  var init_load = __esm({
220
207
  "src/loaders/config/load.ts"() {
221
208
  "use strict";
222
- fs = __toESM(require("fs/promises"), 1);
223
- path = __toESM(require("path"), 1);
209
+ path2 = __toESM(require("path"), 1);
224
210
  import_node_url = require("url");
225
211
  init_build();
226
- cache = null;
227
- }
228
- });
229
-
230
- // src/next/map/watcher.ts
231
- var watcher_exports = {};
232
- __export(watcher_exports, {
233
- watcher: () => watcher
234
- });
235
- function watcher(configPath, config, ignored) {
236
- const watcher2 = new import_chokidar.FSWatcher({
237
- ignoreInitial: true,
238
- persistent: true,
239
- ignored
240
- });
241
- watcher2.add(configPath);
242
- for (const collection of config.collections.values()) {
243
- if (collection.type === "docs") {
244
- watcher2.add(collection.docs.dir);
245
- watcher2.add(collection.meta.dir);
246
- } else {
247
- watcher2.add(collection.dir);
248
- }
249
- }
250
- return watcher2;
251
- }
252
- var import_chokidar;
253
- var init_watcher = __esm({
254
- "src/next/map/watcher.ts"() {
255
- "use strict";
256
- import_chokidar = require("chokidar");
257
212
  }
258
213
  });
259
214
 
@@ -261,18 +216,45 @@ var init_watcher = __esm({
261
216
  var next_exports = {};
262
217
  __export(next_exports, {
263
218
  createMDX: () => createMDX,
264
- postInstall: () => postInstall,
265
- start: () => start
219
+ postInstall: () => postInstall
266
220
  });
267
221
  module.exports = __toCommonJS(next_exports);
222
+
223
+ // src/loaders/config/index.ts
224
+ var import_node_path = __toESM(require("path"), 1);
225
+ var import_promises = __toESM(require("fs/promises"), 1);
226
+ function findConfigFile() {
227
+ return import_node_path.default.resolve("source.config.ts");
228
+ }
229
+
230
+ // src/next/index.ts
231
+ var path9 = __toESM(require("path"), 1);
268
232
  init_load();
269
- var import_node_path5 = __toESM(require("path"), 1);
270
- var import_promises2 = __toESM(require("fs/promises"), 1);
271
233
 
272
- // src/next/map/generate.ts
273
- var path5 = __toESM(require("path"), 1);
274
- var import_node_crypto = require("crypto");
275
- var import_tinyglobby = require("tinyglobby");
234
+ // src/next/file-cache.ts
235
+ var import_lru_cache = require("lru-cache");
236
+ var import_promises2 = __toESM(require("fs/promises"), 1);
237
+ var import_node_path2 = __toESM(require("path"), 1);
238
+ var map = new import_lru_cache.LRUCache({
239
+ max: 100
240
+ });
241
+ function toFullPath(file) {
242
+ if (import_node_path2.default.isAbsolute(file)) {
243
+ return import_node_path2.default.relative(process.cwd(), file);
244
+ }
245
+ return file;
246
+ }
247
+ async function readFileWithCache(file) {
248
+ const fullPath = toFullPath(file);
249
+ const cached = map.get(fullPath);
250
+ if (cached) return cached;
251
+ const read = import_promises2.default.readFile(fullPath).then((s) => s.toString());
252
+ map.set(fullPath, read);
253
+ return read;
254
+ }
255
+ function removeFileCache(file) {
256
+ map.delete(toFullPath(file));
257
+ }
276
258
 
277
259
  // src/utils/validation.ts
278
260
  var import_picocolors = __toESM(require("picocolors"), 1);
@@ -312,51 +294,28 @@ async function validate(schema, data, context, errorMessage) {
312
294
  return data;
313
295
  }
314
296
 
315
- // src/next/map/file-cache.ts
316
- var import_lru_cache = require("lru-cache");
317
- var import_promises = __toESM(require("fs/promises"), 1);
318
- var import_node_path = __toESM(require("path"), 1);
319
- var map = new import_lru_cache.LRUCache({
320
- max: 100
321
- });
322
- function toFullPath(file) {
323
- if (import_node_path.default.isAbsolute(file)) {
324
- return import_node_path.default.relative(process.cwd(), file);
325
- }
326
- return file;
327
- }
328
- async function readFileWithCache(file) {
329
- const fullPath = toFullPath(file);
330
- const cached = map.get(fullPath);
331
- if (cached) return cached;
332
- const read = import_promises.default.readFile(fullPath).then((s) => s.toString());
333
- map.set(fullPath, read);
334
- return read;
335
- }
336
- function removeFileCache(file) {
337
- map.delete(toFullPath(file));
338
- }
339
-
340
- // src/next/map/generate.ts
297
+ // src/plugins/next.ts
298
+ var path7 = __toESM(require("path"), 1);
299
+ var import_node_crypto = require("crypto");
341
300
  var import_js_yaml2 = require("js-yaml");
342
301
 
343
302
  // src/utils/git-timestamp.ts
344
- var import_node_path2 = __toESM(require("path"), 1);
303
+ var import_node_path3 = __toESM(require("path"), 1);
345
304
  var import_tinyexec = require("tinyexec");
346
- var cache2 = /* @__PURE__ */ new Map();
305
+ var cache = /* @__PURE__ */ new Map();
347
306
  async function getGitTimestamp(file) {
348
- const cached = cache2.get(file);
307
+ const cached = cache.get(file);
349
308
  if (cached) return cached;
350
309
  try {
351
310
  const out = await (0, import_tinyexec.x)(
352
311
  "git",
353
- ["log", "-1", '--pretty="%ai"', import_node_path2.default.relative(process.cwd(), file)],
312
+ ["log", "-1", '--pretty="%ai"', import_node_path3.default.relative(process.cwd(), file)],
354
313
  {
355
314
  throwOnError: true
356
315
  }
357
316
  );
358
317
  const time = new Date(out.stdout);
359
- cache2.set(file, time);
318
+ cache.set(file, time);
360
319
  return time;
361
320
  } catch {
362
321
  return;
@@ -380,7 +339,7 @@ function fumaMatter(input) {
380
339
  }
381
340
 
382
341
  // src/utils/import-formatter.ts
383
- var import_node_path3 = __toESM(require("path"), 1);
342
+ var import_node_path4 = __toESM(require("path"), 1);
384
343
  function getImportCode(info) {
385
344
  const specifier = JSON.stringify(info.specifier);
386
345
  if (info.type === "default") return `import ${info.name} from ${specifier}`;
@@ -395,7 +354,7 @@ function getImportCode(info) {
395
354
  return `import ${specifier}`;
396
355
  }
397
356
  function toImportPath(file, config) {
398
- const ext = import_node_path3.default.extname(file);
357
+ const ext = import_node_path4.default.extname(file);
399
358
  let filename;
400
359
  if (ext === ".ts" && config.jsExtension) {
401
360
  filename = file.substring(0, file.length - ext.length) + ".js";
@@ -406,36 +365,92 @@ function toImportPath(file, config) {
406
365
  }
407
366
  let importPath;
408
367
  if ("relativeTo" in config) {
409
- importPath = import_node_path3.default.relative(config.relativeTo, filename);
410
- if (!import_node_path3.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
368
+ importPath = import_node_path4.default.relative(config.relativeTo, filename);
369
+ if (!import_node_path4.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
411
370
  importPath = `./${importPath}`;
412
371
  }
413
372
  } else {
414
- importPath = import_node_path3.default.resolve(filename);
373
+ importPath = import_node_path4.default.resolve(filename);
415
374
  }
416
- return importPath.replaceAll(import_node_path3.default.sep, "/");
375
+ return importPath.replaceAll(import_node_path4.default.sep, "/");
417
376
  }
418
377
 
419
378
  // src/utils/collections.ts
420
- function getSupportedFormats(collection) {
421
- return {
422
- doc: ["mdx", "md"],
423
- meta: ["json", "yaml"]
424
- }[collection.type];
425
- }
379
+ var import_picomatch = __toESM(require("picomatch"), 1);
380
+ var import_tinyglobby = require("tinyglobby");
381
+ var import_node_path5 = __toESM(require("path"), 1);
382
+ var SupportedFormats = {
383
+ doc: ["mdx", "md"],
384
+ meta: ["json", "yaml"]
385
+ };
426
386
  function getGlobPatterns(collection) {
427
387
  if (collection.files) return collection.files;
428
- return [`**/*.{${getSupportedFormats(collection).join(",")}}`];
388
+ return [`**/*.{${SupportedFormats[collection.type].join(",")}}`];
429
389
  }
430
390
  function isFileSupported(filePath, collection) {
431
- for (const format of getSupportedFormats(collection)) {
432
- if (filePath.endsWith(`.${format}`)) return true;
433
- }
434
- return false;
391
+ return SupportedFormats[collection.type].some(
392
+ (format) => filePath.endsWith(`.${format}`)
393
+ );
394
+ }
395
+ async function getCollectionFiles(collection) {
396
+ const files = /* @__PURE__ */ new Map();
397
+ const dirs = Array.isArray(collection.dir) ? collection.dir : [collection.dir];
398
+ const patterns = getGlobPatterns(collection);
399
+ await Promise.all(
400
+ dirs.map(async (dir) => {
401
+ const result = await (0, import_tinyglobby.glob)(patterns, {
402
+ cwd: import_node_path5.default.resolve(dir)
403
+ });
404
+ for (const item of result) {
405
+ if (!isFileSupported(item, collection)) continue;
406
+ const fullPath = import_node_path5.default.join(dir, item);
407
+ files.set(fullPath, {
408
+ path: item,
409
+ fullPath
410
+ });
411
+ }
412
+ })
413
+ );
414
+ return Array.from(files.values());
435
415
  }
436
416
 
437
- // src/next/map/generate.ts
438
- async function generateJS(configPath, config, importPath, configHash = false) {
417
+ // src/plugins/next.ts
418
+ function next() {
419
+ let config;
420
+ let shouldEmitOnChange = false;
421
+ return {
422
+ name: "next",
423
+ config(v) {
424
+ config = v;
425
+ shouldEmitOnChange = false;
426
+ for (const collection of config.collections.values()) {
427
+ if (collection.type === "doc" && collection.async || collection.type === "docs" && collection.docs.async) {
428
+ shouldEmitOnChange = true;
429
+ }
430
+ }
431
+ },
432
+ configureServer(server) {
433
+ if (!server.watcher) return;
434
+ server.watcher.on("all", async () => {
435
+ if (!shouldEmitOnChange) return;
436
+ await this.core.emitAndWrite({
437
+ filterPlugin: (plugin) => plugin.name === "next"
438
+ });
439
+ });
440
+ },
441
+ async emit() {
442
+ return [
443
+ {
444
+ path: "index.ts",
445
+ content: await indexFile(this.configPath, config, {
446
+ relativeTo: this.outDir
447
+ })
448
+ }
449
+ ];
450
+ }
451
+ };
452
+ }
453
+ async function indexFile(configPath, config, importPath, configHash = false) {
439
454
  let asyncInit = false;
440
455
  const lines = [
441
456
  getImportCode({
@@ -564,29 +579,8 @@ async function generateJS(configPath, config, importPath, configHash = false) {
564
579
  ...resolvedDeclares
565
580
  ].join("\n");
566
581
  }
567
- async function getCollectionFiles(collection) {
568
- const files = /* @__PURE__ */ new Map();
569
- const dirs = Array.isArray(collection.dir) ? collection.dir : [collection.dir];
570
- const patterns = getGlobPatterns(collection);
571
- await Promise.all(
572
- dirs.map(async (dir) => {
573
- const result = await (0, import_tinyglobby.glob)(patterns, {
574
- cwd: path5.resolve(dir)
575
- });
576
- for (const item of result) {
577
- if (!isFileSupported(item, collection)) continue;
578
- const fullPath = path5.join(dir, item);
579
- files.set(fullPath, {
580
- path: item,
581
- fullPath
582
- });
583
- }
584
- })
585
- );
586
- return Array.from(files.values());
587
- }
588
582
  function parseMetaEntry(file, content) {
589
- const extname2 = path5.extname(file);
583
+ const extname2 = path7.extname(file);
590
584
  try {
591
585
  if (extname2 === ".json") return JSON.parse(content);
592
586
  if (extname2 === ".yaml") return (0, import_js_yaml2.load)(content);
@@ -598,98 +592,96 @@ function parseMetaEntry(file, content) {
598
592
  throw new Error(`Unknown meta file format: ${extname2}, in ${file}.`);
599
593
  }
600
594
 
601
- // src/loaders/config/index.ts
602
- var import_node_path4 = __toESM(require("path"), 1);
603
- function findConfigFile() {
604
- return import_node_path4.default.resolve("source.config.ts");
605
- }
606
-
607
- // src/next/map/index.ts
608
- var path7 = __toESM(require("path"), 1);
609
- var fs3 = __toESM(require("fs/promises"), 1);
610
- init_load();
611
- async function start(dev, configPath, outDir) {
612
- let configHash = await getConfigHash(configPath);
613
- let config = await loadConfig(configPath, outDir, configHash, true);
614
- const outPath = path7.resolve(outDir, `index.ts`);
615
- async function updateMapFile() {
616
- const start2 = performance.now();
617
- try {
618
- await fs3.writeFile(
619
- outPath,
620
- await generateJS(
621
- configPath,
622
- config,
623
- { relativeTo: outDir },
624
- configHash
625
- )
626
- );
627
- } catch (err) {
628
- if (err instanceof ValidationError) {
629
- console.error(err.toStringFormatted());
630
- } else {
631
- console.error(err);
595
+ // src/core.ts
596
+ var import_node_path6 = __toESM(require("path"), 1);
597
+ var import_promises3 = __toESM(require("fs/promises"), 1);
598
+ function createCore(options, defaultPlugins = []) {
599
+ let config;
600
+ let plugins2;
601
+ return {
602
+ _options: options,
603
+ getPluginContext() {
604
+ return {
605
+ core: this,
606
+ ...options
607
+ };
608
+ },
609
+ /**
610
+ * Convenient cache store, reset when config changes
611
+ */
612
+ cache: /* @__PURE__ */ new Map(),
613
+ async init({ config: newConfig }) {
614
+ config = await newConfig;
615
+ this.cache.clear();
616
+ plugins2 = [];
617
+ for await (const option of [
618
+ ...defaultPlugins,
619
+ ...config.global.plugins ?? []
620
+ ]) {
621
+ if (!option) continue;
622
+ if (Array.isArray(option)) plugins2.push(...option);
623
+ else plugins2.push(option);
632
624
  }
633
- }
634
- console.log(`[MDX] updated map file in ${performance.now() - start2}ms`);
635
- }
636
- await updateMapFile();
637
- if (dev) {
638
- const { watcher: watcher2 } = await Promise.resolve().then(() => (init_watcher(), watcher_exports));
639
- const instance = watcher2(configPath, config, [outPath]);
640
- instance.on("ready", () => {
641
- console.log("[MDX] started dev server");
642
- });
643
- instance.on("all", (event, file) => {
644
- if (typeof file !== "string") return;
645
- const absolutePath = path7.resolve(file);
646
- const onUpdate = async () => {
647
- const isConfigFile = absolutePath === configPath;
648
- if (isConfigFile) {
649
- configHash = await getConfigHash(configPath);
650
- config = await loadConfig(configPath, outDir, configHash, true);
625
+ for (const plugin of plugins2) {
626
+ const out = await plugin.config?.call(this.getPluginContext(), config);
627
+ if (out) config = out;
628
+ }
629
+ return this;
630
+ },
631
+ getConfig() {
632
+ return config;
633
+ },
634
+ creatConfigLoader() {
635
+ return {
636
+ getConfig() {
637
+ return config;
651
638
  }
652
- if (event === "change") removeFileCache(absolutePath);
653
- await updateMapFile();
654
639
  };
655
- void onUpdate();
656
- });
657
- process.on("exit", () => {
658
- console.log("[MDX] closing dev server");
659
- void instance.close();
660
- });
661
- }
640
+ },
641
+ async initServer(server) {
642
+ for (const plugin of plugins2) {
643
+ await plugin.configureServer?.call(this.getPluginContext(), server);
644
+ }
645
+ },
646
+ async emitAndWrite({
647
+ filterPlugin = () => true
648
+ } = {}) {
649
+ const start = performance.now();
650
+ const out = await Promise.all(
651
+ plugins2.map((plugin) => {
652
+ if (!filterPlugin(plugin) || !plugin.emit) return [];
653
+ return plugin.emit.call(this.getPluginContext());
654
+ })
655
+ );
656
+ await Promise.all(
657
+ out.flat().map(async (entry) => {
658
+ const file = import_node_path6.default.join(options.outDir, entry.path);
659
+ await import_promises3.default.mkdir(import_node_path6.default.dirname(file), { recursive: true });
660
+ await import_promises3.default.writeFile(file, entry.content);
661
+ })
662
+ );
663
+ console.log(`[MDX] generated files in ${performance.now() - start}ms`);
664
+ }
665
+ };
662
666
  }
663
667
 
664
- // src/next/create.ts
665
- var import_node_fs = require("fs");
668
+ // src/next/index.ts
666
669
  var defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
667
- var isTurboExperimental;
668
- try {
669
- const content = (0, import_node_fs.readFileSync)("./node_modules/next/package.json").toString();
670
- const version = JSON.parse(content).version;
671
- isTurboExperimental = version.startsWith("15.0.") || version.startsWith("15.1.") || version.startsWith("15.2.");
672
- } catch {
673
- isTurboExperimental = false;
674
- }
675
- function createMDX({
676
- configPath = findConfigFile(),
677
- outDir = ".source"
678
- } = {}) {
670
+ function createMDX(createOptions = {}) {
671
+ const options = applyDefaults(createOptions);
672
+ const isDev = process.env.NODE_ENV === "development";
679
673
  if (process.env._FUMADOCS_MDX !== "1") {
680
674
  process.env._FUMADOCS_MDX = "1";
681
- void start(process.env.NODE_ENV === "development", configPath, outDir);
675
+ void init(isDev, options);
682
676
  }
683
677
  return (nextConfig = {}) => {
684
678
  const mdxLoaderOptions = {
685
- configPath,
686
- outDir
679
+ ...options,
680
+ isDev
687
681
  };
688
- const turbo = {
689
- ...nextConfig.experimental?.turbo,
682
+ const turbopack = {
690
683
  ...nextConfig.turbopack,
691
684
  rules: {
692
- ...nextConfig.experimental?.turbo?.rules,
693
685
  ...nextConfig.turbopack?.rules,
694
686
  "*.{md,mdx}": {
695
687
  loaders: [
@@ -702,17 +694,18 @@ function createMDX({
702
694
  }
703
695
  }
704
696
  };
705
- const updated = {
697
+ return {
706
698
  ...nextConfig,
699
+ turbopack,
707
700
  pageExtensions: nextConfig.pageExtensions ?? defaultPageExtensions,
708
- webpack: (config, options) => {
701
+ webpack: (config, options2) => {
709
702
  config.resolve ||= {};
710
703
  config.module ||= {};
711
704
  config.module.rules ||= [];
712
705
  config.module.rules.push({
713
706
  test: /\.mdx?$/,
714
707
  use: [
715
- options.defaultLoaders.babel,
708
+ options2.defaultLoaders.babel,
716
709
  {
717
710
  loader: "fumadocs-mdx/loader-mdx",
718
711
  options: mdxLoaderOptions
@@ -720,34 +713,105 @@ function createMDX({
720
713
  ]
721
714
  });
722
715
  config.plugins ||= [];
723
- return nextConfig.webpack?.(config, options) ?? config;
716
+ return nextConfig.webpack?.(config, options2) ?? config;
724
717
  }
725
718
  };
726
- if (isTurboExperimental) {
727
- updated.experimental = { ...updated.experimental, turbo };
728
- } else {
729
- updated.turbopack = turbo;
730
- }
731
- return updated;
732
719
  };
733
720
  }
734
-
735
- // src/next/index.ts
721
+ async function init(dev, options) {
722
+ const core = createNextCore(options);
723
+ async function initOrReload() {
724
+ await core.init({
725
+ config: loadConfig(options.configPath, options.outDir, true)
726
+ });
727
+ await core.emitAndWrite();
728
+ }
729
+ async function devServer() {
730
+ const { FSWatcher } = await import("chokidar");
731
+ const watcher = new FSWatcher({
732
+ ignoreInitial: true,
733
+ persistent: true,
734
+ ignored: [options.outDir]
735
+ });
736
+ watcher.add(options.configPath);
737
+ for (const collection of core.getConfig().collections.values()) {
738
+ if (collection.type === "docs") {
739
+ watcher.add(collection.docs.dir);
740
+ watcher.add(collection.meta.dir);
741
+ } else {
742
+ watcher.add(collection.dir);
743
+ }
744
+ }
745
+ watcher.on("ready", () => {
746
+ console.log("[MDX] started dev server");
747
+ });
748
+ watcher.on("all", async (event, file) => {
749
+ const absolutePath = path9.resolve(file);
750
+ if (event === "change") removeFileCache(absolutePath);
751
+ if (absolutePath === path9.resolve(options.configPath)) {
752
+ watcher.removeAllListeners();
753
+ await watcher.close();
754
+ await initOrReload();
755
+ console.log("[MDX] restarting dev server");
756
+ await devServer();
757
+ }
758
+ });
759
+ process.on("exit", () => {
760
+ if (watcher.closed) return;
761
+ console.log("[MDX] closing dev server");
762
+ void watcher.close();
763
+ });
764
+ await core.initServer({ watcher });
765
+ }
766
+ await initOrReload();
767
+ if (dev) {
768
+ await devServer();
769
+ }
770
+ }
736
771
  async function postInstall(configPath = findConfigFile(), outDir = ".source") {
737
- const config = await loadConfig(configPath, outDir, void 0, true);
738
- const outPath = import_node_path5.default.join(outDir, "index.ts");
739
- await import_promises2.default.rm(outDir, { recursive: true });
740
- await import_promises2.default.mkdir(outDir, { recursive: true });
741
- const hash = await getConfigHash(configPath);
742
- await import_promises2.default.writeFile(
743
- outPath,
744
- await generateJS(configPath, config, { relativeTo: outDir }, hash)
772
+ const core = await createNextCore({
773
+ outDir,
774
+ configPath
775
+ }).init({
776
+ config: loadConfig(configPath, outDir, true)
777
+ });
778
+ await core.emitAndWrite();
779
+ }
780
+ function applyDefaults(options) {
781
+ return {
782
+ outDir: options.outDir ?? ".source",
783
+ configPath: options.configPath ?? findConfigFile()
784
+ };
785
+ }
786
+ function createNextCore({
787
+ outDir,
788
+ configPath
789
+ }) {
790
+ const core = createCore(
791
+ {
792
+ environment: "next",
793
+ outDir,
794
+ configPath
795
+ },
796
+ [next()]
745
797
  );
746
- console.log("[MDX] types generated");
798
+ return {
799
+ ...core,
800
+ async emitAndWrite(...args) {
801
+ try {
802
+ await core.emitAndWrite(...args);
803
+ } catch (err) {
804
+ if (err instanceof ValidationError) {
805
+ console.error(err.toStringFormatted());
806
+ } else {
807
+ console.error(err);
808
+ }
809
+ }
810
+ }
811
+ };
747
812
  }
748
813
  // Annotate the CommonJS export names for ESM import in node:
749
814
  0 && (module.exports = {
750
815
  createMDX,
751
- postInstall,
752
- start
816
+ postInstall
753
817
  });