fumadocs-mdx 13.0.7 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +927 -904
- package/dist/bin.js +3 -3
- package/dist/build-mdx-6UAK5FF5.js +8 -0
- package/dist/bun/index.cjs +592 -481
- package/dist/bun/index.d.cts +3 -2
- package/dist/bun/index.d.ts +3 -2
- package/dist/bun/index.js +12 -12
- package/dist/chunk-4JSFLXXT.js +8 -0
- package/dist/chunk-5UMZCWKV.js +17 -0
- package/dist/chunk-5YXP7JLN.js +138 -0
- package/dist/{chunk-2E2JCOSO.js → chunk-6NISOLQ6.js} +16 -44
- package/dist/chunk-7L2KNF6B.js +180 -0
- package/dist/chunk-E5DJTSIM.js +86 -0
- package/dist/{chunk-K5ZLPEIQ.js → chunk-FBLMK4RS.js} +9 -6
- package/dist/{chunk-QXHN25N3.js → chunk-OXSRIWQW.js} +7 -8
- package/dist/chunk-PKI7ZDA5.js +29 -0
- package/dist/{chunk-3J3WL7WN.js → chunk-SLY7WXTX.js} +71 -58
- package/dist/{chunk-ETIN2W7C.js → chunk-SRSRFOVI.js} +22 -19
- package/dist/chunk-TYJDYTKH.js +85 -0
- package/dist/chunk-XHJCLBZ4.js +406 -0
- package/dist/{chunk-2HXTGJBI.js → chunk-ZY6UZ7NH.js} +22 -19
- package/dist/config/index.cjs +79 -71
- package/dist/config/index.d.cts +2 -1
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.js +5 -5
- package/dist/index-BlVBvy-z.d.ts +8 -0
- package/dist/{core-HkAVGq_a.d.cts → index-D7JdSMpp.d.cts} +99 -61
- package/dist/{core-HkAVGq_a.d.ts → index-D7JdSMpp.d.ts} +99 -61
- package/dist/index-P2NNUkHn.d.cts +8 -0
- package/dist/index.d.cts +3 -74
- package/dist/index.d.ts +3 -74
- package/dist/load-from-file-I3ALLIVB.js +8 -0
- package/dist/next/index.cjs +698 -476
- package/dist/next/index.d.cts +11 -1
- package/dist/next/index.d.ts +11 -1
- package/dist/next/index.js +78 -281
- package/dist/node/loader.cjs +705 -603
- package/dist/node/loader.js +10 -11
- package/dist/plugins/index-file.cjs +471 -0
- package/dist/plugins/index-file.d.cts +29 -0
- package/dist/plugins/index-file.d.ts +29 -0
- package/dist/plugins/index-file.js +8 -0
- package/dist/plugins/json-schema.d.cts +3 -2
- package/dist/plugins/json-schema.d.ts +3 -2
- package/dist/plugins/last-modified.cjs +75 -0
- package/dist/plugins/last-modified.d.cts +27 -0
- package/dist/plugins/last-modified.d.ts +27 -0
- package/dist/plugins/last-modified.js +44 -0
- package/dist/runtime/{vite/browser.cjs → browser.cjs} +40 -53
- package/dist/runtime/browser.d.cts +50 -0
- package/dist/runtime/browser.d.ts +50 -0
- package/dist/runtime/browser.js +68 -0
- package/dist/runtime/dynamic.cjs +985 -0
- package/dist/runtime/dynamic.d.cts +27 -0
- package/dist/runtime/dynamic.d.ts +27 -0
- package/dist/runtime/dynamic.js +78 -0
- package/dist/runtime/server.cjs +173 -0
- package/dist/runtime/server.d.cts +161 -0
- package/dist/runtime/server.d.ts +161 -0
- package/dist/runtime/server.js +8 -0
- package/dist/vite/index.cjs +935 -639
- package/dist/vite/index.d.cts +12 -22
- package/dist/vite/index.d.ts +12 -22
- package/dist/vite/index.js +30 -221
- package/dist/webpack/mdx.cjs +614 -515
- package/dist/webpack/mdx.d.cts +9 -1
- package/dist/webpack/mdx.d.ts +9 -1
- package/dist/webpack/mdx.js +12 -17
- package/dist/webpack/meta.cjs +328 -234
- package/dist/webpack/meta.d.cts +9 -1
- package/dist/webpack/meta.d.ts +9 -1
- package/dist/webpack/meta.js +13 -15
- package/package.json +15 -32
- package/dist/build-mdx-BnJhW5O1.d.cts +0 -53
- package/dist/build-mdx-DNzfRRlY.d.ts +0 -53
- package/dist/chunk-2AQRQXSO.js +0 -119
- package/dist/chunk-4757L6ST.js +0 -77
- package/dist/chunk-CXA4JO4Z.js +0 -45
- package/dist/chunk-FSZMKRVH.js +0 -80
- package/dist/chunk-II3H5ZVZ.js +0 -77
- package/dist/chunk-KILFIBVW.js +0 -75
- package/dist/chunk-NVRDCY6Z.js +0 -30
- package/dist/chunk-VUEZTR2H.js +0 -26
- package/dist/index-D7s7kCc2.d.cts +0 -7
- package/dist/index-D7s7kCc2.d.ts +0 -7
- package/dist/load-from-file-AVYOFOI7.js +0 -7
- package/dist/preset-ZMP6U62C.js +0 -6
- package/dist/runtime/next/async.cjs +0 -760
- package/dist/runtime/next/async.d.cts +0 -19
- package/dist/runtime/next/async.d.ts +0 -19
- package/dist/runtime/next/async.js +0 -86
- package/dist/runtime/next/index.cjs +0 -136
- package/dist/runtime/next/index.d.cts +0 -33
- package/dist/runtime/next/index.d.ts +0 -33
- package/dist/runtime/next/index.js +0 -11
- package/dist/runtime/vite/browser.d.cts +0 -59
- package/dist/runtime/vite/browser.d.ts +0 -59
- package/dist/runtime/vite/browser.js +0 -11
- package/dist/runtime/vite/server.cjs +0 -243
- package/dist/runtime/vite/server.d.cts +0 -30
- package/dist/runtime/vite/server.d.ts +0 -30
- package/dist/runtime/vite/server.js +0 -111
- package/dist/types-By6wKOnT.d.cts +0 -45
- package/dist/types-DgD5Omj2.d.ts +0 -45
package/dist/next/index.cjs
CHANGED
|
@@ -5,9 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
-
};
|
|
11
8
|
var __export = (target, all) => {
|
|
12
9
|
for (var name in all)
|
|
13
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -30,11 +27,22 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
27
|
));
|
|
31
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
29
|
|
|
33
|
-
// src/
|
|
34
|
-
var
|
|
35
|
-
__export(
|
|
36
|
-
|
|
30
|
+
// src/next/index.ts
|
|
31
|
+
var next_exports = {};
|
|
32
|
+
__export(next_exports, {
|
|
33
|
+
createMDX: () => createMDX,
|
|
34
|
+
postInstall: () => postInstall
|
|
37
35
|
});
|
|
36
|
+
module.exports = __toCommonJS(next_exports);
|
|
37
|
+
var path5 = __toESM(require("path"), 1);
|
|
38
|
+
|
|
39
|
+
// src/config/load-from-file.ts
|
|
40
|
+
var import_node_url = require("url");
|
|
41
|
+
|
|
42
|
+
// src/config/build.ts
|
|
43
|
+
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
44
|
+
|
|
45
|
+
// src/config/preset.ts
|
|
38
46
|
function pluginOption(def, options = []) {
|
|
39
47
|
const list = def(Array.isArray(options) ? options : []).filter(
|
|
40
48
|
Boolean
|
|
@@ -44,94 +52,80 @@ function pluginOption(def, options = []) {
|
|
|
44
52
|
}
|
|
45
53
|
return list;
|
|
46
54
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
55
|
+
function applyMdxPreset(options = {}) {
|
|
56
|
+
return async (environment = "bundler") => {
|
|
57
|
+
if (options.preset === "minimal") return options;
|
|
58
|
+
const plugins = await import("fumadocs-core/mdx-plugins");
|
|
59
|
+
const {
|
|
60
|
+
valueToExport = [],
|
|
61
|
+
rehypeCodeOptions,
|
|
62
|
+
remarkImageOptions,
|
|
63
|
+
remarkHeadingOptions,
|
|
64
|
+
remarkStructureOptions,
|
|
65
|
+
remarkCodeTabOptions,
|
|
66
|
+
remarkNpmOptions,
|
|
67
|
+
...mdxOptions
|
|
68
|
+
} = options;
|
|
69
|
+
const remarkPlugins = pluginOption(
|
|
70
|
+
(v) => [
|
|
71
|
+
plugins.remarkGfm,
|
|
72
|
+
[
|
|
73
|
+
plugins.remarkHeading,
|
|
74
|
+
{
|
|
75
|
+
generateToc: false,
|
|
76
|
+
...remarkHeadingOptions
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
remarkImageOptions !== false && [
|
|
80
|
+
plugins.remarkImage,
|
|
81
|
+
{
|
|
82
|
+
...remarkImageOptions,
|
|
83
|
+
useImport: remarkImageOptions?.useImport ?? environment === "bundler"
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
|
|
87
|
+
plugins.remarkCodeTab,
|
|
88
|
+
remarkCodeTabOptions
|
|
89
|
+
],
|
|
90
|
+
"remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
|
|
91
|
+
...v,
|
|
92
|
+
remarkStructureOptions !== false && [
|
|
93
|
+
plugins.remarkStructure,
|
|
94
|
+
remarkStructureOptions
|
|
95
|
+
],
|
|
96
|
+
valueToExport.length > 0 && (() => {
|
|
97
|
+
return (_, file) => {
|
|
98
|
+
file.data["mdx-export"] ??= [];
|
|
99
|
+
for (const name of valueToExport) {
|
|
100
|
+
if (!(name in file.data)) continue;
|
|
101
|
+
file.data["mdx-export"].push({
|
|
102
|
+
name,
|
|
103
|
+
value: file.data[name]
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
})
|
|
78
108
|
],
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
109
|
+
mdxOptions.remarkPlugins
|
|
110
|
+
);
|
|
111
|
+
const rehypePlugins = pluginOption(
|
|
112
|
+
(v) => [
|
|
113
|
+
rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
|
|
114
|
+
...v,
|
|
115
|
+
plugins.rehypeToc
|
|
84
116
|
],
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
|
117
|
+
mdxOptions.rehypePlugins
|
|
118
|
+
);
|
|
119
|
+
return {
|
|
120
|
+
...mdxOptions,
|
|
121
|
+
outputFormat: environment === "runtime" ? "function-body" : mdxOptions.outputFormat,
|
|
122
|
+
remarkPlugins,
|
|
123
|
+
rehypePlugins
|
|
124
|
+
};
|
|
110
125
|
};
|
|
111
126
|
}
|
|
112
|
-
var plugins;
|
|
113
|
-
var init_preset = __esm({
|
|
114
|
-
"src/loaders/mdx/preset.ts"() {
|
|
115
|
-
"use strict";
|
|
116
|
-
plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// src/next/index.ts
|
|
121
|
-
var next_exports = {};
|
|
122
|
-
__export(next_exports, {
|
|
123
|
-
createMDX: () => createMDX,
|
|
124
|
-
postInstall: () => postInstall
|
|
125
|
-
});
|
|
126
|
-
module.exports = __toCommonJS(next_exports);
|
|
127
|
-
var path7 = __toESM(require("path"), 1);
|
|
128
|
-
|
|
129
|
-
// src/config/load-from-file.ts
|
|
130
|
-
var path = __toESM(require("path"), 1);
|
|
131
|
-
var import_node_url = require("url");
|
|
132
127
|
|
|
133
128
|
// src/config/build.ts
|
|
134
|
-
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
135
129
|
var SupportedFormats = {
|
|
136
130
|
doc: ["mdx", "md"],
|
|
137
131
|
meta: ["json", "yaml"]
|
|
@@ -142,7 +136,10 @@ function buildCollection(name, config) {
|
|
|
142
136
|
...config,
|
|
143
137
|
name,
|
|
144
138
|
meta: buildPrimitiveCollection(name, config.meta),
|
|
145
|
-
docs: buildPrimitiveCollection(name, config.docs)
|
|
139
|
+
docs: buildPrimitiveCollection(name, config.docs),
|
|
140
|
+
hasFile(filePath) {
|
|
141
|
+
return this.docs.hasFile(filePath) || this.meta.hasFile(filePath);
|
|
142
|
+
}
|
|
146
143
|
};
|
|
147
144
|
}
|
|
148
145
|
return buildPrimitiveCollection(name, config);
|
|
@@ -196,11 +193,6 @@ function buildConfig(config) {
|
|
|
196
193
|
`Unknown export "${k}", you can only export collections from source configuration file.`
|
|
197
194
|
);
|
|
198
195
|
}
|
|
199
|
-
if (loaded.collections) {
|
|
200
|
-
for (const [k, v] of Object.entries(loaded.collections)) {
|
|
201
|
-
collections.set(k, buildCollection(k, v));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
196
|
const mdxOptionsCache = /* @__PURE__ */ new Map();
|
|
205
197
|
return {
|
|
206
198
|
global: loaded,
|
|
@@ -208,33 +200,34 @@ function buildConfig(config) {
|
|
|
208
200
|
getCollection(name) {
|
|
209
201
|
return collections.get(name);
|
|
210
202
|
},
|
|
211
|
-
|
|
212
|
-
const
|
|
203
|
+
getMDXOptions(collection, environment = "bundler") {
|
|
204
|
+
const key = collection ? `${environment}:${collection.name}` : environment;
|
|
205
|
+
const cached = mdxOptionsCache.get(key);
|
|
213
206
|
if (cached) return cached;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
207
|
+
let result;
|
|
208
|
+
if (collection?.mdxOptions) {
|
|
209
|
+
const optionsFn = collection.mdxOptions;
|
|
210
|
+
result = typeof optionsFn === "function" ? optionsFn(environment) : optionsFn;
|
|
211
|
+
} else {
|
|
212
|
+
result = (async () => {
|
|
213
|
+
const optionsFn = this.global.mdxOptions;
|
|
214
|
+
const options = typeof optionsFn === "function" ? await optionsFn() : optionsFn;
|
|
215
|
+
return applyMdxPreset(options)(environment);
|
|
216
|
+
})();
|
|
223
217
|
}
|
|
224
|
-
|
|
225
|
-
mdxOptionsCache.set(mode, result);
|
|
218
|
+
mdxOptionsCache.set(key, result);
|
|
226
219
|
return result;
|
|
227
220
|
}
|
|
228
221
|
};
|
|
229
222
|
}
|
|
230
223
|
|
|
231
224
|
// src/config/load-from-file.ts
|
|
232
|
-
async function compileConfig(
|
|
225
|
+
async function compileConfig(core) {
|
|
233
226
|
const { build } = await import("esbuild");
|
|
234
227
|
const transformed = await build({
|
|
235
|
-
entryPoints: [{ in: configPath, out: "source.config" }],
|
|
228
|
+
entryPoints: [{ in: core._options.configPath, out: "source.config" }],
|
|
236
229
|
bundle: true,
|
|
237
|
-
outdir: outDir,
|
|
230
|
+
outdir: core._options.outDir,
|
|
238
231
|
target: "node20",
|
|
239
232
|
write: true,
|
|
240
233
|
platform: "node",
|
|
@@ -249,9 +242,9 @@ async function compileConfig(configPath, outDir) {
|
|
|
249
242
|
throw new Error("failed to compile configuration file");
|
|
250
243
|
}
|
|
251
244
|
}
|
|
252
|
-
async function loadConfig(
|
|
253
|
-
if (build) await compileConfig(
|
|
254
|
-
const url = (0, import_node_url.pathToFileURL)(
|
|
245
|
+
async function loadConfig(core, build = false) {
|
|
246
|
+
if (build) await compileConfig(core);
|
|
247
|
+
const url = (0, import_node_url.pathToFileURL)(core.getCompiledConfigPath());
|
|
255
248
|
url.searchParams.set("hash", Date.now().toString());
|
|
256
249
|
const config = import(url.href).then(
|
|
257
250
|
(loaded) => buildConfig(loaded)
|
|
@@ -259,33 +252,7 @@ async function loadConfig(configPath, outDir, build = false) {
|
|
|
259
252
|
return await config;
|
|
260
253
|
}
|
|
261
254
|
|
|
262
|
-
// src/next/file-cache.ts
|
|
263
|
-
var import_lru_cache = require("lru-cache");
|
|
264
|
-
var import_promises = __toESM(require("fs/promises"), 1);
|
|
265
|
-
var import_node_path = __toESM(require("path"), 1);
|
|
266
|
-
var map = new import_lru_cache.LRUCache({
|
|
267
|
-
max: 100
|
|
268
|
-
});
|
|
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
|
-
|
|
287
255
|
// src/utils/validation.ts
|
|
288
|
-
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
289
256
|
var ValidationError = class extends Error {
|
|
290
257
|
constructor(message, issues) {
|
|
291
258
|
super(
|
|
@@ -295,12 +262,13 @@ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
|
|
|
295
262
|
this.title = message;
|
|
296
263
|
this.issues = issues;
|
|
297
264
|
}
|
|
298
|
-
toStringFormatted() {
|
|
265
|
+
async toStringFormatted() {
|
|
266
|
+
const picocolors = await import("picocolors");
|
|
299
267
|
return [
|
|
300
|
-
|
|
268
|
+
picocolors.bold(`[MDX] ${this.title}:`),
|
|
301
269
|
...this.issues.map(
|
|
302
|
-
(issue) =>
|
|
303
|
-
`- ${
|
|
270
|
+
(issue) => picocolors.redBright(
|
|
271
|
+
`- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
|
|
304
272
|
)
|
|
305
273
|
)
|
|
306
274
|
].join("\n");
|
|
@@ -322,33 +290,299 @@ async function validate(schema, data, context, errorMessage) {
|
|
|
322
290
|
return data;
|
|
323
291
|
}
|
|
324
292
|
|
|
325
|
-
// src/
|
|
326
|
-
var path5 = __toESM(require("path"), 1);
|
|
327
|
-
var import_node_crypto = require("crypto");
|
|
328
|
-
|
|
329
|
-
// src/utils/git-timestamp.ts
|
|
293
|
+
// src/core.ts
|
|
330
294
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
331
|
-
var
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
295
|
+
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
296
|
+
|
|
297
|
+
// src/utils/codegen/cache.ts
|
|
298
|
+
var import_lru_cache = require("lru-cache");
|
|
299
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
300
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
301
|
+
var map = new import_lru_cache.LRUCache({
|
|
302
|
+
max: 100
|
|
303
|
+
});
|
|
304
|
+
function toFullPath(file) {
|
|
305
|
+
if (import_node_path.default.isAbsolute(file)) {
|
|
306
|
+
return import_node_path.default.relative(process.cwd(), file);
|
|
307
|
+
}
|
|
308
|
+
return file;
|
|
309
|
+
}
|
|
310
|
+
async function readFileWithCache(file) {
|
|
311
|
+
const fullPath = toFullPath(file);
|
|
312
|
+
const cached = map.get(fullPath);
|
|
335
313
|
if (cached) return cached;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
314
|
+
const read = import_promises.default.readFile(fullPath).then((s) => s.toString());
|
|
315
|
+
map.set(fullPath, read);
|
|
316
|
+
return read;
|
|
317
|
+
}
|
|
318
|
+
function removeFileCache(file) {
|
|
319
|
+
map.delete(toFullPath(file));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// src/core.ts
|
|
323
|
+
var _Defaults = {
|
|
324
|
+
configPath: "source.config.ts",
|
|
325
|
+
outDir: ".source"
|
|
326
|
+
};
|
|
327
|
+
async function getPlugins(pluginOptions) {
|
|
328
|
+
const plugins = [];
|
|
329
|
+
for await (const option of pluginOptions) {
|
|
330
|
+
if (!option) continue;
|
|
331
|
+
if (Array.isArray(option)) plugins.push(...await getPlugins(option));
|
|
332
|
+
else plugins.push(option);
|
|
333
|
+
}
|
|
334
|
+
return plugins;
|
|
335
|
+
}
|
|
336
|
+
function createCore(options, defaultPlugins = []) {
|
|
337
|
+
let config;
|
|
338
|
+
let plugins;
|
|
339
|
+
async function transformMetadata({
|
|
340
|
+
collection,
|
|
341
|
+
filePath,
|
|
342
|
+
source
|
|
343
|
+
}, data) {
|
|
344
|
+
if (collection.schema) {
|
|
345
|
+
data = await validate(
|
|
346
|
+
collection.schema,
|
|
347
|
+
data,
|
|
348
|
+
{ path: filePath, source },
|
|
349
|
+
collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
return data;
|
|
353
|
+
}
|
|
354
|
+
const core = {
|
|
355
|
+
_options: options,
|
|
356
|
+
/**
|
|
357
|
+
* Convenient cache store, reset when config changes
|
|
358
|
+
*/
|
|
359
|
+
cache: /* @__PURE__ */ new Map(),
|
|
360
|
+
async init({ config: newConfig }) {
|
|
361
|
+
config = await newConfig;
|
|
362
|
+
this.cache.clear();
|
|
363
|
+
plugins = await getPlugins([
|
|
364
|
+
...defaultPlugins,
|
|
365
|
+
...config.global.plugins ?? []
|
|
366
|
+
]);
|
|
367
|
+
for (const plugin of plugins) {
|
|
368
|
+
const out = await plugin.config?.call(pluginContext, config);
|
|
369
|
+
if (out) config = out;
|
|
342
370
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
371
|
+
return this;
|
|
372
|
+
},
|
|
373
|
+
getConfig() {
|
|
374
|
+
return config;
|
|
375
|
+
},
|
|
376
|
+
/**
|
|
377
|
+
* The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
|
|
378
|
+
*/
|
|
379
|
+
getCompiledConfigPath() {
|
|
380
|
+
return import_node_path2.default.join(options.outDir, "source.config.mjs");
|
|
381
|
+
},
|
|
382
|
+
async initServer(server) {
|
|
383
|
+
server.watcher?.on("all", async (event, file) => {
|
|
384
|
+
if (event === "change") removeFileCache(file);
|
|
385
|
+
});
|
|
386
|
+
for (const plugin of plugins) {
|
|
387
|
+
await plugin.configureServer?.call(pluginContext, server);
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
async emit({ filterPlugin = () => true } = {}) {
|
|
391
|
+
return (await Promise.all(
|
|
392
|
+
plugins.map((plugin) => {
|
|
393
|
+
if (!filterPlugin(plugin) || !plugin.emit) return [];
|
|
394
|
+
return plugin.emit.call(pluginContext);
|
|
395
|
+
})
|
|
396
|
+
)).flat();
|
|
397
|
+
},
|
|
398
|
+
async emitAndWrite(emitOptions) {
|
|
399
|
+
const start = performance.now();
|
|
400
|
+
const out = await this.emit(emitOptions);
|
|
401
|
+
await Promise.all(
|
|
402
|
+
out.map(async (entry) => {
|
|
403
|
+
const file = import_node_path2.default.join(options.outDir, entry.path);
|
|
404
|
+
await import_promises2.default.mkdir(import_node_path2.default.dirname(file), { recursive: true });
|
|
405
|
+
await import_promises2.default.writeFile(file, entry.content);
|
|
406
|
+
})
|
|
407
|
+
);
|
|
408
|
+
console.log(`[MDX] generated files in ${performance.now() - start}ms`);
|
|
409
|
+
},
|
|
410
|
+
async transformMeta(options2, data) {
|
|
411
|
+
const ctx = {
|
|
412
|
+
...pluginContext,
|
|
413
|
+
...options2
|
|
414
|
+
};
|
|
415
|
+
data = await transformMetadata(options2, data);
|
|
416
|
+
for (const plugin of plugins) {
|
|
417
|
+
if (plugin.meta?.transform)
|
|
418
|
+
data = await plugin.meta.transform.call(ctx, data) ?? data;
|
|
419
|
+
}
|
|
420
|
+
return data;
|
|
421
|
+
},
|
|
422
|
+
async transformFrontmatter(options2, data) {
|
|
423
|
+
const ctx = {
|
|
424
|
+
...pluginContext,
|
|
425
|
+
...options2
|
|
426
|
+
};
|
|
427
|
+
data = await transformMetadata(options2, data);
|
|
428
|
+
for (const plugin of plugins) {
|
|
429
|
+
if (plugin.doc?.frontmatter)
|
|
430
|
+
data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
|
|
431
|
+
}
|
|
432
|
+
return data;
|
|
433
|
+
},
|
|
434
|
+
async transformVFile(options2, file) {
|
|
435
|
+
const ctx = {
|
|
436
|
+
...pluginContext,
|
|
437
|
+
...options2
|
|
438
|
+
};
|
|
439
|
+
for (const plugin of plugins) {
|
|
440
|
+
if (plugin.doc?.vfile)
|
|
441
|
+
file = await plugin.doc.vfile.call(ctx, file) ?? file;
|
|
442
|
+
}
|
|
443
|
+
return file;
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
const pluginContext = {
|
|
447
|
+
core,
|
|
448
|
+
...options
|
|
449
|
+
};
|
|
450
|
+
return core;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// src/loaders/index.ts
|
|
454
|
+
var metaLoaderGlob = /\.(json|yaml)(\?.+?)?$/;
|
|
455
|
+
var mdxLoaderGlob = /\.mdx?(\?.+?)?$/;
|
|
456
|
+
|
|
457
|
+
// src/plugins/index-file.ts
|
|
458
|
+
var import_path = __toESM(require("path"), 1);
|
|
459
|
+
|
|
460
|
+
// src/utils/codegen/index.ts
|
|
461
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
462
|
+
var import_tinyglobby = require("tinyglobby");
|
|
463
|
+
function createCodegen({
|
|
464
|
+
target = "default",
|
|
465
|
+
outDir = "",
|
|
466
|
+
jsExtension = false,
|
|
467
|
+
globCache = /* @__PURE__ */ new Map()
|
|
468
|
+
}) {
|
|
469
|
+
let eagerImportId = 0;
|
|
470
|
+
const banner = ["// @ts-nocheck"];
|
|
471
|
+
if (target === "vite") {
|
|
472
|
+
banner.push('/// <reference types="vite/client" />');
|
|
473
|
+
}
|
|
474
|
+
return {
|
|
475
|
+
options: {
|
|
476
|
+
target,
|
|
477
|
+
outDir
|
|
478
|
+
},
|
|
479
|
+
lines: [],
|
|
480
|
+
addImport(statement) {
|
|
481
|
+
this.lines.unshift(statement);
|
|
482
|
+
},
|
|
483
|
+
async pushAsync(insert) {
|
|
484
|
+
for (const line of await Promise.all(insert)) {
|
|
485
|
+
if (line === void 0) continue;
|
|
486
|
+
this.lines.push(line);
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
async generateGlobImport(patterns, options) {
|
|
490
|
+
if (target === "vite") {
|
|
491
|
+
return this.generateViteGlobImport(patterns, options);
|
|
492
|
+
}
|
|
493
|
+
return this.generateNodeGlobImport(patterns, options);
|
|
494
|
+
},
|
|
495
|
+
generateViteGlobImport(patterns, { base, ...rest }) {
|
|
496
|
+
patterns = (typeof patterns === "string" ? [patterns] : patterns).map(
|
|
497
|
+
normalizeViteGlobPath
|
|
498
|
+
);
|
|
499
|
+
return `import.meta.glob(${JSON.stringify(patterns)}, ${JSON.stringify(
|
|
500
|
+
{
|
|
501
|
+
base: normalizeViteGlobPath(import_node_path3.default.relative(outDir, base)),
|
|
502
|
+
...rest
|
|
503
|
+
},
|
|
504
|
+
null,
|
|
505
|
+
2
|
|
506
|
+
)})`;
|
|
507
|
+
},
|
|
508
|
+
async generateNodeGlobImport(patterns, {
|
|
509
|
+
base,
|
|
510
|
+
eager = false,
|
|
511
|
+
query = {},
|
|
512
|
+
import: importName
|
|
513
|
+
}) {
|
|
514
|
+
const cacheKey = JSON.stringify({ patterns, base });
|
|
515
|
+
let files = globCache.get(cacheKey);
|
|
516
|
+
if (!files) {
|
|
517
|
+
files = (0, import_tinyglobby.glob)(patterns, {
|
|
518
|
+
cwd: base
|
|
519
|
+
});
|
|
520
|
+
globCache.set(cacheKey, files);
|
|
521
|
+
}
|
|
522
|
+
let code = "{";
|
|
523
|
+
for (const item of await files) {
|
|
524
|
+
const fullPath = import_node_path3.default.join(base, item);
|
|
525
|
+
const searchParams = new URLSearchParams();
|
|
526
|
+
for (const [k, v] of Object.entries(query)) {
|
|
527
|
+
searchParams.set(k, v);
|
|
528
|
+
}
|
|
529
|
+
const importPath = this.formatImportPath(fullPath) + "?" + searchParams.toString();
|
|
530
|
+
if (eager) {
|
|
531
|
+
const name = `__fd_glob_${eagerImportId++}`;
|
|
532
|
+
this.lines.unshift(
|
|
533
|
+
importName ? `import { ${importName} as ${name} } from ${JSON.stringify(importPath)}` : `import * as ${name} from ${JSON.stringify(importPath)}`
|
|
534
|
+
);
|
|
535
|
+
code += `${JSON.stringify(item)}: ${name}, `;
|
|
536
|
+
} else {
|
|
537
|
+
let line = `${JSON.stringify(item)}: () => import(${JSON.stringify(importPath)})`;
|
|
538
|
+
if (importName) {
|
|
539
|
+
line += `.then(mod => mod.${importName})`;
|
|
540
|
+
}
|
|
541
|
+
code += `${line}, `;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
code += "}";
|
|
545
|
+
return code;
|
|
546
|
+
},
|
|
547
|
+
formatImportPath(file) {
|
|
548
|
+
const ext = import_node_path3.default.extname(file);
|
|
549
|
+
let filename;
|
|
550
|
+
if (ext === ".ts" && jsExtension) {
|
|
551
|
+
filename = file.substring(0, file.length - ext.length) + ".js";
|
|
552
|
+
} else if (ext === ".ts") {
|
|
553
|
+
filename = file.substring(0, file.length - ext.length);
|
|
554
|
+
} else {
|
|
555
|
+
filename = file;
|
|
556
|
+
}
|
|
557
|
+
const importPath = slash(import_node_path3.default.relative(outDir, filename));
|
|
558
|
+
return importPath.startsWith(".") ? importPath : `./${importPath}`;
|
|
559
|
+
},
|
|
560
|
+
toString() {
|
|
561
|
+
return [...banner, ...this.lines].join("\n");
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function normalizeViteGlobPath(file) {
|
|
566
|
+
file = slash(file);
|
|
567
|
+
if (file.startsWith("./")) return file;
|
|
568
|
+
if (file.startsWith("/")) return `.${file}`;
|
|
569
|
+
return `./${file}`;
|
|
570
|
+
}
|
|
571
|
+
function slash(path6) {
|
|
572
|
+
const isExtendedLengthPath = path6.startsWith("\\\\?\\");
|
|
573
|
+
if (isExtendedLengthPath) {
|
|
574
|
+
return path6;
|
|
349
575
|
}
|
|
576
|
+
return path6.replaceAll("\\", "/");
|
|
577
|
+
}
|
|
578
|
+
function ident(code, tab = 1) {
|
|
579
|
+
return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
|
|
350
580
|
}
|
|
351
581
|
|
|
582
|
+
// src/plugins/index-file.ts
|
|
583
|
+
var import_tinyglobby2 = require("tinyglobby");
|
|
584
|
+
var import_crypto = require("crypto");
|
|
585
|
+
|
|
352
586
|
// src/utils/fuma-matter.ts
|
|
353
587
|
var import_js_yaml = require("js-yaml");
|
|
354
588
|
var regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
|
|
@@ -365,323 +599,288 @@ function fumaMatter(input) {
|
|
|
365
599
|
return output;
|
|
366
600
|
}
|
|
367
601
|
|
|
368
|
-
// src/
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const names = info.names.map(
|
|
377
|
-
(name) => Array.isArray(name) ? `${name[0]} as ${name[1]}` : name
|
|
378
|
-
);
|
|
379
|
-
return `import { ${names.join(", ")} } from ${specifier}`;
|
|
380
|
-
}
|
|
381
|
-
return `import ${specifier}`;
|
|
382
|
-
}
|
|
383
|
-
function toImportPath(file, config) {
|
|
384
|
-
const ext = import_node_path3.default.extname(file);
|
|
385
|
-
let filename;
|
|
386
|
-
if (ext === ".ts" && config.jsExtension) {
|
|
387
|
-
filename = file.substring(0, file.length - ext.length) + ".js";
|
|
388
|
-
} else if (ext === ".ts") {
|
|
389
|
-
filename = file.substring(0, file.length - ext.length);
|
|
390
|
-
} else {
|
|
391
|
-
filename = file;
|
|
392
|
-
}
|
|
393
|
-
let importPath;
|
|
394
|
-
if ("relativeTo" in config) {
|
|
395
|
-
importPath = import_node_path3.default.relative(config.relativeTo, filename);
|
|
396
|
-
if (!import_node_path3.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
|
|
397
|
-
importPath = `./${importPath}`;
|
|
398
|
-
}
|
|
399
|
-
} else {
|
|
400
|
-
importPath = import_node_path3.default.resolve(filename);
|
|
401
|
-
}
|
|
402
|
-
return importPath.replaceAll(import_node_path3.default.sep, "/");
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// src/plugins/next.ts
|
|
406
|
-
var import_js_yaml2 = require("js-yaml");
|
|
407
|
-
function next() {
|
|
602
|
+
// src/plugins/index-file.ts
|
|
603
|
+
function indexFile(options = {}) {
|
|
604
|
+
const {
|
|
605
|
+
target = "default",
|
|
606
|
+
addJsExtension,
|
|
607
|
+
browser = true,
|
|
608
|
+
dynamic = true
|
|
609
|
+
} = options;
|
|
408
610
|
let config;
|
|
409
|
-
let
|
|
611
|
+
let dynamicCollections;
|
|
612
|
+
function isDynamic(collection) {
|
|
613
|
+
return collection.type === "docs" && collection.docs.dynamic || collection.type === "doc" && collection.dynamic;
|
|
614
|
+
}
|
|
410
615
|
return {
|
|
411
|
-
name: "
|
|
616
|
+
name: "index-file",
|
|
412
617
|
config(v) {
|
|
413
618
|
config = v;
|
|
414
|
-
|
|
415
|
-
return collection.type === "doc" && collection.async || collection.type === "docs" || collection.type === "meta";
|
|
416
|
-
});
|
|
619
|
+
dynamicCollections = config.collectionList.filter(isDynamic);
|
|
417
620
|
},
|
|
418
621
|
configureServer(server) {
|
|
419
622
|
if (!server.watcher) return;
|
|
420
|
-
server.watcher.on("all", async (event) => {
|
|
421
|
-
if (
|
|
623
|
+
server.watcher.on("all", async (event, file) => {
|
|
624
|
+
if (dynamicCollections.length === 0) {
|
|
625
|
+
if (target === "vite") return;
|
|
626
|
+
if (target === "default" && event === "change") return;
|
|
627
|
+
}
|
|
628
|
+
const updatedCollection = config.collectionList.find(
|
|
629
|
+
(collection) => collection.hasFile(file)
|
|
630
|
+
);
|
|
631
|
+
if (!updatedCollection) return;
|
|
632
|
+
if (!isDynamic(updatedCollection)) {
|
|
633
|
+
if (target === "vite") return;
|
|
634
|
+
if (target === "default" && event === "change") return;
|
|
635
|
+
}
|
|
422
636
|
await this.core.emitAndWrite({
|
|
423
|
-
filterPlugin: (plugin) => plugin.name === "
|
|
637
|
+
filterPlugin: (plugin) => plugin.name === "index-file"
|
|
424
638
|
});
|
|
425
639
|
});
|
|
426
640
|
},
|
|
427
641
|
async emit() {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
642
|
+
const globCache = /* @__PURE__ */ new Map();
|
|
643
|
+
const makeCodeGen = () => createCodegen({
|
|
644
|
+
target,
|
|
645
|
+
outDir: this.outDir,
|
|
646
|
+
jsExtension: addJsExtension,
|
|
647
|
+
globCache
|
|
648
|
+
});
|
|
649
|
+
async function toEmitEntry(path6, content) {
|
|
650
|
+
return {
|
|
651
|
+
path: path6,
|
|
652
|
+
content: await content
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
const out = [
|
|
656
|
+
toEmitEntry(
|
|
657
|
+
"server.ts",
|
|
658
|
+
generateServerIndexFile(makeCodeGen(), config, this.configPath)
|
|
659
|
+
)
|
|
435
660
|
];
|
|
661
|
+
if (dynamic)
|
|
662
|
+
out.push(
|
|
663
|
+
toEmitEntry(
|
|
664
|
+
"dynamic.ts",
|
|
665
|
+
generateDynamicIndexFile(this.core, makeCodeGen())
|
|
666
|
+
)
|
|
667
|
+
);
|
|
668
|
+
if (browser)
|
|
669
|
+
out.push(
|
|
670
|
+
toEmitEntry(
|
|
671
|
+
"browser.ts",
|
|
672
|
+
generateBrowserIndexFile(makeCodeGen(), config, this.configPath)
|
|
673
|
+
)
|
|
674
|
+
);
|
|
675
|
+
return await Promise.all(out);
|
|
436
676
|
}
|
|
437
677
|
};
|
|
438
678
|
}
|
|
439
|
-
async function
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
name
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
async function getMetaEntries(collection, files) {
|
|
468
|
-
const items = files.map(async (file) => {
|
|
469
|
-
const source = await readFileWithCache(file.fullPath).catch(() => "");
|
|
470
|
-
let data = source.length === 0 ? {} : parseMetaEntry(file.fullPath, source);
|
|
471
|
-
if (collection?.schema) {
|
|
472
|
-
data = await validate(
|
|
473
|
-
collection.schema,
|
|
474
|
-
data,
|
|
475
|
-
{
|
|
476
|
-
source,
|
|
477
|
-
path: file.fullPath
|
|
478
|
-
},
|
|
479
|
-
`invalid data in ${file.fullPath}`
|
|
480
|
-
);
|
|
679
|
+
async function generateServerIndexFile(codegen, config, configPath) {
|
|
680
|
+
codegen.lines.push(
|
|
681
|
+
`import { fromConfig } from 'fumadocs-mdx/runtime/server';`,
|
|
682
|
+
`import type * as Config from '${codegen.formatImportPath(configPath)}';`,
|
|
683
|
+
"",
|
|
684
|
+
`const create = fromConfig<typeof Config>();`
|
|
685
|
+
);
|
|
686
|
+
async function generateCollectionObject(collection) {
|
|
687
|
+
switch (collection.type) {
|
|
688
|
+
case "docs": {
|
|
689
|
+
if (collection.docs.dynamic) return;
|
|
690
|
+
if (collection.docs.async) {
|
|
691
|
+
const [metaGlob2, headGlob, bodyGlob] = await Promise.all([
|
|
692
|
+
generateMetaCollectionGlob(codegen, collection.meta, true),
|
|
693
|
+
generateDocCollectionFrontmatterGlob(
|
|
694
|
+
codegen,
|
|
695
|
+
collection.docs,
|
|
696
|
+
true
|
|
697
|
+
),
|
|
698
|
+
generateDocCollectionGlob(codegen, collection.docs)
|
|
699
|
+
]);
|
|
700
|
+
return `await create.docsLazy("${collection.name}", "${collection.dir}", ${metaGlob2}, ${headGlob}, ${bodyGlob})`;
|
|
701
|
+
}
|
|
702
|
+
const [metaGlob, docGlob] = await Promise.all([
|
|
703
|
+
generateMetaCollectionGlob(codegen, collection.meta, true),
|
|
704
|
+
generateDocCollectionGlob(codegen, collection.docs, true)
|
|
705
|
+
]);
|
|
706
|
+
return `await create.docs("${collection.name}", "${collection.dir}", ${metaGlob}, ${docGlob})`;
|
|
481
707
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
708
|
+
case "doc":
|
|
709
|
+
if (collection.dynamic) return;
|
|
710
|
+
if (collection.async) {
|
|
711
|
+
const [headGlob, bodyGlob] = await Promise.all([
|
|
712
|
+
generateDocCollectionFrontmatterGlob(codegen, collection, true),
|
|
713
|
+
generateDocCollectionGlob(codegen, collection)
|
|
714
|
+
]);
|
|
715
|
+
return `await create.docLazy("${collection.name}", "${collection.dir}", ${headGlob}, ${bodyGlob})`;
|
|
716
|
+
}
|
|
717
|
+
return `await create.doc("${collection.name}", "${collection.dir}", ${await generateDocCollectionGlob(
|
|
718
|
+
codegen,
|
|
719
|
+
collection,
|
|
720
|
+
true
|
|
721
|
+
)})`;
|
|
722
|
+
case "meta":
|
|
723
|
+
return `await create.meta("${collection.name}", "${collection.dir}", ${await generateMetaCollectionGlob(
|
|
724
|
+
codegen,
|
|
725
|
+
collection,
|
|
726
|
+
true
|
|
727
|
+
)})`;
|
|
728
|
+
}
|
|
488
729
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
730
|
+
await codegen.pushAsync(
|
|
731
|
+
config.collectionList.map(async (collection) => {
|
|
732
|
+
const obj = await generateCollectionObject(collection);
|
|
733
|
+
if (!obj) return;
|
|
734
|
+
return `
|
|
735
|
+
export const ${collection.name} = ${obj};`;
|
|
736
|
+
})
|
|
737
|
+
);
|
|
738
|
+
return codegen.toString();
|
|
739
|
+
}
|
|
740
|
+
async function generateDynamicIndexFile(core, codegen) {
|
|
741
|
+
const { configPath } = core._options;
|
|
742
|
+
codegen.lines.push(
|
|
743
|
+
`import { fromConfigDynamic } from 'fumadocs-mdx/runtime/dynamic';`,
|
|
744
|
+
`import * as Config from '${codegen.formatImportPath(configPath)}';`,
|
|
745
|
+
"",
|
|
746
|
+
`const create = await fromConfigDynamic(Config);`
|
|
747
|
+
);
|
|
748
|
+
async function generateCollectionObjectEntry(collection, file) {
|
|
749
|
+
const fullPath = import_path.default.join(collection.dir, file);
|
|
750
|
+
const content = await readFileWithCache(fullPath).catch(() => "");
|
|
751
|
+
const parsed = fumaMatter(content);
|
|
752
|
+
const data = await core.transformFrontmatter(
|
|
753
|
+
{
|
|
754
|
+
collection,
|
|
755
|
+
filePath: fullPath,
|
|
756
|
+
source: content
|
|
757
|
+
},
|
|
758
|
+
parsed.data
|
|
759
|
+
);
|
|
760
|
+
const hash = (0, import_crypto.createHash)("md5").update(content).digest("hex");
|
|
761
|
+
const infoStr = [
|
|
762
|
+
// make sure it's included in vercel/nft
|
|
763
|
+
`absolutePath: path.resolve(${JSON.stringify(fullPath)})`
|
|
764
|
+
];
|
|
765
|
+
for (const [k, v] of Object.entries({
|
|
766
|
+
info: {
|
|
767
|
+
fullPath,
|
|
768
|
+
path: file
|
|
769
|
+
},
|
|
770
|
+
data,
|
|
771
|
+
hash
|
|
772
|
+
})) {
|
|
773
|
+
infoStr.push(`${k}: ${JSON.stringify(v)}`);
|
|
505
774
|
}
|
|
506
|
-
|
|
507
|
-
const content = await readFileWithCache(file.fullPath).catch(() => "");
|
|
508
|
-
const parsed = fumaMatter(content);
|
|
509
|
-
let data = parsed.data;
|
|
510
|
-
if (collection.schema) {
|
|
511
|
-
data = await validate(
|
|
512
|
-
collection.schema,
|
|
513
|
-
parsed.data,
|
|
514
|
-
{ path: file.fullPath, source: parsed.content },
|
|
515
|
-
`invalid frontmatter in ${file.fullPath}`
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
let lastModified;
|
|
519
|
-
if (config.global?.lastModifiedTime === "git") {
|
|
520
|
-
lastModified = await getGitTimestamp(file.fullPath);
|
|
521
|
-
}
|
|
522
|
-
const hash = (0, import_node_crypto.createHash)("md5").update(content).digest("hex");
|
|
523
|
-
const infoStr = [];
|
|
524
|
-
for (const [k, v] of Object.entries({ ...file, hash })) {
|
|
525
|
-
infoStr.push(`${k}: ${JSON.stringify(v)}`);
|
|
526
|
-
}
|
|
527
|
-
infoStr.push(
|
|
528
|
-
`absolutePath: path.resolve(${JSON.stringify(file.fullPath)})`
|
|
529
|
-
);
|
|
530
|
-
return `{ info: { ${infoStr.join(", ")} }, lastModified: ${JSON.stringify(lastModified)}, data: ${JSON.stringify(data)} }`;
|
|
531
|
-
});
|
|
532
|
-
return Promise.all(entries);
|
|
775
|
+
return `{ ${infoStr.join(", ")} }`;
|
|
533
776
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
if (
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
777
|
+
async function generateCollectionObject(parent) {
|
|
778
|
+
let collection;
|
|
779
|
+
if (parent.type === "doc") collection = parent;
|
|
780
|
+
else if (parent.type === "docs") collection = parent.docs;
|
|
781
|
+
if (!collection || !collection.dynamic) return;
|
|
782
|
+
const files = await (0, import_tinyglobby2.glob)(collection.patterns, {
|
|
783
|
+
cwd: collection.dir
|
|
784
|
+
});
|
|
785
|
+
const entries = await Promise.all(
|
|
786
|
+
files.map((file) => generateCollectionObjectEntry(collection, file))
|
|
787
|
+
);
|
|
788
|
+
switch (parent.type) {
|
|
789
|
+
case "docs": {
|
|
790
|
+
const metaGlob = await generateMetaCollectionGlob(
|
|
791
|
+
codegen,
|
|
792
|
+
parent.meta,
|
|
793
|
+
true
|
|
545
794
|
);
|
|
546
|
-
return `
|
|
795
|
+
return `await create.docs("${parent.name}", "${parent.dir}", ${metaGlob}, ${entries.join(", ")})`;
|
|
547
796
|
}
|
|
548
|
-
|
|
549
|
-
|
|
797
|
+
case "doc":
|
|
798
|
+
return `await create.doc("${collection.name}", "${collection.dir}", ${entries.join(", ")})`;
|
|
550
799
|
}
|
|
551
|
-
const files = await globCollectionFiles(collection);
|
|
552
|
-
if (collection.type === "meta") {
|
|
553
|
-
return `export const ${k} = _runtime.meta<typeof _source.${k}>([${(await getMetaEntries(collection, files)).join(", ")}]);`;
|
|
554
|
-
}
|
|
555
|
-
if (collection.async) {
|
|
556
|
-
return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(collection, files)).join(", ")}], "${k}", _sourceConfig)`;
|
|
557
|
-
}
|
|
558
|
-
return `export const ${k} = _runtime.doc<typeof _source.${k}>([${getDocEntries(collection, files).join(", ")}]);`;
|
|
559
|
-
});
|
|
560
|
-
const resolvedDeclares = await Promise.all(declares);
|
|
561
|
-
return [
|
|
562
|
-
`// @ts-nocheck -- skip type checking`,
|
|
563
|
-
...lines,
|
|
564
|
-
...resolvedDeclares
|
|
565
|
-
].join("\n");
|
|
566
|
-
}
|
|
567
|
-
function parseMetaEntry(file, content) {
|
|
568
|
-
const extname2 = path5.extname(file);
|
|
569
|
-
try {
|
|
570
|
-
if (extname2 === ".json") return JSON.parse(content);
|
|
571
|
-
if (extname2 === ".yaml") return (0, import_js_yaml2.load)(content);
|
|
572
|
-
} catch (e) {
|
|
573
|
-
throw new Error(`Failed to parse meta file: ${file}.`, {
|
|
574
|
-
cause: e
|
|
575
|
-
});
|
|
576
800
|
}
|
|
577
|
-
|
|
801
|
+
await codegen.pushAsync(
|
|
802
|
+
core.getConfig().collectionList.map(async (collection) => {
|
|
803
|
+
const obj = await generateCollectionObject(collection);
|
|
804
|
+
if (!obj) return;
|
|
805
|
+
return `
|
|
806
|
+
export const ${collection.name} = ${obj};`;
|
|
807
|
+
})
|
|
808
|
+
);
|
|
809
|
+
return codegen.toString();
|
|
578
810
|
}
|
|
579
|
-
async function
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
if (
|
|
590
|
-
|
|
591
|
-
files.set(fullPath, {
|
|
592
|
-
path: item,
|
|
593
|
-
fullPath
|
|
594
|
-
});
|
|
811
|
+
async function generateBrowserIndexFile(codegen, config, configPath) {
|
|
812
|
+
codegen.lines.push(
|
|
813
|
+
`import { fromConfig } from 'fumadocs-mdx/runtime/browser';`,
|
|
814
|
+
`import type * as Config from '${codegen.formatImportPath(configPath)}';`,
|
|
815
|
+
"",
|
|
816
|
+
`const create = fromConfig<typeof Config>();`
|
|
817
|
+
);
|
|
818
|
+
async function generateCollectionObject(collection) {
|
|
819
|
+
switch (collection.type) {
|
|
820
|
+
case "docs": {
|
|
821
|
+
if (collection.docs.dynamic) return;
|
|
822
|
+
return generateCollectionObject(collection.docs);
|
|
595
823
|
}
|
|
824
|
+
case "doc":
|
|
825
|
+
if (collection.dynamic) return;
|
|
826
|
+
return `create.doc("${collection.name}", ${await generateDocCollectionGlob(codegen, collection)})`;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
codegen.lines.push("const browserCollections = {");
|
|
830
|
+
await codegen.pushAsync(
|
|
831
|
+
config.collectionList.map(async (collection) => {
|
|
832
|
+
const obj = await generateCollectionObject(collection);
|
|
833
|
+
if (!obj) return;
|
|
834
|
+
return ident(`${collection.name}: ${obj},`);
|
|
596
835
|
})
|
|
597
836
|
);
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
// src/core.ts
|
|
602
|
-
var import_node_path4 = __toESM(require("path"), 1);
|
|
603
|
-
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
604
|
-
function findConfigFile() {
|
|
605
|
-
return import_node_path4.default.resolve("source.config.ts");
|
|
837
|
+
codegen.lines.push("};", "export default browserCollections;");
|
|
838
|
+
return codegen.toString();
|
|
606
839
|
}
|
|
607
|
-
function
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
getPluginContext() {
|
|
613
|
-
return {
|
|
614
|
-
core: this,
|
|
615
|
-
...options
|
|
616
|
-
};
|
|
840
|
+
function generateDocCollectionFrontmatterGlob(codegen, collection, eager = false) {
|
|
841
|
+
return codegen.generateGlobImport(collection.patterns, {
|
|
842
|
+
query: {
|
|
843
|
+
collection: collection.name,
|
|
844
|
+
only: "frontmatter"
|
|
617
845
|
},
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
...defaultPlugins,
|
|
628
|
-
...config.global.plugins ?? []
|
|
629
|
-
]) {
|
|
630
|
-
if (!option) continue;
|
|
631
|
-
if (Array.isArray(option)) plugins2.push(...option);
|
|
632
|
-
else plugins2.push(option);
|
|
633
|
-
}
|
|
634
|
-
for (const plugin of plugins2) {
|
|
635
|
-
const out = await plugin.config?.call(this.getPluginContext(), config);
|
|
636
|
-
if (out) config = out;
|
|
637
|
-
}
|
|
638
|
-
return this;
|
|
639
|
-
},
|
|
640
|
-
getConfig() {
|
|
641
|
-
return config;
|
|
846
|
+
import: "frontmatter",
|
|
847
|
+
base: collection.dir,
|
|
848
|
+
eager
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
function generateDocCollectionGlob(codegen, collection, eager = false) {
|
|
852
|
+
return codegen.generateGlobImport(collection.patterns, {
|
|
853
|
+
query: {
|
|
854
|
+
collection: collection.name
|
|
642
855
|
},
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
856
|
+
base: collection.dir,
|
|
857
|
+
eager
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
function generateMetaCollectionGlob(codegen, collection, eager = false) {
|
|
861
|
+
return codegen.generateGlobImport(collection.patterns, {
|
|
862
|
+
query: {
|
|
863
|
+
collection: collection.name
|
|
647
864
|
},
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const out = await Promise.all(
|
|
653
|
-
plugins2.map((plugin) => {
|
|
654
|
-
if (!filterPlugin(plugin) || !plugin.emit) return [];
|
|
655
|
-
return plugin.emit.call(this.getPluginContext());
|
|
656
|
-
})
|
|
657
|
-
);
|
|
658
|
-
await Promise.all(
|
|
659
|
-
out.flat().map(async (entry) => {
|
|
660
|
-
const file = import_node_path4.default.join(options.outDir, entry.path);
|
|
661
|
-
await import_promises2.default.mkdir(import_node_path4.default.dirname(file), { recursive: true });
|
|
662
|
-
await import_promises2.default.writeFile(file, entry.content);
|
|
663
|
-
})
|
|
664
|
-
);
|
|
665
|
-
console.log(`[MDX] generated files in ${performance.now() - start}ms`);
|
|
666
|
-
}
|
|
667
|
-
};
|
|
865
|
+
import: "default",
|
|
866
|
+
base: collection.dir,
|
|
867
|
+
eager
|
|
868
|
+
});
|
|
668
869
|
}
|
|
669
870
|
|
|
670
|
-
// src/loaders/index.ts
|
|
671
|
-
var mdxLoaderGlob = /\.mdx?(\?.+?)?$/;
|
|
672
|
-
|
|
673
871
|
// src/next/index.ts
|
|
674
872
|
var defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
|
|
675
873
|
function createMDX(createOptions = {}) {
|
|
676
|
-
const
|
|
874
|
+
const core = createNextCore(applyDefaults(createOptions));
|
|
677
875
|
const isDev = process.env.NODE_ENV === "development";
|
|
678
876
|
if (process.env._FUMADOCS_MDX !== "1") {
|
|
679
877
|
process.env._FUMADOCS_MDX = "1";
|
|
680
|
-
void init(isDev,
|
|
878
|
+
void init(isDev, core);
|
|
681
879
|
}
|
|
682
880
|
return (nextConfig = {}) => {
|
|
683
881
|
const loaderOptions = {
|
|
684
|
-
...
|
|
882
|
+
...core._options,
|
|
883
|
+
compiledConfigPath: core.getCompiledConfigPath(),
|
|
685
884
|
isDev
|
|
686
885
|
};
|
|
687
886
|
const turbopack = {
|
|
@@ -696,6 +895,24 @@ function createMDX(createOptions = {}) {
|
|
|
696
895
|
}
|
|
697
896
|
],
|
|
698
897
|
as: "*.js"
|
|
898
|
+
},
|
|
899
|
+
"*.json": {
|
|
900
|
+
loaders: [
|
|
901
|
+
{
|
|
902
|
+
loader: "fumadocs-mdx/loader-meta",
|
|
903
|
+
options: loaderOptions
|
|
904
|
+
}
|
|
905
|
+
],
|
|
906
|
+
as: "*.json"
|
|
907
|
+
},
|
|
908
|
+
"*.yaml": {
|
|
909
|
+
loaders: [
|
|
910
|
+
{
|
|
911
|
+
loader: "fumadocs-mdx/loader-meta",
|
|
912
|
+
options: loaderOptions
|
|
913
|
+
}
|
|
914
|
+
],
|
|
915
|
+
as: "*.js"
|
|
699
916
|
}
|
|
700
917
|
}
|
|
701
918
|
};
|
|
@@ -703,31 +920,42 @@ function createMDX(createOptions = {}) {
|
|
|
703
920
|
...nextConfig,
|
|
704
921
|
turbopack,
|
|
705
922
|
pageExtensions: nextConfig.pageExtensions ?? defaultPageExtensions,
|
|
706
|
-
webpack: (config,
|
|
923
|
+
webpack: (config, options) => {
|
|
707
924
|
config.resolve ||= {};
|
|
708
925
|
config.module ||= {};
|
|
709
926
|
config.module.rules ||= [];
|
|
710
|
-
config.module.rules.push(
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
927
|
+
config.module.rules.push(
|
|
928
|
+
{
|
|
929
|
+
test: mdxLoaderGlob,
|
|
930
|
+
use: [
|
|
931
|
+
options.defaultLoaders.babel,
|
|
932
|
+
{
|
|
933
|
+
loader: "fumadocs-mdx/loader-mdx",
|
|
934
|
+
options: loaderOptions
|
|
935
|
+
}
|
|
936
|
+
]
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
test: metaLoaderGlob,
|
|
940
|
+
use: [
|
|
941
|
+
options.defaultLoaders.babel,
|
|
942
|
+
{
|
|
943
|
+
loader: "fumadocs-mdx/loader-meta",
|
|
944
|
+
options: loaderOptions
|
|
945
|
+
}
|
|
946
|
+
]
|
|
947
|
+
}
|
|
948
|
+
);
|
|
720
949
|
config.plugins ||= [];
|
|
721
|
-
return nextConfig.webpack?.(config,
|
|
950
|
+
return nextConfig.webpack?.(config, options) ?? config;
|
|
722
951
|
}
|
|
723
952
|
};
|
|
724
953
|
};
|
|
725
954
|
}
|
|
726
|
-
async function init(dev,
|
|
727
|
-
const core = createNextCore(options);
|
|
955
|
+
async function init(dev, core) {
|
|
728
956
|
async function initOrReload() {
|
|
729
957
|
await core.init({
|
|
730
|
-
config: loadConfig(
|
|
958
|
+
config: loadConfig(core, true)
|
|
731
959
|
});
|
|
732
960
|
await core.emitAndWrite();
|
|
733
961
|
}
|
|
@@ -736,9 +964,9 @@ async function init(dev, options) {
|
|
|
736
964
|
const watcher = new FSWatcher({
|
|
737
965
|
ignoreInitial: true,
|
|
738
966
|
persistent: true,
|
|
739
|
-
ignored: [
|
|
967
|
+
ignored: [core._options.outDir]
|
|
740
968
|
});
|
|
741
|
-
watcher.add(
|
|
969
|
+
watcher.add(core._options.configPath);
|
|
742
970
|
for (const collection of core.getConfig().collectionList) {
|
|
743
971
|
if (collection.type === "docs") {
|
|
744
972
|
watcher.add(collection.docs.dir);
|
|
@@ -750,10 +978,8 @@ async function init(dev, options) {
|
|
|
750
978
|
watcher.on("ready", () => {
|
|
751
979
|
console.log("[MDX] started dev server");
|
|
752
980
|
});
|
|
753
|
-
watcher.on("all", async (
|
|
754
|
-
|
|
755
|
-
if (event === "change") removeFileCache(absolutePath);
|
|
756
|
-
if (absolutePath === path7.resolve(options.configPath)) {
|
|
981
|
+
watcher.on("all", async (_event, file) => {
|
|
982
|
+
if (path5.resolve(file) === path5.resolve(core._options.configPath)) {
|
|
757
983
|
watcher.removeAllListeners();
|
|
758
984
|
await watcher.close();
|
|
759
985
|
await initOrReload();
|
|
@@ -773,32 +999,28 @@ async function init(dev, options) {
|
|
|
773
999
|
await devServer();
|
|
774
1000
|
}
|
|
775
1001
|
}
|
|
776
|
-
async function postInstall(
|
|
777
|
-
const core =
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
}).init({
|
|
781
|
-
config: loadConfig(configPath, outDir, true)
|
|
1002
|
+
async function postInstall(options) {
|
|
1003
|
+
const core = createNextCore(applyDefaults(options));
|
|
1004
|
+
await core.init({
|
|
1005
|
+
config: loadConfig(core, true)
|
|
782
1006
|
});
|
|
783
1007
|
await core.emitAndWrite();
|
|
784
1008
|
}
|
|
785
1009
|
function applyDefaults(options) {
|
|
786
1010
|
return {
|
|
787
|
-
|
|
788
|
-
|
|
1011
|
+
index: {},
|
|
1012
|
+
outDir: options.outDir ?? _Defaults.outDir,
|
|
1013
|
+
configPath: options.configPath ?? _Defaults.configPath
|
|
789
1014
|
};
|
|
790
1015
|
}
|
|
791
|
-
function createNextCore({
|
|
792
|
-
outDir,
|
|
793
|
-
configPath
|
|
794
|
-
}) {
|
|
1016
|
+
function createNextCore(options) {
|
|
795
1017
|
const core = createCore(
|
|
796
1018
|
{
|
|
797
1019
|
environment: "next",
|
|
798
|
-
outDir,
|
|
799
|
-
configPath
|
|
1020
|
+
outDir: options.outDir,
|
|
1021
|
+
configPath: options.configPath
|
|
800
1022
|
},
|
|
801
|
-
[
|
|
1023
|
+
[options.index && indexFile(options.index)]
|
|
802
1024
|
);
|
|
803
1025
|
return {
|
|
804
1026
|
...core,
|
|
@@ -807,7 +1029,7 @@ function createNextCore({
|
|
|
807
1029
|
await core.emitAndWrite(...args);
|
|
808
1030
|
} catch (err) {
|
|
809
1031
|
if (err instanceof ValidationError) {
|
|
810
|
-
console.error(err.toStringFormatted());
|
|
1032
|
+
console.error(await err.toStringFormatted());
|
|
811
1033
|
} else {
|
|
812
1034
|
console.error(err);
|
|
813
1035
|
}
|