@hanzo/docs-mdx 14.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bin.d.ts +1 -0
  3. package/dist/bin.js +16 -0
  4. package/dist/build-mdx-LN7FEKIP.js +8 -0
  5. package/dist/build-mdx-RXJZQXGA.js +8 -0
  6. package/dist/bun/index.d.ts +25 -0
  7. package/dist/bun/index.js +52 -0
  8. package/dist/chunk-4JSFLXXT.js +8 -0
  9. package/dist/chunk-5OBUOALK.js +141 -0
  10. package/dist/chunk-72JS4QVZ.js +17 -0
  11. package/dist/chunk-7I4W7XGI.js +179 -0
  12. package/dist/chunk-7W73RILB.js +173 -0
  13. package/dist/chunk-A3YIGE7S.js +334 -0
  14. package/dist/chunk-AOTZP2TV.js +152 -0
  15. package/dist/chunk-AXJB5MGS.js +173 -0
  16. package/dist/chunk-DMIIE3XZ.js +179 -0
  17. package/dist/chunk-DTFUANSF.js +40 -0
  18. package/dist/chunk-JWZR25CW.js +116 -0
  19. package/dist/chunk-K7N6GD4M.js +17 -0
  20. package/dist/chunk-LXB7WYAF.js +334 -0
  21. package/dist/chunk-MYAVS2LD.js +116 -0
  22. package/dist/chunk-OLD35ARB.js +116 -0
  23. package/dist/chunk-PW2AZGGD.js +125 -0
  24. package/dist/chunk-RGBNABKS.js +334 -0
  25. package/dist/chunk-RPUM7REY.js +40 -0
  26. package/dist/chunk-RR2X6AE6.js +274 -0
  27. package/dist/chunk-S7KOJHHO.js +89 -0
  28. package/dist/chunk-STUCUTJQ.js +334 -0
  29. package/dist/chunk-T6G5VOED.js +116 -0
  30. package/dist/chunk-U5YPLCO5.js +89 -0
  31. package/dist/chunk-UB55AMXC.js +274 -0
  32. package/dist/chunk-VITVHHR6.js +334 -0
  33. package/dist/chunk-VKSHE52K.js +274 -0
  34. package/dist/chunk-VWJKRQZR.js +19 -0
  35. package/dist/chunk-WAAWFNDX.js +179 -0
  36. package/dist/chunk-WGXYJGSZ.js +141 -0
  37. package/dist/chunk-WLJ6EKOZ.js +17 -0
  38. package/dist/chunk-WMYYALAS.js +334 -0
  39. package/dist/chunk-Y7ISNZ7X.js +216 -0
  40. package/dist/chunk-YKRCQ42E.js +216 -0
  41. package/dist/chunk-ZAYZWFWP.js +89 -0
  42. package/dist/config/index.d.ts +18 -0
  43. package/dist/config/index.js +63 -0
  44. package/dist/core-BQcKaqmC.d.ts +350 -0
  45. package/dist/core-BhWOtait.d.ts +350 -0
  46. package/dist/core-CV8uFMUa.d.ts +350 -0
  47. package/dist/core-DAQ64Hkq.d.ts +350 -0
  48. package/dist/core-DZtRjhds.d.ts +350 -0
  49. package/dist/core-De5K4ixv.d.ts +350 -0
  50. package/dist/core-X5ggQtBM.d.ts +350 -0
  51. package/dist/index-BqkSNsGO.d.ts +8 -0
  52. package/dist/index.d.ts +61 -0
  53. package/dist/index.js +0 -0
  54. package/dist/load-from-file-FHW724YY.js +8 -0
  55. package/dist/load-from-file-S5CQ4H6T.js +8 -0
  56. package/dist/next/index.cjs +1165 -0
  57. package/dist/next/index.d.ts +33 -0
  58. package/dist/next/index.js +181 -0
  59. package/dist/node/loader.d.ts +5 -0
  60. package/dist/node/loader.js +41 -0
  61. package/dist/plugins/index-file.d.ts +14 -0
  62. package/dist/plugins/index-file.js +8 -0
  63. package/dist/plugins/json-schema.d.ts +31 -0
  64. package/dist/plugins/json-schema.js +80 -0
  65. package/dist/plugins/last-modified.d.ts +40 -0
  66. package/dist/plugins/last-modified.js +89 -0
  67. package/dist/runtime/browser.d.ts +53 -0
  68. package/dist/runtime/browser.js +67 -0
  69. package/dist/runtime/dynamic.d.ts +27 -0
  70. package/dist/runtime/dynamic.js +79 -0
  71. package/dist/runtime/server.d.ts +14 -0
  72. package/dist/runtime/server.js +8 -0
  73. package/dist/runtime/types.d.ts +61 -0
  74. package/dist/runtime/types.js +0 -0
  75. package/dist/vite/index.d.ts +44 -0
  76. package/dist/vite/index.js +122 -0
  77. package/dist/webpack/mdx.d.ts +6 -0
  78. package/dist/webpack/mdx.js +37 -0
  79. package/dist/webpack/meta.d.ts +6 -0
  80. package/dist/webpack/meta.js +40 -0
  81. package/loader-mdx.cjs +7 -0
  82. package/loader-meta.cjs +7 -0
  83. package/package.json +137 -0
@@ -0,0 +1,1165 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/next/index.ts
31
+ var next_exports = {};
32
+ __export(next_exports, {
33
+ createMDX: () => createMDX,
34
+ postInstall: () => postInstall
35
+ });
36
+ module.exports = __toCommonJS(next_exports);
37
+ var path6 = __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
46
+ function pluginOption(def, options = []) {
47
+ const list = def(Array.isArray(options) ? options : []).filter(
48
+ Boolean
49
+ );
50
+ if (typeof options === "function") {
51
+ return options(list);
52
+ }
53
+ return list;
54
+ }
55
+ function applyMdxPreset(options = {}) {
56
+ return async (environment = "bundler") => {
57
+ if (options.preset === "minimal") return options;
58
+ const plugins = await import("@hanzo/docs-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
+ {
95
+ exportAs: "structuredData",
96
+ ...remarkStructureOptions
97
+ }
98
+ ],
99
+ valueToExport.length > 0 && (() => {
100
+ return (_, file) => {
101
+ file.data["mdx-export"] ??= [];
102
+ for (const name of valueToExport) {
103
+ if (!(name in file.data)) continue;
104
+ file.data["mdx-export"].push({
105
+ name,
106
+ value: file.data[name]
107
+ });
108
+ }
109
+ };
110
+ })
111
+ ],
112
+ mdxOptions.remarkPlugins
113
+ );
114
+ const rehypePlugins = pluginOption(
115
+ (v) => [
116
+ rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
117
+ ...v,
118
+ plugins.rehypeToc
119
+ ],
120
+ mdxOptions.rehypePlugins
121
+ );
122
+ return {
123
+ ...mdxOptions,
124
+ outputFormat: environment === "runtime" ? "function-body" : mdxOptions.outputFormat,
125
+ remarkPlugins,
126
+ rehypePlugins
127
+ };
128
+ };
129
+ }
130
+
131
+ // src/config/build.ts
132
+ var import_node_path = __toESM(require("path"), 1);
133
+ var SupportedFormats = {
134
+ doc: ["mdx", "md"],
135
+ meta: ["json", "yaml"]
136
+ };
137
+ function buildCollection(name, collection, cwd) {
138
+ if (collection.type === "docs") {
139
+ return {
140
+ ...collection,
141
+ type: "docs",
142
+ get dir() {
143
+ return this.docs.dir;
144
+ },
145
+ name,
146
+ meta: buildCollection(name, collection.meta, cwd),
147
+ docs: buildCollection(name, collection.docs, cwd),
148
+ hasFile(filePath) {
149
+ return this.docs.hasFile(filePath) || this.meta.hasFile(filePath);
150
+ },
151
+ isFileSupported(filePath) {
152
+ return this.docs.isFileSupported(filePath) || this.meta.isFileSupported(filePath);
153
+ },
154
+ cwd
155
+ };
156
+ }
157
+ return {
158
+ ...collection,
159
+ ...buildPrimitiveCollection(name, collection, cwd)
160
+ };
161
+ }
162
+ function buildPrimitiveCollection(name, config, cwd) {
163
+ const supportedFormats = SupportedFormats[config.type];
164
+ const patterns = config.files ?? [`**/*.{${supportedFormats.join(",")}}`];
165
+ let matcher;
166
+ return {
167
+ dir: import_node_path.default.resolve(cwd, config.dir),
168
+ cwd,
169
+ name,
170
+ patterns,
171
+ isFileSupported(filePath) {
172
+ return supportedFormats.some((format) => filePath.endsWith(`.${format}`));
173
+ },
174
+ hasFile(filePath) {
175
+ if (!this.isFileSupported(filePath)) return false;
176
+ const relativePath = import_node_path.default.relative(this.dir, filePath);
177
+ if (relativePath.startsWith(`..${import_node_path.default.sep}`)) return false;
178
+ return (matcher ??= (0, import_picomatch.default)(patterns))(relativePath);
179
+ }
180
+ };
181
+ }
182
+ function buildConfig(config, cwd = process.cwd()) {
183
+ const collections = /* @__PURE__ */ new Map();
184
+ const loaded = {};
185
+ for (const [k, v] of Object.entries(config)) {
186
+ if (!v) {
187
+ continue;
188
+ }
189
+ if (typeof v === "object" && "type" in v) {
190
+ if (v.type === "docs" || v.type === "doc" || v.type === "meta") {
191
+ collections.set(k, buildCollection(k, v, cwd));
192
+ continue;
193
+ }
194
+ }
195
+ if (k === "default" && v) {
196
+ Object.assign(loaded, v);
197
+ continue;
198
+ }
199
+ throw new Error(
200
+ `Unknown export "${k}", you can only export collections from source configuration file.`
201
+ );
202
+ }
203
+ const mdxOptionsCache = /* @__PURE__ */ new Map();
204
+ return {
205
+ global: loaded,
206
+ collections,
207
+ workspaces: Object.fromEntries(
208
+ Object.entries(loaded.workspaces ?? {}).map(([key, value]) => {
209
+ return [
210
+ key,
211
+ {
212
+ dir: value.dir,
213
+ config: buildConfig(value.config, import_node_path.default.resolve(cwd, value.dir))
214
+ }
215
+ ];
216
+ })
217
+ ),
218
+ getMDXOptions(collection, environment = "bundler") {
219
+ const key = collection ? `${environment}:${collection.name}` : environment;
220
+ const cached = mdxOptionsCache.get(key);
221
+ if (cached) return cached;
222
+ let result;
223
+ if (collection?.mdxOptions) {
224
+ const optionsFn = collection.mdxOptions;
225
+ result = typeof optionsFn === "function" ? optionsFn(environment) : optionsFn;
226
+ } else {
227
+ result = (async () => {
228
+ const optionsFn = this.global.mdxOptions;
229
+ const options = typeof optionsFn === "function" ? await optionsFn() : optionsFn;
230
+ return applyMdxPreset(options)(environment);
231
+ })();
232
+ }
233
+ mdxOptionsCache.set(key, result);
234
+ return result;
235
+ }
236
+ };
237
+ }
238
+
239
+ // src/config/load-from-file.ts
240
+ async function compileConfig(core) {
241
+ const { build } = await import("esbuild");
242
+ const { configPath, outDir } = core.getOptions();
243
+ const transformed = await build({
244
+ entryPoints: [{ in: configPath, out: "source.config" }],
245
+ bundle: true,
246
+ outdir: outDir,
247
+ target: "node20",
248
+ write: true,
249
+ platform: "node",
250
+ format: "esm",
251
+ packages: "external",
252
+ outExtension: {
253
+ ".js": ".mjs"
254
+ },
255
+ allowOverwrite: true
256
+ });
257
+ if (transformed.errors.length > 0) {
258
+ throw new Error("failed to compile configuration file");
259
+ }
260
+ }
261
+ async function loadConfig(core, build = false) {
262
+ if (build) await compileConfig(core);
263
+ const url = (0, import_node_url.pathToFileURL)(core.getCompiledConfigPath());
264
+ url.searchParams.set("hash", Date.now().toString());
265
+ const config = import(url.href).then(
266
+ (loaded) => buildConfig(loaded)
267
+ );
268
+ return await config;
269
+ }
270
+
271
+ // src/core.ts
272
+ var import_node_path3 = __toESM(require("path"), 1);
273
+ var import_promises = __toESM(require("fs/promises"), 1);
274
+
275
+ // src/utils/validation.ts
276
+ var ValidationError = class extends Error {
277
+ constructor(message, issues) {
278
+ super(
279
+ `${message}:
280
+ ${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
281
+ );
282
+ this.title = message;
283
+ this.issues = issues;
284
+ }
285
+ async toStringFormatted() {
286
+ const picocolorsModule = await import("picocolors");
287
+ const picocolors = picocolorsModule.default ?? picocolorsModule;
288
+ return [
289
+ picocolors.bold(`[MDX] ${this.title}:`),
290
+ ...this.issues.map(
291
+ (issue) => picocolors.redBright(
292
+ `- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
293
+ )
294
+ )
295
+ ].join("\n");
296
+ }
297
+ };
298
+ async function validate(schema, data, context, errorMessage) {
299
+ if (typeof schema === "function" && !("~standard" in schema)) {
300
+ schema = schema(context);
301
+ }
302
+ if ("~standard" in schema) {
303
+ const result = await schema["~standard"].validate(
304
+ data
305
+ );
306
+ if (result.issues) {
307
+ throw new ValidationError(errorMessage, result.issues);
308
+ }
309
+ return result.value;
310
+ }
311
+ return data;
312
+ }
313
+
314
+ // src/utils/codegen.ts
315
+ var import_node_path2 = __toESM(require("path"), 1);
316
+ var import_tinyglobby = require("tinyglobby");
317
+ function createCodegen({
318
+ target = "default",
319
+ outDir = "",
320
+ jsExtension = false,
321
+ globCache = /* @__PURE__ */ new Map()
322
+ }) {
323
+ let eagerImportId = 0;
324
+ const banner = ["// @ts-nocheck"];
325
+ if (target === "vite") {
326
+ banner.push('/// <reference types="vite/client" />');
327
+ }
328
+ return {
329
+ options: {
330
+ target,
331
+ outDir
332
+ },
333
+ lines: [],
334
+ addImport(statement) {
335
+ this.lines.unshift(statement);
336
+ },
337
+ async pushAsync(insert) {
338
+ for (const line of await Promise.all(insert)) {
339
+ if (line === void 0) continue;
340
+ this.lines.push(line);
341
+ }
342
+ },
343
+ async generateGlobImport(patterns, options) {
344
+ if (target === "vite") {
345
+ return this.generateViteGlobImport(patterns, options);
346
+ }
347
+ return this.generateNodeGlobImport(patterns, options);
348
+ },
349
+ generateViteGlobImport(patterns, { base, ...rest }) {
350
+ patterns = (typeof patterns === "string" ? [patterns] : patterns).map(
351
+ normalizeViteGlobPath
352
+ );
353
+ return `import.meta.glob(${JSON.stringify(patterns)}, ${JSON.stringify(
354
+ {
355
+ base: normalizeViteGlobPath(import_node_path2.default.relative(outDir, base)),
356
+ ...rest
357
+ },
358
+ null,
359
+ 2
360
+ )})`;
361
+ },
362
+ async generateNodeGlobImport(patterns, {
363
+ base,
364
+ eager = false,
365
+ query = {},
366
+ import: importName
367
+ }) {
368
+ const cacheKey = JSON.stringify({ patterns, base });
369
+ let files = globCache.get(cacheKey);
370
+ if (!files) {
371
+ files = (0, import_tinyglobby.glob)(patterns, {
372
+ cwd: base
373
+ });
374
+ globCache.set(cacheKey, files);
375
+ }
376
+ let code = "{";
377
+ for (const item of await files) {
378
+ const fullPath = import_node_path2.default.join(base, item);
379
+ const searchParams = new URLSearchParams();
380
+ for (const [k, v] of Object.entries(query)) {
381
+ if (v !== void 0) searchParams.set(k, v);
382
+ }
383
+ const importPath = this.formatImportPath(fullPath) + "?" + searchParams.toString();
384
+ if (eager) {
385
+ const name = `__fd_glob_${eagerImportId++}`;
386
+ this.lines.unshift(
387
+ importName ? `import { ${importName} as ${name} } from ${JSON.stringify(importPath)}` : `import * as ${name} from ${JSON.stringify(importPath)}`
388
+ );
389
+ code += `${JSON.stringify(item)}: ${name}, `;
390
+ } else {
391
+ let line = `${JSON.stringify(item)}: () => import(${JSON.stringify(importPath)})`;
392
+ if (importName) {
393
+ line += `.then(mod => mod.${importName})`;
394
+ }
395
+ code += `${line}, `;
396
+ }
397
+ }
398
+ code += "}";
399
+ return code;
400
+ },
401
+ formatImportPath(file) {
402
+ const ext = import_node_path2.default.extname(file);
403
+ let filename;
404
+ if (ext === ".ts") {
405
+ filename = file.substring(0, file.length - ext.length);
406
+ if (jsExtension) filename += ".js";
407
+ } else {
408
+ filename = file;
409
+ }
410
+ const importPath = slash(import_node_path2.default.relative(outDir, filename));
411
+ return importPath.startsWith(".") ? importPath : `./${importPath}`;
412
+ },
413
+ toString() {
414
+ return [...banner, ...this.lines].join("\n");
415
+ }
416
+ };
417
+ }
418
+ function normalizeViteGlobPath(file) {
419
+ file = slash(file);
420
+ if (file.startsWith("./")) return file;
421
+ if (file.startsWith("/")) return `.${file}`;
422
+ return `./${file}`;
423
+ }
424
+ function slash(path7) {
425
+ const isExtendedLengthPath = path7.startsWith("\\\\?\\");
426
+ if (isExtendedLengthPath) {
427
+ return path7;
428
+ }
429
+ return path7.replaceAll("\\", "/");
430
+ }
431
+ function ident(code, tab = 1) {
432
+ return code.split("\n").map((v) => " ".repeat(tab) + v).join("\n");
433
+ }
434
+
435
+ // src/core.ts
436
+ var _Defaults = {
437
+ configPath: "source.config.ts",
438
+ outDir: ".docs"
439
+ };
440
+ async function getPlugins(pluginOptions) {
441
+ const plugins = [];
442
+ for await (const option of pluginOptions) {
443
+ if (!option) continue;
444
+ if (Array.isArray(option)) plugins.push(...await getPlugins(option));
445
+ else plugins.push(option);
446
+ }
447
+ return plugins;
448
+ }
449
+ function createCore(options) {
450
+ let config;
451
+ let plugins;
452
+ const workspaces = /* @__PURE__ */ new Map();
453
+ async function transformMetadata({
454
+ collection,
455
+ filePath,
456
+ source
457
+ }, data) {
458
+ if (collection.schema) {
459
+ data = await validate(
460
+ collection.schema,
461
+ data,
462
+ { path: filePath, source },
463
+ collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
464
+ );
465
+ }
466
+ return data;
467
+ }
468
+ return {
469
+ /**
470
+ * Convenient cache store, reset when config changes
471
+ */
472
+ cache: /* @__PURE__ */ new Map(),
473
+ async init({ config: newConfig }) {
474
+ config = await newConfig;
475
+ this.cache.clear();
476
+ workspaces.clear();
477
+ plugins = await getPlugins([
478
+ postprocessPlugin(),
479
+ options.plugins,
480
+ config.global.plugins
481
+ ]);
482
+ for (const plugin of plugins) {
483
+ const out = await plugin.config?.call(this.getPluginContext(), config);
484
+ if (out) config = out;
485
+ }
486
+ if (!options.workspace) {
487
+ await Promise.all(
488
+ Object.entries(config.workspaces).map(async ([name, workspace]) => {
489
+ const core = createCore({
490
+ ...options,
491
+ outDir: import_node_path3.default.join(options.outDir, name),
492
+ workspace: {
493
+ name,
494
+ parent: this,
495
+ dir: workspace.dir
496
+ }
497
+ });
498
+ await core.init({ config: workspace.config });
499
+ workspaces.set(name, core);
500
+ })
501
+ );
502
+ }
503
+ },
504
+ getWorkspaces() {
505
+ return workspaces;
506
+ },
507
+ getOptions() {
508
+ return options;
509
+ },
510
+ getConfig() {
511
+ return config;
512
+ },
513
+ /**
514
+ * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
515
+ */
516
+ getCompiledConfigPath() {
517
+ return import_node_path3.default.join(options.outDir, "source.config.mjs");
518
+ },
519
+ getPlugins() {
520
+ return plugins;
521
+ },
522
+ getCollections() {
523
+ return Array.from(config.collections.values());
524
+ },
525
+ getCollection(name) {
526
+ return config.collections.get(name);
527
+ },
528
+ getPluginContext() {
529
+ return {
530
+ core: this
531
+ };
532
+ },
533
+ async initServer(server) {
534
+ const ctx = this.getPluginContext();
535
+ for (const plugin of plugins) {
536
+ await plugin.configureServer?.call(ctx, server);
537
+ }
538
+ for (const workspace of workspaces.values()) {
539
+ await workspace.initServer(server);
540
+ }
541
+ },
542
+ async emit(emitOptions = {}) {
543
+ const { filterPlugin, filterWorkspace, write = false } = emitOptions;
544
+ const start = performance.now();
545
+ const ctx = this.getPluginContext();
546
+ const added = /* @__PURE__ */ new Set();
547
+ const out = {
548
+ entries: [],
549
+ workspaces: {}
550
+ };
551
+ for (const li of await Promise.all(
552
+ plugins.map((plugin) => {
553
+ if (filterPlugin && !filterPlugin(plugin) || !plugin.emit) return;
554
+ return plugin.emit.call(ctx);
555
+ })
556
+ )) {
557
+ if (!li) continue;
558
+ for (const item of li) {
559
+ if (added.has(item.path)) continue;
560
+ out.entries.push(item);
561
+ added.add(item.path);
562
+ }
563
+ }
564
+ if (write) {
565
+ await Promise.all(
566
+ out.entries.map(async (entry) => {
567
+ const file = import_node_path3.default.join(options.outDir, entry.path);
568
+ await import_promises.default.mkdir(import_node_path3.default.dirname(file), { recursive: true });
569
+ await import_promises.default.writeFile(file, entry.content);
570
+ })
571
+ );
572
+ console.log(
573
+ options.workspace ? `[MDX: ${options.workspace.name}] generated files in ${performance.now() - start}ms` : `[MDX] generated files in ${performance.now() - start}ms`
574
+ );
575
+ }
576
+ for (const [name, workspace] of workspaces) {
577
+ if (filterWorkspace && !filterWorkspace(name)) continue;
578
+ out.workspaces[name] = (await workspace.emit(emitOptions)).entries;
579
+ }
580
+ return out;
581
+ },
582
+ async transformMeta(options2, data) {
583
+ const ctx = {
584
+ ...this.getPluginContext(),
585
+ ...options2
586
+ };
587
+ data = await transformMetadata(options2, data);
588
+ for (const plugin of plugins) {
589
+ if (plugin.meta?.transform)
590
+ data = await plugin.meta.transform.call(ctx, data) ?? data;
591
+ }
592
+ return data;
593
+ },
594
+ async transformFrontmatter(options2, data) {
595
+ const ctx = {
596
+ ...this.getPluginContext(),
597
+ ...options2
598
+ };
599
+ data = await transformMetadata(options2, data);
600
+ for (const plugin of plugins) {
601
+ if (plugin.doc?.frontmatter)
602
+ data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
603
+ }
604
+ return data;
605
+ },
606
+ async transformVFile(options2, file) {
607
+ const ctx = {
608
+ ...this.getPluginContext(),
609
+ ...options2
610
+ };
611
+ for (const plugin of plugins) {
612
+ if (plugin.doc?.vfile)
613
+ file = await plugin.doc.vfile.call(ctx, file) ?? file;
614
+ }
615
+ return file;
616
+ }
617
+ };
618
+ }
619
+ function postprocessPlugin() {
620
+ const LinkReferenceTypes = `{
621
+ /**
622
+ * extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
623
+ */
624
+ extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
625
+ }`;
626
+ return {
627
+ "index-file": {
628
+ generateTypeConfig() {
629
+ const lines = [];
630
+ lines.push("{");
631
+ lines.push(" DocData: {");
632
+ for (const collection of this.core.getCollections()) {
633
+ let postprocessOptions;
634
+ switch (collection.type) {
635
+ case "doc":
636
+ postprocessOptions = collection.postprocess;
637
+ break;
638
+ case "docs":
639
+ postprocessOptions = collection.docs.postprocess;
640
+ break;
641
+ }
642
+ if (postprocessOptions?.extractLinkReferences) {
643
+ lines.push(ident(`${collection.name}: ${LinkReferenceTypes},`, 2));
644
+ }
645
+ }
646
+ lines.push(" }");
647
+ lines.push("}");
648
+ return lines.join("\n");
649
+ },
650
+ serverOptions(options) {
651
+ options.doc ??= {};
652
+ options.doc.passthroughs ??= [];
653
+ options.doc.passthroughs.push("extractedReferences");
654
+ }
655
+ }
656
+ };
657
+ }
658
+
659
+ // src/loaders/index.ts
660
+ var metaLoaderGlob = /\.(json|yaml)(\?.+?)?$/;
661
+ var mdxLoaderGlob = /\.mdx?(\?.+?)?$/;
662
+
663
+ // src/plugins/index-file.ts
664
+ var import_path = __toESM(require("path"), 1);
665
+ var import_tinyglobby2 = require("tinyglobby");
666
+
667
+ // src/utils/fs-cache.ts
668
+ var import_promises2 = __toESM(require("fs/promises"), 1);
669
+ var import_node_path4 = __toESM(require("path"), 1);
670
+ var map = /* @__PURE__ */ new Map();
671
+ function createFSCache() {
672
+ return {
673
+ read(file) {
674
+ const fullPath = toFullPath(file);
675
+ const cached = map.get(fullPath);
676
+ if (cached) return cached;
677
+ const read = import_promises2.default.readFile(fullPath).then((s) => s.toString());
678
+ map.set(fullPath, read);
679
+ return read;
680
+ },
681
+ delete(file) {
682
+ map.delete(toFullPath(file));
683
+ }
684
+ };
685
+ }
686
+ function toFullPath(file) {
687
+ if (import_node_path4.default.isAbsolute(file)) {
688
+ return import_node_path4.default.relative(process.cwd(), file);
689
+ }
690
+ return file;
691
+ }
692
+
693
+ // src/plugins/index-file.ts
694
+ var import_crypto = require("crypto");
695
+
696
+ // src/utils/fuma-matter.ts
697
+ var import_js_yaml = require("js-yaml");
698
+ var regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
699
+ function fumaMatter(input) {
700
+ const output = { matter: "", data: {}, content: input };
701
+ const match = regex.exec(input);
702
+ if (!match) {
703
+ return output;
704
+ }
705
+ output.matter = match[0];
706
+ output.content = input.slice(match[0].length);
707
+ const loaded = (0, import_js_yaml.load)(match[1]);
708
+ output.data = loaded ?? {};
709
+ return output;
710
+ }
711
+
712
+ // src/plugins/index-file.ts
713
+ var indexFileCache = createFSCache();
714
+ function indexFile(options = {}) {
715
+ const {
716
+ target = "default",
717
+ addJsExtension,
718
+ browser = true,
719
+ dynamic = true
720
+ } = options;
721
+ let dynamicCollections;
722
+ function isDynamic(collection) {
723
+ return collection.type === "docs" && collection.docs.dynamic || collection.type === "doc" && collection.dynamic;
724
+ }
725
+ function generateConfigs(core) {
726
+ const serverOptions = {};
727
+ const typeConfigs = [
728
+ 'import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig'
729
+ ];
730
+ const ctx = core.getPluginContext();
731
+ for (const plugin of core.getPlugins()) {
732
+ const indexFilePlugin = plugin["index-file"];
733
+ if (!indexFilePlugin) continue;
734
+ indexFilePlugin.serverOptions?.call(ctx, serverOptions);
735
+ const config = indexFilePlugin.generateTypeConfig?.call(ctx);
736
+ if (config) typeConfigs.push(config);
737
+ }
738
+ return {
739
+ serverOptions,
740
+ tc: typeConfigs.join(" & ")
741
+ };
742
+ }
743
+ return {
744
+ name: "index-file",
745
+ config() {
746
+ dynamicCollections = this.core.getCollections().filter(isDynamic);
747
+ },
748
+ configureServer(server) {
749
+ if (!server.watcher) return;
750
+ server.watcher.on("all", async (event, file) => {
751
+ indexFileCache.delete(file);
752
+ if (dynamicCollections.length === 0) {
753
+ if (target === "vite") return;
754
+ if (target === "default" && event === "change") return;
755
+ }
756
+ const updatedCollection = this.core.getCollections().find((collection) => collection.hasFile(file));
757
+ if (!updatedCollection) return;
758
+ if (!isDynamic(updatedCollection)) {
759
+ if (target === "vite") return;
760
+ if (target === "default" && event === "change") return;
761
+ }
762
+ await this.core.emit({
763
+ filterPlugin: (plugin) => plugin.name === "index-file",
764
+ filterWorkspace: () => false,
765
+ write: true
766
+ });
767
+ });
768
+ },
769
+ async emit() {
770
+ const globCache = /* @__PURE__ */ new Map();
771
+ const { workspace, outDir } = this.core.getOptions();
772
+ const { serverOptions, tc } = generateConfigs(this.core);
773
+ const toEmitEntry = async (path7, content) => {
774
+ const codegen = createCodegen({
775
+ target,
776
+ outDir,
777
+ jsExtension: addJsExtension,
778
+ globCache
779
+ });
780
+ await content({
781
+ core: this.core,
782
+ codegen,
783
+ serverOptions,
784
+ tc,
785
+ workspace: workspace?.name
786
+ });
787
+ return {
788
+ path: path7,
789
+ content: codegen.toString()
790
+ };
791
+ };
792
+ const out = [
793
+ toEmitEntry("server.ts", generateServerIndexFile)
794
+ ];
795
+ if (dynamic)
796
+ out.push(toEmitEntry("dynamic.ts", generateDynamicIndexFile));
797
+ if (browser)
798
+ out.push(toEmitEntry("browser.ts", generateBrowserIndexFile));
799
+ return await Promise.all(out);
800
+ }
801
+ };
802
+ }
803
+ async function generateServerIndexFile(ctx) {
804
+ const { core, codegen, serverOptions, tc } = ctx;
805
+ codegen.lines.push(
806
+ `import { server } from '@hanzo/docs/mdx/runtime/server';`,
807
+ `import type * as Config from '${codegen.formatImportPath(core.getOptions().configPath)}';`,
808
+ "",
809
+ `const create = server<typeof Config, ${tc}>(${JSON.stringify(serverOptions)});`
810
+ );
811
+ async function generateCollectionObject(collection) {
812
+ const base = getBase(collection);
813
+ switch (collection.type) {
814
+ case "docs": {
815
+ if (collection.docs.dynamic) return;
816
+ if (collection.docs.async) {
817
+ const [metaGlob2, headGlob, bodyGlob] = await Promise.all([
818
+ generateMetaCollectionGlob(ctx, collection.meta, true),
819
+ generateDocCollectionFrontmatterGlob(ctx, collection.docs, true),
820
+ generateDocCollectionGlob(ctx, collection.docs)
821
+ ]);
822
+ return `await create.docsLazy("${collection.name}", "${base}", ${metaGlob2}, ${headGlob}, ${bodyGlob})`;
823
+ }
824
+ const [metaGlob, docGlob] = await Promise.all([
825
+ generateMetaCollectionGlob(ctx, collection.meta, true),
826
+ generateDocCollectionGlob(ctx, collection.docs, true)
827
+ ]);
828
+ return `await create.docs("${collection.name}", "${base}", ${metaGlob}, ${docGlob})`;
829
+ }
830
+ case "doc":
831
+ if (collection.dynamic) return;
832
+ if (collection.async) {
833
+ const [headGlob, bodyGlob] = await Promise.all([
834
+ generateDocCollectionFrontmatterGlob(ctx, collection, true),
835
+ generateDocCollectionGlob(ctx, collection)
836
+ ]);
837
+ return `await create.docLazy("${collection.name}", "${base}", ${headGlob}, ${bodyGlob})`;
838
+ }
839
+ return `await create.doc("${collection.name}", "${base}", ${await generateDocCollectionGlob(
840
+ ctx,
841
+ collection,
842
+ true
843
+ )})`;
844
+ case "meta":
845
+ return `await create.meta("${collection.name}", "${base}", ${await generateMetaCollectionGlob(
846
+ ctx,
847
+ collection,
848
+ true
849
+ )})`;
850
+ }
851
+ }
852
+ await codegen.pushAsync(
853
+ core.getCollections().map(async (collection) => {
854
+ const obj = await generateCollectionObject(collection);
855
+ if (!obj) return;
856
+ return `
857
+ export const ${collection.name} = ${obj};`;
858
+ })
859
+ );
860
+ }
861
+ async function generateDynamicIndexFile(ctx) {
862
+ const { core, codegen, serverOptions, tc } = ctx;
863
+ const { configPath, environment, outDir } = core.getOptions();
864
+ const partialOptions = {
865
+ configPath,
866
+ environment,
867
+ outDir
868
+ };
869
+ codegen.lines.push(
870
+ `import { dynamic } from '@hanzo/docs/mdx/runtime/dynamic';`,
871
+ `import * as Config from '${codegen.formatImportPath(configPath)}';`,
872
+ "",
873
+ `const create = await dynamic<typeof Config, ${tc}>(Config, ${JSON.stringify(partialOptions)}, ${JSON.stringify(serverOptions)});`
874
+ );
875
+ async function generateCollectionObjectEntry(collection, absolutePath) {
876
+ const fullPath = import_path.default.relative(process.cwd(), absolutePath);
877
+ const content = await indexFileCache.read(fullPath).catch(() => "");
878
+ const parsed = fumaMatter(content);
879
+ const data = await core.transformFrontmatter(
880
+ {
881
+ collection,
882
+ filePath: fullPath,
883
+ source: content
884
+ },
885
+ parsed.data
886
+ );
887
+ const hash = (0, import_crypto.createHash)("md5").update(content).digest("hex");
888
+ const infoStr = [
889
+ // make sure it's included in vercel/nft
890
+ `absolutePath: path.resolve(${JSON.stringify(fullPath)})`
891
+ ];
892
+ for (const [k, v] of Object.entries({
893
+ info: {
894
+ fullPath,
895
+ path: import_path.default.relative(collection.dir, absolutePath)
896
+ },
897
+ data,
898
+ hash
899
+ })) {
900
+ infoStr.push(`${k}: ${JSON.stringify(v)}`);
901
+ }
902
+ return `{ ${infoStr.join(", ")} }`;
903
+ }
904
+ async function generateCollectionObject(parent) {
905
+ let collection;
906
+ if (parent.type === "doc") collection = parent;
907
+ else if (parent.type === "docs") collection = parent.docs;
908
+ if (!collection || !collection.dynamic) return;
909
+ const files = await (0, import_tinyglobby2.glob)(collection.patterns, {
910
+ cwd: collection.dir,
911
+ absolute: true
912
+ });
913
+ const entries = await Promise.all(
914
+ files.map((file) => generateCollectionObjectEntry(collection, file))
915
+ );
916
+ switch (parent.type) {
917
+ case "docs": {
918
+ const metaGlob = await generateMetaCollectionGlob(
919
+ ctx,
920
+ parent.meta,
921
+ true
922
+ );
923
+ return `await create.docs("${parent.name}", "${getBase(parent)}", ${metaGlob}, ${entries.join(", ")})`;
924
+ }
925
+ case "doc":
926
+ return `await create.doc("${collection.name}", "${getBase(collection)}", ${entries.join(", ")})`;
927
+ }
928
+ }
929
+ await codegen.pushAsync(
930
+ core.getCollections().map(async (collection) => {
931
+ const obj = await generateCollectionObject(collection);
932
+ if (!obj) return;
933
+ return `
934
+ export const ${collection.name} = ${obj};`;
935
+ })
936
+ );
937
+ }
938
+ async function generateBrowserIndexFile(ctx) {
939
+ const { core, codegen, tc } = ctx;
940
+ codegen.lines.push(
941
+ `import { browser } from '@hanzo/docs/mdx/runtime/browser';`,
942
+ `import type * as Config from '${codegen.formatImportPath(core.getOptions().configPath)}';`,
943
+ "",
944
+ `const create = browser<typeof Config, ${tc}>();`
945
+ );
946
+ async function generateCollectionObject(collection) {
947
+ switch (collection.type) {
948
+ case "docs": {
949
+ if (collection.docs.dynamic) return;
950
+ return generateCollectionObject(collection.docs);
951
+ }
952
+ case "doc":
953
+ if (collection.dynamic) return;
954
+ return `create.doc("${collection.name}", ${await generateDocCollectionGlob(ctx, collection)})`;
955
+ }
956
+ }
957
+ codegen.lines.push("const browserCollections = {");
958
+ await codegen.pushAsync(
959
+ core.getCollections().map(async (collection) => {
960
+ const obj = await generateCollectionObject(collection);
961
+ if (!obj) return;
962
+ return ident(`${collection.name}: ${obj},`);
963
+ })
964
+ );
965
+ codegen.lines.push("};", "export default browserCollections;");
966
+ }
967
+ function getBase(collection) {
968
+ return import_path.default.relative(process.cwd(), collection.dir);
969
+ }
970
+ function generateDocCollectionFrontmatterGlob({ codegen, workspace }, collection, eager = false) {
971
+ return codegen.generateGlobImport(collection.patterns, {
972
+ query: {
973
+ collection: collection.name,
974
+ only: "frontmatter",
975
+ workspace
976
+ },
977
+ import: "frontmatter",
978
+ base: collection.dir,
979
+ eager
980
+ });
981
+ }
982
+ function generateDocCollectionGlob({ codegen, workspace }, collection, eager = false) {
983
+ return codegen.generateGlobImport(collection.patterns, {
984
+ query: {
985
+ collection: collection.name,
986
+ workspace
987
+ },
988
+ base: collection.dir,
989
+ eager
990
+ });
991
+ }
992
+ function generateMetaCollectionGlob({ codegen, workspace }, collection, eager = false) {
993
+ return codegen.generateGlobImport(collection.patterns, {
994
+ query: {
995
+ collection: collection.name,
996
+ workspace
997
+ },
998
+ import: "default",
999
+ base: collection.dir,
1000
+ eager
1001
+ });
1002
+ }
1003
+
1004
+ // src/next/index.ts
1005
+ var defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
1006
+ function createMDX(createOptions = {}) {
1007
+ const core = createNextCore(applyDefaults(createOptions));
1008
+ const isDev = process.env.NODE_ENV === "development";
1009
+ if (process.env._FUMADOCS_MDX !== "1") {
1010
+ process.env._FUMADOCS_MDX = "1";
1011
+ void init(isDev, core);
1012
+ }
1013
+ return (nextConfig = {}) => {
1014
+ const { configPath, outDir } = core.getOptions();
1015
+ const loaderOptions = {
1016
+ configPath,
1017
+ outDir,
1018
+ absoluteCompiledConfigPath: path6.resolve(core.getCompiledConfigPath()),
1019
+ isDev
1020
+ };
1021
+ const turbopack = {
1022
+ ...nextConfig.turbopack,
1023
+ rules: {
1024
+ ...nextConfig.turbopack?.rules,
1025
+ "*.{md,mdx}": {
1026
+ loaders: [
1027
+ {
1028
+ loader: "@hanzo/docs-mdx/loader-mdx",
1029
+ options: loaderOptions
1030
+ }
1031
+ ],
1032
+ as: "*.js"
1033
+ },
1034
+ "*.json": {
1035
+ loaders: [
1036
+ {
1037
+ loader: "@hanzo/docs-mdx/loader-meta",
1038
+ options: loaderOptions
1039
+ }
1040
+ ],
1041
+ as: "*.json"
1042
+ },
1043
+ "*.yaml": {
1044
+ loaders: [
1045
+ {
1046
+ loader: "@hanzo/docs-mdx/loader-meta",
1047
+ options: loaderOptions
1048
+ }
1049
+ ],
1050
+ as: "*.js"
1051
+ }
1052
+ }
1053
+ };
1054
+ return {
1055
+ ...nextConfig,
1056
+ turbopack,
1057
+ pageExtensions: nextConfig.pageExtensions ?? defaultPageExtensions,
1058
+ webpack: (config, options) => {
1059
+ config.resolve ||= {};
1060
+ config.module ||= {};
1061
+ config.module.rules ||= [];
1062
+ config.module.rules.push(
1063
+ {
1064
+ test: mdxLoaderGlob,
1065
+ use: [
1066
+ options.defaultLoaders.babel,
1067
+ {
1068
+ loader: "@hanzo/docs-mdx/loader-mdx",
1069
+ options: loaderOptions
1070
+ }
1071
+ ]
1072
+ },
1073
+ {
1074
+ test: metaLoaderGlob,
1075
+ enforce: "pre",
1076
+ use: [
1077
+ {
1078
+ loader: "@hanzo/docs-mdx/loader-meta",
1079
+ options: loaderOptions
1080
+ }
1081
+ ]
1082
+ }
1083
+ );
1084
+ config.plugins ||= [];
1085
+ return nextConfig.webpack?.(config, options) ?? config;
1086
+ }
1087
+ };
1088
+ };
1089
+ }
1090
+ async function init(dev, core) {
1091
+ async function initOrReload() {
1092
+ await core.init({
1093
+ config: loadConfig(core, true)
1094
+ });
1095
+ await core.emit({ write: true });
1096
+ }
1097
+ async function devServer() {
1098
+ const { FSWatcher } = await import("chokidar");
1099
+ const { configPath, outDir } = core.getOptions();
1100
+ const watcher = new FSWatcher({
1101
+ ignoreInitial: true,
1102
+ persistent: true,
1103
+ ignored: [outDir]
1104
+ });
1105
+ watcher.add(configPath);
1106
+ for (const collection of core.getCollections()) {
1107
+ watcher.add(collection.dir);
1108
+ }
1109
+ for (const workspace of core.getWorkspaces().values()) {
1110
+ for (const collection of workspace.getCollections()) {
1111
+ watcher.add(collection.dir);
1112
+ }
1113
+ }
1114
+ watcher.on("ready", () => {
1115
+ console.log("[MDX] started dev server");
1116
+ });
1117
+ const absoluteConfigPath = path6.resolve(configPath);
1118
+ watcher.on("all", async (_event, file) => {
1119
+ if (path6.resolve(file) === absoluteConfigPath) {
1120
+ watcher.removeAllListeners();
1121
+ await watcher.close();
1122
+ await initOrReload();
1123
+ console.log("[MDX] restarting dev server");
1124
+ await devServer();
1125
+ }
1126
+ });
1127
+ process.on("exit", () => {
1128
+ if (watcher.closed) return;
1129
+ console.log("[MDX] closing dev server");
1130
+ void watcher.close();
1131
+ });
1132
+ await core.initServer({ watcher });
1133
+ }
1134
+ await initOrReload();
1135
+ if (dev) {
1136
+ await devServer();
1137
+ }
1138
+ }
1139
+ async function postInstall(options) {
1140
+ const core = createNextCore(applyDefaults(options));
1141
+ await core.init({
1142
+ config: loadConfig(core, true)
1143
+ });
1144
+ await core.emit({ write: true });
1145
+ }
1146
+ function applyDefaults(options) {
1147
+ return {
1148
+ index: {},
1149
+ outDir: options.outDir ?? _Defaults.outDir,
1150
+ configPath: options.configPath ?? _Defaults.configPath
1151
+ };
1152
+ }
1153
+ function createNextCore(options) {
1154
+ return createCore({
1155
+ environment: "next",
1156
+ outDir: options.outDir,
1157
+ configPath: options.configPath,
1158
+ plugins: [options.index && indexFile(options.index)]
1159
+ });
1160
+ }
1161
+ // Annotate the CommonJS export names for ESM import in node:
1162
+ 0 && (module.exports = {
1163
+ createMDX,
1164
+ postInstall
1165
+ });