fumadocs-mdx 11.6.0 → 13.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.
- package/dist/bin.cjs +1728 -0
- package/dist/bin.d.cts +1 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +16 -0
- package/dist/build-mdx-CCNr86q6.d.ts +53 -0
- package/dist/build-mdx-D-r3_eQL.d.cts +53 -0
- package/dist/bun/index.cjs +857 -0
- package/dist/bun/index.d.cts +13 -0
- package/dist/bun/index.d.ts +13 -0
- package/dist/bun/index.js +62 -0
- package/dist/chunk-3J3WL7WN.js +160 -0
- package/dist/chunk-CXA4JO4Z.js +45 -0
- package/dist/chunk-EELYB2XC.js +207 -0
- package/dist/chunk-FSZMKRVH.js +80 -0
- package/dist/chunk-II3H5ZVZ.js +77 -0
- package/dist/chunk-JVZFH6ND.js +40 -0
- package/dist/chunk-K5ZLPEIQ.js +207 -0
- package/dist/{chunk-VFALQK6O.js → chunk-KILFIBVW.js} +21 -12
- package/dist/chunk-NVRDCY6Z.js +30 -0
- package/dist/chunk-U4MQ44TS.js +53 -0
- package/dist/chunk-VWJKRQZR.js +19 -0
- package/dist/chunk-XQ5O7IPO.js +128 -0
- package/dist/chunk-XZY2AWJI.js +81 -0
- package/dist/chunk-YVCR6FUH.js +82 -0
- package/dist/config/index.cjs +232 -128
- package/dist/config/index.d.cts +4 -6
- package/dist/config/index.d.ts +4 -6
- package/dist/config/index.js +26 -19
- package/dist/core-B6j6Fxse.d.cts +218 -0
- package/dist/core-B6j6Fxse.d.ts +218 -0
- package/dist/index.cjs +0 -76
- package/dist/index.d.cts +73 -20
- package/dist/index.d.ts +73 -20
- package/dist/index.js +0 -10
- package/dist/load-MNG3CLET.js +7 -0
- package/dist/next/index.cjs +567 -314
- package/dist/next/index.d.cts +9 -12
- package/dist/next/index.d.ts +9 -12
- package/dist/next/index.js +238 -211
- package/dist/node/loader.cjs +922 -0
- package/dist/node/loader.d.cts +5 -0
- package/dist/node/loader.d.ts +5 -0
- package/dist/node/loader.js +33 -0
- package/dist/plugins/json-schema.cjs +162 -0
- package/dist/plugins/json-schema.d.cts +24 -0
- package/dist/plugins/json-schema.d.ts +24 -0
- package/dist/plugins/json-schema.js +78 -0
- package/dist/{mdx-options-CAU273O3.js → preset-ZMP6U62C.js} +1 -1
- package/dist/runtime/next/async.cjs +715 -0
- package/dist/runtime/next/async.d.cts +21 -0
- package/dist/runtime/next/async.d.ts +21 -0
- package/dist/runtime/next/async.js +89 -0
- package/dist/runtime/next/index.cjs +136 -0
- package/dist/runtime/next/index.d.cts +33 -0
- package/dist/runtime/next/index.d.ts +33 -0
- package/dist/runtime/next/index.js +11 -0
- package/dist/runtime/vite/browser.cjs +107 -0
- package/dist/runtime/vite/browser.d.cts +59 -0
- package/dist/runtime/vite/browser.d.ts +59 -0
- package/dist/runtime/vite/browser.js +11 -0
- package/dist/runtime/vite/server.cjs +243 -0
- package/dist/runtime/vite/server.d.cts +30 -0
- package/dist/runtime/vite/server.d.ts +30 -0
- package/dist/runtime/vite/server.js +111 -0
- package/dist/types-AGzTfBmf.d.ts +45 -0
- package/dist/types-DKGMoay5.d.cts +45 -0
- package/dist/vite/index.cjs +1185 -0
- package/dist/vite/index.d.cts +45 -0
- package/dist/vite/index.d.ts +45 -0
- package/dist/vite/index.js +297 -0
- package/dist/webpack/index.cjs +957 -0
- package/dist/{loader-mdx.d.cts → webpack/index.d.cts} +3 -6
- package/dist/{loader-mdx.d.ts → webpack/index.d.ts} +3 -6
- package/dist/webpack/index.js +44 -0
- package/loader-mdx.cjs +1 -1
- package/package.json +86 -29
- package/bin.js +0 -5
- package/dist/chunk-2ZOW45YZ.js +0 -63
- package/dist/chunk-DRVUBK5B.js +0 -39
- package/dist/chunk-HFLDWPJA.js +0 -62
- package/dist/chunk-IOENRFUX.js +0 -112
- package/dist/chunk-MK7EXW7O.js +0 -75
- package/dist/define-BaW0PQDJ.d.cts +0 -201
- package/dist/define-BaW0PQDJ.d.ts +0 -201
- package/dist/loader-mdx.cjs +0 -527
- package/dist/loader-mdx.js +0 -162
- package/dist/runtime/async.cjs +0 -269
- package/dist/runtime/async.d.cts +0 -18
- package/dist/runtime/async.d.ts +0 -18
- package/dist/runtime/async.js +0 -73
- package/dist/types-BNrQHCj5.d.cts +0 -100
- package/dist/types-DEduCvIT.d.ts +0 -100
- package/dist/watcher-IAZDSTU7.js +0 -24
package/dist/bin.cjs
ADDED
|
@@ -0,0 +1,1728 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
12
|
+
var __export = (target, all) => {
|
|
13
|
+
for (var name in all)
|
|
14
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
+
mod
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
// src/loaders/config/index.ts
|
|
34
|
+
function findConfigFile() {
|
|
35
|
+
return import_node_path.default.resolve("source.config.ts");
|
|
36
|
+
}
|
|
37
|
+
var import_node_path, import_promises;
|
|
38
|
+
var init_config = __esm({
|
|
39
|
+
"src/loaders/config/index.ts"() {
|
|
40
|
+
"use strict";
|
|
41
|
+
import_node_path = __toESM(require("path"), 1);
|
|
42
|
+
import_promises = __toESM(require("fs/promises"), 1);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// src/loaders/mdx/preset.ts
|
|
47
|
+
var preset_exports = {};
|
|
48
|
+
__export(preset_exports, {
|
|
49
|
+
getDefaultMDXOptions: () => getDefaultMDXOptions
|
|
50
|
+
});
|
|
51
|
+
function pluginOption(def, options = []) {
|
|
52
|
+
const list = def(Array.isArray(options) ? options : []).filter(
|
|
53
|
+
Boolean
|
|
54
|
+
);
|
|
55
|
+
if (typeof options === "function") {
|
|
56
|
+
return options(list);
|
|
57
|
+
}
|
|
58
|
+
return list;
|
|
59
|
+
}
|
|
60
|
+
function getDefaultMDXOptions({
|
|
61
|
+
valueToExport = [],
|
|
62
|
+
rehypeCodeOptions,
|
|
63
|
+
remarkImageOptions,
|
|
64
|
+
remarkHeadingOptions,
|
|
65
|
+
remarkStructureOptions,
|
|
66
|
+
remarkCodeTabOptions,
|
|
67
|
+
remarkNpmOptions,
|
|
68
|
+
_withoutBundler = false,
|
|
69
|
+
...mdxOptions
|
|
70
|
+
}) {
|
|
71
|
+
const remarkPlugins = pluginOption(
|
|
72
|
+
(v) => [
|
|
73
|
+
plugins.remarkGfm,
|
|
74
|
+
[
|
|
75
|
+
plugins.remarkHeading,
|
|
76
|
+
{
|
|
77
|
+
generateToc: false,
|
|
78
|
+
...remarkHeadingOptions
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
remarkImageOptions !== false && [
|
|
82
|
+
plugins.remarkImage,
|
|
83
|
+
{
|
|
84
|
+
...remarkImageOptions,
|
|
85
|
+
useImport: _withoutBundler ? false : remarkImageOptions?.useImport
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"remarkCodeTab" in plugins && remarkCodeTabOptions !== false && [
|
|
89
|
+
plugins.remarkCodeTab,
|
|
90
|
+
remarkCodeTabOptions
|
|
91
|
+
],
|
|
92
|
+
"remarkNpm" in plugins && remarkNpmOptions !== false && [plugins.remarkNpm, remarkNpmOptions],
|
|
93
|
+
...v,
|
|
94
|
+
remarkStructureOptions !== false && [
|
|
95
|
+
plugins.remarkStructure,
|
|
96
|
+
remarkStructureOptions
|
|
97
|
+
],
|
|
98
|
+
() => {
|
|
99
|
+
return (_, file) => {
|
|
100
|
+
file.data["mdx-export"] ??= [];
|
|
101
|
+
for (const name of valueToExport) {
|
|
102
|
+
if (name in file.data)
|
|
103
|
+
file.data["mdx-export"].push({ name, value: file.data[name] });
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
mdxOptions.remarkPlugins
|
|
109
|
+
);
|
|
110
|
+
const rehypePlugins = pluginOption(
|
|
111
|
+
(v) => [
|
|
112
|
+
rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
|
|
113
|
+
...v,
|
|
114
|
+
plugins.rehypeToc
|
|
115
|
+
],
|
|
116
|
+
mdxOptions.rehypePlugins
|
|
117
|
+
);
|
|
118
|
+
return {
|
|
119
|
+
...mdxOptions,
|
|
120
|
+
outputFormat: _withoutBundler ? "function-body" : mdxOptions.outputFormat,
|
|
121
|
+
remarkPlugins,
|
|
122
|
+
rehypePlugins
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
var plugins;
|
|
126
|
+
var init_preset = __esm({
|
|
127
|
+
"src/loaders/mdx/preset.ts"() {
|
|
128
|
+
"use strict";
|
|
129
|
+
plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// src/config/build.ts
|
|
134
|
+
function buildConfig(config) {
|
|
135
|
+
const collections = /* @__PURE__ */ new Map();
|
|
136
|
+
let globalConfig = {};
|
|
137
|
+
for (const [k, v] of Object.entries(config)) {
|
|
138
|
+
if (!v) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (typeof v === "object" && "type" in v) {
|
|
142
|
+
if (v.type === "docs") {
|
|
143
|
+
collections.set(k, v);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (v.type === "doc" || v.type === "meta") {
|
|
147
|
+
collections.set(k, v);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (k === "default" && v) {
|
|
152
|
+
globalConfig = v;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Unknown export "${k}", you can only export collections from source configuration file.`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const mdxOptionsCache = /* @__PURE__ */ new Map();
|
|
160
|
+
return {
|
|
161
|
+
global: globalConfig,
|
|
162
|
+
collections,
|
|
163
|
+
async getDefaultMDXOptions(mode = "default") {
|
|
164
|
+
const cached = mdxOptionsCache.get(mode);
|
|
165
|
+
if (cached) return cached;
|
|
166
|
+
const input = this.global.mdxOptions;
|
|
167
|
+
async function uncached() {
|
|
168
|
+
const options = typeof input === "function" ? await input() : input;
|
|
169
|
+
const { getDefaultMDXOptions: getDefaultMDXOptions2 } = await Promise.resolve().then(() => (init_preset(), preset_exports));
|
|
170
|
+
if (options?.preset === "minimal") return options;
|
|
171
|
+
return getDefaultMDXOptions2({
|
|
172
|
+
...options,
|
|
173
|
+
_withoutBundler: mode === "remote"
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const result = uncached();
|
|
177
|
+
mdxOptionsCache.set(mode, result);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
var init_build = __esm({
|
|
183
|
+
"src/config/build.ts"() {
|
|
184
|
+
"use strict";
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// src/loaders/config/load.ts
|
|
189
|
+
var load_exports = {};
|
|
190
|
+
__export(load_exports, {
|
|
191
|
+
loadConfig: () => loadConfig
|
|
192
|
+
});
|
|
193
|
+
async function compileConfig(configPath, outDir) {
|
|
194
|
+
const { build } = await import("esbuild");
|
|
195
|
+
const transformed = await build({
|
|
196
|
+
entryPoints: [{ in: configPath, out: "source.config" }],
|
|
197
|
+
bundle: true,
|
|
198
|
+
outdir: outDir,
|
|
199
|
+
target: "node20",
|
|
200
|
+
write: true,
|
|
201
|
+
platform: "node",
|
|
202
|
+
format: "esm",
|
|
203
|
+
packages: "external",
|
|
204
|
+
outExtension: {
|
|
205
|
+
".js": ".mjs"
|
|
206
|
+
},
|
|
207
|
+
allowOverwrite: true
|
|
208
|
+
});
|
|
209
|
+
if (transformed.errors.length > 0) {
|
|
210
|
+
throw new Error("failed to compile configuration file");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async function loadConfig(configPath, outDir, build = false) {
|
|
214
|
+
if (build) await compileConfig(configPath, outDir);
|
|
215
|
+
const url = (0, import_node_url.pathToFileURL)(path2.resolve(outDir, "source.config.mjs"));
|
|
216
|
+
url.searchParams.set("hash", Date.now().toString());
|
|
217
|
+
const config = import(url.href).then(
|
|
218
|
+
(loaded) => buildConfig(loaded)
|
|
219
|
+
);
|
|
220
|
+
return await config;
|
|
221
|
+
}
|
|
222
|
+
var path2, import_node_url;
|
|
223
|
+
var init_load = __esm({
|
|
224
|
+
"src/loaders/config/load.ts"() {
|
|
225
|
+
"use strict";
|
|
226
|
+
path2 = __toESM(require("path"), 1);
|
|
227
|
+
import_node_url = require("url");
|
|
228
|
+
init_build();
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// src/next/file-cache.ts
|
|
233
|
+
function toFullPath(file) {
|
|
234
|
+
if (import_node_path2.default.isAbsolute(file)) {
|
|
235
|
+
return import_node_path2.default.relative(process.cwd(), file);
|
|
236
|
+
}
|
|
237
|
+
return file;
|
|
238
|
+
}
|
|
239
|
+
async function readFileWithCache(file) {
|
|
240
|
+
const fullPath = toFullPath(file);
|
|
241
|
+
const cached = map.get(fullPath);
|
|
242
|
+
if (cached) return cached;
|
|
243
|
+
const read = import_promises2.default.readFile(fullPath).then((s) => s.toString());
|
|
244
|
+
map.set(fullPath, read);
|
|
245
|
+
return read;
|
|
246
|
+
}
|
|
247
|
+
function removeFileCache(file) {
|
|
248
|
+
map.delete(toFullPath(file));
|
|
249
|
+
}
|
|
250
|
+
var import_lru_cache, import_promises2, import_node_path2, map;
|
|
251
|
+
var init_file_cache = __esm({
|
|
252
|
+
"src/next/file-cache.ts"() {
|
|
253
|
+
"use strict";
|
|
254
|
+
import_lru_cache = require("lru-cache");
|
|
255
|
+
import_promises2 = __toESM(require("fs/promises"), 1);
|
|
256
|
+
import_node_path2 = __toESM(require("path"), 1);
|
|
257
|
+
map = new import_lru_cache.LRUCache({
|
|
258
|
+
max: 100
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// src/utils/validation.ts
|
|
264
|
+
async function validate(schema, data, context, errorMessage) {
|
|
265
|
+
if (typeof schema === "function" && !("~standard" in schema)) {
|
|
266
|
+
schema = schema(context);
|
|
267
|
+
}
|
|
268
|
+
if ("~standard" in schema) {
|
|
269
|
+
const result = await schema["~standard"].validate(
|
|
270
|
+
data
|
|
271
|
+
);
|
|
272
|
+
if (result.issues) {
|
|
273
|
+
throw new ValidationError(errorMessage, result.issues);
|
|
274
|
+
}
|
|
275
|
+
return result.value;
|
|
276
|
+
}
|
|
277
|
+
return data;
|
|
278
|
+
}
|
|
279
|
+
var import_picocolors, ValidationError;
|
|
280
|
+
var init_validation = __esm({
|
|
281
|
+
"src/utils/validation.ts"() {
|
|
282
|
+
"use strict";
|
|
283
|
+
import_picocolors = __toESM(require("picocolors"), 1);
|
|
284
|
+
ValidationError = class extends Error {
|
|
285
|
+
constructor(message, issues) {
|
|
286
|
+
super(
|
|
287
|
+
`${message}:
|
|
288
|
+
${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
|
|
289
|
+
);
|
|
290
|
+
this.title = message;
|
|
291
|
+
this.issues = issues;
|
|
292
|
+
}
|
|
293
|
+
toStringFormatted() {
|
|
294
|
+
return [
|
|
295
|
+
import_picocolors.default.bold(`[MDX] ${this.title}:`),
|
|
296
|
+
...this.issues.map(
|
|
297
|
+
(issue) => import_picocolors.default.redBright(
|
|
298
|
+
`- ${import_picocolors.default.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
|
|
299
|
+
)
|
|
300
|
+
)
|
|
301
|
+
].join("\n");
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// src/utils/git-timestamp.ts
|
|
308
|
+
async function getGitTimestamp(file) {
|
|
309
|
+
const cached = cache.get(file);
|
|
310
|
+
if (cached) return cached;
|
|
311
|
+
try {
|
|
312
|
+
const out = await (0, import_tinyexec.x)(
|
|
313
|
+
"git",
|
|
314
|
+
["log", "-1", '--pretty="%ai"', import_node_path3.default.relative(process.cwd(), file)],
|
|
315
|
+
{
|
|
316
|
+
throwOnError: true
|
|
317
|
+
}
|
|
318
|
+
);
|
|
319
|
+
const time = new Date(out.stdout);
|
|
320
|
+
cache.set(file, time);
|
|
321
|
+
return time;
|
|
322
|
+
} catch {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
var import_node_path3, import_tinyexec, cache;
|
|
327
|
+
var init_git_timestamp = __esm({
|
|
328
|
+
"src/utils/git-timestamp.ts"() {
|
|
329
|
+
"use strict";
|
|
330
|
+
import_node_path3 = __toESM(require("path"), 1);
|
|
331
|
+
import_tinyexec = require("tinyexec");
|
|
332
|
+
cache = /* @__PURE__ */ new Map();
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// src/utils/fuma-matter.ts
|
|
337
|
+
function fumaMatter(input) {
|
|
338
|
+
const output = { matter: "", data: {}, content: input };
|
|
339
|
+
const match = regex.exec(input);
|
|
340
|
+
if (!match) {
|
|
341
|
+
return output;
|
|
342
|
+
}
|
|
343
|
+
output.matter = match[0];
|
|
344
|
+
output.content = input.slice(match[0].length);
|
|
345
|
+
const loaded = (0, import_js_yaml.load)(match[1]);
|
|
346
|
+
output.data = loaded ?? {};
|
|
347
|
+
return output;
|
|
348
|
+
}
|
|
349
|
+
var import_js_yaml, regex;
|
|
350
|
+
var init_fuma_matter = __esm({
|
|
351
|
+
"src/utils/fuma-matter.ts"() {
|
|
352
|
+
"use strict";
|
|
353
|
+
import_js_yaml = require("js-yaml");
|
|
354
|
+
regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
// src/utils/import-formatter.ts
|
|
359
|
+
function getImportCode(info) {
|
|
360
|
+
const specifier = JSON.stringify(info.specifier);
|
|
361
|
+
if (info.type === "default") return `import ${info.name} from ${specifier}`;
|
|
362
|
+
if (info.type === "namespace")
|
|
363
|
+
return `import * as ${info.name} from ${specifier}`;
|
|
364
|
+
if (info.type === "named") {
|
|
365
|
+
const names = info.names.map(
|
|
366
|
+
(name) => Array.isArray(name) ? `${name[0]} as ${name[1]}` : name
|
|
367
|
+
);
|
|
368
|
+
return `import { ${names.join(", ")} } from ${specifier}`;
|
|
369
|
+
}
|
|
370
|
+
return `import ${specifier}`;
|
|
371
|
+
}
|
|
372
|
+
function toImportPath(file, config) {
|
|
373
|
+
const ext = import_node_path4.default.extname(file);
|
|
374
|
+
let filename;
|
|
375
|
+
if (ext === ".ts" && config.jsExtension) {
|
|
376
|
+
filename = file.substring(0, file.length - ext.length) + ".js";
|
|
377
|
+
} else if (ext === ".ts") {
|
|
378
|
+
filename = file.substring(0, file.length - ext.length);
|
|
379
|
+
} else {
|
|
380
|
+
filename = file;
|
|
381
|
+
}
|
|
382
|
+
let importPath;
|
|
383
|
+
if ("relativeTo" in config) {
|
|
384
|
+
importPath = import_node_path4.default.relative(config.relativeTo, filename);
|
|
385
|
+
if (!import_node_path4.default.isAbsolute(importPath) && !importPath.startsWith(".")) {
|
|
386
|
+
importPath = `./${importPath}`;
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
importPath = import_node_path4.default.resolve(filename);
|
|
390
|
+
}
|
|
391
|
+
return importPath.replaceAll(import_node_path4.default.sep, "/");
|
|
392
|
+
}
|
|
393
|
+
function ident(code, tab = 1) {
|
|
394
|
+
return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
|
|
395
|
+
}
|
|
396
|
+
var import_node_path4;
|
|
397
|
+
var init_import_formatter = __esm({
|
|
398
|
+
"src/utils/import-formatter.ts"() {
|
|
399
|
+
"use strict";
|
|
400
|
+
import_node_path4 = __toESM(require("path"), 1);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// src/utils/collections.ts
|
|
405
|
+
function getGlobPatterns(collection) {
|
|
406
|
+
if (collection.files) return collection.files;
|
|
407
|
+
return [`**/*.{${SupportedFormats[collection.type].join(",")}}`];
|
|
408
|
+
}
|
|
409
|
+
function isFileSupported(filePath, collection) {
|
|
410
|
+
return SupportedFormats[collection.type].some(
|
|
411
|
+
(format) => filePath.endsWith(`.${format}`)
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
async function getCollectionFiles(collection) {
|
|
415
|
+
const files = /* @__PURE__ */ new Map();
|
|
416
|
+
const dirs = Array.isArray(collection.dir) ? collection.dir : [collection.dir];
|
|
417
|
+
const patterns = getGlobPatterns(collection);
|
|
418
|
+
await Promise.all(
|
|
419
|
+
dirs.map(async (dir) => {
|
|
420
|
+
const result = await (0, import_tinyglobby.glob)(patterns, {
|
|
421
|
+
cwd: import_node_path5.default.resolve(dir)
|
|
422
|
+
});
|
|
423
|
+
for (const item of result) {
|
|
424
|
+
if (!isFileSupported(item, collection)) continue;
|
|
425
|
+
const fullPath = import_node_path5.default.join(dir, item);
|
|
426
|
+
files.set(fullPath, {
|
|
427
|
+
path: item,
|
|
428
|
+
fullPath
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
})
|
|
432
|
+
);
|
|
433
|
+
return Array.from(files.values());
|
|
434
|
+
}
|
|
435
|
+
var import_picomatch, import_tinyglobby, import_node_path5, SupportedFormats;
|
|
436
|
+
var init_collections = __esm({
|
|
437
|
+
"src/utils/collections.ts"() {
|
|
438
|
+
"use strict";
|
|
439
|
+
import_picomatch = __toESM(require("picomatch"), 1);
|
|
440
|
+
import_tinyglobby = require("tinyglobby");
|
|
441
|
+
import_node_path5 = __toESM(require("path"), 1);
|
|
442
|
+
SupportedFormats = {
|
|
443
|
+
doc: ["mdx", "md"],
|
|
444
|
+
meta: ["json", "yaml"]
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// src/plugins/next.ts
|
|
450
|
+
function next() {
|
|
451
|
+
let config;
|
|
452
|
+
let shouldEmitOnChange = false;
|
|
453
|
+
return {
|
|
454
|
+
name: "next",
|
|
455
|
+
config(v) {
|
|
456
|
+
config = v;
|
|
457
|
+
shouldEmitOnChange = false;
|
|
458
|
+
for (const collection of config.collections.values()) {
|
|
459
|
+
if (collection.type === "doc" && collection.async || collection.type === "docs" && collection.docs.async) {
|
|
460
|
+
shouldEmitOnChange = true;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
configureServer(server) {
|
|
465
|
+
if (!server.watcher) return;
|
|
466
|
+
server.watcher.on("all", async () => {
|
|
467
|
+
if (!shouldEmitOnChange) return;
|
|
468
|
+
await this.core.emitAndWrite({
|
|
469
|
+
filterPlugin: (plugin) => plugin.name === "next"
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
},
|
|
473
|
+
async emit() {
|
|
474
|
+
return [
|
|
475
|
+
{
|
|
476
|
+
path: "index.ts",
|
|
477
|
+
content: await indexFile(this.configPath, config, {
|
|
478
|
+
relativeTo: this.outDir
|
|
479
|
+
})
|
|
480
|
+
}
|
|
481
|
+
];
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
async function indexFile(configPath, config, importPath, configHash = false) {
|
|
486
|
+
let asyncInit = false;
|
|
487
|
+
const lines = [
|
|
488
|
+
getImportCode({
|
|
489
|
+
type: "named",
|
|
490
|
+
names: ["_runtime"],
|
|
491
|
+
specifier: "fumadocs-mdx/runtime/next"
|
|
492
|
+
}),
|
|
493
|
+
getImportCode({
|
|
494
|
+
type: "namespace",
|
|
495
|
+
specifier: toImportPath(configPath, importPath),
|
|
496
|
+
name: "_source"
|
|
497
|
+
})
|
|
498
|
+
];
|
|
499
|
+
const entries = Array.from(config.collections.entries());
|
|
500
|
+
async function getDocEntries(collectionName, files) {
|
|
501
|
+
const items = files.map(async (file, i) => {
|
|
502
|
+
const importId = `${collectionName}_${i}`;
|
|
503
|
+
const params = [`collection=${collectionName}`];
|
|
504
|
+
if (configHash) {
|
|
505
|
+
params.push(`hash=${configHash}`);
|
|
506
|
+
}
|
|
507
|
+
lines.unshift(
|
|
508
|
+
getImportCode({
|
|
509
|
+
type: "namespace",
|
|
510
|
+
name: importId,
|
|
511
|
+
specifier: `${toImportPath(file.fullPath, importPath)}?${params.join("&")}`
|
|
512
|
+
})
|
|
513
|
+
);
|
|
514
|
+
return `{ info: ${JSON.stringify(file)}, data: ${importId} }`;
|
|
515
|
+
});
|
|
516
|
+
return Promise.all(items);
|
|
517
|
+
}
|
|
518
|
+
async function getMetaEntries(collection, files) {
|
|
519
|
+
const items = files.map(async (file) => {
|
|
520
|
+
const source = await readFileWithCache(file.fullPath).catch(() => "");
|
|
521
|
+
let data = source.length === 0 ? {} : parseMetaEntry(file.fullPath, source);
|
|
522
|
+
if (collection?.schema) {
|
|
523
|
+
data = await validate(
|
|
524
|
+
collection.schema,
|
|
525
|
+
data,
|
|
526
|
+
{
|
|
527
|
+
source,
|
|
528
|
+
path: file.fullPath
|
|
529
|
+
},
|
|
530
|
+
`invalid data in ${file.fullPath}`
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
return JSON.stringify({
|
|
534
|
+
info: file,
|
|
535
|
+
data
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
return Promise.all(items);
|
|
539
|
+
}
|
|
540
|
+
async function getAsyncEntries(collection, files) {
|
|
541
|
+
if (!asyncInit) {
|
|
542
|
+
lines.unshift(
|
|
543
|
+
getImportCode({
|
|
544
|
+
type: "named",
|
|
545
|
+
specifier: "fumadocs-mdx/runtime/async",
|
|
546
|
+
names: ["_runtimeAsync", "buildConfig"]
|
|
547
|
+
}),
|
|
548
|
+
"const _sourceConfig = buildConfig(_source)",
|
|
549
|
+
getImportCode({
|
|
550
|
+
type: "default",
|
|
551
|
+
name: "path",
|
|
552
|
+
specifier: "node:path"
|
|
553
|
+
})
|
|
554
|
+
);
|
|
555
|
+
asyncInit = true;
|
|
556
|
+
}
|
|
557
|
+
const entries2 = files.map(async (file) => {
|
|
558
|
+
const content = await readFileWithCache(file.fullPath).catch(() => "");
|
|
559
|
+
const parsed = fumaMatter(content);
|
|
560
|
+
let data = parsed.data;
|
|
561
|
+
if (collection.schema) {
|
|
562
|
+
data = await validate(
|
|
563
|
+
collection.schema,
|
|
564
|
+
parsed.data,
|
|
565
|
+
{ path: file.fullPath, source: parsed.content },
|
|
566
|
+
`invalid frontmatter in ${file.fullPath}`
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
let lastModified;
|
|
570
|
+
if (config.global?.lastModifiedTime === "git") {
|
|
571
|
+
lastModified = await getGitTimestamp(file.fullPath);
|
|
572
|
+
}
|
|
573
|
+
const hash = (0, import_node_crypto.createHash)("md5").update(content).digest("hex");
|
|
574
|
+
const infoStr = [];
|
|
575
|
+
for (const [k, v] of Object.entries({ ...file, hash })) {
|
|
576
|
+
infoStr.push(`${k}: ${JSON.stringify(v)}`);
|
|
577
|
+
}
|
|
578
|
+
infoStr.push(
|
|
579
|
+
`absolutePath: path.resolve(${JSON.stringify(file.fullPath)})`
|
|
580
|
+
);
|
|
581
|
+
return `{ info: { ${infoStr.join(", ")} }, lastModified: ${JSON.stringify(lastModified)}, data: ${JSON.stringify(data)} }`;
|
|
582
|
+
});
|
|
583
|
+
return Promise.all(entries2);
|
|
584
|
+
}
|
|
585
|
+
const declares = entries.map(async ([k, collection]) => {
|
|
586
|
+
if (collection.type === "docs") {
|
|
587
|
+
const docs = await getCollectionFiles(collection.docs);
|
|
588
|
+
const metas = await getCollectionFiles(collection.meta);
|
|
589
|
+
const metaEntries = (await getMetaEntries(collection.meta, metas)).join(
|
|
590
|
+
", "
|
|
591
|
+
);
|
|
592
|
+
if (collection.docs.async) {
|
|
593
|
+
const docsEntries2 = (await getAsyncEntries(collection.docs, docs)).join(
|
|
594
|
+
", "
|
|
595
|
+
);
|
|
596
|
+
return `export const ${k} = _runtimeAsync.docs<typeof _source.${k}>([${docsEntries2}], [${metaEntries}], "${k}", _sourceConfig)`;
|
|
597
|
+
}
|
|
598
|
+
const docsEntries = (await getDocEntries(k, docs)).join(", ");
|
|
599
|
+
return `export const ${k} = _runtime.docs<typeof _source.${k}>([${docsEntries}], [${metaEntries}])`;
|
|
600
|
+
}
|
|
601
|
+
const files = await getCollectionFiles(collection);
|
|
602
|
+
if (collection.type === "doc" && collection.async) {
|
|
603
|
+
return `export const ${k} = _runtimeAsync.doc<typeof _source.${k}>([${(await getAsyncEntries(collection, files)).join(", ")}], "${k}", _sourceConfig)`;
|
|
604
|
+
}
|
|
605
|
+
return `export const ${k} = _runtime.${collection.type}<typeof _source.${k}>([${(await getDocEntries(k, files)).join(", ")}]);`;
|
|
606
|
+
});
|
|
607
|
+
const resolvedDeclares = await Promise.all(declares);
|
|
608
|
+
return [
|
|
609
|
+
`// @ts-nocheck -- skip type checking`,
|
|
610
|
+
...lines,
|
|
611
|
+
...resolvedDeclares
|
|
612
|
+
].join("\n");
|
|
613
|
+
}
|
|
614
|
+
function parseMetaEntry(file, content) {
|
|
615
|
+
const extname4 = path7.extname(file);
|
|
616
|
+
try {
|
|
617
|
+
if (extname4 === ".json") return JSON.parse(content);
|
|
618
|
+
if (extname4 === ".yaml") return (0, import_js_yaml2.load)(content);
|
|
619
|
+
} catch (e) {
|
|
620
|
+
throw new Error(`Failed to parse meta file: ${file}.`, {
|
|
621
|
+
cause: e
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
throw new Error(`Unknown meta file format: ${extname4}, in ${file}.`);
|
|
625
|
+
}
|
|
626
|
+
var path7, import_node_crypto, import_js_yaml2;
|
|
627
|
+
var init_next = __esm({
|
|
628
|
+
"src/plugins/next.ts"() {
|
|
629
|
+
"use strict";
|
|
630
|
+
path7 = __toESM(require("path"), 1);
|
|
631
|
+
import_node_crypto = require("crypto");
|
|
632
|
+
init_validation();
|
|
633
|
+
init_file_cache();
|
|
634
|
+
import_js_yaml2 = require("js-yaml");
|
|
635
|
+
init_git_timestamp();
|
|
636
|
+
init_fuma_matter();
|
|
637
|
+
init_import_formatter();
|
|
638
|
+
init_collections();
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// src/core.ts
|
|
643
|
+
function createCore(options, defaultPlugins = []) {
|
|
644
|
+
let config;
|
|
645
|
+
let plugins2;
|
|
646
|
+
return {
|
|
647
|
+
_options: options,
|
|
648
|
+
getPluginContext() {
|
|
649
|
+
return {
|
|
650
|
+
core: this,
|
|
651
|
+
...options
|
|
652
|
+
};
|
|
653
|
+
},
|
|
654
|
+
/**
|
|
655
|
+
* Convenient cache store, reset when config changes
|
|
656
|
+
*/
|
|
657
|
+
cache: /* @__PURE__ */ new Map(),
|
|
658
|
+
async init({ config: newConfig }) {
|
|
659
|
+
config = await newConfig;
|
|
660
|
+
this.cache.clear();
|
|
661
|
+
plugins2 = [];
|
|
662
|
+
for await (const option of [
|
|
663
|
+
...defaultPlugins,
|
|
664
|
+
...config.global.plugins ?? []
|
|
665
|
+
]) {
|
|
666
|
+
if (!option) continue;
|
|
667
|
+
if (Array.isArray(option)) plugins2.push(...option);
|
|
668
|
+
else plugins2.push(option);
|
|
669
|
+
}
|
|
670
|
+
for (const plugin of plugins2) {
|
|
671
|
+
const out = await plugin.config?.call(this.getPluginContext(), config);
|
|
672
|
+
if (out) config = out;
|
|
673
|
+
}
|
|
674
|
+
return this;
|
|
675
|
+
},
|
|
676
|
+
getConfig() {
|
|
677
|
+
return config;
|
|
678
|
+
},
|
|
679
|
+
creatConfigLoader() {
|
|
680
|
+
return {
|
|
681
|
+
getConfig() {
|
|
682
|
+
return config;
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
},
|
|
686
|
+
async initServer(server) {
|
|
687
|
+
for (const plugin of plugins2) {
|
|
688
|
+
await plugin.configureServer?.call(this.getPluginContext(), server);
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
async emitAndWrite({
|
|
692
|
+
filterPlugin = () => true
|
|
693
|
+
} = {}) {
|
|
694
|
+
const start2 = performance.now();
|
|
695
|
+
const out = await Promise.all(
|
|
696
|
+
plugins2.map((plugin) => {
|
|
697
|
+
if (!filterPlugin(plugin) || !plugin.emit) return [];
|
|
698
|
+
return plugin.emit.call(this.getPluginContext());
|
|
699
|
+
})
|
|
700
|
+
);
|
|
701
|
+
await Promise.all(
|
|
702
|
+
out.flat().map(async (entry) => {
|
|
703
|
+
const file = import_node_path6.default.join(options.outDir, entry.path);
|
|
704
|
+
await import_promises3.default.mkdir(import_node_path6.default.dirname(file), { recursive: true });
|
|
705
|
+
await import_promises3.default.writeFile(file, entry.content);
|
|
706
|
+
})
|
|
707
|
+
);
|
|
708
|
+
console.log(`[MDX] generated files in ${performance.now() - start2}ms`);
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
var import_node_path6, import_promises3;
|
|
713
|
+
var init_core = __esm({
|
|
714
|
+
"src/core.ts"() {
|
|
715
|
+
"use strict";
|
|
716
|
+
import_node_path6 = __toESM(require("path"), 1);
|
|
717
|
+
import_promises3 = __toESM(require("fs/promises"), 1);
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
// src/next/index.ts
|
|
722
|
+
var next_exports = {};
|
|
723
|
+
__export(next_exports, {
|
|
724
|
+
createMDX: () => createMDX,
|
|
725
|
+
postInstall: () => postInstall
|
|
726
|
+
});
|
|
727
|
+
function createMDX(createOptions = {}) {
|
|
728
|
+
const options = applyDefaults(createOptions);
|
|
729
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
730
|
+
if (process.env._FUMADOCS_MDX !== "1") {
|
|
731
|
+
process.env._FUMADOCS_MDX = "1";
|
|
732
|
+
void init(isDev, options);
|
|
733
|
+
}
|
|
734
|
+
return (nextConfig = {}) => {
|
|
735
|
+
const mdxLoaderOptions = {
|
|
736
|
+
...options,
|
|
737
|
+
isDev
|
|
738
|
+
};
|
|
739
|
+
const turbopack = {
|
|
740
|
+
...nextConfig.turbopack,
|
|
741
|
+
rules: {
|
|
742
|
+
...nextConfig.turbopack?.rules,
|
|
743
|
+
"*.{md,mdx}": {
|
|
744
|
+
loaders: [
|
|
745
|
+
{
|
|
746
|
+
loader: "fumadocs-mdx/loader-mdx",
|
|
747
|
+
options: mdxLoaderOptions
|
|
748
|
+
}
|
|
749
|
+
],
|
|
750
|
+
as: "*.js"
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
return {
|
|
755
|
+
...nextConfig,
|
|
756
|
+
turbopack,
|
|
757
|
+
pageExtensions: nextConfig.pageExtensions ?? defaultPageExtensions,
|
|
758
|
+
webpack: (config, options2) => {
|
|
759
|
+
config.resolve ||= {};
|
|
760
|
+
config.module ||= {};
|
|
761
|
+
config.module.rules ||= [];
|
|
762
|
+
config.module.rules.push({
|
|
763
|
+
test: /\.mdx?$/,
|
|
764
|
+
use: [
|
|
765
|
+
options2.defaultLoaders.babel,
|
|
766
|
+
{
|
|
767
|
+
loader: "fumadocs-mdx/loader-mdx",
|
|
768
|
+
options: mdxLoaderOptions
|
|
769
|
+
}
|
|
770
|
+
]
|
|
771
|
+
});
|
|
772
|
+
config.plugins ||= [];
|
|
773
|
+
return nextConfig.webpack?.(config, options2) ?? config;
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
async function init(dev, options) {
|
|
779
|
+
const core = createNextCore(options);
|
|
780
|
+
async function initOrReload() {
|
|
781
|
+
await core.init({
|
|
782
|
+
config: loadConfig(options.configPath, options.outDir, true)
|
|
783
|
+
});
|
|
784
|
+
await core.emitAndWrite();
|
|
785
|
+
}
|
|
786
|
+
async function devServer() {
|
|
787
|
+
const { FSWatcher } = await import("chokidar");
|
|
788
|
+
const watcher = new FSWatcher({
|
|
789
|
+
ignoreInitial: true,
|
|
790
|
+
persistent: true,
|
|
791
|
+
ignored: [options.outDir]
|
|
792
|
+
});
|
|
793
|
+
watcher.add(options.configPath);
|
|
794
|
+
for (const collection of core.getConfig().collections.values()) {
|
|
795
|
+
if (collection.type === "docs") {
|
|
796
|
+
watcher.add(collection.docs.dir);
|
|
797
|
+
watcher.add(collection.meta.dir);
|
|
798
|
+
} else {
|
|
799
|
+
watcher.add(collection.dir);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
watcher.on("ready", () => {
|
|
803
|
+
console.log("[MDX] started dev server");
|
|
804
|
+
});
|
|
805
|
+
watcher.on("all", async (event, file) => {
|
|
806
|
+
const absolutePath = path9.resolve(file);
|
|
807
|
+
if (event === "change") removeFileCache(absolutePath);
|
|
808
|
+
if (absolutePath === path9.resolve(options.configPath)) {
|
|
809
|
+
watcher.removeAllListeners();
|
|
810
|
+
await watcher.close();
|
|
811
|
+
await initOrReload();
|
|
812
|
+
console.log("[MDX] restarting dev server");
|
|
813
|
+
await devServer();
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
process.on("exit", () => {
|
|
817
|
+
if (watcher.closed) return;
|
|
818
|
+
console.log("[MDX] closing dev server");
|
|
819
|
+
void watcher.close();
|
|
820
|
+
});
|
|
821
|
+
await core.initServer({ watcher });
|
|
822
|
+
}
|
|
823
|
+
await initOrReload();
|
|
824
|
+
if (dev) {
|
|
825
|
+
await devServer();
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
async function postInstall(configPath = findConfigFile(), outDir = ".source") {
|
|
829
|
+
const core = await createNextCore({
|
|
830
|
+
outDir,
|
|
831
|
+
configPath
|
|
832
|
+
}).init({
|
|
833
|
+
config: loadConfig(configPath, outDir, true)
|
|
834
|
+
});
|
|
835
|
+
await core.emitAndWrite();
|
|
836
|
+
}
|
|
837
|
+
function applyDefaults(options) {
|
|
838
|
+
return {
|
|
839
|
+
outDir: options.outDir ?? ".source",
|
|
840
|
+
configPath: options.configPath ?? findConfigFile()
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
function createNextCore({
|
|
844
|
+
outDir,
|
|
845
|
+
configPath
|
|
846
|
+
}) {
|
|
847
|
+
const core = createCore(
|
|
848
|
+
{
|
|
849
|
+
environment: "next",
|
|
850
|
+
outDir,
|
|
851
|
+
configPath
|
|
852
|
+
},
|
|
853
|
+
[next()]
|
|
854
|
+
);
|
|
855
|
+
return {
|
|
856
|
+
...core,
|
|
857
|
+
async emitAndWrite(...args) {
|
|
858
|
+
try {
|
|
859
|
+
await core.emitAndWrite(...args);
|
|
860
|
+
} catch (err) {
|
|
861
|
+
if (err instanceof ValidationError) {
|
|
862
|
+
console.error(err.toStringFormatted());
|
|
863
|
+
} else {
|
|
864
|
+
console.error(err);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
var path9, defaultPageExtensions;
|
|
871
|
+
var init_next2 = __esm({
|
|
872
|
+
"src/next/index.ts"() {
|
|
873
|
+
"use strict";
|
|
874
|
+
init_config();
|
|
875
|
+
path9 = __toESM(require("path"), 1);
|
|
876
|
+
init_load();
|
|
877
|
+
init_file_cache();
|
|
878
|
+
init_validation();
|
|
879
|
+
init_next();
|
|
880
|
+
init_core();
|
|
881
|
+
defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
// src/loaders/mdx/remark-unravel.ts
|
|
886
|
+
function remarkMarkAndUnravel() {
|
|
887
|
+
return (tree) => {
|
|
888
|
+
(0, import_unist_util_visit.visit)(tree, function(node, index, parent) {
|
|
889
|
+
let offset = -1;
|
|
890
|
+
let all = true;
|
|
891
|
+
let oneOrMore = false;
|
|
892
|
+
if (parent && typeof index === "number" && node.type === "paragraph") {
|
|
893
|
+
const children = node.children;
|
|
894
|
+
while (++offset < children.length) {
|
|
895
|
+
const child = children[offset];
|
|
896
|
+
if (child.type === "mdxJsxTextElement" || child.type === "mdxTextExpression") {
|
|
897
|
+
oneOrMore = true;
|
|
898
|
+
} else if (child.type === "text" && child.value.trim().length === 0) {
|
|
899
|
+
} else {
|
|
900
|
+
all = false;
|
|
901
|
+
break;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (all && oneOrMore) {
|
|
905
|
+
offset = -1;
|
|
906
|
+
const newChildren = [];
|
|
907
|
+
while (++offset < children.length) {
|
|
908
|
+
const child = children[offset];
|
|
909
|
+
if (child.type === "mdxJsxTextElement") {
|
|
910
|
+
child.type = "mdxJsxFlowElement";
|
|
911
|
+
}
|
|
912
|
+
if (child.type === "mdxTextExpression") {
|
|
913
|
+
child.type = "mdxFlowExpression";
|
|
914
|
+
}
|
|
915
|
+
if (child.type === "text" && /^[\t\r\n ]+$/.test(String(child.value))) {
|
|
916
|
+
} else {
|
|
917
|
+
newChildren.push(child);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
parent.children.splice(index, 1, ...newChildren);
|
|
921
|
+
return index;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
var import_unist_util_visit;
|
|
928
|
+
var init_remark_unravel = __esm({
|
|
929
|
+
"src/loaders/mdx/remark-unravel.ts"() {
|
|
930
|
+
"use strict";
|
|
931
|
+
import_unist_util_visit = require("unist-util-visit");
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
// src/loaders/mdx/remark-include.ts
|
|
936
|
+
function isElementLike(node) {
|
|
937
|
+
return ElementLikeTypes.includes(node.type);
|
|
938
|
+
}
|
|
939
|
+
function parseElementAttributes(element) {
|
|
940
|
+
if (Array.isArray(element.attributes)) {
|
|
941
|
+
const attributes = {};
|
|
942
|
+
for (const attr of element.attributes) {
|
|
943
|
+
if (attr.type === "mdxJsxAttribute" && (typeof attr.value === "string" || attr.value === null)) {
|
|
944
|
+
attributes[attr.name] = attr.value;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return attributes;
|
|
948
|
+
}
|
|
949
|
+
return element.attributes ?? {};
|
|
950
|
+
}
|
|
951
|
+
function flattenNode(node) {
|
|
952
|
+
if ("children" in node)
|
|
953
|
+
return node.children.map((child) => flattenNode(child)).join("");
|
|
954
|
+
if ("value" in node) return node.value;
|
|
955
|
+
return "";
|
|
956
|
+
}
|
|
957
|
+
function parseSpecifier(specifier) {
|
|
958
|
+
const idx = specifier.lastIndexOf("#");
|
|
959
|
+
if (idx === -1) return { file: specifier };
|
|
960
|
+
return {
|
|
961
|
+
file: specifier.slice(0, idx),
|
|
962
|
+
section: specifier.slice(idx + 1)
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
function extractSection(root, section) {
|
|
966
|
+
let nodes;
|
|
967
|
+
let capturingHeadingContent = false;
|
|
968
|
+
(0, import_unist_util_visit2.visit)(root, (node) => {
|
|
969
|
+
if (node.type === "heading") {
|
|
970
|
+
if (capturingHeadingContent) {
|
|
971
|
+
return false;
|
|
972
|
+
}
|
|
973
|
+
if (node.data?.hProperties?.id === section) {
|
|
974
|
+
capturingHeadingContent = true;
|
|
975
|
+
nodes = [node];
|
|
976
|
+
return "skip";
|
|
977
|
+
}
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
if (capturingHeadingContent) {
|
|
981
|
+
nodes?.push(node);
|
|
982
|
+
return "skip";
|
|
983
|
+
}
|
|
984
|
+
if (isElementLike(node) && node.name === "section") {
|
|
985
|
+
const attributes = parseElementAttributes(node);
|
|
986
|
+
if (attributes.id === section) {
|
|
987
|
+
nodes = node.children;
|
|
988
|
+
return false;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
if (nodes)
|
|
993
|
+
return {
|
|
994
|
+
type: "root",
|
|
995
|
+
children: nodes
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
function remarkInclude() {
|
|
999
|
+
const TagName = "include";
|
|
1000
|
+
const embedContent = async (file, heading, params, data) => {
|
|
1001
|
+
let content;
|
|
1002
|
+
try {
|
|
1003
|
+
content = (await fs4.readFile(file)).toString();
|
|
1004
|
+
} catch (e) {
|
|
1005
|
+
throw new Error(
|
|
1006
|
+
`failed to read file ${file}
|
|
1007
|
+
${e instanceof Error ? e.message : String(e)}`,
|
|
1008
|
+
{ cause: e }
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
const ext = path10.extname(file);
|
|
1012
|
+
data._compiler?.addDependency(file);
|
|
1013
|
+
if (params.lang || ext !== ".md" && ext !== ".mdx") {
|
|
1014
|
+
const lang = params.lang ?? ext.slice(1);
|
|
1015
|
+
return {
|
|
1016
|
+
type: "code",
|
|
1017
|
+
lang,
|
|
1018
|
+
meta: params.meta,
|
|
1019
|
+
value: content,
|
|
1020
|
+
data: {}
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
const parser = data._getProcessor ? data._getProcessor(ext === ".mdx" ? "mdx" : "md") : this;
|
|
1024
|
+
const parsed = fumaMatter(content);
|
|
1025
|
+
let mdast = parser.parse({
|
|
1026
|
+
path: file,
|
|
1027
|
+
value: parsed.content,
|
|
1028
|
+
data: { frontmatter: parsed.data }
|
|
1029
|
+
});
|
|
1030
|
+
const baseProcessor = (0, import_unified.unified)().use(remarkMarkAndUnravel);
|
|
1031
|
+
if (heading) {
|
|
1032
|
+
const extracted = extractSection(
|
|
1033
|
+
await baseProcessor.use(import_mdx_plugins.remarkHeading).run(mdast),
|
|
1034
|
+
heading
|
|
1035
|
+
);
|
|
1036
|
+
if (!extracted)
|
|
1037
|
+
throw new Error(
|
|
1038
|
+
`Cannot find section ${heading} in ${file}, make sure you have encapsulated the section in a <section id="${heading}"> tag, or a :::section directive with remark-directive configured.`
|
|
1039
|
+
);
|
|
1040
|
+
mdast = extracted;
|
|
1041
|
+
} else {
|
|
1042
|
+
mdast = await baseProcessor.run(mdast);
|
|
1043
|
+
}
|
|
1044
|
+
await update(mdast, path10.dirname(file), data);
|
|
1045
|
+
return mdast;
|
|
1046
|
+
};
|
|
1047
|
+
async function update(tree, directory, data) {
|
|
1048
|
+
const queue = [];
|
|
1049
|
+
(0, import_unist_util_visit2.visit)(tree, ElementLikeTypes, (_node, _, parent) => {
|
|
1050
|
+
const node = _node;
|
|
1051
|
+
if (node.name !== TagName) return;
|
|
1052
|
+
const specifier = flattenNode(node);
|
|
1053
|
+
if (specifier.length === 0) return "skip";
|
|
1054
|
+
const attributes = parseElementAttributes(node);
|
|
1055
|
+
const { file: relativePath, section } = parseSpecifier(specifier);
|
|
1056
|
+
const file = path10.resolve(
|
|
1057
|
+
"cwd" in attributes ? process.cwd() : directory,
|
|
1058
|
+
relativePath
|
|
1059
|
+
);
|
|
1060
|
+
queue.push(
|
|
1061
|
+
embedContent(file, section, attributes, data).then((replace) => {
|
|
1062
|
+
Object.assign(
|
|
1063
|
+
parent && parent.type === "paragraph" ? parent : node,
|
|
1064
|
+
replace
|
|
1065
|
+
);
|
|
1066
|
+
})
|
|
1067
|
+
);
|
|
1068
|
+
return "skip";
|
|
1069
|
+
});
|
|
1070
|
+
await Promise.all(queue);
|
|
1071
|
+
}
|
|
1072
|
+
return async (tree, file) => {
|
|
1073
|
+
await update(tree, path10.dirname(file.path), file.data);
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
var import_unified, import_unist_util_visit2, path10, fs4, import_mdx_plugins, ElementLikeTypes;
|
|
1077
|
+
var init_remark_include = __esm({
|
|
1078
|
+
"src/loaders/mdx/remark-include.ts"() {
|
|
1079
|
+
"use strict";
|
|
1080
|
+
import_unified = require("unified");
|
|
1081
|
+
import_unist_util_visit2 = require("unist-util-visit");
|
|
1082
|
+
path10 = __toESM(require("path"), 1);
|
|
1083
|
+
fs4 = __toESM(require("fs/promises"), 1);
|
|
1084
|
+
init_fuma_matter();
|
|
1085
|
+
import_mdx_plugins = require("fumadocs-core/mdx-plugins");
|
|
1086
|
+
init_remark_unravel();
|
|
1087
|
+
ElementLikeTypes = [
|
|
1088
|
+
"mdxJsxFlowElement",
|
|
1089
|
+
"mdxJsxTextElement",
|
|
1090
|
+
"containerDirective",
|
|
1091
|
+
"textDirective",
|
|
1092
|
+
"leafDirective"
|
|
1093
|
+
];
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
|
|
1097
|
+
// src/loaders/mdx/remark-postprocess.ts
|
|
1098
|
+
function remarkPostprocess({
|
|
1099
|
+
_format,
|
|
1100
|
+
includeProcessedMarkdown = false,
|
|
1101
|
+
includeMDAST = false,
|
|
1102
|
+
valueToExport = []
|
|
1103
|
+
}) {
|
|
1104
|
+
let _stringifyProcessor;
|
|
1105
|
+
const getStringifyProcessor = () => {
|
|
1106
|
+
if (_format === "mdx") return this;
|
|
1107
|
+
return _stringifyProcessor ??= this().use(import_remark_mdx.default).freeze();
|
|
1108
|
+
};
|
|
1109
|
+
return (tree, file) => {
|
|
1110
|
+
let title;
|
|
1111
|
+
const urls = [];
|
|
1112
|
+
(0, import_unist_util_visit3.visit)(tree, ["heading", "link"], (node) => {
|
|
1113
|
+
if (node.type === "heading" && node.depth === 1) {
|
|
1114
|
+
title = flattenNode2(node);
|
|
1115
|
+
}
|
|
1116
|
+
if (node.type !== "link") return;
|
|
1117
|
+
urls.push({
|
|
1118
|
+
href: node.url
|
|
1119
|
+
});
|
|
1120
|
+
return "skip";
|
|
1121
|
+
});
|
|
1122
|
+
if (title) {
|
|
1123
|
+
file.data.frontmatter ??= {};
|
|
1124
|
+
if (!file.data.frontmatter.title) file.data.frontmatter.title = title;
|
|
1125
|
+
}
|
|
1126
|
+
file.data.extractedReferences = urls;
|
|
1127
|
+
if (includeProcessedMarkdown) {
|
|
1128
|
+
const processor = getStringifyProcessor();
|
|
1129
|
+
file.data._markdown = (0, import_mdast_util_to_markdown.toMarkdown)(tree, {
|
|
1130
|
+
...processor.data("settings"),
|
|
1131
|
+
// from https://github.com/remarkjs/remark/blob/main/packages/remark-stringify/lib/index.js
|
|
1132
|
+
extensions: processor.data("toMarkdownExtensions") || []
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
if (includeMDAST) {
|
|
1136
|
+
const options = includeMDAST === true ? {} : includeMDAST;
|
|
1137
|
+
file.data._mdast = JSON.stringify(
|
|
1138
|
+
options.removePosition ? (0, import_unist_util_remove_position.removePosition)(structuredClone(tree)) : tree
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1141
|
+
for (const { name, value } of file.data["mdx-export"] ?? []) {
|
|
1142
|
+
tree.children.unshift(getMdastExport(name, value));
|
|
1143
|
+
}
|
|
1144
|
+
for (const name of valueToExport) {
|
|
1145
|
+
if (!(name in file.data)) continue;
|
|
1146
|
+
tree.children.unshift(getMdastExport(name, file.data[name]));
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
function getMdastExport(name, value) {
|
|
1151
|
+
return {
|
|
1152
|
+
type: "mdxjsEsm",
|
|
1153
|
+
value: "",
|
|
1154
|
+
data: {
|
|
1155
|
+
estree: {
|
|
1156
|
+
type: "Program",
|
|
1157
|
+
sourceType: "module",
|
|
1158
|
+
body: [
|
|
1159
|
+
{
|
|
1160
|
+
type: "ExportNamedDeclaration",
|
|
1161
|
+
attributes: [],
|
|
1162
|
+
specifiers: [],
|
|
1163
|
+
source: null,
|
|
1164
|
+
declaration: {
|
|
1165
|
+
type: "VariableDeclaration",
|
|
1166
|
+
kind: "let",
|
|
1167
|
+
declarations: [
|
|
1168
|
+
{
|
|
1169
|
+
type: "VariableDeclarator",
|
|
1170
|
+
id: {
|
|
1171
|
+
type: "Identifier",
|
|
1172
|
+
name
|
|
1173
|
+
},
|
|
1174
|
+
init: (0, import_estree_util_value_to_estree.valueToEstree)(value)
|
|
1175
|
+
}
|
|
1176
|
+
]
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
]
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
function flattenNode2(node) {
|
|
1185
|
+
if ("children" in node)
|
|
1186
|
+
return node.children.map((child) => flattenNode2(child)).join("");
|
|
1187
|
+
if ("value" in node) return node.value;
|
|
1188
|
+
return "";
|
|
1189
|
+
}
|
|
1190
|
+
var import_unist_util_visit3, import_mdast_util_to_markdown, import_estree_util_value_to_estree, import_unist_util_remove_position, import_remark_mdx;
|
|
1191
|
+
var init_remark_postprocess = __esm({
|
|
1192
|
+
"src/loaders/mdx/remark-postprocess.ts"() {
|
|
1193
|
+
"use strict";
|
|
1194
|
+
import_unist_util_visit3 = require("unist-util-visit");
|
|
1195
|
+
import_mdast_util_to_markdown = require("mdast-util-to-markdown");
|
|
1196
|
+
import_estree_util_value_to_estree = require("estree-util-value-to-estree");
|
|
1197
|
+
import_unist_util_remove_position = require("unist-util-remove-position");
|
|
1198
|
+
import_remark_mdx = __toESM(require("remark-mdx"), 1);
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
// src/loaders/mdx/build-mdx.ts
|
|
1203
|
+
async function buildMDX(cacheKey, source, options) {
|
|
1204
|
+
const { filePath, frontmatter, data, _compiler, ...rest } = options;
|
|
1205
|
+
function getProcessor(format) {
|
|
1206
|
+
const key = `${cacheKey}:${format}`;
|
|
1207
|
+
let processor = cache2.get(key);
|
|
1208
|
+
if (!processor) {
|
|
1209
|
+
processor = (0, import_mdx.createProcessor)({
|
|
1210
|
+
outputFormat: "program",
|
|
1211
|
+
...rest,
|
|
1212
|
+
remarkPlugins: [
|
|
1213
|
+
remarkInclude,
|
|
1214
|
+
...rest.remarkPlugins ?? [],
|
|
1215
|
+
[
|
|
1216
|
+
remarkPostprocess,
|
|
1217
|
+
{
|
|
1218
|
+
_format: format,
|
|
1219
|
+
...options.postprocess,
|
|
1220
|
+
valueToExport: [
|
|
1221
|
+
...options.postprocess?.valueToExport ?? [],
|
|
1222
|
+
"structuredData",
|
|
1223
|
+
"extractedReferences",
|
|
1224
|
+
"frontmatter",
|
|
1225
|
+
"lastModified",
|
|
1226
|
+
"_markdown",
|
|
1227
|
+
"_mdast"
|
|
1228
|
+
]
|
|
1229
|
+
}
|
|
1230
|
+
]
|
|
1231
|
+
],
|
|
1232
|
+
format
|
|
1233
|
+
});
|
|
1234
|
+
cache2.set(key, processor);
|
|
1235
|
+
}
|
|
1236
|
+
return processor;
|
|
1237
|
+
}
|
|
1238
|
+
return getProcessor(
|
|
1239
|
+
options.format ?? (filePath.endsWith(".mdx") ? "mdx" : "md")
|
|
1240
|
+
).process({
|
|
1241
|
+
value: source,
|
|
1242
|
+
path: filePath,
|
|
1243
|
+
data: {
|
|
1244
|
+
...data,
|
|
1245
|
+
frontmatter,
|
|
1246
|
+
_compiler,
|
|
1247
|
+
_getProcessor: getProcessor
|
|
1248
|
+
}
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
var import_mdx, cache2;
|
|
1252
|
+
var init_build_mdx = __esm({
|
|
1253
|
+
"src/loaders/mdx/build-mdx.ts"() {
|
|
1254
|
+
"use strict";
|
|
1255
|
+
import_mdx = require("@mdx-js/mdx");
|
|
1256
|
+
init_remark_include();
|
|
1257
|
+
init_remark_postprocess();
|
|
1258
|
+
cache2 = /* @__PURE__ */ new Map();
|
|
1259
|
+
}
|
|
1260
|
+
});
|
|
1261
|
+
|
|
1262
|
+
// src/loaders/mdx/index.ts
|
|
1263
|
+
function createMdxLoader(configLoader) {
|
|
1264
|
+
return async ({
|
|
1265
|
+
source: value,
|
|
1266
|
+
development: isDevelopment,
|
|
1267
|
+
query,
|
|
1268
|
+
compiler,
|
|
1269
|
+
filePath
|
|
1270
|
+
}) => {
|
|
1271
|
+
const matter = fumaMatter(value);
|
|
1272
|
+
const parsed = querySchema.parse(query);
|
|
1273
|
+
const config = await configLoader.getConfig();
|
|
1274
|
+
let after;
|
|
1275
|
+
if (!isDevelopment && config.global.experimentalBuildCache) {
|
|
1276
|
+
const cacheDir = config.global.experimentalBuildCache;
|
|
1277
|
+
const cacheKey = `${parsed.hash}_${parsed.collection ?? "global"}_${generateCacheHash(filePath)}`;
|
|
1278
|
+
const cached = await import_promises4.default.readFile(import_node_path7.default.join(cacheDir, cacheKey)).then((content) => cacheEntry.parse(JSON.parse(content.toString()))).catch(() => null);
|
|
1279
|
+
if (cached && cached.hash === generateCacheHash(value)) return cached;
|
|
1280
|
+
after = async () => {
|
|
1281
|
+
await import_promises4.default.mkdir(cacheDir, { recursive: true });
|
|
1282
|
+
await import_promises4.default.writeFile(
|
|
1283
|
+
import_node_path7.default.join(cacheDir, cacheKey),
|
|
1284
|
+
JSON.stringify({
|
|
1285
|
+
...out,
|
|
1286
|
+
hash: generateCacheHash(value)
|
|
1287
|
+
})
|
|
1288
|
+
);
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
const collection = parsed.collection ? config.collections.get(parsed.collection) : void 0;
|
|
1292
|
+
let docCollection;
|
|
1293
|
+
switch (collection?.type) {
|
|
1294
|
+
case "doc":
|
|
1295
|
+
docCollection = collection;
|
|
1296
|
+
break;
|
|
1297
|
+
case "docs":
|
|
1298
|
+
docCollection = collection.docs;
|
|
1299
|
+
break;
|
|
1300
|
+
}
|
|
1301
|
+
if (docCollection?.schema) {
|
|
1302
|
+
matter.data = await validate(
|
|
1303
|
+
docCollection.schema,
|
|
1304
|
+
matter.data,
|
|
1305
|
+
{
|
|
1306
|
+
source: value,
|
|
1307
|
+
path: filePath
|
|
1308
|
+
},
|
|
1309
|
+
`invalid frontmatter in ${filePath}`
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
if (parsed.only === "frontmatter") {
|
|
1313
|
+
return {
|
|
1314
|
+
code: `export const frontmatter = ${JSON.stringify(matter.data)}`,
|
|
1315
|
+
map: null
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
const data = {};
|
|
1319
|
+
if (config.global.lastModifiedTime === "git") {
|
|
1320
|
+
data.lastModified = (await getGitTimestamp(filePath))?.getTime();
|
|
1321
|
+
}
|
|
1322
|
+
const lineOffset = isDevelopment ? countLines(matter.matter) : 0;
|
|
1323
|
+
const compiled = await buildMDX(
|
|
1324
|
+
`${getConfigHash(config)}:${parsed.collection ?? "global"}`,
|
|
1325
|
+
"\n".repeat(lineOffset) + matter.content,
|
|
1326
|
+
{
|
|
1327
|
+
development: isDevelopment,
|
|
1328
|
+
...docCollection?.mdxOptions ?? await config.getDefaultMDXOptions(),
|
|
1329
|
+
postprocess: docCollection?.postprocess,
|
|
1330
|
+
data,
|
|
1331
|
+
filePath,
|
|
1332
|
+
frontmatter: matter.data,
|
|
1333
|
+
_compiler: compiler
|
|
1334
|
+
}
|
|
1335
|
+
);
|
|
1336
|
+
const out = {
|
|
1337
|
+
code: String(compiled.value),
|
|
1338
|
+
map: compiled.map
|
|
1339
|
+
};
|
|
1340
|
+
await after?.();
|
|
1341
|
+
return out;
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function getConfigHash(config) {
|
|
1345
|
+
let hash = hashes.get(config);
|
|
1346
|
+
if (hash) return hash;
|
|
1347
|
+
hash = Date.now().toString();
|
|
1348
|
+
hashes.set(config, hash);
|
|
1349
|
+
return hash;
|
|
1350
|
+
}
|
|
1351
|
+
function generateCacheHash(input) {
|
|
1352
|
+
return (0, import_node_crypto2.createHash)("md5").update(input).digest("hex");
|
|
1353
|
+
}
|
|
1354
|
+
function countLines(s) {
|
|
1355
|
+
let num = 0;
|
|
1356
|
+
for (const c of s) {
|
|
1357
|
+
if (c === "\n") num++;
|
|
1358
|
+
}
|
|
1359
|
+
return num;
|
|
1360
|
+
}
|
|
1361
|
+
var import_zod, import_promises4, import_node_path7, import_node_crypto2, querySchema, cacheEntry, hashes;
|
|
1362
|
+
var init_mdx = __esm({
|
|
1363
|
+
"src/loaders/mdx/index.ts"() {
|
|
1364
|
+
"use strict";
|
|
1365
|
+
init_fuma_matter();
|
|
1366
|
+
init_validation();
|
|
1367
|
+
init_git_timestamp();
|
|
1368
|
+
init_build_mdx();
|
|
1369
|
+
import_zod = require("zod");
|
|
1370
|
+
import_promises4 = __toESM(require("fs/promises"), 1);
|
|
1371
|
+
import_node_path7 = __toESM(require("path"), 1);
|
|
1372
|
+
import_node_crypto2 = require("crypto");
|
|
1373
|
+
querySchema = import_zod.z.object({
|
|
1374
|
+
only: import_zod.z.literal(["frontmatter", "all"]).default("all"),
|
|
1375
|
+
collection: import_zod.z.string().optional()
|
|
1376
|
+
}).loose();
|
|
1377
|
+
cacheEntry = import_zod.z.object({
|
|
1378
|
+
code: import_zod.z.string(),
|
|
1379
|
+
map: import_zod.z.any().optional(),
|
|
1380
|
+
hash: import_zod.z.string().optional()
|
|
1381
|
+
});
|
|
1382
|
+
hashes = /* @__PURE__ */ new WeakMap();
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
|
|
1386
|
+
// src/loaders/adapter.ts
|
|
1387
|
+
function toVite(loader) {
|
|
1388
|
+
return async function(file, query, value) {
|
|
1389
|
+
const result = await loader({
|
|
1390
|
+
filePath: file,
|
|
1391
|
+
query: (0, import_node_querystring.parse)(query),
|
|
1392
|
+
source: value,
|
|
1393
|
+
development: this.environment.mode === "dev",
|
|
1394
|
+
compiler: {
|
|
1395
|
+
addDependency: (file2) => {
|
|
1396
|
+
this.addWatchFile(file2);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
});
|
|
1400
|
+
return {
|
|
1401
|
+
code: result.code,
|
|
1402
|
+
map: result.map
|
|
1403
|
+
};
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
var import_node_url2, import_promises5, import_node_querystring, import_node_path8;
|
|
1407
|
+
var init_adapter = __esm({
|
|
1408
|
+
"src/loaders/adapter.ts"() {
|
|
1409
|
+
"use strict";
|
|
1410
|
+
import_node_url2 = require("url");
|
|
1411
|
+
import_promises5 = __toESM(require("fs/promises"), 1);
|
|
1412
|
+
import_node_querystring = require("querystring");
|
|
1413
|
+
init_validation();
|
|
1414
|
+
import_node_path8 = __toESM(require("path"), 1);
|
|
1415
|
+
}
|
|
1416
|
+
});
|
|
1417
|
+
|
|
1418
|
+
// src/utils/glob-import.ts
|
|
1419
|
+
function generateGlobImport(patterns, options) {
|
|
1420
|
+
let code = "{";
|
|
1421
|
+
const result = (0, import_tinyglobby2.globSync)(patterns, {
|
|
1422
|
+
cwd: options.base
|
|
1423
|
+
});
|
|
1424
|
+
for (const item of result) {
|
|
1425
|
+
const fullPath = import_node_path9.default.join(options.base, item);
|
|
1426
|
+
const url = (0, import_node_url3.pathToFileURL)(fullPath);
|
|
1427
|
+
for (const [k, v] of Object.entries(options.query ?? {})) {
|
|
1428
|
+
url.searchParams.set(k, v);
|
|
1429
|
+
}
|
|
1430
|
+
let line = `${JSON.stringify(item)}: () => import(${JSON.stringify(url.href)})`;
|
|
1431
|
+
if (options.import) {
|
|
1432
|
+
line += `.then(mod => mod[${JSON.stringify(options.import)}])`;
|
|
1433
|
+
}
|
|
1434
|
+
code += `${line}, `;
|
|
1435
|
+
}
|
|
1436
|
+
code += "}";
|
|
1437
|
+
return code;
|
|
1438
|
+
}
|
|
1439
|
+
var import_tinyglobby2, import_node_path9, import_node_url3;
|
|
1440
|
+
var init_glob_import = __esm({
|
|
1441
|
+
"src/utils/glob-import.ts"() {
|
|
1442
|
+
"use strict";
|
|
1443
|
+
import_tinyglobby2 = require("tinyglobby");
|
|
1444
|
+
import_node_path9 = __toESM(require("path"), 1);
|
|
1445
|
+
import_node_url3 = require("url");
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
|
|
1449
|
+
// src/plugins/vite.ts
|
|
1450
|
+
function vite(options) {
|
|
1451
|
+
let config;
|
|
1452
|
+
return {
|
|
1453
|
+
config(v) {
|
|
1454
|
+
config = v;
|
|
1455
|
+
},
|
|
1456
|
+
emit() {
|
|
1457
|
+
return [
|
|
1458
|
+
{
|
|
1459
|
+
path: "index.ts",
|
|
1460
|
+
content: indexFile2(this.configPath, this.outDir, config, options)
|
|
1461
|
+
}
|
|
1462
|
+
];
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
function indexFile2(configPath, outDir, config, options) {
|
|
1467
|
+
const { addJsExtension = false, runtime } = options;
|
|
1468
|
+
const lines = [
|
|
1469
|
+
'/// <reference types="vite/client" />',
|
|
1470
|
+
`import { fromConfig } from 'fumadocs-mdx/runtime/vite';`,
|
|
1471
|
+
`import type * as Config from '${toImportPath(configPath, {
|
|
1472
|
+
relativeTo: outDir,
|
|
1473
|
+
jsExtension: addJsExtension
|
|
1474
|
+
})}';`,
|
|
1475
|
+
"",
|
|
1476
|
+
`export const create = fromConfig<typeof Config>();`
|
|
1477
|
+
];
|
|
1478
|
+
function docs(name, collection) {
|
|
1479
|
+
const obj = [
|
|
1480
|
+
ident(`doc: ${doc(name, collection.docs)}`),
|
|
1481
|
+
ident(`meta: ${meta(name, collection.meta)}`)
|
|
1482
|
+
].join(",\n");
|
|
1483
|
+
return `{
|
|
1484
|
+
${obj}
|
|
1485
|
+
}`;
|
|
1486
|
+
}
|
|
1487
|
+
function doc(name, collection) {
|
|
1488
|
+
const patterns = getGlobPatterns(collection);
|
|
1489
|
+
const base = getGlobBase(collection);
|
|
1490
|
+
const docGlob = generateGlob(patterns, {
|
|
1491
|
+
query: {
|
|
1492
|
+
collection: name
|
|
1493
|
+
},
|
|
1494
|
+
base
|
|
1495
|
+
});
|
|
1496
|
+
if (collection.async) {
|
|
1497
|
+
const headBlob = generateGlob(patterns, {
|
|
1498
|
+
query: {
|
|
1499
|
+
only: "frontmatter",
|
|
1500
|
+
collection: name
|
|
1501
|
+
},
|
|
1502
|
+
import: "frontmatter",
|
|
1503
|
+
base
|
|
1504
|
+
});
|
|
1505
|
+
return `create.docLazy("${name}", "${base}", ${headBlob}, ${docGlob})`;
|
|
1506
|
+
}
|
|
1507
|
+
return `create.doc("${name}", "${base}", ${docGlob})`;
|
|
1508
|
+
}
|
|
1509
|
+
function meta(name, collection) {
|
|
1510
|
+
const patterns = getGlobPatterns(collection);
|
|
1511
|
+
const base = getGlobBase(collection);
|
|
1512
|
+
return `create.meta("${name}", "${base}", ${generateGlob(patterns, {
|
|
1513
|
+
import: "default",
|
|
1514
|
+
base,
|
|
1515
|
+
query: {
|
|
1516
|
+
collection: name
|
|
1517
|
+
}
|
|
1518
|
+
})})`;
|
|
1519
|
+
}
|
|
1520
|
+
function generateGlob(patterns, options2) {
|
|
1521
|
+
patterns = mapGlobPatterns(patterns);
|
|
1522
|
+
if (runtime === "node" || runtime === "bun") {
|
|
1523
|
+
return generateGlobImport(patterns, options2);
|
|
1524
|
+
} else {
|
|
1525
|
+
return `import.meta.glob(${JSON.stringify(patterns)}, ${JSON.stringify(
|
|
1526
|
+
{
|
|
1527
|
+
...options2,
|
|
1528
|
+
base: import_node_path10.default.relative(outDir, options2.base)
|
|
1529
|
+
},
|
|
1530
|
+
null,
|
|
1531
|
+
2
|
|
1532
|
+
)})`;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
for (const [name, collection] of config.collections.entries()) {
|
|
1536
|
+
let body;
|
|
1537
|
+
if (collection.type === "docs") {
|
|
1538
|
+
body = docs(name, collection);
|
|
1539
|
+
} else if (collection.type === "meta") {
|
|
1540
|
+
body = meta(name, collection);
|
|
1541
|
+
} else {
|
|
1542
|
+
body = doc(name, collection);
|
|
1543
|
+
}
|
|
1544
|
+
lines.push("");
|
|
1545
|
+
lines.push(`export const ${name} = ${body};`);
|
|
1546
|
+
}
|
|
1547
|
+
return lines.join("\n");
|
|
1548
|
+
}
|
|
1549
|
+
function mapGlobPatterns(patterns) {
|
|
1550
|
+
return patterns.map(enforceRelative);
|
|
1551
|
+
}
|
|
1552
|
+
function enforceRelative(file) {
|
|
1553
|
+
if (file.startsWith("./")) return file;
|
|
1554
|
+
if (file.startsWith("/")) return `.${file}`;
|
|
1555
|
+
return `./${file}`;
|
|
1556
|
+
}
|
|
1557
|
+
function getGlobBase(collection) {
|
|
1558
|
+
let dir = collection.dir;
|
|
1559
|
+
if (Array.isArray(dir)) {
|
|
1560
|
+
if (dir.length !== 1)
|
|
1561
|
+
throw new Error(
|
|
1562
|
+
`[Fumadocs MDX] Vite Plugin doesn't support multiple \`dir\` for a collection at the moment.`
|
|
1563
|
+
);
|
|
1564
|
+
dir = dir[0];
|
|
1565
|
+
}
|
|
1566
|
+
return enforceRelative(dir);
|
|
1567
|
+
}
|
|
1568
|
+
var import_node_path10;
|
|
1569
|
+
var init_vite = __esm({
|
|
1570
|
+
"src/plugins/vite.ts"() {
|
|
1571
|
+
"use strict";
|
|
1572
|
+
init_import_formatter();
|
|
1573
|
+
init_collections();
|
|
1574
|
+
init_glob_import();
|
|
1575
|
+
import_node_path10 = __toESM(require("path"), 1);
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1578
|
+
|
|
1579
|
+
// src/vite/index.ts
|
|
1580
|
+
var vite_exports = {};
|
|
1581
|
+
__export(vite_exports, {
|
|
1582
|
+
default: () => mdx,
|
|
1583
|
+
postInstall: () => postInstall2
|
|
1584
|
+
});
|
|
1585
|
+
async function mdx(config, pluginOptions = {}) {
|
|
1586
|
+
const options = applyDefaults2(pluginOptions);
|
|
1587
|
+
const core = await createViteCore(options).init({
|
|
1588
|
+
config: buildConfig(config)
|
|
1589
|
+
});
|
|
1590
|
+
const mdxLoader = toVite(createMdxLoader(core.creatConfigLoader()));
|
|
1591
|
+
async function transformMeta(path16, query, value) {
|
|
1592
|
+
const isJson = path16.endsWith(".json");
|
|
1593
|
+
const parsed = (0, import_node_querystring2.parse)(query);
|
|
1594
|
+
const collection = parsed.collection ? core.getConfig().collections.get(parsed.collection) : void 0;
|
|
1595
|
+
if (!collection) return null;
|
|
1596
|
+
let schema;
|
|
1597
|
+
switch (collection.type) {
|
|
1598
|
+
case "meta":
|
|
1599
|
+
schema = collection.schema;
|
|
1600
|
+
break;
|
|
1601
|
+
case "docs":
|
|
1602
|
+
schema = collection.meta.schema;
|
|
1603
|
+
break;
|
|
1604
|
+
}
|
|
1605
|
+
if (!schema) return null;
|
|
1606
|
+
let data;
|
|
1607
|
+
try {
|
|
1608
|
+
data = isJson ? JSON.parse(value) : (0, import_js_yaml3.load)(value);
|
|
1609
|
+
} catch {
|
|
1610
|
+
return null;
|
|
1611
|
+
}
|
|
1612
|
+
const out = await validate(
|
|
1613
|
+
schema,
|
|
1614
|
+
data,
|
|
1615
|
+
{ path: path16, source: value },
|
|
1616
|
+
`invalid data in ${path16}`
|
|
1617
|
+
);
|
|
1618
|
+
return {
|
|
1619
|
+
code: isJson ? JSON.stringify(out) : `export default ${JSON.stringify(out)}`,
|
|
1620
|
+
map: null
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
return {
|
|
1624
|
+
name: "fumadocs-mdx",
|
|
1625
|
+
// needed, otherwise other plugins will be executed before our `transform`.
|
|
1626
|
+
enforce: "pre",
|
|
1627
|
+
config(config2) {
|
|
1628
|
+
if (!options.updateViteConfig) return config2;
|
|
1629
|
+
return (0, import_vite.mergeConfig)(config2, {
|
|
1630
|
+
optimizeDeps: {
|
|
1631
|
+
exclude: FumadocsDeps
|
|
1632
|
+
},
|
|
1633
|
+
resolve: {
|
|
1634
|
+
noExternal: FumadocsDeps,
|
|
1635
|
+
dedupe: FumadocsDeps
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1638
|
+
},
|
|
1639
|
+
async buildStart() {
|
|
1640
|
+
await core.emitAndWrite();
|
|
1641
|
+
},
|
|
1642
|
+
async configureServer(server) {
|
|
1643
|
+
await core.initServer({
|
|
1644
|
+
watcher: server.watcher
|
|
1645
|
+
});
|
|
1646
|
+
},
|
|
1647
|
+
async transform(value, id) {
|
|
1648
|
+
const [file, query = ""] = id.split("?");
|
|
1649
|
+
const ext = path15.extname(file);
|
|
1650
|
+
try {
|
|
1651
|
+
if ([".yaml", ".json"].includes(ext))
|
|
1652
|
+
return await transformMeta(file, query, value);
|
|
1653
|
+
if ([".md", ".mdx"].includes(ext))
|
|
1654
|
+
return await mdxLoader.call(this, file, query, value);
|
|
1655
|
+
} catch (e) {
|
|
1656
|
+
if (e instanceof ValidationError) {
|
|
1657
|
+
throw new Error(e.toStringFormatted());
|
|
1658
|
+
}
|
|
1659
|
+
throw e;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
async function postInstall2(configPath = findConfigFile(), pluginOptions = {}) {
|
|
1665
|
+
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_load(), load_exports));
|
|
1666
|
+
const options = applyDefaults2(pluginOptions);
|
|
1667
|
+
const core = await createViteCore(options).init({
|
|
1668
|
+
config: loadConfig2(configPath, options.outDir, true)
|
|
1669
|
+
});
|
|
1670
|
+
await core.emitAndWrite();
|
|
1671
|
+
}
|
|
1672
|
+
function createViteCore({
|
|
1673
|
+
configPath,
|
|
1674
|
+
outDir,
|
|
1675
|
+
generateIndexFile
|
|
1676
|
+
}) {
|
|
1677
|
+
return createCore(
|
|
1678
|
+
{
|
|
1679
|
+
environment: "vite",
|
|
1680
|
+
configPath,
|
|
1681
|
+
outDir
|
|
1682
|
+
},
|
|
1683
|
+
[
|
|
1684
|
+
generateIndexFile !== false && vite(typeof generateIndexFile === "object" ? generateIndexFile : {})
|
|
1685
|
+
]
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1688
|
+
function applyDefaults2(options) {
|
|
1689
|
+
return {
|
|
1690
|
+
updateViteConfig: options.updateViteConfig ?? true,
|
|
1691
|
+
generateIndexFile: options.generateIndexFile ?? true,
|
|
1692
|
+
configPath: options.configPath ?? "source.config.ts",
|
|
1693
|
+
outDir: options.outDir ?? ".source"
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
var import_vite, import_node_querystring2, path15, import_js_yaml3, FumadocsDeps;
|
|
1697
|
+
var init_vite2 = __esm({
|
|
1698
|
+
"src/vite/index.ts"() {
|
|
1699
|
+
"use strict";
|
|
1700
|
+
import_vite = require("vite");
|
|
1701
|
+
init_build();
|
|
1702
|
+
import_node_querystring2 = require("querystring");
|
|
1703
|
+
init_validation();
|
|
1704
|
+
path15 = __toESM(require("path"), 1);
|
|
1705
|
+
import_js_yaml3 = require("js-yaml");
|
|
1706
|
+
init_mdx();
|
|
1707
|
+
init_config();
|
|
1708
|
+
init_adapter();
|
|
1709
|
+
init_vite();
|
|
1710
|
+
init_core();
|
|
1711
|
+
FumadocsDeps = ["fumadocs-core", "fumadocs-ui", "fumadocs-openapi"];
|
|
1712
|
+
}
|
|
1713
|
+
});
|
|
1714
|
+
|
|
1715
|
+
// src/bin.ts
|
|
1716
|
+
var import_node_fs = require("fs");
|
|
1717
|
+
async function start() {
|
|
1718
|
+
const [configPath] = process.argv.slice(2);
|
|
1719
|
+
const isNext = (0, import_node_fs.existsSync)("next.config.js") || (0, import_node_fs.existsSync)("next.config.mjs") || (0, import_node_fs.existsSync)("next.config.ts");
|
|
1720
|
+
if (isNext) {
|
|
1721
|
+
const { postInstall: postInstall3 } = await Promise.resolve().then(() => (init_next2(), next_exports));
|
|
1722
|
+
await postInstall3(configPath);
|
|
1723
|
+
} else {
|
|
1724
|
+
const { postInstall: postInstall3 } = await Promise.resolve().then(() => (init_vite2(), vite_exports));
|
|
1725
|
+
await postInstall3(configPath);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
void start();
|