boltdocs 2.6.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/bin/boltdocs.js +0 -1
  2. package/dist/cache-CQKlT4fI.mjs +6 -0
  3. package/dist/cache-DorPMFgW.cjs +6 -0
  4. package/dist/cards-BLoSiRuL.d.ts +30 -0
  5. package/dist/cards-CQn9mXZS.d.cts +30 -0
  6. package/dist/chunk-Ds5LZdWN.cjs +6 -0
  7. package/dist/client/index.cjs +1 -1
  8. package/dist/client/index.d.cts +173 -1328
  9. package/dist/client/index.d.ts +172 -1327
  10. package/dist/client/index.js +1 -1
  11. package/dist/{package-c99Cs7mD.cjs → client/mdx.cjs} +1 -1
  12. package/dist/client/mdx.d.cts +128 -0
  13. package/dist/client/mdx.d.ts +129 -0
  14. package/dist/client/mdx.js +6 -0
  15. package/dist/client/primitives.cjs +6 -0
  16. package/dist/client/primitives.d.cts +818 -0
  17. package/dist/client/primitives.d.ts +818 -0
  18. package/dist/client/primitives.js +6 -0
  19. package/dist/client/theme/neutral.css +74 -361
  20. package/dist/client/theme/reset.css +189 -0
  21. package/dist/docs-layout-BlDhcQRv.cjs +6 -0
  22. package/dist/docs-layout-BvAOWEJw.js +6 -0
  23. package/dist/doctor-BQiQhCTl.cjs +6 -0
  24. package/dist/doctor-COpf35L2.cjs +20 -0
  25. package/dist/doctor-Dh1XP7Pz.mjs +20 -0
  26. package/dist/generator-DGW6pkCC.cjs +22 -0
  27. package/dist/generator-Dv3wEmhZ.mjs +22 -0
  28. package/dist/icons-dev-CrQLjoQp.js +6 -0
  29. package/dist/icons-dev-rzdz6Lf3.cjs +6 -0
  30. package/dist/image-BkIfa9oo.js +6 -0
  31. package/dist/image-DIGjCPe6.cjs +6 -0
  32. package/dist/mdx-K0WYBAJ3.js +7 -0
  33. package/dist/mdx-hpErbRUe.cjs +7 -0
  34. package/dist/meta-loader-0gJ4PtBC.cjs +6 -0
  35. package/dist/meta-loader-9IpAHWDS.mjs +6 -0
  36. package/dist/node/cli-entry.cjs +1 -2
  37. package/dist/node/cli-entry.mjs +1 -2
  38. package/dist/node/index.cjs +1 -1
  39. package/dist/node/index.d.cts +66 -13
  40. package/dist/node/index.d.mts +66 -14
  41. package/dist/node/index.mjs +1 -1
  42. package/dist/node/routes/worker.cjs +6 -0
  43. package/dist/node/routes/worker.d.cts +2 -0
  44. package/dist/node/routes/worker.d.mts +2 -0
  45. package/dist/node/routes/worker.mjs +6 -0
  46. package/dist/node-C2nWXElP.mjs +112 -0
  47. package/dist/node-CinkUtxV.cjs +112 -0
  48. package/dist/package-BMYLDBBP.cjs +6 -0
  49. package/dist/{package-DukYeKmD.mjs → package-HegMOTL_.mjs} +1 -1
  50. package/dist/parser-Bh11BsdA.cjs +6 -0
  51. package/dist/parser-D8eQvE7N.mjs +6 -0
  52. package/dist/parser-DYRzXWmA.cjs +6 -0
  53. package/dist/routes-CHf76Ye4.cjs +6 -0
  54. package/dist/routes-CMUZGI6T.mjs +6 -0
  55. package/dist/routes-Co1mRM58.cjs +6 -0
  56. package/dist/search-dialog-BACuzoVX.cjs +6 -0
  57. package/dist/search-dialog-BKagVT17.js +6 -0
  58. package/dist/search-dialog-C8w12eUx.js +6 -0
  59. package/dist/search-dialog-CGyrozZE.cjs +6 -0
  60. package/dist/search-dialog-D26rUnJ_.cjs +6 -0
  61. package/dist/sidebar-DKvg6KOc.d.cts +491 -0
  62. package/dist/sidebar-Dr1TiRIy.d.ts +491 -0
  63. package/dist/utils-BxNAXhZZ.mjs +7 -0
  64. package/dist/utils-Clzu7jvb.cjs +7 -0
  65. package/dist/worker-pool-Bd8Y9KDv.mjs +6 -0
  66. package/dist/worker-pool-BwU8ckrg.cjs +6 -0
  67. package/package.json +27 -8
  68. package/src/client/app/doc-page.tsx +9 -5
  69. package/src/client/app/docs-layout.tsx +17 -3
  70. package/src/client/app/head.tsx +122 -0
  71. package/src/client/app/helmet-compat.tsx +36 -0
  72. package/src/client/app/mdx-component.tsx +5 -52
  73. package/src/client/app/mdx-components-context.tsx +32 -8
  74. package/src/client/app/routes-context.tsx +2 -2
  75. package/src/client/app/scroll-handler.tsx +1 -1
  76. package/src/client/app/theme-context.tsx +5 -5
  77. package/src/client/app/ui-context.tsx +42 -0
  78. package/src/client/components/docs-layout-default.tsx +85 -0
  79. package/src/client/components/icons-dev.tsx +38 -15
  80. package/src/client/components/mdx/callout.tsx +97 -0
  81. package/src/client/components/mdx/card.tsx +73 -98
  82. package/src/client/components/mdx/cards.tsx +27 -0
  83. package/src/client/components/mdx/code-block.tsx +37 -17
  84. package/src/client/components/mdx/field.tsx +24 -56
  85. package/src/client/components/mdx/image.tsx +36 -15
  86. package/src/client/components/mdx/index.ts +19 -53
  87. package/src/client/components/mdx/table.tsx +46 -148
  88. package/src/client/components/mdx/typographics.tsx +120 -0
  89. package/src/client/components/mdx/{hooks/use-code-block.ts → use-code-block.ts} +5 -7
  90. package/src/client/components/primitives/breadcrumbs.tsx +5 -24
  91. package/src/client/components/primitives/button.tsx +3 -142
  92. package/src/client/components/primitives/code-block.tsx +104 -97
  93. package/src/client/components/{docs-layout.tsx → primitives/docs-layout.tsx} +15 -24
  94. package/src/client/components/primitives/error-boundary.tsx +107 -0
  95. package/src/client/components/primitives/heading.tsx +128 -0
  96. package/src/client/components/primitives/helpers/observer.ts +62 -32
  97. package/src/client/components/primitives/image.tsx +26 -0
  98. package/src/client/components/primitives/link.tsx +50 -52
  99. package/src/client/components/primitives/menu.tsx +25 -49
  100. package/src/client/components/primitives/navbar.tsx +234 -59
  101. package/src/client/components/primitives/on-this-page.tsx +169 -40
  102. package/src/client/components/primitives/page-nav.tsx +11 -39
  103. package/src/client/components/primitives/popover.tsx +12 -30
  104. package/src/client/components/primitives/search-dialog.tsx +77 -71
  105. package/src/client/components/primitives/sidebar.tsx +312 -119
  106. package/src/client/components/primitives/skeleton.tsx +1 -1
  107. package/src/client/components/primitives/tabs.tsx +5 -16
  108. package/src/client/components/primitives/tooltip.tsx +1 -1
  109. package/src/client/components/ui-base/banner.tsx +66 -0
  110. package/src/client/components/ui-base/breadcrumbs.tsx +26 -20
  111. package/src/client/components/ui-base/copy-markdown.tsx +43 -35
  112. package/src/client/components/ui-base/error-boundary.tsx +9 -46
  113. package/src/client/components/ui-base/github-stars.tsx +5 -3
  114. package/src/client/components/ui-base/index.ts +3 -3
  115. package/src/client/components/ui-base/last-updated.tsx +27 -0
  116. package/src/client/components/ui-base/navbar.tsx +183 -89
  117. package/src/client/components/ui-base/not-found.tsx +11 -9
  118. package/src/client/components/ui-base/on-this-page.tsx +8 -104
  119. package/src/client/components/ui-base/page-nav.tsx +23 -9
  120. package/src/client/components/ui-base/search-dialog.tsx +111 -36
  121. package/src/client/components/ui-base/search-highlight.tsx +10 -0
  122. package/src/client/components/ui-base/sidebar.tsx +77 -154
  123. package/src/client/components/ui-base/tabs.tsx +20 -7
  124. package/src/client/components/ui-base/theme-toggle.tsx +88 -10
  125. package/src/client/components/ui-base/version-i18n.tsx +80 -0
  126. package/src/client/hooks/index.ts +2 -1
  127. package/src/client/hooks/use-analytics.ts +272 -0
  128. package/src/client/hooks/use-i18n.ts +120 -53
  129. package/src/client/hooks/use-localized-to.ts +70 -30
  130. package/src/client/hooks/use-navbar.ts +69 -39
  131. package/src/client/hooks/use-page-nav.ts +28 -25
  132. package/src/client/hooks/use-routes.ts +64 -81
  133. package/src/client/hooks/use-search-highlight.ts +185 -0
  134. package/src/client/hooks/use-search.ts +12 -3
  135. package/src/client/hooks/use-sidebar.ts +183 -77
  136. package/src/client/hooks/use-tabs.ts +3 -4
  137. package/src/client/hooks/use-version.ts +46 -18
  138. package/src/client/index.ts +13 -86
  139. package/src/client/mdx.ts +2 -0
  140. package/src/client/primitives.ts +19 -0
  141. package/src/client/ssg/boltdocs-shell.tsx +78 -57
  142. package/src/client/ssg/create-routes.tsx +290 -50
  143. package/src/client/ssg/mdx-page.tsx +2 -1
  144. package/src/client/store/boltdocs-context.tsx +83 -12
  145. package/src/client/theme/neutral.css +74 -361
  146. package/src/client/theme/reset.css +189 -0
  147. package/src/client/types.ts +10 -2
  148. package/src/client/utils/path.ts +9 -0
  149. package/src/client/utils/react-to-text.ts +24 -24
  150. package/src/client/virtual.d.ts +1 -1
  151. package/src/shared/types.ts +97 -21
  152. package/dist/node-CWN8U_p8.mjs +0 -88
  153. package/dist/node-D5iosYXv.cjs +0 -88
  154. package/dist/search-dialog-3lvKsbVG.js +0 -6
  155. package/dist/search-dialog-DMK5OpgH.cjs +0 -6
  156. package/dist/use-search-C9bxCqfF.js +0 -6
  157. package/dist/use-search-DcfZSunO.cjs +0 -6
  158. package/src/client/components/mdx/admonition.tsx +0 -91
  159. package/src/client/components/mdx/badge.tsx +0 -41
  160. package/src/client/components/mdx/button.tsx +0 -35
  161. package/src/client/components/mdx/component-preview.tsx +0 -37
  162. package/src/client/components/mdx/component-props.tsx +0 -83
  163. package/src/client/components/mdx/file-tree.tsx +0 -325
  164. package/src/client/components/mdx/hooks/use-component-preview.ts +0 -16
  165. package/src/client/components/mdx/hooks/useTable.ts +0 -74
  166. package/src/client/components/mdx/hooks/useTabs.ts +0 -68
  167. package/src/client/components/mdx/link.tsx +0 -38
  168. package/src/client/components/mdx/list.tsx +0 -192
  169. package/src/client/components/mdx/tabs.tsx +0 -135
  170. package/src/client/components/mdx/video.tsx +0 -68
  171. package/src/client/components/primitives/index.ts +0 -19
  172. package/src/client/components/primitives/navigation-menu.tsx +0 -114
  173. package/src/client/components/ui-base/head.tsx +0 -76
  174. package/src/client/components/ui-base/loading.tsx +0 -57
  175. package/src/client/components/ui-base/powered-by.tsx +0 -25
  176. package/src/client/hooks/use-onthispage.ts +0 -23
  177. package/src/client/utils/use-on-change.ts +0 -15
@@ -0,0 +1,189 @@
1
+ @layer base {
2
+ *,
3
+ *::before,
4
+ *::after {
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ html,
9
+ body {
10
+ margin: 0;
11
+ padding: 0;
12
+ min-height: 100%;
13
+ overflow-x: hidden;
14
+ }
15
+
16
+ body {
17
+ @apply bg-main text-body antialiased;
18
+ font-family: var(--font-sans);
19
+ line-height: 1.7;
20
+ }
21
+
22
+ a {
23
+ text-decoration: none;
24
+ }
25
+
26
+ /* Scroll-margin-top for anchor scrolling */
27
+ h1,
28
+ h2,
29
+ h3,
30
+ h4,
31
+ h5,
32
+ h6 {
33
+ scroll-margin-top: 6rem;
34
+ }
35
+
36
+ /* Scrollbar */
37
+ ::-webkit-scrollbar {
38
+ width: 6px;
39
+ height: 6px;
40
+ }
41
+
42
+ ::-webkit-scrollbar-track {
43
+ background: transparent;
44
+ }
45
+
46
+ ::-webkit-scrollbar-thumb {
47
+ background-color: var(--color-strong);
48
+ border-radius: 9999px;
49
+ }
50
+
51
+ ::-webkit-scrollbar-thumb:hover {
52
+ background-color: var(--color-muted);
53
+ }
54
+
55
+ /* ═══ Content Area ═══ */
56
+ .boltdocs-content {
57
+ scrollbar-width: none;
58
+ }
59
+
60
+ .boltdocs-content::-webkit-scrollbar {
61
+ display: none;
62
+ }
63
+
64
+ /* ═══ MDX Page - Mobile Text Overflow Prevention ═══ */
65
+ .boltdocs-page {
66
+ overflow-wrap: break-word;
67
+ word-break: break-word;
68
+ }
69
+
70
+ /* Inline code inside prose shouldn't force horizontal overflow */
71
+ .boltdocs-page :not(pre) > code {
72
+ word-break: break-all;
73
+ }
74
+
75
+ .scrollbar-hide {
76
+ scrollbar-width: none;
77
+ -ms-overflow-style: none;
78
+ }
79
+
80
+ .scrollbar-hide::-webkit-scrollbar {
81
+ display: none;
82
+ }
83
+
84
+ /* Hide native search cancel button */
85
+ input::-webkit-search-cancel-button,
86
+ input::-webkit-search-decoration,
87
+ input::-webkit-search-results-button,
88
+ input::-webkit-search-results-decoration {
89
+ display: none;
90
+ }
91
+
92
+ /* Shiki Styles are defined below */
93
+
94
+ /* ═══ Shiki Styles ═══ */
95
+
96
+ /* Shiki Light/Dark Mode */
97
+ :root .shiki,
98
+ :root .shiki span {
99
+ font-family: var(--font-mono);
100
+ font-size: 12px !important;
101
+ background-color: transparent !important;
102
+ }
103
+
104
+ :root.dark .shiki,
105
+ :root.dark .shiki span {
106
+ color: var(--shiki-dark) !important;
107
+ }
108
+
109
+ /* Base Shiki Pre & Span Styles */
110
+ pre.shiki {
111
+ @apply py-2 text-[12px] leading-[1.6];
112
+ overflow-x: auto;
113
+ -webkit-overflow-scrolling: touch;
114
+ }
115
+
116
+ pre.shiki span.line {
117
+ @apply relative block px-4 py-0;
118
+ min-height: 1.6em;
119
+ }
120
+
121
+ /* Shiki Word Wrap */
122
+ pre.shiki-word-wrap {
123
+ @apply whitespace-pre-wrap break-words;
124
+ }
125
+
126
+ pre.shiki-word-wrap span.line {
127
+ @apply block w-full;
128
+ }
129
+
130
+ /* Shiki Line Numbers */
131
+ pre.shiki-line-numbers code {
132
+ counter-reset: step;
133
+ counter-increment: step 0;
134
+ }
135
+
136
+ pre.shiki-line-numbers .line {
137
+ @apply !pl-12;
138
+ }
139
+
140
+ /* Hide the last line if it is completely empty to avoid extra numbers or spacing */
141
+ pre.shiki .line:last-child:empty,
142
+ pre.shiki .line:last-child:has(> :empty),
143
+ pre.shiki-line-numbers .line:last-child:empty,
144
+ pre.shiki-line-numbers .line:last-child:has(> :empty) {
145
+ display: none;
146
+ }
147
+
148
+ pre.shiki-line-numbers .line::before {
149
+ counter-increment: step;
150
+ content: counter(step);
151
+ @apply absolute left-0 top-0 inline-flex w-10 justify-end pr-3;
152
+ @apply text-[11px] text-muted opacity-30 select-none;
153
+ line-height: inherit;
154
+ /* Sync with line text */
155
+ }
156
+
157
+ /* Shiki Highlight */
158
+ pre span.shiki-line-highlight {
159
+ @apply relative z-0 inline-block w-full;
160
+
161
+ &::after {
162
+ content: "";
163
+ @apply absolute top-0 left-0 -z-10 h-full w-full border-l-2 border-primary-500 !bg-primary-500/10 opacity-100;
164
+ }
165
+ }
166
+
167
+ /* Shiki Notation Diff */
168
+ pre.has-diff span.line.diff {
169
+ @apply relative inline-block w-full;
170
+ }
171
+
172
+ pre.has-diff span.line.diff.add {
173
+ @apply !bg-emerald-500/10 dark:!bg-emerald-500/10;
174
+
175
+ &::before {
176
+ content: "+";
177
+ @apply absolute left-2 text-emerald-500 font-bold;
178
+ }
179
+ }
180
+
181
+ pre.has-diff span.line.diff.remove {
182
+ @apply !bg-danger-500/10 opacity-70;
183
+
184
+ &::before {
185
+ content: "-";
186
+ @apply absolute left-2 text-danger-500 font-bold;
187
+ }
188
+ }
189
+ }
@@ -1,3 +1,4 @@
1
+ import type * as React from 'react'
1
2
  export type { BoltdocsConfig } from '../shared/types'
2
3
 
3
4
  /**
@@ -45,6 +46,14 @@ export interface ComponentRoute {
45
46
  _content?: string
46
47
  /** The raw markdown content of the page */
47
48
  _rawContent?: string
49
+ /** The publication date */
50
+ date?: string | Date
51
+ /** The last updated timestamp or date */
52
+ lastUpdated?: string | number | Date
53
+ /** Raw extensible frontmatter data for custom components and formatters */
54
+ frontmatter?: Record<string, any>
55
+ /** Clean URL segments stripped of locale/version prefixes */
56
+ slugParts?: string[]
48
57
  }
49
58
 
50
59
  /**
@@ -99,10 +108,9 @@ export interface LayoutProps {
99
108
  * Unified type for navbar links.
100
109
  */
101
110
  export interface NavbarLink {
102
- /** Label to display (can be a string or a map of translations) */
103
111
  label: string | Record<string, string>
104
112
  href: string
105
113
  active: boolean
106
- /** Optional icon or string for external link indication */
107
114
  to?: string
115
+ items?: NavbarLink[]
108
116
  }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Normalizes a URL path by stripping any trailing slash unless it's the root path.
3
+ *
4
+ * @param p - The path to normalize.
5
+ * @returns The normalized path.
6
+ */
7
+ export function normalizePath(p: string): string {
8
+ return p.endsWith('/') && p.length > 1 ? p.slice(0, -1) : p
9
+ }
@@ -1,34 +1,34 @@
1
1
  import {
2
- isValidElement,
3
- type ReactNode,
4
- type JSXElementConstructor,
5
- } from "react";
2
+ isValidElement,
3
+ type ReactNode,
4
+ type JSXElementConstructor,
5
+ } from 'react'
6
6
 
7
7
  type ResolverMap = Map<
8
- string | JSXElementConstructor<object>,
9
- (props: object) => string
10
- >;
8
+ string | JSXElementConstructor<object>,
9
+ (props: object) => string
10
+ >
11
11
 
12
12
  const reactToText = (node: ReactNode, resolvers?: ResolverMap): string => {
13
- if (node == null || typeof node === "boolean") return "";
13
+ if (node == null || typeof node === 'boolean') return ''
14
14
 
15
- if (typeof node === "string" || typeof node === "number") return String(node);
15
+ if (typeof node === 'string' || typeof node === 'number') return String(node)
16
16
 
17
- if (Array.isArray(node))
18
- return node.map((n) => reactToText(n, resolvers)).join("");
17
+ if (Array.isArray(node))
18
+ return node.map((n) => reactToText(n, resolvers)).join('')
19
19
 
20
- if (isValidElement(node)) {
21
- const resolver = resolvers?.get(
22
- node.type as string | JSXElementConstructor<object>,
23
- );
24
- if (resolver) return resolver(node.props as object);
25
- return reactToText(
26
- (node.props as { children?: ReactNode }).children,
27
- resolvers,
28
- );
29
- }
20
+ if (isValidElement(node)) {
21
+ const resolver = resolvers?.get(
22
+ node.type as string | JSXElementConstructor<object>,
23
+ )
24
+ if (resolver) return resolver(node.props as object)
25
+ return reactToText(
26
+ (node.props as { children?: ReactNode }).children,
27
+ resolvers,
28
+ )
29
+ }
30
30
 
31
- return "";
32
- };
31
+ return ''
32
+ }
33
33
 
34
- export { reactToText };
34
+ export { reactToText }
@@ -9,7 +9,7 @@ declare module 'virtual:boltdocs-config' {
9
9
  }
10
10
 
11
11
  declare module 'virtual:boltdocs-layout' {
12
- const Layout: React.ComponentType<{ children: React.ReactNode }>
12
+ const Layout: React.ComponentType<{ children: React.ReactNode; route?: any }>
13
13
  export default Layout
14
14
  }
15
15
 
@@ -1,4 +1,5 @@
1
1
  import type { Plugin as VitePlugin } from 'vite'
2
+ import type { ComponentType } from 'react'
2
3
 
3
4
  /**
4
5
  * Represents a single social link in the configuration.
@@ -22,36 +23,40 @@ export interface BoltdocsThemeConfig {
22
23
  title?: string | Record<string, string>
23
24
  description?: string | Record<string, string>
24
25
  logo?:
25
- | string
26
- | {
27
- dark: string
28
- light: string
29
- alt?: string
30
- width?: number
31
- height?: number
32
- }
26
+ | string
27
+ | {
28
+ dark: string
29
+ light: string
30
+ alt?: string
31
+ width?: number
32
+ height?: number
33
+ }
33
34
  navbar?: Array<{
34
35
  label: string | Record<string, string>
35
36
  href: string
37
+ items?: Array<{
38
+ label: string | Record<string, string>
39
+ href: string
40
+ }>
36
41
  }>
37
42
  sidebar?: Record<string, Array<{ text: string; link: string }>>
38
- sidebarGroups?: Record<string, { title?: string; icon?: string }>
43
+ sidebarGroups?: Record<
44
+ string,
45
+ { title?: string | Record<string, string>; icon?: string }
46
+ >
39
47
  socialLinks?: BoltdocsSocialLink[]
40
48
  footer?: BoltdocsFooterConfig
41
- breadcrumbs?: boolean
42
49
  editLink?: string
43
50
  communityHelp?: string
44
51
  version?: string
45
52
  githubRepo?: string
46
53
  favicon?: string
47
- poweredBy?: boolean
48
54
  tabs?: Array<{
49
55
  id: string
50
56
  text: string | Record<string, string>
51
57
  icon?: string
52
58
  }>
53
59
  codeTheme?: ShikiTheme | { light: ShikiTheme; dark: ShikiTheme }
54
- copyMarkdown?: boolean | { text?: string; icon?: string }
55
60
  }
56
61
 
57
62
  /**
@@ -72,13 +77,13 @@ export type ShikiTheme =
72
77
  export type BoltdocsRobotsConfig =
73
78
  | string
74
79
  | {
75
- rules?: Array<{
76
- userAgent: string
77
- allow?: string | string[]
78
- disallow?: string | string[]
79
- }>
80
- sitemaps?: string[]
81
- }
80
+ rules?: Array<{
81
+ userAgent: string
82
+ allow?: string | string[]
83
+ disallow?: string | string[]
84
+ }>
85
+ sitemaps?: string[]
86
+ }
82
87
 
83
88
  /**
84
89
  * Configuration for a specific locale.
@@ -95,7 +100,7 @@ export interface BoltdocsLocaleConfig {
95
100
  */
96
101
  export interface BoltdocsI18nConfig {
97
102
  defaultLocale: string
98
- locales: Record<string, string>
103
+ locales: string[] | Record<string, string>
99
104
  localeConfigs?: Record<string, BoltdocsLocaleConfig>
100
105
  }
101
106
 
@@ -152,6 +157,37 @@ export interface BoltdocsSeoConfig {
152
157
  }
153
158
  }
154
159
 
160
+ /**
161
+ * Configuration for Google Analytics 4 (GA4).
162
+ */
163
+ export interface BoltdocsGA4Config {
164
+ measurementId: string
165
+ debug?: boolean
166
+ anonymizeIp?: boolean
167
+ sendPageView?: boolean
168
+ cookieFlags?: string
169
+ autoTrack?: {
170
+ pageViews?: boolean
171
+ downloads?: boolean
172
+ externalLinks?: boolean
173
+ search?: boolean
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Configuration for Google Tag Manager (GTM).
179
+ */
180
+ export interface BoltdocsGTMConfig {
181
+ tagId: string
182
+ dataLayerName?: string
183
+ preview?: string
184
+ }
185
+
186
+ export interface BoltdocsIntegrationsConfig {
187
+ ga4?: BoltdocsGA4Config
188
+ gtm?: BoltdocsGTMConfig
189
+ }
190
+
155
191
  /**
156
192
  * The root configuration object for Boltdocs.
157
193
  */
@@ -159,7 +195,6 @@ export interface BoltdocsConfig {
159
195
  siteUrl?: string
160
196
  docsDir?: string
161
197
  base?: string
162
- homePage?: string
163
198
  theme?: BoltdocsThemeConfig
164
199
  i18n?: BoltdocsI18nConfig
165
200
  versions?: BoltdocsVersionsConfig
@@ -167,5 +202,46 @@ export interface BoltdocsConfig {
167
202
  robots?: BoltdocsRobotsConfig
168
203
  security?: BoltdocsSecurityConfig
169
204
  seo?: BoltdocsSeoConfig
205
+ integrations?: BoltdocsIntegrationsConfig
206
+ /** Aggregated metadata from local meta.json files */
207
+ directoryMeta?: Record<string, any>
170
208
  vite?: any // Avoid pulling in entire Vite types here
171
209
  }
210
+
211
+ /**
212
+ * Global namespace for Boltdocs types that can be augmented by generated code.
213
+ * This allows for strictly typed locales and versions based on the project configuration.
214
+ */
215
+ declare global {
216
+ namespace Boltdocs {
217
+ interface Types {}
218
+ }
219
+ }
220
+
221
+ export type BoltdocsTypes = Boltdocs.Types
222
+
223
+ export type BoltdocsLocale = Boltdocs.Types extends { Locale: infer L }
224
+ ? L
225
+ : string
226
+ export type BoltdocsVersion = Boltdocs.Types extends { Version: infer V }
227
+ ? V
228
+ : string
229
+
230
+ export type UnpackMdxComponents<T> = T extends { default: infer D } ? D : T
231
+
232
+ export type TransformMdxComponents<T> = {
233
+ [K in keyof T as K extends `Frontmatter_${string}` ? never : K]: T[K]
234
+ } & {
235
+ Frontmatter: {
236
+ [K in keyof T as K extends `Frontmatter_${infer Name}` ? Name : never]: T[K]
237
+ }
238
+ }
239
+
240
+ export type BoltdocsMdxComponents = Boltdocs.Types extends {
241
+ MdxComponents: infer M
242
+ }
243
+ ? TransformMdxComponents<UnpackMdxComponents<M>>
244
+ : {
245
+ [key: string]: ComponentType<any>
246
+ Frontmatter: Record<string, ComponentType<any>>
247
+ }
@@ -1,88 +0,0 @@
1
- /**
2
- * Boltdocs - https://boltdocs.vercel.app
3
- * Copyright (c) 2026 Jesus Alcala
4
- * Licensed under the MIT License.
5
- */
6
- import e from"@vitejs/plugin-react";import t from"@tailwindcss/vite";import n from"node:path";import{fileURLToPath as r}from"node:url";import{loadConfigFromFile as i,loadEnv as a,normalizePath as o}from"vite";import s from"fast-glob";import c from"fs";import l from"gray-matter";import u from"isomorphic-dompurify";import{z as d}from"zod";import f from"path";import p from"crypto";import m from"zlib";import{promisify as h}from"util";import ee from"github-slugger";import{ViteImageOptimizer as te}from"vite-plugin-image-optimizer";import g from"node:fs";import _ from"semver";import ne from"@mdx-js/rollup";import re from"remark-gfm";import ie from"remark-frontmatter";import ae from"rehype-slug";import{visit as v}from"unist-util-visit";import{createJavaScriptRegexEngine as y}from"shiki/engine/javascript";import{createHighlighterCore as b}from"shiki/core";import x from"@shikijs/themes/github-light";import S from"@shikijs/themes/github-dark";import C from"@shikijs/themes/tokyo-night";import w from"@shikijs/themes/dracula";import oe from"@shikijs/themes/nord";import T from"@shikijs/themes/one-dark-pro";import E from"@shikijs/themes/one-light";import D from"@shikijs/langs/html";import se from"@shikijs/langs/js";import ce from"@shikijs/langs/ts";import le from"@shikijs/langs/tsx";import ue from"@shikijs/langs/css";import de from"@shikijs/langs/json";import fe from"@shikijs/langs/bash";import pe from"@shikijs/langs/markdown";import me from"@shikijs/langs/mdx";import he from"@shikijs/langs/yaml";import ge from"@shikijs/langs/rust";import _e from"@shikijs/langs/toml";const O=n.dirname(r(import.meta.url)),ve=/^[a-zA-Z0-9\-_\/\.\(\)]+$/,ye=d.object({title:d.string().max(200).optional(),description:d.string().max(500).optional(),sidebarPosition:d.number().optional(),sidebarLabel:d.string().max(100).optional(),category:d.string().max(50).optional(),order:d.number().optional(),badge:d.string().max(50).optional(),icon:d.string().max(50).optional()});var k=class e extends Error{constructor(t){super(t),this.name=`SecurityViolationError`,Object.setPrototypeOf(this,e.prototype)}},be=class e extends k{constructor(t){super(t),this.name=`PathTraversalError`,Object.setPrototypeOf(this,e.prototype)}},xe=class e extends k{constructor(t){super(t),this.name=`EncodingSecurityError`,Object.setPrototypeOf(this,e.prototype)}},A=class e extends k{constructor(t){super(t),this.name=`ValidationError`,Object.setPrototypeOf(this,e.prototype)}};function j(e){return e.replace(/\\/g,`/`)}function M(e){return e.replace(/^\d+\./,``)}function N(e){let t=e.match(/^(\d+)\./);return t?parseInt(t[1],10):void 0}function Se(e){return/\.mdx?$/.test(e)}function P(e){try{return c.statSync(e).mtimeMs}catch{return 0}}function Ce(e){let t=c.readFileSync(e,`utf-8`);try{let{data:n,content:r,matter:i}=l(t);if(i&&i.length>10240)throw R(`FRONTMATTER_TOO_LARGE`,`Frontmatter block exceeds size limit`,{size:i.length,file:e}),new A(`Security breach: Frontmatter size exceeds limit of 10240 bytes`);let a=ye.safeParse(n);a.success||console.warn(`[VALIDATION][${e}] Invalid frontmatter fields detected.`);let o={...a.success?a.data:{}};return o.title&&=I(o.title).trim(),o.description&&=I(o.description).trim(),{data:o,content:r}}catch(e){if(e instanceof A)throw e;return{data:{},content:t}}}function we(e){return e.replace(/&/g,`&amp;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}function Te(e){return we(e)}function Ee(e){let t=e.split(`/`).map(e=>M(De(e))).join(`/`).replace(/\/$/,``);return t=t.replace(/\.mdx?$/,``),(t===`index`||t.endsWith(`/index`))&&(t=t.replace(/index$/,``)),t.startsWith(`/`)||(t=`/`+t),t.length>1&&t.endsWith(`/`)&&(t=t.slice(0,-1)),t}function F(e){return u.sanitize(e,{ALLOWED_TAGS:`b.i.em.strong.a.p.br.code.pre.span.div.h1.h2.h3.h4.h5.h6.ul.ol.li.table.thead.tbody.tr.th.td.blockquote.hr`.split(`.`),ALLOWED_ATTR:[`href`,`title`,`target`,`class`,`id`,`src`,`alt`,`width`,`height`],FORCE_BODY:!0})}u.addHook(`afterSanitizeAttributes`,e=>{if(e.hasAttribute(`href`)){let t=e.getAttribute(`href`)?.toLowerCase()||``;(t.startsWith(`javascript:`)||t.startsWith(`data:`)||t.startsWith(`vbscript:`))&&e.removeAttribute(`href`)}if(e.hasAttribute(`src`)){let t=e.getAttribute(`src`)?.toLowerCase()||``;(t.startsWith(`javascript:`)||t.startsWith(`data:`)||t.startsWith(`vbscript:`))&&e.removeAttribute(`src`)}});function I(e){return u.sanitize(e,{ALLOWED_TAGS:[],KEEP_CONTENT:!0})}function L(e){return e.charAt(0).toUpperCase()+e.slice(1)}function De(e){return e.replace(/[^a-zA-Z0-9\-_\/\.]/g,``).split(`/`).filter(e=>e!==`..`&&e!==`.`).map(e=>e.replace(/\.\.+/g,`.`)).join(`/`)}function R(e,t,n={}){let r=new Date().toISOString(),i={...n};for(let e in i)typeof i[e]==`string`&&i[e].includes(`:`)&&(i[e]=i[e].split(/[\\/]/).pop()||i[e]);console.error(`[SECURITY][${r}] TYPE: ${e} | MESSAGE: ${t} | DETAILS: ${JSON.stringify(i)}`)}const z=h(c.writeFile),Oe=h(c.readFile),B=h(c.mkdir),ke=h(c.rename);h(c.unlink);const Ae=process.env.BOLTDOCS_CACHE_DIR||`.boltdocs`,je=parseInt(process.env.BOLTDOCS_CACHE_LRU_LIMIT||`2000`,10),Me=process.env.BOLTDOCS_CACHE_COMPRESS!==`0`;var Ne=class{cache=new Map;constructor(e){this.limit=e}get(e){let t=this.cache.get(e);return t!==void 0&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.limit){let e=this.cache.keys().next().value;e!==void 0&&this.cache.delete(e)}this.cache.set(e,t)}get size(){return this.cache.size}clear(){this.cache.clear()}};const V=new class{queue=Promise.resolve();pendingCount=0;add(e){this.pendingCount++,this.queue=this.queue.then(e).finally(()=>{this.pendingCount--})}async flush(){await this.queue}get pending(){return this.pendingCount}};var Pe=class{entries=new Map;cachePath=null;compress;constructor(e={}){if(this.compress=e.compress===void 0?Me:e.compress,e.name){let t=e.root||process.cwd(),n=this.compress?`json.gz`:`json`;this.cachePath=f.resolve(t,Ae,`${e.name}.${n}`)}}load(){if(process.env.BOLTDOCS_NO_CACHE!==`1`&&!(!this.cachePath||!c.existsSync(this.cachePath)))try{let e=c.readFileSync(this.cachePath);this.cachePath.endsWith(`.gz`)&&(e=m.gunzipSync(e));let t=JSON.parse(e.toString(`utf-8`));this.entries=new Map(Object.entries(t))}catch{}}save(){if(process.env.BOLTDOCS_NO_CACHE===`1`||!this.cachePath)return;let e=Object.fromEntries(this.entries),t=JSON.stringify(e),n=this.cachePath,r=this.compress;V.add(async()=>{try{await B(f.dirname(n),{recursive:!0});let e=Buffer.from(t);r&&(e=m.gzipSync(e));let i=`${n}.${p.randomBytes(4).toString(`hex`)}.tmp`;await z(i,e),await ke(i,n)}catch{}})}get(e){let t=this.entries.get(e);return!t||P(e)!==t.mtime?null:t.data}set(e,t){this.entries.set(e,{data:t,mtime:P(e)})}isValid(e){let t=this.entries.get(e);return t?P(e)===t.mtime:!1}invalidate(e){this.entries.delete(e)}invalidateAll(){this.entries.clear()}pruneStale(e){for(let t of this.entries.keys())e.has(t)||this.entries.delete(t)}get size(){return this.entries.size}async flush(){await V.flush()}},Fe=class{index=new Map;memoryCache=new Ne(je);baseDir;shardsDir;indexPath;constructor(e,t=process.cwd()){this.baseDir=f.resolve(t,Ae,`transform-${e}`),this.shardsDir=f.resolve(this.baseDir,`shards`),this.indexPath=f.resolve(this.baseDir,`index.json`)}load(){if(process.env.BOLTDOCS_NO_CACHE!==`1`&&c.existsSync(this.indexPath))try{let e=c.readFileSync(this.indexPath,`utf-8`);this.index=new Map(Object.entries(JSON.parse(e)))}catch{}}save(){if(process.env.BOLTDOCS_NO_CACHE===`1`)return;let e=JSON.stringify(Object.fromEntries(this.index)),t=this.indexPath;V.add(async()=>{await B(f.dirname(t),{recursive:!0}),await z(t,e)})}async getMany(e){let t=new Map,n=[];for(let r of e){let e=this.memoryCache.get(r);e?t.set(r,e):this.index.has(r)&&n.push(r)}if(n.length>0){let e=await Promise.all(n.map(async e=>{let t=this.index.get(e),n=f.resolve(this.shardsDir,`${t}.gz`);try{let t=await Oe(n),r=m.gunzipSync(t).toString(`utf-8`);return this.memoryCache.set(e,r),{key:e,val:r}}catch{return null}}));for(let n of e)n&&t.set(n.key,n.val)}return t}get(e){let t=this.memoryCache.get(e);if(t)return t;let n=this.index.get(e);if(!n)return null;let r=f.resolve(this.shardsDir,`${n}.gz`);if(!c.existsSync(r))return null;try{let t=c.readFileSync(r),n=m.gunzipSync(t).toString(`utf-8`);return this.memoryCache.set(e,n),n}catch{return null}}set(e,t){let n=p.createHash(`md5`).update(t).digest(`hex`);this.index.set(e,n),this.memoryCache.set(e,t);let r=f.resolve(this.shardsDir,`${n}.gz`);V.add(async()=>{if(c.existsSync(r))return;await B(this.shardsDir,{recursive:!0});let e=m.gzipSync(Buffer.from(t)),n=`${r}.${p.randomBytes(4).toString(`hex`)}.tmp`;await z(n,e),await ke(n,r)})}get size(){return this.index.size}async flush(){await V.flush()}};const H=new Pe({name:`routes`});function Ie(){H.invalidateAll()}function Le(e){H.invalidate(e)}function Re(e,t,n,r){let i;try{i=decodeURIComponent(e)}catch{let t=f.basename(e);throw R(`ENCODING_ERROR`,`Invalid character encoding`,{file:t}),new xe(`Security breach: Invalid characters or encoding in path: ${t}`)}if(i.length>260){let e=f.basename(i);throw R(`PATH_TOO_LONG`,`Path length exceeds limit`,{length:i.length,file:e}),new be(`Security breach: Path length exceeds limit of 260 characters: ${e}`)}let a=f.resolve(i),o=f.resolve(t),s=j(f.relative(o,a));if(s.startsWith(`../`)||s===`..`||a.includes(`\0`)||!ve.test(s)){let t=f.basename(e);throw R(`PATH_TRAVERSAL_ATTEMPT`,`Path traversal or invalid characters detected`,{path:s}),new be(`Security breach: File is outside of docs directory, contains null bytes, or invalid characters: ${t}`)}let{data:c,content:l}=Ce(e),u=s.split(`/`),d,p;if(r?.versions&&u.length>0){let e=u[0],t=r.versions.prefix||``,n=r.versions.versions.find(n=>e===t+n.path||e===n.path);n&&(p=n.path,u=u.slice(1))}if(r?.i18n&&u.length>0){let e=u[0];r.i18n.locales[e]&&(d=e,u=u.slice(1))}let m;if(u.length>0){let e=u[0].match(/^\((.+)\)$/);e&&(m=e[1].toLowerCase(),u=u.slice(1))}let h;u=u.map(e=>{let t=M(e);return t.startsWith(`_`)&&t!==`_`?(h=t.substring(1),e.substring(0,e.length-t.length)+t.substring(1)):e});let te=u.join(`/`),g;g=c.permalink?c.permalink.startsWith(`/`)?c.permalink:`/${c.permalink}`:Ee(te||`index.md`);let _=n;p&&(_+=`/`+p),d&&(_+=`/`+d),m&&(_+=`/`+m),_+=g===`/`?``:g,(!_||_===``)&&(_=`/`);let ne=u[u.length-1],re=M(ne),ie=M(f.basename(e,f.extname(e))),ae=c.sidebarPosition??N(ne),v=u.length>=2?u[0]:void 0,y=v?M(v):void 0,b=u.length===2&&/^index\.mdx?$/.test(re),x=new ee,S=[];for(let e of l.matchAll(/^(#{2,4})\s+(.+)$/gm)){let t=e[1].length,n=F(e[2].replace(/\[([^\]]+)\]\([^\)]+\)/g,`$1`).replace(/[_*`]/g,``).trim()).trim(),r=x.slug(n);S.push({level:t,text:n,id:r})}let C=c.title?F(String(c.title)):ie,w=c.description?F(String(c.description)):``;!w&&l&&(w=I(l.replace(/^#+.*$/gm,``).replace(/\[([^\]]+)\]\([^\)]+\)/g,`$1`).replace(/[_*`]/g,``).replace(/\s+/g,` `)).trim().slice(0,160));let oe=c.badge?F(String(c.badge)):void 0,T=c.icon?String(c.icon):void 0,E=ze(l),D={},se=[`og:`,`twitter:`,`article:`,`music:`,`video:`,`profile:`,`book:`],ce=[`noindex`,`robots`,`canonical`,`keywords`,`author`];c.seo&&typeof c.seo==`object`&&Object.assign(D,c.seo);for(let e of Object.keys(c))(ce.includes(e)||se.some(t=>e.startsWith(t)))&&(D[e]=c[e]);return c.hidden===!0&&D.noindex===void 0&&(D.noindex=!0),{route:{path:_,componentPath:e,filePath:s,title:C,description:w,sidebarPosition:ae,headings:S,locale:d,version:p,badge:oe,icon:T,tab:m,subRouteGroup:h,_content:E,_rawContent:l,seo:Object.keys(D).length>0?D:void 0},relativeDir:y,isGroupIndex:b,inferredTab:m,groupMeta:b?{title:c.groupTitle||c.title||(y?L(y):``),position:c.groupPosition??c.sidebarPosition??(v?N(v):void 0),icon:T}:void 0,inferredGroupPosition:v?N(v):void 0}}function ze(e){return I(e.replace(/^#+.*$/gm,``).replace(/\[([^\]]+)\]\([^\)]+\)/g,`$1`).replace(/\{[^\}]+\}/g,``).replace(/[_*`]/g,``).replace(/\s+/g,` `)).trim()}function Be(e){return e.sort((e,t)=>!e.group&&!t.group?Ve(e,t):e.group?t.group?e.group===t.group?Ve(e,t):He(e,t):1:-1)}function Ve(e,t){return e.sidebarPosition!==void 0&&t.sidebarPosition!==void 0?e.sidebarPosition-t.sidebarPosition:e.sidebarPosition===void 0?t.sidebarPosition===void 0?e.title.localeCompare(t.title):1:-1}function He(e,t){return e.groupPosition!==void 0&&t.groupPosition!==void 0?e.groupPosition-t.groupPosition:e.groupPosition===void 0?t.groupPosition===void 0?(e.groupTitle||e.group).localeCompare(t.groupTitle||t.group):1:-1}let U=null;const W=new Map;async function G(e,t,n=`/docs`,r=!0){H.load(),W.clear(),(process.env.BOLTDOCS_FORCE_REPARSE===`true`||t?.i18n)&&H.invalidateAll();let i;!r&&U?i=U:(i=await s([`**/*.md`,`**/*.mdx`],{cwd:e,absolute:!0,suppressErrors:!0,followSymbolicLinks:!1}),U=i),H.pruneStale(new Set(i));let a=[],o=0;for(let r=0;r<i.length;r+=50){let s=i.slice(r,r+50),c=await Promise.all(s.map(async r=>{let i=H.get(r);if(i)return o++,i;let a=Re(r,e,n,t);return H.set(r,a),a}));a.push(...c),r+50<i.length&&await new Promise(e=>setImmediate(e))}H.save();let c=new Map,l=[];for(let e of a)if(e.isGroupIndex&&e.relativeDir&&l.push(e),e.relativeDir){let t=c.get(e.relativeDir);t?t.position===void 0&&e.inferredGroupPosition!==void 0&&(t.position=e.inferredGroupPosition):(t={title:L(e.relativeDir),position:e.inferredGroupPosition},c.set(e.relativeDir,t))}for(let e of l){let t=c.get(e.relativeDir);e.groupMeta&&(t.title=e.groupMeta.title,e.groupMeta.position!==void 0&&(t.position=e.groupMeta.position),e.groupMeta.icon&&(t.icon=e.groupMeta.icon))}if(t?.theme?.sidebarGroups)for(let[e,n]of Object.entries(t.theme.sidebarGroups)){let t=c.get(e);t?(n.title&&(t.title=n.title),n.icon&&(t.icon=n.icon)):c.set(e,{title:n.title||L(e),icon:n.icon})}let u=Array(a.length);for(let e=0;e<a.length;e++){let t=a[e],n=t.relativeDir,r=n?c.get(n):void 0;u[e]={...t.route,group:n,groupTitle:r?.title||(n?L(n):void 0),groupPosition:r?.position,groupIcon:r?.icon}}let d=u;if(t?.i18n){let e=Ue(u,t,n);d=[...u,...e]}return Be(d)}function Ue(e,t,n){let r=t.i18n.defaultLocale,i=Object.keys(t.i18n.locales),a=[],o=new Map,s=[];for(let t of e){let e=t.locale||r;o.has(e)||o.set(e,new Set),o.get(e).add(t.path),e===r&&s.push(t)}for(let e of i){let i=o.get(e)||new Set;for(let o of s){let s=We(o.path,r,e,n,t);s!==o.path&&(i.has(s)||a.push({...o,path:s,locale:e}))}}return a}function We(e,t,n,r,i){let a=`${e}:${n}`,o=W.get(a);if(o)return o;let s=r;if(i?.versions){let t=i.versions.prefix||``;for(let n of i.versions.versions){let i=t+n.path;if(e.startsWith(`${r}/${i}`)){s+=`/`+i;break}if(e.startsWith(`${r}/${n.path}`)){s+=`/`+n.path;break}}}let c=e.substring(s.length),l=`/${t}`;if(c.startsWith(l+`/`))c=`/`+n+`/`+c.substring(l.length+1);else if(c===l)c=`/`+n;else if(c===`/`||c===``)c=`/`+n;else{let e=c.startsWith(`/`)?``:`/`;c=`/`+n+e+c}let u=s+c;return W.size>2e3&&W.clear(),W.set(a,u),u}function Ge(e){return e.map(e=>({path:e.path,filePath:e.filePath,title:e.title,description:e.description||``,sidebarPosition:e.sidebarPosition,badge:e.badge,icon:e.icon,headings:e.headings||[],_content:e._content||``,locale:e.locale,version:e.version,tab:e.tab,group:e.group,groupTitle:e.groupTitle,groupPosition:e.groupPosition,groupIcon:e.groupIcon,subRouteGroup:e.subRouteGroup,seo:e.seo}))}const Ke=d.object({icon:d.string().max(50),link:d.string().url()}),qe=d.object({text:d.string().max(2e3).optional()}),Je=d.enum([`fs:read`,`fs:write`,`vite:config`,`mdx:remark`,`mdx:rehype`,`components`,`hooks:build`,`hooks:dev`]),Ye=d.object({name:d.string(),enforce:d.enum([`pre`,`post`]).optional(),version:d.string().optional(),boltdocsVersion:d.string().optional(),permissions:d.array(Je).optional(),remarkPlugins:d.array(d.any()).optional(),rehypePlugins:d.array(d.any()).optional(),vitePlugins:d.array(d.any()).optional(),components:d.record(d.string(),d.string()).optional(),hooks:d.record(d.string(),d.any()).optional()}),Xe=d.object({title:d.union([d.string(),d.record(d.string(),d.string())]).optional(),description:d.union([d.string(),d.record(d.string(),d.string())]).optional(),logo:d.union([d.string(),d.object({dark:d.string(),light:d.string(),alt:d.string().optional(),width:d.number().optional(),height:d.number().optional()})]).optional(),navbar:d.array(d.object({label:d.union([d.string(),d.record(d.string(),d.string())]),href:d.string()})).optional(),sidebar:d.record(d.string(),d.array(d.object({text:d.string(),link:d.string()}))).optional(),sidebarGroups:d.record(d.string(),d.object({title:d.string().optional(),icon:d.string().optional()})).optional(),socialLinks:d.array(Ke).optional(),footer:qe.optional(),breadcrumbs:d.boolean().optional(),editLink:d.string().refine(e=>!e||e.includes(`:path`),{message:`editLink must contain ':path' placeholder if specified`}).optional(),communityHelp:d.string().url().optional(),version:d.string().max(50).optional(),githubRepo:d.string().max(100).optional(),favicon:d.string().optional(),poweredBy:d.boolean().optional(),tabs:d.array(d.object({id:d.string(),text:d.union([d.string(),d.record(d.string(),d.string())]),icon:d.string().optional()})).optional(),codeTheme:d.union([d.string(),d.object({light:d.string(),dark:d.string()})]).optional(),copyMarkdown:d.union([d.boolean(),d.object({text:d.string().optional(),icon:d.string().optional()})]).optional()}),Ze=d.union([d.string(),d.object({rules:d.array(d.object({userAgent:d.string(),allow:d.union([d.string(),d.array(d.string())]).optional(),disallow:d.union([d.string(),d.array(d.string())]).optional()})).optional(),sitemaps:d.array(d.string().url()).optional()})]),Qe=d.object({defaultLocale:d.string(),locales:d.record(d.string(),d.string()),localeConfigs:d.record(d.string(),d.object({label:d.string().optional(),direction:d.enum([`ltr`,`rtl`]).optional(),htmlLang:d.string().optional(),calendar:d.string().optional()})).optional()}),$e=d.object({defaultVersion:d.string(),prefix:d.string().optional(),versions:d.array(d.object({label:d.string(),path:d.string()}))}),et=d.object({headers:d.record(d.string(),d.string()).optional(),enableCSP:d.boolean().optional(),customHeaders:d.record(d.string(),d.string()).optional()}),tt=d.object({metatags:d.record(d.string(),d.string()).optional(),indexing:d.enum([`all`,`public`]).optional(),thumbnails:d.object({background:d.string().optional()}).optional()}),nt=d.object({siteUrl:d.string().url().optional(),docsDir:d.string().optional(),homePage:d.string().optional(),theme:Xe.optional(),i18n:Qe.optional(),versions:$e.optional(),plugins:d.array(Ye).optional(),robots:Ze.optional(),security:et.optional(),seo:tt.optional(),vite:d.record(d.string(),d.unknown()).optional()});function rt(e){return e}const K=[`boltdocs.config.js`,`boltdocs.config.mjs`,`boltdocs.config.ts`];async function q(e,t=process.cwd()){let r=t,a={docsDir:n.resolve(e),theme:{title:`Boltdocs`,description:`A Vite documentation framework`,navbar:[{label:`Home`,href:`/`},{label:`Documentation`,href:`/docs`}],codeTheme:{light:`github-light`,dark:`github-dark`},poweredBy:!0,breadcrumbs:!0}},o={};for(let e of K){let t=n.resolve(r,e);if(g.existsSync(t))try{let e=await i({command:`serve`,mode:`development`},t,r);if(e){o=e.config;break}}catch(t){console.warn(`[boltdocs] Failed to load config from ${e}:`,t)}}let s={title:o.title,description:o.description,logo:o.logo,favicon:o.favicon,navbar:o.navbar,sidebar:o.sidebar,sidebarGroups:o.theme?.sidebarGroups,socialLinks:o.socialLinks,footer:o.footer,githubRepo:o.githubRepo,tabs:o.tabs,codeTheme:o.codeTheme,copyMarkdown:o.copyMarkdown,breadcrumbs:o.breadcrumbs,poweredBy:o.poweredBy,communityHelp:o.communityHelp,version:o.version,editLink:o.editLink,...o.theme||{}},c=Object.fromEntries(Object.entries(s).filter(([e,t])=>t!==void 0));c.navbar&&=c.navbar.map(e=>({label:e.label||e.text||``,href:e.href||e.link||e.to||``}));let l={docsDir:n.resolve(e),homePage:o.homePage,theme:{...a.theme,...c},i18n:o.i18n,versions:o.versions,siteUrl:o.siteUrl,plugins:o.plugins||[],robots:o.robots,security:o.security,vite:o.vite},u=nt.safeParse(l);if(!u.success)throw new A(`Invalid Boltdocs configuration:\n${u.error.issues.map(e=>` - ${e.path.join(`.`)}: ${e.message}`).join(`
7
- `)}`);return u.data}function it(e,t){let n=(t.siteUrl||``).replace(/\/$/,``);if(!n)return``;let r=t.seo?.indexing!==`all`&&t.seo?.indexing!==`public`;return`<?xml version="1.0" encoding="UTF-8"?>
8
- <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
9
- ${e.filter(e=>e.seo?.noindex||typeof e.seo?.robots==`string`&&e.seo.robots.includes(`noindex`)?!1:(r&&e.seo?.index,!0)).map(e=>` <url>
10
- <loc>${Te(`${n}${e.path.startsWith(`/`)?e.path:`/${e.path}`}`)}</loc>
11
- <changefreq>weekly</changefreq>
12
- <priority>0.7</priority>
13
- </url>`).join(`
14
- `)}
15
- </urlset>`}function at(e){let t=e.siteUrl||``,n=t?`${t.replace(/\/$/,``)}/sitemap.xml`:``;if(e.seo?.indexing!==`all`&&e.seo?.indexing!==`public`&&e.seo?.indexing)return[`User-agent: *`,`Disallow: /`].filter(Boolean).join(`
16
- `);if(typeof e.robots==`string`)return e.robots;if(e.robots&&typeof e.robots==`object`){let t=e.robots.rules||[],r=e.robots.sitemaps||[],i=t.map(e=>{let t=`User-agent: ${e.userAgent}\n`;return e.allow&&(Array.isArray(e.allow)?t+=e.allow.map(e=>`Allow: ${e}`).join(`
17
- `)+`
18
- `:t+=`Allow: ${e.allow}\n`),e.disallow&&(Array.isArray(e.disallow)?t+=e.disallow.map(e=>`Disallow: ${e}`).join(`
19
- `)+`
20
- `:t+=`Disallow: ${e.disallow}\n`),t.trim()}).join(`
21
-
22
- `),a=[...n?[n]:[],...r].map(e=>`Sitemap: ${e}`).join(`
23
- `);return`${i}${a?`\n\n${a}`:``}`}return[`User-agent: *`,`Allow: /`,``,n?`Sitemap: ${n}`:``].filter(Boolean).join(`
24
- `)}function J(e,t){let n=e.homePage?`import HomePage from '${j(e.homePage)}';`:``,r=f.resolve(process.cwd(),`index.css`),i=c.existsSync(r)?`import './index.css';`:``,a=e.homePage?`homePage: HomePage,`:``,o=t?.plugins?.flatMap(e=>Object.entries(e.components||{}))||[],s=o.map(([e,t])=>`import * as _comp_${e} from '${j(t)}';
25
- const ${e} = _comp_${e}.default || _comp_${e}['${e}'] || _comp_${e};`).join(`
26
- `),l=o.map(([e])=>e).join(`, `),u=f.basename(e.docsDir||`docs`),d=f.resolve(process.cwd(),e.docsDir||`docs`),p=[`tsx`,`ts`,`jsx`,`js`].map(e=>f.resolve(d,`pages-external/index.${e}`)).find(e=>c.existsSync(e)),m=p?`import * as _external_module from '${j(p)}';`:``;return a=p?`homePage: _external_module.homePage || HomePage,`:e.homePage?`homePage: HomePage,`:``,`
27
- import { ViteReactSSG } from '@bdocs/ssg';
28
- import { createRoutes } from 'boltdocs/client';
29
- import _routes from 'virtual:boltdocs-routes.ts';
30
- import _config from 'virtual:boltdocs-config.ts';
31
- import _user_mdx_components from 'virtual:boltdocs-mdx-components.tsx';
32
- import _Layout from 'virtual:boltdocs-layout.tsx';
33
- ${i}
34
- ${n}
35
- ${s}
36
- ${m}
37
-
38
- const mdxModules = import.meta.glob('/${u}/**/*.{md,mdx}', { eager: true });
39
-
40
- export const createRoot = ViteReactSSG(
41
- {
42
- routes: createRoutes({
43
- routesData: _routes,
44
- config: _config,
45
- mdxModules,
46
- Layout: _Layout,
47
- ${a}
48
- ${p?`externalPages: _external_module.pages, externalLayout: _external_module.layout,`:``}
49
- components: { ${l}${l?`, `:``} ...(_user_mdx_components || {}) },
50
- }),
51
- },
52
- ({ isClient }) => {
53
- // Boltdocs initialization hook
54
- if (isClient) {
55
- // Client-side initialization
56
- }
57
- },
58
- );
59
- `}function ot(e){return`<!doctype html>
60
- <html lang="en">
61
- <head>
62
- <meta charset="UTF-8" />
63
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
64
- <title>${e.theme?.title||`Boltdocs`}</title>
65
- </head>
66
- <body>
67
- <div id="root"></div>
68
- </body>
69
- </html>`}function st(e,t){(!e||!e.includes(`<body`)||!e.includes(`<head`))&&(e=ot(t));let n=t.theme,r=n?.title||`Boltdocs`,i=n?.description||``,a=n?.favicon;!a&&n?.logo&&(a=typeof n.logo==`string`?n.logo:n.logo.light||n.logo.dark);let o=[a?`<link rel="icon" href="${a}">`:``,`<meta name="description" content="${i}">`,`<meta property="og:title" content="${r}">`,`<meta property="og:description" content="${i}">`,`<meta property="og:type" content="website">`,`<meta name="twitter:card" content="summary_large_image">`,`<meta name="twitter:title" content="${r}">`,`<meta name="twitter:description" content="${i}">`,`<meta name="generator" content="Boltdocs">`].filter(Boolean).join(`
70
- `);return e=e.includes(`<title>`)?e.replace(/<title>.*?<\/title>/,`<title>${r}</title>`):e.replace(`</head>`,` <title>${r}</title>\n </head>`),e=e.replace(`</head>`,` ${o}\n
71
- <script>
72
- (function() {
73
- try {
74
- var stored = localStorage.getItem("boltdocs-theme");
75
- var isDark =
76
- stored === "dark" ||
77
- (stored !== "light" && window.matchMedia("(prefers-color-scheme: dark)").matches);
78
- document.documentElement.classList.toggle("dark", isDark);
79
- document.documentElement.dataset.theme = isDark ? "dark" : "light";
80
- } catch (e) {}
81
- })();
82
- <\/script>
83
- </head>`),!e.includes(`src/main`)&&!e.includes(`virtual:boltdocs-entry`)&&(e=e.replace(`</body>`,` <script type="module">import "virtual:boltdocs-entry";<\/script>
84
- </body>`)),e}function ct(e){let t=[];for(let n of e)if(t.push({id:n.path,title:n.title,content:n._content||``,url:n.path,display:n.groupTitle?`${n.groupTitle} > ${n.title}`:n.title,locale:n.locale,version:n.version}),n.headings)for(let e of n.headings)t.push({id:`${n.path}#${e.id}`,title:e.text,content:`${e.text} in ${n.title}`,url:`${n.path}#${e.id}`,display:`${n.title} > ${e.text}`,locale:n.locale,version:n.version});return t}const lt={"X-Content-Type-Options":`nosniff`,"X-Frame-Options":`DENY`,"X-XSS-Protection":`1; mode=block`,"Referrer-Policy":`strict-origin-when-cross-origin`,"Permissions-Policy":`camera=(), microphone=(), geolocation=()`,"Strict-Transport-Security":`max-age=31536000; includeSubDomains`};function ut(e){let t=process.env.NODE_ENV===`development`,n={"default-src":[`'self'`],"script-src":[`'self'`,`'unsafe-inline'`],"style-src":[`'self'`,`'unsafe-inline'`],"img-src":[`'self'`,`data:`,`https:`],"font-src":[`'self'`],"connect-src":[`'self'`]};return t&&(n[`script-src`]=[`'self'`,`'unsafe-eval'`,`'unsafe-inline'`],n[`style-src`]=[`'self'`,`'unsafe-inline'`]),Object.entries(n).map(([e,t])=>`${e} ${t.join(` `)}`).join(`; `)}var Y=class e extends Error{pluginName;constructor(t,n){super(`[plugin:${t}] ${n}`),this.name=`PluginError`,this.pluginName=t,Object.setPrototypeOf(this,e.prototype)}},X=class e extends Y{constructor(t,n){super(t,`Validation failed: ${n}`),this.name=`PluginValidationError`,Object.setPrototypeOf(this,e.prototype)}},dt=class e extends Y{constructor(t,n){super(t,`Compatibility error: ${n}`),this.name=`PluginCompatibilityError`,Object.setPrototypeOf(this,e.prototype)}},ft=class e extends Y{constructor(t,n){super(t,`Missing required permission: '${n}'`),this.name=`PluginPermissionError`,Object.setPrototypeOf(this,e.prototype)}},pt=class e extends Y{hookName;constructor(t,n,r){super(t,`Error in hook '${n}': ${r.message}`),this.name=`PluginHookError`,this.hookName=n,this.stack=r.stack,Object.setPrototypeOf(this,e.prototype)}},mt=class{data=new Map;getNamespaceKey(e,t){return`${e}:${t}`}get(e,t){let n=this.getNamespaceKey(e,t),r=this.data.get(n);if(r!==void 0)return typeof r==`object`&&r?JSON.parse(JSON.stringify(r)):r}set(e,t,n){let r=this.getNamespaceKey(e,t),i=typeof n==`object`&&n?JSON.parse(JSON.stringify(n)):n;this.data.set(r,i)}has(e,t){let n=this.getNamespaceKey(e,t);return this.data.has(n)}};const ht=Ye.extend({version:d.string().optional(),boltdocsVersion:d.string().optional(),permissions:d.array(d.string()).optional(),hooks:d.object({beforeBuild:d.function().optional(),afterBuild:d.function().optional(),beforeDev:d.function().optional(),afterDev:d.function().optional(),configResolved:d.function().optional(),buildEnd:d.function().optional()}).optional()});function gt(e,t){let n=[],r=new Set;for(let i of e){let e=ht.safeParse(i);if(!e.success)throw new X(i.name||`unknown`,e.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`, `));let a=e.data;if(r.has(a.name))throw new X(a.name,`Duplicate plugin name detected`);if(r.add(a.name),a.boltdocsVersion&&!_.satisfies(t,a.boltdocsVersion))throw new dt(a.name,`Plugin expects Boltdocs version ${a.boltdocsVersion}, but current is ${t}`);if(a.components){for(let[e,t]of Object.entries(a.components))if((t.includes(`..`)||f.isAbsolute(t))&&t.includes(`..`))throw new X(a.name,`Component '${e}' has an invalid path: traversal sequences are not allowed.`)}n.push(a)}return n}function Z(e,t){return e.permissions?e.permissions.includes(t):!1}var Q=class{static checkPermission(e,t){if(!Z(e,t))throw new ft(e.name,t)}static getSanitizedCapabilities(e){return{remarkPlugins:Z(e,`mdx:remark`)?e.remarkPlugins:[],rehypePlugins:Z(e,`mdx:rehype`)?e.rehypePlugins:[],vitePlugins:Z(e,`vite:config`)?e.vitePlugins:[],components:Z(e,`components`)?e.components:{}}}static async executeWithIsolation(e,t,n,r){try{return this.checkPermission(e,t),await r()}catch(t){if(t instanceof ft){console.warn(`[boltdocs] Skipping hook '${n}' for plugin '${e.name}': ${t.message}`);return}throw t}}},_t=class{plugins;config;store;constructor(e,t){this.plugins=e,this.config=t,this.store=new mt}async runHook(e,...t){let n=this.getSortedPlugins();for(let r of n){if(!r.hooks?.[e])continue;let n=this.createContext(r),i=e.toLowerCase().includes(`build`),a=e.toLowerCase().includes(`dev`),o=i?`hooks:build`:a?`hooks:dev`:void 0;try{o?await Q.executeWithIsolation(r,o,e,()=>r.hooks[e](n,...t)):await r.hooks[e](n,...t)}catch(t){let i=new pt(r.name,e,t instanceof Error?t:Error(String(t)));n.logger.error(i)}}}getSortedPlugins(){let e=this.plugins.filter(e=>e.enforce===`pre`),t=this.plugins.filter(e=>!e.enforce),n=this.plugins.filter(e=>e.enforce===`post`);return[...e,...t,...n]}createContext(e){return{config:Object.freeze({...this.config}),meta:{name:e.name,version:e.version,boltdocsVersion:e.boltdocsVersion},store:{get:(e,t)=>this.store.get(e,t),set:(e,t,n)=>this.store.set(e,t,n),has:(e,t)=>this.store.has(e,t)},logger:this.createLogger(e.name)}}createLogger(e){let t=`[plugin:${e}]`;return{info:e=>console.log(`${t} INFO: ${e}`),warn:e=>console.warn(`${t} WARN: ${e}`),error:e=>{let n=e instanceof Error?e.message:e;console.error(`${t} ERROR: ${n}`)},debug:e=>console.debug(`${t} DEBUG: ${e}`)}}};function vt(e){return e}function yt(e={},t){let r=n.resolve(process.cwd(),e.docsDir||`docs`),i=j(r),o=t,s,c=!1,l,u=[];return[{name:`vite-plugin-boltdocs`,enforce:`pre`,async config(e,t){c=t.command===`build`;let i=e.envDir||process.cwd(),s=a(t.mode,i,``);Object.assign(process.env,s),o||=await q(r);let d=(await import(`./package-DukYeKmD.mjs`)).version,f=gt(o.plugins||[],d);return o.plugins=f,l=new _t(f,o),u=f.flatMap(e=>Q.getSanitizedCapabilities(e).vitePlugins||[]),c&&await l.runHook(`beforeBuild`),{ssgOptions:{entry:`boltdocs/entry`,htmlEntry:`index.html`,dirStyle:`nested`,includeAllRoutes:!0,mock:!0,script:`async`,beastiesOptions:{preload:`media`},onFinished:async e=>{let t=it(Ge(await G(r,o)),o);t&&g.writeFileSync(n.join(e,`sitemap.xml`),t);let i=at(o);g.writeFileSync(n.join(e,`robots.txt`),i)}},build:{ssrManifest:c},async config(){let e=O;for(;e!==n.parse(e).root&&!g.existsSync(n.join(e,`package.json`));)e=n.dirname(e);if(g.existsSync(n.join(e,`package.json`))&&JSON.parse(g.readFileSync(n.join(e,`package.json`),`utf-8`)).name!==`boltdocs`){let t=n.dirname(e);for(;t!==n.parse(t).root;){if(g.existsSync(n.join(t,`package.json`))&&JSON.parse(g.readFileSync(n.join(t,`package.json`),`utf-8`)).name===`boltdocs`){e=t;break}t=n.dirname(t)}}return{optimizeDeps:{include:[`react`,`react-dom`,`react-dom/client`,`react-router-dom`,`react-helmet-async`],exclude:[`boltdocs`,`boltdocs/client`]},resolve:{dedupe:[`react`,`react-dom`]}}}}},configResolved(e){s=e,l?.runHook(`configResolved`,o)},async configureServer(e){await l?.runHook(`beforeDev`),e.middlewares.use((e,t,n)=>{process.env.NODE_ENV===`production`&&Object.entries(lt).forEach(([e,n])=>{t.setHeader(e,n)}),o.security?.enableCSP&&t.setHeader(`Content-Security-Policy`,ut(o)),n()}),e.middlewares.use((e,t,n)=>{if(e.url===`/robots.txt`){n();return}n()}),e.middlewares.use(async(t,n,r)=>{let i=t.url?.split(`?`)[0]||`/`,a=t.headers.accept||``,s=i===`/`||i.startsWith(`/docs`)||o.i18n&&Object.keys(o.i18n.locales).some(e=>i.startsWith(`/${e}/docs`)||i===`/${e}`)||!0,c=/\.(js|css|png|jpe?g|gif|svg|ico|webp|woff2?|ttf|otf|mp4|webm|ogg|mp3|wav|flac|aac|pdf|zip|gz|map|json)$/i.test(i);if(a.includes(`text/html`)&&!c&&s){let r=ot(o);r=st(r,o),r=await e.transformIndexHtml(t.url||`/`,r),n.statusCode=200,n.setHeader(`Content-Type`,`text/html`),n.end(r);return}r()});let t=K.map(e=>n.resolve(process.cwd(),e)),a=[`tsx`,`jsx`].map(e=>n.resolve(r,`layout.${e}`)),s=[`tsx`,`ts`,`jsx`,`js`],c=s.map(e=>n.resolve(r,`mdx-components.${e}`)),u=s.map(e=>n.resolve(r,`pages-external/index.${e}`)),d=s.map(e=>n.resolve(r,`icons.${e}`));e.watcher.add([...t,...c,...a,...u,...d]);let f=async(t,n)=>{try{let a=j(t);if(K.some(e=>a.endsWith(e))){e.restart();return}if(s.some(e=>a.endsWith(`mdx-components.${e}`))){let t=e.moduleGraph.getModuleById(`\0virtual:boltdocs-mdx-components.tsx`);t&&e.moduleGraph.invalidateModule(t),e.ws.send({type:`full-reload`});return}if(s.some(e=>a.endsWith(`icons.${e}`))){let t=e.moduleGraph.getModuleById(`\0virtual:boltdocs-icons.tsx`);t&&e.moduleGraph.invalidateModule(t),e.ws.send({type:`full-reload`});return}if(a.endsWith(`layout.tsx`)||a.endsWith(`layout.jsx`)){let t=e.moduleGraph.getModuleById(`\0virtual:boltdocs-layout.tsx`);t&&e.moduleGraph.invalidateModule(t),e.ws.send({type:`full-reload`});return}if(a.includes(`/pages-external/`)||a.includes(`\\pages-external\\`)){let t=e.moduleGraph.getModuleById(`\0virtual:boltdocs-entry`);t&&e.moduleGraph.invalidateModule(t),e.ws.send({type:`full-reload`});return}if(!a.startsWith(i)||!Se(a))return;if(n===`add`||n===`unlink`){Ie(),o=await q(r);let t=e.moduleGraph.getModuleById(`\0virtual:boltdocs-config.ts`);t&&e.moduleGraph.invalidateModule(t),e.ws.send({type:`custom`,event:`boltdocs:config-update`,data:{theme:o?.theme,i18n:o?.i18n,versions:o?.versions,siteUrl:o?.siteUrl}})}else Le(t);let c=e.moduleGraph.getModuleById(`\0virtual:boltdocs-routes.ts`);c&&e.moduleGraph.invalidateModule(c);let l=e.moduleGraph.getModuleById(`\0virtual:boltdocs-config.ts`);l&&e.moduleGraph.invalidateModule(l),e.ws.send({type:`full-reload`})}catch(e){console.error(`[boltdocs] HMR error during ${n} event:`,e)}};e.watcher.on(`add`,e=>f(e,`add`)),e.watcher.on(`unlink`,e=>f(e,`unlink`)),e.watcher.on(`change`,e=>f(e,`change`)),await l?.runHook(`afterDev`)},resolveId(e){let t=s?.root||process.cwd();return e.includes(`boltdocs-entry.mjs`)||e===`virtual:boltdocs-entry`||e===`boltdocs-entry`||e===`\0virtual:boltdocs-entry`?j(n.resolve(t,`boltdocs-entry.mjs`)):e.includes(`boltdocs-client.mjs`)||e===`virtual:boltdocs-client`||e===`boltdocs-client`||e===`\0virtual:boltdocs-client.ts`?j(n.resolve(t,`boltdocs-client.mjs`)):e.startsWith(`virtual:boltdocs-`)?`\0`+e:e.startsWith(`\0virtual:boltdocs-`)?e:null},async load(t){if(t.includes(`boltdocs-entry.mjs`)||t===`\0virtual:boltdocs-entry`)return J(e,o);if(t.includes(`boltdocs-client.mjs`)||t===`\0virtual:boltdocs-client.ts`||t===`virtual:boltdocs-client`){let e=O,t=e;for(;e!==n.parse(e).root;){if(g.existsSync(n.join(e,`package.json`))&&JSON.parse(g.readFileSync(n.join(e,`package.json`),`utf-8`)).name===`boltdocs`){t=e;break}e=n.dirname(e)}let r=n.join(t,`src/client/index.ts`),i=n.join(t,`dist/client/index.js`);return`export * from '${j(g.existsSync(r)?r:i)}';`}if(!t.startsWith(`\0virtual:boltdocs-`))return;let i=t.replace(`\0virtual:boltdocs-`,``).replace(/\.tsx?$/,``);if(i===`routes`){let e=Ge(await G(r,o));return`export default ${JSON.stringify(e,null,2)};`}if(i===`config`){let e={theme:o?.theme,i18n:o?.i18n,versions:o?.versions,siteUrl:o?.siteUrl,plugins:o?.plugins?.map(e=>({name:e.name}))};return`export default ${JSON.stringify(e,null,2)};`}if(i===`entry`)return J(e,o);if(i===`mdx-components`){let e=[`tsx`,`ts`,`jsx`,`js`],t=null;for(let i of e){let e=n.resolve(r,`mdx-components.${i}`);if(g.existsSync(e)){t=e;break}}if(t){let e=j(t);return`import * as components from '${e}';
85
- const mdxComponents = components.default || components;
86
- export default mdxComponents;
87
- export * from '${e}';`}return`export default {};`}if(i===`layout`){let e=[`tsx`,`jsx`],t=null;for(let i of e){let e=n.resolve(r,`layout.${i}`);if(g.existsSync(e)){t=e;break}}if(t)return`import UserLayout from '${j(t)}';
88
- export default UserLayout;`;throw Error(`[Boltdocs] Layout file not found. A 'layout.tsx' or 'layout.jsx' file is mandatory in your docs directory. Please create one to define your site structure.`)}if(i===`icons`){let e=[`tsx`,`jsx`,`ts`,`js`],t=null;for(let i of e){let e=n.resolve(r,`icons.${i}`);if(g.existsSync(e)){t=e;break}}return t?`import * as icons from '${j(t)}';\nexport default icons;`:`export default {};`}if(i===`search`){let e=ct(await G(r,o));return`export default ${JSON.stringify(e,null,2)};`}if(i===`client`){let e=O,t=``;for(;e&&e!==n.parse(e).root;){let r=n.join(e,`src/client/index.ts`),i=n.join(e,`dist/client/index.mjs`),a=n.join(e,`client/index.ts`);if(g.existsSync(r)){t=j(r);break}if(g.existsSync(i)){t=j(i);break}if(g.existsSync(a)){t=j(a);break}e=n.dirname(e)}if(!t)throw Error(`[boltdocs] Could not resolve boltdocs/client entry point starting from ${O}`);return`export * from '${t}';`}},transformIndexHtml:{order:`pre`,handler(e){return st(e,o)}},async closeBundle(){!c||s?.build?.ssr||(await l?.runHook(`afterBuild`),await l?.runHook(`buildEnd`))}},te({includePublic:!0,png:{quality:80},jpeg:{quality:80},jpg:{quality:80},webp:{quality:80},avif:{quality:80},svg:{multipass:!0,plugins:[{name:`preset-default`}]}}),{name:`vite-plugin-boltdocs-extra-plugins`,async configResolved(){}},...u]}const $=new Fe(`mdx`),bt=[x.default||x,S.default||S,C.default||C,w.default||w,oe.default||oe,T.default||T,E.default||E],xt=[D,se,ce,le,ue,de,fe,pe,me,he,ge,_e];let St=null,Ct=null;const wt=()=>(St??=y(),St),Tt=async e=>Ct||(Ct=b({themes:bt,langs:xt,engine:wt()}),Ct),Et=(e={})=>{let{activateByDefault:t=!1}=e;return{name:`boltdocs:line-numbers`,pre(e){let n=this.options.meta?.__raw||``,r=/lineNumbers|showLineNumbers/.test(n);(t||r)&&this.addClassToHast(e,`shiki-line-numbers`)}}},Dt=(e={})=>{let{activateByDefault:t=!1}=e;return{name:`boltdocs:word-wrap`,pre(e){let n=this.options.meta?.__raw||``,r=/wordWrap|word-wrap/.test(n);(t||r)&&this.addClassToHast(e,`shiki-word-wrap`)}}},Ot=()=>({name:`AddTitleProperty`,pre(e){let t=this.options.meta?.__raw;if(!t)return;let n=t.match(/title=(["'])(.*?)\1/)?.[2];e.properties[`data-title`]=n}}),kt=()=>({name:`AddLanguageProperty`,pre(e){e.properties[`data-lang`]=this.options.lang||`plaintext`}});var At=class{config;constructor(e){this.config=e}getTheme(){return this.config?.theme?.codeTheme||{light:`github-light`,dark:`github-dark`}}async getHighlighter(){return await Tt(this.getTheme())}getOptions(e,t){let n=this.getTheme(),r={lang:e,meta:{__raw:t},transformers:[Et(),Dt(),Ot(),kt()]};return typeof n==`object`?r.themes={light:n.light,dark:n.dark}:r.theme=n,r}async render(e,t,n){let r=await this.getHighlighter(),i=this.getOptions(t,n);return r.codeToHtml(e,i)}};function jt(e){let t=new At(e);return async e=>{let n=await t.getHighlighter();v(e,[`mdxJsxFlowElement`,`mdxJsxTextElement`],e=>{if(e.name!==`ComponentPreview`)return;let r=e.attributes?.find(e=>e.name===`code`),i=``;if(r){if(typeof r.value==`string`)i=r.value;else if(r.value?.type===`mdxJsxAttributeValueExpression`){let e=r.value.value??``;i=e.match(/^[`'"]([\s\S]+)[`'"]$/)?.[1]??e}}if(!i)return;let a=e.attributes?.find(e=>e.name===`lineNumbers`||e.name===`showLineNumbers`),o=e.attributes?.find(e=>e.name===`wordWrap`||e.name===`word-wrap`),s=e.attributes?.find(e=>e.name===`title`),c=``;a&&(c+=` lineNumbers`),o&&(c+=` wordWrap`),s&&typeof s.value==`string`&&(c+=` title="${s.value}"`);let l=t.getOptions(`tsx`,c),u=n.codeToHtml(i,l);e.attributes=(e.attributes??[]).filter(e=>e.name!==`highlightedHtml`),e.attributes.push({type:`mdxJsxAttribute`,name:`highlightedHtml`,value:u})})}}function Mt(e){let t=new At(e);return async e=>{let n=await t.getHighlighter();v(e,`element`,e=>{if(e.tagName===`pre`&&e.children?.[0]?.tagName===`code`){let r=e.children[0],i=(r.properties?.className||[]).find(e=>e.startsWith(`language-`)),a=i?i.slice(9):`text`,o=r.children[0]?.value||``,s=r.properties?.metastring||r.data?.meta||``,c=t.getOptions(a,s),l=n.codeToHtml(o,c);e.properties[`data-highlighted`]=`true`,e.properties[`data-highlighted-html`]=l,e.properties[`data-lang`]=a,e.children=[]}})}}function Nt(){return e=>{v(e,`code`,e=>{e.meta&&(e.data=e.data||{},e.data.hProperties=e.data.hProperties||{},e.data.hProperties.metastring=e.meta)})}}let Pt=!1;function Ft(e,t=ne){let n=e?.plugins?.flatMap(e=>Q.getSanitizedCapabilities(e).remarkPlugins||[])||[],r=e?.plugins?.flatMap(e=>Q.getSanitizedCapabilities(e).rehypePlugins||[])||[],i=t({remarkPlugins:[re,ie,Nt,[jt,e],...n],rehypePlugins:[ae,[Mt,e],...r],jsxRuntime:`automatic`});return{...i,name:`vite-plugin-boltdocs-mdx`,async buildStart(){Pt||=($.load(),!0),i.buildStart&&await i.buildStart.call(this)},async transform(e,t,n){if(!t.endsWith(`.md`)&&!t.endsWith(`.mdx`))return i.transform?.call(this,e,t,n);let r=`${t}:${p.createHash(`md5`).update(e).digest(`hex`)}:v2`,a=$.get(r);if(a)return{code:a,map:null};let o=await i.transform.call(this,e,t,n);return o&&typeof o==`object`&&o.code&&$.set(r,o.code),o},async buildEnd(){$.save(),await $.flush(),i.buildEnd&&await i.buildEnd.call(this)}}}async function It(e){let t=await q(e?.docsDir||`docs`);return[...yt({...e,homePage:e?.homePage||t.homePage},t),Ft(t)]}async function Lt(r,i=`development`){let a=await q(`docs`,r),s=i===`production`,c=s?{...lt}:{};return a.security?.enableCSP&&(c[`Content-Security-Policy`]=ut(a)),{root:r,mode:i,oxc:{jsx:{development:!s,runtime:`automatic`,importSource:`react`}},optimizeDeps:{include:[`react`,`react-dom`,`react-dom/client`,`react-helmet-async`,`react-router-dom`,`use-sync-external-store/shim`],rolldownOptions:{}},build:{rolldownOptions:{}},plugins:[e(),t(),await It({...a,root:r})],resolve:{alias:[{find:`boltdocs/entry`,replacement:o(n.resolve(r,`boltdocs-entry.mjs`))},{find:`boltdocs/client`,replacement:o(n.resolve(r,`boltdocs-client.mjs`))},{find:`use-sync-external-store/shim/index.js`,replacement:`react`},{find:`use-sync-external-store/shim`,replacement:`react`},{find:`use-sync-external-store`,replacement:`react`}],dedupe:[`react`,`react-dom`,`react-router-dom`,`react-helmet-async`,`@bdocs/ssg`]},ssr:{noExternal:[`boltdocs`,/@bdocs\/(?!ssg).*/,`react-helmet-async`,`react-aria-components`,`@react-aria/collections`,`@react-aria/utils`]},server:{headers:{...c,...a.vite?.server?.headers},...a.vite?.server},preview:{headers:{...c,...a.vite?.preview?.headers},...a.vite?.preview},...a.vite}}export{rt as _,Q as a,De as b,gt as c,Y as d,pt as f,q as g,J as h,_t as i,mt as l,X as m,Lt as n,ht as o,ft as p,vt as r,Z as s,It as t,dt as u,j as v,Ce as y};