boltdocs 2.5.4 → 2.5.6
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/bin/boltdocs.js +1 -1
- package/dist/cache-Cr8W2zgZ.cjs +6 -0
- package/dist/cache-DFdakSmR.mjs +6 -0
- package/dist/client/index.d.mts +1276 -861
- package/dist/client/index.d.ts +1276 -861
- package/dist/client/index.js +6 -1
- package/dist/client/index.mjs +6 -1
- package/dist/client/ssr.cjs +6 -0
- package/dist/client/ssr.d.cts +80 -0
- package/dist/client/ssr.d.mts +63 -61
- package/dist/client/ssr.mjs +6 -1
- package/dist/client/theme/neutral.css +388 -0
- package/dist/node/cli-entry.cjs +8 -0
- package/dist/node/cli-entry.d.cts +2 -0
- package/dist/node/cli-entry.d.mts +2 -1
- package/dist/node/cli-entry.mjs +7 -5
- package/dist/node/index.cjs +6 -0
- package/dist/node/index.d.cts +574 -0
- package/dist/node/index.d.mts +385 -378
- package/dist/node/index.mjs +6 -1
- package/dist/node-CWXme96p.mjs +73 -0
- package/dist/node-VYfhzGrh.cjs +73 -0
- package/dist/package-BY8Jd2j4.cjs +6 -0
- package/dist/package-OFZf0s2j.mjs +6 -0
- package/dist/search-dialog-BeNyI_KQ.mjs +6 -0
- package/dist/search-dialog-dYsCAk5S.js +6 -0
- package/dist/use-search-D25n0PrV.mjs +6 -0
- package/dist/use-search-WuzdH1cJ.js +6 -0
- package/package.json +16 -12
- package/src/client/app/index.tsx +15 -12
- package/src/client/components/default-layout.tsx +21 -19
- package/src/client/hooks/use-i18n.ts +1 -1
- package/src/client/hooks/use-routes.ts +1 -1
- package/src/client/hooks/use-version.ts +1 -1
- package/src/client/store/boltdocs-context.tsx +119 -0
- package/CHANGELOG.md +0 -92
- package/dist/cache-3FOEPC2P.mjs +0 -1
- package/dist/chunk-IMEKU5U3.mjs +0 -75
- package/dist/chunk-J2PTDWZM.mjs +0 -1
- package/dist/chunk-TP5KMRD3.mjs +0 -1
- package/dist/chunk-Y4RE5KI7.mjs +0 -1
- package/dist/client/ssr.d.ts +0 -78
- package/dist/client/ssr.js +0 -1
- package/dist/node/cli-entry.d.ts +0 -1
- package/dist/node/cli-entry.js +0 -80
- package/dist/node/index.d.ts +0 -567
- package/dist/node/index.js +0 -75
- package/dist/package-KCTE4HFV.mjs +0 -1
- package/dist/search-dialog-O6VLVSOA.mjs +0 -1
- package/src/client/store/use-boltdocs-store.ts +0 -44
- package/src/node/cache.ts +0 -408
- package/src/node/cli/build.ts +0 -53
- package/src/node/cli/dev.ts +0 -22
- package/src/node/cli/doctor.ts +0 -243
- package/src/node/cli/index.ts +0 -9
- package/src/node/cli/ui.ts +0 -54
- package/src/node/cli-entry.ts +0 -24
- package/src/node/config.ts +0 -382
- package/src/node/errors.ts +0 -44
- package/src/node/index.ts +0 -84
- package/src/node/mdx/cache.ts +0 -12
- package/src/node/mdx/highlighter.ts +0 -47
- package/src/node/mdx/index.ts +0 -122
- package/src/node/mdx/rehype-shiki.ts +0 -62
- package/src/node/mdx/remark-code-meta.ts +0 -35
- package/src/node/mdx/remark-shiki.ts +0 -61
- package/src/node/plugin/entry.ts +0 -87
- package/src/node/plugin/html.ts +0 -99
- package/src/node/plugin/index.ts +0 -464
- package/src/node/plugin/types.ts +0 -9
- package/src/node/plugins/index.ts +0 -17
- package/src/node/plugins/plugin-errors.ts +0 -62
- package/src/node/plugins/plugin-lifecycle.ts +0 -117
- package/src/node/plugins/plugin-sandbox.ts +0 -59
- package/src/node/plugins/plugin-store.ts +0 -54
- package/src/node/plugins/plugin-types.ts +0 -107
- package/src/node/plugins/plugin-validator.ts +0 -105
- package/src/node/routes/cache.ts +0 -28
- package/src/node/routes/index.ts +0 -293
- package/src/node/routes/parser.ts +0 -262
- package/src/node/routes/sorter.ts +0 -42
- package/src/node/routes/types.ts +0 -61
- package/src/node/schema/config.ts +0 -195
- package/src/node/schema/frontmatter.ts +0 -17
- package/src/node/search/index.ts +0 -55
- package/src/node/security/constants/index.ts +0 -10
- package/src/node/security/csp.ts +0 -31
- package/src/node/security/headers.ts +0 -27
- package/src/node/ssg/index.ts +0 -205
- package/src/node/ssg/meta.ts +0 -33
- package/src/node/ssg/options.ts +0 -15
- package/src/node/ssg/robots.ts +0 -53
- package/src/node/ssg/sitemap.ts +0 -55
- package/src/node/utils.ts +0 -349
- package/tsconfig.json +0 -26
- package/tsup.config.ts +0 -56
package/src/node/config.ts
DELETED
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import fs from 'fs'
|
|
3
|
-
import { loadConfigFromFile, type Plugin as VitePlugin } from 'vite'
|
|
4
|
-
import { BoltdocsConfigSchema } from './schema/config'
|
|
5
|
-
import { ValidationError } from './errors'
|
|
6
|
-
import type {
|
|
7
|
-
PluginLifecycleHooks,
|
|
8
|
-
PluginPermission,
|
|
9
|
-
} from './plugins/plugin-types'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Represents a single social link in the configuration.
|
|
13
|
-
*/
|
|
14
|
-
export interface BoltdocsSocialLink {
|
|
15
|
-
/** Identifier for the icon (e.g., 'github') */
|
|
16
|
-
icon: 'discord' | 'x' | 'github' | 'bluesky' | string
|
|
17
|
-
/** The URL the social link points to */
|
|
18
|
-
link: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Configuration for the site footer.
|
|
23
|
-
*/
|
|
24
|
-
export interface BoltdocsFooterConfig {
|
|
25
|
-
/** Text to display in the footer (HTML is supported) */
|
|
26
|
-
text?: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Theme-specific configuration options governing the appearance and navigation of the site.
|
|
31
|
-
*/
|
|
32
|
-
export interface BoltdocsThemeConfig {
|
|
33
|
-
/** The global title of the documentation site (can be translated) */
|
|
34
|
-
title?: string | Record<string, string>
|
|
35
|
-
/** The global description of the site (can be translated) */
|
|
36
|
-
description?: string | Record<string, string>
|
|
37
|
-
/** URL path to the site logo or an object for light/dark versions */
|
|
38
|
-
logo?:
|
|
39
|
-
| string
|
|
40
|
-
| {
|
|
41
|
-
dark: string
|
|
42
|
-
light: string
|
|
43
|
-
alt?: string
|
|
44
|
-
width?: number
|
|
45
|
-
height?: number
|
|
46
|
-
}
|
|
47
|
-
/** Items to display in the top navigation bar */
|
|
48
|
-
navbar?: Array<{
|
|
49
|
-
/** Text to display (can be a string or a map of translations) */
|
|
50
|
-
label: string | Record<string, string>
|
|
51
|
-
/** URL path or external link */
|
|
52
|
-
href: string
|
|
53
|
-
}>
|
|
54
|
-
/** Items to display in the sidebar, organized optionally by group URLs */
|
|
55
|
-
sidebar?: Record<string, Array<{ text: string; link: string }>>
|
|
56
|
-
/** Social links to display in the navigation bar */
|
|
57
|
-
socialLinks?: BoltdocsSocialLink[]
|
|
58
|
-
/** Site footer configuration */
|
|
59
|
-
footer?: BoltdocsFooterConfig
|
|
60
|
-
/** Whether to show breadcrumbs navigation (default: true) */
|
|
61
|
-
breadcrumbs?: boolean
|
|
62
|
-
/** URL template for 'Edit this page'. Use :path as a placeholder. */
|
|
63
|
-
editLink?: string
|
|
64
|
-
/** URL for the 'Community help' link. */
|
|
65
|
-
communityHelp?: string
|
|
66
|
-
/** The current version of the project (e.g., 'v2.8.9'). Displayed in the Navbar. */
|
|
67
|
-
version?: string
|
|
68
|
-
/** The GitHub repository in the format 'owner/repo' to fetch and display star count. */
|
|
69
|
-
githubRepo?: string
|
|
70
|
-
/**
|
|
71
|
-
* URL path to the site favicon.
|
|
72
|
-
* If not specified, the logo will be used if available.
|
|
73
|
-
*/
|
|
74
|
-
favicon?: string
|
|
75
|
-
/**
|
|
76
|
-
* The Open Graph image URL to display when the site is shared on social media.
|
|
77
|
-
*/
|
|
78
|
-
ogImage?: string
|
|
79
|
-
/** Whether to show the 'Powered by LiteDocs' badge in the sidebar (default: true) */
|
|
80
|
-
poweredBy?: boolean
|
|
81
|
-
/**
|
|
82
|
-
* Top-level tabs for organizing documentation groups.
|
|
83
|
-
* Tab discovery uses the (tab-id) directory syntax.
|
|
84
|
-
*/
|
|
85
|
-
tabs?: Array<{
|
|
86
|
-
id: string
|
|
87
|
-
/** Text to display (can be a string or a map of translations) */
|
|
88
|
-
text: string | Record<string, string>
|
|
89
|
-
icon?: string
|
|
90
|
-
}>
|
|
91
|
-
/**
|
|
92
|
-
* The syntax highlighting theme for code blocks.
|
|
93
|
-
* Supports any Shiki theme name (e.g., 'github-dark', 'one-dark-pro', 'aurora-x').
|
|
94
|
-
* Can also be an object for multiple themes (e.g., { light: 'github-light', dark: 'github-dark' }).
|
|
95
|
-
* Default: { light: 'github-light', dark: 'one-dark-pro' }
|
|
96
|
-
*/
|
|
97
|
-
codeTheme?: string | { light: string; dark: string }
|
|
98
|
-
/**
|
|
99
|
-
* Configuration for the 'Copy Markdown' button.
|
|
100
|
-
* Can be a boolean or an object with text and icon.
|
|
101
|
-
* Default: true
|
|
102
|
-
*/
|
|
103
|
-
copyMarkdown?: boolean | { text?: string; icon?: string }
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Configuration for the robots.txt file.
|
|
108
|
-
*/
|
|
109
|
-
export type BoltdocsRobotsConfig =
|
|
110
|
-
| string
|
|
111
|
-
| {
|
|
112
|
-
/** User-agent rules */
|
|
113
|
-
rules?: Array<{
|
|
114
|
-
userAgent: string
|
|
115
|
-
/** Paths allowed to be crawled */
|
|
116
|
-
allow?: string | string[]
|
|
117
|
-
/** Paths disallowed to be crawled */
|
|
118
|
-
disallow?: string | string[]
|
|
119
|
-
}>
|
|
120
|
-
/** Sitemaps to include in the robots.txt */
|
|
121
|
-
sitemaps?: string[]
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Configuration for a specific locale.
|
|
126
|
-
*/
|
|
127
|
-
export interface BoltdocsLocaleConfig {
|
|
128
|
-
/** The display name of the locale */
|
|
129
|
-
label?: string
|
|
130
|
-
/** The text direction (ltr or rtl) */
|
|
131
|
-
direction?: 'ltr' | 'rtl'
|
|
132
|
-
/** The HTML lang attribute value (e.g., 'en-US') */
|
|
133
|
-
htmlLang?: string
|
|
134
|
-
/** The calendar system to use (e.g., 'gregory') */
|
|
135
|
-
calendar?: string
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Configuration for internationalization (i18n).
|
|
140
|
-
*/
|
|
141
|
-
export interface BoltdocsI18nConfig {
|
|
142
|
-
/** The default locale (e.g., 'en') */
|
|
143
|
-
defaultLocale: string
|
|
144
|
-
/** Available locales and their basic display names (e.g., { en: 'English', es: 'Español' }) */
|
|
145
|
-
locales: Record<string, string>
|
|
146
|
-
/** Detailed configuration for each locale */
|
|
147
|
-
localeConfigs?: Record<string, BoltdocsLocaleConfig>
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Configuration for a specific documentation version.
|
|
152
|
-
*/
|
|
153
|
-
export interface BoltdocsVersionConfig {
|
|
154
|
-
/** The display name of the version (e.g., 'v2.0') */
|
|
155
|
-
label: string
|
|
156
|
-
/** The URL path prefix for the version (e.g., '2.0') */
|
|
157
|
-
path: string
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Configuration for documentation versioning.
|
|
162
|
-
*/
|
|
163
|
-
export interface BoltdocsVersionsConfig {
|
|
164
|
-
/** The default version path (e.g., 'v2') */
|
|
165
|
-
defaultVersion: string
|
|
166
|
-
/**
|
|
167
|
-
* Optional prefix for all version paths (e.g., 'v').
|
|
168
|
-
* If set to 'v', version '1.1' will be available at '/docs/v1.1'.
|
|
169
|
-
*/
|
|
170
|
-
prefix?: string
|
|
171
|
-
/** Available versions configurations */
|
|
172
|
-
versions: BoltdocsVersionConfig[]
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Defines a Boltdocs plugin that can extend the build process and client-side functionality.
|
|
177
|
-
*/
|
|
178
|
-
export interface BoltdocsPlugin {
|
|
179
|
-
/** A unique name for the plugin */
|
|
180
|
-
name: string
|
|
181
|
-
/** Whether to run this plugin before or after default ones (optional) */
|
|
182
|
-
enforce?: 'pre' | 'post'
|
|
183
|
-
/** Version of the plugin (optional) */
|
|
184
|
-
version?: string
|
|
185
|
-
/** Minimum compatible Boltdocs version (optional, semver range) */
|
|
186
|
-
boltdocsVersion?: string
|
|
187
|
-
/** List of permissions this plugin requires to operate */
|
|
188
|
-
permissions?: PluginPermission[]
|
|
189
|
-
/** Optional remark plugins to add to the MDX pipeline */
|
|
190
|
-
remarkPlugins?: unknown[]
|
|
191
|
-
/** Optional rehype plugins to add to the MDX pipeline */
|
|
192
|
-
rehypePlugins?: unknown[]
|
|
193
|
-
/** Optional Vite plugins to inject into the build process */
|
|
194
|
-
vitePlugins?: VitePlugin[]
|
|
195
|
-
/** Optional custom React components to register in MDX. Map of Name -> Module Path. */
|
|
196
|
-
components?: Record<string, string>
|
|
197
|
-
/** Implementation of lifecycle hooks */
|
|
198
|
-
hooks?: PluginLifecycleHooks
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Configuration for security-related settings.
|
|
203
|
-
*/
|
|
204
|
-
export interface BoltdocsSecurityConfig {
|
|
205
|
-
/** Map of standard security headers to override or supplement defaults */
|
|
206
|
-
headers?: Record<string, string>
|
|
207
|
-
/** Whether to enable Content Security Policy (CSP) generation (default: false) */
|
|
208
|
-
enableCSP?: boolean
|
|
209
|
-
/** Additional custom headers to inject into responses */
|
|
210
|
-
customHeaders?: Record<string, string>
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* The root configuration object for Boltdocs.
|
|
215
|
-
*/
|
|
216
|
-
export interface BoltdocsConfig {
|
|
217
|
-
/** The base URL of the site, used for generating the sitemap */
|
|
218
|
-
siteUrl?: string
|
|
219
|
-
/** The root directory containing markdown documentation files (default: 'docs') */
|
|
220
|
-
docsDir?: string
|
|
221
|
-
/** Path to a custom HomePage component */
|
|
222
|
-
homePage?: string
|
|
223
|
-
/** Configuration pertaining to the UI and appearance */
|
|
224
|
-
theme?: BoltdocsThemeConfig
|
|
225
|
-
/** Configuration for internationalization */
|
|
226
|
-
i18n?: BoltdocsI18nConfig
|
|
227
|
-
/** Configuration for documentation versioning */
|
|
228
|
-
versions?: BoltdocsVersionsConfig
|
|
229
|
-
/** Custom plugins for extending functionality */
|
|
230
|
-
plugins?: BoltdocsPlugin[]
|
|
231
|
-
/** Configuration for the robots.txt file */
|
|
232
|
-
robots?: BoltdocsRobotsConfig
|
|
233
|
-
/** Security-related settings and headers */
|
|
234
|
-
security?: BoltdocsSecurityConfig
|
|
235
|
-
/** Low-level Vite configuration overrides */
|
|
236
|
-
vite?: import('vite').InlineConfig
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export function defineConfig(config: BoltdocsConfig): BoltdocsConfig {
|
|
240
|
-
return config
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export const CONFIG_FILES = [
|
|
244
|
-
'boltdocs.config.js',
|
|
245
|
-
'boltdocs.config.mjs',
|
|
246
|
-
'boltdocs.config.ts',
|
|
247
|
-
]
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Small helper to handle partial config objects from user input.
|
|
251
|
-
*/
|
|
252
|
-
interface RawUserConfig
|
|
253
|
-
extends Partial<BoltdocsConfig>,
|
|
254
|
-
Partial<BoltdocsThemeConfig> {
|
|
255
|
-
favicon?: string
|
|
256
|
-
ogImage?: string
|
|
257
|
-
security?: BoltdocsSecurityConfig
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Loads user's configuration file (e.g., `boltdocs.config.js` or `boltdocs.config.ts`) if it exists,
|
|
262
|
-
* merges it with the default configuration, and returns the final `BoltdocsConfig`.
|
|
263
|
-
*
|
|
264
|
-
* @param docsDir - The directory containing the documentation files
|
|
265
|
-
* @param root - The project root directory (defaults to process.cwd())
|
|
266
|
-
* @returns The merged configuration object
|
|
267
|
-
*/
|
|
268
|
-
export async function resolveConfig(
|
|
269
|
-
docsDir: string,
|
|
270
|
-
root: string = process.cwd(),
|
|
271
|
-
): Promise<BoltdocsConfig> {
|
|
272
|
-
const projectRoot = root
|
|
273
|
-
|
|
274
|
-
const defaults: BoltdocsConfig = {
|
|
275
|
-
docsDir: path.resolve(docsDir),
|
|
276
|
-
theme: {
|
|
277
|
-
title: 'Boltdocs',
|
|
278
|
-
description: 'A Vite documentation framework',
|
|
279
|
-
navbar: [
|
|
280
|
-
{ label: 'Home', href: '/' },
|
|
281
|
-
{ label: 'Documentation', href: '/docs' },
|
|
282
|
-
],
|
|
283
|
-
codeTheme: {
|
|
284
|
-
light: 'github-light',
|
|
285
|
-
dark: 'github-dark',
|
|
286
|
-
},
|
|
287
|
-
poweredBy: true,
|
|
288
|
-
breadcrumbs: true,
|
|
289
|
-
},
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
let userConfig: RawUserConfig = {}
|
|
293
|
-
|
|
294
|
-
// Try to load user config
|
|
295
|
-
for (const filename of CONFIG_FILES) {
|
|
296
|
-
const configPath = path.resolve(projectRoot, filename)
|
|
297
|
-
if (fs.existsSync(configPath)) {
|
|
298
|
-
try {
|
|
299
|
-
const loaded = await loadConfigFromFile(
|
|
300
|
-
{ command: 'serve', mode: 'development' },
|
|
301
|
-
configPath,
|
|
302
|
-
projectRoot,
|
|
303
|
-
)
|
|
304
|
-
if (loaded) {
|
|
305
|
-
userConfig = loaded.config as RawUserConfig
|
|
306
|
-
break
|
|
307
|
-
}
|
|
308
|
-
} catch (e) {
|
|
309
|
-
console.warn(`[boltdocs] Failed to load config from ${filename}:`, e)
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
const themeConfigFromTop: BoltdocsThemeConfig = {
|
|
315
|
-
title: userConfig.title,
|
|
316
|
-
description: userConfig.description,
|
|
317
|
-
logo: userConfig.logo,
|
|
318
|
-
favicon: userConfig.favicon,
|
|
319
|
-
ogImage: userConfig.ogImage,
|
|
320
|
-
navbar: userConfig.navbar,
|
|
321
|
-
sidebar: userConfig.sidebar,
|
|
322
|
-
socialLinks: userConfig.socialLinks,
|
|
323
|
-
footer: userConfig.footer,
|
|
324
|
-
githubRepo: userConfig.githubRepo,
|
|
325
|
-
tabs: userConfig.tabs,
|
|
326
|
-
codeTheme: userConfig.codeTheme,
|
|
327
|
-
copyMarkdown: userConfig.copyMarkdown,
|
|
328
|
-
breadcrumbs: userConfig.breadcrumbs,
|
|
329
|
-
poweredBy: userConfig.poweredBy,
|
|
330
|
-
communityHelp: userConfig.communityHelp,
|
|
331
|
-
version: userConfig.version,
|
|
332
|
-
editLink: userConfig.editLink,
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const userThemeConfig: BoltdocsThemeConfig = {
|
|
336
|
-
...themeConfigFromTop,
|
|
337
|
-
...(userConfig.theme || {}),
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const cleanThemeConfig = Object.fromEntries(
|
|
341
|
-
Object.entries(userThemeConfig).filter(([_, v]) => v !== undefined),
|
|
342
|
-
) as BoltdocsThemeConfig
|
|
343
|
-
if (cleanThemeConfig.navbar) {
|
|
344
|
-
cleanThemeConfig.navbar = cleanThemeConfig.navbar.map((item: any) => ({
|
|
345
|
-
label: item.label || item.text || '',
|
|
346
|
-
href: item.href || item.link || item.to || '',
|
|
347
|
-
}))
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const finalConfig: BoltdocsConfig = {
|
|
351
|
-
docsDir: path.resolve(docsDir),
|
|
352
|
-
homePage: userConfig.homePage,
|
|
353
|
-
theme: {
|
|
354
|
-
...defaults.theme,
|
|
355
|
-
...cleanThemeConfig,
|
|
356
|
-
},
|
|
357
|
-
i18n: userConfig.i18n,
|
|
358
|
-
versions: userConfig.versions,
|
|
359
|
-
siteUrl: userConfig.siteUrl,
|
|
360
|
-
plugins: userConfig.plugins || [],
|
|
361
|
-
robots: userConfig.robots,
|
|
362
|
-
security: userConfig.security,
|
|
363
|
-
vite: userConfig.vite,
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Validate the final configuration
|
|
367
|
-
const validation = BoltdocsConfigSchema.safeParse(finalConfig)
|
|
368
|
-
if (!validation.success) {
|
|
369
|
-
const errorMessages = validation.error.issues
|
|
370
|
-
.map((err: any) => {
|
|
371
|
-
const path = err.path.join('.')
|
|
372
|
-
return ` - ${path}: ${err.message}`
|
|
373
|
-
})
|
|
374
|
-
.join('\n')
|
|
375
|
-
|
|
376
|
-
throw new ValidationError(
|
|
377
|
-
`Invalid Boltdocs configuration:\n${errorMessages}`,
|
|
378
|
-
)
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return validation.data as BoltdocsConfig
|
|
382
|
-
}
|
package/src/node/errors.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base class for all security-related violations in Boltdocs.
|
|
3
|
-
*/
|
|
4
|
-
export class SecurityViolationError extends Error {
|
|
5
|
-
constructor(message: string) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.name = 'SecurityViolationError';
|
|
8
|
-
// Ensure the prototype is set correctly for instanceof checks in older TS versions
|
|
9
|
-
Object.setPrototypeOf(this, SecurityViolationError.prototype);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Specifically for directory traversal attempts and related filesystem breaches.
|
|
15
|
-
*/
|
|
16
|
-
export class PathTraversalError extends SecurityViolationError {
|
|
17
|
-
constructor(message: string) {
|
|
18
|
-
super(message);
|
|
19
|
-
this.name = 'PathTraversalError';
|
|
20
|
-
Object.setPrototypeOf(this, PathTraversalError.prototype);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Specifically for invalid or malicious character encoding in paths.
|
|
26
|
-
*/
|
|
27
|
-
export class EncodingSecurityError extends SecurityViolationError {
|
|
28
|
-
constructor(message: string) {
|
|
29
|
-
super(message);
|
|
30
|
-
this.name = 'EncodingSecurityError';
|
|
31
|
-
Object.setPrototypeOf(this, EncodingSecurityError.prototype);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Specifically for schema or size validation failures in inputs (like frontmatter).
|
|
37
|
-
*/
|
|
38
|
-
export class ValidationError extends SecurityViolationError {
|
|
39
|
-
constructor(message: string) {
|
|
40
|
-
super(message);
|
|
41
|
-
this.name = 'ValidationError';
|
|
42
|
-
Object.setPrototypeOf(this, ValidationError.prototype);
|
|
43
|
-
}
|
|
44
|
-
}
|
package/src/node/index.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import type { Plugin, InlineConfig } from 'vite'
|
|
2
|
-
import react from '@vitejs/plugin-react'
|
|
3
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
4
|
-
import { boltdocsPlugin } from './plugin/index'
|
|
5
|
-
import { boltdocsMdxPlugin } from './mdx/index'
|
|
6
|
-
import { SECURITY_HEADERS } from './security/headers'
|
|
7
|
-
import { getCSPHeader } from './security/csp'
|
|
8
|
-
import type { BoltdocsPluginOptions } from './plugin/index'
|
|
9
|
-
|
|
10
|
-
import { resolveConfig } from './config'
|
|
11
|
-
|
|
12
|
-
export default async function boltdocs(
|
|
13
|
-
options?: BoltdocsPluginOptions,
|
|
14
|
-
): Promise<Plugin[]> {
|
|
15
|
-
const docsDir = options?.docsDir || 'docs'
|
|
16
|
-
const config = await resolveConfig(docsDir)
|
|
17
|
-
|
|
18
|
-
// Merge options with config
|
|
19
|
-
const mergedOptions: BoltdocsPluginOptions = {
|
|
20
|
-
...options,
|
|
21
|
-
homePage: options?.homePage || config.homePage,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return [...boltdocsPlugin(mergedOptions, config), boltdocsMdxPlugin(config)]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generates the complete Vite configuration for a Boltdocs project.
|
|
29
|
-
* This is used by the Boltdocs CLI to run Vite without a user-defined vite.config.ts.
|
|
30
|
-
*/
|
|
31
|
-
export async function createViteConfig(
|
|
32
|
-
root: string,
|
|
33
|
-
mode: 'development' | 'production' = 'development',
|
|
34
|
-
): Promise<InlineConfig> {
|
|
35
|
-
const config = await resolveConfig('docs', root)
|
|
36
|
-
const isProd = mode === 'production'
|
|
37
|
-
|
|
38
|
-
// Prepare security headers
|
|
39
|
-
const securityHeaders: Record<string, string> = isProd
|
|
40
|
-
? { ...SECURITY_HEADERS }
|
|
41
|
-
: {}
|
|
42
|
-
if (config.security?.enableCSP) {
|
|
43
|
-
securityHeaders['Content-Security-Policy'] = getCSPHeader(config)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const viteConfig: InlineConfig = {
|
|
47
|
-
root,
|
|
48
|
-
mode,
|
|
49
|
-
plugins: [
|
|
50
|
-
react(),
|
|
51
|
-
tailwindcss(),
|
|
52
|
-
await boltdocs({
|
|
53
|
-
docsDir: config.docsDir,
|
|
54
|
-
homePage: config.homePage,
|
|
55
|
-
}),
|
|
56
|
-
],
|
|
57
|
-
server: {
|
|
58
|
-
headers: {
|
|
59
|
-
...securityHeaders,
|
|
60
|
-
...config.vite?.server?.headers,
|
|
61
|
-
},
|
|
62
|
-
...config.vite?.server,
|
|
63
|
-
},
|
|
64
|
-
preview: {
|
|
65
|
-
headers: {
|
|
66
|
-
...securityHeaders,
|
|
67
|
-
...config.vite?.preview?.headers,
|
|
68
|
-
},
|
|
69
|
-
...config.vite?.preview,
|
|
70
|
-
},
|
|
71
|
-
...config.vite,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return viteConfig
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export type { BoltdocsPluginOptions }
|
|
78
|
-
export { generateStaticPages } from './ssg'
|
|
79
|
-
export type { SSGOptions } from './ssg'
|
|
80
|
-
export type { RouteMeta } from './routes'
|
|
81
|
-
export type { BoltdocsConfig, BoltdocsThemeConfig, BoltdocsPlugin } from './config'
|
|
82
|
-
export { resolveConfig, defineConfig } from './config'
|
|
83
|
-
|
|
84
|
-
export * from './plugins'
|
package/src/node/mdx/cache.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { TransformCache } from '../cache'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Version identifier for the MDX plugin to invalidate cache if logic changes.
|
|
5
|
-
*/
|
|
6
|
-
export const MDX_PLUGIN_VERSION = 'v4'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Persistent cache for MDX transformations.
|
|
10
|
-
* Saves results to `.boltdocs/transform-mdx.json.gz`.
|
|
11
|
-
*/
|
|
12
|
-
export const mdxCache = new TransformCache('mdx')
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { createHighlighter } from 'shiki'
|
|
2
|
-
import type { Highlighter } from 'shiki'
|
|
3
|
-
|
|
4
|
-
let shikiHighlighter: Highlighter | null = null
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Retrieves or initializes the Shiki highlighter instance.
|
|
8
|
-
* Supports dual-theme configurations (light/dark).
|
|
9
|
-
*
|
|
10
|
-
* @param codeTheme - Theme configuration (string for single, object for dual).
|
|
11
|
-
* @returns A promise resolving to the highlighter instance.
|
|
12
|
-
*/
|
|
13
|
-
export async function getShikiHighlighter(codeTheme: any) {
|
|
14
|
-
if (shikiHighlighter) return shikiHighlighter
|
|
15
|
-
|
|
16
|
-
const themes =
|
|
17
|
-
typeof codeTheme === 'object'
|
|
18
|
-
? [codeTheme.light, codeTheme.dark]
|
|
19
|
-
: [codeTheme ?? 'github-dark']
|
|
20
|
-
|
|
21
|
-
// Fallbacks for standard themes
|
|
22
|
-
;['github-light', 'github-dark'].forEach((t) => {
|
|
23
|
-
if (!themes.includes(t)) themes.push(t)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// Initialize with a core set of languages first to speed up boot
|
|
27
|
-
shikiHighlighter = await createHighlighter({
|
|
28
|
-
themes,
|
|
29
|
-
langs: [
|
|
30
|
-
'tsx',
|
|
31
|
-
'jsx',
|
|
32
|
-
'ts',
|
|
33
|
-
'js',
|
|
34
|
-
'json',
|
|
35
|
-
'md',
|
|
36
|
-
'mdx',
|
|
37
|
-
'css',
|
|
38
|
-
'html',
|
|
39
|
-
'bash',
|
|
40
|
-
'sh',
|
|
41
|
-
'yaml',
|
|
42
|
-
'yml',
|
|
43
|
-
],
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
return shikiHighlighter
|
|
47
|
-
}
|
package/src/node/mdx/index.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import mdxPlugin from '@mdx-js/rollup'
|
|
2
|
-
import remarkGfm from 'remark-gfm'
|
|
3
|
-
import remarkFrontmatter from 'remark-frontmatter'
|
|
4
|
-
import rehypeSlug from 'rehype-slug'
|
|
5
|
-
import type { Plugin } from 'vite'
|
|
6
|
-
import crypto from 'crypto'
|
|
7
|
-
|
|
8
|
-
import type { BoltdocsConfig } from '../config'
|
|
9
|
-
import { mdxCache, MDX_PLUGIN_VERSION } from './cache'
|
|
10
|
-
import { remarkShiki } from './remark-shiki'
|
|
11
|
-
import { rehypeShiki } from './rehype-shiki'
|
|
12
|
-
import { remarkCodeMeta } from './remark-code-meta'
|
|
13
|
-
import { PluginSandbox } from '../plugins'
|
|
14
|
-
|
|
15
|
-
let mdxCacheLoaded = false
|
|
16
|
-
let hits = 0
|
|
17
|
-
let total = 0
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Configures the MDX compiler for Vite using `@mdx-js/rollup`.
|
|
21
|
-
* Includes standard remark and rehype plugins for GitHub Flavored Markdown (GFM),
|
|
22
|
-
* frontmatter extraction, and auto-linking headers.
|
|
23
|
-
*
|
|
24
|
-
* Also wraps the plugin with a persistent cache to avoid re-compiling unchanged MDX files.
|
|
25
|
-
*
|
|
26
|
-
* @param config - The Boltdocs configuration containing custom plugins
|
|
27
|
-
* @param compiler - The MDX compiler plugin (for testing)
|
|
28
|
-
* @returns A Vite plugin configured for MDX parsing with caching
|
|
29
|
-
*/
|
|
30
|
-
export function boltdocsMdxPlugin(
|
|
31
|
-
config?: BoltdocsConfig,
|
|
32
|
-
compiler = mdxPlugin,
|
|
33
|
-
): Plugin {
|
|
34
|
-
const extraRemarkPlugins =
|
|
35
|
-
config?.plugins?.flatMap((p) => {
|
|
36
|
-
const caps = PluginSandbox.getSanitizedCapabilities(p as any)
|
|
37
|
-
return caps.remarkPlugins || []
|
|
38
|
-
}) || []
|
|
39
|
-
const extraRehypePlugins =
|
|
40
|
-
config?.plugins?.flatMap((p) => {
|
|
41
|
-
const caps = PluginSandbox.getSanitizedCapabilities(p as any)
|
|
42
|
-
return caps.rehypePlugins || []
|
|
43
|
-
}) || []
|
|
44
|
-
|
|
45
|
-
const baseMdxPlugin = compiler({
|
|
46
|
-
remarkPlugins: [
|
|
47
|
-
remarkGfm,
|
|
48
|
-
remarkFrontmatter,
|
|
49
|
-
remarkCodeMeta,
|
|
50
|
-
[remarkShiki, config],
|
|
51
|
-
...(extraRemarkPlugins as any[]),
|
|
52
|
-
],
|
|
53
|
-
rehypePlugins: [
|
|
54
|
-
rehypeSlug,
|
|
55
|
-
[rehypeShiki, config],
|
|
56
|
-
...(extraRehypePlugins as any[]),
|
|
57
|
-
],
|
|
58
|
-
jsxRuntime: 'automatic',
|
|
59
|
-
}) as Plugin
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
...baseMdxPlugin,
|
|
63
|
-
name: 'vite-plugin-boltdocs-mdx',
|
|
64
|
-
|
|
65
|
-
async buildStart() {
|
|
66
|
-
hits = 0
|
|
67
|
-
total = 0
|
|
68
|
-
if (!mdxCacheLoaded) {
|
|
69
|
-
mdxCache.load()
|
|
70
|
-
mdxCacheLoaded = true
|
|
71
|
-
}
|
|
72
|
-
// @ts-ignore
|
|
73
|
-
if (baseMdxPlugin.buildStart) {
|
|
74
|
-
// @ts-ignore
|
|
75
|
-
await baseMdxPlugin.buildStart.call(this)
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
async transform(code, id, options) {
|
|
80
|
-
if (!id.endsWith('.md') && !id.endsWith('.mdx')) {
|
|
81
|
-
// @ts-ignore
|
|
82
|
-
return baseMdxPlugin.transform?.call(this, code, id, options)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
console.log(`[boltdocs] Transforming MDX: ${id}`)
|
|
86
|
-
total++
|
|
87
|
-
// Create a cache key based on path, content, and plugin version
|
|
88
|
-
const contentHash = crypto.createHash('md5').update(code).digest('hex')
|
|
89
|
-
const cacheKey = `${id}:${contentHash}:${MDX_PLUGIN_VERSION}`
|
|
90
|
-
|
|
91
|
-
const cached = mdxCache.get(cacheKey)
|
|
92
|
-
if (cached) {
|
|
93
|
-
hits++
|
|
94
|
-
return { code: cached, map: null }
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
const result = await baseMdxPlugin.transform.call(this, code, id, options)
|
|
99
|
-
|
|
100
|
-
if (result && typeof result === 'object' && result.code) {
|
|
101
|
-
mdxCache.set(cacheKey, result.code)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return result
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
async buildEnd() {
|
|
108
|
-
if (total > 0) {
|
|
109
|
-
console.log(
|
|
110
|
-
`[boltdocs] MDX Cache Performance: ${hits}/${total} hits (${Math.round((hits / total) * 100) || 0}%)`,
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
mdxCache.save()
|
|
114
|
-
await mdxCache.flush()
|
|
115
|
-
// @ts-ignore
|
|
116
|
-
if (baseMdxPlugin.buildEnd) {
|
|
117
|
-
// @ts-ignore
|
|
118
|
-
await baseMdxPlugin.buildEnd.call(this)
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
}
|
|
122
|
-
}
|