boltdocs 1.0.4 → 1.3.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/{SearchDialog-R36WKAQ7.mjs → SearchDialog-5EDRACEG.mjs} +1 -1
- package/dist/{SearchDialog-PYF3QMYG.css → SearchDialog-X57WPTNN.css} +54 -126
- package/dist/cache-EHR7SXRU.mjs +12 -0
- package/dist/chunk-GSYECEZY.mjs +381 -0
- package/dist/{chunk-TWSRXUFF.mjs → chunk-NS7WHDYA.mjs} +229 -418
- package/dist/client/index.css +54 -126
- package/dist/client/index.d.mts +5 -4
- package/dist/client/index.d.ts +5 -4
- package/dist/client/index.js +555 -580
- package/dist/client/index.mjs +304 -16
- package/dist/client/ssr.css +54 -126
- package/dist/client/ssr.js +257 -580
- package/dist/client/ssr.mjs +1 -1
- package/dist/{config-D2XmHJYe.d.mts → config-BD5ZHz15.d.mts} +7 -0
- package/dist/{config-D2XmHJYe.d.ts → config-BD5ZHz15.d.ts} +7 -0
- package/dist/node/index.d.mts +2 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +477 -123
- package/dist/node/index.mjs +114 -142
- package/package.json +2 -2
- package/src/client/app/index.tsx +344 -373
- package/src/client/app/preload.tsx +56 -56
- package/src/client/index.ts +40 -40
- package/src/client/ssr.tsx +51 -51
- package/src/client/theme/components/CodeBlock/CodeBlock.tsx +76 -76
- package/src/client/theme/components/CodeBlock/index.ts +1 -1
- package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +154 -154
- package/src/client/theme/components/PackageManagerTabs/index.ts +1 -1
- package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +64 -64
- package/src/client/theme/components/Playground/Playground.tsx +124 -124
- package/src/client/theme/components/Playground/index.ts +1 -1
- package/src/client/theme/components/Playground/playground.css +168 -168
- package/src/client/theme/components/Video/Video.tsx +84 -84
- package/src/client/theme/components/Video/index.ts +1 -1
- package/src/client/theme/components/Video/video.css +41 -41
- package/src/client/theme/components/mdx/Admonition.tsx +80 -80
- package/src/client/theme/components/mdx/Badge.tsx +31 -31
- package/src/client/theme/components/mdx/Button.tsx +50 -50
- package/src/client/theme/components/mdx/Card.tsx +80 -80
- package/src/client/theme/components/mdx/List.tsx +57 -57
- package/src/client/theme/components/mdx/Tabs.tsx +94 -94
- package/src/client/theme/components/mdx/index.ts +18 -18
- package/src/client/theme/components/mdx/mdx-components.css +424 -405
- package/src/client/theme/icons/bun.tsx +62 -62
- package/src/client/theme/icons/deno.tsx +20 -20
- package/src/client/theme/icons/discord.tsx +12 -12
- package/src/client/theme/icons/github.tsx +15 -15
- package/src/client/theme/icons/npm.tsx +13 -13
- package/src/client/theme/icons/pnpm.tsx +72 -72
- package/src/client/theme/icons/twitter.tsx +12 -12
- package/src/client/theme/styles/markdown.css +343 -343
- package/src/client/theme/styles/variables.css +162 -162
- package/src/client/theme/styles.css +37 -38
- package/src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx +10 -10
- package/src/client/theme/ui/BackgroundGradient/index.ts +1 -1
- package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +68 -68
- package/src/client/theme/ui/Breadcrumbs/index.ts +1 -1
- package/src/client/theme/ui/Footer/footer.css +32 -32
- package/src/client/theme/ui/Head/Head.tsx +69 -69
- package/src/client/theme/ui/Head/index.ts +1 -1
- package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +125 -125
- package/src/client/theme/ui/LanguageSwitcher/index.ts +1 -1
- package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +98 -98
- package/src/client/theme/ui/Layout/Layout.tsx +202 -213
- package/src/client/theme/ui/Layout/base.css +76 -76
- package/src/client/theme/ui/Layout/index.ts +2 -2
- package/src/client/theme/ui/Layout/pagination.css +72 -72
- package/src/client/theme/ui/Layout/responsive.css +36 -40
- package/src/client/theme/ui/Link/Link.tsx +254 -202
- package/src/client/theme/ui/Link/index.ts +2 -2
- package/src/client/theme/ui/Loading/Loading.tsx +10 -10
- package/src/client/theme/ui/Loading/index.ts +1 -1
- package/src/client/theme/ui/Loading/loading.css +30 -30
- package/src/client/theme/ui/Navbar/GithubStars.tsx +27 -27
- package/src/client/theme/ui/Navbar/Navbar.tsx +145 -145
- package/src/client/theme/ui/Navbar/index.ts +2 -2
- package/src/client/theme/ui/Navbar/navbar.css +233 -233
- package/src/client/theme/ui/NotFound/NotFound.tsx +19 -20
- package/src/client/theme/ui/NotFound/index.ts +1 -1
- package/src/client/theme/ui/NotFound/not-found.css +64 -64
- package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +235 -192
- package/src/client/theme/ui/OnThisPage/index.ts +1 -1
- package/src/client/theme/ui/OnThisPage/toc.css +132 -132
- package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +18 -18
- package/src/client/theme/ui/PoweredBy/index.ts +1 -1
- package/src/client/theme/ui/PoweredBy/powered-by.css +76 -76
- package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +199 -199
- package/src/client/theme/ui/SearchDialog/index.ts +1 -1
- package/src/client/theme/ui/SearchDialog/search.css +152 -152
- package/src/client/theme/ui/Sidebar/Sidebar.tsx +204 -200
- package/src/client/theme/ui/Sidebar/index.ts +1 -1
- package/src/client/theme/ui/Sidebar/sidebar.css +236 -269
- package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +69 -69
- package/src/client/theme/ui/ThemeToggle/index.ts +1 -1
- package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +136 -136
- package/src/client/theme/ui/VersionSwitcher/index.ts +1 -1
- package/src/client/types.ts +50 -50
- package/src/client/utils.ts +26 -26
- package/src/node/cache.ts +408 -94
- package/src/node/config.ts +192 -185
- package/src/node/index.ts +21 -21
- package/src/node/mdx.ts +120 -41
- package/src/node/plugin/entry.ts +58 -58
- package/src/node/plugin/html.ts +55 -55
- package/src/node/plugin/index.ts +193 -190
- package/src/node/plugin/types.ts +11 -11
- package/src/node/routes/cache.ts +28 -24
- package/src/node/routes/index.ts +167 -152
- package/src/node/routes/parser.ts +153 -127
- package/src/node/routes/sorter.ts +42 -42
- package/src/node/routes/types.ts +49 -49
- package/src/node/ssg/index.ts +114 -110
- package/src/node/ssg/meta.ts +34 -34
- package/src/node/ssg/options.ts +13 -13
- package/src/node/ssg/sitemap.ts +54 -54
- package/src/node/utils.ts +134 -134
- package/tsconfig.json +20 -20
- package/tsup.config.ts +22 -22
- package/dist/Playground-B2FA34BC.mjs +0 -6
- package/dist/chunk-WPT4MWTQ.mjs +0 -89
- package/src/client/theme/styles/home.css +0 -60
package/dist/node/index.mjs
CHANGED
|
@@ -1,133 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileCache,
|
|
3
|
+
TransformCache,
|
|
4
|
+
capitalize,
|
|
5
|
+
escapeHtml,
|
|
6
|
+
extractNumberPrefix,
|
|
7
|
+
fileToRoutePath,
|
|
8
|
+
isDocFile,
|
|
9
|
+
normalizePath,
|
|
10
|
+
parseFrontmatter,
|
|
11
|
+
stripNumberPrefix
|
|
12
|
+
} from "../chunk-GSYECEZY.mjs";
|
|
13
|
+
|
|
1
14
|
// src/node/plugin/index.ts
|
|
2
15
|
import { loadEnv } from "vite";
|
|
3
16
|
|
|
4
17
|
// src/node/routes/index.ts
|
|
5
18
|
import fastGlob from "fast-glob";
|
|
6
19
|
|
|
7
|
-
// src/node/utils.ts
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
import matter from "gray-matter";
|
|
10
|
-
function normalizePath(p) {
|
|
11
|
-
return p.replace(/\\/g, "/");
|
|
12
|
-
}
|
|
13
|
-
function stripNumberPrefix(name) {
|
|
14
|
-
return name.replace(/^\d+\./, "");
|
|
15
|
-
}
|
|
16
|
-
function extractNumberPrefix(name) {
|
|
17
|
-
const match = name.match(/^(\d+)\./);
|
|
18
|
-
return match ? parseInt(match[1], 10) : void 0;
|
|
19
|
-
}
|
|
20
|
-
function isDocFile(filePath) {
|
|
21
|
-
return /\.mdx?$/.test(filePath);
|
|
22
|
-
}
|
|
23
|
-
function getFileMtime(filePath) {
|
|
24
|
-
try {
|
|
25
|
-
return fs.statSync(filePath).mtimeMs;
|
|
26
|
-
} catch {
|
|
27
|
-
return 0;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function parseFrontmatter(filePath) {
|
|
31
|
-
const raw = fs.readFileSync(filePath, "utf-8");
|
|
32
|
-
const { data, content } = matter(raw);
|
|
33
|
-
return { data, content };
|
|
34
|
-
}
|
|
35
|
-
function escapeHtml(str) {
|
|
36
|
-
return str.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
37
|
-
}
|
|
38
|
-
function fileToRoutePath(relativePath) {
|
|
39
|
-
let cleanedPath = relativePath.split("/").map(stripNumberPrefix).join("/");
|
|
40
|
-
let routePath = cleanedPath.replace(/\.mdx?$/, "");
|
|
41
|
-
if (routePath === "index" || routePath.endsWith("/index")) {
|
|
42
|
-
routePath = routePath.replace(/index$/, "");
|
|
43
|
-
}
|
|
44
|
-
if (!routePath.startsWith("/")) {
|
|
45
|
-
routePath = "/" + routePath;
|
|
46
|
-
}
|
|
47
|
-
if (routePath.length > 1 && routePath.endsWith("/")) {
|
|
48
|
-
routePath = routePath.slice(0, -1);
|
|
49
|
-
}
|
|
50
|
-
return routePath;
|
|
51
|
-
}
|
|
52
|
-
function capitalize(str) {
|
|
53
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// src/node/cache.ts
|
|
57
|
-
var FileCache = class {
|
|
58
|
-
entries = /* @__PURE__ */ new Map();
|
|
59
|
-
/**
|
|
60
|
-
* Retrieves parsed data for a file from the cache.
|
|
61
|
-
* Compares the current filesystem mtime with the cached mtime.
|
|
62
|
-
*
|
|
63
|
-
* @param filePath - The absolute path of the file
|
|
64
|
-
* @returns The cached data if valid, or `null` if the file has changed or doesn't exist
|
|
65
|
-
*/
|
|
66
|
-
get(filePath) {
|
|
67
|
-
const entry = this.entries.get(filePath);
|
|
68
|
-
if (!entry) return null;
|
|
69
|
-
const currentMtime = getFileMtime(filePath);
|
|
70
|
-
if (currentMtime !== entry.mtime) return null;
|
|
71
|
-
return entry.data;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Stores parsed data for a file in the cache, recording its current mtime.
|
|
75
|
-
*
|
|
76
|
-
* @param filePath - The absolute path to the file
|
|
77
|
-
* @param data - The parsed data to store
|
|
78
|
-
*/
|
|
79
|
-
set(filePath, data) {
|
|
80
|
-
this.entries.set(filePath, {
|
|
81
|
-
data,
|
|
82
|
-
mtime: getFileMtime(filePath)
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Checks if a specific file's cache is still valid (based on its mtime).
|
|
87
|
-
*
|
|
88
|
-
* @param filePath - The absolute path to the file
|
|
89
|
-
* @returns `true` if the cache is valid, `false` otherwise
|
|
90
|
-
*/
|
|
91
|
-
isValid(filePath) {
|
|
92
|
-
return this.get(filePath) !== null;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Manually removes a specific file from the cache.
|
|
96
|
-
* Useful when forcefully invalidating a single updated file.
|
|
97
|
-
*
|
|
98
|
-
* @param filePath - The absolute path to the file
|
|
99
|
-
*/
|
|
100
|
-
invalidate(filePath) {
|
|
101
|
-
this.entries.delete(filePath);
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Clears the entire cache, forcing all files to be re-parsed on the next request.
|
|
105
|
-
* Useful when global dependencies (like config) change.
|
|
106
|
-
*/
|
|
107
|
-
invalidateAll() {
|
|
108
|
-
this.entries.clear();
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Removes cached entries for files that no longer exist on the filesystem.
|
|
112
|
-
* Prevents memory leaks from deleted files.
|
|
113
|
-
*
|
|
114
|
-
* @param currentFiles - A Set of absolute file paths currently discovered on the disk
|
|
115
|
-
*/
|
|
116
|
-
pruneStale(currentFiles) {
|
|
117
|
-
for (const key of this.entries.keys()) {
|
|
118
|
-
if (!currentFiles.has(key)) {
|
|
119
|
-
this.entries.delete(key);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/** Number of cached entries */
|
|
124
|
-
get size() {
|
|
125
|
-
return this.entries.size;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
20
|
// src/node/routes/cache.ts
|
|
130
|
-
var docCache = new FileCache();
|
|
21
|
+
var docCache = new FileCache({ name: "routes" });
|
|
131
22
|
function invalidateRouteCache() {
|
|
132
23
|
docCache.invalidateAll();
|
|
133
24
|
}
|
|
@@ -139,8 +30,18 @@ function invalidateFile(filePath) {
|
|
|
139
30
|
import path from "path";
|
|
140
31
|
import GithubSlugger from "github-slugger";
|
|
141
32
|
function parseDocFile(file, docsDir, basePath, config) {
|
|
33
|
+
const decodedFile = decodeURIComponent(file);
|
|
34
|
+
const absoluteFile = path.resolve(decodedFile);
|
|
35
|
+
const absoluteDocsDir = path.resolve(docsDir);
|
|
36
|
+
const relativePath = normalizePath(
|
|
37
|
+
path.relative(absoluteDocsDir, absoluteFile)
|
|
38
|
+
);
|
|
39
|
+
if (relativePath.startsWith("../") || relativePath === ".." || absoluteFile.includes("\0")) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Security breach: File is outside of docs directory or contains null bytes: ${file}`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
142
44
|
const { data, content } = parseFrontmatter(file);
|
|
143
|
-
const relativePath = normalizePath(path.relative(docsDir, file));
|
|
144
45
|
let parts = relativePath.split("/");
|
|
145
46
|
let locale;
|
|
146
47
|
let version;
|
|
@@ -186,25 +87,30 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
186
87
|
const level = match[1].length;
|
|
187
88
|
const text = match[2].replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/[_*`]/g, "").trim();
|
|
188
89
|
const id = slugger.slug(text);
|
|
189
|
-
headings.push({ level, text, id });
|
|
90
|
+
headings.push({ level, text: escapeHtml(text), id });
|
|
190
91
|
}
|
|
92
|
+
const sanitizedTitle = data.title ? escapeHtml(data.title) : inferredTitle;
|
|
93
|
+
const sanitizedDescription = data.description ? escapeHtml(data.description) : "";
|
|
94
|
+
const sanitizedBadge = data.badge ? escapeHtml(data.badge) : void 0;
|
|
191
95
|
return {
|
|
192
96
|
route: {
|
|
193
97
|
path: finalPath,
|
|
194
98
|
componentPath: file,
|
|
195
99
|
filePath: relativePath,
|
|
196
|
-
title:
|
|
197
|
-
description:
|
|
100
|
+
title: sanitizedTitle,
|
|
101
|
+
description: sanitizedDescription,
|
|
198
102
|
sidebarPosition,
|
|
199
103
|
headings,
|
|
200
104
|
locale,
|
|
201
105
|
version,
|
|
202
|
-
badge:
|
|
106
|
+
badge: sanitizedBadge
|
|
203
107
|
},
|
|
204
108
|
relativeDir: cleanDirName,
|
|
205
109
|
isGroupIndex,
|
|
206
110
|
groupMeta: isGroupIndex ? {
|
|
207
|
-
title:
|
|
111
|
+
title: escapeHtml(
|
|
112
|
+
data.groupTitle || data.title || (cleanDirName ? capitalize(cleanDirName) : "")
|
|
113
|
+
),
|
|
208
114
|
position: data.groupPosition ?? data.sidebarPosition ?? (rawDirName ? extractNumberPrefix(rawDirName) : void 0)
|
|
209
115
|
} : void 0,
|
|
210
116
|
inferredGroupPosition: rawDirName ? extractNumberPrefix(rawDirName) : void 0
|
|
@@ -240,6 +146,7 @@ function compareByGroupPosition(a, b) {
|
|
|
240
146
|
|
|
241
147
|
// src/node/routes/index.ts
|
|
242
148
|
async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
149
|
+
docCache.load();
|
|
243
150
|
const files = await fastGlob(["**/*.md", "**/*.mdx"], {
|
|
244
151
|
cwd: docsDir,
|
|
245
152
|
absolute: true
|
|
@@ -248,15 +155,25 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
248
155
|
if (config?.i18n) {
|
|
249
156
|
docCache.invalidateAll();
|
|
250
157
|
}
|
|
158
|
+
let cacheHits = 0;
|
|
251
159
|
const parsed = await Promise.all(
|
|
252
160
|
files.map(async (file) => {
|
|
253
161
|
const cached = docCache.get(file);
|
|
254
|
-
if (cached)
|
|
162
|
+
if (cached) {
|
|
163
|
+
cacheHits++;
|
|
164
|
+
return cached;
|
|
165
|
+
}
|
|
255
166
|
const result = parseDocFile(file, docsDir, basePath, config);
|
|
256
167
|
docCache.set(file, result);
|
|
257
168
|
return result;
|
|
258
169
|
})
|
|
259
170
|
);
|
|
171
|
+
if (files.length > 0) {
|
|
172
|
+
console.log(
|
|
173
|
+
`[boltdocs] Routes generated: ${files.length} files (${cacheHits} from cache, ${files.length - cacheHits} parsed)`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
docCache.save();
|
|
260
177
|
const groupMeta = /* @__PURE__ */ new Map();
|
|
261
178
|
for (const p of parsed) {
|
|
262
179
|
if (p.relativeDir) {
|
|
@@ -336,7 +253,7 @@ import { ViteImageOptimizer } from "vite-plugin-image-optimizer";
|
|
|
336
253
|
// src/node/config.ts
|
|
337
254
|
import path2 from "path";
|
|
338
255
|
import { pathToFileURL } from "url";
|
|
339
|
-
import
|
|
256
|
+
import fs from "fs";
|
|
340
257
|
var CONFIG_FILES = [
|
|
341
258
|
"boltdocs.config.js",
|
|
342
259
|
"boltdocs.config.mjs",
|
|
@@ -357,7 +274,7 @@ async function resolveConfig(docsDir) {
|
|
|
357
274
|
};
|
|
358
275
|
for (const filename of CONFIG_FILES) {
|
|
359
276
|
const configPath = path2.resolve(projectRoot, filename);
|
|
360
|
-
if (
|
|
277
|
+
if (fs.existsSync(configPath)) {
|
|
361
278
|
try {
|
|
362
279
|
const fileUrl = pathToFileURL(configPath).href + "?t=" + Date.now();
|
|
363
280
|
const mod = await import(fileUrl);
|
|
@@ -383,7 +300,7 @@ async function resolveConfig(docsDir) {
|
|
|
383
300
|
}
|
|
384
301
|
|
|
385
302
|
// src/node/ssg/index.ts
|
|
386
|
-
import
|
|
303
|
+
import fs2 from "fs";
|
|
387
304
|
import path3 from "path";
|
|
388
305
|
import { fileURLToPath } from "url";
|
|
389
306
|
import { createRequire } from "module";
|
|
@@ -456,7 +373,7 @@ async function generateStaticPages(options) {
|
|
|
456
373
|
const siteTitle = config?.themeConfig?.title || "Boltdocs";
|
|
457
374
|
const siteDescription = config?.themeConfig?.description || "";
|
|
458
375
|
const ssrModulePath = path3.resolve(_dirname, "../client/ssr.js");
|
|
459
|
-
if (!
|
|
376
|
+
if (!fs2.existsSync(ssrModulePath)) {
|
|
460
377
|
console.error(
|
|
461
378
|
"[boltdocs] SSR module not found at",
|
|
462
379
|
ssrModulePath,
|
|
@@ -466,11 +383,11 @@ async function generateStaticPages(options) {
|
|
|
466
383
|
}
|
|
467
384
|
const { render } = _require(ssrModulePath);
|
|
468
385
|
const templatePath = path3.join(outDir, "index.html");
|
|
469
|
-
if (!
|
|
386
|
+
if (!fs2.existsSync(templatePath)) {
|
|
470
387
|
console.warn("[boltdocs] No index.html found in outDir, skipping SSG.");
|
|
471
388
|
return;
|
|
472
389
|
}
|
|
473
|
-
const template =
|
|
390
|
+
const template = fs2.readFileSync(templatePath, "utf-8");
|
|
474
391
|
let homePageComp;
|
|
475
392
|
if (config?._homePagePath) {
|
|
476
393
|
try {
|
|
@@ -497,8 +414,8 @@ async function generateStaticPages(options) {
|
|
|
497
414
|
description: escapeHtml(pageDescription)
|
|
498
415
|
}).replace("<!--app-html-->", appHtml).replace(`<div id="root"></div>`, `<div id="root">${appHtml}</div>`);
|
|
499
416
|
const routeDir = path3.join(outDir, route.path);
|
|
500
|
-
await
|
|
501
|
-
await
|
|
417
|
+
await fs2.promises.mkdir(routeDir, { recursive: true });
|
|
418
|
+
await fs2.promises.writeFile(
|
|
502
419
|
path3.join(routeDir, "index.html"),
|
|
503
420
|
html,
|
|
504
421
|
"utf-8"
|
|
@@ -512,10 +429,12 @@ async function generateStaticPages(options) {
|
|
|
512
429
|
routes.map((r) => r.path),
|
|
513
430
|
config
|
|
514
431
|
);
|
|
515
|
-
|
|
432
|
+
fs2.writeFileSync(path3.join(outDir, "sitemap.xml"), sitemap, "utf-8");
|
|
516
433
|
console.log(
|
|
517
434
|
`[boltdocs] Generated ${routes.length} static pages + sitemap.xml`
|
|
518
435
|
);
|
|
436
|
+
const { flushCache } = await import("../cache-EHR7SXRU.mjs");
|
|
437
|
+
await flushCache();
|
|
519
438
|
}
|
|
520
439
|
|
|
521
440
|
// src/node/plugin/index.ts
|
|
@@ -696,6 +615,8 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
696
615
|
if (!isBuild) return;
|
|
697
616
|
const outDir = viteConfig?.build?.outDir ? path4.resolve(viteConfig.root, viteConfig.build.outDir) : path4.resolve(process.cwd(), "dist");
|
|
698
617
|
await generateStaticPages({ docsDir, outDir, config });
|
|
618
|
+
const { flushCache } = await import("../cache-EHR7SXRU.mjs");
|
|
619
|
+
await flushCache();
|
|
699
620
|
}
|
|
700
621
|
},
|
|
701
622
|
ViteImageOptimizer({
|
|
@@ -725,10 +646,13 @@ import remarkGfm from "remark-gfm";
|
|
|
725
646
|
import remarkFrontmatter from "remark-frontmatter";
|
|
726
647
|
import rehypeSlug from "rehype-slug";
|
|
727
648
|
import rehypePrettyCode from "rehype-pretty-code";
|
|
649
|
+
import crypto from "crypto";
|
|
650
|
+
var mdxCache = new TransformCache("mdx");
|
|
651
|
+
var mdxCacheLoaded = false;
|
|
728
652
|
function boltdocsMdxPlugin(config) {
|
|
729
653
|
const extraRemarkPlugins = config?.plugins?.flatMap((p) => p.remarkPlugins || []) || [];
|
|
730
654
|
const extraRehypePlugins = config?.plugins?.flatMap((p) => p.rehypePlugins || []) || [];
|
|
731
|
-
|
|
655
|
+
const baseMdxPlugin = mdxPlugin({
|
|
732
656
|
remarkPlugins: [remarkGfm, remarkFrontmatter, ...extraRemarkPlugins],
|
|
733
657
|
rehypePlugins: [
|
|
734
658
|
rehypeSlug,
|
|
@@ -736,16 +660,64 @@ function boltdocsMdxPlugin(config) {
|
|
|
736
660
|
[
|
|
737
661
|
rehypePrettyCode,
|
|
738
662
|
{
|
|
739
|
-
theme: "one-dark-pro",
|
|
663
|
+
theme: config?.themeConfig?.codeTheme || "one-dark-pro",
|
|
740
664
|
keepBackground: false
|
|
741
665
|
}
|
|
742
666
|
]
|
|
743
667
|
],
|
|
744
|
-
// Provide React as default for JSX
|
|
745
668
|
jsxRuntime: "automatic",
|
|
746
669
|
providerImportSource: "@mdx-js/react"
|
|
747
670
|
});
|
|
671
|
+
return {
|
|
672
|
+
...baseMdxPlugin,
|
|
673
|
+
name: "vite-plugin-boltdocs-mdx",
|
|
674
|
+
async buildStart() {
|
|
675
|
+
hits = 0;
|
|
676
|
+
total = 0;
|
|
677
|
+
if (!mdxCacheLoaded) {
|
|
678
|
+
mdxCache.load();
|
|
679
|
+
mdxCacheLoaded = true;
|
|
680
|
+
}
|
|
681
|
+
if (baseMdxPlugin.buildStart) {
|
|
682
|
+
await baseMdxPlugin.buildStart.call(this);
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
async transform(code, id, options) {
|
|
686
|
+
if (!id.endsWith(".md") && !id.endsWith(".mdx")) {
|
|
687
|
+
return baseMdxPlugin.transform?.call(this, code, id, options);
|
|
688
|
+
}
|
|
689
|
+
total++;
|
|
690
|
+
const contentHash = crypto.createHash("md5").update(code).digest("hex");
|
|
691
|
+
const cacheKey = `${id}:${contentHash}`;
|
|
692
|
+
const cached = mdxCache.get(cacheKey);
|
|
693
|
+
if (cached) {
|
|
694
|
+
hits++;
|
|
695
|
+
return { code: cached, map: null };
|
|
696
|
+
}
|
|
697
|
+
const result = await baseMdxPlugin.transform.call(
|
|
698
|
+
this,
|
|
699
|
+
code,
|
|
700
|
+
id,
|
|
701
|
+
options
|
|
702
|
+
);
|
|
703
|
+
if (result && typeof result === "object" && result.code) {
|
|
704
|
+
mdxCache.set(cacheKey, result.code);
|
|
705
|
+
} else if (typeof result === "string") {
|
|
706
|
+
mdxCache.set(cacheKey, result);
|
|
707
|
+
}
|
|
708
|
+
return result;
|
|
709
|
+
},
|
|
710
|
+
async buildEnd() {
|
|
711
|
+
mdxCache.save();
|
|
712
|
+
await mdxCache.flush();
|
|
713
|
+
if (baseMdxPlugin.buildEnd) {
|
|
714
|
+
await baseMdxPlugin.buildEnd.call(this);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
};
|
|
748
718
|
}
|
|
719
|
+
var hits = 0;
|
|
720
|
+
var total = 0;
|
|
749
721
|
|
|
750
722
|
// src/node/index.ts
|
|
751
723
|
async function boltdocs(options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "boltdocs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "A lightweight documentation generator for React projects.",
|
|
5
5
|
"main": "dist/node/index.js",
|
|
6
6
|
"module": "dist/node/index.mjs",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"remark-gfm": "^4.0.1",
|
|
55
55
|
"sharp": "^0.34.5",
|
|
56
56
|
"shiki": "^3.23.0",
|
|
57
|
-
"svgo": "^4.0.
|
|
57
|
+
"svgo": "^4.0.1",
|
|
58
58
|
"unist-util-visit": "^5.1.0",
|
|
59
59
|
"vite": "^7.3.1",
|
|
60
60
|
"vite-plugin-image-optimizer": "^2.0.3"
|