fumadocs-mdx 11.5.8 → 11.6.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.
@@ -1,5 +1,6 @@
1
1
  // src/utils/schema.ts
2
2
  import { z } from "zod";
3
+ import picocolors from "picocolors";
3
4
  var metaSchema = z.object({
4
5
  title: z.string().optional(),
5
6
  pages: z.array(z.string()).optional(),
@@ -16,6 +17,28 @@ var frontmatterSchema = z.object({
16
17
  // Fumadocs OpenAPI generated
17
18
  _openapi: z.object({}).passthrough().optional()
18
19
  });
20
+ var ValidationError = class extends Error {
21
+ constructor(message, issues) {
22
+ super(message);
23
+ this.issues = issues;
24
+ }
25
+ print() {
26
+ console.error(
27
+ [
28
+ `[MDX] ${this.message}:`,
29
+ ...this.issues.map(
30
+ (issue) => picocolors.redBright(
31
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
32
+ )
33
+ )
34
+ ].join("\n")
35
+ );
36
+ }
37
+ toString() {
38
+ return `${this.message}:
39
+ ${this.issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
40
+ }
41
+ };
19
42
  async function validate(schema, data, context, errorMessage) {
20
43
  if (typeof schema === "function" && !("~standard" in schema)) {
21
44
  schema = schema(context);
@@ -25,19 +48,16 @@ async function validate(schema, data, context, errorMessage) {
25
48
  data
26
49
  );
27
50
  if (result.issues) {
28
- throw new Error(formatError(errorMessage, result.issues));
51
+ throw new ValidationError(errorMessage, result.issues);
29
52
  }
30
53
  return result.value;
31
54
  }
32
55
  return data;
33
56
  }
34
- function formatError(message, issues) {
35
- return `${message}:
36
- ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
37
- }
38
57
 
39
58
  export {
40
59
  metaSchema,
41
60
  frontmatterSchema,
61
+ ValidationError,
42
62
  validate
43
63
  };
@@ -42,6 +42,7 @@ module.exports = __toCommonJS(config_exports);
42
42
 
43
43
  // src/utils/schema.ts
44
44
  var import_zod = require("zod");
45
+ var import_picocolors = __toESM(require("picocolors"), 1);
45
46
  var metaSchema = import_zod.z.object({
46
47
  title: import_zod.z.string().optional(),
47
48
  pages: import_zod.z.array(import_zod.z.string()).optional(),
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  frontmatterSchema,
3
3
  metaSchema
4
- } from "../chunk-KGLACICA.js";
4
+ } from "../chunk-2ZOW45YZ.js";
5
5
  import {
6
6
  remarkInclude
7
7
  } from "../chunk-MK7EXW7O.js";
package/dist/index.d.cts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { PageData, MetaData, Source, VirtualFile } from 'fumadocs-core/source';
2
2
  import { B as BaseCollectionEntry } from './define-CGHfrlrJ.cjs';
3
- import { R as Runtime } from './types-DCyuz-WB.cjs';
4
- export { a as RuntimeFile } from './types-DCyuz-WB.cjs';
3
+ import { R as Runtime } from './types-CTLLuPxW.cjs';
5
4
  import '@mdx-js/mdx';
6
5
  import 'mdx/types';
7
6
  import 'fumadocs-core/mdx-plugins';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { PageData, MetaData, Source, VirtualFile } from 'fumadocs-core/source';
2
2
  import { B as BaseCollectionEntry } from './define-CGHfrlrJ.js';
3
- import { R as Runtime } from './types-DfVJrYH1.js';
4
- export { a as RuntimeFile } from './types-DfVJrYH1.js';
3
+ import { R as Runtime } from './types-CUbprvBB.js';
5
4
  import '@mdx-js/mdx';
6
5
  import 'mdx/types';
7
6
  import 'fumadocs-core/mdx-plugins';
@@ -389,6 +389,7 @@ function getGitTimestamp(file) {
389
389
 
390
390
  // src/utils/schema.ts
391
391
  var import_zod = require("zod");
392
+ var import_picocolors = __toESM(require("picocolors"), 1);
392
393
  var metaSchema = import_zod.z.object({
393
394
  title: import_zod.z.string().optional(),
394
395
  pages: import_zod.z.array(import_zod.z.string()).optional(),
@@ -405,6 +406,28 @@ var frontmatterSchema = import_zod.z.object({
405
406
  // Fumadocs OpenAPI generated
406
407
  _openapi: import_zod.z.object({}).passthrough().optional()
407
408
  });
409
+ var ValidationError = class extends Error {
410
+ constructor(message, issues) {
411
+ super(message);
412
+ this.issues = issues;
413
+ }
414
+ print() {
415
+ console.error(
416
+ [
417
+ `[MDX] ${this.message}:`,
418
+ ...this.issues.map(
419
+ (issue) => import_picocolors.default.redBright(
420
+ `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
421
+ )
422
+ )
423
+ ].join("\n")
424
+ );
425
+ }
426
+ toString() {
427
+ return `${this.message}:
428
+ ${this.issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
429
+ }
430
+ };
408
431
  async function validate(schema, data, context, errorMessage) {
409
432
  if (typeof schema === "function" && !("~standard" in schema)) {
410
433
  schema = schema(context);
@@ -414,16 +437,12 @@ async function validate(schema, data, context, errorMessage) {
414
437
  data
415
438
  );
416
439
  if (result.issues) {
417
- throw new Error(formatError(errorMessage, result.issues));
440
+ throw new ValidationError(errorMessage, result.issues);
418
441
  }
419
442
  return result.value;
420
443
  }
421
444
  return data;
422
445
  }
423
- function formatError(message, issues) {
424
- return `${message}:
425
- ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
426
- }
427
446
 
428
447
  // src/loader-mdx.ts
429
448
  function parseQuery(query) {
@@ -467,7 +486,7 @@ async function loader(source, callback) {
467
486
  source,
468
487
  path: filePath
469
488
  },
470
- `invalid frontmatter in ${filePath}:`
489
+ `invalid frontmatter in ${filePath}`
471
490
  );
472
491
  }
473
492
  let timestamp;
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-HFLDWPJA.js";
5
5
  import {
6
6
  validate
7
- } from "./chunk-KGLACICA.js";
7
+ } from "./chunk-2ZOW45YZ.js";
8
8
  import {
9
9
  remarkInclude
10
10
  } from "./chunk-MK7EXW7O.js";
@@ -118,7 +118,7 @@ async function loader(source, callback) {
118
118
  source,
119
119
  path: filePath
120
120
  },
121
- `invalid frontmatter in ${filePath}:`
121
+ `invalid frontmatter in ${filePath}`
122
122
  );
123
123
  }
124
124
  let timestamp;
@@ -35,7 +35,7 @@ var watcher_exports = {};
35
35
  __export(watcher_exports, {
36
36
  watcher: () => watcher
37
37
  });
38
- function watcher(configPath, config) {
38
+ function watcher(configPath, config, ignored) {
39
39
  const deps = [configPath];
40
40
  function add(dir) {
41
41
  if (Array.isArray(dir)) deps.push(...dir);
@@ -51,6 +51,7 @@ function watcher(configPath, config) {
51
51
  }
52
52
  return (0, import_chokidar.watch)(deps, {
53
53
  ignoreInitial: true,
54
+ ignored,
54
55
  persistent: true
55
56
  });
56
57
  }
@@ -167,11 +168,11 @@ async function getConfigHash(configPath) {
167
168
 
168
169
  // src/map/index.ts
169
170
  var path3 = __toESM(require("path"), 1);
170
- var fs4 = __toESM(require("fs/promises"), 1);
171
+ var fs3 = __toESM(require("fs/promises"), 1);
171
172
 
172
173
  // src/map/generate.ts
173
174
  var path2 = __toESM(require("path"), 1);
174
- var fs3 = __toESM(require("fs/promises"), 1);
175
+ var fs2 = __toESM(require("fs/promises"), 1);
175
176
  var import_fast_glob = __toESM(require("fast-glob"), 1);
176
177
 
177
178
  // src/utils/get-type-from-path.ts
@@ -186,6 +187,7 @@ function getTypeFromPath(path6) {
186
187
 
187
188
  // src/utils/schema.ts
188
189
  var import_zod = require("zod");
190
+ var import_picocolors = __toESM(require("picocolors"), 1);
189
191
  var metaSchema = import_zod.z.object({
190
192
  title: import_zod.z.string().optional(),
191
193
  pages: import_zod.z.array(import_zod.z.string()).optional(),
@@ -202,6 +204,28 @@ var frontmatterSchema = import_zod.z.object({
202
204
  // Fumadocs OpenAPI generated
203
205
  _openapi: import_zod.z.object({}).passthrough().optional()
204
206
  });
207
+ var ValidationError = class extends Error {
208
+ constructor(message, issues) {
209
+ super(message);
210
+ this.issues = issues;
211
+ }
212
+ print() {
213
+ console.error(
214
+ [
215
+ `[MDX] ${this.message}:`,
216
+ ...this.issues.map(
217
+ (issue) => import_picocolors.default.redBright(
218
+ `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
219
+ )
220
+ )
221
+ ].join("\n")
222
+ );
223
+ }
224
+ toString() {
225
+ return `${this.message}:
226
+ ${this.issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
227
+ }
228
+ };
205
229
  async function validate(schema, data, context, errorMessage) {
206
230
  if (typeof schema === "function" && !("~standard" in schema)) {
207
231
  schema = schema(context);
@@ -211,16 +235,12 @@ async function validate(schema, data, context, errorMessage) {
211
235
  data
212
236
  );
213
237
  if (result.issues) {
214
- throw new Error(formatError(errorMessage, result.issues));
238
+ throw new ValidationError(errorMessage, result.issues);
215
239
  }
216
240
  return result.value;
217
241
  }
218
242
  return data;
219
243
  }
220
- function formatError(message, issues) {
221
- return `${message}:
222
- ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
223
- }
224
244
 
225
245
  // src/map/file-cache.ts
226
246
  var import_lru_cache = require("lru-cache");
@@ -242,46 +262,12 @@ var fileCache = {
242
262
  }
243
263
  };
244
264
 
245
- // src/utils/read-frontmatter.ts
246
- var fs2 = __toESM(require("fs"), 1);
247
- var import_gray_matter = __toESM(require("gray-matter"), 1);
248
- async function readFrontmatter(file) {
249
- const readStream = fs2.createReadStream(file, {
250
- highWaterMark: 250
251
- });
252
- return new Promise((res, rej) => {
253
- let idx = 0;
254
- let str = "";
255
- readStream.on("data", (_chunk) => {
256
- const chunk = _chunk.toString();
257
- if (idx === 0 && !chunk.startsWith("---")) {
258
- res({});
259
- readStream.close();
260
- return;
261
- }
262
- str += chunk;
263
- idx++;
264
- if (str.includes("\n---")) {
265
- res(
266
- (0, import_gray_matter.default)({
267
- content: str
268
- }).data
269
- );
270
- readStream.close();
271
- }
272
- });
273
- readStream.on("end", () => res({}));
274
- readStream.on("error", (e) => rej(e));
275
- });
276
- }
277
-
278
265
  // src/map/generate.ts
279
- async function readFrontmatterWithCache(file) {
280
- const cached = fileCache.read("read-frontmatter", file);
266
+ var import_gray_matter = __toESM(require("gray-matter"), 1);
267
+ async function readFileWithCache(file) {
268
+ const cached = fileCache.read("read-file", file);
281
269
  if (cached) return cached;
282
- const res = await readFrontmatter(file);
283
- fileCache.write("read-frontmatter", file, res);
284
- return res;
270
+ return (await fs2.readFile(file)).toString();
285
271
  }
286
272
  async function generateJS(configPath, config, outputPath, configHash) {
287
273
  const outDir2 = path2.dirname(outputPath);
@@ -299,28 +285,8 @@ async function generateJS(configPath, config, outputPath, configHash) {
299
285
  })
300
286
  ];
301
287
  const entries = Array.from(config.collections.entries());
302
- async function getEntries(collectionName, collection, files) {
288
+ async function getDocEntries(collectionName, files) {
303
289
  const items = files.map(async (file, i) => {
304
- if (collection.type === "meta") {
305
- const cached = fileCache.read("generate-js", file.absolutePath);
306
- if (cached) return cached;
307
- const source = (await fs3.readFile(file.absolutePath)).toString();
308
- let data = JSON.parse(source);
309
- if (collection?.schema) {
310
- data = await validate(
311
- collection.schema,
312
- data,
313
- {
314
- source,
315
- path: file.absolutePath
316
- },
317
- `invalid data in ${file.absolutePath}:`
318
- );
319
- }
320
- const entry = `{ info: ${JSON.stringify(file)}, data: ${JSON.stringify(data)} }`;
321
- fileCache.write("generate-js", file.absolutePath, entry);
322
- return entry;
323
- }
324
290
  const importId = `${collectionName}_${i}`;
325
291
  lines.unshift(
326
292
  getImportCode({
@@ -333,7 +299,29 @@ async function generateJS(configPath, config, outputPath, configHash) {
333
299
  });
334
300
  return Promise.all(items);
335
301
  }
336
- async function getAsyncEntries(files) {
302
+ async function getMetaEntries(collection, files) {
303
+ const items = files.map(async (file) => {
304
+ const source = await readFileWithCache(file.absolutePath).catch(() => "");
305
+ let data = source.length === 0 ? {} : JSON.parse(source);
306
+ if (collection?.schema) {
307
+ data = await validate(
308
+ collection.schema,
309
+ data,
310
+ {
311
+ source,
312
+ path: file.absolutePath
313
+ },
314
+ `invalid data in ${file.absolutePath}`
315
+ );
316
+ }
317
+ return JSON.stringify({
318
+ info: file,
319
+ data
320
+ });
321
+ });
322
+ return Promise.all(items);
323
+ }
324
+ async function getAsyncEntries(collection, files) {
337
325
  if (!asyncInit) {
338
326
  lines.unshift(
339
327
  getImportCode({
@@ -347,9 +335,21 @@ async function generateJS(configPath, config, outputPath, configHash) {
347
335
  asyncInit = true;
348
336
  }
349
337
  const entries2 = files.map(async (file) => {
338
+ const parsed = (0, import_gray_matter.default)(
339
+ await readFileWithCache(file.absolutePath).catch(() => "")
340
+ );
341
+ if (collection.schema) {
342
+ parsed.data = await validate(
343
+ collection.schema,
344
+ parsed.data,
345
+ { path: file.absolutePath, source: parsed.content },
346
+ `invalid frontmatter in ${file.absolutePath}`
347
+ );
348
+ }
350
349
  return JSON.stringify({
351
350
  info: file,
352
- data: await readFrontmatterWithCache(file.absolutePath)
351
+ data: parsed.data,
352
+ content: parsed.content
353
353
  });
354
354
  });
355
355
  return Promise.all(entries2);
@@ -358,23 +358,23 @@ async function generateJS(configPath, config, outputPath, configHash) {
358
358
  if (collection.type === "docs") {
359
359
  const docs = await getCollectionFiles(collection.docs);
360
360
  const metas = await getCollectionFiles(collection.meta);
361
- const metaEntries = (await getEntries(k, collection.meta, metas)).join(
361
+ const metaEntries = (await getMetaEntries(collection.meta, metas)).join(
362
362
  ", "
363
363
  );
364
364
  if (collection.docs.async) {
365
- const docsEntries2 = (await getAsyncEntries(docs)).join(", ");
365
+ const docsEntries2 = (await getAsyncEntries(collection.docs, docs)).join(
366
+ ", "
367
+ );
366
368
  return `export const ${k} = _runtimeAsync.docs<typeof _source.${k}>([${docsEntries2}], [${metaEntries}], "${k}", _sourceConfig)`;
367
369
  }
368
- const docsEntries = (await getEntries(k, collection.docs, docs)).join(
369
- ", "
370
- );
370
+ const docsEntries = (await getDocEntries(k, docs)).join(", ");
371
371
  return `export const ${k} = _runtime.docs<typeof _source.${k}>([${docsEntries}], [${metaEntries}])`;
372
372
  }
373
373
  const files = await getCollectionFiles(collection);
374
374
  if (collection.type === "doc" && collection.async) {
375
- return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(files)).join(", ")}], "${k}", _sourceConfig)`;
375
+ return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(collection, files)).join(", ")}], "${k}", _sourceConfig)`;
376
376
  }
377
- return `export const ${k} = _runtime.${collection.type}<typeof _source.${k}>([${(await getEntries(k, collection, files)).join(", ")}]);`;
377
+ return `export const ${k} = _runtime.${collection.type}<typeof _source.${k}>([${(await getDocEntries(k, files)).join(", ")}]);`;
378
378
  });
379
379
  const resolvedDeclares = await Promise.all(declares);
380
380
  return [
@@ -430,24 +430,29 @@ function toImportPath(file, dir) {
430
430
 
431
431
  // src/map/index.ts
432
432
  async function start(dev, configPath, outDir2) {
433
- void fs4.rm(path3.resolve(outDir2, `index.js`), { force: true });
434
- void fs4.rm(path3.resolve(outDir2, `index.d.ts`), { force: true });
435
- await fs4.mkdir(outDir2, { recursive: true });
436
433
  let configHash = await getConfigHash(configPath);
437
434
  let config = await loadConfig(configPath, configHash, true);
438
435
  const outPath = path3.resolve(outDir2, `index.ts`);
439
436
  async function updateMapFile() {
440
- console.time(`[MDX] update map file`);
441
- await fs4.writeFile(
442
- outPath,
443
- await generateJS(configPath, config, outPath, configHash)
444
- );
445
- console.timeEnd(`[MDX] update map file`);
437
+ const start2 = Date.now();
438
+ try {
439
+ await fs3.writeFile(
440
+ outPath,
441
+ await generateJS(configPath, config, outPath, configHash)
442
+ );
443
+ } catch (err) {
444
+ if (err instanceof ValidationError) {
445
+ err.print();
446
+ } else {
447
+ console.error(err);
448
+ }
449
+ }
450
+ console.log(`[MDX] updated map file in ${Date.now() - start2}ms`);
446
451
  }
447
452
  await updateMapFile();
448
453
  if (dev) {
449
454
  const { watcher: watcher2 } = await Promise.resolve().then(() => (init_watcher(), watcher_exports));
450
- const instance = watcher2(configPath, config);
455
+ const instance = watcher2(configPath, config, [outPath]);
451
456
  instance.on("ready", () => {
452
457
  console.log("[MDX] started dev server");
453
458
  });
@@ -492,22 +497,19 @@ function createMDX({
492
497
  };
493
498
  return {
494
499
  ...nextConfig,
495
- experimental: {
496
- ...nextConfig.experimental,
497
- turbo: {
498
- ...nextConfig.experimental?.turbo,
499
- rules: {
500
- ...nextConfig.experimental?.turbo?.rules,
501
- // @ts-expect-error -- safe types
502
- "*.{md,mdx}": {
503
- loaders: [
504
- {
505
- loader: "fumadocs-mdx/loader-mdx",
506
- options: mdxLoaderOptions
507
- }
508
- ],
509
- as: "*.js"
510
- }
500
+ turbopack: {
501
+ ...nextConfig?.turbopack,
502
+ rules: {
503
+ ...nextConfig?.turbopack?.rules,
504
+ // @ts-expect-error -- safe
505
+ "*.{md,mdx}": {
506
+ loaders: [
507
+ {
508
+ loader: "fumadocs-mdx/loader-mdx",
509
+ options: mdxLoaderOptions
510
+ }
511
+ ],
512
+ as: "*.js"
511
513
  }
512
514
  }
513
515
  },
@@ -535,21 +537,14 @@ function createMDX({
535
537
 
536
538
  // src/postinstall.ts
537
539
  var path5 = __toESM(require("path"), 1);
538
- var fs5 = __toESM(require("fs"), 1);
540
+ var fs4 = __toESM(require("fs/promises"), 1);
539
541
  async function postInstall(configPath = findConfigFile()) {
540
542
  const jsOut = path5.resolve(".source/index.ts");
541
543
  const hash = await getConfigHash(configPath);
542
544
  const config = await loadConfig(configPath, hash, true);
543
- fs5.mkdirSync(path5.dirname(jsOut), { recursive: true });
544
- fs5.writeFileSync(
545
- jsOut,
546
- await generateJS(
547
- configPath,
548
- config,
549
- path5.resolve(".source/index.ts"),
550
- hash
551
- )
552
- );
545
+ await fs4.rm(path5.dirname(jsOut), { recursive: true });
546
+ await fs4.mkdir(path5.dirname(jsOut), { recursive: true });
547
+ await fs4.writeFile(jsOut, await generateJS(configPath, config, jsOut, hash));
553
548
  console.log("[MDX] types generated");
554
549
  }
555
550
  // Annotate the CommonJS export names for ESM import in node:
@@ -4,8 +4,9 @@ import {
4
4
  loadConfig
5
5
  } from "../chunk-HFLDWPJA.js";
6
6
  import {
7
+ ValidationError,
7
8
  validate
8
- } from "../chunk-KGLACICA.js";
9
+ } from "../chunk-2ZOW45YZ.js";
9
10
  import "../chunk-DRVUBK5B.js";
10
11
 
11
12
  // src/next/create.ts
@@ -13,11 +14,11 @@ import path3 from "node:path";
13
14
 
14
15
  // src/map/index.ts
15
16
  import * as path2 from "node:path";
16
- import * as fs3 from "node:fs/promises";
17
+ import * as fs2 from "node:fs/promises";
17
18
 
18
19
  // src/map/generate.ts
19
20
  import * as path from "node:path";
20
- import * as fs2 from "node:fs/promises";
21
+ import * as fs from "node:fs/promises";
21
22
  import fg from "fast-glob";
22
23
 
23
24
  // src/utils/get-type-from-path.ts
@@ -50,46 +51,12 @@ var fileCache = {
50
51
  }
51
52
  };
52
53
 
53
- // src/utils/read-frontmatter.ts
54
- import * as fs from "node:fs";
55
- import grayMatter from "gray-matter";
56
- async function readFrontmatter(file) {
57
- const readStream = fs.createReadStream(file, {
58
- highWaterMark: 250
59
- });
60
- return new Promise((res, rej) => {
61
- let idx = 0;
62
- let str = "";
63
- readStream.on("data", (_chunk) => {
64
- const chunk = _chunk.toString();
65
- if (idx === 0 && !chunk.startsWith("---")) {
66
- res({});
67
- readStream.close();
68
- return;
69
- }
70
- str += chunk;
71
- idx++;
72
- if (str.includes("\n---")) {
73
- res(
74
- grayMatter({
75
- content: str
76
- }).data
77
- );
78
- readStream.close();
79
- }
80
- });
81
- readStream.on("end", () => res({}));
82
- readStream.on("error", (e) => rej(e));
83
- });
84
- }
85
-
86
54
  // src/map/generate.ts
87
- async function readFrontmatterWithCache(file) {
88
- const cached = fileCache.read("read-frontmatter", file);
55
+ import matter from "gray-matter";
56
+ async function readFileWithCache(file) {
57
+ const cached = fileCache.read("read-file", file);
89
58
  if (cached) return cached;
90
- const res = await readFrontmatter(file);
91
- fileCache.write("read-frontmatter", file, res);
92
- return res;
59
+ return (await fs.readFile(file)).toString();
93
60
  }
94
61
  async function generateJS(configPath, config, outputPath, configHash) {
95
62
  const outDir2 = path.dirname(outputPath);
@@ -107,28 +74,8 @@ async function generateJS(configPath, config, outputPath, configHash) {
107
74
  })
108
75
  ];
109
76
  const entries = Array.from(config.collections.entries());
110
- async function getEntries(collectionName, collection, files) {
77
+ async function getDocEntries(collectionName, files) {
111
78
  const items = files.map(async (file, i) => {
112
- if (collection.type === "meta") {
113
- const cached = fileCache.read("generate-js", file.absolutePath);
114
- if (cached) return cached;
115
- const source = (await fs2.readFile(file.absolutePath)).toString();
116
- let data = JSON.parse(source);
117
- if (collection?.schema) {
118
- data = await validate(
119
- collection.schema,
120
- data,
121
- {
122
- source,
123
- path: file.absolutePath
124
- },
125
- `invalid data in ${file.absolutePath}:`
126
- );
127
- }
128
- const entry = `{ info: ${JSON.stringify(file)}, data: ${JSON.stringify(data)} }`;
129
- fileCache.write("generate-js", file.absolutePath, entry);
130
- return entry;
131
- }
132
79
  const importId = `${collectionName}_${i}`;
133
80
  lines.unshift(
134
81
  getImportCode({
@@ -141,7 +88,29 @@ async function generateJS(configPath, config, outputPath, configHash) {
141
88
  });
142
89
  return Promise.all(items);
143
90
  }
144
- async function getAsyncEntries(files) {
91
+ async function getMetaEntries(collection, files) {
92
+ const items = files.map(async (file) => {
93
+ const source = await readFileWithCache(file.absolutePath).catch(() => "");
94
+ let data = source.length === 0 ? {} : JSON.parse(source);
95
+ if (collection?.schema) {
96
+ data = await validate(
97
+ collection.schema,
98
+ data,
99
+ {
100
+ source,
101
+ path: file.absolutePath
102
+ },
103
+ `invalid data in ${file.absolutePath}`
104
+ );
105
+ }
106
+ return JSON.stringify({
107
+ info: file,
108
+ data
109
+ });
110
+ });
111
+ return Promise.all(items);
112
+ }
113
+ async function getAsyncEntries(collection, files) {
145
114
  if (!asyncInit) {
146
115
  lines.unshift(
147
116
  getImportCode({
@@ -155,9 +124,21 @@ async function generateJS(configPath, config, outputPath, configHash) {
155
124
  asyncInit = true;
156
125
  }
157
126
  const entries2 = files.map(async (file) => {
127
+ const parsed = matter(
128
+ await readFileWithCache(file.absolutePath).catch(() => "")
129
+ );
130
+ if (collection.schema) {
131
+ parsed.data = await validate(
132
+ collection.schema,
133
+ parsed.data,
134
+ { path: file.absolutePath, source: parsed.content },
135
+ `invalid frontmatter in ${file.absolutePath}`
136
+ );
137
+ }
158
138
  return JSON.stringify({
159
139
  info: file,
160
- data: await readFrontmatterWithCache(file.absolutePath)
140
+ data: parsed.data,
141
+ content: parsed.content
161
142
  });
162
143
  });
163
144
  return Promise.all(entries2);
@@ -166,23 +147,23 @@ async function generateJS(configPath, config, outputPath, configHash) {
166
147
  if (collection.type === "docs") {
167
148
  const docs = await getCollectionFiles(collection.docs);
168
149
  const metas = await getCollectionFiles(collection.meta);
169
- const metaEntries = (await getEntries(k, collection.meta, metas)).join(
150
+ const metaEntries = (await getMetaEntries(collection.meta, metas)).join(
170
151
  ", "
171
152
  );
172
153
  if (collection.docs.async) {
173
- const docsEntries2 = (await getAsyncEntries(docs)).join(", ");
154
+ const docsEntries2 = (await getAsyncEntries(collection.docs, docs)).join(
155
+ ", "
156
+ );
174
157
  return `export const ${k} = _runtimeAsync.docs<typeof _source.${k}>([${docsEntries2}], [${metaEntries}], "${k}", _sourceConfig)`;
175
158
  }
176
- const docsEntries = (await getEntries(k, collection.docs, docs)).join(
177
- ", "
178
- );
159
+ const docsEntries = (await getDocEntries(k, docs)).join(", ");
179
160
  return `export const ${k} = _runtime.docs<typeof _source.${k}>([${docsEntries}], [${metaEntries}])`;
180
161
  }
181
162
  const files = await getCollectionFiles(collection);
182
163
  if (collection.type === "doc" && collection.async) {
183
- return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(files)).join(", ")}], "${k}", _sourceConfig)`;
164
+ return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(collection, files)).join(", ")}], "${k}", _sourceConfig)`;
184
165
  }
185
- return `export const ${k} = _runtime.${collection.type}<typeof _source.${k}>([${(await getEntries(k, collection, files)).join(", ")}]);`;
166
+ return `export const ${k} = _runtime.${collection.type}<typeof _source.${k}>([${(await getDocEntries(k, files)).join(", ")}]);`;
186
167
  });
187
168
  const resolvedDeclares = await Promise.all(declares);
188
169
  return [
@@ -238,24 +219,29 @@ function toImportPath(file, dir) {
238
219
 
239
220
  // src/map/index.ts
240
221
  async function start(dev, configPath, outDir2) {
241
- void fs3.rm(path2.resolve(outDir2, `index.js`), { force: true });
242
- void fs3.rm(path2.resolve(outDir2, `index.d.ts`), { force: true });
243
- await fs3.mkdir(outDir2, { recursive: true });
244
222
  let configHash = await getConfigHash(configPath);
245
223
  let config = await loadConfig(configPath, configHash, true);
246
224
  const outPath = path2.resolve(outDir2, `index.ts`);
247
225
  async function updateMapFile() {
248
- console.time(`[MDX] update map file`);
249
- await fs3.writeFile(
250
- outPath,
251
- await generateJS(configPath, config, outPath, configHash)
252
- );
253
- console.timeEnd(`[MDX] update map file`);
226
+ const start2 = Date.now();
227
+ try {
228
+ await fs2.writeFile(
229
+ outPath,
230
+ await generateJS(configPath, config, outPath, configHash)
231
+ );
232
+ } catch (err) {
233
+ if (err instanceof ValidationError) {
234
+ err.print();
235
+ } else {
236
+ console.error(err);
237
+ }
238
+ }
239
+ console.log(`[MDX] updated map file in ${Date.now() - start2}ms`);
254
240
  }
255
241
  await updateMapFile();
256
242
  if (dev) {
257
- const { watcher } = await import("../watcher-IAZDSTU7.js");
258
- const instance = watcher(configPath, config);
243
+ const { watcher } = await import("../watcher-7O2HAQ63.js");
244
+ const instance = watcher(configPath, config, [outPath]);
259
245
  instance.on("ready", () => {
260
246
  console.log("[MDX] started dev server");
261
247
  });
@@ -300,22 +286,19 @@ function createMDX({
300
286
  };
301
287
  return {
302
288
  ...nextConfig,
303
- experimental: {
304
- ...nextConfig.experimental,
305
- turbo: {
306
- ...nextConfig.experimental?.turbo,
307
- rules: {
308
- ...nextConfig.experimental?.turbo?.rules,
309
- // @ts-expect-error -- safe types
310
- "*.{md,mdx}": {
311
- loaders: [
312
- {
313
- loader: "fumadocs-mdx/loader-mdx",
314
- options: mdxLoaderOptions
315
- }
316
- ],
317
- as: "*.js"
318
- }
289
+ turbopack: {
290
+ ...nextConfig?.turbopack,
291
+ rules: {
292
+ ...nextConfig?.turbopack?.rules,
293
+ // @ts-expect-error -- safe
294
+ "*.{md,mdx}": {
295
+ loaders: [
296
+ {
297
+ loader: "fumadocs-mdx/loader-mdx",
298
+ options: mdxLoaderOptions
299
+ }
300
+ ],
301
+ as: "*.js"
319
302
  }
320
303
  }
321
304
  },
@@ -343,21 +326,14 @@ function createMDX({
343
326
 
344
327
  // src/postinstall.ts
345
328
  import * as path4 from "node:path";
346
- import * as fs4 from "node:fs";
329
+ import * as fs3 from "node:fs/promises";
347
330
  async function postInstall(configPath = findConfigFile()) {
348
331
  const jsOut = path4.resolve(".source/index.ts");
349
332
  const hash = await getConfigHash(configPath);
350
333
  const config = await loadConfig(configPath, hash, true);
351
- fs4.mkdirSync(path4.dirname(jsOut), { recursive: true });
352
- fs4.writeFileSync(
353
- jsOut,
354
- await generateJS(
355
- configPath,
356
- config,
357
- path4.resolve(".source/index.ts"),
358
- hash
359
- )
360
- );
334
+ await fs3.rm(path4.dirname(jsOut), { recursive: true });
335
+ await fs3.mkdir(path4.dirname(jsOut), { recursive: true });
336
+ await fs3.writeFile(jsOut, await generateJS(configPath, config, jsOut, hash));
361
337
  console.log("[MDX] types generated");
362
338
  }
363
339
  export {
@@ -35,7 +35,6 @@ __export(async_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(async_exports);
37
37
  var import_mdx_remote = require("@fumadocs/mdx-remote");
38
- var fs2 = __toESM(require("fs/promises"), 1);
39
38
 
40
39
  // src/mdx-plugins/remark-include.ts
41
40
  var import_unist_util_visit = require("unist-util-visit");
@@ -230,14 +229,15 @@ async function initCompiler(config, collection) {
230
229
  var _runtimeAsync = {
231
230
  doc(files, collection, config) {
232
231
  const init = initCompiler(config, collection);
233
- return files.map(({ info: file, data: frontmatter }) => {
232
+ return files.map(({ info: file, data, content }) => {
234
233
  return {
235
- ...frontmatter,
234
+ ...data,
236
235
  _file: file,
236
+ content,
237
237
  async load() {
238
238
  const compiler = await init;
239
239
  const out = await compiler.compile({
240
- source: (await fs2.readFile(file.absolutePath)).toString(),
240
+ source: content,
241
241
  filePath: file.absolutePath
242
242
  });
243
243
  return {
@@ -1,4 +1,4 @@
1
- import { L as LoadedConfig, b as RuntimeAsync } from '../types-DCyuz-WB.cjs';
1
+ import { L as LoadedConfig, a as RuntimeAsync } from '../types-CTLLuPxW.cjs';
2
2
  import '../define-CGHfrlrJ.cjs';
3
3
  import '@mdx-js/mdx';
4
4
  import 'mdx/types';
@@ -1,4 +1,4 @@
1
- import { L as LoadedConfig, b as RuntimeAsync } from '../types-DfVJrYH1.js';
1
+ import { L as LoadedConfig, a as RuntimeAsync } from '../types-CUbprvBB.js';
2
2
  import '../define-CGHfrlrJ.js';
3
3
  import '@mdx-js/mdx';
4
4
  import 'mdx/types';
@@ -11,7 +11,6 @@ import {
11
11
 
12
12
  // src/runtime/async.ts
13
13
  import { createCompiler } from "@fumadocs/mdx-remote";
14
- import * as fs from "node:fs/promises";
15
14
  import {
16
15
  remarkStructure
17
16
  } from "fumadocs-core/mdx-plugins";
@@ -35,14 +34,15 @@ async function initCompiler(config, collection) {
35
34
  var _runtimeAsync = {
36
35
  doc(files, collection, config) {
37
36
  const init = initCompiler(config, collection);
38
- return files.map(({ info: file, data: frontmatter }) => {
37
+ return files.map(({ info: file, data, content }) => {
39
38
  return {
40
- ...frontmatter,
39
+ ...data,
41
40
  _file: file,
41
+ content,
42
42
  async load() {
43
43
  const compiler = await init;
44
44
  const out = await compiler.compile({
45
- source: (await fs.readFile(file.absolutePath)).toString(),
45
+ source: content,
46
46
  filePath: file.absolutePath
47
47
  });
48
48
  return {
@@ -19,6 +19,11 @@ interface RuntimeFile {
19
19
  info: FileInfo;
20
20
  data: Record<string, unknown>;
21
21
  }
22
+ interface AsyncRuntimeFile {
23
+ info: FileInfo;
24
+ data: Record<string, unknown>;
25
+ content: string;
26
+ }
22
27
  type DocOut<Schema extends StandardSchemaV1> = Omit<MarkdownProps, keyof StandardSchemaV1.InferOutput<Schema>> & StandardSchemaV1.InferOutput<Schema> & BaseCollectionEntry;
23
28
  type MetaOut<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema> & BaseCollectionEntry;
24
29
  interface Runtime {
@@ -58,16 +63,17 @@ interface Runtime {
58
63
  } : never;
59
64
  }
60
65
  type AsyncDocOut<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema> & BaseCollectionEntry & {
66
+ content: string;
61
67
  load: () => Promise<MarkdownProps>;
62
68
  };
63
69
  interface RuntimeAsync {
64
- doc: <C>(files: RuntimeFile[], collection: string, config: LoadedConfig) => C extends {
70
+ doc: <C>(files: AsyncRuntimeFile[], collection: string, config: LoadedConfig) => C extends {
65
71
  type: 'doc';
66
72
  _type: {
67
73
  schema: infer Schema extends StandardSchemaV1;
68
74
  };
69
75
  } ? AsyncDocOut<Schema>[] : never;
70
- docs: <C>(docs: RuntimeFile[], metas: RuntimeFile[], collection: string, config: LoadedConfig) => C extends {
76
+ docs: <C>(docs: AsyncRuntimeFile[], metas: RuntimeFile[], collection: string, config: LoadedConfig) => C extends {
71
77
  type: 'docs';
72
78
  docs: {
73
79
  type: 'doc';
@@ -91,4 +97,4 @@ interface RuntimeAsync {
91
97
  } : never;
92
98
  }
93
99
 
94
- export type { LoadedConfig as L, Runtime as R, RuntimeFile as a, RuntimeAsync as b };
100
+ export type { LoadedConfig as L, Runtime as R, RuntimeAsync as a };
@@ -19,6 +19,11 @@ interface RuntimeFile {
19
19
  info: FileInfo;
20
20
  data: Record<string, unknown>;
21
21
  }
22
+ interface AsyncRuntimeFile {
23
+ info: FileInfo;
24
+ data: Record<string, unknown>;
25
+ content: string;
26
+ }
22
27
  type DocOut<Schema extends StandardSchemaV1> = Omit<MarkdownProps, keyof StandardSchemaV1.InferOutput<Schema>> & StandardSchemaV1.InferOutput<Schema> & BaseCollectionEntry;
23
28
  type MetaOut<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema> & BaseCollectionEntry;
24
29
  interface Runtime {
@@ -58,16 +63,17 @@ interface Runtime {
58
63
  } : never;
59
64
  }
60
65
  type AsyncDocOut<Schema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<Schema> & BaseCollectionEntry & {
66
+ content: string;
61
67
  load: () => Promise<MarkdownProps>;
62
68
  };
63
69
  interface RuntimeAsync {
64
- doc: <C>(files: RuntimeFile[], collection: string, config: LoadedConfig) => C extends {
70
+ doc: <C>(files: AsyncRuntimeFile[], collection: string, config: LoadedConfig) => C extends {
65
71
  type: 'doc';
66
72
  _type: {
67
73
  schema: infer Schema extends StandardSchemaV1;
68
74
  };
69
75
  } ? AsyncDocOut<Schema>[] : never;
70
- docs: <C>(docs: RuntimeFile[], metas: RuntimeFile[], collection: string, config: LoadedConfig) => C extends {
76
+ docs: <C>(docs: AsyncRuntimeFile[], metas: RuntimeFile[], collection: string, config: LoadedConfig) => C extends {
71
77
  type: 'docs';
72
78
  docs: {
73
79
  type: 'doc';
@@ -91,4 +97,4 @@ interface RuntimeAsync {
91
97
  } : never;
92
98
  }
93
99
 
94
- export type { LoadedConfig as L, Runtime as R, RuntimeFile as a, RuntimeAsync as b };
100
+ export type { LoadedConfig as L, Runtime as R, RuntimeAsync as a };
@@ -1,6 +1,6 @@
1
1
  // src/map/watcher.ts
2
2
  import { watch } from "chokidar";
3
- function watcher(configPath, config) {
3
+ function watcher(configPath, config, ignored) {
4
4
  const deps = [configPath];
5
5
  function add(dir) {
6
6
  if (Array.isArray(dir)) deps.push(...dir);
@@ -16,6 +16,7 @@ function watcher(configPath, config) {
16
16
  }
17
17
  return watch(deps, {
18
18
  ignoreInitial: true,
19
+ ignored,
19
20
  persistent: true
20
21
  });
21
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-mdx",
3
- "version": "11.5.8",
3
+ "version": "11.6.1",
4
4
  "description": "The built-in source for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -47,32 +47,33 @@
47
47
  "chokidar": "^4.0.3",
48
48
  "cross-spawn": "^7.0.6",
49
49
  "esbuild": "^0.25.2",
50
- "estree-util-value-to-estree": "^3.3.2",
50
+ "estree-util-value-to-estree": "^3.3.3",
51
51
  "fast-glob": "^3.3.3",
52
52
  "gray-matter": "^4.0.3",
53
53
  "lru-cache": "^11.1.0",
54
+ "picocolors": "^1.1.1",
54
55
  "unist-util-visit": "^5.0.0",
55
- "zod": "^3.24.2"
56
+ "zod": "^3.24.3"
56
57
  },
57
58
  "devDependencies": {
58
59
  "@types/cross-spawn": "^6.0.6",
59
60
  "@types/mdast": "^4.0.3",
60
61
  "@types/mdx": "^2.0.13",
61
- "@types/react": "^19.1.0",
62
+ "@types/react": "^19.1.2",
62
63
  "mdast-util-mdx-jsx": "^3.2.0",
63
- "next": "^15.2.4",
64
+ "next": "^15.3.1",
64
65
  "unified": "^11.0.5",
65
66
  "vfile": "^6.0.3",
66
- "webpack": "^5.97.1",
67
+ "webpack": "^5.99.5",
67
68
  "@fumadocs/mdx-remote": "1.3.0",
68
69
  "eslint-config-custom": "0.0.0",
69
- "fumadocs-core": "15.2.4",
70
+ "fumadocs-core": "15.2.9",
70
71
  "tsconfig": "0.0.0"
71
72
  },
72
73
  "peerDependencies": {
73
74
  "@fumadocs/mdx-remote": "^1.2.0",
74
75
  "fumadocs-core": "^14.0.0 || ^15.0.0",
75
- "next": "14.x.x || 15.x.x"
76
+ "next": "^15.3.0"
76
77
  },
77
78
  "peerDependenciesMeta": {
78
79
  "@fumadocs/mdx-remote": {