@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.
- package/LICENSE +21 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +16 -0
- package/dist/build-mdx-LN7FEKIP.js +8 -0
- package/dist/build-mdx-RXJZQXGA.js +8 -0
- package/dist/bun/index.d.ts +25 -0
- package/dist/bun/index.js +52 -0
- package/dist/chunk-4JSFLXXT.js +8 -0
- package/dist/chunk-5OBUOALK.js +141 -0
- package/dist/chunk-72JS4QVZ.js +17 -0
- package/dist/chunk-7I4W7XGI.js +179 -0
- package/dist/chunk-7W73RILB.js +173 -0
- package/dist/chunk-A3YIGE7S.js +334 -0
- package/dist/chunk-AOTZP2TV.js +152 -0
- package/dist/chunk-AXJB5MGS.js +173 -0
- package/dist/chunk-DMIIE3XZ.js +179 -0
- package/dist/chunk-DTFUANSF.js +40 -0
- package/dist/chunk-JWZR25CW.js +116 -0
- package/dist/chunk-K7N6GD4M.js +17 -0
- package/dist/chunk-LXB7WYAF.js +334 -0
- package/dist/chunk-MYAVS2LD.js +116 -0
- package/dist/chunk-OLD35ARB.js +116 -0
- package/dist/chunk-PW2AZGGD.js +125 -0
- package/dist/chunk-RGBNABKS.js +334 -0
- package/dist/chunk-RPUM7REY.js +40 -0
- package/dist/chunk-RR2X6AE6.js +274 -0
- package/dist/chunk-S7KOJHHO.js +89 -0
- package/dist/chunk-STUCUTJQ.js +334 -0
- package/dist/chunk-T6G5VOED.js +116 -0
- package/dist/chunk-U5YPLCO5.js +89 -0
- package/dist/chunk-UB55AMXC.js +274 -0
- package/dist/chunk-VITVHHR6.js +334 -0
- package/dist/chunk-VKSHE52K.js +274 -0
- package/dist/chunk-VWJKRQZR.js +19 -0
- package/dist/chunk-WAAWFNDX.js +179 -0
- package/dist/chunk-WGXYJGSZ.js +141 -0
- package/dist/chunk-WLJ6EKOZ.js +17 -0
- package/dist/chunk-WMYYALAS.js +334 -0
- package/dist/chunk-Y7ISNZ7X.js +216 -0
- package/dist/chunk-YKRCQ42E.js +216 -0
- package/dist/chunk-ZAYZWFWP.js +89 -0
- package/dist/config/index.d.ts +18 -0
- package/dist/config/index.js +63 -0
- package/dist/core-BQcKaqmC.d.ts +350 -0
- package/dist/core-BhWOtait.d.ts +350 -0
- package/dist/core-CV8uFMUa.d.ts +350 -0
- package/dist/core-DAQ64Hkq.d.ts +350 -0
- package/dist/core-DZtRjhds.d.ts +350 -0
- package/dist/core-De5K4ixv.d.ts +350 -0
- package/dist/core-X5ggQtBM.d.ts +350 -0
- package/dist/index-BqkSNsGO.d.ts +8 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +0 -0
- package/dist/load-from-file-FHW724YY.js +8 -0
- package/dist/load-from-file-S5CQ4H6T.js +8 -0
- package/dist/next/index.cjs +1165 -0
- package/dist/next/index.d.ts +33 -0
- package/dist/next/index.js +181 -0
- package/dist/node/loader.d.ts +5 -0
- package/dist/node/loader.js +41 -0
- package/dist/plugins/index-file.d.ts +14 -0
- package/dist/plugins/index-file.js +8 -0
- package/dist/plugins/json-schema.d.ts +31 -0
- package/dist/plugins/json-schema.js +80 -0
- package/dist/plugins/last-modified.d.ts +40 -0
- package/dist/plugins/last-modified.js +89 -0
- package/dist/runtime/browser.d.ts +53 -0
- package/dist/runtime/browser.js +67 -0
- package/dist/runtime/dynamic.d.ts +27 -0
- package/dist/runtime/dynamic.js +79 -0
- package/dist/runtime/server.d.ts +14 -0
- package/dist/runtime/server.js +8 -0
- package/dist/runtime/types.d.ts +61 -0
- package/dist/runtime/types.js +0 -0
- package/dist/vite/index.d.ts +44 -0
- package/dist/vite/index.js +122 -0
- package/dist/webpack/mdx.d.ts +6 -0
- package/dist/webpack/mdx.js +37 -0
- package/dist/webpack/meta.d.ts +6 -0
- package/dist/webpack/meta.js +40 -0
- package/loader-mdx.cjs +7 -0
- package/loader-meta.cjs +7 -0
- package/package.json +137 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ident
|
|
3
|
+
} from "./chunk-PW2AZGGD.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/validation.ts
|
|
6
|
+
var ValidationError = class extends Error {
|
|
7
|
+
constructor(message, issues) {
|
|
8
|
+
super(
|
|
9
|
+
`${message}:
|
|
10
|
+
${issues.map((issue) => ` ${issue.path}: ${issue.message}`).join("\n")}`
|
|
11
|
+
);
|
|
12
|
+
this.title = message;
|
|
13
|
+
this.issues = issues;
|
|
14
|
+
}
|
|
15
|
+
async toStringFormatted() {
|
|
16
|
+
const picocolorsModule = await import("picocolors");
|
|
17
|
+
const picocolors = picocolorsModule.default ?? picocolorsModule;
|
|
18
|
+
return [
|
|
19
|
+
picocolors.bold(`[MDX] ${this.title}:`),
|
|
20
|
+
...this.issues.map(
|
|
21
|
+
(issue) => picocolors.redBright(
|
|
22
|
+
`- ${picocolors.bold(issue.path?.join(".") ?? "*")}: ${issue.message}`
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
].join("\n");
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
async function validate(schema, data, context, errorMessage) {
|
|
29
|
+
if (typeof schema === "function" && !("~standard" in schema)) {
|
|
30
|
+
schema = schema(context);
|
|
31
|
+
}
|
|
32
|
+
if ("~standard" in schema) {
|
|
33
|
+
const result = await schema["~standard"].validate(
|
|
34
|
+
data
|
|
35
|
+
);
|
|
36
|
+
if (result.issues) {
|
|
37
|
+
throw new ValidationError(errorMessage, result.issues);
|
|
38
|
+
}
|
|
39
|
+
return result.value;
|
|
40
|
+
}
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/core.ts
|
|
45
|
+
import path from "path";
|
|
46
|
+
import fs from "fs/promises";
|
|
47
|
+
var _Defaults = {
|
|
48
|
+
configPath: "source.config.ts",
|
|
49
|
+
outDir: ".source"
|
|
50
|
+
};
|
|
51
|
+
async function getPlugins(pluginOptions) {
|
|
52
|
+
const plugins = [];
|
|
53
|
+
for await (const option of pluginOptions) {
|
|
54
|
+
if (!option) continue;
|
|
55
|
+
if (Array.isArray(option)) plugins.push(...await getPlugins(option));
|
|
56
|
+
else plugins.push(option);
|
|
57
|
+
}
|
|
58
|
+
return plugins;
|
|
59
|
+
}
|
|
60
|
+
function createCore(options) {
|
|
61
|
+
let config;
|
|
62
|
+
let plugins;
|
|
63
|
+
const workspaces = /* @__PURE__ */ new Map();
|
|
64
|
+
async function transformMetadata({
|
|
65
|
+
collection,
|
|
66
|
+
filePath,
|
|
67
|
+
source
|
|
68
|
+
}, data) {
|
|
69
|
+
if (collection.schema) {
|
|
70
|
+
data = await validate(
|
|
71
|
+
collection.schema,
|
|
72
|
+
data,
|
|
73
|
+
{ path: filePath, source },
|
|
74
|
+
collection.type === "doc" ? `invalid frontmatter in ${filePath}` : `invalid data in ${filePath}`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
/**
|
|
81
|
+
* Convenient cache store, reset when config changes
|
|
82
|
+
*/
|
|
83
|
+
cache: /* @__PURE__ */ new Map(),
|
|
84
|
+
async init({ config: newConfig }) {
|
|
85
|
+
config = await newConfig;
|
|
86
|
+
this.cache.clear();
|
|
87
|
+
workspaces.clear();
|
|
88
|
+
plugins = await getPlugins([
|
|
89
|
+
postprocessPlugin(),
|
|
90
|
+
options.plugins,
|
|
91
|
+
config.global.plugins
|
|
92
|
+
]);
|
|
93
|
+
for (const plugin of plugins) {
|
|
94
|
+
const out = await plugin.config?.call(this.getPluginContext(), config);
|
|
95
|
+
if (out) config = out;
|
|
96
|
+
}
|
|
97
|
+
if (!options.workspace) {
|
|
98
|
+
await Promise.all(
|
|
99
|
+
Object.entries(config.workspaces).map(async ([name, workspace]) => {
|
|
100
|
+
const core = createCore({
|
|
101
|
+
...options,
|
|
102
|
+
outDir: path.join(options.outDir, name),
|
|
103
|
+
workspace: {
|
|
104
|
+
name,
|
|
105
|
+
parent: this,
|
|
106
|
+
dir: workspace.dir
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
await core.init({ config: workspace.config });
|
|
110
|
+
workspaces.set(name, core);
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
getWorkspaces() {
|
|
116
|
+
return workspaces;
|
|
117
|
+
},
|
|
118
|
+
getOptions() {
|
|
119
|
+
return options;
|
|
120
|
+
},
|
|
121
|
+
getConfig() {
|
|
122
|
+
return config;
|
|
123
|
+
},
|
|
124
|
+
/**
|
|
125
|
+
* The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
|
|
126
|
+
*/
|
|
127
|
+
getCompiledConfigPath() {
|
|
128
|
+
return path.join(options.outDir, "source.config.mjs");
|
|
129
|
+
},
|
|
130
|
+
getPlugins() {
|
|
131
|
+
return plugins;
|
|
132
|
+
},
|
|
133
|
+
getCollections() {
|
|
134
|
+
return Array.from(config.collections.values());
|
|
135
|
+
},
|
|
136
|
+
getCollection(name) {
|
|
137
|
+
return config.collections.get(name);
|
|
138
|
+
},
|
|
139
|
+
getPluginContext() {
|
|
140
|
+
return {
|
|
141
|
+
core: this
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
async initServer(server) {
|
|
145
|
+
const ctx = this.getPluginContext();
|
|
146
|
+
for (const plugin of plugins) {
|
|
147
|
+
await plugin.configureServer?.call(ctx, server);
|
|
148
|
+
}
|
|
149
|
+
for (const workspace of workspaces.values()) {
|
|
150
|
+
await workspace.initServer(server);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
async emit(emitOptions = {}) {
|
|
154
|
+
const { filterPlugin, filterWorkspace, write = false } = emitOptions;
|
|
155
|
+
const start = performance.now();
|
|
156
|
+
const ctx = this.getPluginContext();
|
|
157
|
+
const added = /* @__PURE__ */ new Set();
|
|
158
|
+
const out = {
|
|
159
|
+
entries: [],
|
|
160
|
+
workspaces: {}
|
|
161
|
+
};
|
|
162
|
+
for (const li of await Promise.all(
|
|
163
|
+
plugins.map((plugin) => {
|
|
164
|
+
if (filterPlugin && !filterPlugin(plugin) || !plugin.emit) return;
|
|
165
|
+
return plugin.emit.call(ctx);
|
|
166
|
+
})
|
|
167
|
+
)) {
|
|
168
|
+
if (!li) continue;
|
|
169
|
+
for (const item of li) {
|
|
170
|
+
if (added.has(item.path)) continue;
|
|
171
|
+
out.entries.push(item);
|
|
172
|
+
added.add(item.path);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (write) {
|
|
176
|
+
await Promise.all(
|
|
177
|
+
out.entries.map(async (entry) => {
|
|
178
|
+
const file = path.join(options.outDir, entry.path);
|
|
179
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
180
|
+
await fs.writeFile(file, entry.content);
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
console.log(
|
|
184
|
+
options.workspace ? `[MDX: ${options.workspace.name}] generated files in ${performance.now() - start}ms` : `[MDX] generated files in ${performance.now() - start}ms`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
for (const [name, workspace] of workspaces) {
|
|
188
|
+
if (filterWorkspace && !filterWorkspace(name)) continue;
|
|
189
|
+
out.workspaces[name] = (await workspace.emit(emitOptions)).entries;
|
|
190
|
+
}
|
|
191
|
+
return out;
|
|
192
|
+
},
|
|
193
|
+
async transformMeta(options2, data) {
|
|
194
|
+
const ctx = {
|
|
195
|
+
...this.getPluginContext(),
|
|
196
|
+
...options2
|
|
197
|
+
};
|
|
198
|
+
data = await transformMetadata(options2, data);
|
|
199
|
+
for (const plugin of plugins) {
|
|
200
|
+
if (plugin.meta?.transform)
|
|
201
|
+
data = await plugin.meta.transform.call(ctx, data) ?? data;
|
|
202
|
+
}
|
|
203
|
+
return data;
|
|
204
|
+
},
|
|
205
|
+
async transformFrontmatter(options2, data) {
|
|
206
|
+
const ctx = {
|
|
207
|
+
...this.getPluginContext(),
|
|
208
|
+
...options2
|
|
209
|
+
};
|
|
210
|
+
data = await transformMetadata(options2, data);
|
|
211
|
+
for (const plugin of plugins) {
|
|
212
|
+
if (plugin.doc?.frontmatter)
|
|
213
|
+
data = await plugin.doc.frontmatter.call(ctx, data) ?? data;
|
|
214
|
+
}
|
|
215
|
+
return data;
|
|
216
|
+
},
|
|
217
|
+
async transformVFile(options2, file) {
|
|
218
|
+
const ctx = {
|
|
219
|
+
...this.getPluginContext(),
|
|
220
|
+
...options2
|
|
221
|
+
};
|
|
222
|
+
for (const plugin of plugins) {
|
|
223
|
+
if (plugin.doc?.vfile)
|
|
224
|
+
file = await plugin.doc.vfile.call(ctx, file) ?? file;
|
|
225
|
+
}
|
|
226
|
+
return file;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function postprocessPlugin() {
|
|
231
|
+
const LinkReferenceTypes = `{
|
|
232
|
+
/**
|
|
233
|
+
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
|
|
234
|
+
*/
|
|
235
|
+
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
|
|
236
|
+
}`;
|
|
237
|
+
return {
|
|
238
|
+
"index-file": {
|
|
239
|
+
generateTypeConfig() {
|
|
240
|
+
const lines = [];
|
|
241
|
+
lines.push("{");
|
|
242
|
+
lines.push(" DocData: {");
|
|
243
|
+
for (const collection of this.core.getCollections()) {
|
|
244
|
+
let postprocessOptions;
|
|
245
|
+
switch (collection.type) {
|
|
246
|
+
case "doc":
|
|
247
|
+
postprocessOptions = collection.postprocess;
|
|
248
|
+
break;
|
|
249
|
+
case "docs":
|
|
250
|
+
postprocessOptions = collection.docs.postprocess;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
if (postprocessOptions?.extractLinkReferences) {
|
|
254
|
+
lines.push(ident(`${collection.name}: ${LinkReferenceTypes},`, 2));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
lines.push(" }");
|
|
258
|
+
lines.push("}");
|
|
259
|
+
return lines.join("\n");
|
|
260
|
+
},
|
|
261
|
+
serverOptions(options) {
|
|
262
|
+
options.doc ??= {};
|
|
263
|
+
options.doc.passthroughs ??= [];
|
|
264
|
+
options.doc.passthroughs.push("extractedReferences");
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export {
|
|
271
|
+
ValidationError,
|
|
272
|
+
_Defaults,
|
|
273
|
+
createCore
|
|
274
|
+
};
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createCodegen,
|
|
3
|
+
ident
|
|
4
|
+
} from "./chunk-PW2AZGGD.js";
|
|
5
|
+
import {
|
|
6
|
+
fumaMatter
|
|
7
|
+
} from "./chunk-VWJKRQZR.js";
|
|
8
|
+
|
|
9
|
+
// src/plugins/index-file.ts
|
|
10
|
+
import path2 from "path";
|
|
11
|
+
import { glob } from "tinyglobby";
|
|
12
|
+
|
|
13
|
+
// src/utils/fs-cache.ts
|
|
14
|
+
import fs from "fs/promises";
|
|
15
|
+
import path from "path";
|
|
16
|
+
var map = /* @__PURE__ */ new Map();
|
|
17
|
+
function createFSCache() {
|
|
18
|
+
return {
|
|
19
|
+
read(file) {
|
|
20
|
+
const fullPath = toFullPath(file);
|
|
21
|
+
const cached = map.get(fullPath);
|
|
22
|
+
if (cached) return cached;
|
|
23
|
+
const read = fs.readFile(fullPath).then((s) => s.toString());
|
|
24
|
+
map.set(fullPath, read);
|
|
25
|
+
return read;
|
|
26
|
+
},
|
|
27
|
+
delete(file) {
|
|
28
|
+
map.delete(toFullPath(file));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function toFullPath(file) {
|
|
33
|
+
if (path.isAbsolute(file)) {
|
|
34
|
+
return path.relative(process.cwd(), file);
|
|
35
|
+
}
|
|
36
|
+
return file;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/plugins/index-file.ts
|
|
40
|
+
import { createHash } from "crypto";
|
|
41
|
+
var indexFileCache = createFSCache();
|
|
42
|
+
function indexFile(options = {}) {
|
|
43
|
+
const {
|
|
44
|
+
target = "default",
|
|
45
|
+
addJsExtension,
|
|
46
|
+
browser = true,
|
|
47
|
+
dynamic = true
|
|
48
|
+
} = options;
|
|
49
|
+
let dynamicCollections;
|
|
50
|
+
function isDynamic(collection) {
|
|
51
|
+
return collection.type === "docs" && collection.docs.dynamic || collection.type === "doc" && collection.dynamic;
|
|
52
|
+
}
|
|
53
|
+
function generateConfigs(core) {
|
|
54
|
+
const serverOptions = {};
|
|
55
|
+
const typeConfigs = [
|
|
56
|
+
'import("fumadocs-mdx/runtime/types").InternalTypeConfig'
|
|
57
|
+
];
|
|
58
|
+
const ctx = core.getPluginContext();
|
|
59
|
+
for (const plugin of core.getPlugins()) {
|
|
60
|
+
const indexFilePlugin = plugin["index-file"];
|
|
61
|
+
if (!indexFilePlugin) continue;
|
|
62
|
+
indexFilePlugin.serverOptions?.call(ctx, serverOptions);
|
|
63
|
+
const config = indexFilePlugin.generateTypeConfig?.call(ctx);
|
|
64
|
+
if (config) typeConfigs.push(config);
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
serverOptions,
|
|
68
|
+
tc: typeConfigs.join(" & ")
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
name: "index-file",
|
|
73
|
+
config() {
|
|
74
|
+
dynamicCollections = this.core.getCollections().filter(isDynamic);
|
|
75
|
+
},
|
|
76
|
+
configureServer(server) {
|
|
77
|
+
if (!server.watcher) return;
|
|
78
|
+
server.watcher.on("all", async (event, file) => {
|
|
79
|
+
indexFileCache.delete(file);
|
|
80
|
+
if (dynamicCollections.length === 0) {
|
|
81
|
+
if (target === "vite") return;
|
|
82
|
+
if (target === "default" && event === "change") return;
|
|
83
|
+
}
|
|
84
|
+
const updatedCollection = this.core.getCollections().find((collection) => collection.hasFile(file));
|
|
85
|
+
if (!updatedCollection) return;
|
|
86
|
+
if (!isDynamic(updatedCollection)) {
|
|
87
|
+
if (target === "vite") return;
|
|
88
|
+
if (target === "default" && event === "change") return;
|
|
89
|
+
}
|
|
90
|
+
await this.core.emit({
|
|
91
|
+
filterPlugin: (plugin) => plugin.name === "index-file",
|
|
92
|
+
filterWorkspace: () => false,
|
|
93
|
+
write: true
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
async emit() {
|
|
98
|
+
const globCache = /* @__PURE__ */ new Map();
|
|
99
|
+
const { workspace, outDir } = this.core.getOptions();
|
|
100
|
+
const { serverOptions, tc } = generateConfigs(this.core);
|
|
101
|
+
const toEmitEntry = async (path3, content) => {
|
|
102
|
+
const codegen = createCodegen({
|
|
103
|
+
target,
|
|
104
|
+
outDir,
|
|
105
|
+
jsExtension: addJsExtension,
|
|
106
|
+
globCache
|
|
107
|
+
});
|
|
108
|
+
await content({
|
|
109
|
+
core: this.core,
|
|
110
|
+
codegen,
|
|
111
|
+
serverOptions,
|
|
112
|
+
tc,
|
|
113
|
+
workspace: workspace?.name
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
path: path3,
|
|
117
|
+
content: codegen.toString()
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
const out = [
|
|
121
|
+
toEmitEntry("server.ts", generateServerIndexFile)
|
|
122
|
+
];
|
|
123
|
+
if (dynamic)
|
|
124
|
+
out.push(toEmitEntry("dynamic.ts", generateDynamicIndexFile));
|
|
125
|
+
if (browser)
|
|
126
|
+
out.push(toEmitEntry("browser.ts", generateBrowserIndexFile));
|
|
127
|
+
return await Promise.all(out);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async function generateServerIndexFile(ctx) {
|
|
132
|
+
const { core, codegen, serverOptions, tc } = ctx;
|
|
133
|
+
codegen.lines.push(
|
|
134
|
+
`import { server } from 'fumadocs-mdx/runtime/server';`,
|
|
135
|
+
`import type * as Config from '${codegen.formatImportPath(core.getOptions().configPath)}';`,
|
|
136
|
+
"",
|
|
137
|
+
`const create = server<typeof Config, ${tc}>(${JSON.stringify(serverOptions)});`
|
|
138
|
+
);
|
|
139
|
+
async function generateCollectionObject(collection) {
|
|
140
|
+
const base = getBase(collection);
|
|
141
|
+
switch (collection.type) {
|
|
142
|
+
case "docs": {
|
|
143
|
+
if (collection.docs.dynamic) return;
|
|
144
|
+
if (collection.docs.async) {
|
|
145
|
+
const [metaGlob2, headGlob, bodyGlob] = await Promise.all([
|
|
146
|
+
generateMetaCollectionGlob(ctx, collection.meta, true),
|
|
147
|
+
generateDocCollectionFrontmatterGlob(ctx, collection.docs, true),
|
|
148
|
+
generateDocCollectionGlob(ctx, collection.docs)
|
|
149
|
+
]);
|
|
150
|
+
return `await create.docsLazy("${collection.name}", "${base}", ${metaGlob2}, ${headGlob}, ${bodyGlob})`;
|
|
151
|
+
}
|
|
152
|
+
const [metaGlob, docGlob] = await Promise.all([
|
|
153
|
+
generateMetaCollectionGlob(ctx, collection.meta, true),
|
|
154
|
+
generateDocCollectionGlob(ctx, collection.docs, true)
|
|
155
|
+
]);
|
|
156
|
+
return `await create.docs("${collection.name}", "${base}", ${metaGlob}, ${docGlob})`;
|
|
157
|
+
}
|
|
158
|
+
case "doc":
|
|
159
|
+
if (collection.dynamic) return;
|
|
160
|
+
if (collection.async) {
|
|
161
|
+
const [headGlob, bodyGlob] = await Promise.all([
|
|
162
|
+
generateDocCollectionFrontmatterGlob(ctx, collection, true),
|
|
163
|
+
generateDocCollectionGlob(ctx, collection)
|
|
164
|
+
]);
|
|
165
|
+
return `await create.docLazy("${collection.name}", "${base}", ${headGlob}, ${bodyGlob})`;
|
|
166
|
+
}
|
|
167
|
+
return `await create.doc("${collection.name}", "${base}", ${await generateDocCollectionGlob(
|
|
168
|
+
ctx,
|
|
169
|
+
collection,
|
|
170
|
+
true
|
|
171
|
+
)})`;
|
|
172
|
+
case "meta":
|
|
173
|
+
return `await create.meta("${collection.name}", "${base}", ${await generateMetaCollectionGlob(
|
|
174
|
+
ctx,
|
|
175
|
+
collection,
|
|
176
|
+
true
|
|
177
|
+
)})`;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
await codegen.pushAsync(
|
|
181
|
+
core.getCollections().map(async (collection) => {
|
|
182
|
+
const obj = await generateCollectionObject(collection);
|
|
183
|
+
if (!obj) return;
|
|
184
|
+
return `
|
|
185
|
+
export const ${collection.name} = ${obj};`;
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
async function generateDynamicIndexFile(ctx) {
|
|
190
|
+
const { core, codegen, serverOptions, tc } = ctx;
|
|
191
|
+
const { configPath, environment, outDir } = core.getOptions();
|
|
192
|
+
const partialOptions = {
|
|
193
|
+
configPath,
|
|
194
|
+
environment,
|
|
195
|
+
outDir
|
|
196
|
+
};
|
|
197
|
+
codegen.lines.push(
|
|
198
|
+
`import { dynamic } from 'fumadocs-mdx/runtime/dynamic';`,
|
|
199
|
+
`import * as Config from '${codegen.formatImportPath(configPath)}';`,
|
|
200
|
+
"",
|
|
201
|
+
`const create = await dynamic<typeof Config, ${tc}>(Config, ${JSON.stringify(partialOptions)}, ${JSON.stringify(serverOptions)});`
|
|
202
|
+
);
|
|
203
|
+
async function generateCollectionObjectEntry(collection, absolutePath) {
|
|
204
|
+
const fullPath = path2.relative(process.cwd(), absolutePath);
|
|
205
|
+
const content = await indexFileCache.read(fullPath).catch(() => "");
|
|
206
|
+
const parsed = fumaMatter(content);
|
|
207
|
+
const data = await core.transformFrontmatter(
|
|
208
|
+
{
|
|
209
|
+
collection,
|
|
210
|
+
filePath: fullPath,
|
|
211
|
+
source: content
|
|
212
|
+
},
|
|
213
|
+
parsed.data
|
|
214
|
+
);
|
|
215
|
+
const hash = createHash("md5").update(content).digest("hex");
|
|
216
|
+
const infoStr = [
|
|
217
|
+
// make sure it's included in vercel/nft
|
|
218
|
+
`absolutePath: path.resolve(${JSON.stringify(fullPath)})`
|
|
219
|
+
];
|
|
220
|
+
for (const [k, v] of Object.entries({
|
|
221
|
+
info: {
|
|
222
|
+
fullPath,
|
|
223
|
+
path: path2.relative(collection.dir, absolutePath)
|
|
224
|
+
},
|
|
225
|
+
data,
|
|
226
|
+
hash
|
|
227
|
+
})) {
|
|
228
|
+
infoStr.push(`${k}: ${JSON.stringify(v)}`);
|
|
229
|
+
}
|
|
230
|
+
return `{ ${infoStr.join(", ")} }`;
|
|
231
|
+
}
|
|
232
|
+
async function generateCollectionObject(parent) {
|
|
233
|
+
let collection;
|
|
234
|
+
if (parent.type === "doc") collection = parent;
|
|
235
|
+
else if (parent.type === "docs") collection = parent.docs;
|
|
236
|
+
if (!collection || !collection.dynamic) return;
|
|
237
|
+
const files = await glob(collection.patterns, {
|
|
238
|
+
cwd: collection.dir,
|
|
239
|
+
absolute: true
|
|
240
|
+
});
|
|
241
|
+
const entries = await Promise.all(
|
|
242
|
+
files.map((file) => generateCollectionObjectEntry(collection, file))
|
|
243
|
+
);
|
|
244
|
+
switch (parent.type) {
|
|
245
|
+
case "docs": {
|
|
246
|
+
const metaGlob = await generateMetaCollectionGlob(
|
|
247
|
+
ctx,
|
|
248
|
+
parent.meta,
|
|
249
|
+
true
|
|
250
|
+
);
|
|
251
|
+
return `await create.docs("${parent.name}", "${getBase(parent)}", ${metaGlob}, ${entries.join(", ")})`;
|
|
252
|
+
}
|
|
253
|
+
case "doc":
|
|
254
|
+
return `await create.doc("${collection.name}", "${getBase(collection)}", ${entries.join(", ")})`;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
await codegen.pushAsync(
|
|
258
|
+
core.getCollections().map(async (collection) => {
|
|
259
|
+
const obj = await generateCollectionObject(collection);
|
|
260
|
+
if (!obj) return;
|
|
261
|
+
return `
|
|
262
|
+
export const ${collection.name} = ${obj};`;
|
|
263
|
+
})
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
async function generateBrowserIndexFile(ctx) {
|
|
267
|
+
const { core, codegen, tc } = ctx;
|
|
268
|
+
codegen.lines.push(
|
|
269
|
+
`import { browser } from 'fumadocs-mdx/runtime/browser';`,
|
|
270
|
+
`import type * as Config from '${codegen.formatImportPath(core.getOptions().configPath)}';`,
|
|
271
|
+
"",
|
|
272
|
+
`const create = browser<typeof Config, ${tc}>();`
|
|
273
|
+
);
|
|
274
|
+
async function generateCollectionObject(collection) {
|
|
275
|
+
switch (collection.type) {
|
|
276
|
+
case "docs": {
|
|
277
|
+
if (collection.docs.dynamic) return;
|
|
278
|
+
return generateCollectionObject(collection.docs);
|
|
279
|
+
}
|
|
280
|
+
case "doc":
|
|
281
|
+
if (collection.dynamic) return;
|
|
282
|
+
return `create.doc("${collection.name}", ${await generateDocCollectionGlob(ctx, collection)})`;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
codegen.lines.push("const browserCollections = {");
|
|
286
|
+
await codegen.pushAsync(
|
|
287
|
+
core.getCollections().map(async (collection) => {
|
|
288
|
+
const obj = await generateCollectionObject(collection);
|
|
289
|
+
if (!obj) return;
|
|
290
|
+
return ident(`${collection.name}: ${obj},`);
|
|
291
|
+
})
|
|
292
|
+
);
|
|
293
|
+
codegen.lines.push("};", "export default browserCollections;");
|
|
294
|
+
}
|
|
295
|
+
function getBase(collection) {
|
|
296
|
+
return path2.relative(process.cwd(), collection.dir);
|
|
297
|
+
}
|
|
298
|
+
function generateDocCollectionFrontmatterGlob({ codegen, workspace }, collection, eager = false) {
|
|
299
|
+
return codegen.generateGlobImport(collection.patterns, {
|
|
300
|
+
query: {
|
|
301
|
+
collection: collection.name,
|
|
302
|
+
only: "frontmatter",
|
|
303
|
+
workspace
|
|
304
|
+
},
|
|
305
|
+
import: "frontmatter",
|
|
306
|
+
base: collection.dir,
|
|
307
|
+
eager
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
function generateDocCollectionGlob({ codegen, workspace }, collection, eager = false) {
|
|
311
|
+
return codegen.generateGlobImport(collection.patterns, {
|
|
312
|
+
query: {
|
|
313
|
+
collection: collection.name,
|
|
314
|
+
workspace
|
|
315
|
+
},
|
|
316
|
+
base: collection.dir,
|
|
317
|
+
eager
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
function generateMetaCollectionGlob({ codegen, workspace }, collection, eager = false) {
|
|
321
|
+
return codegen.generateGlobImport(collection.patterns, {
|
|
322
|
+
query: {
|
|
323
|
+
collection: collection.name,
|
|
324
|
+
workspace
|
|
325
|
+
},
|
|
326
|
+
import: "default",
|
|
327
|
+
base: collection.dir,
|
|
328
|
+
eager
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export {
|
|
333
|
+
indexFile
|
|
334
|
+
};
|