boltdocs 1.6.0 → 1.7.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-J3KNRGNO.mjs → SearchDialog-6Z7CUAYJ.mjs} +8 -1
- package/dist/{SearchDialog-3QICRMWF.css → SearchDialog-GOZ6X53X.css} +385 -113
- package/dist/{chunk-HSPDIRTW.mjs → chunk-SFVOGJ2W.mjs} +955 -737
- package/dist/client/index.css +385 -113
- package/dist/client/index.d.mts +19 -7
- package/dist/client/index.d.ts +19 -7
- package/dist/client/index.js +964 -577
- package/dist/client/index.mjs +118 -1
- package/dist/client/ssr.css +385 -113
- package/dist/client/ssr.d.mts +3 -1
- package/dist/client/ssr.d.ts +3 -1
- package/dist/client/ssr.js +743 -474
- package/dist/client/ssr.mjs +3 -2
- package/dist/{config-DkZg5aCf.d.ts → config-D68h41CA.d.mts} +21 -2
- package/dist/{config-DkZg5aCf.d.mts → config-D68h41CA.d.ts} +21 -2
- package/dist/node/index.d.mts +12 -2
- package/dist/node/index.d.ts +12 -2
- package/dist/node/index.js +48 -21
- package/dist/node/index.mjs +48 -21
- package/dist/{types-DGIo1VKD.d.mts → types-BbceAHA0.d.mts} +15 -0
- package/dist/{types-DGIo1VKD.d.ts → types-BbceAHA0.d.ts} +15 -0
- package/package.json +1 -1
- package/src/client/app/index.tsx +16 -11
- package/src/client/index.ts +2 -0
- package/src/client/ssr.tsx +4 -1
- package/src/client/theme/components/mdx/Table.tsx +151 -0
- package/src/client/theme/components/mdx/index.ts +3 -0
- package/src/client/theme/components/mdx/mdx-components.css +128 -0
- package/src/client/theme/styles/markdown.css +8 -3
- package/src/client/theme/styles/variables.css +34 -9
- package/src/client/theme/ui/ErrorBoundary/ErrorBoundary.tsx +46 -0
- package/src/client/theme/ui/ErrorBoundary/index.ts +1 -0
- package/src/client/theme/ui/Layout/Layout.tsx +10 -11
- package/src/client/theme/ui/Layout/base.css +15 -3
- package/src/client/theme/ui/Link/Link.tsx +2 -2
- package/src/client/theme/ui/Link/LinkPreview.tsx +9 -14
- package/src/client/theme/ui/Link/link-preview.css +30 -27
- package/src/client/theme/ui/Navbar/Navbar.tsx +65 -17
- package/src/client/theme/ui/Navbar/Tabs.tsx +99 -0
- package/src/client/theme/ui/Navbar/navbar.css +119 -5
- package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +66 -57
- package/src/client/theme/ui/OnThisPage/toc.css +30 -10
- package/src/client/theme/ui/ProgressBar/ProgressBar.css +17 -0
- package/src/client/theme/ui/ProgressBar/ProgressBar.tsx +51 -0
- package/src/client/theme/ui/ProgressBar/index.ts +1 -0
- package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +11 -1
- package/src/client/theme/ui/Sidebar/Sidebar.tsx +97 -57
- package/src/client/theme/ui/Sidebar/sidebar.css +61 -67
- package/src/client/types.ts +12 -0
- package/src/node/config.ts +19 -1
- package/src/node/plugin/entry.ts +5 -1
- package/src/node/plugin/index.ts +2 -1
- package/src/node/routes/index.ts +13 -1
- package/src/node/routes/parser.ts +32 -7
- package/src/node/routes/types.ts +11 -1
- package/src/node/ssg/index.ts +2 -1
- package/src/node/ssg/options.ts +2 -0
package/dist/client/ssr.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AppShell
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-SFVOGJ2W.mjs";
|
|
4
4
|
import "../chunk-FMTOYQLO.mjs";
|
|
5
5
|
|
|
6
6
|
// src/client/ssr.tsx
|
|
@@ -9,7 +9,7 @@ import ReactDOMServer from "react-dom/server";
|
|
|
9
9
|
import { StaticRouter } from "react-router-dom/server";
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
async function render(options) {
|
|
12
|
-
const { path, routes, config, modules, homePage } = options;
|
|
12
|
+
const { path, routes, config, modules, homePage, docsDirName } = options;
|
|
13
13
|
const resolvedModules = {};
|
|
14
14
|
for (const [key, mod] of Object.entries(modules)) {
|
|
15
15
|
resolvedModules[key] = () => Promise.resolve(mod);
|
|
@@ -20,6 +20,7 @@ async function render(options) {
|
|
|
20
20
|
{
|
|
21
21
|
initialRoutes: routes,
|
|
22
22
|
initialConfig: config,
|
|
23
|
+
docsDirName,
|
|
23
24
|
modules: resolvedModules,
|
|
24
25
|
homePage
|
|
25
26
|
}
|
|
@@ -28,8 +28,18 @@ interface BoltdocsThemeConfig {
|
|
|
28
28
|
logo?: string;
|
|
29
29
|
/** Items to display in the top navigation bar */
|
|
30
30
|
navbar?: Array<{
|
|
31
|
-
text
|
|
32
|
-
|
|
31
|
+
/** Text to display (alias for text) */
|
|
32
|
+
label?: string;
|
|
33
|
+
/** Text to display */
|
|
34
|
+
text?: string;
|
|
35
|
+
/** URL path or external link (alias for link) */
|
|
36
|
+
to?: string;
|
|
37
|
+
/** URL path or external link (alias for link) */
|
|
38
|
+
href?: string;
|
|
39
|
+
/** URL path or external link */
|
|
40
|
+
link?: string;
|
|
41
|
+
/** Alignment of the item in the navbar */
|
|
42
|
+
position?: "left" | "right";
|
|
33
43
|
}>;
|
|
34
44
|
/** Items to display in the sidebar, organized optionally by group URLs */
|
|
35
45
|
sidebar?: Record<string, Array<{
|
|
@@ -67,6 +77,15 @@ interface BoltdocsThemeConfig {
|
|
|
67
77
|
className?: string;
|
|
68
78
|
style?: any;
|
|
69
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Top-level tabs for organizing documentation groups.
|
|
82
|
+
* Tab discovery uses the (tab-id) directory syntax.
|
|
83
|
+
*/
|
|
84
|
+
tabs?: Array<{
|
|
85
|
+
id: string;
|
|
86
|
+
text: string;
|
|
87
|
+
icon?: string;
|
|
88
|
+
}>;
|
|
70
89
|
/**
|
|
71
90
|
* The syntax highlighting theme for code blocks.
|
|
72
91
|
* Supports any Shiki theme name (e.g., 'github-dark', 'one-dark-pro', 'aurora-x').
|
|
@@ -28,8 +28,18 @@ interface BoltdocsThemeConfig {
|
|
|
28
28
|
logo?: string;
|
|
29
29
|
/** Items to display in the top navigation bar */
|
|
30
30
|
navbar?: Array<{
|
|
31
|
-
text
|
|
32
|
-
|
|
31
|
+
/** Text to display (alias for text) */
|
|
32
|
+
label?: string;
|
|
33
|
+
/** Text to display */
|
|
34
|
+
text?: string;
|
|
35
|
+
/** URL path or external link (alias for link) */
|
|
36
|
+
to?: string;
|
|
37
|
+
/** URL path or external link (alias for link) */
|
|
38
|
+
href?: string;
|
|
39
|
+
/** URL path or external link */
|
|
40
|
+
link?: string;
|
|
41
|
+
/** Alignment of the item in the navbar */
|
|
42
|
+
position?: "left" | "right";
|
|
33
43
|
}>;
|
|
34
44
|
/** Items to display in the sidebar, organized optionally by group URLs */
|
|
35
45
|
sidebar?: Record<string, Array<{
|
|
@@ -67,6 +77,15 @@ interface BoltdocsThemeConfig {
|
|
|
67
77
|
className?: string;
|
|
68
78
|
style?: any;
|
|
69
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Top-level tabs for organizing documentation groups.
|
|
82
|
+
* Tab discovery uses the (tab-id) directory syntax.
|
|
83
|
+
*/
|
|
84
|
+
tabs?: Array<{
|
|
85
|
+
id: string;
|
|
86
|
+
text: string;
|
|
87
|
+
icon?: string;
|
|
88
|
+
}>;
|
|
70
89
|
/**
|
|
71
90
|
* The syntax highlighting theme for code blocks.
|
|
72
91
|
* Supports any Shiki theme name (e.g., 'github-dark', 'one-dark-pro', 'aurora-x').
|
package/dist/node/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
-
import { B as BoltdocsConfig } from '../config-
|
|
3
|
-
export { a as BoltdocsThemeConfig } from '../config-
|
|
2
|
+
import { B as BoltdocsConfig } from '../config-D68h41CA.mjs';
|
|
3
|
+
export { a as BoltdocsThemeConfig } from '../config-D68h41CA.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Configuration options specifically for the Boltdocs Vite plugin.
|
|
@@ -20,6 +20,8 @@ interface BoltdocsPluginOptions {
|
|
|
20
20
|
interface SSGOptions {
|
|
21
21
|
/** The root directory containing markdown documentation files */
|
|
22
22
|
docsDir: string;
|
|
23
|
+
/** The name of the documentation directory (e.g. 'docs') */
|
|
24
|
+
docsDirName: string;
|
|
23
25
|
/** The output directory where Vite placed the compiled `index.html` and assets */
|
|
24
26
|
outDir: string;
|
|
25
27
|
/** Pre-resolved config (avoids re-resolving during the SSG phase) */
|
|
@@ -57,6 +59,8 @@ interface RouteMeta {
|
|
|
57
59
|
groupTitle?: string;
|
|
58
60
|
/** Optional explicit position for ordering the group itself */
|
|
59
61
|
groupPosition?: number;
|
|
62
|
+
/** Optional icon for the route's group */
|
|
63
|
+
groupIcon?: string;
|
|
60
64
|
/** Extracted markdown headings for search indexing */
|
|
61
65
|
headings?: {
|
|
62
66
|
level: number;
|
|
@@ -72,6 +76,12 @@ interface RouteMeta {
|
|
|
72
76
|
text: string;
|
|
73
77
|
expires?: string;
|
|
74
78
|
};
|
|
79
|
+
/** Optional icon to display (Lucide icon name or raw SVG) */
|
|
80
|
+
icon?: string;
|
|
81
|
+
/** The tab this route belongs to, if tabs are configured */
|
|
82
|
+
tab?: string;
|
|
83
|
+
/** The extracted plain-text content of the page for search indexing */
|
|
84
|
+
_content?: string;
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
|
package/dist/node/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
-
import { B as BoltdocsConfig } from '../config-
|
|
3
|
-
export { a as BoltdocsThemeConfig } from '../config-
|
|
2
|
+
import { B as BoltdocsConfig } from '../config-D68h41CA.js';
|
|
3
|
+
export { a as BoltdocsThemeConfig } from '../config-D68h41CA.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Configuration options specifically for the Boltdocs Vite plugin.
|
|
@@ -20,6 +20,8 @@ interface BoltdocsPluginOptions {
|
|
|
20
20
|
interface SSGOptions {
|
|
21
21
|
/** The root directory containing markdown documentation files */
|
|
22
22
|
docsDir: string;
|
|
23
|
+
/** The name of the documentation directory (e.g. 'docs') */
|
|
24
|
+
docsDirName: string;
|
|
23
25
|
/** The output directory where Vite placed the compiled `index.html` and assets */
|
|
24
26
|
outDir: string;
|
|
25
27
|
/** Pre-resolved config (avoids re-resolving during the SSG phase) */
|
|
@@ -57,6 +59,8 @@ interface RouteMeta {
|
|
|
57
59
|
groupTitle?: string;
|
|
58
60
|
/** Optional explicit position for ordering the group itself */
|
|
59
61
|
groupPosition?: number;
|
|
62
|
+
/** Optional icon for the route's group */
|
|
63
|
+
groupIcon?: string;
|
|
60
64
|
/** Extracted markdown headings for search indexing */
|
|
61
65
|
headings?: {
|
|
62
66
|
level: number;
|
|
@@ -72,6 +76,12 @@ interface RouteMeta {
|
|
|
72
76
|
text: string;
|
|
73
77
|
expires?: string;
|
|
74
78
|
};
|
|
79
|
+
/** Optional icon to display (Lucide icon name or raw SVG) */
|
|
80
|
+
icon?: string;
|
|
81
|
+
/** The tab this route belongs to, if tabs are configured */
|
|
82
|
+
tab?: string;
|
|
83
|
+
/** The extracted plain-text content of the page for search indexing */
|
|
84
|
+
_content?: string;
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
|
package/dist/node/index.js
CHANGED
|
@@ -478,6 +478,14 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
478
478
|
parts = parts.slice(1);
|
|
479
479
|
}
|
|
480
480
|
}
|
|
481
|
+
let inferredTab;
|
|
482
|
+
if (parts.length > 0) {
|
|
483
|
+
const tabMatch = parts[0].match(/^\((.+)\)$/);
|
|
484
|
+
if (tabMatch) {
|
|
485
|
+
inferredTab = tabMatch[1].toLowerCase();
|
|
486
|
+
parts = parts.slice(1);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
481
489
|
const cleanRelativePath = parts.join("/");
|
|
482
490
|
let cleanRoutePath;
|
|
483
491
|
if (data.permalink) {
|
|
@@ -511,15 +519,17 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
511
519
|
const level = match[1].length;
|
|
512
520
|
const text = match[2].replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/[_*`]/g, "").trim();
|
|
513
521
|
const id = slugger.slug(text);
|
|
514
|
-
headings.push({ level, text
|
|
522
|
+
headings.push({ level, text, id });
|
|
515
523
|
}
|
|
516
|
-
const sanitizedTitle = data.title ?
|
|
517
|
-
let sanitizedDescription = data.description ?
|
|
524
|
+
const sanitizedTitle = data.title ? data.title : inferredTitle;
|
|
525
|
+
let sanitizedDescription = data.description ? data.description : "";
|
|
518
526
|
if (!sanitizedDescription && content) {
|
|
519
527
|
const summary = content.replace(/^#+.*$/gm, "").replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/[_*`]/g, "").replace(/\n+/g, " ").trim().slice(0, 160);
|
|
520
|
-
sanitizedDescription =
|
|
528
|
+
sanitizedDescription = summary;
|
|
521
529
|
}
|
|
522
|
-
const sanitizedBadge = data.badge ?
|
|
530
|
+
const sanitizedBadge = data.badge ? data.badge : void 0;
|
|
531
|
+
const icon = data.icon ? String(data.icon) : void 0;
|
|
532
|
+
const plainText = content.replace(/^#+.*$/gm, "").replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/<[^>]+>/g, "").replace(/\{[^\}]+\}/g, "").replace(/[_*`]/g, "").replace(/\n+/g, " ").trim();
|
|
523
533
|
return {
|
|
524
534
|
route: {
|
|
525
535
|
path: finalPath,
|
|
@@ -531,15 +541,18 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
531
541
|
headings,
|
|
532
542
|
locale,
|
|
533
543
|
version,
|
|
534
|
-
badge: sanitizedBadge
|
|
544
|
+
badge: sanitizedBadge,
|
|
545
|
+
icon,
|
|
546
|
+
tab: inferredTab,
|
|
547
|
+
_content: plainText
|
|
535
548
|
},
|
|
536
549
|
relativeDir: cleanDirName,
|
|
537
550
|
isGroupIndex,
|
|
551
|
+
inferredTab,
|
|
538
552
|
groupMeta: isGroupIndex ? {
|
|
539
|
-
title:
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
position: data.groupPosition ?? data.sidebarPosition ?? (rawDirName ? extractNumberPrefix(rawDirName) : void 0)
|
|
553
|
+
title: data.groupTitle || data.title || (cleanDirName ? capitalize(cleanDirName) : ""),
|
|
554
|
+
position: data.groupPosition ?? data.sidebarPosition ?? (rawDirName ? extractNumberPrefix(rawDirName) : void 0),
|
|
555
|
+
icon
|
|
543
556
|
} : void 0,
|
|
544
557
|
inferredGroupPosition: rawDirName ? extractNumberPrefix(rawDirName) : void 0
|
|
545
558
|
};
|
|
@@ -575,6 +588,7 @@ function compareByGroupPosition(a, b) {
|
|
|
575
588
|
// src/node/routes/index.ts
|
|
576
589
|
async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
577
590
|
docCache.load();
|
|
591
|
+
docCache.invalidateAll();
|
|
578
592
|
const files = await (0, import_fast_glob.default)(["**/*.md", "**/*.mdx"], {
|
|
579
593
|
cwd: docsDir,
|
|
580
594
|
absolute: true
|
|
@@ -608,13 +622,17 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
608
622
|
if (!groupMeta.has(p.relativeDir)) {
|
|
609
623
|
groupMeta.set(p.relativeDir, {
|
|
610
624
|
title: capitalize(p.relativeDir),
|
|
611
|
-
position: p.inferredGroupPosition
|
|
625
|
+
position: p.inferredGroupPosition,
|
|
626
|
+
icon: p.route.icon
|
|
612
627
|
});
|
|
613
628
|
} else {
|
|
614
629
|
const entry = groupMeta.get(p.relativeDir);
|
|
615
630
|
if (entry.position === void 0 && p.inferredGroupPosition !== void 0) {
|
|
616
631
|
entry.position = p.inferredGroupPosition;
|
|
617
632
|
}
|
|
633
|
+
if (!entry.icon && p.route.icon) {
|
|
634
|
+
entry.icon = p.route.icon;
|
|
635
|
+
}
|
|
618
636
|
}
|
|
619
637
|
}
|
|
620
638
|
if (p.isGroupIndex && p.relativeDir && p.groupMeta) {
|
|
@@ -623,6 +641,9 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
623
641
|
if (p.groupMeta.position !== void 0) {
|
|
624
642
|
entry.position = p.groupMeta.position;
|
|
625
643
|
}
|
|
644
|
+
if (p.groupMeta.icon) {
|
|
645
|
+
entry.icon = p.groupMeta.icon;
|
|
646
|
+
}
|
|
626
647
|
}
|
|
627
648
|
}
|
|
628
649
|
const routes = parsed.map((p) => {
|
|
@@ -632,7 +653,8 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
632
653
|
...p.route,
|
|
633
654
|
group: dir,
|
|
634
655
|
groupTitle: meta?.title || (dir ? capitalize(dir) : void 0),
|
|
635
|
-
groupPosition: meta?.position
|
|
656
|
+
groupPosition: meta?.position,
|
|
657
|
+
groupIcon: meta?.icon
|
|
636
658
|
};
|
|
637
659
|
});
|
|
638
660
|
if (config?.i18n) {
|
|
@@ -797,7 +819,7 @@ var _filename = (0, import_url2.fileURLToPath)(import_meta2.url);
|
|
|
797
819
|
var _dirname = import_path4.default.dirname(_filename);
|
|
798
820
|
var _require = (0, import_module.createRequire)(import_meta2.url);
|
|
799
821
|
async function generateStaticPages(options) {
|
|
800
|
-
const { docsDir, outDir, config } = options;
|
|
822
|
+
const { docsDir, docsDirName, outDir, config } = options;
|
|
801
823
|
const routes = await generateRoutes(docsDir, config);
|
|
802
824
|
const siteTitle = config?.themeConfig?.title || "Boltdocs";
|
|
803
825
|
const siteDescription = config?.themeConfig?.description || "";
|
|
@@ -829,6 +851,7 @@ async function generateStaticPages(options) {
|
|
|
829
851
|
path: route.path,
|
|
830
852
|
routes,
|
|
831
853
|
config: config || {},
|
|
854
|
+
docsDirName,
|
|
832
855
|
modules: fakeModules,
|
|
833
856
|
homePage: void 0
|
|
834
857
|
// No custom home page for now
|
|
@@ -863,10 +886,11 @@ async function generateStaticPages(options) {
|
|
|
863
886
|
|
|
864
887
|
// src/node/plugin/index.ts
|
|
865
888
|
init_utils();
|
|
866
|
-
var
|
|
889
|
+
var import_path6 = __toESM(require("path"));
|
|
867
890
|
|
|
868
891
|
// src/node/plugin/entry.ts
|
|
869
892
|
init_utils();
|
|
893
|
+
var import_path5 = __toESM(require("path"));
|
|
870
894
|
function generateEntryCode(options, config) {
|
|
871
895
|
const homeImport = options.homePage ? `import HomePage from '${normalizePath(options.homePage)}';` : "";
|
|
872
896
|
const homeOption = options.homePage ? "homePage: HomePage," : "";
|
|
@@ -875,11 +899,12 @@ function generateEntryCode(options, config) {
|
|
|
875
899
|
const componentImports = pluginComponents.map(
|
|
876
900
|
([
|
|
877
901
|
name,
|
|
878
|
-
|
|
879
|
-
]) => `import * as _comp_${name} from '${normalizePath(
|
|
902
|
+
path7
|
|
903
|
+
]) => `import * as _comp_${name} from '${normalizePath(path7)}';
|
|
880
904
|
const ${name} = _comp_${name}.default || _comp_${name}['${name}'] || _comp_${name};`
|
|
881
905
|
).join("\n");
|
|
882
906
|
const componentMap = pluginComponents.map(([name]) => name).join(", ");
|
|
907
|
+
const docsDirName = import_path5.default.basename(options.docsDir || "docs");
|
|
883
908
|
return `
|
|
884
909
|
import { createBoltdocsApp as _createApp } from 'boltdocs/client';
|
|
885
910
|
import 'boltdocs/style.css';
|
|
@@ -892,8 +917,9 @@ ${componentImports}
|
|
|
892
917
|
_createApp({
|
|
893
918
|
target: '#root',
|
|
894
919
|
routes: _routes,
|
|
920
|
+
docsDirName: '${docsDirName}',
|
|
895
921
|
config: _config,
|
|
896
|
-
modules: import.meta.glob('
|
|
922
|
+
modules: import.meta.glob('/${docsDirName}/**/*.{md,mdx}'),
|
|
897
923
|
hot: import.meta.hot,
|
|
898
924
|
${homeOption}
|
|
899
925
|
components: { ${componentMap} },
|
|
@@ -946,7 +972,7 @@ ${themeScript} </head>`);
|
|
|
946
972
|
|
|
947
973
|
// src/node/plugin/index.ts
|
|
948
974
|
function boltdocsPlugin(options = {}, passedConfig) {
|
|
949
|
-
const docsDir =
|
|
975
|
+
const docsDir = import_path6.default.resolve(process.cwd(), options.docsDir || "docs");
|
|
950
976
|
const normalizedDocsDir = normalizePath(docsDir);
|
|
951
977
|
let config = passedConfig;
|
|
952
978
|
let viteConfig;
|
|
@@ -976,7 +1002,7 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
976
1002
|
},
|
|
977
1003
|
configureServer(server) {
|
|
978
1004
|
const configPaths = CONFIG_FILES.map(
|
|
979
|
-
(c) =>
|
|
1005
|
+
(c) => import_path6.default.resolve(process.cwd(), c)
|
|
980
1006
|
);
|
|
981
1007
|
server.watcher.add(configPaths);
|
|
982
1008
|
const handleFileEvent = async (file, type) => {
|
|
@@ -1039,8 +1065,9 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
1039
1065
|
},
|
|
1040
1066
|
async closeBundle() {
|
|
1041
1067
|
if (!isBuild) return;
|
|
1042
|
-
const outDir = viteConfig?.build?.outDir ?
|
|
1043
|
-
|
|
1068
|
+
const outDir = viteConfig?.build?.outDir ? import_path6.default.resolve(viteConfig.root, viteConfig.build.outDir) : import_path6.default.resolve(process.cwd(), "dist");
|
|
1069
|
+
const docsDirName = import_path6.default.basename(docsDir || "docs");
|
|
1070
|
+
await generateStaticPages({ docsDir, docsDirName, outDir, config });
|
|
1044
1071
|
const { flushCache: flushCache2 } = await Promise.resolve().then(() => (init_cache(), cache_exports));
|
|
1045
1072
|
await flushCache2();
|
|
1046
1073
|
}
|
package/dist/node/index.mjs
CHANGED
|
@@ -60,6 +60,14 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
60
60
|
parts = parts.slice(1);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
let inferredTab;
|
|
64
|
+
if (parts.length > 0) {
|
|
65
|
+
const tabMatch = parts[0].match(/^\((.+)\)$/);
|
|
66
|
+
if (tabMatch) {
|
|
67
|
+
inferredTab = tabMatch[1].toLowerCase();
|
|
68
|
+
parts = parts.slice(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
63
71
|
const cleanRelativePath = parts.join("/");
|
|
64
72
|
let cleanRoutePath;
|
|
65
73
|
if (data.permalink) {
|
|
@@ -93,15 +101,17 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
93
101
|
const level = match[1].length;
|
|
94
102
|
const text = match[2].replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/[_*`]/g, "").trim();
|
|
95
103
|
const id = slugger.slug(text);
|
|
96
|
-
headings.push({ level, text
|
|
104
|
+
headings.push({ level, text, id });
|
|
97
105
|
}
|
|
98
|
-
const sanitizedTitle = data.title ?
|
|
99
|
-
let sanitizedDescription = data.description ?
|
|
106
|
+
const sanitizedTitle = data.title ? data.title : inferredTitle;
|
|
107
|
+
let sanitizedDescription = data.description ? data.description : "";
|
|
100
108
|
if (!sanitizedDescription && content) {
|
|
101
109
|
const summary = content.replace(/^#+.*$/gm, "").replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/[_*`]/g, "").replace(/\n+/g, " ").trim().slice(0, 160);
|
|
102
|
-
sanitizedDescription =
|
|
110
|
+
sanitizedDescription = summary;
|
|
103
111
|
}
|
|
104
|
-
const sanitizedBadge = data.badge ?
|
|
112
|
+
const sanitizedBadge = data.badge ? data.badge : void 0;
|
|
113
|
+
const icon = data.icon ? String(data.icon) : void 0;
|
|
114
|
+
const plainText = content.replace(/^#+.*$/gm, "").replace(/\[([^\]]+)\]\([^\)]+\)/g, "$1").replace(/<[^>]+>/g, "").replace(/\{[^\}]+\}/g, "").replace(/[_*`]/g, "").replace(/\n+/g, " ").trim();
|
|
105
115
|
return {
|
|
106
116
|
route: {
|
|
107
117
|
path: finalPath,
|
|
@@ -113,15 +123,18 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
113
123
|
headings,
|
|
114
124
|
locale,
|
|
115
125
|
version,
|
|
116
|
-
badge: sanitizedBadge
|
|
126
|
+
badge: sanitizedBadge,
|
|
127
|
+
icon,
|
|
128
|
+
tab: inferredTab,
|
|
129
|
+
_content: plainText
|
|
117
130
|
},
|
|
118
131
|
relativeDir: cleanDirName,
|
|
119
132
|
isGroupIndex,
|
|
133
|
+
inferredTab,
|
|
120
134
|
groupMeta: isGroupIndex ? {
|
|
121
|
-
title:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
position: data.groupPosition ?? data.sidebarPosition ?? (rawDirName ? extractNumberPrefix(rawDirName) : void 0)
|
|
135
|
+
title: data.groupTitle || data.title || (cleanDirName ? capitalize(cleanDirName) : ""),
|
|
136
|
+
position: data.groupPosition ?? data.sidebarPosition ?? (rawDirName ? extractNumberPrefix(rawDirName) : void 0),
|
|
137
|
+
icon
|
|
125
138
|
} : void 0,
|
|
126
139
|
inferredGroupPosition: rawDirName ? extractNumberPrefix(rawDirName) : void 0
|
|
127
140
|
};
|
|
@@ -157,6 +170,7 @@ function compareByGroupPosition(a, b) {
|
|
|
157
170
|
// src/node/routes/index.ts
|
|
158
171
|
async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
159
172
|
docCache.load();
|
|
173
|
+
docCache.invalidateAll();
|
|
160
174
|
const files = await fastGlob(["**/*.md", "**/*.mdx"], {
|
|
161
175
|
cwd: docsDir,
|
|
162
176
|
absolute: true
|
|
@@ -190,13 +204,17 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
190
204
|
if (!groupMeta.has(p.relativeDir)) {
|
|
191
205
|
groupMeta.set(p.relativeDir, {
|
|
192
206
|
title: capitalize(p.relativeDir),
|
|
193
|
-
position: p.inferredGroupPosition
|
|
207
|
+
position: p.inferredGroupPosition,
|
|
208
|
+
icon: p.route.icon
|
|
194
209
|
});
|
|
195
210
|
} else {
|
|
196
211
|
const entry = groupMeta.get(p.relativeDir);
|
|
197
212
|
if (entry.position === void 0 && p.inferredGroupPosition !== void 0) {
|
|
198
213
|
entry.position = p.inferredGroupPosition;
|
|
199
214
|
}
|
|
215
|
+
if (!entry.icon && p.route.icon) {
|
|
216
|
+
entry.icon = p.route.icon;
|
|
217
|
+
}
|
|
200
218
|
}
|
|
201
219
|
}
|
|
202
220
|
if (p.isGroupIndex && p.relativeDir && p.groupMeta) {
|
|
@@ -205,6 +223,9 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
205
223
|
if (p.groupMeta.position !== void 0) {
|
|
206
224
|
entry.position = p.groupMeta.position;
|
|
207
225
|
}
|
|
226
|
+
if (p.groupMeta.icon) {
|
|
227
|
+
entry.icon = p.groupMeta.icon;
|
|
228
|
+
}
|
|
208
229
|
}
|
|
209
230
|
}
|
|
210
231
|
const routes = parsed.map((p) => {
|
|
@@ -214,7 +235,8 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
214
235
|
...p.route,
|
|
215
236
|
group: dir,
|
|
216
237
|
groupTitle: meta?.title || (dir ? capitalize(dir) : void 0),
|
|
217
|
-
groupPosition: meta?.position
|
|
238
|
+
groupPosition: meta?.position,
|
|
239
|
+
groupIcon: meta?.icon
|
|
218
240
|
};
|
|
219
241
|
});
|
|
220
242
|
if (config?.i18n) {
|
|
@@ -375,7 +397,7 @@ var _filename = fileURLToPath(import.meta.url);
|
|
|
375
397
|
var _dirname = path3.dirname(_filename);
|
|
376
398
|
var _require = createRequire(import.meta.url);
|
|
377
399
|
async function generateStaticPages(options) {
|
|
378
|
-
const { docsDir, outDir, config } = options;
|
|
400
|
+
const { docsDir, docsDirName, outDir, config } = options;
|
|
379
401
|
const routes = await generateRoutes(docsDir, config);
|
|
380
402
|
const siteTitle = config?.themeConfig?.title || "Boltdocs";
|
|
381
403
|
const siteDescription = config?.themeConfig?.description || "";
|
|
@@ -407,6 +429,7 @@ async function generateStaticPages(options) {
|
|
|
407
429
|
path: route.path,
|
|
408
430
|
routes,
|
|
409
431
|
config: config || {},
|
|
432
|
+
docsDirName,
|
|
410
433
|
modules: fakeModules,
|
|
411
434
|
homePage: void 0
|
|
412
435
|
// No custom home page for now
|
|
@@ -440,9 +463,10 @@ async function generateStaticPages(options) {
|
|
|
440
463
|
}
|
|
441
464
|
|
|
442
465
|
// src/node/plugin/index.ts
|
|
443
|
-
import
|
|
466
|
+
import path5 from "path";
|
|
444
467
|
|
|
445
468
|
// src/node/plugin/entry.ts
|
|
469
|
+
import path4 from "path";
|
|
446
470
|
function generateEntryCode(options, config) {
|
|
447
471
|
const homeImport = options.homePage ? `import HomePage from '${normalizePath(options.homePage)}';` : "";
|
|
448
472
|
const homeOption = options.homePage ? "homePage: HomePage," : "";
|
|
@@ -451,11 +475,12 @@ function generateEntryCode(options, config) {
|
|
|
451
475
|
const componentImports = pluginComponents.map(
|
|
452
476
|
([
|
|
453
477
|
name,
|
|
454
|
-
|
|
455
|
-
]) => `import * as _comp_${name} from '${normalizePath(
|
|
478
|
+
path6
|
|
479
|
+
]) => `import * as _comp_${name} from '${normalizePath(path6)}';
|
|
456
480
|
const ${name} = _comp_${name}.default || _comp_${name}['${name}'] || _comp_${name};`
|
|
457
481
|
).join("\n");
|
|
458
482
|
const componentMap = pluginComponents.map(([name]) => name).join(", ");
|
|
483
|
+
const docsDirName = path4.basename(options.docsDir || "docs");
|
|
459
484
|
return `
|
|
460
485
|
import { createBoltdocsApp as _createApp } from 'boltdocs/client';
|
|
461
486
|
import 'boltdocs/style.css';
|
|
@@ -468,8 +493,9 @@ ${componentImports}
|
|
|
468
493
|
_createApp({
|
|
469
494
|
target: '#root',
|
|
470
495
|
routes: _routes,
|
|
496
|
+
docsDirName: '${docsDirName}',
|
|
471
497
|
config: _config,
|
|
472
|
-
modules: import.meta.glob('
|
|
498
|
+
modules: import.meta.glob('/${docsDirName}/**/*.{md,mdx}'),
|
|
473
499
|
hot: import.meta.hot,
|
|
474
500
|
${homeOption}
|
|
475
501
|
components: { ${componentMap} },
|
|
@@ -522,7 +548,7 @@ ${themeScript} </head>`);
|
|
|
522
548
|
|
|
523
549
|
// src/node/plugin/index.ts
|
|
524
550
|
function boltdocsPlugin(options = {}, passedConfig) {
|
|
525
|
-
const docsDir =
|
|
551
|
+
const docsDir = path5.resolve(process.cwd(), options.docsDir || "docs");
|
|
526
552
|
const normalizedDocsDir = normalizePath(docsDir);
|
|
527
553
|
let config = passedConfig;
|
|
528
554
|
let viteConfig;
|
|
@@ -552,7 +578,7 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
552
578
|
},
|
|
553
579
|
configureServer(server) {
|
|
554
580
|
const configPaths = CONFIG_FILES.map(
|
|
555
|
-
(c) =>
|
|
581
|
+
(c) => path5.resolve(process.cwd(), c)
|
|
556
582
|
);
|
|
557
583
|
server.watcher.add(configPaths);
|
|
558
584
|
const handleFileEvent = async (file, type) => {
|
|
@@ -615,8 +641,9 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
615
641
|
},
|
|
616
642
|
async closeBundle() {
|
|
617
643
|
if (!isBuild) return;
|
|
618
|
-
const outDir = viteConfig?.build?.outDir ?
|
|
619
|
-
|
|
644
|
+
const outDir = viteConfig?.build?.outDir ? path5.resolve(viteConfig.root, viteConfig.build.outDir) : path5.resolve(process.cwd(), "dist");
|
|
645
|
+
const docsDirName = path5.basename(docsDir || "docs");
|
|
646
|
+
await generateStaticPages({ docsDir, docsDirName, outDir, config });
|
|
620
647
|
const { flushCache } = await import("../cache-KNL5B4EE.mjs");
|
|
621
648
|
await flushCache();
|
|
622
649
|
}
|
|
@@ -33,6 +33,19 @@ interface ComponentRoute {
|
|
|
33
33
|
locale?: string;
|
|
34
34
|
/** The version this route belongs to, if versioning is configured */
|
|
35
35
|
version?: string;
|
|
36
|
+
/** Optional icon to display (Lucide icon name or raw SVG) */
|
|
37
|
+
icon?: string;
|
|
38
|
+
/** The tab this route belongs to, if tabs are configured */
|
|
39
|
+
tab?: string;
|
|
40
|
+
/** Optional badge to display next to the sidebar item */
|
|
41
|
+
badge?: string | {
|
|
42
|
+
text: string;
|
|
43
|
+
expires?: string;
|
|
44
|
+
};
|
|
45
|
+
/** Optional icon for the route's group */
|
|
46
|
+
groupIcon?: string;
|
|
47
|
+
/** The extracted plain-text content of the page for search indexing */
|
|
48
|
+
_content?: string;
|
|
36
49
|
}
|
|
37
50
|
/**
|
|
38
51
|
* Configuration options for initializing the Boltdocs client app.
|
|
@@ -42,6 +55,8 @@ interface CreateBoltdocsAppOptions {
|
|
|
42
55
|
target: string;
|
|
43
56
|
/** Initial routes generated by the Vite plugin (`virtual:boltdocs-routes`) */
|
|
44
57
|
routes: ComponentRoute[];
|
|
58
|
+
/** The name of the documentation directory (e.g. 'docs') */
|
|
59
|
+
docsDirName: string;
|
|
45
60
|
/** Site configuration (`virtual:boltdocs-config`) */
|
|
46
61
|
config: any;
|
|
47
62
|
/** Dynamic import mapping from `import.meta.glob` for the documentation pages */
|
|
@@ -33,6 +33,19 @@ interface ComponentRoute {
|
|
|
33
33
|
locale?: string;
|
|
34
34
|
/** The version this route belongs to, if versioning is configured */
|
|
35
35
|
version?: string;
|
|
36
|
+
/** Optional icon to display (Lucide icon name or raw SVG) */
|
|
37
|
+
icon?: string;
|
|
38
|
+
/** The tab this route belongs to, if tabs are configured */
|
|
39
|
+
tab?: string;
|
|
40
|
+
/** Optional badge to display next to the sidebar item */
|
|
41
|
+
badge?: string | {
|
|
42
|
+
text: string;
|
|
43
|
+
expires?: string;
|
|
44
|
+
};
|
|
45
|
+
/** Optional icon for the route's group */
|
|
46
|
+
groupIcon?: string;
|
|
47
|
+
/** The extracted plain-text content of the page for search indexing */
|
|
48
|
+
_content?: string;
|
|
36
49
|
}
|
|
37
50
|
/**
|
|
38
51
|
* Configuration options for initializing the Boltdocs client app.
|
|
@@ -42,6 +55,8 @@ interface CreateBoltdocsAppOptions {
|
|
|
42
55
|
target: string;
|
|
43
56
|
/** Initial routes generated by the Vite plugin (`virtual:boltdocs-routes`) */
|
|
44
57
|
routes: ComponentRoute[];
|
|
58
|
+
/** The name of the documentation directory (e.g. 'docs') */
|
|
59
|
+
docsDirName: string;
|
|
45
60
|
/** Site configuration (`virtual:boltdocs-config`) */
|
|
46
61
|
config: any;
|
|
47
62
|
/** Dynamic import mapping from `import.meta.glob` for the documentation pages */
|