fumadocs-mdx 13.0.8 → 14.0.1

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 (111) hide show
  1. package/dist/bin.cjs +985 -893
  2. package/dist/bin.js +3 -3
  3. package/dist/build-mdx-6UAK5FF5.js +8 -0
  4. package/dist/bun/index.cjs +613 -471
  5. package/dist/bun/index.d.cts +9 -2
  6. package/dist/bun/index.d.ts +9 -2
  7. package/dist/bun/index.js +15 -14
  8. package/dist/chunk-4JSFLXXT.js +8 -0
  9. package/dist/chunk-5OBUOALK.js +141 -0
  10. package/dist/{chunk-2E2JCOSO.js → chunk-6NISOLQ6.js} +16 -44
  11. package/dist/chunk-7UKSZSPY.js +331 -0
  12. package/dist/chunk-BEBCWQC7.js +224 -0
  13. package/dist/chunk-E5DJTSIM.js +86 -0
  14. package/dist/{chunk-K5ZLPEIQ.js → chunk-FBLMK4RS.js} +9 -6
  15. package/dist/chunk-IQGEFL2B.js +17 -0
  16. package/dist/{chunk-5FTSWCB4.js → chunk-K6HCOGOX.js} +9 -11
  17. package/dist/{chunk-QXHN25N3.js → chunk-MTTISKQJ.js} +6 -6
  18. package/dist/{chunk-3J3WL7WN.js → chunk-SLY7WXTX.js} +71 -58
  19. package/dist/chunk-TYJDYTKH.js +85 -0
  20. package/dist/chunk-WBIHDYMN.js +126 -0
  21. package/dist/{chunk-2HXTGJBI.js → chunk-ZY6UZ7NH.js} +22 -19
  22. package/dist/config/index.cjs +79 -71
  23. package/dist/config/index.d.cts +7 -1
  24. package/dist/config/index.d.ts +7 -1
  25. package/dist/config/index.js +5 -5
  26. package/dist/core-B9ZoS6sA.d.ts +341 -0
  27. package/dist/core-DTuP23zu.d.cts +341 -0
  28. package/dist/index-BD8Woo4m.d.cts +8 -0
  29. package/dist/index-CNOvhtOn.d.ts +8 -0
  30. package/dist/index.d.cts +38 -56
  31. package/dist/index.d.ts +38 -56
  32. package/dist/load-from-file-5HUQN36V.js +8 -0
  33. package/dist/next/index.cjs +763 -473
  34. package/dist/next/index.d.cts +16 -1
  35. package/dist/next/index.d.ts +16 -1
  36. package/dist/next/index.js +80 -281
  37. package/dist/node/loader.cjs +764 -627
  38. package/dist/node/loader.js +10 -11
  39. package/dist/plugins/index-file.cjs +495 -0
  40. package/dist/plugins/index-file.d.cts +14 -0
  41. package/dist/plugins/index-file.d.ts +14 -0
  42. package/dist/plugins/index-file.js +8 -0
  43. package/dist/plugins/json-schema.d.cts +9 -2
  44. package/dist/plugins/json-schema.d.ts +9 -2
  45. package/dist/plugins/last-modified.cjs +110 -0
  46. package/dist/plugins/last-modified.d.cts +37 -0
  47. package/dist/plugins/last-modified.d.ts +37 -0
  48. package/dist/plugins/last-modified.js +74 -0
  49. package/dist/runtime/browser.cjs +93 -0
  50. package/dist/runtime/browser.d.cts +53 -0
  51. package/dist/runtime/browser.d.ts +53 -0
  52. package/dist/runtime/browser.js +67 -0
  53. package/dist/runtime/dynamic.cjs +1023 -0
  54. package/dist/runtime/dynamic.d.cts +27 -0
  55. package/dist/runtime/dynamic.d.ts +27 -0
  56. package/dist/runtime/dynamic.js +79 -0
  57. package/dist/runtime/server.cjs +176 -0
  58. package/dist/runtime/server.d.cts +14 -0
  59. package/dist/runtime/server.d.ts +14 -0
  60. package/dist/runtime/server.js +8 -0
  61. package/dist/runtime/types.cjs +18 -0
  62. package/dist/runtime/types.d.cts +61 -0
  63. package/dist/runtime/types.d.ts +61 -0
  64. package/dist/runtime/types.js +0 -0
  65. package/dist/vite/index.cjs +984 -621
  66. package/dist/vite/index.d.cts +17 -22
  67. package/dist/vite/index.d.ts +17 -22
  68. package/dist/vite/index.js +32 -222
  69. package/dist/webpack/mdx.cjs +647 -514
  70. package/dist/webpack/mdx.d.cts +15 -1
  71. package/dist/webpack/mdx.d.ts +15 -1
  72. package/dist/webpack/mdx.js +12 -17
  73. package/dist/webpack/meta.cjs +360 -231
  74. package/dist/webpack/meta.d.cts +15 -1
  75. package/dist/webpack/meta.d.ts +15 -1
  76. package/dist/webpack/meta.js +13 -15
  77. package/package.json +15 -32
  78. package/dist/build-mdx-BjXOmv0b.d.cts +0 -53
  79. package/dist/build-mdx-CY5UldCO.d.ts +0 -53
  80. package/dist/chunk-2AQRQXSO.js +0 -119
  81. package/dist/chunk-CXA4JO4Z.js +0 -45
  82. package/dist/chunk-DMJ6I4C3.js +0 -76
  83. package/dist/chunk-FSZMKRVH.js +0 -80
  84. package/dist/chunk-II3H5ZVZ.js +0 -77
  85. package/dist/chunk-KILFIBVW.js +0 -75
  86. package/dist/chunk-NVRDCY6Z.js +0 -30
  87. package/dist/chunk-VUEZTR2H.js +0 -26
  88. package/dist/core-DB7TdlyC.d.cts +0 -234
  89. package/dist/core-DB7TdlyC.d.ts +0 -234
  90. package/dist/index-D7s7kCc2.d.cts +0 -7
  91. package/dist/index-D7s7kCc2.d.ts +0 -7
  92. package/dist/load-from-file-AVYOFOI7.js +0 -7
  93. package/dist/preset-ZMP6U62C.js +0 -6
  94. package/dist/runtime/next/async.cjs +0 -760
  95. package/dist/runtime/next/async.d.cts +0 -19
  96. package/dist/runtime/next/async.d.ts +0 -19
  97. package/dist/runtime/next/async.js +0 -86
  98. package/dist/runtime/next/index.cjs +0 -136
  99. package/dist/runtime/next/index.d.cts +0 -33
  100. package/dist/runtime/next/index.d.ts +0 -33
  101. package/dist/runtime/next/index.js +0 -11
  102. package/dist/runtime/vite/browser.cjs +0 -107
  103. package/dist/runtime/vite/browser.d.cts +0 -59
  104. package/dist/runtime/vite/browser.d.ts +0 -59
  105. package/dist/runtime/vite/browser.js +0 -11
  106. package/dist/runtime/vite/server.cjs +0 -243
  107. package/dist/runtime/vite/server.d.cts +0 -30
  108. package/dist/runtime/vite/server.d.ts +0 -30
  109. package/dist/runtime/vite/server.js +0 -111
  110. package/dist/types-Bnh9n7mj.d.cts +0 -45
  111. package/dist/types-ey1AZqrg.d.ts +0 -45
package/dist/bin.cjs CHANGED
@@ -30,11 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  mod
31
31
  ));
32
32
 
33
- // src/loaders/mdx/preset.ts
34
- var preset_exports = {};
35
- __export(preset_exports, {
36
- getDefaultMDXOptions: () => getDefaultMDXOptions
37
- });
33
+ // src/config/preset.ts
38
34
  function pluginOption(def, options = []) {
39
35
  const list = def(Array.isArray(options) ? options : []).filter(
40
36
  Boolean
@@ -44,76 +40,81 @@ function pluginOption(def, options = []) {
44
40
  }
45
41
  return list;
46
42
  }
47
- function getDefaultMDXOptions({
48
- valueToExport = [],
49
- rehypeCodeOptions,
50
- remarkImageOptions,
51
- remarkHeadingOptions,
52
- remarkStructureOptions,
53
- remarkCodeTabOptions,
54
- remarkNpmOptions,
55
- _withoutBundler = false,
56
- ...mdxOptions
57
- }) {
58
- const remarkPlugins = pluginOption(
59
- (v) => [
60
- plugins.remarkGfm,
61
- [
62
- plugins.remarkHeading,
63
- {
64
- generateToc: false,
65
- ...remarkHeadingOptions
66
- }
67
- ],
68
- remarkImageOptions !== false && [
69
- plugins.remarkImage,
70
- {
71
- ...remarkImageOptions,
72
- useImport: _withoutBundler ? false : remarkImageOptions?.useImport
73
- }
74
- ],
75
- "remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
76
- plugins.remarkCodeTab,
77
- remarkCodeTabOptions
43
+ function applyMdxPreset(options = {}) {
44
+ return async (environment = "bundler") => {
45
+ if (options.preset === "minimal") return options;
46
+ const plugins = await import("fumadocs-core/mdx-plugins");
47
+ const {
48
+ valueToExport = [],
49
+ rehypeCodeOptions,
50
+ remarkImageOptions,
51
+ remarkHeadingOptions,
52
+ remarkStructureOptions,
53
+ remarkCodeTabOptions,
54
+ remarkNpmOptions,
55
+ ...mdxOptions
56
+ } = options;
57
+ const remarkPlugins = pluginOption(
58
+ (v) => [
59
+ plugins.remarkGfm,
60
+ [
61
+ plugins.remarkHeading,
62
+ {
63
+ generateToc: false,
64
+ ...remarkHeadingOptions
65
+ }
66
+ ],
67
+ remarkImageOptions !== false && [
68
+ plugins.remarkImage,
69
+ {
70
+ ...remarkImageOptions,
71
+ useImport: remarkImageOptions?.useImport ?? environment === "bundler"
72
+ }
73
+ ],
74
+ "remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
75
+ plugins.remarkCodeTab,
76
+ remarkCodeTabOptions
77
+ ],
78
+ "remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
79
+ ...v,
80
+ remarkStructureOptions !== false && [
81
+ plugins.remarkStructure,
82
+ remarkStructureOptions
83
+ ],
84
+ valueToExport.length > 0 && (() => {
85
+ return (_, file) => {
86
+ file.data["mdx-export"] ??= [];
87
+ for (const name of valueToExport) {
88
+ if (!(name in file.data)) continue;
89
+ file.data["mdx-export"].push({
90
+ name,
91
+ value: file.data[name]
92
+ });
93
+ }
94
+ };
95
+ })
78
96
  ],
79
- "remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
80
- ...v,
81
- remarkStructureOptions !== false && [
82
- plugins.remarkStructure,
83
- remarkStructureOptions
97
+ mdxOptions.remarkPlugins
98
+ );
99
+ const rehypePlugins = pluginOption(
100
+ (v) => [
101
+ rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
102
+ ...v,
103
+ plugins.rehypeToc
84
104
  ],
85
- () => {
86
- return (_, file) => {
87
- file.data["mdx-export"] ??= [];
88
- for (const name of valueToExport) {
89
- if (name in file.data)
90
- file.data["mdx-export"].push({ name, value: file.data[name] });
91
- }
92
- };
93
- }
94
- ],
95
- mdxOptions.remarkPlugins
96
- );
97
- const rehypePlugins = pluginOption(
98
- (v) => [
99
- rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
100
- ...v,
101
- plugins.rehypeToc
102
- ],
103
- mdxOptions.rehypePlugins
104
- );
105
- return {
106
- ...mdxOptions,
107
- outputFormat: _withoutBundler ? "function-body" : mdxOptions.outputFormat,
108
- remarkPlugins,
109
- rehypePlugins
105
+ mdxOptions.rehypePlugins
106
+ );
107
+ return {
108
+ ...mdxOptions,
109
+ outputFormat: environment === "runtime" ? "function-body" : mdxOptions.outputFormat,
110
+ remarkPlugins,
111
+ rehypePlugins
112
+ };
110
113
  };
111
114
  }
112
- var plugins;
113
115
  var init_preset = __esm({
114
- "src/loaders/mdx/preset.ts"() {
116
+ "src/config/preset.ts"() {
115
117
  "use strict";
116
- plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
117
118
  }
118
119
  });
119
120
 
@@ -124,7 +125,10 @@ function buildCollection(name, config) {
124
125
  ...config,
125
126
  name,
126
127
  meta: buildPrimitiveCollection(name, config.meta),
127
- docs: buildPrimitiveCollection(name, config.docs)
128
+ docs: buildPrimitiveCollection(name, config.docs),
129
+ hasFile(filePath) {
130
+ return this.docs.hasFile(filePath) || this.meta.hasFile(filePath);
131
+ }
128
132
  };
129
133
  }
130
134
  return buildPrimitiveCollection(name, config);
@@ -178,11 +182,6 @@ function buildConfig(config) {
178
182
  `Unknown export "${k}", you can only export collections from source configuration file.`
179
183
  );
180
184
  }
181
- if (loaded.collections) {
182
- for (const [k, v] of Object.entries(loaded.collections)) {
183
- collections.set(k, buildCollection(k, v));
184
- }
185
- }
186
185
  const mdxOptionsCache = /* @__PURE__ */ new Map();
187
186
  return {
188
187
  global: loaded,
@@ -190,21 +189,22 @@ function buildConfig(config) {
190
189
  getCollection(name) {
191
190
  return collections.get(name);
192
191
  },
193
- async getDefaultMDXOptions(mode = "default") {
194
- const cached = mdxOptionsCache.get(mode);
192
+ getMDXOptions(collection, environment = "bundler") {
193
+ const key = collection ? `${environment}:${collection.name}` : environment;
194
+ const cached = mdxOptionsCache.get(key);
195
195
  if (cached) return cached;
196
- const input = this.global.mdxOptions;
197
- async function uncached() {
198
- const options = typeof input === "function" ? await input() : input;
199
- const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_preset(), preset_exports));
200
- if (options?.preset === "minimal") return options;
201
- return getDefaultMDXOptions2({
202
- ...options,
203
- _withoutBundler: mode === "remote"
204
- });
196
+ let result;
197
+ if (collection?.mdxOptions) {
198
+ const optionsFn = collection.mdxOptions;
199
+ result = typeof optionsFn === "function" ? optionsFn(environment) : optionsFn;
200
+ } else {
201
+ result = (async () => {
202
+ const optionsFn = this.global.mdxOptions;
203
+ const options = typeof optionsFn === "function" ? await optionsFn() : optionsFn;
204
+ return applyMdxPreset(options)(environment);
205
+ })();
205
206
  }
206
- const result = uncached();
207
- mdxOptionsCache.set(mode, result);
207
+ mdxOptionsCache.set(key, result);
208
208
  return result;
209
209
  }
210
210
  };
@@ -214,6 +214,7 @@ var init_build = __esm({
214
214
  "src/config/build.ts"() {
215
215
  "use strict";
216
216
  import_picomatch = __toESM(require("picomatch"), 1);
217
+ init_preset();
217
218
  SupportedFormats = {
218
219
  doc: ["mdx", "md"],
219
220
  meta: ["json", "yaml"]
@@ -226,8 +227,9 @@ var load_from_file_exports = {};
226
227
  __export(load_from_file_exports, {
227
228
  loadConfig: () => loadConfig
228
229
  });
229
- async function compileConfig(configPath, outDir) {
230
+ async function compileConfig(core) {
230
231
  const { build } = await import("esbuild");
232
+ const { configPath, outDir } = core.getOptions();
231
233
  const transformed = await build({
232
234
  entryPoints: [{ in: configPath, out: "source.config" }],
233
235
  bundle: true,
@@ -246,56 +248,24 @@ async function compileConfig(configPath, outDir) {
246
248
  throw new Error("failed to compile configuration file");
247
249
  }
248
250
  }
249
- async function loadConfig(configPath, outDir, build = false) {
250
- if (build) await compileConfig(configPath, outDir);
251
- const url = (0, import_node_url.pathToFileURL)(path.resolve(outDir, "source.config.mjs"));
251
+ async function loadConfig(core, build = false) {
252
+ if (build) await compileConfig(core);
253
+ const url = (0, import_node_url.pathToFileURL)(core.getCompiledConfigPath());
252
254
  url.searchParams.set("hash", Date.now().toString());
253
255
  const config = import(url.href).then(
254
256
  (loaded) => buildConfig(loaded)
255
257
  );
256
258
  return await config;
257
259
  }
258
- var path, import_node_url;
260
+ var import_node_url;
259
261
  var init_load_from_file = __esm({
260
262
  "src/config/load-from-file.ts"() {
261
263
  "use strict";
262
- path = __toESM(require("path"), 1);
263
264
  import_node_url = require("url");
264
265
  init_build();
265
266
  }
266
267
  });
267
268
 
268
- // src/next/file-cache.ts
269
- function toFullPath(file) {
270
- if (import_node_path.default.isAbsolute(file)) {
271
- return import_node_path.default.relative(process.cwd(), file);
272
- }
273
- return file;
274
- }
275
- async function readFileWithCache(file) {
276
- const fullPath = toFullPath(file);
277
- const cached = map.get(fullPath);
278
- if (cached) return cached;
279
- const read = import_promises.default.readFile(fullPath).then((s) => s.toString());
280
- map.set(fullPath, read);
281
- return read;
282
- }
283
- function removeFileCache(file) {
284
- map.delete(toFullPath(file));
285
- }
286
- var import_lru_cache, import_promises, import_node_path, map;
287
- var init_file_cache = __esm({
288
- "src/next/file-cache.ts"() {
289
- "use strict";
290
- import_lru_cache = require("lru-cache");
291
- import_promises = __toESM(require("fs/promises"), 1);
292
- import_node_path = __toESM(require("path"), 1);
293
- map = new import_lru_cache.LRUCache({
294
- max: 100
295
- });
296
- }
297
- });
298
-
299
269
  // src/utils/validation.ts
300
270
  async function validate(schema, data, context, errorMessage) {
301
271
  if (typeof schema === "function" && !("~standard" in schema)) {
@@ -312,11 +282,10 @@ async function validate(schema, data, context, errorMessage) {
312
282
  }
313
283
  return data;
314
284
  }
315
- var import_picocolors, ValidationError;
285
+ var ValidationError;
316
286
  var init_validation = __esm({
317
287
  "src/utils/validation.ts"() {
318
288
  "use strict";
319
- import_picocolors = __toESM(require("picocolors"), 1);
320
289
  ValidationError = class extends Error {
321
290
  constructor(message, issues) {
322
291
  super(
@@ -326,12 +295,13 @@ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
326
295
  this.title = message;
327
296
  this.issues = issues;
328
297
  }
329
- toStringFormatted() {
298
+ async toStringFormatted() {
299
+ const picocolors = await import("picocolors");
330
300
  return [
331
- import_picocolors.default.bold(`[MDX] ${this.title}:`),
301
+ picocolors.bold(`[MDX] ${this.title}:`),
332
302
  ...this.issues.map(
333
- (issue) => import_picocolors.default.redBright(
334
- `- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
303
+ (issue) => picocolors.redBright(
304
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
335
305
  )
336
306
  )
337
307
  ].join("\n");
@@ -340,32 +310,357 @@ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
340
310
  }
341
311
  });
342
312
 
343
- // src/utils/git-timestamp.ts
344
- async function getGitTimestamp(file) {
345
- const cached = cache.get(file);
346
- if (cached) return cached;
347
- try {
348
- const out = await (0, import_tinyexec.x)(
349
- "git",
350
- ["log", "-1", '--pretty="%ai"', import_node_path2.default.relative(process.cwd(), file)],
351
- {
352
- throwOnError: true
313
+ // src/utils/codegen.ts
314
+ function createCodegen({
315
+ target = "default",
316
+ outDir = "",
317
+ jsExtension = false,
318
+ globCache = /* @__PURE__ */ new Map()
319
+ }) {
320
+ let eagerImportId = 0;
321
+ const banner = ["// @ts-nocheck"];
322
+ if (target === "vite") {
323
+ banner.push('/// <reference types="vite/client" />');
324
+ }
325
+ return {
326
+ options: {
327
+ target,
328
+ outDir
329
+ },
330
+ lines: [],
331
+ addImport(statement) {
332
+ this.lines.unshift(statement);
333
+ },
334
+ async pushAsync(insert) {
335
+ for (const line of await Promise.all(insert)) {
336
+ if (line === void 0) continue;
337
+ this.lines.push(line);
353
338
  }
354
- );
355
- const time = new Date(out.stdout);
356
- cache.set(file, time);
357
- return time;
358
- } catch {
359
- return;
339
+ },
340
+ async generateGlobImport(patterns, options) {
341
+ if (target === "vite") {
342
+ return this.generateViteGlobImport(patterns, options);
343
+ }
344
+ return this.generateNodeGlobImport(patterns, options);
345
+ },
346
+ generateViteGlobImport(patterns, { base, ...rest }) {
347
+ patterns = (typeof patterns === "string" ? [patterns] : patterns).map(
348
+ normalizeViteGlobPath
349
+ );
350
+ return `import.meta.glob(${JSON.stringify(patterns)}, ${JSON.stringify(
351
+ {
352
+ base: normalizeViteGlobPath(import_node_path.default.relative(outDir, base)),
353
+ ...rest
354
+ },
355
+ null,
356
+ 2
357
+ )})`;
358
+ },
359
+ async generateNodeGlobImport(patterns, {
360
+ base,
361
+ eager = false,
362
+ query = {},
363
+ import: importName
364
+ }) {
365
+ const cacheKey = JSON.stringify({ patterns, base });
366
+ let files = globCache.get(cacheKey);
367
+ if (!files) {
368
+ files = (0, import_tinyglobby.glob)(patterns, {
369
+ cwd: base
370
+ });
371
+ globCache.set(cacheKey, files);
372
+ }
373
+ let code = "{";
374
+ for (const item of await files) {
375
+ const fullPath = import_node_path.default.join(base, item);
376
+ const searchParams = new URLSearchParams();
377
+ for (const [k, v] of Object.entries(query)) {
378
+ searchParams.set(k, v);
379
+ }
380
+ const importPath = this.formatImportPath(fullPath) + "?" + searchParams.toString();
381
+ if (eager) {
382
+ const name = `__fd_glob_${eagerImportId++}`;
383
+ this.lines.unshift(
384
+ importName ? `import { ${importName} as ${name} } from ${JSON.stringify(importPath)}` : `import * as ${name} from ${JSON.stringify(importPath)}`
385
+ );
386
+ code += `${JSON.stringify(item)}: ${name}, `;
387
+ } else {
388
+ let line = `${JSON.stringify(item)}: () => import(${JSON.stringify(importPath)})`;
389
+ if (importName) {
390
+ line += `.then(mod => mod.${importName})`;
391
+ }
392
+ code += `${line}, `;
393
+ }
394
+ }
395
+ code += "}";
396
+ return code;
397
+ },
398
+ formatImportPath(file) {
399
+ const ext = import_node_path.default.extname(file);
400
+ let filename;
401
+ if (ext === ".ts" && jsExtension) {
402
+ filename = file.substring(0, file.length - ext.length) + ".js";
403
+ } else if (ext === ".ts") {
404
+ filename = file.substring(0, file.length - ext.length);
405
+ } else {
406
+ filename = file;
407
+ }
408
+ const importPath = slash(import_node_path.default.relative(outDir, filename));
409
+ return importPath.startsWith(".") ? importPath : `./${importPath}`;
410
+ },
411
+ toString() {
412
+ return [...banner, ...this.lines].join("\n");
413
+ }
414
+ };
415
+ }
416
+ function normalizeViteGlobPath(file) {
417
+ file = slash(file);
418
+ if (file.startsWith("./")) return file;
419
+ if (file.startsWith("/")) return `.${file}`;
420
+ return `./${file}`;
421
+ }
422
+ function slash(path9) {
423
+ const isExtendedLengthPath = path9.startsWith("\\\\?\\");
424
+ if (isExtendedLengthPath) {
425
+ return path9;
426
+ }
427
+ return path9.replaceAll("\\", "/");
428
+ }
429
+ function ident(code, tab = 1) {
430
+ return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
431
+ }
432
+ var import_node_path, import_tinyglobby;
433
+ var init_codegen = __esm({
434
+ "src/utils/codegen.ts"() {
435
+ "use strict";
436
+ import_node_path = __toESM(require("path"), 1);
437
+ import_tinyglobby = require("tinyglobby");
438
+ }
439
+ });
440
+
441
+ // src/core.ts
442
+ async function getPlugins(pluginOptions) {
443
+ const plugins = [];
444
+ for await (const option of pluginOptions) {
445
+ if (!option) continue;
446
+ if (Array.isArray(option)) plugins.push(...await getPlugins(option));
447
+ else plugins.push(option);
448
+ }
449
+ return plugins;
450
+ }
451
+ function createCore(options, defaultPlugins = []) {
452
+ let config;
453
+ let plugins;
454
+ async function transformMetadata({
455
+ collection,
456
+ filePath,
457
+ source
458
+ }, data) {
459
+ if (collection.schema) {
460
+ data = await validate(
461
+ collection.schema,
462
+ data,
463
+ { path: filePath, source },
464
+ collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
465
+ );
466
+ }
467
+ return data;
360
468
  }
469
+ const core = {
470
+ /**
471
+ * Convenient cache store, reset when config changes
472
+ */
473
+ cache: /* @__PURE__ */ new Map(),
474
+ async init({ config: newConfig }) {
475
+ config = await newConfig;
476
+ this.cache.clear();
477
+ plugins = await getPlugins([
478
+ postprocessPlugin(),
479
+ ...defaultPlugins,
480
+ ...config.global.plugins ?? []
481
+ ]);
482
+ for (const plugin of plugins) {
483
+ const out = await plugin.config?.call(pluginContext, config);
484
+ if (out) config = out;
485
+ }
486
+ },
487
+ getOptions() {
488
+ return options;
489
+ },
490
+ getConfig() {
491
+ return config;
492
+ },
493
+ /**
494
+ * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
495
+ */
496
+ getCompiledConfigPath() {
497
+ return import_node_path2.default.join(options.outDir, "source.config.mjs");
498
+ },
499
+ getPlugins() {
500
+ return plugins;
501
+ },
502
+ getPluginContext() {
503
+ return pluginContext;
504
+ },
505
+ async initServer(server) {
506
+ for (const plugin of plugins) {
507
+ await plugin.configureServer?.call(pluginContext, server);
508
+ }
509
+ },
510
+ async emit({ filterPlugin = () => true } = {}) {
511
+ return (await Promise.all(
512
+ plugins.map((plugin) => {
513
+ if (!filterPlugin(plugin) || !plugin.emit) return [];
514
+ return plugin.emit.call(pluginContext);
515
+ })
516
+ )).flat();
517
+ },
518
+ async emitAndWrite(emitOptions) {
519
+ const start2 = performance.now();
520
+ const out = await this.emit(emitOptions);
521
+ await Promise.all(
522
+ out.map(async (entry) => {
523
+ const file = import_node_path2.default.join(options.outDir, entry.path);
524
+ await import_promises.default.mkdir(import_node_path2.default.dirname(file), { recursive: true });
525
+ await import_promises.default.writeFile(file, entry.content);
526
+ })
527
+ );
528
+ console.log(`[MDX] generated files in ${performance.now() - start2}ms`);
529
+ },
530
+ async transformMeta(options2, data) {
531
+ const ctx = {
532
+ ...pluginContext,
533
+ ...options2
534
+ };
535
+ data = await transformMetadata(options2, data);
536
+ for (const plugin of plugins) {
537
+ if (plugin.meta?.transform)
538
+ data = await plugin.meta.transform.call(ctx, data) ?? data;
539
+ }
540
+ return data;
541
+ },
542
+ async transformFrontmatter(options2, data) {
543
+ const ctx = {
544
+ ...pluginContext,
545
+ ...options2
546
+ };
547
+ data = await transformMetadata(options2, data);
548
+ for (const plugin of plugins) {
549
+ if (plugin.doc?.frontmatter)
550
+ data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
551
+ }
552
+ return data;
553
+ },
554
+ async transformVFile(options2, file) {
555
+ const ctx = {
556
+ ...pluginContext,
557
+ ...options2
558
+ };
559
+ for (const plugin of plugins) {
560
+ if (plugin.doc?.vfile)
561
+ file = await plugin.doc.vfile.call(ctx, file) ?? file;
562
+ }
563
+ return file;
564
+ }
565
+ };
566
+ const pluginContext = {
567
+ core,
568
+ ...options
569
+ };
570
+ return core;
361
571
  }
362
- var import_node_path2, import_tinyexec, cache;
363
- var init_git_timestamp = __esm({
364
- "src/utils/git-timestamp.ts"() {
572
+ function postprocessPlugin() {
573
+ const LinkReferenceTypes = `{
574
+ /**
575
+ * extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
576
+ */
577
+ extractedReferences?: import('fumadocs-mdx').ExtractedReference[];
578
+ }`;
579
+ return {
580
+ "index-file": {
581
+ generateTypeConfig() {
582
+ const lines = [];
583
+ lines.push("{");
584
+ lines.push(" DocData: {");
585
+ for (const collection of this.core.getConfig().collectionList) {
586
+ let postprocessOptions;
587
+ switch (collection.type) {
588
+ case "doc":
589
+ postprocessOptions = collection.postprocess;
590
+ break;
591
+ case "docs":
592
+ postprocessOptions = collection.docs.postprocess;
593
+ break;
594
+ }
595
+ if (postprocessOptions?.extractLinkReferences) {
596
+ lines.push(ident(`${collection.name}: ${LinkReferenceTypes},`, 2));
597
+ }
598
+ }
599
+ lines.push(" }");
600
+ lines.push("}");
601
+ return lines.join("\n");
602
+ },
603
+ serverOptions(options) {
604
+ options.doc ??= {};
605
+ options.doc.passthroughs ??= [];
606
+ options.doc.passthroughs.push("extractedReferences");
607
+ }
608
+ }
609
+ };
610
+ }
611
+ var import_node_path2, import_promises, _Defaults;
612
+ var init_core = __esm({
613
+ "src/core.ts"() {
365
614
  "use strict";
366
615
  import_node_path2 = __toESM(require("path"), 1);
367
- import_tinyexec = require("tinyexec");
368
- cache = /* @__PURE__ */ new Map();
616
+ import_promises = __toESM(require("fs/promises"), 1);
617
+ init_validation();
618
+ init_codegen();
619
+ _Defaults = {
620
+ configPath: "source.config.ts",
621
+ outDir: ".source"
622
+ };
623
+ }
624
+ });
625
+
626
+ // src/loaders/index.ts
627
+ var metaLoaderGlob, mdxLoaderGlob;
628
+ var init_loaders = __esm({
629
+ "src/loaders/index.ts"() {
630
+ "use strict";
631
+ metaLoaderGlob = /\.(json|yaml)(\?.+?)?$/;
632
+ mdxLoaderGlob = /\.mdx?(\?.+?)?$/;
633
+ }
634
+ });
635
+
636
+ // src/utils/fs-cache.ts
637
+ function toFullPath(file) {
638
+ if (import_node_path3.default.isAbsolute(file)) {
639
+ return import_node_path3.default.relative(process.cwd(), file);
640
+ }
641
+ return file;
642
+ }
643
+ function readFileWithCache(file) {
644
+ const fullPath = toFullPath(file);
645
+ const cached = map.get(fullPath);
646
+ if (cached) return cached;
647
+ const read = import_promises2.default.readFile(fullPath).then((s) => s.toString());
648
+ map.set(fullPath, read);
649
+ return read;
650
+ }
651
+ function removeFileCache(file) {
652
+ map.delete(toFullPath(file));
653
+ }
654
+ var import_lru_cache, import_promises2, import_node_path3, map;
655
+ var init_fs_cache = __esm({
656
+ "src/utils/fs-cache.ts"() {
657
+ "use strict";
658
+ import_lru_cache = require("lru-cache");
659
+ import_promises2 = __toESM(require("fs/promises"), 1);
660
+ import_node_path3 = __toESM(require("path"), 1);
661
+ map = new import_lru_cache.LRUCache({
662
+ max: 100
663
+ });
369
664
  }
370
665
  });
371
666
 
@@ -391,343 +686,305 @@ var init_fuma_matter = __esm({
391
686
  }
392
687
  });
393
688
 
394
- // src/utils/import-formatter.ts
395
- function getImportCode(info) {
396
- const specifier = JSON.stringify(info.specifier);
397
- if (info.type === "default") return `import ${info.name} from ${specifier}`;
398
- if (info.type === "namespace")
399
- return `import * as ${info.name} from ${specifier}`;
400
- if (info.type === "named") {
401
- const names = info.names.map(
402
- (name) => Array.isArray(name) ? `${name[0]} as ${name[1]}` : name
403
- );
404
- return `import { ${names.join(", ")} } from ${specifier}`;
405
- }
406
- return `import ${specifier}`;
407
- }
408
- function toImportPath(file, config) {
409
- const ext = import_node_path3.default.extname(file);
410
- let filename;
411
- if (ext === ".ts" && config.jsExtension) {
412
- filename = file.substring(0, file.length - ext.length) + ".js";
413
- } else if (ext === ".ts") {
414
- filename = file.substring(0, file.length - ext.length);
415
- } else {
416
- filename = file;
689
+ // src/plugins/index-file.ts
690
+ function indexFile(options = {}) {
691
+ const {
692
+ target = "default",
693
+ addJsExtension,
694
+ browser = true,
695
+ dynamic = true
696
+ } = options;
697
+ let config;
698
+ let dynamicCollections;
699
+ function isDynamic(collection) {
700
+ return collection.type === "docs" && collection.docs.dynamic || collection.type === "doc" && collection.dynamic;
417
701
  }
418
- let importPath;
419
- if ("relativeTo" in config) {
420
- importPath = import_node_path3.default.relative(config.relativeTo, filename);
421
- if (!import_node_path3.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
422
- importPath = `./${importPath}`;
702
+ function generateConfigs(core) {
703
+ const serverOptions = {};
704
+ const typeConfigs = [];
705
+ const ctx = core.getPluginContext();
706
+ for (const plugin of core.getPlugins()) {
707
+ const indexFilePlugin = plugin["index-file"];
708
+ if (!indexFilePlugin) continue;
709
+ indexFilePlugin.serverOptions?.call(ctx, serverOptions);
710
+ const config2 = indexFilePlugin.generateTypeConfig?.call(ctx);
711
+ if (config2) typeConfigs.push(config2);
423
712
  }
424
- } else {
425
- importPath = import_node_path3.default.resolve(filename);
426
- }
427
- return importPath.replaceAll(import_node_path3.default.sep, "/");
428
- }
429
- function ident(code, tab = 1) {
430
- return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
431
- }
432
- var import_node_path3;
433
- var init_import_formatter = __esm({
434
- "src/utils/import-formatter.ts"() {
435
- "use strict";
436
- import_node_path3 = __toESM(require("path"), 1);
713
+ if (typeConfigs.length === 0) {
714
+ typeConfigs.push("{ DocData: {} }");
715
+ }
716
+ return {
717
+ serverOptions,
718
+ tc: typeConfigs.join(" & ")
719
+ };
437
720
  }
438
- });
439
-
440
- // src/plugins/next.ts
441
- function next() {
442
- let config;
443
- let shouldEmitOnChange = false;
444
721
  return {
445
- name: "next",
722
+ name: "index-file",
446
723
  config(v) {
447
724
  config = v;
448
- shouldEmitOnChange = config.collectionList.some((collection) => {
449
- return collection.type === "doc" && collection.async || collection.type === "docs" || collection.type === "meta";
450
- });
725
+ dynamicCollections = config.collectionList.filter(isDynamic);
451
726
  },
452
727
  configureServer(server) {
453
728
  if (!server.watcher) return;
454
- server.watcher.on("all", async (event) => {
455
- if (event === "change" && !shouldEmitOnChange) return;
729
+ server.watcher.on("all", async (event, file) => {
730
+ removeFileCache(file);
731
+ if (dynamicCollections.length === 0) {
732
+ if (target === "vite") return;
733
+ if (target === "default" && event === "change") return;
734
+ }
735
+ const updatedCollection = config.collectionList.find(
736
+ (collection) => collection.hasFile(file)
737
+ );
738
+ if (!updatedCollection) return;
739
+ if (!isDynamic(updatedCollection)) {
740
+ if (target === "vite") return;
741
+ if (target === "default" && event === "change") return;
742
+ }
456
743
  await this.core.emitAndWrite({
457
- filterPlugin: (plugin) => plugin.name === "next"
744
+ filterPlugin: (plugin) => plugin.name === "index-file"
458
745
  });
459
746
  });
460
747
  },
461
748
  async emit() {
462
- return [
463
- {
464
- path: "index.ts",
465
- content: await indexFile(this.configPath, config, {
466
- relativeTo: this.outDir
467
- })
468
- }
749
+ const globCache = /* @__PURE__ */ new Map();
750
+ const { serverOptions, tc } = generateConfigs(this.core);
751
+ const toEmitEntry = async (path9, content) => {
752
+ const codegen = createCodegen({
753
+ target,
754
+ outDir: this.outDir,
755
+ jsExtension: addJsExtension,
756
+ globCache
757
+ });
758
+ await content({
759
+ core: this.core,
760
+ codegen,
761
+ serverOptions,
762
+ tc
763
+ });
764
+ return {
765
+ path: path9,
766
+ content: codegen.toString()
767
+ };
768
+ };
769
+ const out = [
770
+ toEmitEntry("server.ts", generateServerIndexFile)
469
771
  ];
772
+ if (dynamic)
773
+ out.push(toEmitEntry("dynamic.ts", generateDynamicIndexFile));
774
+ if (browser)
775
+ out.push(toEmitEntry("browser.ts", generateBrowserIndexFile));
776
+ return await Promise.all(out);
470
777
  }
471
778
  };
472
779
  }
473
- async function indexFile(configPath, config, importPath) {
474
- let asyncInit = false;
475
- const lines = [
476
- getImportCode({
477
- type: "named",
478
- names: ["_runtime"],
479
- specifier: "fumadocs-mdx/runtime/next"
480
- }),
481
- getImportCode({
482
- type: "namespace",
483
- specifier: toImportPath(configPath, importPath),
484
- name: "_source"
485
- })
486
- ];
487
- function getDocEntries(collection, files) {
488
- return files.map((file, i) => {
489
- const importId = `d_${collection.name}_${i}`;
490
- const params = [`collection=${collection.name}`];
491
- lines.unshift(
492
- getImportCode({
493
- type: "namespace",
494
- name: importId,
495
- specifier: `${toImportPath(file.fullPath, importPath)}?${params.join("&")}`
496
- })
497
- );
498
- return `{ info: ${JSON.stringify(file)}, data: ${importId} }`;
499
- });
500
- }
501
- async function getMetaEntries(collection, files) {
502
- const items = files.map(async (file) => {
503
- const source = await readFileWithCache(file.fullPath).catch(() => "");
504
- let data = source.length === 0 ? {} : parseMetaEntry(file.fullPath, source);
505
- if (collection?.schema) {
506
- data = await validate(
507
- collection.schema,
508
- data,
509
- {
510
- source,
511
- path: file.fullPath
512
- },
513
- `invalid data in ${file.fullPath}`
514
- );
780
+ async function generateServerIndexFile({
781
+ core,
782
+ codegen,
783
+ serverOptions,
784
+ tc
785
+ }) {
786
+ codegen.lines.push(
787
+ `import { server } from 'fumadocs-mdx/runtime/server';`,
788
+ `import type * as Config from '${codegen.formatImportPath(core.getOptions().configPath)}';`,
789
+ "",
790
+ `const create = server<typeof Config, ${tc}>(${JSON.stringify(serverOptions)});`
791
+ );
792
+ async function generateCollectionObject(collection) {
793
+ switch (collection.type) {
794
+ case "docs": {
795
+ if (collection.docs.dynamic) return;
796
+ if (collection.docs.async) {
797
+ const [metaGlob2, headGlob, bodyGlob] = await Promise.all([
798
+ generateMetaCollectionGlob(codegen, collection.meta, true),
799
+ generateDocCollectionFrontmatterGlob(
800
+ codegen,
801
+ collection.docs,
802
+ true
803
+ ),
804
+ generateDocCollectionGlob(codegen, collection.docs)
805
+ ]);
806
+ return `await create.docsLazy("${collection.name}", "${collection.dir}", ${metaGlob2}, ${headGlob}, ${bodyGlob})`;
807
+ }
808
+ const [metaGlob, docGlob] = await Promise.all([
809
+ generateMetaCollectionGlob(codegen, collection.meta, true),
810
+ generateDocCollectionGlob(codegen, collection.docs, true)
811
+ ]);
812
+ return `await create.docs("${collection.name}", "${collection.dir}", ${metaGlob}, ${docGlob})`;
515
813
  }
516
- return JSON.stringify({
517
- info: file,
518
- data
519
- });
520
- });
521
- return Promise.all(items);
814
+ case "doc":
815
+ if (collection.dynamic) return;
816
+ if (collection.async) {
817
+ const [headGlob, bodyGlob] = await Promise.all([
818
+ generateDocCollectionFrontmatterGlob(codegen, collection, true),
819
+ generateDocCollectionGlob(codegen, collection)
820
+ ]);
821
+ return `await create.docLazy("${collection.name}", "${collection.dir}", ${headGlob}, ${bodyGlob})`;
822
+ }
823
+ return `await create.doc("${collection.name}", "${collection.dir}", ${await generateDocCollectionGlob(
824
+ codegen,
825
+ collection,
826
+ true
827
+ )})`;
828
+ case "meta":
829
+ return `await create.meta("${collection.name}", "${collection.dir}", ${await generateMetaCollectionGlob(
830
+ codegen,
831
+ collection,
832
+ true
833
+ )})`;
834
+ }
522
835
  }
523
- async function getAsyncEntries(collection, files) {
524
- if (!asyncInit) {
525
- lines.unshift(
526
- getImportCode({
527
- type: "named",
528
- specifier: "fumadocs-mdx/runtime/async",
529
- names: ["_runtimeAsync", "buildConfig"]
530
- }),
531
- "const _sourceConfig = buildConfig(_source)",
532
- getImportCode({
533
- type: "default",
534
- name: "path",
535
- specifier: "node:path"
536
- })
537
- );
538
- asyncInit = true;
836
+ await codegen.pushAsync(
837
+ core.getConfig().collectionList.map(async (collection) => {
838
+ const obj = await generateCollectionObject(collection);
839
+ if (!obj) return;
840
+ return `
841
+ export const ${collection.name} = ${obj};`;
842
+ })
843
+ );
844
+ }
845
+ async function generateDynamicIndexFile({
846
+ core,
847
+ codegen,
848
+ serverOptions,
849
+ tc
850
+ }) {
851
+ const { configPath } = core.getOptions();
852
+ codegen.lines.push(
853
+ `import { dynamic } from 'fumadocs-mdx/runtime/dynamic';`,
854
+ `import * as Config from '${codegen.formatImportPath(configPath)}';`,
855
+ "",
856
+ `const create = await dynamic<typeof Config, ${tc}>(Config, ${JSON.stringify(core.getOptions())}, ${JSON.stringify(serverOptions)});`
857
+ );
858
+ async function generateCollectionObjectEntry(collection, file) {
859
+ const fullPath = import_path.default.join(collection.dir, file);
860
+ const content = await readFileWithCache(fullPath).catch(() => "");
861
+ const parsed = fumaMatter(content);
862
+ const data = await core.transformFrontmatter(
863
+ {
864
+ collection,
865
+ filePath: fullPath,
866
+ source: content
867
+ },
868
+ parsed.data
869
+ );
870
+ const hash = (0, import_crypto.createHash)("md5").update(content).digest("hex");
871
+ const infoStr = [
872
+ // make sure it's included in vercel/nft
873
+ `absolutePath: path.resolve(${JSON.stringify(fullPath)})`
874
+ ];
875
+ for (const [k, v] of Object.entries({
876
+ info: {
877
+ fullPath,
878
+ path: file
879
+ },
880
+ data,
881
+ hash
882
+ })) {
883
+ infoStr.push(`${k}: ${JSON.stringify(v)}`);
539
884
  }
540
- const entries = files.map(async (file) => {
541
- const content = await readFileWithCache(file.fullPath).catch(() => "");
542
- const parsed = fumaMatter(content);
543
- let data = parsed.data;
544
- if (collection.schema) {
545
- data = await validate(
546
- collection.schema,
547
- parsed.data,
548
- { path: file.fullPath, source: parsed.content },
549
- `invalid frontmatter in ${file.fullPath}`
550
- );
551
- }
552
- let lastModified;
553
- if (config.global?.lastModifiedTime === "git") {
554
- lastModified = await getGitTimestamp(file.fullPath);
555
- }
556
- const hash = (0, import_node_crypto.createHash)("md5").update(content).digest("hex");
557
- const infoStr = [];
558
- for (const [k, v] of Object.entries({ ...file, hash })) {
559
- infoStr.push(`${k}: ${JSON.stringify(v)}`);
560
- }
561
- infoStr.push(
562
- `absolutePath: path.resolve(${JSON.stringify(file.fullPath)})`
563
- );
564
- return `{ info: { ${infoStr.join(", ")} }, lastModified: ${JSON.stringify(lastModified)}, data: ${JSON.stringify(data)} }`;
565
- });
566
- return Promise.all(entries);
885
+ return `{ ${infoStr.join(", ")} }`;
567
886
  }
568
- const declares = config.collectionList.map(async (collection) => {
569
- const k = collection.name;
570
- if (collection.type === "docs") {
571
- const docs = await globCollectionFiles(collection.docs);
572
- const metas = await globCollectionFiles(collection.meta);
573
- const metaEntries = (await getMetaEntries(collection.meta, metas)).join(
574
- ", "
575
- );
576
- if (collection.docs.async) {
577
- const docsEntries2 = (await getAsyncEntries(collection.docs, docs)).join(
578
- ", "
887
+ async function generateCollectionObject(parent) {
888
+ let collection;
889
+ if (parent.type === "doc") collection = parent;
890
+ else if (parent.type === "docs") collection = parent.docs;
891
+ if (!collection || !collection.dynamic) return;
892
+ const files = await (0, import_tinyglobby2.glob)(collection.patterns, {
893
+ cwd: collection.dir
894
+ });
895
+ const entries = await Promise.all(
896
+ files.map((file) => generateCollectionObjectEntry(collection, file))
897
+ );
898
+ switch (parent.type) {
899
+ case "docs": {
900
+ const metaGlob = await generateMetaCollectionGlob(
901
+ codegen,
902
+ parent.meta,
903
+ true
579
904
  );
580
- return `export const ${k} = _runtimeAsync.docs<typeof _source.${k}>([${docsEntries2}], [${metaEntries}], "${k}", _sourceConfig)`;
905
+ return `await create.docs("${parent.name}", "${parent.dir}", ${metaGlob}, ${entries.join(", ")})`;
581
906
  }
582
- const docsEntries = getDocEntries(collection.docs, docs).join(", ");
583
- return `export const ${k} = _runtime.docs<typeof _source.${k}>([${docsEntries}], [${metaEntries}])`;
584
- }
585
- const files = await globCollectionFiles(collection);
586
- if (collection.type === "meta") {
587
- return `export const ${k} = _runtime.meta<typeof _source.${k}>([${(await getMetaEntries(collection, files)).join(", ")}]);`;
588
- }
589
- if (collection.async) {
590
- return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(collection, files)).join(", ")}], "${k}", _sourceConfig)`;
907
+ case "doc":
908
+ return `await create.doc("${collection.name}", "${collection.dir}", ${entries.join(", ")})`;
591
909
  }
592
- return `export const ${k} = _runtime.doc<typeof _source.${k}>([${getDocEntries(collection, files).join(", ")}]);`;
593
- });
594
- const resolvedDeclares = await Promise.all(declares);
595
- return [
596
- `// @ts-nocheck -- skip type checking`,
597
- ...lines,
598
- ...resolvedDeclares
599
- ].join("\n");
600
- }
601
- function parseMetaEntry(file, content) {
602
- const extname3 = path5.extname(file);
603
- try {
604
- if (extname3 === ".json") return JSON.parse(content);
605
- if (extname3 === ".yaml") return (0, import_js_yaml2.load)(content);
606
- } catch (e) {
607
- throw new Error(`Failed to parse meta file: ${file}.`, {
608
- cause: e
609
- });
610
- }
611
- throw new Error(`Unknown meta file format: ${extname3}, in ${file}.`);
612
- }
613
- async function globCollectionFiles(collection) {
614
- const { glob } = await import("tinyglobby");
615
- const files = /* @__PURE__ */ new Map();
616
- const dirs = Array.isArray(collection.dir) ? collection.dir : [collection.dir];
617
- await Promise.all(
618
- dirs.map(async (dir) => {
619
- const result = await glob(collection.patterns, {
620
- cwd: path5.resolve(dir)
621
- });
622
- for (const item of result) {
623
- if (!collection.isFileSupported(item)) continue;
624
- const fullPath = path5.join(dir, item);
625
- files.set(fullPath, {
626
- path: item,
627
- fullPath
628
- });
629
- }
630
- })
631
- );
632
- return Array.from(files.values());
633
- }
634
- var path5, import_node_crypto, import_js_yaml2;
635
- var init_next = __esm({
636
- "src/plugins/next.ts"() {
637
- "use strict";
638
- path5 = __toESM(require("path"), 1);
639
- import_node_crypto = require("crypto");
640
- init_validation();
641
- init_file_cache();
642
- init_git_timestamp();
643
- init_fuma_matter();
644
- init_import_formatter();
645
- import_js_yaml2 = require("js-yaml");
646
910
  }
647
- });
648
-
649
- // src/core.ts
650
- function findConfigFile() {
651
- return import_node_path4.default.resolve("source.config.ts");
911
+ await codegen.pushAsync(
912
+ core.getConfig().collectionList.map(async (collection) => {
913
+ const obj = await generateCollectionObject(collection);
914
+ if (!obj) return;
915
+ return `
916
+ export const ${collection.name} = ${obj};`;
917
+ })
918
+ );
652
919
  }
653
- function createCore(options, defaultPlugins = []) {
654
- let config;
655
- let plugins2;
656
- return {
657
- _options: options,
658
- getPluginContext() {
659
- return {
660
- core: this,
661
- ...options
662
- };
663
- },
664
- /**
665
- * Convenient cache store, reset when config changes
666
- */
667
- cache: /* @__PURE__ */ new Map(),
668
- async init({ config: newConfig }) {
669
- config = await newConfig;
670
- this.cache.clear();
671
- plugins2 = [];
672
- for await (const option of [
673
- ...defaultPlugins,
674
- ...config.global.plugins ?? []
675
- ]) {
676
- if (!option) continue;
677
- if (Array.isArray(option)) plugins2.push(...option);
678
- else plugins2.push(option);
679
- }
680
- for (const plugin of plugins2) {
681
- const out = await plugin.config?.call(this.getPluginContext(), config);
682
- if (out) config = out;
920
+ async function generateBrowserIndexFile({ core, codegen, tc }) {
921
+ codegen.lines.push(
922
+ `import { browser } from 'fumadocs-mdx/runtime/browser';`,
923
+ `import type * as Config from '${codegen.formatImportPath(core.getOptions().configPath)}';`,
924
+ "",
925
+ `const create = browser<typeof Config, ${tc}>();`
926
+ );
927
+ async function generateCollectionObject(collection) {
928
+ switch (collection.type) {
929
+ case "docs": {
930
+ if (collection.docs.dynamic) return;
931
+ return generateCollectionObject(collection.docs);
683
932
  }
684
- return this;
933
+ case "doc":
934
+ if (collection.dynamic) return;
935
+ return `create.doc("${collection.name}", ${await generateDocCollectionGlob(codegen, collection)})`;
936
+ }
937
+ }
938
+ codegen.lines.push("const browserCollections = {");
939
+ await codegen.pushAsync(
940
+ core.getConfig().collectionList.map(async (collection) => {
941
+ const obj = await generateCollectionObject(collection);
942
+ if (!obj) return;
943
+ return ident(`${collection.name}: ${obj},`);
944
+ })
945
+ );
946
+ codegen.lines.push("};", "export default browserCollections;");
947
+ }
948
+ function generateDocCollectionFrontmatterGlob(codegen, collection, eager = false) {
949
+ return codegen.generateGlobImport(collection.patterns, {
950
+ query: {
951
+ collection: collection.name,
952
+ only: "frontmatter"
685
953
  },
686
- getConfig() {
687
- return config;
954
+ import: "frontmatter",
955
+ base: collection.dir,
956
+ eager
957
+ });
958
+ }
959
+ function generateDocCollectionGlob(codegen, collection, eager = false) {
960
+ return codegen.generateGlobImport(collection.patterns, {
961
+ query: {
962
+ collection: collection.name
688
963
  },
689
- async initServer(server) {
690
- for (const plugin of plugins2) {
691
- await plugin.configureServer?.call(this.getPluginContext(), server);
692
- }
964
+ base: collection.dir,
965
+ eager
966
+ });
967
+ }
968
+ function generateMetaCollectionGlob(codegen, collection, eager = false) {
969
+ return codegen.generateGlobImport(collection.patterns, {
970
+ query: {
971
+ collection: collection.name
693
972
  },
694
- async emitAndWrite({
695
- filterPlugin = () => true
696
- } = {}) {
697
- const start2 = performance.now();
698
- const out = await Promise.all(
699
- plugins2.map((plugin) => {
700
- if (!filterPlugin(plugin) || !plugin.emit) return [];
701
- return plugin.emit.call(this.getPluginContext());
702
- })
703
- );
704
- await Promise.all(
705
- out.flat().map(async (entry) => {
706
- const file = import_node_path4.default.join(options.outDir, entry.path);
707
- await import_promises2.default.mkdir(import_node_path4.default.dirname(file), { recursive: true });
708
- await import_promises2.default.writeFile(file, entry.content);
709
- })
710
- );
711
- console.log(`[MDX] generated files in ${performance.now() - start2}ms`);
712
- }
713
- };
973
+ import: "default",
974
+ base: collection.dir,
975
+ eager
976
+ });
714
977
  }
715
- var import_node_path4, import_promises2;
716
- var init_core = __esm({
717
- "src/core.ts"() {
718
- "use strict";
719
- import_node_path4 = __toESM(require("path"), 1);
720
- import_promises2 = __toESM(require("fs/promises"), 1);
721
- }
722
- });
723
-
724
- // src/loaders/index.ts
725
- var metaLoaderGlob, mdxLoaderGlob;
726
- var init_loaders = __esm({
727
- "src/loaders/index.ts"() {
978
+ var import_path, import_tinyglobby2, import_crypto;
979
+ var init_index_file = __esm({
980
+ "src/plugins/index-file.ts"() {
728
981
  "use strict";
729
- metaLoaderGlob = /\.(json|yaml)(\?.+?)?$/;
730
- mdxLoaderGlob = /\.mdx?(\?.+?)?$/;
982
+ import_path = __toESM(require("path"), 1);
983
+ init_codegen();
984
+ import_tinyglobby2 = require("tinyglobby");
985
+ init_fs_cache();
986
+ import_crypto = require("crypto");
987
+ init_fuma_matter();
731
988
  }
732
989
  });
733
990
 
@@ -738,15 +995,16 @@ __export(next_exports, {
738
995
  postInstall: () => postInstall
739
996
  });
740
997
  function createMDX(createOptions = {}) {
741
- const options = applyDefaults(createOptions);
998
+ const core = createNextCore(applyDefaults(createOptions));
742
999
  const isDev = process.env.NODE_ENV === "development";
743
1000
  if (process.env._FUMADOCS_MDX !== "1") {
744
1001
  process.env._FUMADOCS_MDX = "1";
745
- void init(isDev, options);
1002
+ void init(isDev, core);
746
1003
  }
747
1004
  return (nextConfig = {}) => {
748
1005
  const loaderOptions = {
749
- ...options,
1006
+ ...core.getOptions(),
1007
+ compiledConfigPath: core.getCompiledConfigPath(),
750
1008
  isDev
751
1009
  };
752
1010
  const turbopack = {
@@ -761,6 +1019,24 @@ function createMDX(createOptions = {}) {
761
1019
  }
762
1020
  ],
763
1021
  as: "*.js"
1022
+ },
1023
+ "*.json": {
1024
+ loaders: [
1025
+ {
1026
+ loader: "fumadocs-mdx/loader-meta",
1027
+ options: loaderOptions
1028
+ }
1029
+ ],
1030
+ as: "*.json"
1031
+ },
1032
+ "*.yaml": {
1033
+ loaders: [
1034
+ {
1035
+ loader: "fumadocs-mdx/loader-meta",
1036
+ options: loaderOptions
1037
+ }
1038
+ ],
1039
+ as: "*.js"
764
1040
  }
765
1041
  }
766
1042
  };
@@ -768,42 +1044,54 @@ function createMDX(createOptions = {}) {
768
1044
  ...nextConfig,
769
1045
  turbopack,
770
1046
  pageExtensions: nextConfig.pageExtensions ?? defaultPageExtensions,
771
- webpack: (config, options2) => {
1047
+ webpack: (config, options) => {
772
1048
  config.resolve ||= {};
773
1049
  config.module ||= {};
774
1050
  config.module.rules ||= [];
775
- config.module.rules.push({
776
- test: mdxLoaderGlob,
777
- use: [
778
- options2.defaultLoaders.babel,
779
- {
780
- loader: "fumadocs-mdx/loader-mdx",
781
- options: loaderOptions
782
- }
783
- ]
784
- });
1051
+ config.module.rules.push(
1052
+ {
1053
+ test: mdxLoaderGlob,
1054
+ use: [
1055
+ options.defaultLoaders.babel,
1056
+ {
1057
+ loader: "fumadocs-mdx/loader-mdx",
1058
+ options: loaderOptions
1059
+ }
1060
+ ]
1061
+ },
1062
+ {
1063
+ test: metaLoaderGlob,
1064
+ use: [
1065
+ options.defaultLoaders.babel,
1066
+ {
1067
+ loader: "fumadocs-mdx/loader-meta",
1068
+ options: loaderOptions
1069
+ }
1070
+ ]
1071
+ }
1072
+ );
785
1073
  config.plugins ||= [];
786
- return nextConfig.webpack?.(config, options2) ?? config;
1074
+ return nextConfig.webpack?.(config, options) ?? config;
787
1075
  }
788
1076
  };
789
1077
  };
790
1078
  }
791
- async function init(dev, options) {
792
- const core = createNextCore(options);
1079
+ async function init(dev, core) {
793
1080
  async function initOrReload() {
794
1081
  await core.init({
795
- config: loadConfig(options.configPath, options.outDir, true)
1082
+ config: loadConfig(core, true)
796
1083
  });
797
1084
  await core.emitAndWrite();
798
1085
  }
799
1086
  async function devServer() {
800
1087
  const { FSWatcher } = await import("chokidar");
1088
+ const { configPath, outDir } = core.getOptions();
801
1089
  const watcher = new FSWatcher({
802
1090
  ignoreInitial: true,
803
1091
  persistent: true,
804
- ignored: [options.outDir]
1092
+ ignored: [outDir]
805
1093
  });
806
- watcher.add(options.configPath);
1094
+ watcher.add(configPath);
807
1095
  for (const collection of core.getConfig().collectionList) {
808
1096
  if (collection.type === "docs") {
809
1097
  watcher.add(collection.docs.dir);
@@ -815,10 +1103,9 @@ async function init(dev, options) {
815
1103
  watcher.on("ready", () => {
816
1104
  console.log("[MDX] started dev server");
817
1105
  });
818
- watcher.on("all", async (event, file) => {
819
- const absolutePath = path7.resolve(file);
820
- if (event === "change") removeFileCache(absolutePath);
821
- if (absolutePath === path7.resolve(options.configPath)) {
1106
+ const absoluteConfigPath = path5.resolve(configPath);
1107
+ watcher.on("all", async (_event, file) => {
1108
+ if (path5.resolve(file) === absoluteConfigPath) {
822
1109
  watcher.removeAllListeners();
823
1110
  await watcher.close();
824
1111
  await initOrReload();
@@ -838,32 +1125,28 @@ async function init(dev, options) {
838
1125
  await devServer();
839
1126
  }
840
1127
  }
841
- async function postInstall(configPath = findConfigFile(), outDir = ".source") {
842
- const core = await createNextCore({
843
- outDir,
844
- configPath
845
- }).init({
846
- config: loadConfig(configPath, outDir, true)
1128
+ async function postInstall(options) {
1129
+ const core = createNextCore(applyDefaults(options));
1130
+ await core.init({
1131
+ config: loadConfig(core, true)
847
1132
  });
848
1133
  await core.emitAndWrite();
849
1134
  }
850
1135
  function applyDefaults(options) {
851
1136
  return {
852
- outDir: options.outDir ?? ".source",
853
- configPath: options.configPath ?? findConfigFile()
1137
+ index: {},
1138
+ outDir: options.outDir ?? _Defaults.outDir,
1139
+ configPath: options.configPath ?? _Defaults.configPath
854
1140
  };
855
1141
  }
856
- function createNextCore({
857
- outDir,
858
- configPath
859
- }) {
1142
+ function createNextCore(options) {
860
1143
  const core = createCore(
861
1144
  {
862
1145
  environment: "next",
863
- outDir,
864
- configPath
1146
+ outDir: options.outDir,
1147
+ configPath: options.configPath
865
1148
  },
866
- [next()]
1149
+ [options.index && indexFile(options.index)]
867
1150
  );
868
1151
  return {
869
1152
  ...core,
@@ -872,7 +1155,7 @@ function createNextCore({
872
1155
  await core.emitAndWrite(...args);
873
1156
  } catch (err) {
874
1157
  if (err instanceof ValidationError) {
875
- console.error(err.toStringFormatted());
1158
+ console.error(await err.toStringFormatted());
876
1159
  } else {
877
1160
  console.error(err);
878
1161
  }
@@ -880,17 +1163,16 @@ function createNextCore({
880
1163
  }
881
1164
  };
882
1165
  }
883
- var path7, defaultPageExtensions;
884
- var init_next2 = __esm({
1166
+ var path5, defaultPageExtensions;
1167
+ var init_next = __esm({
885
1168
  "src/next/index.ts"() {
886
1169
  "use strict";
887
- path7 = __toESM(require("path"), 1);
1170
+ path5 = __toESM(require("path"), 1);
888
1171
  init_load_from_file();
889
- init_file_cache();
890
1172
  init_validation();
891
- init_next();
892
1173
  init_core();
893
1174
  init_loaders();
1175
+ init_index_file();
894
1176
  defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
895
1177
  }
896
1178
  });
@@ -945,6 +1227,19 @@ var init_remark_unravel = __esm({
945
1227
  }
946
1228
  });
947
1229
 
1230
+ // src/loaders/mdx/mdast-utils.ts
1231
+ function flattenNode(node) {
1232
+ if ("children" in node)
1233
+ return node.children.map((child) => flattenNode(child)).join("");
1234
+ if ("value" in node) return node.value;
1235
+ return "";
1236
+ }
1237
+ var init_mdast_utils = __esm({
1238
+ "src/loaders/mdx/mdast-utils.ts"() {
1239
+ "use strict";
1240
+ }
1241
+ });
1242
+
948
1243
  // src/loaders/mdx/remark-include.ts
949
1244
  function isElementLike(node) {
950
1245
  return ElementLikeTypes.includes(node.type);
@@ -961,12 +1256,6 @@ function parseElementAttributes(element) {
961
1256
  }
962
1257
  return element.attributes ?? {};
963
1258
  }
964
- function flattenNode(node) {
965
- if ("children" in node)
966
- return node.children.map((child) => flattenNode(child)).join("");
967
- if ("value" in node) return node.value;
968
- return "";
969
- }
970
1259
  function parseSpecifier(specifier) {
971
1260
  const idx = specifier.lastIndexOf("#");
972
1261
  if (idx === -1) return { file: specifier };
@@ -1021,7 +1310,7 @@ ${e instanceof Error ? e.message : String(e)}`,
1021
1310
  { cause: e }
1022
1311
  );
1023
1312
  }
1024
- const ext = path8.extname(file);
1313
+ const ext = path6.extname(file);
1025
1314
  data._compiler?.addDependency(file);
1026
1315
  if (params.lang || ext !== ".md" && ext !== ".mdx") {
1027
1316
  const lang = params.lang ?? ext.slice(1);
@@ -1054,7 +1343,7 @@ ${e instanceof Error ? e.message : String(e)}`,
1054
1343
  } else {
1055
1344
  mdast = await baseProcessor.run(mdast);
1056
1345
  }
1057
- await update(mdast, path8.dirname(file), data);
1346
+ await update(mdast, path6.dirname(file), data);
1058
1347
  return mdast;
1059
1348
  };
1060
1349
  async function update(tree, directory, data) {
@@ -1066,7 +1355,7 @@ ${e instanceof Error ? e.message : String(e)}`,
1066
1355
  if (specifier.length === 0) return "skip";
1067
1356
  const attributes = parseElementAttributes(node);
1068
1357
  const { file: relativePath, section } = parseSpecifier(specifier);
1069
- const file = path8.resolve(
1358
+ const file = path6.resolve(
1070
1359
  "cwd" in attributes ? process.cwd() : directory,
1071
1360
  relativePath
1072
1361
  );
@@ -1083,20 +1372,21 @@ ${e instanceof Error ? e.message : String(e)}`,
1083
1372
  await Promise.all(queue);
1084
1373
  }
1085
1374
  return async (tree, file) => {
1086
- await update(tree, path8.dirname(file.path), file.data);
1375
+ await update(tree, path6.dirname(file.path), file.data);
1087
1376
  };
1088
1377
  }
1089
- var import_unified, import_unist_util_visit2, path8, fs3, import_mdx_plugins, ElementLikeTypes;
1378
+ var import_unified, import_unist_util_visit2, path6, fs3, import_mdx_plugins, ElementLikeTypes;
1090
1379
  var init_remark_include = __esm({
1091
1380
  "src/loaders/mdx/remark-include.ts"() {
1092
1381
  "use strict";
1093
1382
  import_unified = require("unified");
1094
1383
  import_unist_util_visit2 = require("unist-util-visit");
1095
- path8 = __toESM(require("path"), 1);
1384
+ path6 = __toESM(require("path"), 1);
1096
1385
  fs3 = __toESM(require("fs/promises"), 1);
1097
1386
  init_fuma_matter();
1098
1387
  import_mdx_plugins = require("fumadocs-core/mdx-plugins");
1099
1388
  init_remark_unravel();
1389
+ init_mdast_utils();
1100
1390
  ElementLikeTypes = [
1101
1391
  "mdxJsxFlowElement",
1102
1392
  "mdxJsxTextElement",
@@ -1112,48 +1402,66 @@ function remarkPostprocess({
1112
1402
  _format,
1113
1403
  includeProcessedMarkdown = false,
1114
1404
  includeMDAST = false,
1405
+ extractLinkReferences = false,
1115
1406
  valueToExport = []
1116
1407
  }) {
1117
1408
  let _stringifyProcessor;
1118
1409
  const getStringifyProcessor = () => {
1119
- if (_format === "mdx") return this;
1120
- return _stringifyProcessor ??= this().use(import_remark_mdx.default).freeze();
1410
+ return _stringifyProcessor ??= _format === "mdx" ? this : (
1411
+ // force Markdown processor to stringify MDX nodes
1412
+ this().use(import_remark_mdx.default).freeze()
1413
+ );
1121
1414
  };
1122
1415
  return (tree, file) => {
1123
- let title;
1124
- const urls = [];
1125
- (0, import_unist_util_visit3.visit)(tree, ["heading", "link"], (node) => {
1126
- if (node.type === "heading" && node.depth === 1) {
1127
- title = flattenNode2(node);
1128
- }
1129
- if (node.type !== "link") return;
1130
- urls.push({
1131
- href: node.url
1416
+ const frontmatter = file.data.frontmatter ??= {};
1417
+ if (!frontmatter.title) {
1418
+ (0, import_unist_util_visit3.visit)(tree, "heading", (node) => {
1419
+ if (node.depth === 1) {
1420
+ frontmatter.title = flattenNode(node);
1421
+ return false;
1422
+ }
1423
+ });
1424
+ }
1425
+ file.data["mdx-export"] ??= [];
1426
+ if (extractLinkReferences) {
1427
+ const urls = [];
1428
+ (0, import_unist_util_visit3.visit)(tree, "link", (node) => {
1429
+ urls.push({
1430
+ href: node.url
1431
+ });
1432
+ return "skip";
1433
+ });
1434
+ file.data["mdx-export"].push({
1435
+ name: "extractedReferences",
1436
+ value: urls
1132
1437
  });
1133
- return "skip";
1134
- });
1135
- if (title) {
1136
- file.data.frontmatter ??= {};
1137
- if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
1138
1438
  }
1139
- file.data.extractedReferences = urls;
1140
1439
  if (includeProcessedMarkdown) {
1141
1440
  const processor = getStringifyProcessor();
1142
- file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
1441
+ const markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
1143
1442
  ...processor.data("settings"),
1144
1443
  // from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
1145
1444
  extensions: processor.data("toMarkdownExtensions") || []
1146
1445
  });
1446
+ file.data["mdx-export"].push({
1447
+ name: "_markdown",
1448
+ value: markdown
1449
+ });
1147
1450
  }
1148
1451
  if (includeMDAST) {
1149
1452
  const options = includeMDAST === true ? {} : includeMDAST;
1150
- file.data._mdast = JSON.stringify(
1453
+ const mdast = JSON.stringify(
1151
1454
  options.removePosition ? (0, import_unist_util_remove_position.removePosition)(structuredClone(tree)) : tree
1152
1455
  );
1456
+ file.data["mdx-export"].push({
1457
+ name: "_mdast",
1458
+ value: mdast
1459
+ });
1153
1460
  }
1154
- for (const { name, value } of file.data["mdx-export"] ?? []) {
1461
+ for (const { name, value } of file.data["mdx-export"]) {
1155
1462
  tree.children.unshift(getMdastExport(name, value));
1156
1463
  }
1464
+ file.data["mdx-export"] = [];
1157
1465
  for (const name of valueToExport) {
1158
1466
  if (!(name in file.data)) continue;
1159
1467
  tree.children.unshift(getMdastExport(name, file.data[name]));
@@ -1194,12 +1502,6 @@ function getMdastExport(name, value) {
1194
1502
  }
1195
1503
  };
1196
1504
  }
1197
- function flattenNode2(node) {
1198
- if ("children" in node)
1199
- return node.children.map((child) => flattenNode2(child)).join("");
1200
- if ("value" in node) return node.value;
1201
- return "";
1202
- }
1203
1505
  var import_unist_util_visit3, import_mdast_util_to_markdown, import_estree_util_value_to_estree, import_unist_util_remove_position, import_remark_mdx;
1204
1506
  var init_remark_postprocess = __esm({
1205
1507
  "src/loaders/mdx/remark-postprocess.ts"() {
@@ -1209,66 +1511,71 @@ var init_remark_postprocess = __esm({
1209
1511
  import_estree_util_value_to_estree = require("estree-util-value-to-estree");
1210
1512
  import_unist_util_remove_position = require("unist-util-remove-position");
1211
1513
  import_remark_mdx = __toESM(require("remark-mdx"), 1);
1514
+ init_mdast_utils();
1212
1515
  }
1213
1516
  });
1214
1517
 
1215
1518
  // src/loaders/mdx/build-mdx.ts
1216
- async function buildMDX(cacheKey, source, options) {
1217
- const { filePath, frontmatter, data, _compiler, ...rest } = options;
1519
+ var build_mdx_exports = {};
1520
+ __export(build_mdx_exports, {
1521
+ buildMDX: () => buildMDX
1522
+ });
1523
+ async function buildMDX(core, collection, {
1524
+ filePath,
1525
+ frontmatter,
1526
+ source,
1527
+ _compiler,
1528
+ environment,
1529
+ isDevelopment
1530
+ }) {
1531
+ const mdxOptions = await core.getConfig().getMDXOptions(collection, environment);
1218
1532
  function getProcessor(format) {
1219
- const key = `${cacheKey}:${format}`;
1220
- let processor = cache2.get(key);
1533
+ const cache = core.cache;
1534
+ const key = `build-mdx:${collection?.name ?? "global"}:${format}`;
1535
+ let processor = cache.get(key);
1221
1536
  if (!processor) {
1537
+ const postprocessOptions = {
1538
+ _format: format,
1539
+ ...collection?.postprocess,
1540
+ valueToExport: [
1541
+ ...collection?.postprocess?.valueToExport ?? [],
1542
+ "structuredData",
1543
+ "frontmatter"
1544
+ ]
1545
+ };
1222
1546
  processor = (0, import_mdx.createProcessor)({
1223
1547
  outputFormat: "program",
1224
- ...rest,
1548
+ development: isDevelopment,
1549
+ ...mdxOptions,
1225
1550
  remarkPlugins: [
1226
1551
  remarkInclude,
1227
- ...rest.remarkPlugins ?? [],
1228
- [
1229
- remarkPostprocess,
1230
- {
1231
- _format: format,
1232
- ...options.postprocess,
1233
- valueToExport: [
1234
- ...options.postprocess?.valueToExport ?? [],
1235
- "structuredData",
1236
- "extractedReferences",
1237
- "frontmatter",
1238
- "lastModified",
1239
- "_markdown",
1240
- "_mdast"
1241
- ]
1242
- }
1243
- ]
1552
+ ...mdxOptions.remarkPlugins ?? [],
1553
+ [remarkPostprocess, postprocessOptions]
1244
1554
  ],
1245
1555
  format
1246
1556
  });
1247
- cache2.set(key, processor);
1557
+ cache.set(key, processor);
1248
1558
  }
1249
1559
  return processor;
1250
1560
  }
1251
- return getProcessor(
1252
- options.format ?? (filePath.endsWith(".mdx") ? "mdx" : "md")
1253
- ).process({
1561
+ let vfile = new import_vfile.VFile({
1254
1562
  value: source,
1255
1563
  path: filePath,
1256
- data: {
1257
- ...data,
1258
- frontmatter,
1259
- _compiler,
1260
- _getProcessor: getProcessor
1261
- }
1564
+ data: { frontmatter, _compiler, _getProcessor: getProcessor }
1262
1565
  });
1566
+ if (collection) {
1567
+ vfile = await core.transformVFile({ collection, filePath, source }, vfile);
1568
+ }
1569
+ return getProcessor(filePath.endsWith(".mdx") ? "mdx" : "md").process(vfile);
1263
1570
  }
1264
- var import_mdx, cache2;
1571
+ var import_mdx, import_vfile;
1265
1572
  var init_build_mdx = __esm({
1266
1573
  "src/loaders/mdx/build-mdx.ts"() {
1267
1574
  "use strict";
1268
1575
  import_mdx = require("@mdx-js/mdx");
1576
+ import_vfile = require("vfile");
1269
1577
  init_remark_include();
1270
1578
  init_remark_postprocess();
1271
- cache2 = /* @__PURE__ */ new Map();
1272
1579
  }
1273
1580
  });
1274
1581
 
@@ -1283,20 +1590,20 @@ function createMdxLoader(configLoader) {
1283
1590
  compiler,
1284
1591
  filePath
1285
1592
  }) {
1593
+ const config = await configLoader.getConfig();
1286
1594
  const value = await getSource();
1287
1595
  const matter = fumaMatter(value);
1288
1596
  const parsed = querySchema.parse(query);
1289
- const config = await configLoader.getConfig();
1290
1597
  let after;
1291
1598
  if (!isDevelopment && config.global.experimentalBuildCache) {
1292
1599
  const cacheDir = config.global.experimentalBuildCache;
1293
1600
  const cacheKey = `${parsed.hash}_${parsed.collection ?? "global"}_${generateCacheHash(filePath)}`;
1294
- const cached = await import_promises3.default.readFile(import_node_path5.default.join(cacheDir, cacheKey)).then((content) => cacheEntry.parse(JSON.parse(content.toString()))).catch(() => null);
1601
+ const cached = await import_promises3.default.readFile(import_node_path4.default.join(cacheDir, cacheKey)).then((content) => cacheEntry.parse(JSON.parse(content.toString()))).catch(() => null);
1295
1602
  if (cached && cached.hash === generateCacheHash(value)) return cached;
1296
1603
  after = async () => {
1297
1604
  await import_promises3.default.mkdir(cacheDir, { recursive: true });
1298
1605
  await import_promises3.default.writeFile(
1299
- import_node_path5.default.join(cacheDir, cacheKey),
1606
+ import_node_path4.default.join(cacheDir, cacheKey),
1300
1607
  JSON.stringify({
1301
1608
  ...out,
1302
1609
  hash: generateCacheHash(value)
@@ -1314,15 +1621,10 @@ function createMdxLoader(configLoader) {
1314
1621
  docCollection = collection.docs;
1315
1622
  break;
1316
1623
  }
1317
- if (docCollection?.schema) {
1318
- matter.data = await validate(
1319
- docCollection.schema,
1320
- matter.data,
1321
- {
1322
- source: value,
1323
- path: filePath
1324
- },
1325
- `invalid frontmatter in ${filePath}`
1624
+ if (docCollection) {
1625
+ matter.data = await configLoader.core.transformFrontmatter(
1626
+ { collection: docCollection, filePath, source: value },
1627
+ matter.data
1326
1628
  );
1327
1629
  }
1328
1630
  if (parsed.only === "frontmatter") {
@@ -1331,24 +1633,16 @@ function createMdxLoader(configLoader) {
1331
1633
  map: null
1332
1634
  };
1333
1635
  }
1334
- const data = {};
1335
- if (config.global.lastModifiedTime === "git") {
1336
- data.lastModified = (await getGitTimestamp(filePath))?.getTime();
1337
- }
1338
1636
  const lineOffset = isDevelopment ? countLines(matter.matter) : 0;
1339
- const compiled = await buildMDX(
1340
- `${getConfigHash(config)}:${parsed.collection ?? "global"}`,
1341
- "\n".repeat(lineOffset) + matter.content,
1342
- {
1343
- development: isDevelopment,
1344
- ...docCollection?.mdxOptions ?? await config.getDefaultMDXOptions(),
1345
- postprocess: docCollection?.postprocess,
1346
- data,
1347
- filePath,
1348
- frontmatter: matter.data,
1349
- _compiler: compiler
1350
- }
1351
- );
1637
+ const { buildMDX: buildMDX2 } = await Promise.resolve().then(() => (init_build_mdx(), build_mdx_exports));
1638
+ const compiled = await buildMDX2(configLoader.core, docCollection, {
1639
+ isDevelopment,
1640
+ source: "\n".repeat(lineOffset) + matter.content,
1641
+ filePath,
1642
+ frontmatter: matter.data,
1643
+ _compiler: compiler,
1644
+ environment: "bundler"
1645
+ });
1352
1646
  const out = {
1353
1647
  code: String(compiled.value),
1354
1648
  map: compiled.map
@@ -1358,15 +1652,8 @@ function createMdxLoader(configLoader) {
1358
1652
  }
1359
1653
  };
1360
1654
  }
1361
- function getConfigHash(config) {
1362
- let hash = hashes.get(config);
1363
- if (hash) return hash;
1364
- hash = Date.now().toString();
1365
- hashes.set(config, hash);
1366
- return hash;
1367
- }
1368
1655
  function generateCacheHash(input) {
1369
- return (0, import_node_crypto2.createHash)("md5").update(input).digest("hex");
1656
+ return (0, import_node_crypto.createHash)("md5").update(input).digest("hex");
1370
1657
  }
1371
1658
  function countLines(s) {
1372
1659
  let num = 0;
@@ -1375,18 +1662,15 @@ function countLines(s) {
1375
1662
  }
1376
1663
  return num;
1377
1664
  }
1378
- var import_zod, import_promises3, import_node_path5, import_node_crypto2, querySchema, cacheEntry, hashes;
1665
+ var import_zod, import_promises3, import_node_path4, import_node_crypto, querySchema, cacheEntry;
1379
1666
  var init_mdx = __esm({
1380
1667
  "src/loaders/mdx/index.ts"() {
1381
1668
  "use strict";
1382
1669
  init_fuma_matter();
1383
- init_validation();
1384
- init_git_timestamp();
1385
- init_build_mdx();
1386
1670
  import_zod = require("zod");
1387
1671
  import_promises3 = __toESM(require("fs/promises"), 1);
1388
- import_node_path5 = __toESM(require("path"), 1);
1389
- import_node_crypto2 = require("crypto");
1672
+ import_node_path4 = __toESM(require("path"), 1);
1673
+ import_node_crypto = require("crypto");
1390
1674
  init_loaders();
1391
1675
  querySchema = import_zod.z.object({
1392
1676
  only: import_zod.z.literal(["frontmatter", "all"]).default("all"),
@@ -1397,7 +1681,6 @@ var init_mdx = __esm({
1397
1681
  map: import_zod.z.any().optional(),
1398
1682
  hash: import_zod.z.string().optional()
1399
1683
  });
1400
- hashes = /* @__PURE__ */ new WeakMap();
1401
1684
  }
1402
1685
  });
1403
1686
 
@@ -1430,7 +1713,7 @@ function toVite(loader) {
1430
1713
  }
1431
1714
  };
1432
1715
  }
1433
- var import_node_url2, import_promises4, import_node_querystring, import_node_path6, import_node_fs;
1716
+ var import_node_url2, import_promises4, import_node_querystring, import_node_path5, import_node_fs;
1434
1717
  var init_adapter = __esm({
1435
1718
  "src/loaders/adapter.ts"() {
1436
1719
  "use strict";
@@ -1438,218 +1721,15 @@ var init_adapter = __esm({
1438
1721
  import_promises4 = __toESM(require("fs/promises"), 1);
1439
1722
  import_node_querystring = require("querystring");
1440
1723
  init_validation();
1441
- import_node_path6 = __toESM(require("path"), 1);
1724
+ import_node_path5 = __toESM(require("path"), 1);
1442
1725
  import_node_fs = require("fs");
1443
1726
  }
1444
1727
  });
1445
1728
 
1446
- // src/utils/glob-import.ts
1447
- function generateGlobImport(patterns, options) {
1448
- let code = "{";
1449
- const result = (0, import_tinyglobby.globSync)(patterns, {
1450
- cwd: options.base
1451
- });
1452
- for (const item of result) {
1453
- const fullPath = import_node_path7.default.join(options.base, item);
1454
- const url = (0, import_node_url3.pathToFileURL)(fullPath);
1455
- for (const [k, v] of Object.entries(options.query ?? {})) {
1456
- url.searchParams.set(k, v);
1457
- }
1458
- let line = `${JSON.stringify(item)}: () => import(${JSON.stringify(url.href)})`;
1459
- if (options.import) {
1460
- line += `.then(mod => mod[${JSON.stringify(options.import)}])`;
1461
- }
1462
- code += `${line}, `;
1463
- }
1464
- code += "}";
1465
- return code;
1466
- }
1467
- var import_tinyglobby, import_node_path7, import_node_url3;
1468
- var init_glob_import = __esm({
1469
- "src/utils/glob-import.ts"() {
1470
- "use strict";
1471
- import_tinyglobby = require("tinyglobby");
1472
- import_node_path7 = __toESM(require("path"), 1);
1473
- import_node_url3 = require("url");
1474
- }
1475
- });
1476
-
1477
- // src/plugins/vite.ts
1478
- function vite({
1479
- index
1480
- }) {
1481
- let config;
1482
- let indexOptions;
1483
- if (index === false) indexOptions = false;
1484
- else indexOptions = applyDefaults2(index === true ? {} : index);
1485
- return {
1486
- name: "vite",
1487
- config(v) {
1488
- config = v;
1489
- },
1490
- configureServer(server) {
1491
- if (!server.watcher || indexOptions === false || indexOptions.runtime === false)
1492
- return;
1493
- server.watcher.on("all", (event, file) => {
1494
- if (event === "change") return;
1495
- const isUpdated = config.collectionList.some((collection) => {
1496
- if (collection.type === "docs")
1497
- return collection.docs.hasFile(file) || collection.meta.hasFile(file);
1498
- return collection.hasFile(file);
1499
- });
1500
- if (isUpdated) {
1501
- this.core.emitAndWrite({
1502
- filterPlugin: (plugin) => plugin.name === "vite"
1503
- });
1504
- }
1505
- });
1506
- },
1507
- emit() {
1508
- const out = [];
1509
- if (indexOptions === false) return out;
1510
- if (indexOptions.browser) {
1511
- out.push({
1512
- path: "browser.ts",
1513
- content: indexFile2(this, config, indexOptions, "browser")
1514
- });
1515
- }
1516
- out.push({
1517
- path: "index.ts",
1518
- content: indexFile2(
1519
- this,
1520
- config,
1521
- indexOptions,
1522
- indexOptions.browser ? "server" : "all"
1523
- )
1524
- });
1525
- return out;
1526
- }
1527
- };
1528
- }
1529
- function applyDefaults2(options) {
1530
- return {
1531
- addJsExtension: options.addJsExtension ?? false,
1532
- browser: options.browser ?? false,
1533
- runtime: options.runtime ?? false
1534
- };
1535
- }
1536
- function indexFile2({ configPath, outDir }, config, { addJsExtension, runtime }, environment) {
1537
- const runtimePath = {
1538
- all: "fumadocs-mdx/runtime/vite",
1539
- server: "fumadocs-mdx/runtime/vite.server",
1540
- browser: "fumadocs-mdx/runtime/vite.browser"
1541
- }[environment];
1542
- const lines = [
1543
- '/// <reference types="vite/client" />',
1544
- `import { fromConfig } from '${runtimePath}';`,
1545
- `import type * as Config from '${toImportPath(configPath, {
1546
- relativeTo: outDir,
1547
- jsExtension: addJsExtension
1548
- })}';`,
1549
- "",
1550
- `export const create = fromConfig<typeof Config>();`
1551
- ];
1552
- function generateCollectionGlob(collection) {
1553
- if (collection.type === "docs") {
1554
- const obj = [
1555
- ident(`doc: ${generateCollectionGlob(collection.docs)}`),
1556
- ident(`meta: ${generateCollectionGlob(collection.meta)}`)
1557
- ].join(",\n");
1558
- return `{
1559
- ${obj}
1560
- }`;
1561
- }
1562
- const dir = getCollectionDir(collection);
1563
- if (collection.type === "doc") {
1564
- const docGlob = generateGlob(collection.patterns, {
1565
- query: {
1566
- collection: collection.name
1567
- },
1568
- base: dir
1569
- });
1570
- if (collection.async) {
1571
- const headBlob = generateGlob(collection.patterns, {
1572
- query: {
1573
- only: "frontmatter",
1574
- collection: collection.name
1575
- },
1576
- import: "frontmatter",
1577
- base: dir
1578
- });
1579
- return `create.docLazy("${collection.name}", "${dir}", ${headBlob}, ${docGlob})`;
1580
- }
1581
- return `create.doc("${collection.name}", "${dir}", ${docGlob})`;
1582
- }
1583
- return `create.meta("${collection.name}", "${dir}", ${generateGlob(
1584
- collection.patterns,
1585
- {
1586
- import: "default",
1587
- base: dir,
1588
- query: {
1589
- collection: collection.name
1590
- }
1591
- }
1592
- )})`;
1593
- }
1594
- function generateGlob(patterns, options) {
1595
- patterns = patterns.map(normalizeGlobPath);
1596
- if (runtime === "node" || runtime === "bun") {
1597
- return generateGlobImport(patterns, options);
1598
- } else {
1599
- return `import.meta.glob(${JSON.stringify(patterns)}, ${JSON.stringify(
1600
- {
1601
- ...options,
1602
- base: normalizeGlobPath(import_node_path8.default.relative(outDir, options.base))
1603
- },
1604
- null,
1605
- 2
1606
- )})`;
1607
- }
1608
- }
1609
- for (const collection of config.collectionList) {
1610
- lines.push("");
1611
- lines.push(
1612
- `export const ${collection.name} = ${generateCollectionGlob(collection)};`
1613
- );
1614
- }
1615
- return lines.join("\n");
1616
- }
1617
- function normalizeGlobPath(file) {
1618
- file = slash(file);
1619
- if (file.startsWith("./")) return file;
1620
- if (file.startsWith("/")) return `.${file}`;
1621
- return `./${file}`;
1622
- }
1623
- function getCollectionDir({ dir }) {
1624
- if (Array.isArray(dir)) {
1625
- if (dir.length !== 1)
1626
- throw new Error(
1627
- `[Fumadocs MDX] Vite Plugin doesn't support multiple \`dir\` for a collection at the moment.`
1628
- );
1629
- return dir[0];
1630
- }
1631
- return dir;
1632
- }
1633
- function slash(path13) {
1634
- const isExtendedLengthPath = path13.startsWith("\\\\?\\");
1635
- if (isExtendedLengthPath) {
1636
- return path13;
1637
- }
1638
- return path13.replaceAll("\\", "/");
1639
- }
1640
- var import_node_path8;
1641
- var init_vite = __esm({
1642
- "src/plugins/vite.ts"() {
1643
- "use strict";
1644
- init_import_formatter();
1645
- init_glob_import();
1646
- import_node_path8 = __toESM(require("path"), 1);
1647
- }
1648
- });
1649
-
1650
1729
  // src/loaders/config.ts
1651
1730
  function createIntegratedConfigLoader(core) {
1652
1731
  return {
1732
+ core,
1653
1733
  getConfig() {
1654
1734
  return core.getConfig();
1655
1735
  }
@@ -1664,73 +1744,82 @@ var init_config = __esm({
1664
1744
  });
1665
1745
 
1666
1746
  // src/loaders/meta.ts
1667
- function createMetaLoader(configLoader, resolve5 = {}) {
1668
- const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve5;
1669
- function stringifyOutput(isJson, data) {
1670
- if (isJson) {
1671
- return resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}`;
1672
- } else {
1673
- return resolveYaml === "yaml" ? (0, import_js_yaml3.dump)(data) : `export default ${JSON.stringify(data)}`;
1747
+ function createMetaLoader(configLoader, resolve3 = {}) {
1748
+ const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve3;
1749
+ function parse2(filePath, source) {
1750
+ try {
1751
+ if (filePath.endsWith(".json")) return JSON.parse(source);
1752
+ if (filePath.endsWith(".yaml")) return (0, import_js_yaml2.load)(source);
1753
+ } catch (e) {
1754
+ throw new Error(`invalid data in ${filePath}`, { cause: e });
1674
1755
  }
1756
+ throw new Error("Unknown file type " + filePath);
1675
1757
  }
1676
- return {
1677
- test: metaLoaderGlob,
1678
- async load({ filePath, query, getSource }) {
1679
- const parsed = querySchema2.parse(query);
1680
- const collection = parsed.collection ? (await configLoader.getConfig()).getCollection(parsed.collection) : void 0;
1681
- if (!collection) return null;
1682
- const isJson = filePath.endsWith(".json");
1683
- const source = await getSource();
1684
- let data;
1685
- try {
1686
- data = isJson ? JSON.parse(source) : (0, import_js_yaml3.load)(source);
1687
- } catch (e) {
1688
- throw new Error(`invalid data in ${filePath}`, { cause: e });
1689
- }
1690
- let schema;
1758
+ function onMeta(source, { filePath, query }) {
1759
+ const parsed = querySchema2.safeParse(query);
1760
+ if (!parsed.success || !parsed.data.collection) return null;
1761
+ const collectionName = parsed.data.collection;
1762
+ return async () => {
1763
+ const config = await configLoader.getConfig();
1764
+ const collection = config.getCollection(collectionName);
1765
+ let metaCollection;
1691
1766
  switch (collection?.type) {
1692
1767
  case "meta":
1693
- schema = collection.schema;
1768
+ metaCollection = collection;
1694
1769
  break;
1695
1770
  case "docs":
1696
- schema = collection.meta.schema;
1771
+ metaCollection = collection.meta;
1697
1772
  break;
1698
1773
  }
1699
- if (schema) {
1700
- data = await validate(
1701
- schema,
1702
- data,
1703
- { path: filePath, source },
1704
- `invalid data in ${filePath}`
1705
- );
1774
+ const data = parse2(filePath, source);
1775
+ if (!metaCollection) return data;
1776
+ return configLoader.core.transformMeta(
1777
+ {
1778
+ collection: metaCollection,
1779
+ filePath,
1780
+ source
1781
+ },
1782
+ data
1783
+ );
1784
+ };
1785
+ }
1786
+ return {
1787
+ test: metaLoaderGlob,
1788
+ async load(input) {
1789
+ const result = onMeta(await input.getSource(), input);
1790
+ if (result === null) return null;
1791
+ const data = await result();
1792
+ if (input.filePath.endsWith(".json")) {
1793
+ return {
1794
+ code: resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}`
1795
+ };
1796
+ } else {
1797
+ return {
1798
+ code: resolveYaml === "yaml" ? (0, import_js_yaml2.dump)(data) : `export default ${JSON.stringify(data)}`
1799
+ };
1706
1800
  }
1707
- return {
1708
- code: stringifyOutput(isJson, data)
1709
- };
1710
1801
  },
1711
1802
  bun: {
1712
- loadSync(source, { filePath }) {
1713
- const isJson = filePath.endsWith(".json");
1714
- let data;
1715
- try {
1716
- data = isJson ? JSON.parse(source) : (0, import_js_yaml3.load)(source);
1717
- } catch (e) {
1718
- throw new Error(`invalid data in ${filePath}`, { cause: e });
1719
- }
1720
- return {
1803
+ load(source, input) {
1804
+ const result = onMeta(source, input);
1805
+ if (result === null)
1806
+ return {
1807
+ loader: "object",
1808
+ exports: parse2(input.filePath, source)
1809
+ };
1810
+ return result().then((data) => ({
1721
1811
  loader: "object",
1722
- exports: data
1723
- };
1812
+ exports: { default: data }
1813
+ }));
1724
1814
  }
1725
1815
  }
1726
1816
  };
1727
1817
  }
1728
- var import_js_yaml3, import_zod2, querySchema2;
1818
+ var import_js_yaml2, import_zod2, querySchema2;
1729
1819
  var init_meta = __esm({
1730
1820
  "src/loaders/meta.ts"() {
1731
1821
  "use strict";
1732
- import_js_yaml3 = require("js-yaml");
1733
- init_validation();
1822
+ import_js_yaml2 = require("js-yaml");
1734
1823
  import_zod2 = require("zod");
1735
1824
  init_loaders();
1736
1825
  querySchema2 = import_zod2.z.object({
@@ -1746,8 +1835,9 @@ __export(vite_exports, {
1746
1835
  postInstall: () => postInstall2
1747
1836
  });
1748
1837
  async function mdx(config, pluginOptions = {}) {
1749
- const options = applyDefaults3(pluginOptions);
1750
- const core = await createViteCore(options).init({
1838
+ const options = applyDefaults2(pluginOptions);
1839
+ const core = createViteCore(options);
1840
+ await core.init({
1751
1841
  config: buildConfig(config)
1752
1842
  });
1753
1843
  const configLoader = createIntegratedConfigLoader(core);
@@ -1792,26 +1882,27 @@ async function mdx(config, pluginOptions = {}) {
1792
1882
  }
1793
1883
  } catch (e) {
1794
1884
  if (e instanceof ValidationError) {
1795
- throw new Error(e.toStringFormatted());
1885
+ throw new Error(await e.toStringFormatted());
1796
1886
  }
1797
1887
  throw e;
1798
1888
  }
1799
1889
  }
1800
1890
  };
1801
1891
  }
1802
- async function postInstall2(configPath = findConfigFile(), pluginOptions = {}) {
1892
+ async function postInstall2(pluginOptions = {}) {
1803
1893
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_load_from_file(), load_from_file_exports));
1804
- const options = applyDefaults3(pluginOptions);
1805
- const core = await createViteCore(options).init({
1806
- config: loadConfig2(configPath, options.outDir, true)
1894
+ const core = createViteCore(applyDefaults2(pluginOptions));
1895
+ await core.init({
1896
+ config: loadConfig2(core, true)
1807
1897
  });
1808
1898
  await core.emitAndWrite();
1809
1899
  }
1810
1900
  function createViteCore({
1901
+ index,
1811
1902
  configPath,
1812
- outDir,
1813
- generateIndexFile
1903
+ outDir
1814
1904
  }) {
1905
+ if (index === true) index = {};
1815
1906
  return createCore(
1816
1907
  {
1817
1908
  environment: "vite",
@@ -1819,22 +1910,23 @@ function createViteCore({
1819
1910
  outDir
1820
1911
  },
1821
1912
  [
1822
- vite({
1823
- index: generateIndexFile
1913
+ index && indexFile({
1914
+ ...index,
1915
+ target: index.target ?? "vite"
1824
1916
  })
1825
1917
  ]
1826
1918
  );
1827
1919
  }
1828
- function applyDefaults3(options) {
1920
+ function applyDefaults2(options) {
1829
1921
  return {
1830
1922
  updateViteConfig: options.updateViteConfig ?? true,
1831
- generateIndexFile: options.generateIndexFile ?? true,
1832
- configPath: options.configPath ?? "source.config.ts",
1833
- outDir: options.outDir ?? ".source"
1923
+ index: options.index ?? true,
1924
+ configPath: options.configPath ?? _Defaults.configPath,
1925
+ outDir: options.outDir ?? _Defaults.outDir
1834
1926
  };
1835
1927
  }
1836
1928
  var import_vite, FumadocsDeps;
1837
- var init_vite2 = __esm({
1929
+ var init_vite = __esm({
1838
1930
  "src/vite/index.ts"() {
1839
1931
  "use strict";
1840
1932
  import_vite = require("vite");
@@ -1842,10 +1934,10 @@ var init_vite2 = __esm({
1842
1934
  init_validation();
1843
1935
  init_mdx();
1844
1936
  init_adapter();
1845
- init_vite();
1846
1937
  init_core();
1847
1938
  init_config();
1848
1939
  init_meta();
1940
+ init_index_file();
1849
1941
  FumadocsDeps = ["fumadocs-core", "fumadocs-ui", "fumadocs-openapi"];
1850
1942
  }
1851
1943
  });
@@ -1853,14 +1945,14 @@ var init_vite2 = __esm({
1853
1945
  // src/bin.ts
1854
1946
  var import_node_fs2 = require("fs");
1855
1947
  async function start() {
1856
- const [configPath] = process.argv.slice(2);
1948
+ const [configPath, outDir] = process.argv.slice(2);
1857
1949
  const isNext = (0, import_node_fs2.existsSync)("next.config.js") || (0, import_node_fs2.existsSync)("next.config.mjs") || (0, import_node_fs2.existsSync)("next.config.mts") || (0, import_node_fs2.existsSync)("next.config.ts");
1858
1950
  if (isNext) {
1859
- const { postInstall: postInstall3 } = await Promise.resolve().then(() => (init_next2(), next_exports));
1860
- await postInstall3(configPath);
1951
+ const { postInstall: postInstall3 } = await Promise.resolve().then(() => (init_next(), next_exports));
1952
+ await postInstall3({ configPath, outDir });
1861
1953
  } else {
1862
- const { postInstall: postInstall3 } = await Promise.resolve().then(() => (init_vite2(), vite_exports));
1863
- await postInstall3(configPath);
1954
+ const { postInstall: postInstall3 } = await Promise.resolve().then(() => (init_vite(), vite_exports));
1955
+ await postInstall3({ configPath, outDir });
1864
1956
  }
1865
1957
  }
1866
1958
  void start();