fumadocs-mdx 13.0.2 → 13.0.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.
Files changed (67) hide show
  1. package/dist/bin.cjs +381 -279
  2. package/dist/{build-mdx-D-r3_eQL.d.cts → build-mdx-BjXOmv0b.d.cts} +1 -1
  3. package/dist/{build-mdx-CCNr86q6.d.ts → build-mdx-CY5UldCO.d.ts} +1 -1
  4. package/dist/bun/index.cjs +177 -57
  5. package/dist/bun/index.d.cts +2 -2
  6. package/dist/bun/index.d.ts +2 -2
  7. package/dist/bun/index.js +26 -34
  8. package/dist/chunk-2HXTGJBI.js +101 -0
  9. package/dist/chunk-4JSFLXXT.js +8 -0
  10. package/dist/{chunk-JVZFH6ND.js → chunk-QXHN25N3.js} +2 -2
  11. package/dist/{chunk-EELYB2XC.js → chunk-TZ5EQBFW.js} +9 -103
  12. package/dist/chunk-VUEZTR2H.js +26 -0
  13. package/dist/{chunk-XQ5O7IPO.js → chunk-XYGORKQA.js} +5 -3
  14. package/dist/chunk-YAIPHUCZ.js +56 -0
  15. package/dist/chunk-ZNVPB2IR.js +170 -0
  16. package/dist/config/index.d.cts +2 -2
  17. package/dist/config/index.d.ts +2 -2
  18. package/dist/{core-B6j6Fxse.d.cts → core-DB7TdlyC.d.cts} +23 -7
  19. package/dist/{core-B6j6Fxse.d.ts → core-DB7TdlyC.d.ts} +23 -7
  20. package/dist/index-D7s7kCc2.d.cts +7 -0
  21. package/dist/index-D7s7kCc2.d.ts +7 -0
  22. package/dist/index.d.cts +4 -4
  23. package/dist/index.d.ts +4 -4
  24. package/dist/load-from-file-AVYOFOI7.js +7 -0
  25. package/dist/next/index.cjs +147 -142
  26. package/dist/next/index.js +58 -39
  27. package/dist/node/loader.cjs +242 -128
  28. package/dist/node/loader.d.cts +2 -2
  29. package/dist/node/loader.d.ts +2 -2
  30. package/dist/node/loader.js +29 -16
  31. package/dist/plugins/json-schema.cjs +22 -70
  32. package/dist/plugins/json-schema.d.cts +2 -2
  33. package/dist/plugins/json-schema.d.ts +2 -2
  34. package/dist/plugins/json-schema.js +19 -14
  35. package/dist/runtime/next/async.cjs +56 -11
  36. package/dist/runtime/next/async.d.cts +4 -6
  37. package/dist/runtime/next/async.d.ts +4 -6
  38. package/dist/runtime/next/async.js +3 -6
  39. package/dist/runtime/next/index.d.cts +5 -5
  40. package/dist/runtime/next/index.d.ts +5 -5
  41. package/dist/runtime/vite/browser.d.cts +3 -3
  42. package/dist/runtime/vite/browser.d.ts +3 -3
  43. package/dist/runtime/vite/server.d.cts +3 -3
  44. package/dist/runtime/vite/server.d.ts +3 -3
  45. package/dist/{types-DKGMoay5.d.cts → types-Bnh9n7mj.d.cts} +2 -2
  46. package/dist/{types-AGzTfBmf.d.ts → types-ey1AZqrg.d.ts} +2 -2
  47. package/dist/vite/index.cjs +265 -163
  48. package/dist/vite/index.d.cts +4 -0
  49. package/dist/vite/index.d.ts +4 -0
  50. package/dist/vite/index.js +140 -122
  51. package/dist/webpack/{index.cjs → mdx.cjs} +126 -104
  52. package/dist/webpack/mdx.d.cts +6 -0
  53. package/dist/webpack/mdx.d.ts +6 -0
  54. package/dist/webpack/{index.js → mdx.js} +12 -14
  55. package/dist/webpack/meta.cjs +528 -0
  56. package/dist/webpack/meta.d.cts +6 -0
  57. package/dist/webpack/meta.d.ts +6 -0
  58. package/dist/webpack/meta.js +42 -0
  59. package/loader-mdx.cjs +1 -1
  60. package/loader-meta.cjs +7 -0
  61. package/package.json +11 -8
  62. package/dist/chunk-U4MQ44TS.js +0 -53
  63. package/dist/chunk-XZY2AWJI.js +0 -81
  64. package/dist/chunk-YVCR6FUH.js +0 -82
  65. package/dist/load-MNG3CLET.js +0 -7
  66. package/dist/webpack/index.d.cts +0 -15
  67. package/dist/webpack/index.d.ts +0 -15
@@ -118,35 +118,78 @@ var init_preset = __esm({
118
118
  });
119
119
 
120
120
  // src/config/build.ts
121
+ function buildCollection(name, config) {
122
+ if (config.type === "docs") {
123
+ return {
124
+ ...config,
125
+ name,
126
+ meta: buildPrimitiveCollection(name, config.meta),
127
+ docs: buildPrimitiveCollection(name, config.docs)
128
+ };
129
+ }
130
+ return buildPrimitiveCollection(name, config);
131
+ }
132
+ function buildPrimitiveCollection(name, { files, ...config }) {
133
+ const supportedFormats = SupportedFormats[config.type];
134
+ const patterns = files ?? [`**/*.{${supportedFormats.join(",")}}`];
135
+ let matchers;
136
+ return {
137
+ ...config,
138
+ name,
139
+ patterns,
140
+ isFileSupported(filePath) {
141
+ return supportedFormats.some((format) => filePath.endsWith(`.${format}`));
142
+ },
143
+ hasFile(filePath) {
144
+ matchers ??= (Array.isArray(config.dir) ? config.dir : [config.dir]).map(
145
+ (dir) => (0, import_picomatch.default)(patterns, {
146
+ cwd: dir
147
+ })
148
+ );
149
+ return this.isFileSupported(filePath) && matchers.some((matcher) => matcher(filePath));
150
+ }
151
+ };
152
+ }
121
153
  function buildConfig(config) {
122
154
  const collections = /* @__PURE__ */ new Map();
123
- let globalConfig = {};
155
+ const loaded = {};
124
156
  for (const [k, v] of Object.entries(config)) {
125
157
  if (!v) {
126
158
  continue;
127
159
  }
128
160
  if (typeof v === "object" && "type" in v) {
129
161
  if (v.type === "docs") {
130
- collections.set(k, v);
162
+ collections.set(k, buildCollection(k, v));
131
163
  continue;
132
164
  }
133
165
  if (v.type === "doc" || v.type === "meta") {
134
- collections.set(k, v);
166
+ collections.set(
167
+ k,
168
+ buildCollection(k, v)
169
+ );
135
170
  continue;
136
171
  }
137
172
  }
138
173
  if (k === "default" && v) {
139
- globalConfig = v;
174
+ Object.assign(loaded, v);
140
175
  continue;
141
176
  }
142
177
  throw new Error(
143
178
  `Unknown export "${k}", you can only export collections from source configuration file.`
144
179
  );
145
180
  }
181
+ if (loaded.collections) {
182
+ for (const [k, v] of Object.entries(loaded.collections)) {
183
+ collections.set(k, buildCollection(k, v));
184
+ }
185
+ }
146
186
  const mdxOptionsCache = /* @__PURE__ */ new Map();
147
187
  return {
148
- global: globalConfig,
149
- collections,
188
+ global: loaded,
189
+ collectionList: Array.from(collections.values()),
190
+ getCollection(name) {
191
+ return collections.get(name);
192
+ },
150
193
  async getDefaultMDXOptions(mode = "default") {
151
194
  const cached = mdxOptionsCache.get(mode);
152
195
  if (cached) return cached;
@@ -166,15 +209,21 @@ function buildConfig(config) {
166
209
  }
167
210
  };
168
211
  }
212
+ var import_picomatch, SupportedFormats;
169
213
  var init_build = __esm({
170
214
  "src/config/build.ts"() {
171
215
  "use strict";
216
+ import_picomatch = __toESM(require("picomatch"), 1);
217
+ SupportedFormats = {
218
+ doc: ["mdx", "md"],
219
+ meta: ["json", "yaml"]
220
+ };
172
221
  }
173
222
  });
174
223
 
175
- // src/loaders/config/load.ts
176
- var load_exports = {};
177
- __export(load_exports, {
224
+ // src/config/load-from-file.ts
225
+ var load_from_file_exports = {};
226
+ __export(load_from_file_exports, {
178
227
  loadConfig: () => loadConfig
179
228
  });
180
229
  async function compileConfig(configPath, outDir) {
@@ -199,18 +248,18 @@ async function compileConfig(configPath, outDir) {
199
248
  }
200
249
  async function loadConfig(configPath, outDir, build = false) {
201
250
  if (build) await compileConfig(configPath, outDir);
202
- const url = (0, import_node_url3.pathToFileURL)(path11.resolve(outDir, "source.config.mjs"));
251
+ const url = (0, import_node_url3.pathToFileURL)(path9.resolve(outDir, "source.config.mjs"));
203
252
  url.searchParams.set("hash", Date.now().toString());
204
253
  const config = import(url.href).then(
205
254
  (loaded) => buildConfig(loaded)
206
255
  );
207
256
  return await config;
208
257
  }
209
- var path11, import_node_url3;
210
- var init_load = __esm({
211
- "src/loaders/config/load.ts"() {
258
+ var path9, import_node_url3;
259
+ var init_load_from_file = __esm({
260
+ "src/config/load-from-file.ts"() {
212
261
  "use strict";
213
- path11 = __toESM(require("path"), 1);
262
+ path9 = __toESM(require("path"), 1);
214
263
  import_node_url3 = require("url");
215
264
  init_build();
216
265
  }
@@ -225,7 +274,6 @@ __export(vite_exports, {
225
274
  module.exports = __toCommonJS(vite_exports);
226
275
  var import_vite = require("vite");
227
276
  init_build();
228
- var import_node_querystring2 = require("querystring");
229
277
 
230
278
  // src/utils/validation.ts
231
279
  var import_picocolors = __toESM(require("picocolors"), 1);
@@ -265,10 +313,6 @@ async function validate(schema, data, context, errorMessage) {
265
313
  return data;
266
314
  }
267
315
 
268
- // src/vite/index.ts
269
- var path12 = __toESM(require("path"), 1);
270
- var import_js_yaml2 = require("js-yaml");
271
-
272
316
  // src/utils/fuma-matter.ts
273
317
  var import_js_yaml = require("js-yaml");
274
318
  var regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
@@ -703,7 +747,7 @@ function createMdxLoader(configLoader) {
703
747
  );
704
748
  };
705
749
  }
706
- const collection = parsed.collection ? config.collections.get(parsed.collection) : void 0;
750
+ const collection = parsed.collection ? config.getCollection(parsed.collection) : void 0;
707
751
  let docCollection;
708
752
  switch (collection?.type) {
709
753
  case "doc":
@@ -775,18 +819,11 @@ function countLines(s) {
775
819
  return num;
776
820
  }
777
821
 
778
- // src/loaders/config/index.ts
779
- var import_node_path3 = __toESM(require("path"), 1);
780
- var import_promises2 = __toESM(require("fs/promises"), 1);
781
- function findConfigFile() {
782
- return import_node_path3.default.resolve("source.config.ts");
783
- }
784
-
785
822
  // src/loaders/adapter.ts
786
823
  var import_node_url = require("url");
787
- var import_promises3 = __toESM(require("fs/promises"), 1);
824
+ var import_promises2 = __toESM(require("fs/promises"), 1);
788
825
  var import_node_querystring = require("querystring");
789
- var import_node_path4 = __toESM(require("path"), 1);
826
+ var import_node_path3 = __toESM(require("path"), 1);
790
827
  function toVite(loader) {
791
828
  return async function(file, query, value) {
792
829
  const result = await loader({
@@ -800,6 +837,7 @@ function toVite(loader) {
800
837
  }
801
838
  }
802
839
  });
840
+ if (result === null) return null;
803
841
  return {
804
842
  code: result.code,
805
843
  map: result.map
@@ -808,9 +846,9 @@ function toVite(loader) {
808
846
  }
809
847
 
810
848
  // src/utils/import-formatter.ts
811
- var import_node_path5 = __toESM(require("path"), 1);
849
+ var import_node_path4 = __toESM(require("path"), 1);
812
850
  function toImportPath(file, config) {
813
- const ext = import_node_path5.default.extname(file);
851
+ const ext = import_node_path4.default.extname(file);
814
852
  let filename;
815
853
  if (ext === ".ts" && config.jsExtension) {
816
854
  filename = file.substring(0, file.length - ext.length) + ".js";
@@ -821,43 +859,30 @@ function toImportPath(file, config) {
821
859
  }
822
860
  let importPath;
823
861
  if ("relativeTo" in config) {
824
- importPath = import_node_path5.default.relative(config.relativeTo, filename);
825
- if (!import_node_path5.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
862
+ importPath = import_node_path4.default.relative(config.relativeTo, filename);
863
+ if (!import_node_path4.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
826
864
  importPath = `./${importPath}`;
827
865
  }
828
866
  } else {
829
- importPath = import_node_path5.default.resolve(filename);
867
+ importPath = import_node_path4.default.resolve(filename);
830
868
  }
831
- return importPath.replaceAll(import_node_path5.default.sep, "/");
869
+ return importPath.replaceAll(import_node_path4.default.sep, "/");
832
870
  }
833
871
  function ident(code, tab = 1) {
834
872
  return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
835
873
  }
836
874
 
837
- // src/utils/collections.ts
838
- var import_picomatch = __toESM(require("picomatch"), 1);
839
- var import_tinyglobby = require("tinyglobby");
840
- var import_node_path6 = __toESM(require("path"), 1);
841
- var SupportedFormats = {
842
- doc: ["mdx", "md"],
843
- meta: ["json", "yaml"]
844
- };
845
- function getGlobPatterns(collection) {
846
- if (collection.files) return collection.files;
847
- return [`**/*.{${SupportedFormats[collection.type].join(",")}}`];
848
- }
849
-
850
875
  // src/utils/glob-import.ts
851
- var import_tinyglobby2 = require("tinyglobby");
852
- var import_node_path7 = __toESM(require("path"), 1);
876
+ var import_tinyglobby = require("tinyglobby");
877
+ var import_node_path5 = __toESM(require("path"), 1);
853
878
  var import_node_url2 = require("url");
854
879
  function generateGlobImport(patterns, options) {
855
880
  let code = "{";
856
- const result = (0, import_tinyglobby2.globSync)(patterns, {
881
+ const result = (0, import_tinyglobby.globSync)(patterns, {
857
882
  cwd: options.base
858
883
  });
859
884
  for (const item of result) {
860
- const fullPath = import_node_path7.default.join(options.base, item);
885
+ const fullPath = import_node_path5.default.join(options.base, item);
861
886
  const url = (0, import_node_url2.pathToFileURL)(fullPath);
862
887
  for (const [k, v] of Object.entries(options.query ?? {})) {
863
888
  url.searchParams.set(k, v);
@@ -873,28 +898,74 @@ function generateGlobImport(patterns, options) {
873
898
  }
874
899
 
875
900
  // src/plugins/vite.ts
876
- var import_node_path8 = __toESM(require("path"), 1);
877
- function vite(options) {
901
+ var import_node_path6 = __toESM(require("path"), 1);
902
+ function vite({
903
+ index
904
+ }) {
878
905
  let config;
906
+ let indexOptions;
907
+ if (index === false) indexOptions = false;
908
+ else indexOptions = applyDefaults(index === true ? {} : index);
879
909
  return {
910
+ name: "vite",
880
911
  config(v) {
881
912
  config = v;
882
913
  },
883
- emit() {
884
- return [
885
- {
886
- path: "index.ts",
887
- content: indexFile(this.configPath, this.outDir, config, options)
914
+ configureServer(server) {
915
+ if (!server.watcher || indexOptions === false || indexOptions.runtime === false)
916
+ return;
917
+ server.watcher.on("all", (event, file) => {
918
+ if (event === "change") return;
919
+ const isUpdated = config.collectionList.some((collection) => {
920
+ if (collection.type === "docs")
921
+ return collection.docs.hasFile(file) || collection.meta.hasFile(file);
922
+ return collection.hasFile(file);
923
+ });
924
+ if (isUpdated) {
925
+ this.core.emitAndWrite({
926
+ filterPlugin: (plugin) => plugin.name === "vite"
927
+ });
888
928
  }
889
- ];
929
+ });
930
+ },
931
+ emit() {
932
+ const out = [];
933
+ if (indexOptions === false) return out;
934
+ if (indexOptions.browser) {
935
+ out.push({
936
+ path: "browser.ts",
937
+ content: indexFile(this, config, indexOptions, "browser")
938
+ });
939
+ }
940
+ out.push({
941
+ path: "index.ts",
942
+ content: indexFile(
943
+ this,
944
+ config,
945
+ indexOptions,
946
+ indexOptions.browser ? "server" : "all"
947
+ )
948
+ });
949
+ return out;
890
950
  }
891
951
  };
892
952
  }
893
- function indexFile(configPath, outDir, config, options) {
894
- const { addJsExtension = false, runtime } = options;
953
+ function applyDefaults(options) {
954
+ return {
955
+ addJsExtension: options.addJsExtension ?? false,
956
+ browser: options.browser ?? false,
957
+ runtime: options.runtime ?? false
958
+ };
959
+ }
960
+ function indexFile({ configPath, outDir }, config, { addJsExtension, runtime }, environment) {
961
+ const runtimePath = {
962
+ all: "fumadocs-mdx/runtime/vite",
963
+ server: "fumadocs-mdx/runtime/vite.server",
964
+ browser: "fumadocs-mdx/runtime/vite.browser"
965
+ }[environment];
895
966
  const lines = [
896
967
  '/// <reference types="vite/client" />',
897
- `import { fromConfig } from 'fumadocs-mdx/runtime/vite';`,
968
+ `import { fromConfig } from '${runtimePath}';`,
898
969
  `import type * as Config from '${toImportPath(configPath, {
899
970
  relativeTo: outDir,
900
971
  jsExtension: addJsExtension
@@ -902,74 +973,68 @@ function indexFile(configPath, outDir, config, options) {
902
973
  "",
903
974
  `export const create = fromConfig<typeof Config>();`
904
975
  ];
905
- function docs(name, collection) {
906
- const obj = [
907
- ident(`doc: ${doc(name, collection.docs)}`),
908
- ident(`meta: ${meta(name, collection.meta)}`)
909
- ].join(",\n");
910
- return `{
976
+ function generateCollectionGlob(collection) {
977
+ if (collection.type === "docs") {
978
+ const obj = [
979
+ ident(`doc: ${generateCollectionGlob(collection.docs)}`),
980
+ ident(`meta: ${generateCollectionGlob(collection.meta)}`)
981
+ ].join(",\n");
982
+ return `{
911
983
  ${obj}
912
984
  }`;
913
- }
914
- function doc(name, collection) {
915
- const patterns = getGlobPatterns(collection);
985
+ }
916
986
  const dir = getCollectionDir(collection);
917
- const docGlob = generateGlob(patterns, {
918
- query: {
919
- collection: name
920
- },
921
- base: dir
922
- });
923
- if (collection.async) {
924
- const headBlob = generateGlob(patterns, {
987
+ if (collection.type === "doc") {
988
+ const docGlob = generateGlob(collection.patterns, {
925
989
  query: {
926
- only: "frontmatter",
927
- collection: name
990
+ collection: collection.name
928
991
  },
929
- import: "frontmatter",
930
992
  base: dir
931
993
  });
932
- return `create.docLazy("${name}", "${dir}", ${headBlob}, ${docGlob})`;
994
+ if (collection.async) {
995
+ const headBlob = generateGlob(collection.patterns, {
996
+ query: {
997
+ only: "frontmatter",
998
+ collection: collection.name
999
+ },
1000
+ import: "frontmatter",
1001
+ base: dir
1002
+ });
1003
+ return `create.docLazy("${collection.name}", "${dir}", ${headBlob}, ${docGlob})`;
1004
+ }
1005
+ return `create.doc("${collection.name}", "${dir}", ${docGlob})`;
933
1006
  }
934
- return `create.doc("${name}", "${dir}", ${docGlob})`;
935
- }
936
- function meta(name, collection) {
937
- const patterns = getGlobPatterns(collection);
938
- const dir = getCollectionDir(collection);
939
- return `create.meta("${name}", "${dir}", ${generateGlob(patterns, {
940
- import: "default",
941
- base: dir,
942
- query: {
943
- collection: name
1007
+ return `create.meta("${collection.name}", "${dir}", ${generateGlob(
1008
+ collection.patterns,
1009
+ {
1010
+ import: "default",
1011
+ base: dir,
1012
+ query: {
1013
+ collection: collection.name
1014
+ }
944
1015
  }
945
- })})`;
1016
+ )})`;
946
1017
  }
947
- function generateGlob(patterns, options2) {
1018
+ function generateGlob(patterns, options) {
948
1019
  patterns = patterns.map(normalizeGlobPath);
949
1020
  if (runtime === "node" || runtime === "bun") {
950
- return generateGlobImport(patterns, options2);
1021
+ return generateGlobImport(patterns, options);
951
1022
  } else {
952
1023
  return `import.meta.glob(${JSON.stringify(patterns)}, ${JSON.stringify(
953
1024
  {
954
- ...options2,
955
- base: normalizeGlobPath(import_node_path8.default.relative(outDir, options2.base))
1025
+ ...options,
1026
+ base: normalizeGlobPath(import_node_path6.default.relative(outDir, options.base))
956
1027
  },
957
1028
  null,
958
1029
  2
959
1030
  )})`;
960
1031
  }
961
1032
  }
962
- for (const [name, collection] of config.collections.entries()) {
963
- let body;
964
- if (collection.type === "docs") {
965
- body = docs(name, collection);
966
- } else if (collection.type === "meta") {
967
- body = meta(name, collection);
968
- } else {
969
- body = doc(name, collection);
970
- }
1033
+ for (const collection of config.collectionList) {
971
1034
  lines.push("");
972
- lines.push(`export const ${name} = ${body};`);
1035
+ lines.push(
1036
+ `export const ${collection.name} = ${generateCollectionGlob(collection)};`
1037
+ );
973
1038
  }
974
1039
  return lines.join("\n");
975
1040
  }
@@ -979,8 +1044,7 @@ function normalizeGlobPath(file) {
979
1044
  if (file.startsWith("/")) return `.${file}`;
980
1045
  return `./${file}`;
981
1046
  }
982
- function getCollectionDir(collection) {
983
- const dir = collection.dir;
1047
+ function getCollectionDir({ dir }) {
984
1048
  if (Array.isArray(dir)) {
985
1049
  if (dir.length !== 1)
986
1050
  throw new Error(
@@ -990,17 +1054,20 @@ function getCollectionDir(collection) {
990
1054
  }
991
1055
  return dir;
992
1056
  }
993
- function slash(path13) {
994
- const isExtendedLengthPath = path13.startsWith("\\\\?\\");
1057
+ function slash(path10) {
1058
+ const isExtendedLengthPath = path10.startsWith("\\\\?\\");
995
1059
  if (isExtendedLengthPath) {
996
- return path13;
1060
+ return path10;
997
1061
  }
998
- return path13.replaceAll("\\", "/");
1062
+ return path10.replaceAll("\\", "/");
999
1063
  }
1000
1064
 
1001
1065
  // src/core.ts
1002
- var import_node_path9 = __toESM(require("path"), 1);
1003
- var import_promises4 = __toESM(require("fs/promises"), 1);
1066
+ var import_node_path7 = __toESM(require("path"), 1);
1067
+ var import_promises3 = __toESM(require("fs/promises"), 1);
1068
+ function findConfigFile() {
1069
+ return import_node_path7.default.resolve("source.config.ts");
1070
+ }
1004
1071
  function createCore(options, defaultPlugins = []) {
1005
1072
  let config;
1006
1073
  let plugins2;
@@ -1037,13 +1104,6 @@ function createCore(options, defaultPlugins = []) {
1037
1104
  getConfig() {
1038
1105
  return config;
1039
1106
  },
1040
- creatConfigLoader() {
1041
- return {
1042
- getConfig() {
1043
- return config;
1044
- }
1045
- };
1046
- },
1047
1107
  async initServer(server) {
1048
1108
  for (const plugin of plugins2) {
1049
1109
  await plugin.configureServer?.call(this.getPluginContext(), server);
@@ -1061,9 +1121,9 @@ function createCore(options, defaultPlugins = []) {
1061
1121
  );
1062
1122
  await Promise.all(
1063
1123
  out.flat().map(async (entry) => {
1064
- const file = import_node_path9.default.join(options.outDir, entry.path);
1065
- await import_promises4.default.mkdir(import_node_path9.default.dirname(file), { recursive: true });
1066
- await import_promises4.default.writeFile(file, entry.content);
1124
+ const file = import_node_path7.default.join(options.outDir, entry.path);
1125
+ await import_promises3.default.mkdir(import_node_path7.default.dirname(file), { recursive: true });
1126
+ await import_promises3.default.writeFile(file, entry.content);
1067
1127
  })
1068
1128
  );
1069
1129
  console.log(`[MDX] generated files in ${performance.now() - start}ms`);
@@ -1071,21 +1131,37 @@ function createCore(options, defaultPlugins = []) {
1071
1131
  };
1072
1132
  }
1073
1133
 
1074
- // src/vite/index.ts
1075
- var FumadocsDeps = ["fumadocs-core", "fumadocs-ui", "fumadocs-openapi"];
1076
- async function mdx(config, pluginOptions = {}) {
1077
- const options = applyDefaults(pluginOptions);
1078
- const core = await createViteCore(options).init({
1079
- config: buildConfig(config)
1080
- });
1081
- const mdxLoader = toVite(createMdxLoader(core.creatConfigLoader()));
1082
- async function transformMeta(path13, query, value) {
1083
- const isJson = path13.endsWith(".json");
1084
- const parsed = (0, import_node_querystring2.parse)(query);
1085
- const collection = parsed.collection ? core.getConfig().collections.get(parsed.collection) : void 0;
1134
+ // src/loaders/config.ts
1135
+ var import_promises4 = __toESM(require("fs/promises"), 1);
1136
+ function createIntegratedConfigLoader(core) {
1137
+ return {
1138
+ getConfig() {
1139
+ return core.getConfig();
1140
+ }
1141
+ };
1142
+ }
1143
+
1144
+ // src/loaders/meta.ts
1145
+ var import_js_yaml2 = require("js-yaml");
1146
+ var import_zod2 = require("zod");
1147
+ var querySchema2 = import_zod2.z.object({
1148
+ collection: import_zod2.z.string().optional()
1149
+ }).loose();
1150
+ function createMetaLoader(configLoader, resolve3 = {}) {
1151
+ const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve3;
1152
+ return async ({ filePath, query, source }) => {
1153
+ const isJson = filePath.endsWith(".json");
1154
+ const parsed = querySchema2.parse(query);
1155
+ const collection = parsed.collection ? (await configLoader.getConfig()).getCollection(parsed.collection) : void 0;
1086
1156
  if (!collection) return null;
1157
+ let data;
1158
+ try {
1159
+ data = isJson ? JSON.parse(source) : (0, import_js_yaml2.load)(source);
1160
+ } catch (e) {
1161
+ throw new Error(`invalid data in ${filePath}`, { cause: e });
1162
+ }
1087
1163
  let schema;
1088
- switch (collection.type) {
1164
+ switch (collection?.type) {
1089
1165
  case "meta":
1090
1166
  schema = collection.schema;
1091
1167
  break;
@@ -1093,24 +1169,46 @@ async function mdx(config, pluginOptions = {}) {
1093
1169
  schema = collection.meta.schema;
1094
1170
  break;
1095
1171
  }
1096
- if (!schema) return null;
1097
- let data;
1098
- try {
1099
- data = isJson ? JSON.parse(value) : (0, import_js_yaml2.load)(value);
1100
- } catch {
1101
- return null;
1172
+ if (schema) {
1173
+ data = await validate(
1174
+ schema,
1175
+ data,
1176
+ { path: filePath, source },
1177
+ `invalid data in ${filePath}`
1178
+ );
1179
+ }
1180
+ let code;
1181
+ if (isJson) {
1182
+ code = resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}`;
1183
+ } else {
1184
+ code = resolveYaml === "yaml" ? (0, import_js_yaml2.dump)(data) : `export default ${JSON.stringify(data)}`;
1102
1185
  }
1103
- const out = await validate(
1104
- schema,
1105
- data,
1106
- { path: path13, source: value },
1107
- `invalid data in ${path13}`
1108
- );
1109
1186
  return {
1110
- code: isJson ? JSON.stringify(out) : `export default ${JSON.stringify(out)}`,
1187
+ code,
1111
1188
  map: null
1112
1189
  };
1113
- }
1190
+ };
1191
+ }
1192
+
1193
+ // src/loaders/index.ts
1194
+ var metaLoaderGlob = /\.(json|yaml)(\?.+?)?$/;
1195
+ var mdxLoaderGlob = /\.mdx?(\?.+?)?$/;
1196
+
1197
+ // src/vite/index.ts
1198
+ var FumadocsDeps = ["fumadocs-core", "fumadocs-ui", "fumadocs-openapi"];
1199
+ async function mdx(config, pluginOptions = {}) {
1200
+ const options = applyDefaults2(pluginOptions);
1201
+ const core = await createViteCore(options).init({
1202
+ config: buildConfig(config)
1203
+ });
1204
+ const configLoader = createIntegratedConfigLoader(core);
1205
+ const mdxLoader = toVite(createMdxLoader(configLoader));
1206
+ const metaLoader = toVite(
1207
+ createMetaLoader(configLoader, {
1208
+ // vite has built-in plugin for JSON files
1209
+ json: "json"
1210
+ })
1211
+ );
1114
1212
  return {
1115
1213
  name: "fumadocs-mdx",
1116
1214
  // needed, otherwise other plugins will be executed before our `transform`.
@@ -1136,13 +1234,15 @@ async function mdx(config, pluginOptions = {}) {
1136
1234
  });
1137
1235
  },
1138
1236
  async transform(value, id) {
1139
- const [file, query = ""] = id.split("?");
1140
- const ext = path12.extname(file);
1141
1237
  try {
1142
- if ([".yaml", ".json"].includes(ext))
1143
- return await transformMeta(file, query, value);
1144
- if ([".md", ".mdx"].includes(ext))
1238
+ if (metaLoaderGlob.test(id)) {
1239
+ const [file, query = ""] = id.split("?", 2);
1240
+ return await metaLoader.call(this, file, query, value);
1241
+ }
1242
+ if (mdxLoaderGlob.test(id)) {
1243
+ const [file, query = ""] = id.split("?", 2);
1145
1244
  return await mdxLoader.call(this, file, query, value);
1245
+ }
1146
1246
  } catch (e) {
1147
1247
  if (e instanceof ValidationError) {
1148
1248
  throw new Error(e.toStringFormatted());
@@ -1153,8 +1253,8 @@ async function mdx(config, pluginOptions = {}) {
1153
1253
  };
1154
1254
  }
1155
1255
  async function postInstall(configPath = findConfigFile(), pluginOptions = {}) {
1156
- const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_load(), load_exports));
1157
- const options = applyDefaults(pluginOptions);
1256
+ const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_load_from_file(), load_from_file_exports));
1257
+ const options = applyDefaults2(pluginOptions);
1158
1258
  const core = await createViteCore(options).init({
1159
1259
  config: loadConfig2(configPath, options.outDir, true)
1160
1260
  });
@@ -1172,11 +1272,13 @@ function createViteCore({
1172
1272
  outDir
1173
1273
  },
1174
1274
  [
1175
- generateIndexFile !== false && vite(typeof generateIndexFile === "object" ? generateIndexFile : {})
1275
+ vite({
1276
+ index: generateIndexFile
1277
+ })
1176
1278
  ]
1177
1279
  );
1178
1280
  }
1179
- function applyDefaults(options) {
1281
+ function applyDefaults2(options) {
1180
1282
  return {
1181
1283
  updateViteConfig: options.updateViteConfig ?? true,
1182
1284
  generateIndexFile: options.generateIndexFile ?? true,
@@ -13,6 +13,10 @@ interface IndexFileOptions {
13
13
  * add `.js` extensions to imports, needed for ESM without bundler resolution
14
14
  */
15
15
  addJsExtension?: boolean;
16
+ /**
17
+ * Generate entry point for browser environment
18
+ */
19
+ browser?: boolean;
16
20
  }
17
21
 
18
22
  interface PluginOptions {