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.
Files changed (93) hide show
  1. package/dist/bin.cjs +1728 -0
  2. package/dist/bin.d.cts +1 -0
  3. package/dist/bin.d.ts +1 -0
  4. package/dist/bin.js +16 -0
  5. package/dist/build-mdx-CCNr86q6.d.ts +53 -0
  6. package/dist/build-mdx-D-r3_eQL.d.cts +53 -0
  7. package/dist/bun/index.cjs +857 -0
  8. package/dist/bun/index.d.cts +13 -0
  9. package/dist/bun/index.d.ts +13 -0
  10. package/dist/bun/index.js +62 -0
  11. package/dist/chunk-3J3WL7WN.js +160 -0
  12. package/dist/chunk-CXA4JO4Z.js +45 -0
  13. package/dist/chunk-EELYB2XC.js +207 -0
  14. package/dist/chunk-FSZMKRVH.js +80 -0
  15. package/dist/chunk-II3H5ZVZ.js +77 -0
  16. package/dist/chunk-JVZFH6ND.js +40 -0
  17. package/dist/chunk-K5ZLPEIQ.js +207 -0
  18. package/dist/{chunk-VFALQK6O.js → chunk-KILFIBVW.js} +21 -12
  19. package/dist/chunk-NVRDCY6Z.js +30 -0
  20. package/dist/chunk-U4MQ44TS.js +53 -0
  21. package/dist/chunk-VWJKRQZR.js +19 -0
  22. package/dist/chunk-XQ5O7IPO.js +128 -0
  23. package/dist/chunk-XZY2AWJI.js +81 -0
  24. package/dist/chunk-YVCR6FUH.js +82 -0
  25. package/dist/config/index.cjs +232 -128
  26. package/dist/config/index.d.cts +4 -6
  27. package/dist/config/index.d.ts +4 -6
  28. package/dist/config/index.js +26 -19
  29. package/dist/core-B6j6Fxse.d.cts +218 -0
  30. package/dist/core-B6j6Fxse.d.ts +218 -0
  31. package/dist/index.cjs +0 -76
  32. package/dist/index.d.cts +73 -20
  33. package/dist/index.d.ts +73 -20
  34. package/dist/index.js +0 -10
  35. package/dist/load-MNG3CLET.js +7 -0
  36. package/dist/next/index.cjs +567 -314
  37. package/dist/next/index.d.cts +9 -12
  38. package/dist/next/index.d.ts +9 -12
  39. package/dist/next/index.js +238 -211
  40. package/dist/node/loader.cjs +922 -0
  41. package/dist/node/loader.d.cts +5 -0
  42. package/dist/node/loader.d.ts +5 -0
  43. package/dist/node/loader.js +33 -0
  44. package/dist/plugins/json-schema.cjs +162 -0
  45. package/dist/plugins/json-schema.d.cts +24 -0
  46. package/dist/plugins/json-schema.d.ts +24 -0
  47. package/dist/plugins/json-schema.js +78 -0
  48. package/dist/{mdx-options-CAU273O3.js → preset-ZMP6U62C.js} +1 -1
  49. package/dist/runtime/next/async.cjs +715 -0
  50. package/dist/runtime/next/async.d.cts +21 -0
  51. package/dist/runtime/next/async.d.ts +21 -0
  52. package/dist/runtime/next/async.js +89 -0
  53. package/dist/runtime/next/index.cjs +136 -0
  54. package/dist/runtime/next/index.d.cts +33 -0
  55. package/dist/runtime/next/index.d.ts +33 -0
  56. package/dist/runtime/next/index.js +11 -0
  57. package/dist/runtime/vite/browser.cjs +107 -0
  58. package/dist/runtime/vite/browser.d.cts +59 -0
  59. package/dist/runtime/vite/browser.d.ts +59 -0
  60. package/dist/runtime/vite/browser.js +11 -0
  61. package/dist/runtime/vite/server.cjs +243 -0
  62. package/dist/runtime/vite/server.d.cts +30 -0
  63. package/dist/runtime/vite/server.d.ts +30 -0
  64. package/dist/runtime/vite/server.js +111 -0
  65. package/dist/types-AGzTfBmf.d.ts +45 -0
  66. package/dist/types-DKGMoay5.d.cts +45 -0
  67. package/dist/vite/index.cjs +1185 -0
  68. package/dist/vite/index.d.cts +45 -0
  69. package/dist/vite/index.d.ts +45 -0
  70. package/dist/vite/index.js +297 -0
  71. package/dist/webpack/index.cjs +957 -0
  72. package/dist/{loader-mdx.d.cts → webpack/index.d.cts} +3 -6
  73. package/dist/{loader-mdx.d.ts → webpack/index.d.ts} +3 -6
  74. package/dist/webpack/index.js +44 -0
  75. package/loader-mdx.cjs +1 -1
  76. package/package.json +86 -29
  77. package/bin.js +0 -5
  78. package/dist/chunk-2ZOW45YZ.js +0 -63
  79. package/dist/chunk-DRVUBK5B.js +0 -39
  80. package/dist/chunk-HFLDWPJA.js +0 -62
  81. package/dist/chunk-IOENRFUX.js +0 -112
  82. package/dist/chunk-MK7EXW7O.js +0 -75
  83. package/dist/define-BaW0PQDJ.d.cts +0 -201
  84. package/dist/define-BaW0PQDJ.d.ts +0 -201
  85. package/dist/loader-mdx.cjs +0 -527
  86. package/dist/loader-mdx.js +0 -162
  87. package/dist/runtime/async.cjs +0 -269
  88. package/dist/runtime/async.d.cts +0 -18
  89. package/dist/runtime/async.d.ts +0 -18
  90. package/dist/runtime/async.js +0 -73
  91. package/dist/types-BNrQHCj5.d.cts +0 -100
  92. package/dist/types-DEduCvIT.d.ts +0 -100
  93. package/dist/watcher-IAZDSTU7.js +0 -24
@@ -1,21 +1,18 @@
1
1
  import { NextConfig } from 'next';
2
2
 
3
- /**
4
- * Start a MDX server that builds index and manifest files.
5
- *
6
- * In development mode, it starts a file watcher to auto-update output as your input changes.
7
- */
8
- declare function start(dev: boolean, configPath: string, outDir: string): Promise<void>;
9
-
10
3
  interface CreateMDXOptions {
11
4
  /**
12
5
  * Path to source configuration file
13
6
  */
14
7
  configPath?: string;
8
+ /**
9
+ * Directory for output files
10
+ *
11
+ * @defaultValue '.source'
12
+ */
13
+ outDir?: string;
15
14
  }
15
+ declare function createMDX(createOptions?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
16
+ declare function postInstall(configPath?: string, outDir?: string): Promise<void>;
16
17
 
17
- declare function createMDX({ configPath, }?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
18
-
19
- declare function postInstall(configPath?: string): Promise<void>;
20
-
21
- export { type CreateMDXOptions, createMDX, postInstall, start };
18
+ export { type CreateMDXOptions, createMDX, postInstall };
@@ -1,21 +1,18 @@
1
1
  import { NextConfig } from 'next';
2
2
 
3
- /**
4
- * Start a MDX server that builds index and manifest files.
5
- *
6
- * In development mode, it starts a file watcher to auto-update output as your input changes.
7
- */
8
- declare function start(dev: boolean, configPath: string, outDir: string): Promise<void>;
9
-
10
3
  interface CreateMDXOptions {
11
4
  /**
12
5
  * Path to source configuration file
13
6
  */
14
7
  configPath?: string;
8
+ /**
9
+ * Directory for output files
10
+ *
11
+ * @defaultValue '.source'
12
+ */
13
+ outDir?: string;
15
14
  }
15
+ declare function createMDX(createOptions?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
16
+ declare function postInstall(configPath?: string, outDir?: string): Promise<void>;
16
17
 
17
- declare function createMDX({ configPath, }?: CreateMDXOptions): (nextConfig?: NextConfig) => NextConfig;
18
-
19
- declare function postInstall(configPath?: string): Promise<void>;
20
-
21
- export { type CreateMDXOptions, createMDX, postInstall, start };
18
+ export { type CreateMDXOptions, createMDX, postInstall };
@@ -1,75 +1,103 @@
1
1
  import {
2
- findConfigFile,
3
- getConfigHash,
4
2
  loadConfig
5
- } from "../chunk-HFLDWPJA.js";
6
- import "../chunk-DRVUBK5B.js";
3
+ } from "../chunk-JVZFH6ND.js";
4
+ import {
5
+ getImportCode,
6
+ toImportPath
7
+ } from "../chunk-CXA4JO4Z.js";
8
+ import "../chunk-U4MQ44TS.js";
7
9
  import {
8
10
  ValidationError,
11
+ createCore,
12
+ findConfigFile,
13
+ getGitTimestamp,
9
14
  validate
10
- } from "../chunk-2ZOW45YZ.js";
11
-
12
- // src/next/create.ts
13
- import path3 from "node:path";
14
-
15
- // src/map/index.ts
16
- import * as path2 from "node:path";
17
- import * as fs2 from "node:fs/promises";
18
-
19
- // src/map/generate.ts
20
- import * as path from "node:path";
21
- import * as fs from "node:fs/promises";
22
- import fg from "fast-glob";
15
+ } from "../chunk-EELYB2XC.js";
16
+ import {
17
+ fumaMatter
18
+ } from "../chunk-VWJKRQZR.js";
19
+ import {
20
+ getCollectionFiles
21
+ } from "../chunk-XZY2AWJI.js";
23
22
 
24
- // src/utils/get-type-from-path.ts
25
- import { extname } from "node:path";
26
- var docTypes = [".mdx", ".md"];
27
- var metaTypes = [".json", ".yaml"];
28
- function getTypeFromPath(path5) {
29
- const ext = extname(path5);
30
- if (docTypes.includes(ext)) return "doc";
31
- if (metaTypes.includes(ext)) return "meta";
32
- }
23
+ // src/next/index.ts
24
+ import * as path3 from "path";
33
25
 
34
- // src/map/file-cache.ts
26
+ // src/next/file-cache.ts
35
27
  import { LRUCache } from "lru-cache";
28
+ import fs from "fs/promises";
29
+ import path from "path";
36
30
  var map = new LRUCache({
37
- max: 200
31
+ max: 100
38
32
  });
39
- var fileCache = {
40
- read(namespace, path5) {
41
- return map.get(`${namespace}.${path5}`);
42
- },
43
- write(namespace, path5, data) {
44
- map.set(`${namespace}.${path5}`, data);
45
- },
46
- removeCache(path5) {
47
- for (const key of map.keys()) {
48
- const keyPath = key.slice(key.indexOf(".") + 1);
49
- if (keyPath === path5) map.delete(key);
50
- }
33
+ function toFullPath(file) {
34
+ if (path.isAbsolute(file)) {
35
+ return path.relative(process.cwd(), file);
51
36
  }
52
- };
53
-
54
- // src/map/generate.ts
55
- import matter from "gray-matter";
37
+ return file;
38
+ }
56
39
  async function readFileWithCache(file) {
57
- const cached = fileCache.read("read-file", file);
40
+ const fullPath = toFullPath(file);
41
+ const cached = map.get(fullPath);
58
42
  if (cached) return cached;
59
- return (await fs.readFile(file)).toString();
43
+ const read = fs.readFile(fullPath).then((s) => s.toString());
44
+ map.set(fullPath, read);
45
+ return read;
46
+ }
47
+ function removeFileCache(file) {
48
+ map.delete(toFullPath(file));
49
+ }
50
+
51
+ // src/plugins/next.ts
52
+ import * as path2 from "path";
53
+ import { createHash } from "crypto";
54
+ import { load } from "js-yaml";
55
+ function next() {
56
+ let config;
57
+ let shouldEmitOnChange = false;
58
+ return {
59
+ name: "next",
60
+ config(v) {
61
+ config = v;
62
+ shouldEmitOnChange = false;
63
+ for (const collection of config.collections.values()) {
64
+ if (collection.type === "doc" && collection.async || collection.type === "docs" && collection.docs.async) {
65
+ shouldEmitOnChange = true;
66
+ }
67
+ }
68
+ },
69
+ configureServer(server) {
70
+ if (!server.watcher) return;
71
+ server.watcher.on("all", async () => {
72
+ if (!shouldEmitOnChange) return;
73
+ await this.core.emitAndWrite({
74
+ filterPlugin: (plugin) => plugin.name === "next"
75
+ });
76
+ });
77
+ },
78
+ async emit() {
79
+ return [
80
+ {
81
+ path: "index.ts",
82
+ content: await indexFile(this.configPath, config, {
83
+ relativeTo: this.outDir
84
+ })
85
+ }
86
+ ];
87
+ }
88
+ };
60
89
  }
61
- async function generateJS(configPath, config, outputPath, configHash) {
62
- const outDir2 = path.dirname(outputPath);
90
+ async function indexFile(configPath, config, importPath, configHash = false) {
63
91
  let asyncInit = false;
64
92
  const lines = [
65
93
  getImportCode({
66
94
  type: "named",
67
95
  names: ["_runtime"],
68
- specifier: "fumadocs-mdx"
96
+ specifier: "fumadocs-mdx/runtime/next"
69
97
  }),
70
98
  getImportCode({
71
99
  type: "namespace",
72
- specifier: toImportPath(configPath, outDir2),
100
+ specifier: toImportPath(configPath, importPath),
73
101
  name: "_source"
74
102
  })
75
103
  ];
@@ -77,11 +105,15 @@ async function generateJS(configPath, config, outputPath, configHash) {
77
105
  async function getDocEntries(collectionName, files) {
78
106
  const items = files.map(async (file, i) => {
79
107
  const importId = `${collectionName}_${i}`;
108
+ const params = [`collection=${collectionName}`];
109
+ if (configHash) {
110
+ params.push(`hash=${configHash}`);
111
+ }
80
112
  lines.unshift(
81
113
  getImportCode({
82
114
  type: "namespace",
83
115
  name: importId,
84
- specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${collectionName}&hash=${configHash}`
116
+ specifier: `${toImportPath(file.fullPath, importPath)}?${params.join("&")}`
85
117
  })
86
118
  );
87
119
  return `{ info: ${JSON.stringify(file)}, data: ${importId} }`;
@@ -90,17 +122,17 @@ async function generateJS(configPath, config, outputPath, configHash) {
90
122
  }
91
123
  async function getMetaEntries(collection, files) {
92
124
  const items = files.map(async (file) => {
93
- const source = await readFileWithCache(file.absolutePath).catch(() => "");
94
- let data = source.length === 0 ? {} : JSON.parse(source);
125
+ const source = await readFileWithCache(file.fullPath).catch(() => "");
126
+ let data = source.length === 0 ? {} : parseMetaEntry(file.fullPath, source);
95
127
  if (collection?.schema) {
96
128
  data = await validate(
97
129
  collection.schema,
98
130
  data,
99
131
  {
100
132
  source,
101
- path: file.absolutePath
133
+ path: file.fullPath
102
134
  },
103
- `invalid data in ${file.absolutePath}`
135
+ `invalid data in ${file.fullPath}`
104
136
  );
105
137
  }
106
138
  return JSON.stringify({
@@ -118,28 +150,40 @@ async function generateJS(configPath, config, outputPath, configHash) {
118
150
  specifier: "fumadocs-mdx/runtime/async",
119
151
  names: ["_runtimeAsync", "buildConfig"]
120
152
  }),
121
- "const [err, _sourceConfig] = buildConfig(_source)",
122
- "if (!_sourceConfig) throw new Error(err)"
153
+ "const _sourceConfig = buildConfig(_source)",
154
+ getImportCode({
155
+ type: "default",
156
+ name: "path",
157
+ specifier: "node:path"
158
+ })
123
159
  );
124
160
  asyncInit = true;
125
161
  }
126
162
  const entries2 = files.map(async (file) => {
127
- const parsed = matter(
128
- await readFileWithCache(file.absolutePath).catch(() => "")
129
- );
163
+ const content = await readFileWithCache(file.fullPath).catch(() => "");
164
+ const parsed = fumaMatter(content);
165
+ let data = parsed.data;
130
166
  if (collection.schema) {
131
- parsed.data = await validate(
167
+ data = await validate(
132
168
  collection.schema,
133
169
  parsed.data,
134
- { path: file.absolutePath, source: parsed.content },
135
- `invalid frontmatter in ${file.absolutePath}`
170
+ { path: file.fullPath, source: parsed.content },
171
+ `invalid frontmatter in ${file.fullPath}`
136
172
  );
137
173
  }
138
- return JSON.stringify({
139
- info: file,
140
- data: parsed.data,
141
- content: parsed.content
142
- });
174
+ let lastModified;
175
+ if (config.global?.lastModifiedTime === "git") {
176
+ lastModified = await getGitTimestamp(file.fullPath);
177
+ }
178
+ const hash = createHash("md5").update(content).digest("hex");
179
+ const infoStr = [];
180
+ for (const [k, v] of Object.entries({ ...file, hash })) {
181
+ infoStr.push(`${k}: ${JSON.stringify(v)}`);
182
+ }
183
+ infoStr.push(
184
+ `absolutePath: path.resolve(${JSON.stringify(file.fullPath)})`
185
+ );
186
+ return `{ info: { ${infoStr.join(", ")} }, lastModified: ${JSON.stringify(lastModified)}, data: ${JSON.stringify(data)} }`;
143
187
  });
144
188
  return Promise.all(entries2);
145
189
  }
@@ -172,148 +216,60 @@ async function generateJS(configPath, config, outputPath, configHash) {
172
216
  ...resolvedDeclares
173
217
  ].join("\n");
174
218
  }
175
- async function getCollectionFiles(collection) {
176
- const files = /* @__PURE__ */ new Map();
177
- const dirs = Array.isArray(collection.dir) ? collection.dir : [collection.dir];
178
- await Promise.all(
179
- dirs.map(async (dir) => {
180
- const result = await fg(collection.files ?? "**/*", {
181
- cwd: path.resolve(dir),
182
- absolute: true
183
- });
184
- for (const item of result) {
185
- if (getTypeFromPath(item) !== collection.type) continue;
186
- files.set(item, {
187
- path: path.relative(dir, item),
188
- absolutePath: item
189
- });
190
- }
191
- })
192
- );
193
- return Array.from(files.values());
194
- }
195
- function getImportCode(info) {
196
- const specifier = JSON.stringify(info.specifier);
197
- if (info.type === "default") return `import ${info.name} from ${specifier}`;
198
- if (info.type === "namespace")
199
- return `import * as ${info.name} from ${specifier}`;
200
- if (info.type === "named") {
201
- const names = info.names.map(
202
- (name) => Array.isArray(name) ? `${name[0]} as ${name[1]}` : name
203
- );
204
- return `import { ${names.join(", ")} } from ${specifier}`;
205
- }
206
- return `import ${specifier}`;
207
- }
208
- function toImportPath(file, dir) {
209
- const ext = path.extname(file);
210
- let importPath = path.relative(
211
- dir,
212
- ext === ".ts" ? file.substring(0, file.length - ext.length) : file
213
- );
214
- if (!path.isAbsolute(importPath) && !importPath.startsWith(".")) {
215
- importPath = `./${importPath}`;
216
- }
217
- return importPath.replaceAll(path.sep, "/");
218
- }
219
-
220
- // src/map/index.ts
221
- async function start(dev, configPath, outDir2) {
222
- void fs2.rm(path2.resolve(outDir2, `index.js`), { force: true });
223
- void fs2.rm(path2.resolve(outDir2, `index.d.ts`), { force: true });
224
- await fs2.mkdir(outDir2, { recursive: true });
225
- let configHash = await getConfigHash(configPath);
226
- let config = await loadConfig(configPath, configHash, true);
227
- const outPath = path2.resolve(outDir2, `index.ts`);
228
- async function updateMapFile() {
229
- console.time(`[MDX] update map file`);
230
- try {
231
- await fs2.writeFile(
232
- outPath,
233
- await generateJS(configPath, config, outPath, configHash)
234
- );
235
- } catch (err) {
236
- if (err instanceof ValidationError) {
237
- err.print();
238
- } else {
239
- console.error(err);
240
- }
241
- }
242
- console.timeEnd(`[MDX] update map file`);
243
- }
244
- await updateMapFile();
245
- if (dev) {
246
- const { watcher } = await import("../watcher-IAZDSTU7.js");
247
- const instance = watcher(configPath, config);
248
- instance.on("ready", () => {
249
- console.log("[MDX] started dev server");
250
- });
251
- instance.on("all", (event, file) => {
252
- if (typeof file !== "string") return;
253
- const absolutePath = path2.resolve(file);
254
- const onUpdate = async () => {
255
- const isConfigFile = absolutePath === configPath;
256
- if (isConfigFile) {
257
- configHash = await getConfigHash(configPath);
258
- config = await loadConfig(configPath, configHash, true);
259
- }
260
- if (event === "change") fileCache.removeCache(absolutePath);
261
- await updateMapFile();
262
- };
263
- void onUpdate();
264
- });
265
- process.on("exit", () => {
266
- console.log("[MDX] closing dev server");
267
- void instance.close();
219
+ function parseMetaEntry(file, content) {
220
+ const extname2 = path2.extname(file);
221
+ try {
222
+ if (extname2 === ".json") return JSON.parse(content);
223
+ if (extname2 === ".yaml") return load(content);
224
+ } catch (e) {
225
+ throw new Error(`Failed to parse meta file: ${file}.`, {
226
+ cause: e
268
227
  });
269
228
  }
229
+ throw new Error(`Unknown meta file format: ${extname2}, in ${file}.`);
270
230
  }
271
231
 
272
- // src/next/create.ts
273
- var outDir = path3.resolve(".source");
232
+ // src/next/index.ts
274
233
  var defaultPageExtensions = ["mdx", "md", "jsx", "js", "tsx", "ts"];
275
- function createMDX({
276
- configPath = findConfigFile()
277
- } = {}) {
278
- const isDev = process.argv.includes("dev");
279
- const isBuild = process.argv.includes("build");
280
- if ((isDev || isBuild) && process.env._FUMADOCS_MDX !== "1") {
234
+ function createMDX(createOptions = {}) {
235
+ const options = applyDefaults(createOptions);
236
+ const isDev = process.env.NODE_ENV === "development";
237
+ if (process.env._FUMADOCS_MDX !== "1") {
281
238
  process.env._FUMADOCS_MDX = "1";
282
- void start(isDev, configPath, outDir);
239
+ void init(isDev, options);
283
240
  }
284
241
  return (nextConfig = {}) => {
285
242
  const mdxLoaderOptions = {
286
- _ctx: {
287
- configPath
243
+ ...options,
244
+ isDev
245
+ };
246
+ const turbopack = {
247
+ ...nextConfig.turbopack,
248
+ rules: {
249
+ ...nextConfig.turbopack?.rules,
250
+ "*.{md,mdx}": {
251
+ loaders: [
252
+ {
253
+ loader: "fumadocs-mdx/loader-mdx",
254
+ options: mdxLoaderOptions
255
+ }
256
+ ],
257
+ as: "*.js"
258
+ }
288
259
  }
289
260
  };
290
261
  return {
291
262
  ...nextConfig,
292
- turbopack: {
293
- ...nextConfig?.turbopack,
294
- rules: {
295
- ...nextConfig?.turbopack?.rules,
296
- // @ts-expect-error -- safe
297
- "*.{md,mdx}": {
298
- loaders: [
299
- {
300
- loader: "fumadocs-mdx/loader-mdx",
301
- options: mdxLoaderOptions
302
- }
303
- ],
304
- as: "*.js"
305
- }
306
- }
307
- },
263
+ turbopack,
308
264
  pageExtensions: nextConfig.pageExtensions ?? defaultPageExtensions,
309
- webpack: (config, options) => {
265
+ webpack: (config, options2) => {
310
266
  config.resolve ||= {};
311
267
  config.module ||= {};
312
268
  config.module.rules ||= [];
313
269
  config.module.rules.push({
314
270
  test: /\.mdx?$/,
315
271
  use: [
316
- options.defaultLoaders.babel,
272
+ options2.defaultLoaders.babel,
317
273
  {
318
274
  loader: "fumadocs-mdx/loader-mdx",
319
275
  options: mdxLoaderOptions
@@ -321,33 +277,104 @@ function createMDX({
321
277
  ]
322
278
  });
323
279
  config.plugins ||= [];
324
- return nextConfig.webpack?.(config, options) ?? config;
280
+ return nextConfig.webpack?.(config, options2) ?? config;
325
281
  }
326
282
  };
327
283
  };
328
284
  }
329
-
330
- // src/postinstall.ts
331
- import * as path4 from "node:path";
332
- import * as fs3 from "node:fs";
333
- async function postInstall(configPath = findConfigFile()) {
334
- const jsOut = path4.resolve(".source/index.ts");
335
- const hash = await getConfigHash(configPath);
336
- const config = await loadConfig(configPath, hash, true);
337
- fs3.mkdirSync(path4.dirname(jsOut), { recursive: true });
338
- fs3.writeFileSync(
339
- jsOut,
340
- await generateJS(
341
- configPath,
342
- config,
343
- path4.resolve(".source/index.ts"),
344
- hash
345
- )
285
+ async function init(dev, options) {
286
+ const core = createNextCore(options);
287
+ async function initOrReload() {
288
+ await core.init({
289
+ config: loadConfig(options.configPath, options.outDir, true)
290
+ });
291
+ await core.emitAndWrite();
292
+ }
293
+ async function devServer() {
294
+ const { FSWatcher } = await import("chokidar");
295
+ const watcher = new FSWatcher({
296
+ ignoreInitial: true,
297
+ persistent: true,
298
+ ignored: [options.outDir]
299
+ });
300
+ watcher.add(options.configPath);
301
+ for (const collection of core.getConfig().collections.values()) {
302
+ if (collection.type === "docs") {
303
+ watcher.add(collection.docs.dir);
304
+ watcher.add(collection.meta.dir);
305
+ } else {
306
+ watcher.add(collection.dir);
307
+ }
308
+ }
309
+ watcher.on("ready", () => {
310
+ console.log("[MDX] started dev server");
311
+ });
312
+ watcher.on("all", async (event, file) => {
313
+ const absolutePath = path3.resolve(file);
314
+ if (event === "change") removeFileCache(absolutePath);
315
+ if (absolutePath === path3.resolve(options.configPath)) {
316
+ watcher.removeAllListeners();
317
+ await watcher.close();
318
+ await initOrReload();
319
+ console.log("[MDX] restarting dev server");
320
+ await devServer();
321
+ }
322
+ });
323
+ process.on("exit", () => {
324
+ if (watcher.closed) return;
325
+ console.log("[MDX] closing dev server");
326
+ void watcher.close();
327
+ });
328
+ await core.initServer({ watcher });
329
+ }
330
+ await initOrReload();
331
+ if (dev) {
332
+ await devServer();
333
+ }
334
+ }
335
+ async function postInstall(configPath = findConfigFile(), outDir = ".source") {
336
+ const core = await createNextCore({
337
+ outDir,
338
+ configPath
339
+ }).init({
340
+ config: loadConfig(configPath, outDir, true)
341
+ });
342
+ await core.emitAndWrite();
343
+ }
344
+ function applyDefaults(options) {
345
+ return {
346
+ outDir: options.outDir ?? ".source",
347
+ configPath: options.configPath ?? findConfigFile()
348
+ };
349
+ }
350
+ function createNextCore({
351
+ outDir,
352
+ configPath
353
+ }) {
354
+ const core = createCore(
355
+ {
356
+ environment: "next",
357
+ outDir,
358
+ configPath
359
+ },
360
+ [next()]
346
361
  );
347
- console.log("[MDX] types generated");
362
+ return {
363
+ ...core,
364
+ async emitAndWrite(...args) {
365
+ try {
366
+ await core.emitAndWrite(...args);
367
+ } catch (err) {
368
+ if (err instanceof ValidationError) {
369
+ console.error(err.toStringFormatted());
370
+ } else {
371
+ console.error(err);
372
+ }
373
+ }
374
+ }
375
+ };
348
376
  }
349
377
  export {
350
378
  createMDX,
351
- postInstall,
352
- start
379
+ postInstall
353
380
  };