fumadocs-mdx 11.6.5 → 11.6.7

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.
package/bin.js CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  import { postInstall } from './dist/next/index.js';
4
4
 
5
- void postInstall(process.argv[2]);
5
+ void postInstall(process.argv[2], process.argv[3]);
@@ -57,7 +57,10 @@ function remarkInclude() {
57
57
  parsed
58
58
  );
59
59
  }).catch((e) => {
60
- console.warn(`failed to read file: ${targetPath}`, e);
60
+ throw new Error(
61
+ `failed to read file ${targetPath}
62
+ ${e instanceof Error ? e.message : String(e)}`
63
+ );
61
64
  })
62
65
  );
63
66
  return "skip";
@@ -22,22 +22,20 @@ var ValidationError = class extends Error {
22
22
  super(message);
23
23
  this.issues = issues;
24
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
25
  toString() {
38
26
  return `${this.message}:
39
27
  ${this.issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
40
28
  }
29
+ toStringFormatted() {
30
+ return [
31
+ picocolors.bold(`[MDX] ${this.message}:`),
32
+ ...this.issues.map(
33
+ (issue) => picocolors.redBright(
34
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
35
+ )
36
+ )
37
+ ].join("\n");
38
+ }
41
39
  };
42
40
  async function validate(schema, data, context, errorMessage) {
43
41
  if (typeof schema === "function" && !("~standard" in schema)) {
@@ -30,12 +30,12 @@ async function compileConfig(configPath, outDir) {
30
30
  throw new Error("failed to compile configuration file");
31
31
  }
32
32
  }
33
- async function loadConfig(configPath, hash, build = false) {
33
+ async function loadConfig(configPath, outDir, hash, build = false) {
34
34
  if (cache && cache.hash === hash) {
35
35
  return await cache.config;
36
36
  }
37
- if (build) await compileConfig(configPath, ".source");
38
- const url = pathToFileURL(path.resolve(".source/source.config.mjs"));
37
+ if (build) await compileConfig(configPath, outDir);
38
+ const url = pathToFileURL(path.resolve(outDir, "source.config.mjs"));
39
39
  const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
40
40
  const [err, config2] = buildConfig(
41
41
  // every call to `loadConfig` will cause the previous cache to be ignored
@@ -55,8 +55,32 @@ async function getConfigHash(configPath) {
55
55
  throw new Error("Cannot find config file");
56
56
  }
57
57
 
58
+ // src/utils/git-timestamp.ts
59
+ import path2 from "path";
60
+ import { x } from "tinyexec";
61
+ var cache2 = /* @__PURE__ */ new Map();
62
+ async function getGitTimestamp(file) {
63
+ const cached = cache2.get(file);
64
+ if (cached) return cached;
65
+ try {
66
+ const out = await x(
67
+ "git",
68
+ ["log", "-1", '--pretty="%ai"', path2.relative(process.cwd(), file)],
69
+ {
70
+ throwOnError: true
71
+ }
72
+ );
73
+ const time = new Date(out.stdout);
74
+ cache2.set(file, time);
75
+ return time;
76
+ } catch {
77
+ return;
78
+ }
79
+ }
80
+
58
81
  export {
59
82
  findConfigFile,
60
83
  loadConfig,
61
- getConfigHash
84
+ getConfigHash,
85
+ getGitTimestamp
62
86
  };
@@ -99,7 +99,7 @@ function getDefaultMDXOptions({
99
99
  (v) => [
100
100
  rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
101
101
  ...v,
102
- [plugins.rehypeToc]
102
+ plugins.rehypeToc
103
103
  ],
104
104
  mdxOptions.rehypePlugins
105
105
  );
@@ -198,7 +198,7 @@ function getDefaultMDXOptions({
198
198
  (v) => [
199
199
  rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
200
200
  ...v,
201
- [plugins.rehypeToc]
201
+ plugins.rehypeToc
202
202
  ],
203
203
  mdxOptions.rehypePlugins
204
204
  );
@@ -268,7 +268,10 @@ function remarkInclude() {
268
268
  parsed
269
269
  );
270
270
  }).catch((e) => {
271
- console.warn(`failed to read file: ${targetPath}`, e);
271
+ throw new Error(
272
+ `failed to read file ${targetPath}
273
+ ${e instanceof Error ? e.message : String(e)}`
274
+ );
272
275
  })
273
276
  );
274
277
  return "skip";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  frontmatterSchema,
3
3
  metaSchema
4
- } from "../chunk-2ZOW45YZ.js";
4
+ } from "../chunk-OTM6WYMS.js";
5
5
  import {
6
6
  remarkInclude
7
- } from "../chunk-3UUEUK4M.js";
7
+ } from "../chunk-2Z6EJ3GA.js";
8
8
  import {
9
9
  getDefaultMDXOptions
10
- } from "../chunk-7UCWBLFI.js";
10
+ } from "../chunk-VC3Y6FLZ.js";
11
11
 
12
12
  // src/config/define.ts
13
13
  function defineCollections(options) {
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PageData, MetaData, Source, VirtualFile } from 'fumadocs-core/source';
2
2
  import { B as BaseCollectionEntry } from './define-uoePrCQ_.cjs';
3
- import { R as Runtime } from './types-Cph8Ml_K.cjs';
3
+ import { R as Runtime } from './types-BsJd_P5O.cjs';
4
4
  import '@mdx-js/mdx';
5
5
  import 'mdx/types';
6
6
  import 'fumadocs-core/mdx-plugins';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PageData, MetaData, Source, VirtualFile } from 'fumadocs-core/source';
2
2
  import { B as BaseCollectionEntry } from './define-uoePrCQ_.js';
3
- import { R as Runtime } from './types-BvEsyMKj.js';
3
+ import { R as Runtime } from './types-BYJBKH4G.js';
4
4
  import '@mdx-js/mdx';
5
5
  import 'mdx/types';
6
6
  import 'fumadocs-core/mdx-plugins';
@@ -138,7 +138,7 @@ function getDefaultMDXOptions({
138
138
  (v) => [
139
139
  rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
140
140
  ...v,
141
- [plugins.rehypeToc]
141
+ plugins.rehypeToc
142
142
  ],
143
143
  mdxOptions.rehypePlugins
144
144
  );
@@ -230,12 +230,12 @@ async function compileConfig(configPath, outDir) {
230
230
  throw new Error("failed to compile configuration file");
231
231
  }
232
232
  }
233
- async function loadConfig(configPath, hash, build = false) {
233
+ async function loadConfig(configPath, outDir, hash, build = false) {
234
234
  if (cache && cache.hash === hash) {
235
235
  return await cache.config;
236
236
  }
237
- if (build) await compileConfig(configPath, ".source");
238
- const url = (0, import_node_url.pathToFileURL)(path.resolve(".source/source.config.mjs"));
237
+ if (build) await compileConfig(configPath, outDir);
238
+ const url = (0, import_node_url.pathToFileURL)(path.resolve(outDir, "source.config.mjs"));
239
239
  const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
240
240
  const [err, config2] = buildConfig(
241
241
  // every call to `loadConfig` will cause the previous cache to be ignored
@@ -317,7 +317,10 @@ function remarkInclude() {
317
317
  parsed
318
318
  );
319
319
  }).catch((e) => {
320
- console.warn(`failed to read file: ${targetPath}`, e);
320
+ throw new Error(
321
+ `failed to read file ${targetPath}
322
+ ${e instanceof Error ? e.message : String(e)}`
323
+ );
321
324
  })
322
325
  );
323
326
  return "skip";
@@ -332,7 +335,7 @@ function remarkInclude() {
332
335
 
333
336
  // src/utils/build-mdx.ts
334
337
  var cache2 = /* @__PURE__ */ new Map();
335
- async function buildMDX(cacheKey, source, options = {}) {
338
+ async function buildMDX(cacheKey, source, options) {
336
339
  const { filePath, frontmatter, data, ...rest } = options;
337
340
  let format = options.format;
338
341
  if (!format && filePath) {
@@ -364,30 +367,25 @@ async function buildMDX(cacheKey, source, options = {}) {
364
367
 
365
368
  // src/utils/git-timestamp.ts
366
369
  var import_node_path = __toESM(require("path"), 1);
367
- var import_node_fs = __toESM(require("fs"), 1);
368
- var import_cross_spawn = require("cross-spawn");
370
+ var import_tinyexec = require("tinyexec");
369
371
  var cache3 = /* @__PURE__ */ new Map();
370
- function getGitTimestamp(file) {
371
- const cachedTimestamp = cache3.get(file);
372
- if (cachedTimestamp) return Promise.resolve(cachedTimestamp);
373
- return new Promise((resolve3, reject) => {
374
- const cwd = import_node_path.default.dirname(file);
375
- if (!import_node_fs.default.existsSync(cwd)) {
376
- resolve3(void 0);
377
- return;
378
- }
379
- const fileName = import_node_path.default.basename(file);
380
- const child = (0, import_cross_spawn.spawn)("git", ["log", "-1", '--pretty="%ai"', fileName], {
381
- cwd
382
- });
383
- let output;
384
- child.stdout.on("data", (d) => output = new Date(String(d)));
385
- child.on("close", () => {
386
- if (output) cache3.set(file, output);
387
- resolve3(output);
388
- });
389
- child.on("error", reject);
390
- });
372
+ async function getGitTimestamp(file) {
373
+ const cached = cache3.get(file);
374
+ if (cached) return cached;
375
+ try {
376
+ const out = await (0, import_tinyexec.x)(
377
+ "git",
378
+ ["log", "-1", '--pretty="%ai"', import_node_path.default.relative(process.cwd(), file)],
379
+ {
380
+ throwOnError: true
381
+ }
382
+ );
383
+ const time = new Date(out.stdout);
384
+ cache3.set(file, time);
385
+ return time;
386
+ } catch {
387
+ return;
388
+ }
391
389
  }
392
390
 
393
391
  // src/utils/schema.ts
@@ -414,22 +412,20 @@ var ValidationError = class extends Error {
414
412
  super(message);
415
413
  this.issues = issues;
416
414
  }
417
- print() {
418
- console.error(
419
- [
420
- `[MDX] ${this.message}:`,
421
- ...this.issues.map(
422
- (issue) => import_picocolors.default.redBright(
423
- `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
424
- )
425
- )
426
- ].join("\n")
427
- );
428
- }
429
415
  toString() {
430
416
  return `${this.message}:
431
417
  ${this.issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
432
418
  }
419
+ toStringFormatted() {
420
+ return [
421
+ import_picocolors.default.bold(`[MDX] ${this.message}:`),
422
+ ...this.issues.map(
423
+ (issue) => import_picocolors.default.redBright(
424
+ `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
425
+ )
426
+ )
427
+ ].join("\n");
428
+ }
433
429
  };
434
430
  async function validate(schema, data, context, errorMessage) {
435
431
  if (typeof schema === "function" && !("~standard" in schema)) {
@@ -448,56 +444,48 @@ async function validate(schema, data, context, errorMessage) {
448
444
  }
449
445
 
450
446
  // src/loader-mdx.ts
451
- function parseQuery(query) {
452
- let collection;
453
- let hash;
454
- const parsed = (0, import_node_querystring.parse)(query.slice(1));
455
- if (parsed.collection && typeof parsed.collection === "string")
456
- collection = parsed.collection;
457
- if (parsed.hash && typeof parsed.hash === "string") hash = parsed.hash;
458
- return { collection, hash };
459
- }
460
447
  async function loader(source, callback) {
461
448
  this.cacheable(true);
462
449
  const context = this.context;
463
450
  const filePath = this.resourcePath;
464
- const { _ctx } = this.getOptions();
451
+ const { configPath, outDir } = this.getOptions();
465
452
  const matter2 = (0, import_gray_matter2.default)(source);
466
453
  const {
467
- hash: configHash = await getConfigHash(_ctx.configPath),
454
+ hash: configHash = await getConfigHash(configPath),
468
455
  collection: collectionId
469
- } = parseQuery(this.resourceQuery);
470
- const config = await loadConfig(_ctx.configPath, configHash);
456
+ } = (0, import_node_querystring.parse)(this.resourceQuery.slice(1));
457
+ const config = await loadConfig(configPath, outDir, configHash);
471
458
  let collection = collectionId !== void 0 ? config.collections.get(collectionId) : void 0;
472
459
  if (collection && collection.type === "docs") collection = collection.docs;
473
460
  if (collection && collection.type !== "doc") {
474
461
  collection = void 0;
475
462
  }
476
- let mdxOptions = collection?.mdxOptions;
477
- if (!mdxOptions) {
478
- const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_mdx_options(), mdx_options_exports));
479
- config._mdx_loader ??= {};
480
- const extendedOptions = config.global?.mdxOptions;
481
- config._mdx_loader.cachedProcessorOptions ??= typeof extendedOptions === "function" ? getDefaultMDXOptions2(await extendedOptions()) : getDefaultMDXOptions2(extendedOptions ?? {});
482
- mdxOptions = config._mdx_loader.cachedProcessorOptions;
483
- }
463
+ const mdxOptions = collection?.mdxOptions ?? await loadDefaultOptions(config);
484
464
  if (collection?.schema) {
485
- matter2.data = await validate(
486
- collection.schema,
487
- matter2.data,
488
- {
489
- source,
490
- path: filePath
491
- },
492
- `invalid frontmatter in ${filePath}`
493
- );
465
+ try {
466
+ matter2.data = await validate(
467
+ collection.schema,
468
+ matter2.data,
469
+ {
470
+ source,
471
+ path: filePath
472
+ },
473
+ `invalid frontmatter in ${filePath}`
474
+ );
475
+ } catch (e) {
476
+ if (e instanceof ValidationError) {
477
+ return callback(new Error(e.toStringFormatted()));
478
+ }
479
+ return callback(e);
480
+ }
494
481
  }
495
482
  let timestamp;
496
- if (config.global?.lastModifiedTime === "git")
483
+ if (config.global?.lastModifiedTime === "git") {
497
484
  timestamp = (await getGitTimestamp(filePath))?.getTime();
485
+ }
498
486
  try {
499
487
  const lineOffset = "\n".repeat(
500
- this.mode === "development" ? lines(source) - lines(matter2.content) : 0
488
+ this.mode === "development" ? lines(matter2.matter) : 0
501
489
  );
502
490
  const file = await buildMDX(
503
491
  `${configHash}:${collectionId ?? "global"}`,
@@ -521,6 +509,16 @@ async function loader(source, callback) {
521
509
  callback(error);
522
510
  }
523
511
  }
512
+ async function loadDefaultOptions(config) {
513
+ const input = config.global?.mdxOptions;
514
+ config._mdx_loader ??= {};
515
+ const mdxLoader = config._mdx_loader;
516
+ if (!mdxLoader.cachedOptions) {
517
+ const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_mdx_options(), mdx_options_exports));
518
+ mdxLoader.cachedOptions = typeof input === "function" ? getDefaultMDXOptions2(await input()) : getDefaultMDXOptions2(input ?? {});
519
+ }
520
+ return mdxLoader.cachedOptions;
521
+ }
524
522
  function lines(s) {
525
523
  let num = 0;
526
524
  for (const c of s) {
@@ -1,12 +1,8 @@
1
1
  import { LoaderContext } from 'webpack';
2
2
 
3
3
  interface Options {
4
- /**
5
- * @internal
6
- */
7
- _ctx: {
8
- configPath: string;
9
- };
4
+ configPath: string;
5
+ outDir: string;
10
6
  }
11
7
  /**
12
8
  * Load MDX/markdown files
@@ -1,12 +1,8 @@
1
1
  import { LoaderContext } from 'webpack';
2
2
 
3
3
  interface Options {
4
- /**
5
- * @internal
6
- */
7
- _ctx: {
8
- configPath: string;
9
- };
4
+ configPath: string;
5
+ outDir: string;
10
6
  }
11
7
  /**
12
8
  * Load MDX/markdown files
@@ -1,24 +1,26 @@
1
1
  import {
2
2
  getConfigHash,
3
+ getGitTimestamp,
3
4
  loadConfig
4
- } from "./chunk-LC4HO353.js";
5
+ } from "./chunk-SXOJYWZ3.js";
5
6
  import {
7
+ ValidationError,
6
8
  validate
7
- } from "./chunk-2ZOW45YZ.js";
9
+ } from "./chunk-OTM6WYMS.js";
8
10
  import {
9
11
  remarkInclude
10
- } from "./chunk-3UUEUK4M.js";
12
+ } from "./chunk-2Z6EJ3GA.js";
11
13
  import "./chunk-DRVUBK5B.js";
12
14
 
13
15
  // src/loader-mdx.ts
14
- import * as path2 from "path";
16
+ import * as path from "path";
15
17
  import { parse } from "querystring";
16
18
  import grayMatter from "gray-matter";
17
19
 
18
20
  // src/utils/build-mdx.ts
19
21
  import { createProcessor } from "@mdx-js/mdx";
20
22
  var cache = /* @__PURE__ */ new Map();
21
- async function buildMDX(cacheKey, source, options = {}) {
23
+ async function buildMDX(cacheKey, source, options) {
22
24
  const { filePath, frontmatter, data, ...rest } = options;
23
25
  let format = options.format;
24
26
  if (!format && filePath) {
@@ -48,85 +50,49 @@ async function buildMDX(cacheKey, source, options = {}) {
48
50
  });
49
51
  }
50
52
 
51
- // src/utils/git-timestamp.ts
52
- import path from "path";
53
- import fs from "fs";
54
- import { spawn } from "cross-spawn";
55
- var cache2 = /* @__PURE__ */ new Map();
56
- function getGitTimestamp(file) {
57
- const cachedTimestamp = cache2.get(file);
58
- if (cachedTimestamp) return Promise.resolve(cachedTimestamp);
59
- return new Promise((resolve, reject) => {
60
- const cwd = path.dirname(file);
61
- if (!fs.existsSync(cwd)) {
62
- resolve(void 0);
63
- return;
64
- }
65
- const fileName = path.basename(file);
66
- const child = spawn("git", ["log", "-1", '--pretty="%ai"', fileName], {
67
- cwd
68
- });
69
- let output;
70
- child.stdout.on("data", (d) => output = new Date(String(d)));
71
- child.on("close", () => {
72
- if (output) cache2.set(file, output);
73
- resolve(output);
74
- });
75
- child.on("error", reject);
76
- });
77
- }
78
-
79
53
  // src/loader-mdx.ts
80
- function parseQuery(query) {
81
- let collection;
82
- let hash;
83
- const parsed = parse(query.slice(1));
84
- if (parsed.collection && typeof parsed.collection === "string")
85
- collection = parsed.collection;
86
- if (parsed.hash && typeof parsed.hash === "string") hash = parsed.hash;
87
- return { collection, hash };
88
- }
89
54
  async function loader(source, callback) {
90
55
  this.cacheable(true);
91
56
  const context = this.context;
92
57
  const filePath = this.resourcePath;
93
- const { _ctx } = this.getOptions();
58
+ const { configPath, outDir } = this.getOptions();
94
59
  const matter = grayMatter(source);
95
60
  const {
96
- hash: configHash = await getConfigHash(_ctx.configPath),
61
+ hash: configHash = await getConfigHash(configPath),
97
62
  collection: collectionId
98
- } = parseQuery(this.resourceQuery);
99
- const config = await loadConfig(_ctx.configPath, configHash);
63
+ } = parse(this.resourceQuery.slice(1));
64
+ const config = await loadConfig(configPath, outDir, configHash);
100
65
  let collection = collectionId !== void 0 ? config.collections.get(collectionId) : void 0;
101
66
  if (collection && collection.type === "docs") collection = collection.docs;
102
67
  if (collection && collection.type !== "doc") {
103
68
  collection = void 0;
104
69
  }
105
- let mdxOptions = collection?.mdxOptions;
106
- if (!mdxOptions) {
107
- const { getDefaultMDXOptions } = await import("./mdx-options-7J2A6BUA.js");
108
- config._mdx_loader ??= {};
109
- const extendedOptions = config.global?.mdxOptions;
110
- config._mdx_loader.cachedProcessorOptions ??= typeof extendedOptions === "function" ? getDefaultMDXOptions(await extendedOptions()) : getDefaultMDXOptions(extendedOptions ?? {});
111
- mdxOptions = config._mdx_loader.cachedProcessorOptions;
112
- }
70
+ const mdxOptions = collection?.mdxOptions ?? await loadDefaultOptions(config);
113
71
  if (collection?.schema) {
114
- matter.data = await validate(
115
- collection.schema,
116
- matter.data,
117
- {
118
- source,
119
- path: filePath
120
- },
121
- `invalid frontmatter in ${filePath}`
122
- );
72
+ try {
73
+ matter.data = await validate(
74
+ collection.schema,
75
+ matter.data,
76
+ {
77
+ source,
78
+ path: filePath
79
+ },
80
+ `invalid frontmatter in ${filePath}`
81
+ );
82
+ } catch (e) {
83
+ if (e instanceof ValidationError) {
84
+ return callback(new Error(e.toStringFormatted()));
85
+ }
86
+ return callback(e);
87
+ }
123
88
  }
124
89
  let timestamp;
125
- if (config.global?.lastModifiedTime === "git")
90
+ if (config.global?.lastModifiedTime === "git") {
126
91
  timestamp = (await getGitTimestamp(filePath))?.getTime();
92
+ }
127
93
  try {
128
94
  const lineOffset = "\n".repeat(
129
- this.mode === "development" ? lines(source) - lines(matter.content) : 0
95
+ this.mode === "development" ? lines(matter.matter) : 0
130
96
  );
131
97
  const file = await buildMDX(
132
98
  `${configHash}:${collectionId ?? "global"}`,
@@ -145,11 +111,21 @@ async function loader(source, callback) {
145
111
  callback(void 0, String(file.value), file.map ?? void 0);
146
112
  } catch (error) {
147
113
  if (!(error instanceof Error)) throw error;
148
- const fpath = path2.relative(context, filePath);
114
+ const fpath = path.relative(context, filePath);
149
115
  error.message = `${fpath}:${error.name}: ${error.message}`;
150
116
  callback(error);
151
117
  }
152
118
  }
119
+ async function loadDefaultOptions(config) {
120
+ const input = config.global?.mdxOptions;
121
+ config._mdx_loader ??= {};
122
+ const mdxLoader = config._mdx_loader;
123
+ if (!mdxLoader.cachedOptions) {
124
+ const { getDefaultMDXOptions } = await import("./mdx-options-YGL3EP3M.js");
125
+ mdxLoader.cachedOptions = typeof input === "function" ? getDefaultMDXOptions(await input()) : getDefaultMDXOptions(input ?? {});
126
+ }
127
+ return mdxLoader.cachedOptions;
128
+ }
153
129
  function lines(s) {
154
130
  let num = 0;
155
131
  for (const c of s) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDefaultMDXOptions
3
- } from "./chunk-7UCWBLFI.js";
3
+ } from "./chunk-VC3Y6FLZ.js";
4
4
  export {
5
5
  getDefaultMDXOptions
6
6
  };
@@ -69,9 +69,6 @@ __export(next_exports, {
69
69
  });
70
70
  module.exports = __toCommonJS(next_exports);
71
71
 
72
- // src/next/create.ts
73
- var import_node_path2 = __toESM(require("path"), 1);
74
-
75
72
  // src/utils/config.ts
76
73
  var fs = __toESM(require("fs/promises"), 1);
77
74
  var path = __toESM(require("path"), 1);
@@ -118,12 +115,12 @@ function findConfigFile() {
118
115
  return path.resolve("source.config.ts");
119
116
  }
120
117
  var cache = null;
121
- async function compileConfig(configPath, outDir2) {
118
+ async function compileConfig(configPath, outDir) {
122
119
  const { build } = await import("esbuild");
123
120
  const transformed = await build({
124
121
  entryPoints: [{ in: configPath, out: "source.config" }],
125
122
  bundle: true,
126
- outdir: outDir2,
123
+ outdir: outDir,
127
124
  target: "node18",
128
125
  write: true,
129
126
  platform: "node",
@@ -138,12 +135,12 @@ async function compileConfig(configPath, outDir2) {
138
135
  throw new Error("failed to compile configuration file");
139
136
  }
140
137
  }
141
- async function loadConfig(configPath, hash, build = false) {
138
+ async function loadConfig(configPath, outDir, hash, build = false) {
142
139
  if (cache && cache.hash === hash) {
143
140
  return await cache.config;
144
141
  }
145
- if (build) await compileConfig(configPath, ".source");
146
- const url = (0, import_node_url.pathToFileURL)(path.resolve(".source/source.config.mjs"));
142
+ if (build) await compileConfig(configPath, outDir);
143
+ const url = (0, import_node_url.pathToFileURL)(path.resolve(outDir, "source.config.mjs"));
147
144
  const config = import(`${url.href}?hash=${hash}`).then((loaded) => {
148
145
  const [err, config2] = buildConfig(
149
146
  // every call to `loadConfig` will cause the previous cache to be ignored
@@ -164,11 +161,11 @@ async function getConfigHash(configPath) {
164
161
  }
165
162
 
166
163
  // src/map/index.ts
167
- var path3 = __toESM(require("path"), 1);
164
+ var path4 = __toESM(require("path"), 1);
168
165
  var fs3 = __toESM(require("fs/promises"), 1);
169
166
 
170
167
  // src/map/generate.ts
171
- var path2 = __toESM(require("path"), 1);
168
+ var path3 = __toESM(require("path"), 1);
172
169
  var fs2 = __toESM(require("fs/promises"), 1);
173
170
  var import_tinyglobby = require("tinyglobby");
174
171
 
@@ -206,22 +203,20 @@ var ValidationError = class extends Error {
206
203
  super(message);
207
204
  this.issues = issues;
208
205
  }
209
- print() {
210
- console.error(
211
- [
212
- `[MDX] ${this.message}:`,
213
- ...this.issues.map(
214
- (issue) => import_picocolors.default.redBright(
215
- `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
216
- )
217
- )
218
- ].join("\n")
219
- );
220
- }
221
206
  toString() {
222
207
  return `${this.message}:
223
208
  ${this.issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`;
224
209
  }
210
+ toStringFormatted() {
211
+ return [
212
+ import_picocolors.default.bold(`[MDX] ${this.message}:`),
213
+ ...this.issues.map(
214
+ (issue) => import_picocolors.default.redBright(
215
+ `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
216
+ )
217
+ )
218
+ ].join("\n");
219
+ }
225
220
  };
226
221
  async function validate(schema, data, context, errorMessage) {
227
222
  if (typeof schema === "function" && !("~standard" in schema)) {
@@ -262,13 +257,38 @@ var fileCache = {
262
257
  // src/map/generate.ts
263
258
  var import_gray_matter = __toESM(require("gray-matter"), 1);
264
259
  var import_js_yaml = require("js-yaml");
260
+
261
+ // src/utils/git-timestamp.ts
262
+ var import_node_path2 = __toESM(require("path"), 1);
263
+ var import_tinyexec = require("tinyexec");
264
+ var cache2 = /* @__PURE__ */ new Map();
265
+ async function getGitTimestamp(file) {
266
+ const cached = cache2.get(file);
267
+ if (cached) return cached;
268
+ try {
269
+ const out = await (0, import_tinyexec.x)(
270
+ "git",
271
+ ["log", "-1", '--pretty="%ai"', import_node_path2.default.relative(process.cwd(), file)],
272
+ {
273
+ throwOnError: true
274
+ }
275
+ );
276
+ const time = new Date(out.stdout);
277
+ cache2.set(file, time);
278
+ return time;
279
+ } catch {
280
+ return;
281
+ }
282
+ }
283
+
284
+ // src/map/generate.ts
265
285
  async function readFileWithCache(file) {
266
286
  const cached = fileCache.read("read-file", file);
267
287
  if (cached) return cached;
268
288
  return (await fs2.readFile(file)).toString();
269
289
  }
270
290
  async function generateJS(configPath, config, outputPath, configHash) {
271
- const outDir2 = path2.dirname(outputPath);
291
+ const outDir = path3.dirname(outputPath);
272
292
  let asyncInit = false;
273
293
  const lines = [
274
294
  getImportCode({
@@ -278,7 +298,7 @@ async function generateJS(configPath, config, outputPath, configHash) {
278
298
  }),
279
299
  getImportCode({
280
300
  type: "namespace",
281
- specifier: toImportPath(configPath, outDir2),
301
+ specifier: toImportPath(configPath, outDir),
282
302
  name: "_source"
283
303
  })
284
304
  ];
@@ -290,7 +310,7 @@ async function generateJS(configPath, config, outputPath, configHash) {
290
310
  getImportCode({
291
311
  type: "namespace",
292
312
  name: importId,
293
- specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${collectionName}&hash=${configHash}`
313
+ specifier: `${toImportPath(file.absolutePath, outDir)}?collection=${collectionName}&hash=${configHash}`
294
314
  })
295
315
  );
296
316
  return `{ info: ${JSON.stringify(file)}, data: ${importId} }`;
@@ -344,8 +364,13 @@ async function generateJS(configPath, config, outputPath, configHash) {
344
364
  `invalid frontmatter in ${file.absolutePath}`
345
365
  );
346
366
  }
367
+ let lastModified;
368
+ if (config.global?.lastModifiedTime === "git") {
369
+ lastModified = await getGitTimestamp(file.absolutePath);
370
+ }
347
371
  return JSON.stringify({
348
372
  info: file,
373
+ lastModified,
349
374
  data: parsed.data,
350
375
  content: parsed.content
351
376
  });
@@ -387,13 +412,13 @@ async function getCollectionFiles(collection) {
387
412
  await Promise.all(
388
413
  dirs.map(async (dir) => {
389
414
  const result = await (0, import_tinyglobby.glob)(collection.files ?? "**/*", {
390
- cwd: path2.resolve(dir),
415
+ cwd: path3.resolve(dir),
391
416
  absolute: true
392
417
  });
393
418
  for (const item of result) {
394
419
  if (getTypeFromPath(item) !== collection.type) continue;
395
420
  files.set(item, {
396
- path: path2.relative(dir, item),
421
+ path: path3.relative(dir, item),
397
422
  absolutePath: item
398
423
  });
399
424
  }
@@ -415,18 +440,18 @@ function getImportCode(info) {
415
440
  return `import ${specifier}`;
416
441
  }
417
442
  function toImportPath(file, dir) {
418
- const ext = path2.extname(file);
419
- let importPath = path2.relative(
443
+ const ext = path3.extname(file);
444
+ let importPath = path3.relative(
420
445
  dir,
421
446
  ext === ".ts" ? file.substring(0, file.length - ext.length) : file
422
447
  );
423
- if (!path2.isAbsolute(importPath) && !importPath.startsWith(".")) {
448
+ if (!path3.isAbsolute(importPath) && !importPath.startsWith(".")) {
424
449
  importPath = `./${importPath}`;
425
450
  }
426
- return importPath.replaceAll(path2.sep, "/");
451
+ return importPath.replaceAll(path3.sep, "/");
427
452
  }
428
453
  function parseMetaEntry(file, content) {
429
- const extname3 = path2.extname(file);
454
+ const extname3 = path3.extname(file);
430
455
  try {
431
456
  if (extname3 === ".json") return JSON.parse(content);
432
457
  if (extname3 === ".yaml") return (0, import_js_yaml.load)(content);
@@ -439,10 +464,10 @@ function parseMetaEntry(file, content) {
439
464
  }
440
465
 
441
466
  // src/map/index.ts
442
- async function start(dev, configPath, outDir2) {
467
+ async function start(dev, configPath, outDir) {
443
468
  let configHash = await getConfigHash(configPath);
444
- let config = await loadConfig(configPath, configHash, true);
445
- const outPath = path3.resolve(outDir2, `index.ts`);
469
+ let config = await loadConfig(configPath, outDir, configHash, true);
470
+ const outPath = path4.resolve(outDir, `index.ts`);
446
471
  async function updateMapFile() {
447
472
  const start2 = performance.now();
448
473
  try {
@@ -452,7 +477,7 @@ async function start(dev, configPath, outDir2) {
452
477
  );
453
478
  } catch (err) {
454
479
  if (err instanceof ValidationError) {
455
- err.print();
480
+ console.error(err.toStringFormatted());
456
481
  } else {
457
482
  console.error(err);
458
483
  }
@@ -468,12 +493,12 @@ async function start(dev, configPath, outDir2) {
468
493
  });
469
494
  instance.on("all", (event, file) => {
470
495
  if (typeof file !== "string") return;
471
- const absolutePath = path3.resolve(file);
496
+ const absolutePath = path4.resolve(file);
472
497
  const onUpdate = async () => {
473
498
  const isConfigFile = absolutePath === configPath;
474
499
  if (isConfigFile) {
475
500
  configHash = await getConfigHash(configPath);
476
- config = await loadConfig(configPath, configHash, true);
501
+ config = await loadConfig(configPath, outDir, configHash, true);
477
502
  }
478
503
  if (event === "change") fileCache.removeCache(absolutePath);
479
504
  await updateMapFile();
@@ -488,10 +513,10 @@ async function start(dev, configPath, outDir2) {
488
513
  }
489
514
 
490
515
  // src/next/create.ts
491
- var outDir = import_node_path2.default.resolve(".source");
492
516
  var defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
493
517
  function createMDX({
494
- configPath = findConfigFile()
518
+ configPath = findConfigFile(),
519
+ outDir = ".source"
495
520
  } = {}) {
496
521
  const isDev = process.argv.includes("dev");
497
522
  const isBuild = process.argv.includes("build");
@@ -501,9 +526,8 @@ function createMDX({
501
526
  }
502
527
  return (nextConfig = {}) => {
503
528
  const mdxLoaderOptions = {
504
- _ctx: {
505
- configPath
506
- }
529
+ configPath,
530
+ outDir
507
531
  };
508
532
  return {
509
533
  ...nextConfig,
@@ -548,10 +572,10 @@ function createMDX({
548
572
  // src/postinstall.ts
549
573
  var path5 = __toESM(require("path"), 1);
550
574
  var fs4 = __toESM(require("fs/promises"), 1);
551
- async function postInstall(configPath = findConfigFile()) {
552
- const jsOut = path5.resolve(".source/index.ts");
575
+ async function postInstall(configPath = findConfigFile(), outDir = ".source") {
576
+ const jsOut = path5.resolve(outDir, "index.ts");
553
577
  const hash = await getConfigHash(configPath);
554
- const config = await loadConfig(configPath, hash, true);
578
+ const config = await loadConfig(configPath, outDir, hash, true);
555
579
  await fs4.rm(path5.dirname(jsOut), { recursive: true });
556
580
  await fs4.mkdir(path5.dirname(jsOut), { recursive: true });
557
581
  await fs4.writeFile(jsOut, await generateJS(configPath, config, jsOut, hash));
@@ -12,10 +12,16 @@ interface CreateMDXOptions {
12
12
  * Path to source configuration file
13
13
  */
14
14
  configPath?: string;
15
+ /**
16
+ * Directory for output files
17
+ *
18
+ * @defaultValue '.source'
19
+ */
20
+ outDir?: string;
15
21
  }
16
22
 
17
- declare function createMDX({ configPath, }?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
23
+ declare function createMDX({ configPath, outDir, }?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
18
24
 
19
- declare function postInstall(configPath?: string): Promise<void>;
25
+ declare function postInstall(configPath?: string, outDir?: string): Promise<void>;
20
26
 
21
27
  export { type CreateMDXOptions, createMDX, postInstall, start };
@@ -12,10 +12,16 @@ interface CreateMDXOptions {
12
12
  * Path to source configuration file
13
13
  */
14
14
  configPath?: string;
15
+ /**
16
+ * Directory for output files
17
+ *
18
+ * @defaultValue '.source'
19
+ */
20
+ outDir?: string;
15
21
  }
16
22
 
17
- declare function createMDX({ configPath, }?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
23
+ declare function createMDX({ configPath, outDir, }?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
18
24
 
19
- declare function postInstall(configPath?: string): Promise<void>;
25
+ declare function postInstall(configPath?: string, outDir?: string): Promise<void>;
20
26
 
21
27
  export { type CreateMDXOptions, createMDX, postInstall, start };
@@ -1,17 +1,15 @@
1
1
  import {
2
2
  findConfigFile,
3
3
  getConfigHash,
4
+ getGitTimestamp,
4
5
  loadConfig
5
- } from "../chunk-LC4HO353.js";
6
+ } from "../chunk-SXOJYWZ3.js";
6
7
  import {
7
8
  ValidationError,
8
9
  validate
9
- } from "../chunk-2ZOW45YZ.js";
10
+ } from "../chunk-OTM6WYMS.js";
10
11
  import "../chunk-DRVUBK5B.js";
11
12
 
12
- // src/next/create.ts
13
- import path3 from "path";
14
-
15
13
  // src/map/index.ts
16
14
  import * as path2 from "path";
17
15
  import * as fs2 from "fs/promises";
@@ -25,8 +23,8 @@ import { glob } from "tinyglobby";
25
23
  import { extname } from "path";
26
24
  var docTypes = [".mdx", ".md"];
27
25
  var metaTypes = [".json", ".yaml"];
28
- function getTypeFromPath(path5) {
29
- const ext = extname(path5);
26
+ function getTypeFromPath(path4) {
27
+ const ext = extname(path4);
30
28
  if (docTypes.includes(ext)) return "doc";
31
29
  if (metaTypes.includes(ext)) return "meta";
32
30
  }
@@ -37,16 +35,16 @@ var map = new LRUCache({
37
35
  max: 200
38
36
  });
39
37
  var fileCache = {
40
- read(namespace, path5) {
41
- return map.get(`${namespace}.${path5}`);
38
+ read(namespace, path4) {
39
+ return map.get(`${namespace}.${path4}`);
42
40
  },
43
- write(namespace, path5, data) {
44
- map.set(`${namespace}.${path5}`, data);
41
+ write(namespace, path4, data) {
42
+ map.set(`${namespace}.${path4}`, data);
45
43
  },
46
- removeCache(path5) {
44
+ removeCache(path4) {
47
45
  for (const key of map.keys()) {
48
46
  const keyPath = key.slice(key.indexOf(".") + 1);
49
- if (keyPath === path5) map.delete(key);
47
+ if (keyPath === path4) map.delete(key);
50
48
  }
51
49
  }
52
50
  };
@@ -60,7 +58,7 @@ async function readFileWithCache(file) {
60
58
  return (await fs.readFile(file)).toString();
61
59
  }
62
60
  async function generateJS(configPath, config, outputPath, configHash) {
63
- const outDir2 = path.dirname(outputPath);
61
+ const outDir = path.dirname(outputPath);
64
62
  let asyncInit = false;
65
63
  const lines = [
66
64
  getImportCode({
@@ -70,7 +68,7 @@ async function generateJS(configPath, config, outputPath, configHash) {
70
68
  }),
71
69
  getImportCode({
72
70
  type: "namespace",
73
- specifier: toImportPath(configPath, outDir2),
71
+ specifier: toImportPath(configPath, outDir),
74
72
  name: "_source"
75
73
  })
76
74
  ];
@@ -82,7 +80,7 @@ async function generateJS(configPath, config, outputPath, configHash) {
82
80
  getImportCode({
83
81
  type: "namespace",
84
82
  name: importId,
85
- specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${collectionName}&hash=${configHash}`
83
+ specifier: `${toImportPath(file.absolutePath, outDir)}?collection=${collectionName}&hash=${configHash}`
86
84
  })
87
85
  );
88
86
  return `{ info: ${JSON.stringify(file)}, data: ${importId} }`;
@@ -136,8 +134,13 @@ async function generateJS(configPath, config, outputPath, configHash) {
136
134
  `invalid frontmatter in ${file.absolutePath}`
137
135
  );
138
136
  }
137
+ let lastModified;
138
+ if (config.global?.lastModifiedTime === "git") {
139
+ lastModified = await getGitTimestamp(file.absolutePath);
140
+ }
139
141
  return JSON.stringify({
140
142
  info: file,
143
+ lastModified,
141
144
  data: parsed.data,
142
145
  content: parsed.content
143
146
  });
@@ -231,10 +234,10 @@ function parseMetaEntry(file, content) {
231
234
  }
232
235
 
233
236
  // src/map/index.ts
234
- async function start(dev, configPath, outDir2) {
237
+ async function start(dev, configPath, outDir) {
235
238
  let configHash = await getConfigHash(configPath);
236
- let config = await loadConfig(configPath, configHash, true);
237
- const outPath = path2.resolve(outDir2, `index.ts`);
239
+ let config = await loadConfig(configPath, outDir, configHash, true);
240
+ const outPath = path2.resolve(outDir, `index.ts`);
238
241
  async function updateMapFile() {
239
242
  const start2 = performance.now();
240
243
  try {
@@ -244,7 +247,7 @@ async function start(dev, configPath, outDir2) {
244
247
  );
245
248
  } catch (err) {
246
249
  if (err instanceof ValidationError) {
247
- err.print();
250
+ console.error(err.toStringFormatted());
248
251
  } else {
249
252
  console.error(err);
250
253
  }
@@ -265,7 +268,7 @@ async function start(dev, configPath, outDir2) {
265
268
  const isConfigFile = absolutePath === configPath;
266
269
  if (isConfigFile) {
267
270
  configHash = await getConfigHash(configPath);
268
- config = await loadConfig(configPath, configHash, true);
271
+ config = await loadConfig(configPath, outDir, configHash, true);
269
272
  }
270
273
  if (event === "change") fileCache.removeCache(absolutePath);
271
274
  await updateMapFile();
@@ -280,10 +283,10 @@ async function start(dev, configPath, outDir2) {
280
283
  }
281
284
 
282
285
  // src/next/create.ts
283
- var outDir = path3.resolve(".source");
284
286
  var defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
285
287
  function createMDX({
286
- configPath = findConfigFile()
288
+ configPath = findConfigFile(),
289
+ outDir = ".source"
287
290
  } = {}) {
288
291
  const isDev = process.argv.includes("dev");
289
292
  const isBuild = process.argv.includes("build");
@@ -293,9 +296,8 @@ function createMDX({
293
296
  }
294
297
  return (nextConfig = {}) => {
295
298
  const mdxLoaderOptions = {
296
- _ctx: {
297
- configPath
298
- }
299
+ configPath,
300
+ outDir
299
301
  };
300
302
  return {
301
303
  ...nextConfig,
@@ -338,14 +340,14 @@ function createMDX({
338
340
  }
339
341
 
340
342
  // src/postinstall.ts
341
- import * as path4 from "path";
343
+ import * as path3 from "path";
342
344
  import * as fs3 from "fs/promises";
343
- async function postInstall(configPath = findConfigFile()) {
344
- const jsOut = path4.resolve(".source/index.ts");
345
+ async function postInstall(configPath = findConfigFile(), outDir = ".source") {
346
+ const jsOut = path3.resolve(outDir, "index.ts");
345
347
  const hash = await getConfigHash(configPath);
346
- const config = await loadConfig(configPath, hash, true);
347
- await fs3.rm(path4.dirname(jsOut), { recursive: true });
348
- await fs3.mkdir(path4.dirname(jsOut), { recursive: true });
348
+ const config = await loadConfig(configPath, outDir, hash, true);
349
+ await fs3.rm(path3.dirname(jsOut), { recursive: true });
350
+ await fs3.mkdir(path3.dirname(jsOut), { recursive: true });
349
351
  await fs3.writeFile(jsOut, await generateJS(configPath, config, jsOut, hash));
350
352
  console.log("[MDX] types generated");
351
353
  }
@@ -95,7 +95,10 @@ function remarkInclude() {
95
95
  parsed
96
96
  );
97
97
  }).catch((e) => {
98
- console.warn(`failed to read file: ${targetPath}`, e);
98
+ throw new Error(
99
+ `failed to read file ${targetPath}
100
+ ${e instanceof Error ? e.message : String(e)}`
101
+ );
99
102
  })
100
103
  );
101
104
  return "skip";
@@ -223,10 +226,14 @@ async function initCompiler(config, collection) {
223
226
  mdxOptions = col.docs?.mdxOptions;
224
227
  if (!mdxOptions) {
225
228
  config._mdx_async ??= {};
226
- config._mdx_async.cachedMdxOptions ??= typeof config.global?.mdxOptions === "function" ? await config.global.mdxOptions() : config.global?.mdxOptions ?? {};
227
- mdxOptions = config._mdx_async.cachedMdxOptions;
229
+ const async = config._mdx_async;
230
+ const globalConfig = config.global;
231
+ if (globalConfig && !async.cachedMdxOptions) {
232
+ async.cachedMdxOptions = typeof globalConfig.mdxOptions === "function" ? await globalConfig.mdxOptions() : globalConfig.mdxOptions;
233
+ }
234
+ mdxOptions = async.cachedMdxOptions;
228
235
  }
229
- const remarkPlugins = mdxOptions.remarkPlugins ?? [];
236
+ const remarkPlugins = mdxOptions?.remarkPlugins ?? [];
230
237
  return (0, import_mdx_remote.createCompiler)({
231
238
  ...mdxOptions,
232
239
  remarkPlugins: (v) => typeof remarkPlugins === "function" ? [remarkInclude, ...remarkPlugins(v), import_mdx_plugins.remarkStructure] : [remarkInclude, ...v, ...remarkPlugins, import_mdx_plugins.remarkStructure]
@@ -235,7 +242,7 @@ async function initCompiler(config, collection) {
235
242
  var _runtimeAsync = {
236
243
  doc(files, collection, config) {
237
244
  const init = initCompiler(config, collection);
238
- return files.map(({ info: file, data, content }) => {
245
+ return files.map(({ info: file, data, content, lastModified }) => {
239
246
  return {
240
247
  ...data,
241
248
  _file: file,
@@ -249,6 +256,7 @@ var _runtimeAsync = {
249
256
  return {
250
257
  body: out.body,
251
258
  toc: out.toc,
259
+ lastModified,
252
260
  structuredData: out.vfile.data.structuredData,
253
261
  _exports: out.exports ?? {}
254
262
  };
@@ -1,4 +1,4 @@
1
- import { L as LoadedConfig, a as RuntimeAsync } from '../types-Cph8Ml_K.cjs';
1
+ import { L as LoadedConfig, a as RuntimeAsync } from '../types-BsJd_P5O.cjs';
2
2
  import '../define-uoePrCQ_.cjs';
3
3
  import '@mdx-js/mdx';
4
4
  import 'mdx/types';
@@ -1,4 +1,4 @@
1
- import { L as LoadedConfig, a as RuntimeAsync } from '../types-BvEsyMKj.js';
1
+ import { L as LoadedConfig, a as RuntimeAsync } from '../types-BYJBKH4G.js';
2
2
  import '../define-uoePrCQ_.js';
3
3
  import '@mdx-js/mdx';
4
4
  import 'mdx/types';
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-7SSA5RCV.js";
5
5
  import {
6
6
  remarkInclude
7
- } from "../chunk-3UUEUK4M.js";
7
+ } from "../chunk-2Z6EJ3GA.js";
8
8
  import {
9
9
  buildConfig
10
10
  } from "../chunk-DRVUBK5B.js";
@@ -22,10 +22,14 @@ async function initCompiler(config, collection) {
22
22
  mdxOptions = col.docs?.mdxOptions;
23
23
  if (!mdxOptions) {
24
24
  config._mdx_async ??= {};
25
- config._mdx_async.cachedMdxOptions ??= typeof config.global?.mdxOptions === "function" ? await config.global.mdxOptions() : config.global?.mdxOptions ?? {};
26
- mdxOptions = config._mdx_async.cachedMdxOptions;
25
+ const async = config._mdx_async;
26
+ const globalConfig = config.global;
27
+ if (globalConfig && !async.cachedMdxOptions) {
28
+ async.cachedMdxOptions = typeof globalConfig.mdxOptions === "function" ? await globalConfig.mdxOptions() : globalConfig.mdxOptions;
29
+ }
30
+ mdxOptions = async.cachedMdxOptions;
27
31
  }
28
- const remarkPlugins = mdxOptions.remarkPlugins ?? [];
32
+ const remarkPlugins = mdxOptions?.remarkPlugins ?? [];
29
33
  return createCompiler({
30
34
  ...mdxOptions,
31
35
  remarkPlugins: (v) => typeof remarkPlugins === "function" ? [remarkInclude, ...remarkPlugins(v), remarkStructure] : [remarkInclude, ...v, ...remarkPlugins, remarkStructure]
@@ -34,7 +38,7 @@ async function initCompiler(config, collection) {
34
38
  var _runtimeAsync = {
35
39
  doc(files, collection, config) {
36
40
  const init = initCompiler(config, collection);
37
- return files.map(({ info: file, data, content }) => {
41
+ return files.map(({ info: file, data, content, lastModified }) => {
38
42
  return {
39
43
  ...data,
40
44
  _file: file,
@@ -48,6 +52,7 @@ var _runtimeAsync = {
48
52
  return {
49
53
  body: out.body,
50
54
  toc: out.toc,
55
+ lastModified,
51
56
  structuredData: out.vfile.data.structuredData,
52
57
  _exports: out.exports ?? {}
53
58
  };
@@ -8,7 +8,7 @@ interface LoadedConfig {
8
8
  collections: Map<string, DocCollection | MetaCollection | DocsCollection>;
9
9
  global?: GlobalConfig;
10
10
  _mdx_loader?: {
11
- cachedProcessorOptions?: ProcessorOptions;
11
+ cachedOptions?: ProcessorOptions;
12
12
  };
13
13
  _mdx_async?: {
14
14
  cachedMdxOptions?: MDXOptions;
@@ -23,6 +23,7 @@ interface AsyncRuntimeFile {
23
23
  info: FileInfo;
24
24
  data: Record<string, unknown>;
25
25
  content: string;
26
+ lastModified?: Date;
26
27
  }
27
28
  type DocOut<Schema extends StandardSchemaV1> = Override<MarkdownProps & {
28
29
  /**
@@ -8,7 +8,7 @@ interface LoadedConfig {
8
8
  collections: Map<string, DocCollection | MetaCollection | DocsCollection>;
9
9
  global?: GlobalConfig;
10
10
  _mdx_loader?: {
11
- cachedProcessorOptions?: ProcessorOptions;
11
+ cachedOptions?: ProcessorOptions;
12
12
  };
13
13
  _mdx_async?: {
14
14
  cachedMdxOptions?: MDXOptions;
@@ -23,6 +23,7 @@ interface AsyncRuntimeFile {
23
23
  info: FileInfo;
24
24
  data: Record<string, unknown>;
25
25
  content: string;
26
+ lastModified?: Date;
26
27
  }
27
28
  type DocOut<Schema extends StandardSchemaV1> = Override<MarkdownProps & {
28
29
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-mdx",
3
- "version": "11.6.5",
3
+ "version": "11.6.7",
4
4
  "description": "The built-in source for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -45,31 +45,30 @@
45
45
  "@mdx-js/mdx": "^3.1.0",
46
46
  "@standard-schema/spec": "^1.0.0",
47
47
  "chokidar": "^4.0.3",
48
- "cross-spawn": "^7.0.6",
49
- "esbuild": "^0.25.4",
48
+ "esbuild": "^0.25.5",
50
49
  "estree-util-value-to-estree": "^3.4.0",
51
50
  "gray-matter": "^4.0.3",
52
51
  "js-yaml": "^4.1.0",
53
52
  "lru-cache": "^11.1.0",
54
53
  "picocolors": "^1.1.1",
55
- "tinyglobby": "^0.2.13",
54
+ "tinyexec": "^1.0.1",
55
+ "tinyglobby": "^0.2.14",
56
56
  "unist-util-visit": "^5.0.0",
57
- "zod": "^3.25.7"
57
+ "zod": "^3.25.42"
58
58
  },
59
59
  "devDependencies": {
60
- "@types/cross-spawn": "^6.0.6",
61
60
  "@types/js-yaml": "^4.0.9",
62
61
  "@types/mdast": "^4.0.3",
63
62
  "@types/mdx": "^2.0.13",
64
- "@types/react": "^19.1.4",
63
+ "@types/react": "^19.1.6",
65
64
  "mdast-util-mdx-jsx": "^3.2.0",
66
- "next": "^15.3.2",
65
+ "next": "^15.3.3",
67
66
  "unified": "^11.0.5",
68
67
  "vfile": "^6.0.3",
69
68
  "webpack": "^5.99.9",
70
69
  "@fumadocs/mdx-remote": "1.3.2",
71
70
  "eslint-config-custom": "0.0.0",
72
- "fumadocs-core": "15.3.4",
71
+ "fumadocs-core": "15.5.1",
73
72
  "tsconfig": "0.0.0"
74
73
  },
75
74
  "peerDependencies": {