fumadocs-mdx 15.5.3 → 15.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/adapter-DUcfPohH.js +143 -0
  2. package/dist/{build-Bnz9TOnv.js → build-ClrPX9Ea.js} +2 -2
  3. package/dist/{build-default-BU_9K-PJ.js → build-default-CQWQe8Am.js} +20 -13
  4. package/dist/{build-satteri-D8On1S2_.js → build-satteri-D5Wi9P9C.js} +12 -6
  5. package/dist/bun/index.d.ts +1 -1
  6. package/dist/bun/index.js +3 -2
  7. package/dist/code-BWwFhg-7.js +168 -0
  8. package/dist/code-output-CvL35taM.js +40 -0
  9. package/dist/config/index.d.ts +1 -1
  10. package/dist/config/index.js +1 -1
  11. package/dist/{core-DA_zPpY3.d.ts → core-CrKTFOR5.d.ts} +18 -11
  12. package/dist/{index-BghUMTgU.d.ts → index-Cwcc8D9G.d.ts} +1 -1
  13. package/dist/{index-file-BKxOSG_x.js → index-file-BwHGQnO1.js} +17 -8
  14. package/dist/index.d.ts +1 -1
  15. package/dist/{last-modified-COIEvwZu.js → last-modified-CCz7qakL.js} +35 -1
  16. package/dist/macro/index.d.ts +1 -1
  17. package/dist/{mdx-VmqU5Oaj.js → mdx-onCcdgWo.js} +17 -46
  18. package/dist/meta-CmTae89C.js +123 -0
  19. package/dist/next/index.d.ts +1 -1
  20. package/dist/next/index.js +1 -1
  21. package/dist/node/_loader.js +3 -2
  22. package/dist/node/index.d.ts +1 -1
  23. package/dist/node/loader.js +3 -2
  24. package/dist/page-BVmw5SER.js +148 -0
  25. package/dist/plugins/index-file.d.ts +1 -1
  26. package/dist/plugins/index-file.js +1 -1
  27. package/dist/plugins/json-schema.d.ts +1 -1
  28. package/dist/plugins/last-modified.d.ts +1 -1
  29. package/dist/{preset-BLDvTSeK.js → preset-CUfyGsn3.js} +4 -3
  30. package/dist/press.js +14 -2
  31. package/dist/rolldown/index.d.ts +1 -1
  32. package/dist/rolldown/index.js +3 -2
  33. package/dist/runtime/browser.d.ts +20 -7
  34. package/dist/runtime/browser.js +17 -15
  35. package/dist/runtime/dynamic.d.ts +2 -2
  36. package/dist/runtime/dynamic.js +2 -2
  37. package/dist/runtime/macro.d.ts +2 -2
  38. package/dist/runtime/macro.js +4 -37
  39. package/dist/runtime/server.d.ts +3 -2
  40. package/dist/runtime/server.js +66 -82
  41. package/dist/runtime/types.d.ts +1 -1
  42. package/dist/{types-CBr1-xYX.d.ts → types-DfxNhkVk.d.ts} +5 -3
  43. package/dist/vite/index.d.ts +1 -1
  44. package/dist/vite/index.js +4 -3
  45. package/dist/webpack/macro.d.ts +1 -1
  46. package/dist/webpack/mdx.d.ts +1 -1
  47. package/dist/webpack/mdx.js +2 -2
  48. package/dist/webpack/meta.d.ts +1 -1
  49. package/dist/webpack/meta.js +2 -1
  50. package/package.json +3 -3
  51. package/dist/adapter-C04Ekc4W.js +0 -277
  52. package/dist/code-BF5OS485.js +0 -86
@@ -0,0 +1,143 @@
1
+ import { r as buildConfig } from "./build-TiTOkhq4.js";
2
+ import { n as ValidationError } from "./core-CJjfu3ju.js";
3
+ import { t as loadConfig } from "./load-from-file-gZlf7m88.js";
4
+ import { existsSync, readFileSync } from "node:fs";
5
+ import fs from "node:fs/promises";
6
+ import { fileURLToPath } from "node:url";
7
+ import { parse } from "node:querystring";
8
+ // src/loaders/config.ts
9
+ function createStandaloneConfigLoader({ core, buildConfig: buildConfig$1, mode }) {
10
+ let prev;
11
+ async function getConfigHash() {
12
+ if (mode === "production") return "static";
13
+ const stats = await fs.stat(core.configPath).catch(() => void 0);
14
+ return stats ? stats.mtime.getTime() : "missing";
15
+ }
16
+ async function load(hash) {
17
+ if (hash === "missing") return buildConfig({}, process.cwd());
18
+ return (await loadConfig(core, buildConfig$1)).config;
19
+ }
20
+ return { async getCore() {
21
+ const hash = await getConfigHash();
22
+ if (!prev || hash !== prev.hash) prev = {
23
+ hash,
24
+ init: core.init({ config: load(hash) })
25
+ };
26
+ await prev.init;
27
+ return core;
28
+ } };
29
+ }
30
+ /**
31
+ * create config loader from initialized core
32
+ */
33
+ function createIntegratedConfigLoader(core) {
34
+ return { async getCore() {
35
+ return core;
36
+ } };
37
+ }
38
+ // src/loaders/adapter.ts
39
+ function toNode(test, loader) {
40
+ return async (url, _context, nextLoad) => {
41
+ if (url.startsWith("file:///") && (!test || test.test(url))) {
42
+ const parsedUrl = new URL(url);
43
+ const filePath = fileURLToPath(parsedUrl);
44
+ const result = await loader.load({
45
+ filePath,
46
+ query: Object.fromEntries(parsedUrl.searchParams.entries()),
47
+ async getSource() {
48
+ return await fs.readFile(filePath, "utf-8");
49
+ },
50
+ development: false,
51
+ compiler: { addDependency() {} }
52
+ });
53
+ if (result) return {
54
+ source: result.code,
55
+ format: "module",
56
+ shortCircuit: true
57
+ };
58
+ }
59
+ return nextLoad(url);
60
+ };
61
+ }
62
+ function toVite(loader, getInput) {
63
+ return { async transform(value, id) {
64
+ const [file, query = ""] = id.split("?", 2);
65
+ try {
66
+ const parsedQuery = parse(query);
67
+ if ("raw" in parsedQuery) return null;
68
+ const result = await loader.load({
69
+ ...getInput?.(),
70
+ filePath: file,
71
+ query: parsedQuery,
72
+ getSource() {
73
+ return value;
74
+ },
75
+ development: this.environment ? this.environment.mode === "dev" : false,
76
+ compiler: { addDependency: (file) => {
77
+ if (existsSync(file)) this.addWatchFile(file);
78
+ } }
79
+ });
80
+ if (result === null) return null;
81
+ return {
82
+ code: result.code,
83
+ map: result.map ?? { mappings: "" },
84
+ moduleType: result.moduleType
85
+ };
86
+ } catch (e) {
87
+ if (e instanceof ValidationError) throw new Error(await e.toStringFormatted(), { cause: e });
88
+ throw e;
89
+ }
90
+ } };
91
+ }
92
+ /**
93
+ * need to handle the `test` regex in Webpack config instead.
94
+ */
95
+ function toWebpack(loader) {
96
+ return async function(source, callback) {
97
+ try {
98
+ const result = await loader.load({
99
+ filePath: this.resourcePath,
100
+ query: parse(this.resourceQuery.slice(1)),
101
+ getSource() {
102
+ return source;
103
+ },
104
+ development: this.mode === "development",
105
+ compiler: this
106
+ });
107
+ if (result === null) callback(void 0, source);
108
+ else callback(void 0, result.code, result.map);
109
+ } catch (error) {
110
+ if (error instanceof ValidationError) return callback(new Error(await error.toStringFormatted()));
111
+ if (!(error instanceof Error)) throw error;
112
+ callback(error);
113
+ }
114
+ };
115
+ }
116
+ function toBun(test, loader) {
117
+ function toResult(output) {
118
+ if (!output) return;
119
+ return {
120
+ contents: output.code,
121
+ loader: output.moduleType ?? "js"
122
+ };
123
+ }
124
+ return (build) => {
125
+ build.onLoad({ filter: test ?? /.+/ }, (args) => {
126
+ const [filePath, query = ""] = args.path.split("?", 2);
127
+ const input = {
128
+ async getSource() {
129
+ return Bun.file(filePath).text();
130
+ },
131
+ query: parse(query),
132
+ filePath,
133
+ development: false,
134
+ compiler: { addDependency() {} }
135
+ };
136
+ if (loader.bun?.load) return loader.bun.load(readFileSync(filePath, "utf-8"), input);
137
+ const result = loader.load(input);
138
+ if (result instanceof Promise) return result.then(toResult);
139
+ return toResult(result);
140
+ });
141
+ };
142
+ }
143
+ export { createIntegratedConfigLoader as a, toWebpack as i, toNode as n, createStandaloneConfigLoader as o, toVite as r, toBun as t };
@@ -3,10 +3,10 @@ import { t as __exportAll } from "./rolldown-runtime-D3KUYPsf.js";
3
3
  var build_exports = /* @__PURE__ */ __exportAll({ buildMDX: () => buildMDX });
4
4
  async function buildMDX(core, collection, options) {
5
5
  if ((collection ? collection.compiler : core.getConfig().global.compiler) === "satteri") {
6
- const { buildSatteriMDX } = await import("./build-satteri-D8On1S2_.js");
6
+ const { buildSatteriMDX } = await import("./build-satteri-D5Wi9P9C.js");
7
7
  return buildSatteriMDX(core, collection, options);
8
8
  }
9
- const { buildJSMDX } = await import("./build-default-BU_9K-PJ.js");
9
+ const { buildJSMDX } = await import("./build-default-CQWQe8Am.js");
10
10
  return buildJSMDX(core, collection, options);
11
11
  }
12
12
  export { build_exports as n, buildMDX as t };
@@ -1,5 +1,7 @@
1
- import { t as applyMdxPreset } from "./preset-BLDvTSeK.js";
2
- import { t as resolveLastModified } from "./last-modified-COIEvwZu.js";
1
+ import { t as applyMdxPreset } from "./preset-CUfyGsn3.js";
2
+ import { t as listCode } from "./code-output-CvL35taM.js";
3
+ import { r as walkBranches, t as resolveLastModified } from "./last-modified-CCz7qakL.js";
4
+ import { Parser } from "acorn";
3
5
  import { remarkInclude } from "fumadocs-core/mdx-plugins/remark-include";
4
6
  import { createProcessor } from "@mdx-js/mdx";
5
7
  import { VFile } from "vfile";
@@ -43,15 +45,20 @@ function remarkPostprocess({ includeProcessedMarkdown = false, includeMDAST = fa
43
45
  value: frontmatter
44
46
  });
45
47
  if (extractLinkReferences) {
46
- const urls = [];
47
- walk(tree, (node) => {
48
- if (node.type !== "link") return;
49
- urls.push({ href: node.url });
50
- return "skip";
48
+ const items = [];
49
+ walkBranches(tree, (node, when) => {
50
+ if (node.type === "link") items.push({
51
+ code: JSON.stringify({ href: node.url }),
52
+ when
53
+ });
51
54
  });
52
- file.data["mdx-export"].push({
53
- name: "extractedReferences",
54
- value: urls
55
+ tree.children.unshift({
56
+ type: "mdxjsEsm",
57
+ value: "",
58
+ data: { estree: Parser.parse(`export const extractedReferences = ${listCode(items, false)};`, {
59
+ ecmaVersion: "latest",
60
+ sourceType: "module"
61
+ }) }
55
62
  });
56
63
  }
57
64
  if (includeProcessedMarkdown) remarkLLMs(typeof includeProcessedMarkdown === "object" ? includeProcessedMarkdown : void 0)(tree, file, () => void 0);
@@ -110,7 +117,7 @@ function getMdastExport(name, value) {
110
117
  };
111
118
  }
112
119
  // src/loaders/mdx/build-default.ts
113
- async function buildJSMDX(core, collection, { filePath, frontmatter, source, _compiler, environment, isDevelopment, importsOnly = false, params }) {
120
+ async function buildJSMDX(core, collection, { filePath, frontmatter, source, _compiler, environment, isDevelopment, importsOnly = false }) {
114
121
  const mdxOptions = await getMDXOptions(core.getConfig(), collection, environment);
115
122
  function getProcessor(format) {
116
123
  const cache = core.cache;
@@ -142,7 +149,8 @@ async function buildJSMDX(core, collection, { filePath, frontmatter, source, _co
142
149
  cwd: collection?.cwd,
143
150
  data: {
144
151
  frontmatter,
145
- _compiler
152
+ _compiler,
153
+ unstable_runtimeOutputs: collection !== void 0
146
154
  }
147
155
  });
148
156
  if (collection) vfile = await core.transformVFile({
@@ -150,7 +158,6 @@ async function buildJSMDX(core, collection, { filePath, frontmatter, source, _co
150
158
  filePath,
151
159
  source
152
160
  }, vfile);
153
- vfile.data.params = params;
154
161
  const lastModified = await resolveLastModified(collection, filePath);
155
162
  if (lastModified) {
156
163
  vfile.data["mdx-export"] ??= [];
@@ -1,7 +1,8 @@
1
- import { t as resolveLastModified } from "./last-modified-COIEvwZu.js";
1
+ import { n as showConditions, t as resolveLastModified } from "./last-modified-CCz7qakL.js";
2
+ import { t as listCode } from "./code-output-CvL35taM.js";
2
3
  import { pathToFileURL } from "node:url";
3
4
  // src/loaders/mdx/build-satteri.ts
4
- async function buildSatteriMDX(core, collection, { filePath, frontmatter, source, _compiler, environment, isDevelopment, params }) {
5
+ async function buildSatteriMDX(core, collection, { filePath, frontmatter, source, _compiler, environment, isDevelopment }) {
5
6
  const satteriOptions = await getSatteriOptions(core.getConfig(), collection, environment);
6
7
  const format = filePath.endsWith(".mdx") ? "mdx" : "md";
7
8
  const postprocess = {
@@ -25,9 +26,9 @@ async function buildSatteriMDX(core, collection, { filePath, frontmatter, source
25
26
  const data = {
26
27
  frontmatter,
27
28
  _compiler,
28
- params,
29
29
  _cwd: collection?.cwd,
30
- _valueToExport: collection?.postprocess?.valueToExport
30
+ _valueToExport: collection?.postprocess?.valueToExport,
31
+ unstable_runtimeOutputs: collection !== void 0
31
32
  };
32
33
  const mdastPlugins = [remarkInclude({ cwd: collection?.cwd })];
33
34
  if (satteriOptions.mdastPlugins) mdastPlugins.push(...satteriOptions.mdastPlugins);
@@ -59,10 +60,15 @@ function postprocessPlugin({ extractLinkReferences = false }, lastModified) {
59
60
  if (!frontmatter.title && node.depth === 1) frontmatter.title = ctx.textContent(node);
60
61
  },
61
62
  link(node, ctx) {
62
- if (extractLinkReferences) ctx.data.extractedReferences.push({ href: node.url });
63
+ if (!extractLinkReferences) return;
64
+ const when = showConditions(node, ctx);
65
+ ctx.data.extractedReferences.push({
66
+ code: JSON.stringify({ href: node.url }),
67
+ when
68
+ });
63
69
  },
64
70
  collectExports({ data, addExport }) {
65
- if (extractLinkReferences) addExport("extractedReferences", JSON.stringify(data.extractedReferences));
71
+ if (extractLinkReferences) addExport("extractedReferences", listCode(data.extractedReferences, false));
66
72
  if (lastModified) addExport("lastModified", `new Date(${lastModified.getTime()})`);
67
73
  }
68
74
  };
@@ -1,4 +1,4 @@
1
- import { r as CoreOptions } from "../core-DA_zPpY3.js";
1
+ import { r as CoreOptions } from "../core-CrKTFOR5.js";
2
2
  import { n as ResolvedMacroOptions, t as MacroPluginOption } from "../options-BCId5Url.js";
3
3
  import { BunPlugin } from "bun";
4
4
  export interface MdxPluginOptions extends Pick<CoreOptions, 'configPath' | 'outDir' | 'plugins'> {
package/dist/bun/index.js CHANGED
@@ -1,7 +1,8 @@
1
- import { t as createMdxLoader } from "../mdx-VmqU5Oaj.js";
1
+ import { t as createMdxLoader } from "../mdx-onCcdgWo.js";
2
2
  import { r as buildConfig } from "../build-TiTOkhq4.js";
3
3
  import { t as createCore } from "../core-CJjfu3ju.js";
4
- import { a as createIntegratedConfigLoader, s as createMetaLoader, t as toBun } from "../adapter-C04Ekc4W.js";
4
+ import { a as createIntegratedConfigLoader, t as toBun } from "../adapter-DUcfPohH.js";
5
+ import { t as createMetaLoader } from "../meta-CmTae89C.js";
5
6
  import { r as metaLoaderGlob, t as mdxLoaderGlob } from "../loaders-3R0gLmlP.js";
6
7
  import { r as resolveMacroOptions } from "../options-B2o-zV4A.js";
7
8
  import { r as slash } from "../codegen-BAuFQ5Ew.js";
@@ -0,0 +1,168 @@
1
+ import { statSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { createRequire } from "node:module";
4
+ import { compileFunction } from "node:vm";
5
+ import { buildSync } from "esbuild";
6
+ import { Parser } from "acorn";
7
+ import acornJsx from "acorn-jsx";
8
+ import { fromMarkdown } from "mdast-util-from-markdown";
9
+ import { mdxFromMarkdown } from "mdast-util-mdx";
10
+ import { mdxjsEsm } from "micromark-extension-mdxjs-esm";
11
+ // ../shared/frontmatter-code.ts
12
+ /**
13
+ * The frontmatter in code of an ESM block, `export const frontmatter = ...`, as the module of `frontmatter(props = {})`:
14
+ * with the imports it reads and the exports before it in the block. `remove` is what to leave out of the content.
15
+ *
16
+ * @param imports - the imports of the document with their code, they are hoisted
17
+ */
18
+ function frontmatterModule(source, block, imports, range) {
19
+ let body = "";
20
+ const declarations = [];
21
+ for (const statement of block) {
22
+ const { declaration } = statement;
23
+ if (statement.type !== "ExportNamedDeclaration" || !declaration) continue;
24
+ body += `${source.slice(...range(declaration))}\n`;
25
+ declarations.push(declaration);
26
+ const [first, second] = declaration.declarations ?? [];
27
+ if (first?.id.type !== "Identifier" || first.id.name !== "frontmatter") continue;
28
+ const names = /* @__PURE__ */ new Set();
29
+ collectNames(declarations, names);
30
+ let code = "";
31
+ for (const [item, text] of imports) if (item.specifiers?.some(({ local }) => local.name && names.has(local.name))) code += `${text}\n`;
32
+ return {
33
+ module: `${code}export const frontmatter = (props = {}) => {\n${body}return frontmatter;\n};`,
34
+ remove: second ? [range(first)[0], range(second)[0]] : range(statement)
35
+ };
36
+ }
37
+ }
38
+ function collectNames(node, out) {
39
+ if (typeof node !== "object" || node === null) return;
40
+ if ("type" in node && node.type === "Identifier" && "name" in node) out.add(node.name);
41
+ for (const value of Object.values(node)) collectNames(value, out);
42
+ }
43
+ /**
44
+ * The data of a meta file in code, like `meta.ts`, from its exports: the default export, which can be a function of
45
+ * the params of its folder, and the `staticParams` as a named export or in its data.
46
+ */
47
+ function metaModule({ default: data, staticParams = data?.staticParams }) {
48
+ if (typeof data === "function") return {
49
+ data: { staticParams },
50
+ dataAt: data
51
+ };
52
+ return { data: {
53
+ ...data,
54
+ staticParams
55
+ } };
56
+ }
57
+ // src/loaders/mdx/code.ts
58
+ const esm = mdxjsEsm({
59
+ acorn: Parser.extend(acornJsx()),
60
+ acornOptions: {
61
+ ecmaVersion: "latest",
62
+ sourceType: "module"
63
+ },
64
+ addResult: true
65
+ });
66
+ /** the last run of each module: its code, the modification times of the files it read, its exports */
67
+ const modules = /* @__PURE__ */ new Map();
68
+ /**
69
+ * Run a module in code synchronously, like a meta file in TypeScript. Every page of a dynamic folder reads its meta
70
+ * file, it runs again only when it or a file it reads changes.
71
+ */
72
+ function runModule(file, contents, addDependency) {
73
+ const cached = modules.get(file);
74
+ if (cached?.contents === contents && cached.inputs.every(([input, time]) => mtime(input) === time)) {
75
+ for (const [input] of cached.inputs) addDependency(input);
76
+ return cached.exports;
77
+ }
78
+ const { outputFiles, metafile } = buildSync({
79
+ stdin: {
80
+ contents,
81
+ sourcefile: file,
82
+ resolveDir: path.dirname(file),
83
+ loader: file.endsWith(".mdx") ? "tsx" : "ts"
84
+ },
85
+ bundle: true,
86
+ format: "cjs",
87
+ platform: "node",
88
+ packages: "external",
89
+ write: false,
90
+ metafile: true
91
+ });
92
+ const inputs = [];
93
+ for (const input in metafile.inputs) {
94
+ if (input.startsWith("<")) continue;
95
+ const resolved = path.resolve(input);
96
+ addDependency(resolved);
97
+ inputs.push([resolved, mtime(resolved)]);
98
+ }
99
+ const module = { exports: {} };
100
+ compileFunction(outputFiles[0].text, [
101
+ "module",
102
+ "exports",
103
+ "require"
104
+ ], { filename: file })(module, module.exports, createRequire(file));
105
+ modules.set(file, {
106
+ contents,
107
+ inputs,
108
+ exports: module.exports
109
+ });
110
+ return module.exports;
111
+ }
112
+ function mtime(file) {
113
+ return statSync(file, { throwIfNoEntry: false })?.mtimeMs ?? -1;
114
+ }
115
+ /**
116
+ * The frontmatter in the code of a page, `export const frontmatter = {...}`. It runs at build time with the imports it
117
+ * reads, the statements before it in its ESM block and the params of a page as `props`, the content no longer has it.
118
+ */
119
+ function frontmatterCode(filePath, content) {
120
+ if (!filePath.endsWith(".mdx") || !/^export const frontmatter\b/m.test(content)) return;
121
+ const tree = fromMarkdown(content, {
122
+ extensions: [esm],
123
+ mdastExtensions: [mdxFromMarkdown()]
124
+ });
125
+ const range = (node) => node.range;
126
+ const imports = [];
127
+ for (const node of tree.children) if (node.type === "mdxjsEsm") {
128
+ for (const statement of node.data?.estree?.body ?? []) if (statement.type === "ImportDeclaration") imports.push([statement, content.slice(...range(statement))]);
129
+ }
130
+ for (const node of tree.children) {
131
+ if (node.type !== "mdxjsEsm" || !node.data?.estree) continue;
132
+ const frontmatter = frontmatterModule(content, node.data.estree.body, imports, range);
133
+ if (!frontmatter) continue;
134
+ const [start, end] = frontmatter.remove;
135
+ return {
136
+ content: content.slice(0, start) + content.slice(start, end).replace(/[^\n]/g, "") + content.slice(end),
137
+ /** compile it into a function of the params */
138
+ compile(addDependency) {
139
+ return runModule(filePath, frontmatter.module, addDependency).frontmatter;
140
+ }
141
+ };
142
+ }
143
+ }
144
+ /**
145
+ * The frontmatter of a page, validated: the YAML with its frontmatter in code. A dynamic file has the frontmatter in
146
+ * code of each params in `_frontmatterAt`.
147
+ *
148
+ * @param listed - whether to run the frontmatter in code of a dynamic file
149
+ */
150
+ async function resolveFrontmatter({ code, yaml, staticParams, validate, addDependency, listed = true }) {
151
+ if (!code || !staticParams) return await validate(code ? {
152
+ ...yaml,
153
+ ...code.compile(addDependency)()
154
+ } : yaml);
155
+ const frontmatterAt = {};
156
+ if (listed) {
157
+ const run = code.compile(addDependency);
158
+ for (const item of staticParams) frontmatterAt[JSON.stringify(item)] = await validate({
159
+ ...yaml,
160
+ ...run(item)
161
+ });
162
+ }
163
+ return {
164
+ ...yaml,
165
+ _frontmatterAt: frontmatterAt
166
+ };
167
+ }
168
+ export { metaModule as i, resolveFrontmatter as n, runModule as r, frontmatterCode as t };
@@ -0,0 +1,40 @@
1
+ // ../shared/code-output.ts
2
+ /**
3
+ * An element as an HTML tag, so search dialogs render it as an element: its attributes that are text or `true`, with
4
+ * values and content on one line, values truncated.
5
+ */
6
+ function toHtmlTag(name, attributes, inner) {
7
+ let open = `<${name}`;
8
+ for (const key in attributes) {
9
+ const value = attributes[key];
10
+ if (value === true) open += ` ${key}`;
11
+ if (key === "children" || typeof value !== "string" && typeof value !== "number") continue;
12
+ let text = String(value).replace(/\s+/g, " ");
13
+ if (text.length > 100) text = `${text.slice(0, 100)}…`;
14
+ open += ` ${key}="${text.replaceAll("&", "&amp;").replaceAll("\"", "&quot;")}"`;
15
+ }
16
+ const children = inner.replace(/\s+/g, " ");
17
+ return children ? `${open}>${children}</${name}>` : `${open} />`;
18
+ }
19
+ /** all of the conditions */
20
+ function and(conditions) {
21
+ if (conditions.length > 0) return `(${conditions.join(") && (")})`;
22
+ }
23
+ /**
24
+ * The code of a list output: a function of the props giving the items whose conditions hold, or the list when static.
25
+ * The list is read in document order, so an entry with `run` can count the items that show.
26
+ *
27
+ * @param declaration - the code that declares the names of the items, see {@link componentsCode}
28
+ */
29
+ function listCode(items, isStatic, declaration = "") {
30
+ let list = "[";
31
+ for (const { code, when, run } of items) {
32
+ const test = and(when);
33
+ const item = run ? `...((${code}), [])` : code;
34
+ list += test ? `...(${test} ? [${item}] : []),` : `${item},`;
35
+ }
36
+ list += "]";
37
+ if (isStatic) return list;
38
+ return declaration ? `(props) => {\n${declaration}\nreturn ${list};\n}` : `(props) => ${list}`;
39
+ }
40
+ export { toHtmlTag as n, listCode as t };
@@ -1,4 +1,4 @@
1
- import { C as DocsCollection, D as defineCollections, E as SatteriPresetOptions, F as DefaultMDXOptions, I as MDXPresetOptions, L as applyMdxPreset, O as defineConfig, P as PostprocessOptions, S as DocCollectionSatteri, T as MetaCollection, _ as BaseCollection, b as DocCollectionBase, g as AnyCollection, k as defineDocs, v as CollectionSchema, w as GlobalConfig, x as DocCollectionMdx, y as DocCollection } from "../core-DA_zPpY3.js";
1
+ import { C as DocsCollection, D as defineCollections, E as SatteriPresetOptions, F as DefaultMDXOptions, I as MDXPresetOptions, L as applyMdxPreset, O as defineConfig, P as PostprocessOptions, S as DocCollectionSatteri, T as MetaCollection, _ as BaseCollection, b as DocCollectionBase, g as AnyCollection, k as defineDocs, v as CollectionSchema, w as GlobalConfig, x as DocCollectionMdx, y as DocCollection } from "../core-CrKTFOR5.js";
2
2
  import { remarkInclude } from "fumadocs-core/mdx-plugins/remark-include";
3
3
  /** @deprecated import `pageSchema` from `fumadocs-core/source/schema` instead (since 16.2.3) */
4
4
  export declare const frontmatterSchema: import("zod").ZodObject<{
@@ -1,5 +1,5 @@
1
1
  import { n as defineConfig, r as defineDocs, t as defineCollections } from "../define-C2jwQBlt.js";
2
- import { t as applyMdxPreset } from "../preset-BLDvTSeK.js";
2
+ import { t as applyMdxPreset } from "../preset-CUfyGsn3.js";
3
3
  import { metaSchema as metaSchema$1, pageSchema } from "fumadocs-core/source/schema";
4
4
  import { remarkInclude } from "fumadocs-core/mdx-plugins/remark-include";
5
5
  // src/config/index.ts
@@ -1,14 +1,14 @@
1
- import { FC } from "react";
2
- import "fumadocs-core/source";
1
+ import { FC, ReactNode } from "react";
3
2
  import { metaSchema, pageSchema } from "fumadocs-core/source/schema";
4
3
  import { ProcessorOptions } from "@mdx-js/mdx";
5
4
  import { VFile } from "vfile";
6
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
7
6
  import { Pluggable } from "unified";
8
7
  import * as Plugins from "fumadocs-core/mdx-plugins";
9
- import { LLMsOptions, StructuredData } from "fumadocs-core/mdx-plugins";
8
+ import { LLMsOptions } from "fumadocs-core/mdx-plugins";
10
9
  import "mdast";
11
10
  import { SatteriPresetOptions, SatteriPresetOptions as SatteriPresetOptions$1 } from "@fumadocs/satteri/preset";
11
+ import { StructuredData, StructuredDataContent } from "fumadocs-core/mdx-plugins/remark-structure";
12
12
  import { TOCItemType } from "fumadocs-core/toc";
13
13
  import { MDXProps } from "mdx/types";
14
14
  import { FSWatcher } from "chokidar";
@@ -20,7 +20,6 @@ type DefaultMDXOptions = Omit<NonNullable<ProcessorOptions>, 'rehypePlugins' | '
20
20
  * Properties to export from `vfile.data`
21
21
  */
22
22
  valueToExport?: string[];
23
- remarkShowOptions?: Plugins.RemarkShowOptions;
24
23
  remarkStructureOptions?: Plugins.StructureOptions | false;
25
24
  remarkHeadingOptions?: Plugins.RemarkHeadingOptions;
26
25
  remarkImageOptions?: Plugins.RemarkImageOptions | false;
@@ -67,29 +66,37 @@ interface PostprocessOptions {
67
66
  * @returns `null`/`undefined` when unknown (e.g. the file isn't committed).
68
67
  */
69
68
  type LastModifiedFn = (filePath: string) => Promise<Date | null | undefined>;
69
+ /** a record of structured data that `remarkStructure` exports for props, a heading has an `id` */
70
+ interface StructuredRecord extends Partial<Omit<StructuredDataContent, 'content'>> {
71
+ id?: string;
72
+ content: ReactNode;
73
+ }
74
+ /** the export of `remarkStructure` for props: the records that show for the props of a page, in document order */
75
+ type StructuredRecords = (props: Record<string, unknown>) => StructuredRecord[];
76
+ /** the exports of a compiled page, its content and runtime outputs read the params of a page as props */
70
77
  interface CompiledMDXProperties<Frontmatter = Record<string, unknown>> {
71
78
  frontmatter: Frontmatter;
72
- structuredData: StructuredData;
73
- toc: TOCItemType[];
79
+ structuredData: StructuredData | StructuredRecords;
80
+ toc: TOCItemType[] | ((props: Record<string, unknown>) => TOCItemType[]);
74
81
  default: FC<MDXProps>;
82
+ extractedReferences?: ExtractedReference[] | ((props: Record<string, unknown>) => ExtractedReference[]);
75
83
  /**
76
84
  * Enable from `postprocess` option.
77
85
  *
78
- * A component with `output: 'function'` in `includeProcessedMarkdown`,
79
- * render it with `renderToMarkdown` from `fumadocs-core/server`.
86
+ * A string, or for runtime output a component, render it with `renderToMarkdown` from `fumadocs-core/server`.
80
87
  */
81
88
  _markdown?: string | FC<MDXProps>;
82
89
  /**
83
90
  * Enable from `postprocess` option.
84
91
  */
85
92
  _mdast?: string;
86
- /** for a dynamic file, the module compiled for each of its params, by the params as JSON */
87
- _pages?: Record<string, CompiledMDXProperties<Frontmatter>>;
88
93
  }
89
94
  declare module 'satteri' {
90
95
  interface DataMap {
96
+ /** the code of references, with the conditions of the branches of `<show>` around them */
91
97
  extractedReferences?: {
92
- href: string;
98
+ code: string;
99
+ when: string[];
93
100
  }[];
94
101
  }
95
102
  }
@@ -1,4 +1,4 @@
1
- import "./core-DA_zPpY3.js";
1
+ import "./core-CrKTFOR5.js";
2
2
  interface WebpackLoaderOptions {
3
3
  type: 'webpack' | 'turbopack';
4
4
  /** absolute path */
@@ -1,10 +1,12 @@
1
1
  import { n as ident, r as slash, t as createCodegen } from "./codegen-BAuFQ5Ew.js";
2
- import { t as frontmatterCode } from "./code-BF5OS485.js";
2
+ import { n as resolveFrontmatter, t as frontmatterCode } from "./code-BWwFhg-7.js";
3
+ import { n as readStaticParams } from "./meta-CmTae89C.js";
3
4
  import { frontmatter } from "fumadocs-core/content/md/frontmatter";
4
5
  import fs from "node:fs/promises";
5
6
  import path from "node:path";
6
7
  import { createHash } from "node:crypto";
7
8
  import { glob } from "tinyglobby";
9
+ import { getStaticParams } from "fumadocs-core/source";
8
10
  // src/utils/fs-cache.ts
9
11
  const map = /* @__PURE__ */ new Map();
10
12
  function createFSCache() {
@@ -167,13 +169,20 @@ async function generateDynamicIndexFile(ctx) {
167
169
  const fullPath = normalizePath(absolutePath);
168
170
  const content = await indexFileCache.read(fullPath).catch(() => "");
169
171
  const parsed = frontmatter(content);
170
- const data = await core.transformFrontmatter({
171
- collection,
172
- filePath: absolutePath,
173
- source: content
174
- }, {
175
- ...parsed.data,
176
- ...frontmatterCode(absolutePath, parsed.content)?.compile(() => void 0)()
172
+ const yaml = parsed.data;
173
+ const data = await resolveFrontmatter({
174
+ code: frontmatterCode(absolutePath, parsed.content),
175
+ yaml,
176
+ staticParams: getStaticParams(slash(path.relative(collection.dir, absolutePath)), {
177
+ staticParams: yaml.staticParams,
178
+ readStaticParams: (meta) => readStaticParams(collection.dir, meta, () => void 0)
179
+ }),
180
+ validate: (data) => core.transformFrontmatter({
181
+ collection,
182
+ filePath: absolutePath,
183
+ source: content
184
+ }, data),
185
+ addDependency: () => void 0
177
186
  });
178
187
  const hash = createHash("md5").update(content).digest("hex");
179
188
  const infoStr = [`absolutePath: path.resolve(${JSON.stringify(fullPath)})`];
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { N as ExtractedReference, a as EmitOptions, c as PluginContext, d as TransformOptions, i as EmitEntry, j as CompiledMDXProperties, l as PluginOption, n as Core, o as EmitOutput, r as CoreOptions, s as Plugin, t as CompilationContext, u as ServerContext } from "./core-DA_zPpY3.js";
1
+ import { N as ExtractedReference, a as EmitOptions, c as PluginContext, d as TransformOptions, i as EmitEntry, j as CompiledMDXProperties, l as PluginOption, n as Core, o as EmitOutput, r as CoreOptions, s as Plugin, t as CompilationContext, u as ServerContext } from "./core-CrKTFOR5.js";
2
2
  export type { CompilationContext, CompiledMDXProperties, Core, CoreOptions, EmitEntry, EmitOptions, EmitOutput, ExtractedReference, Plugin, PluginContext, PluginOption, ServerContext, TransformOptions };