fumadocs-mdx 11.7.3 → 11.7.4

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,6 +1,6 @@
1
1
  import {
2
2
  remarkInclude
3
- } from "./chunk-AVMO2SRO.js";
3
+ } from "./chunk-PQCNPAD3.js";
4
4
 
5
5
  // src/utils/build-mdx.ts
6
6
  import { createProcessor } from "@mdx-js/mdx";
@@ -12,9 +12,29 @@ function flattenNode(node) {
12
12
  if ("value" in node) return node.value;
13
13
  return "";
14
14
  }
15
+ function parseSpecifier(specifier) {
16
+ const idx = specifier.lastIndexOf("#");
17
+ if (idx === -1) return { file: specifier };
18
+ return {
19
+ file: specifier.slice(0, idx),
20
+ section: specifier.slice(idx + 1)
21
+ };
22
+ }
23
+ function extractSection(root, section) {
24
+ for (const node of root.children) {
25
+ if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
26
+ (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
27
+ )) {
28
+ return {
29
+ type: "root",
30
+ children: node.children
31
+ };
32
+ }
33
+ }
34
+ }
15
35
  function remarkInclude() {
16
36
  const TagName = "include";
17
- async function update(tree, file, processor, compiler) {
37
+ async function update(tree, directory, processor, compiler) {
18
38
  const queue = [];
19
39
  visit(
20
40
  tree,
@@ -34,27 +54,41 @@ function remarkInclude() {
34
54
  }
35
55
  }
36
56
  if (!specifier) return;
57
+ const { file, section } = parseSpecifier(specifier);
37
58
  const targetPath = path.resolve(
38
- "cwd" in params ? process.cwd() : path.dirname(file),
39
- specifier
59
+ "cwd" in params ? process.cwd() : directory,
60
+ file
40
61
  );
41
- const asCode = params.lang || !specifier.endsWith(".md") && !specifier.endsWith(".mdx");
62
+ const asCode = params.lang || !file.endsWith(".md") && !file.endsWith(".mdx");
42
63
  queue.push(
43
64
  fs.readFile(targetPath).then((buffer) => buffer.toString()).then(async (content) => {
44
65
  compiler?.addDependency(targetPath);
45
66
  if (asCode) {
46
- const lang = params.lang ?? path.extname(specifier).slice(1);
67
+ const lang = params.lang ?? path.extname(file).slice(1);
47
68
  Object.assign(node, {
48
69
  type: "code",
49
70
  lang,
50
71
  meta: params.meta,
51
- value: content.toString(),
72
+ value: content,
52
73
  data: {}
53
74
  });
54
75
  return;
55
76
  }
56
- const parsed = processor.parse(fumaMatter(content).content);
57
- await update(parsed, targetPath, processor, compiler);
77
+ let parsed = processor.parse(fumaMatter(content).content);
78
+ if (section) {
79
+ const extracted = extractSection(parsed, section);
80
+ if (!extracted)
81
+ throw new Error(
82
+ `Cannot find section ${section} in ${file}, make sure you have encapsulated the section in a <section id="${section}"> tag`
83
+ );
84
+ parsed = extracted;
85
+ }
86
+ await update(
87
+ parsed,
88
+ path.dirname(targetPath),
89
+ processor,
90
+ compiler
91
+ );
58
92
  Object.assign(
59
93
  parent && parent.type === "paragraph" ? parent : node,
60
94
  parsed
@@ -62,7 +96,8 @@ function remarkInclude() {
62
96
  }).catch((e) => {
63
97
  throw new Error(
64
98
  `failed to read file ${targetPath}
65
- ${e instanceof Error ? e.message : String(e)}`
99
+ ${e instanceof Error ? e.message : String(e)}`,
100
+ { cause: e }
66
101
  );
67
102
  })
68
103
  );
@@ -72,7 +107,7 @@ ${e instanceof Error ? e.message : String(e)}`
72
107
  await Promise.all(queue);
73
108
  }
74
109
  return async (tree, file) => {
75
- await update(tree, file.path, this, file.data._compiler);
110
+ await update(tree, path.dirname(file.path), this, file.data._compiler);
76
111
  };
77
112
  }
78
113
 
@@ -232,9 +232,29 @@ function flattenNode(node) {
232
232
  if ("value" in node) return node.value;
233
233
  return "";
234
234
  }
235
+ function parseSpecifier(specifier) {
236
+ const idx = specifier.lastIndexOf("#");
237
+ if (idx === -1) return { file: specifier };
238
+ return {
239
+ file: specifier.slice(0, idx),
240
+ section: specifier.slice(idx + 1)
241
+ };
242
+ }
243
+ function extractSection(root, section) {
244
+ for (const node of root.children) {
245
+ if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
246
+ (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
247
+ )) {
248
+ return {
249
+ type: "root",
250
+ children: node.children
251
+ };
252
+ }
253
+ }
254
+ }
235
255
  function remarkInclude() {
236
256
  const TagName = "include";
237
- async function update(tree, file, processor, compiler) {
257
+ async function update(tree, directory, processor, compiler) {
238
258
  const queue = [];
239
259
  (0, import_unist_util_visit.visit)(
240
260
  tree,
@@ -254,27 +274,41 @@ function remarkInclude() {
254
274
  }
255
275
  }
256
276
  if (!specifier) return;
277
+ const { file, section } = parseSpecifier(specifier);
257
278
  const targetPath = path.resolve(
258
- "cwd" in params ? process.cwd() : path.dirname(file),
259
- specifier
279
+ "cwd" in params ? process.cwd() : directory,
280
+ file
260
281
  );
261
- const asCode = params.lang || !specifier.endsWith(".md") && !specifier.endsWith(".mdx");
282
+ const asCode = params.lang || !file.endsWith(".md") && !file.endsWith(".mdx");
262
283
  queue.push(
263
284
  fs.readFile(targetPath).then((buffer) => buffer.toString()).then(async (content) => {
264
285
  compiler?.addDependency(targetPath);
265
286
  if (asCode) {
266
- const lang = params.lang ?? path.extname(specifier).slice(1);
287
+ const lang = params.lang ?? path.extname(file).slice(1);
267
288
  Object.assign(node, {
268
289
  type: "code",
269
290
  lang,
270
291
  meta: params.meta,
271
- value: content.toString(),
292
+ value: content,
272
293
  data: {}
273
294
  });
274
295
  return;
275
296
  }
276
- const parsed = processor.parse(fumaMatter(content).content);
277
- await update(parsed, targetPath, processor, compiler);
297
+ let parsed = processor.parse(fumaMatter(content).content);
298
+ if (section) {
299
+ const extracted = extractSection(parsed, section);
300
+ if (!extracted)
301
+ throw new Error(
302
+ `Cannot find section ${section} in ${file}, make sure you have encapsulated the section in a <section id="${section}"> tag`
303
+ );
304
+ parsed = extracted;
305
+ }
306
+ await update(
307
+ parsed,
308
+ path.dirname(targetPath),
309
+ processor,
310
+ compiler
311
+ );
278
312
  Object.assign(
279
313
  parent && parent.type === "paragraph" ? parent : node,
280
314
  parsed
@@ -282,7 +316,8 @@ function remarkInclude() {
282
316
  }).catch((e) => {
283
317
  throw new Error(
284
318
  `failed to read file ${targetPath}
285
- ${e instanceof Error ? e.message : String(e)}`
319
+ ${e instanceof Error ? e.message : String(e)}`,
320
+ { cause: e }
286
321
  );
287
322
  })
288
323
  );
@@ -292,7 +327,7 @@ ${e instanceof Error ? e.message : String(e)}`
292
327
  await Promise.all(queue);
293
328
  }
294
329
  return async (tree, file) => {
295
- await update(tree, file.path, this, file.data._compiler);
330
+ await update(tree, path.dirname(file.path), this, file.data._compiler);
296
331
  };
297
332
  }
298
333
  // Annotate the CommonJS export names for ESM import in node:
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-ZOWJF3OH.js";
5
5
  import {
6
6
  remarkInclude
7
- } from "../chunk-AVMO2SRO.js";
7
+ } from "../chunk-PQCNPAD3.js";
8
8
  import "../chunk-KVWX6THC.js";
9
9
  import {
10
10
  getDefaultMDXOptions
@@ -292,9 +292,29 @@ function flattenNode(node) {
292
292
  if ("value" in node) return node.value;
293
293
  return "";
294
294
  }
295
+ function parseSpecifier(specifier) {
296
+ const idx = specifier.lastIndexOf("#");
297
+ if (idx === -1) return { file: specifier };
298
+ return {
299
+ file: specifier.slice(0, idx),
300
+ section: specifier.slice(idx + 1)
301
+ };
302
+ }
303
+ function extractSection(root, section) {
304
+ for (const node of root.children) {
305
+ if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
306
+ (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
307
+ )) {
308
+ return {
309
+ type: "root",
310
+ children: node.children
311
+ };
312
+ }
313
+ }
314
+ }
295
315
  function remarkInclude() {
296
316
  const TagName = "include";
297
- async function update(tree, file, processor, compiler) {
317
+ async function update(tree, directory, processor, compiler) {
298
318
  const queue = [];
299
319
  (0, import_unist_util_visit.visit)(
300
320
  tree,
@@ -314,27 +334,41 @@ function remarkInclude() {
314
334
  }
315
335
  }
316
336
  if (!specifier) return;
337
+ const { file, section } = parseSpecifier(specifier);
317
338
  const targetPath = path2.resolve(
318
- "cwd" in params ? process.cwd() : path2.dirname(file),
319
- specifier
339
+ "cwd" in params ? process.cwd() : directory,
340
+ file
320
341
  );
321
- const asCode = params.lang || !specifier.endsWith(".md") && !specifier.endsWith(".mdx");
342
+ const asCode = params.lang || !file.endsWith(".md") && !file.endsWith(".mdx");
322
343
  queue.push(
323
344
  fs2.readFile(targetPath).then((buffer) => buffer.toString()).then(async (content) => {
324
345
  compiler?.addDependency(targetPath);
325
346
  if (asCode) {
326
- const lang = params.lang ?? path2.extname(specifier).slice(1);
347
+ const lang = params.lang ?? path2.extname(file).slice(1);
327
348
  Object.assign(node, {
328
349
  type: "code",
329
350
  lang,
330
351
  meta: params.meta,
331
- value: content.toString(),
352
+ value: content,
332
353
  data: {}
333
354
  });
334
355
  return;
335
356
  }
336
- const parsed = processor.parse(fumaMatter(content).content);
337
- await update(parsed, targetPath, processor, compiler);
357
+ let parsed = processor.parse(fumaMatter(content).content);
358
+ if (section) {
359
+ const extracted = extractSection(parsed, section);
360
+ if (!extracted)
361
+ throw new Error(
362
+ `Cannot find section ${section} in ${file}, make sure you have encapsulated the section in a <section id="${section}"> tag`
363
+ );
364
+ parsed = extracted;
365
+ }
366
+ await update(
367
+ parsed,
368
+ path2.dirname(targetPath),
369
+ processor,
370
+ compiler
371
+ );
338
372
  Object.assign(
339
373
  parent && parent.type === "paragraph" ? parent : node,
340
374
  parsed
@@ -342,7 +376,8 @@ function remarkInclude() {
342
376
  }).catch((e) => {
343
377
  throw new Error(
344
378
  `failed to read file ${targetPath}
345
- ${e instanceof Error ? e.message : String(e)}`
379
+ ${e instanceof Error ? e.message : String(e)}`,
380
+ { cause: e }
346
381
  );
347
382
  })
348
383
  );
@@ -352,7 +387,7 @@ ${e instanceof Error ? e.message : String(e)}`
352
387
  await Promise.all(queue);
353
388
  }
354
389
  return async (tree, file) => {
355
- await update(tree, file.path, this, file.data._compiler);
390
+ await update(tree, path2.dirname(file.path), this, file.data._compiler);
356
391
  };
357
392
  }
358
393
 
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  buildMDX,
7
7
  countLines
8
- } from "./chunk-C5INPAZJ.js";
8
+ } from "./chunk-2K55VKP6.js";
9
9
  import {
10
10
  getGitTimestamp
11
11
  } from "./chunk-VUEZTR2H.js";
@@ -13,7 +13,7 @@ import {
13
13
  ValidationError,
14
14
  validate
15
15
  } from "./chunk-ZOWJF3OH.js";
16
- import "./chunk-AVMO2SRO.js";
16
+ import "./chunk-PQCNPAD3.js";
17
17
  import "./chunk-JFNBRKRV.js";
18
18
  import {
19
19
  fumaMatter
@@ -195,9 +195,29 @@ function flattenNode(node) {
195
195
  if ("value" in node) return node.value;
196
196
  return "";
197
197
  }
198
+ function parseSpecifier(specifier) {
199
+ const idx = specifier.lastIndexOf("#");
200
+ if (idx === -1) return { file: specifier };
201
+ return {
202
+ file: specifier.slice(0, idx),
203
+ section: specifier.slice(idx + 1)
204
+ };
205
+ }
206
+ function extractSection(root, section) {
207
+ for (const node of root.children) {
208
+ if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
209
+ (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
210
+ )) {
211
+ return {
212
+ type: "root",
213
+ children: node.children
214
+ };
215
+ }
216
+ }
217
+ }
198
218
  function remarkInclude() {
199
219
  const TagName = "include";
200
- async function update(tree, file, processor, compiler) {
220
+ async function update(tree, directory, processor, compiler) {
201
221
  const queue = [];
202
222
  (0, import_unist_util_visit.visit)(
203
223
  tree,
@@ -217,27 +237,41 @@ function remarkInclude() {
217
237
  }
218
238
  }
219
239
  if (!specifier) return;
240
+ const { file, section } = parseSpecifier(specifier);
220
241
  const targetPath = path.resolve(
221
- "cwd" in params ? process.cwd() : path.dirname(file),
222
- specifier
242
+ "cwd" in params ? process.cwd() : directory,
243
+ file
223
244
  );
224
- const asCode = params.lang || !specifier.endsWith(".md") && !specifier.endsWith(".mdx");
245
+ const asCode = params.lang || !file.endsWith(".md") && !file.endsWith(".mdx");
225
246
  queue.push(
226
247
  fs.readFile(targetPath).then((buffer) => buffer.toString()).then(async (content) => {
227
248
  compiler?.addDependency(targetPath);
228
249
  if (asCode) {
229
- const lang = params.lang ?? path.extname(specifier).slice(1);
250
+ const lang = params.lang ?? path.extname(file).slice(1);
230
251
  Object.assign(node, {
231
252
  type: "code",
232
253
  lang,
233
254
  meta: params.meta,
234
- value: content.toString(),
255
+ value: content,
235
256
  data: {}
236
257
  });
237
258
  return;
238
259
  }
239
- const parsed = processor.parse(fumaMatter(content).content);
240
- await update(parsed, targetPath, processor, compiler);
260
+ let parsed = processor.parse(fumaMatter(content).content);
261
+ if (section) {
262
+ const extracted = extractSection(parsed, section);
263
+ if (!extracted)
264
+ throw new Error(
265
+ `Cannot find section ${section} in ${file}, make sure you have encapsulated the section in a <section id="${section}"> tag`
266
+ );
267
+ parsed = extracted;
268
+ }
269
+ await update(
270
+ parsed,
271
+ path.dirname(targetPath),
272
+ processor,
273
+ compiler
274
+ );
241
275
  Object.assign(
242
276
  parent && parent.type === "paragraph" ? parent : node,
243
277
  parsed
@@ -245,7 +279,8 @@ function remarkInclude() {
245
279
  }).catch((e) => {
246
280
  throw new Error(
247
281
  `failed to read file ${targetPath}
248
- ${e instanceof Error ? e.message : String(e)}`
282
+ ${e instanceof Error ? e.message : String(e)}`,
283
+ { cause: e }
249
284
  );
250
285
  })
251
286
  );
@@ -255,7 +290,7 @@ ${e instanceof Error ? e.message : String(e)}`
255
290
  await Promise.all(queue);
256
291
  }
257
292
  return async (tree, file) => {
258
- await update(tree, file.path, this, file.data._compiler);
293
+ await update(tree, path.dirname(file.path), this, file.data._compiler);
259
294
  };
260
295
  }
261
296
 
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-NUDEC6C5.js";
5
5
  import {
6
6
  remarkInclude
7
- } from "../chunk-AVMO2SRO.js";
7
+ } from "../chunk-PQCNPAD3.js";
8
8
  import {
9
9
  buildConfig
10
10
  } from "../chunk-JFNBRKRV.js";
@@ -240,9 +240,29 @@ function flattenNode(node) {
240
240
  if ("value" in node) return node.value;
241
241
  return "";
242
242
  }
243
+ function parseSpecifier(specifier) {
244
+ const idx = specifier.lastIndexOf("#");
245
+ if (idx === -1) return { file: specifier };
246
+ return {
247
+ file: specifier.slice(0, idx),
248
+ section: specifier.slice(idx + 1)
249
+ };
250
+ }
251
+ function extractSection(root, section) {
252
+ for (const node of root.children) {
253
+ if (node.type === "mdxJsxFlowElement" && node.name === "section" && node.attributes.some(
254
+ (attr) => attr.type === "mdxJsxAttribute" && attr.name === "id" && attr.value === section
255
+ )) {
256
+ return {
257
+ type: "root",
258
+ children: node.children
259
+ };
260
+ }
261
+ }
262
+ }
243
263
  function remarkInclude() {
244
264
  const TagName = "include";
245
- async function update(tree, file, processor, compiler) {
265
+ async function update(tree, directory, processor, compiler) {
246
266
  const queue = [];
247
267
  (0, import_unist_util_visit.visit)(
248
268
  tree,
@@ -262,27 +282,41 @@ function remarkInclude() {
262
282
  }
263
283
  }
264
284
  if (!specifier) return;
285
+ const { file, section } = parseSpecifier(specifier);
265
286
  const targetPath = path.resolve(
266
- "cwd" in params ? process.cwd() : path.dirname(file),
267
- specifier
287
+ "cwd" in params ? process.cwd() : directory,
288
+ file
268
289
  );
269
- const asCode = params.lang || !specifier.endsWith(".md") && !specifier.endsWith(".mdx");
290
+ const asCode = params.lang || !file.endsWith(".md") && !file.endsWith(".mdx");
270
291
  queue.push(
271
292
  fs.readFile(targetPath).then((buffer) => buffer.toString()).then(async (content) => {
272
293
  compiler?.addDependency(targetPath);
273
294
  if (asCode) {
274
- const lang = params.lang ?? path.extname(specifier).slice(1);
295
+ const lang = params.lang ?? path.extname(file).slice(1);
275
296
  Object.assign(node, {
276
297
  type: "code",
277
298
  lang,
278
299
  meta: params.meta,
279
- value: content.toString(),
300
+ value: content,
280
301
  data: {}
281
302
  });
282
303
  return;
283
304
  }
284
- const parsed = processor.parse(fumaMatter(content).content);
285
- await update(parsed, targetPath, processor, compiler);
305
+ let parsed = processor.parse(fumaMatter(content).content);
306
+ if (section) {
307
+ const extracted = extractSection(parsed, section);
308
+ if (!extracted)
309
+ throw new Error(
310
+ `Cannot find section ${section} in ${file}, make sure you have encapsulated the section in a <section id="${section}"> tag`
311
+ );
312
+ parsed = extracted;
313
+ }
314
+ await update(
315
+ parsed,
316
+ path.dirname(targetPath),
317
+ processor,
318
+ compiler
319
+ );
286
320
  Object.assign(
287
321
  parent && parent.type === "paragraph" ? parent : node,
288
322
  parsed
@@ -290,7 +324,8 @@ function remarkInclude() {
290
324
  }).catch((e) => {
291
325
  throw new Error(
292
326
  `failed to read file ${targetPath}
293
- ${e instanceof Error ? e.message : String(e)}`
327
+ ${e instanceof Error ? e.message : String(e)}`,
328
+ { cause: e }
294
329
  );
295
330
  })
296
331
  );
@@ -300,7 +335,7 @@ ${e instanceof Error ? e.message : String(e)}`
300
335
  await Promise.all(queue);
301
336
  }
302
337
  return async (tree, file) => {
303
- await update(tree, file.path, this, file.data._compiler);
338
+ await update(tree, path.dirname(file.path), this, file.data._compiler);
304
339
  };
305
340
  }
306
341
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  buildMDX,
3
3
  countLines
4
- } from "../chunk-C5INPAZJ.js";
4
+ } from "../chunk-2K55VKP6.js";
5
5
  import {
6
6
  getGlobPatterns,
7
7
  ident,
@@ -14,7 +14,7 @@ import {
14
14
  ValidationError,
15
15
  validate
16
16
  } from "../chunk-ZOWJF3OH.js";
17
- import "../chunk-AVMO2SRO.js";
17
+ import "../chunk-PQCNPAD3.js";
18
18
  import {
19
19
  buildConfig
20
20
  } from "../chunk-JFNBRKRV.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-mdx",
3
- "version": "11.7.3",
3
+ "version": "11.7.4",
4
4
  "description": "The built-in source for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -62,26 +62,26 @@
62
62
  "tinyexec": "^1.0.1",
63
63
  "tinyglobby": "^0.2.14",
64
64
  "unist-util-visit": "^5.0.0",
65
- "zod": "^4.0.14"
65
+ "zod": "^4.0.15"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/js-yaml": "^4.0.9",
69
69
  "@types/mdast": "^4.0.3",
70
70
  "@types/mdx": "^2.0.13",
71
- "@types/node": "^24.1.0",
71
+ "@types/node": "^24.2.0",
72
72
  "@types/react": "^19.1.9",
73
73
  "mdast-util-mdx-jsx": "^3.2.0",
74
- "next": "^15.4.5",
74
+ "next": "^15.4.6",
75
75
  "react": "^19.1.1",
76
76
  "rollup": "^4.46.2",
77
77
  "unified": "^11.0.5",
78
78
  "vfile": "^6.0.3",
79
- "vite": "^7.0.5",
79
+ "vite": "^7.1.0",
80
80
  "webpack": "^5.101.0",
81
- "@fumadocs/mdx-remote": "1.4.0",
81
+ "fumadocs-core": "15.6.9",
82
82
  "eslint-config-custom": "0.0.0",
83
- "fumadocs-core": "15.6.7",
84
- "tsconfig": "0.0.0"
83
+ "tsconfig": "0.0.0",
84
+ "@fumadocs/mdx-remote": "1.4.0"
85
85
  },
86
86
  "peerDependencies": {
87
87
  "@fumadocs/mdx-remote": "^1.4.0",