fumadocs-mdx 11.6.10 → 11.7.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 (36) hide show
  1. package/dist/{chunk-64MMPGML.js → chunk-2CSSQTP6.js} +1 -10
  2. package/dist/{chunk-SXOJYWZ3.js → chunk-2KBRPMAM.js} +1 -1
  3. package/dist/{chunk-6PDS7MUA.js → chunk-C5INPAZJ.js} +4 -4
  4. package/dist/{chunk-DRVUBK5B.js → chunk-GWR7KMRU.js} +13 -1
  5. package/dist/chunk-JPPCALFT.js +34 -0
  6. package/dist/{chunk-OTM6WYMS.js → chunk-ZOWJF3OH.js} +7 -7
  7. package/dist/config/index.cjs +6 -19
  8. package/dist/config/index.d.cts +3 -7
  9. package/dist/config/index.d.ts +3 -7
  10. package/dist/config/index.js +8 -12
  11. package/dist/define-CCrinVBZ.d.cts +109 -0
  12. package/dist/define-CCrinVBZ.d.ts +109 -0
  13. package/dist/index.d.cts +6 -7
  14. package/dist/index.d.ts +6 -7
  15. package/dist/loader-mdx.cjs +156 -135
  16. package/dist/loader-mdx.js +7 -10
  17. package/dist/mdx-options-UDV5WEFU.js +6 -0
  18. package/dist/next/index.cjs +197 -54
  19. package/dist/next/index.js +7 -30
  20. package/dist/runtime/async.cjs +167 -15
  21. package/dist/runtime/async.d.cts +5 -6
  22. package/dist/runtime/async.d.ts +5 -6
  23. package/dist/runtime/async.js +26 -17
  24. package/dist/runtime/vite.cjs +116 -0
  25. package/dist/runtime/vite.d.cts +47 -0
  26. package/dist/runtime/vite.d.ts +47 -0
  27. package/dist/runtime/vite.js +90 -0
  28. package/dist/{types-Dk7DhSKZ.d.ts → types-C0bKwtAx.d.ts} +38 -50
  29. package/dist/{types-ZwLebhOl.d.cts → types-CnslxmoO.d.cts} +38 -50
  30. package/dist/vite/index.cjs +384 -137
  31. package/dist/vite/index.d.cts +12 -3
  32. package/dist/vite/index.d.ts +12 -3
  33. package/dist/vite/index.js +177 -21
  34. package/package.json +20 -10
  35. package/dist/types-DvTNxAvo.d.cts +0 -217
  36. package/dist/types-DvTNxAvo.d.ts +0 -217
@@ -1,57 +1,212 @@
1
1
  import {
2
2
  buildMDX,
3
3
  countLines
4
- } from "../chunk-6PDS7MUA.js";
4
+ } from "../chunk-C5INPAZJ.js";
5
5
  import {
6
- loadDefaultOptions
7
- } from "../chunk-64MMPGML.js";
8
- import "../chunk-AVMO2SRO.js";
6
+ toImportPath
7
+ } from "../chunk-JPPCALFT.js";
9
8
  import {
10
9
  buildConfig
11
- } from "../chunk-DRVUBK5B.js";
10
+ } from "../chunk-GWR7KMRU.js";
11
+ import {
12
+ ValidationError,
13
+ validate
14
+ } from "../chunk-ZOWJF3OH.js";
15
+ import "../chunk-AVMO2SRO.js";
12
16
  import {
13
17
  fumaMatter
14
18
  } from "../chunk-KVWX6THC.js";
15
19
 
16
20
  // src/vite/index.ts
17
21
  import { parse } from "querystring";
22
+ import { z } from "zod";
23
+ import fs from "fs/promises";
24
+ import path from "path";
25
+ import { load } from "js-yaml";
18
26
  var fileRegex = /\.(md|mdx)$/;
19
- function unstable_mdx(config, _options = {}) {
27
+ var onlySchema = z.literal(["frontmatter", "all"]);
28
+ function mdx(config, options = {}) {
29
+ const { generateIndexFile = true, configPath = "source.config.ts" } = options;
20
30
  const [err, loaded] = buildConfig(config);
21
31
  if (err || !loaded) {
22
32
  throw new Error(err);
23
33
  }
24
34
  return {
25
35
  name: "fumadocs-mdx",
26
- // TODO: need a way to generate .source folder that works for non-RSC based frameworks, currently, we need to dynamic import MDX files using `import.meta.glob`.
27
- // at the moment, RR and Tanstack Start has no stable support for RSC yet.
36
+ // needed, otherwise other plugins will be executed before our `transform`.
37
+ enforce: "pre",
38
+ async buildStart() {
39
+ if (!generateIndexFile) return;
40
+ console.log("[Fumadocs MDX] Generating index files");
41
+ const outdir = process.cwd();
42
+ const outFile = "source.generated.ts";
43
+ const lines = [
44
+ `import { fromConfig } from 'fumadocs-mdx/runtime/vite';`,
45
+ `import type * as Config from '${toImportPath(configPath, {
46
+ relativeTo: outdir
47
+ })}';`,
48
+ "",
49
+ `export const create = fromConfig<typeof Config>();`
50
+ ];
51
+ function filesToGlob(files) {
52
+ return files.map((file) => {
53
+ if (file.startsWith("./")) return file;
54
+ if (file.startsWith("/")) return `.${file}`;
55
+ return `./${file}`;
56
+ });
57
+ }
58
+ function docs(name, dir, collection) {
59
+ const docFiles = collection.docs.files ? filesToGlob(collection.docs.files) : ["./**/*.{mdx,md}"];
60
+ const metaFiles = collection.meta.files ? filesToGlob(collection.meta.files) : ["./**/*.{yaml,json}"];
61
+ return `export const ${name} = create.docs('${name}', {
62
+ doc: import.meta.glob(${JSON.stringify(docFiles)}, {
63
+ query: {
64
+ collection: '${name}',
65
+ },
66
+ base: '${dir}',
67
+ }),
68
+ meta: import.meta.glob(${JSON.stringify(metaFiles)}, {
69
+ query: {
70
+ collection: '${name}',
71
+ },
72
+ base: '${dir}',
73
+ import: 'default',
74
+ }),
75
+ });`;
76
+ }
77
+ function doc(name, dir, collection) {
78
+ const files = collection.files ? filesToGlob(collection.files) : ["./**/*.{mdx,md}"];
79
+ return `export const ${name} = create.doc(
80
+ '${name}',
81
+ import.meta.glob(${JSON.stringify(files)}, {
82
+ query: {
83
+ collection: '${name}',
84
+ },
85
+ base: '${dir}',
86
+ }),
87
+ );`;
88
+ }
89
+ function meta(name, dir, collection) {
90
+ const files = collection.files ? filesToGlob(collection.files) : ["./**/*.{yaml,json}"];
91
+ return `export const ${name} = create.meta(
92
+ '${name}',
93
+ import.meta.glob(${JSON.stringify(files)}, {
94
+ query: {
95
+ collection: '${name}',
96
+ },
97
+ base: '${dir}',
98
+ import: 'default',
99
+ }),
100
+ );`;
101
+ }
102
+ for (const [name, collection] of loaded.collections.entries()) {
103
+ let dir = collection.dir;
104
+ if (Array.isArray(dir) && dir.length === 1) {
105
+ dir = dir[0];
106
+ } else if (Array.isArray(dir)) {
107
+ throw new Error(
108
+ `[Fumadocs MDX] Vite Plugin doesn't support multiple \`dir\` for a collection at the moment.`
109
+ );
110
+ }
111
+ if (!dir.startsWith("./") && !dir.startsWith("/")) {
112
+ dir = "/" + dir;
113
+ }
114
+ lines.push("");
115
+ if (collection.type === "docs") {
116
+ lines.push(docs(name, dir, collection));
117
+ } else if (collection.type === "meta") {
118
+ lines.push(meta(name, dir, collection));
119
+ } else {
120
+ lines.push(doc(name, dir, collection));
121
+ }
122
+ }
123
+ await fs.writeFile(path.join(outdir, outFile), lines.join("\n"));
124
+ },
28
125
  async transform(value, id) {
29
- const [path, query = ""] = id.split("?");
30
- if (!fileRegex.test(path)) return;
126
+ const [path2, query = ""] = id.split("?");
127
+ const isJson = path2.endsWith(".json");
128
+ const isYaml = path2.endsWith(".yaml");
129
+ if (isJson || isYaml) {
130
+ const parsed2 = parse(query);
131
+ const collection2 = parsed2.collection ? loaded.collections.get(parsed2.collection) : void 0;
132
+ if (!collection2) return null;
133
+ let schema2;
134
+ switch (collection2.type) {
135
+ case "meta":
136
+ schema2 = collection2.schema;
137
+ break;
138
+ case "docs":
139
+ schema2 = collection2.meta.schema;
140
+ break;
141
+ }
142
+ if (!schema2) return null;
143
+ let data;
144
+ try {
145
+ data = isJson ? JSON.parse(value) : load(value);
146
+ } catch {
147
+ return null;
148
+ }
149
+ const out = await validate(
150
+ schema2,
151
+ data,
152
+ { path: path2, source: value },
153
+ `invalid data in ${path2}`
154
+ );
155
+ return {
156
+ code: isJson ? JSON.stringify(out) : `export default ${JSON.stringify(out)}`,
157
+ map: null
158
+ };
159
+ }
160
+ if (!fileRegex.test(path2)) return;
31
161
  const matter = fumaMatter(value);
32
162
  const isDevelopment = this.environment.mode === "dev";
33
- const { collection: collectionId, raw } = parse(query);
34
- const collection = collectionId ? loaded.collections.get(collectionId) : void 0;
35
- const lineOffset = "\n".repeat(
36
- isDevelopment ? countLines(matter.matter) : 0
37
- );
163
+ const parsed = parse(query);
164
+ const collection = parsed.collection ? loaded.collections.get(parsed.collection) : void 0;
165
+ const only = parsed.only ? onlySchema.parse(parsed.only) : "all";
166
+ let schema;
38
167
  let mdxOptions;
39
168
  switch (collection?.type) {
40
169
  case "doc":
41
170
  mdxOptions = collection.mdxOptions;
171
+ schema = collection.schema;
42
172
  break;
43
173
  case "docs":
44
174
  mdxOptions = collection.docs.mdxOptions;
175
+ schema = collection.docs.schema;
45
176
  break;
46
177
  }
47
- mdxOptions ??= await loadDefaultOptions(loaded);
178
+ if (schema) {
179
+ try {
180
+ matter.data = await validate(
181
+ schema,
182
+ matter.data,
183
+ {
184
+ source: value,
185
+ path: path2
186
+ },
187
+ `invalid frontmatter in ${path2}`
188
+ );
189
+ } catch (e) {
190
+ if (e instanceof ValidationError) {
191
+ throw new Error(e.toStringFormatted());
192
+ }
193
+ throw e;
194
+ }
195
+ }
196
+ if (only === "frontmatter") {
197
+ return {
198
+ code: `export const frontmatter = ${JSON.stringify(matter.data)}`
199
+ };
200
+ }
201
+ mdxOptions ??= await loaded.getDefaultMDXOptions();
202
+ const lineOffset = isDevelopment ? countLines(matter.matter) : 0;
48
203
  const file = await buildMDX(
49
- collectionId ?? "global",
50
- lineOffset + matter.content,
204
+ parsed.collection ?? "global",
205
+ "\n".repeat(lineOffset) + matter.content,
51
206
  {
52
207
  development: isDevelopment,
53
208
  ...mdxOptions,
54
- filePath: path,
209
+ filePath: path2,
55
210
  frontmatter: matter.data,
56
211
  _compiler: {
57
212
  addDependency: (file2) => {
@@ -61,11 +216,12 @@ function unstable_mdx(config, _options = {}) {
61
216
  }
62
217
  );
63
218
  return {
64
- code: typeof raw === "string" ? `export default ${JSON.stringify(file.value)}` : String(file.value)
219
+ code: String(file.value),
220
+ map: file.map
65
221
  };
66
222
  }
67
223
  };
68
224
  }
69
225
  export {
70
- unstable_mdx as default
226
+ mdx as default
71
227
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-mdx",
3
- "version": "11.6.10",
3
+ "version": "11.7.0",
4
4
  "description": "The built-in source for Fumadocs",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -32,6 +32,10 @@
32
32
  "import": "./dist/runtime/async.js",
33
33
  "types": "./dist/runtime/async.d.ts"
34
34
  },
35
+ "./runtime/vite": {
36
+ "import": "./dist/runtime/vite.js",
37
+ "types": "./dist/runtime/vite.d.ts"
38
+ },
35
39
  ".": {
36
40
  "import": "./dist/index.js",
37
41
  "types": "./dist/index.d.ts",
@@ -50,7 +54,7 @@
50
54
  "@mdx-js/mdx": "^3.1.0",
51
55
  "@standard-schema/spec": "^1.0.0",
52
56
  "chokidar": "^4.0.3",
53
- "esbuild": "^0.25.5",
57
+ "esbuild": "^0.25.8",
54
58
  "estree-util-value-to-estree": "^3.4.0",
55
59
  "js-yaml": "^4.1.0",
56
60
  "lru-cache": "^11.1.0",
@@ -58,31 +62,37 @@
58
62
  "tinyexec": "^1.0.1",
59
63
  "tinyglobby": "^0.2.14",
60
64
  "unist-util-visit": "^5.0.0",
61
- "zod": "^3.25.67"
65
+ "zod": "^4.0.5"
62
66
  },
63
67
  "devDependencies": {
64
68
  "@types/js-yaml": "^4.0.9",
65
69
  "@types/mdast": "^4.0.3",
66
70
  "@types/mdx": "^2.0.13",
71
+ "@types/node": "^24.0.15",
67
72
  "@types/react": "^19.1.8",
68
73
  "mdast-util-mdx-jsx": "^3.2.0",
69
- "next": "^15.3.4",
74
+ "next": "^15.4.2",
75
+ "react": "^19.1.0",
70
76
  "unified": "^11.0.5",
71
77
  "vfile": "^6.0.3",
72
- "vite": "^7.0.0",
73
- "webpack": "^5.99.9",
74
- "@fumadocs/mdx-remote": "1.3.4",
78
+ "vite": "^7.0.5",
79
+ "webpack": "^5.100.2",
80
+ "@fumadocs/mdx-remote": "1.4.0",
75
81
  "eslint-config-custom": "0.0.0",
76
- "fumadocs-core": "15.6.0",
82
+ "fumadocs-core": "15.6.5",
77
83
  "tsconfig": "0.0.0"
78
84
  },
79
85
  "peerDependencies": {
80
- "@fumadocs/mdx-remote": "^1.2.0",
86
+ "@fumadocs/mdx-remote": "^1.4.0",
81
87
  "fumadocs-core": "^14.0.0 || ^15.0.0",
82
88
  "next": "^15.3.0",
83
- "vite": "6.x.x"
89
+ "react": "*",
90
+ "vite": "6.x.x || 7.x.x"
84
91
  },
85
92
  "peerDependenciesMeta": {
93
+ "react": {
94
+ "optional": true
95
+ },
86
96
  "next": {
87
97
  "optional": true
88
98
  },
@@ -1,217 +0,0 @@
1
- import { MDXProps } from 'mdx/types';
2
- import * as plugins from 'fumadocs-core/mdx-plugins';
3
- import { StructuredData } from 'fumadocs-core/mdx-plugins';
4
- import { TableOfContents } from 'fumadocs-core/server';
5
- import { ProcessorOptions } from '@mdx-js/mdx';
6
- import { Pluggable } from 'unified';
7
- import { FC } from 'react';
8
- import { z } from 'zod';
9
- import { StandardSchemaV1 } from '@standard-schema/spec';
10
- import { MDXOptions as MDXOptions$1 } from '@fumadocs/mdx-remote';
11
-
12
- interface MDXOptions extends ProcessorOptions {
13
- /**
14
- * Name of collection
15
- */
16
- collection?: string;
17
- /**
18
- * Specify a file path for source
19
- */
20
- filePath?: string;
21
- frontmatter?: Record<string, unknown>;
22
- /**
23
- * Custom Vfile data
24
- */
25
- data?: Record<string, unknown>;
26
- _compiler?: CompilerOptions;
27
- }
28
- interface CompilerOptions {
29
- addDependency: (file: string) => void;
30
- }
31
- declare module 'vfile' {
32
- interface DataMap {
33
- /**
34
- * The compiler object from loader
35
- */
36
- _compiler?: CompilerOptions;
37
- }
38
- }
39
-
40
- declare const metaSchema: z.ZodObject<{
41
- title: z.ZodOptional<z.ZodString>;
42
- pages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
43
- description: z.ZodOptional<z.ZodString>;
44
- root: z.ZodOptional<z.ZodBoolean>;
45
- defaultOpen: z.ZodOptional<z.ZodBoolean>;
46
- icon: z.ZodOptional<z.ZodString>;
47
- }, "strip", z.ZodTypeAny, {
48
- root?: boolean | undefined;
49
- title?: string | undefined;
50
- pages?: string[] | undefined;
51
- description?: string | undefined;
52
- defaultOpen?: boolean | undefined;
53
- icon?: string | undefined;
54
- }, {
55
- root?: boolean | undefined;
56
- title?: string | undefined;
57
- pages?: string[] | undefined;
58
- description?: string | undefined;
59
- defaultOpen?: boolean | undefined;
60
- icon?: string | undefined;
61
- }>;
62
- declare const frontmatterSchema: z.ZodObject<{
63
- title: z.ZodString;
64
- description: z.ZodOptional<z.ZodString>;
65
- icon: z.ZodOptional<z.ZodString>;
66
- full: z.ZodOptional<z.ZodBoolean>;
67
- _openapi: z.ZodOptional<z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>;
68
- }, "strip", z.ZodTypeAny, {
69
- title: string;
70
- description?: string | undefined;
71
- icon?: string | undefined;
72
- full?: boolean | undefined;
73
- _openapi?: z.objectOutputType<{}, z.ZodTypeAny, "passthrough"> | undefined;
74
- }, {
75
- title: string;
76
- description?: string | undefined;
77
- icon?: string | undefined;
78
- full?: boolean | undefined;
79
- _openapi?: z.objectInputType<{}, z.ZodTypeAny, "passthrough"> | undefined;
80
- }>;
81
-
82
- type CollectionSchema<Schema extends StandardSchemaV1, Context> = Schema | ((ctx: Context) => Schema);
83
- interface BaseCollection {
84
- /**
85
- * Directories to scan
86
- */
87
- dir: string | string[];
88
- /**
89
- * what files to include/exclude (glob patterns)
90
- *
91
- * Include all files if not specified
92
- */
93
- files?: string[];
94
- }
95
- interface MetaCollection<Schema extends StandardSchemaV1 = StandardSchemaV1> extends BaseCollection {
96
- type: 'meta';
97
- schema?: CollectionSchema<Schema, {
98
- path: string;
99
- source: string;
100
- }>;
101
- }
102
- interface DocCollection<Schema extends StandardSchemaV1 = StandardSchemaV1, Async extends boolean = boolean> extends BaseCollection {
103
- type: 'doc';
104
- mdxOptions?: MDXOptions;
105
- /**
106
- * Load files with async
107
- */
108
- async?: Async;
109
- schema?: CollectionSchema<Schema, {
110
- path: string;
111
- source: string;
112
- }>;
113
- }
114
- interface DocsCollection<DocSchema extends StandardSchemaV1 = StandardSchemaV1, MetaSchema extends StandardSchemaV1 = StandardSchemaV1, Async extends boolean = boolean> {
115
- type: 'docs';
116
- dir: string | string[];
117
- docs: DocCollection<DocSchema, Async>;
118
- meta: MetaCollection<MetaSchema>;
119
- }
120
- declare function defineCollections<T extends 'doc' | 'meta', Schema extends StandardSchemaV1 = StandardSchemaV1<unknown, any>, Async extends boolean = false>(options: {
121
- type: T;
122
- } & (T extends 'doc' ? DocCollection<Schema, Async> : MetaCollection<Schema>)): {
123
- type: T;
124
- _type: {
125
- async: Async;
126
- schema: Schema;
127
- };
128
- };
129
- declare function defineDocs<DocSchema extends StandardSchemaV1 = typeof frontmatterSchema, MetaSchema extends StandardSchemaV1 = typeof metaSchema, Async extends boolean = false>(options?: {
130
- /**
131
- * The directory to scan files
132
- *
133
- * @defaultValue 'content/docs'
134
- */
135
- dir?: string | string[];
136
- docs?: Omit<DocCollection<DocSchema, Async>, 'dir' | 'type'>;
137
- meta?: Omit<MetaCollection<MetaSchema>, 'dir' | 'type'>;
138
- }): {
139
- type: 'docs';
140
- docs: {
141
- type: 'doc';
142
- _type: {
143
- schema: DocSchema;
144
- async: Async;
145
- };
146
- };
147
- meta: {
148
- type: 'meta';
149
- _type: {
150
- schema: MetaSchema;
151
- async: false;
152
- };
153
- };
154
- };
155
- declare function defineConfig(config?: GlobalConfig): GlobalConfig;
156
-
157
- interface LoadedConfig {
158
- collections: Map<string, DocCollection | MetaCollection | DocsCollection>;
159
- global?: GlobalConfig;
160
- _mdx_loader?: {
161
- cachedOptions?: ProcessorOptions;
162
- };
163
- _mdx_async?: {
164
- cachedMdxOptions?: MDXOptions$1;
165
- };
166
- }
167
-
168
- type ResolvePlugins = Pluggable[] | ((v: Pluggable[]) => Pluggable[]);
169
- type DefaultMDXOptions = Omit<NonNullable<ProcessorOptions>, 'rehypePlugins' | 'remarkPlugins' | '_ctx'> & {
170
- rehypePlugins?: ResolvePlugins;
171
- remarkPlugins?: ResolvePlugins;
172
- /**
173
- * Properties to export from `vfile.data`
174
- */
175
- valueToExport?: string[];
176
- remarkStructureOptions?: plugins.StructureOptions | false;
177
- remarkHeadingOptions?: plugins.RemarkHeadingOptions;
178
- remarkImageOptions?: plugins.RemarkImageOptions | false;
179
- remarkCodeTabOptions?: plugins.RemarkCodeTabOptions | false;
180
- remarkNpmOptions?: plugins.RemarkNpmOptions | false;
181
- rehypeCodeOptions?: plugins.RehypeCodeOptions | false;
182
- };
183
- declare function loadDefaultOptions(config: LoadedConfig): Promise<ProcessorOptions>;
184
-
185
- interface GlobalConfig {
186
- /**
187
- * Configure global MDX options
188
- */
189
- mdxOptions?: DefaultMDXOptions | (() => DefaultMDXOptions | Promise<DefaultMDXOptions>);
190
- /**
191
- * Fetch last modified time with specified version control
192
- * @defaultValue 'none'
193
- */
194
- lastModifiedTime?: 'git' | 'none';
195
- }
196
- interface FileInfo {
197
- path: string;
198
- absolutePath: string;
199
- }
200
- interface MarkdownProps {
201
- body: FC<MDXProps>;
202
- structuredData: StructuredData;
203
- toc: TableOfContents;
204
- _exports: Record<string, unknown>;
205
- /**
206
- * Only available when `lastModifiedTime` is enabled on MDX loader
207
- */
208
- lastModified?: Date;
209
- }
210
- interface BaseCollectionEntry {
211
- /**
212
- * Raw file path of collection entry, including absolute path (not normalized).
213
- */
214
- _file: FileInfo;
215
- }
216
-
217
- export { type BaseCollectionEntry as B, type CollectionSchema as C, type DefaultMDXOptions as D, type FileInfo as F, type GlobalConfig as G, type LoadedConfig as L, type MarkdownProps as M, type BaseCollection as a, type MetaCollection as b, type DocCollection as c, type DocsCollection as d, defineCollections as e, frontmatterSchema as f, defineDocs as g, defineConfig as h, loadDefaultOptions as l, metaSchema as m };