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
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { visit } from 'unist-util-visit'
|
|
2
|
-
import type { BoltdocsConfig } from '../config'
|
|
3
|
-
import { getShikiHighlighter } from './highlighter'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Custom rehype plugin to perform syntax highlighting at build time for
|
|
7
|
-
* standard Markdown code blocks.
|
|
8
|
-
*
|
|
9
|
-
* Injects 'data-highlighted="true"' and 'highlightedHtml' into the 'pre' tag properties,
|
|
10
|
-
* which are then consumed by the client-side CodeBlock component.
|
|
11
|
-
*
|
|
12
|
-
* @param config - The Boltdocs configuration
|
|
13
|
-
* @returns A rehype plugin function
|
|
14
|
-
*/
|
|
15
|
-
export function rehypeShiki(config?: BoltdocsConfig) {
|
|
16
|
-
return async (tree: any) => {
|
|
17
|
-
const codeTheme = config?.theme?.codeTheme || {
|
|
18
|
-
light: 'github-light',
|
|
19
|
-
dark: 'github-dark',
|
|
20
|
-
}
|
|
21
|
-
const highlighter = await getShikiHighlighter(codeTheme)
|
|
22
|
-
|
|
23
|
-
visit(tree, 'element', (node: any) => {
|
|
24
|
-
// Handle standard Markdown code blocks
|
|
25
|
-
if (node.tagName === 'pre' && node.children?.[0]?.tagName === 'code') {
|
|
26
|
-
const codeNode = node.children[0]
|
|
27
|
-
const className = codeNode.properties?.className || []
|
|
28
|
-
const langMatch = className.find((c: string) =>
|
|
29
|
-
c.startsWith('language-'),
|
|
30
|
-
)
|
|
31
|
-
const lang = langMatch ? langMatch.slice(9) : 'text'
|
|
32
|
-
const code = codeNode.children[0]?.value || ''
|
|
33
|
-
|
|
34
|
-
// Extract title from meta string (e.g., ```ts title="app.ts")
|
|
35
|
-
const meta: string = codeNode.data?.meta || codeNode.properties?.metastring || ''
|
|
36
|
-
const titleMatch = meta.match(/title\s*=\s*"([^"]*)"/)
|
|
37
|
-
const title = titleMatch ? titleMatch[1] : undefined
|
|
38
|
-
|
|
39
|
-
const options: any = { lang }
|
|
40
|
-
if (typeof codeTheme === 'object') {
|
|
41
|
-
options.themes = {
|
|
42
|
-
light: codeTheme.light,
|
|
43
|
-
dark: codeTheme.dark,
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
options.theme = codeTheme
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const html = highlighter.codeToHtml(code, options)
|
|
50
|
-
|
|
51
|
-
// Inject highlighted HTML and mark as highlighted for CodeBlock component
|
|
52
|
-
node.properties['data-highlighted'] = 'true'
|
|
53
|
-
node.properties['data-highlighted-html'] = html
|
|
54
|
-
node.properties['data-lang'] = lang
|
|
55
|
-
if (title) {
|
|
56
|
-
node.properties.title = title
|
|
57
|
-
}
|
|
58
|
-
node.children = []
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { visit } from 'unist-util-visit'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Remark plugin that preserves code fence meta strings (e.g., title="file.ts")
|
|
5
|
-
* and the language identifier by copying them to hProperties so they survive
|
|
6
|
-
* the remark → rehype conversion and are accessible as props on the `<pre>` element.
|
|
7
|
-
*
|
|
8
|
-
* Usage in MDX: ```ts title="app.ts"
|
|
9
|
-
*/
|
|
10
|
-
export function remarkCodeMeta() {
|
|
11
|
-
return (tree: any) => {
|
|
12
|
-
visit(tree, 'code', (node: any) => {
|
|
13
|
-
node.data = node.data || {}
|
|
14
|
-
node.data.hProperties = node.data.hProperties || {}
|
|
15
|
-
|
|
16
|
-
// Always pass the lang through
|
|
17
|
-
if (node.lang) {
|
|
18
|
-
node.data.hProperties['data-lang'] = node.lang
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!node.meta) return
|
|
22
|
-
|
|
23
|
-
const meta: string = node.meta
|
|
24
|
-
|
|
25
|
-
// Extract title="..." from the meta string
|
|
26
|
-
const titleMatch = meta.match(/title\s*=\s*"([^"]*)"/)
|
|
27
|
-
if (titleMatch) {
|
|
28
|
-
node.data.hProperties.title = titleMatch[1]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Preserve the full meta string for other plugins
|
|
32
|
-
node.data.hProperties.metastring = meta
|
|
33
|
-
})
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { visit } from 'unist-util-visit'
|
|
2
|
-
import type { BoltdocsConfig } from '../config'
|
|
3
|
-
import { getShikiHighlighter } from './highlighter'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Custom remark plugin to highlight code in ComponentPreview components.
|
|
7
|
-
* This runs before rehype, ensuring that the 'highlightedHtml' prop is correctly
|
|
8
|
-
* attached to the MDX component as a JSX attribute.
|
|
9
|
-
*
|
|
10
|
-
* Supports both string literals and MDX expression values (template literals)
|
|
11
|
-
* for the 'code' attribute.
|
|
12
|
-
*
|
|
13
|
-
* @param config - The Boltdocs configuration
|
|
14
|
-
* @returns A remark plugin function
|
|
15
|
-
*/
|
|
16
|
-
export function remarkShiki(config?: BoltdocsConfig) {
|
|
17
|
-
return async (tree: any) => {
|
|
18
|
-
const codeTheme = config?.theme?.codeTheme ?? {
|
|
19
|
-
light: 'github-light',
|
|
20
|
-
dark: 'github-dark',
|
|
21
|
-
}
|
|
22
|
-
const highlighter = await getShikiHighlighter(codeTheme)
|
|
23
|
-
|
|
24
|
-
visit(tree, ['mdxJsxFlowElement', 'mdxJsxTextElement'], (node: any) => {
|
|
25
|
-
if (node.name !== 'ComponentPreview') return
|
|
26
|
-
|
|
27
|
-
const codeAttr = node.attributes?.find((a: any) => a.name === 'code')
|
|
28
|
-
let code = ''
|
|
29
|
-
|
|
30
|
-
if (codeAttr) {
|
|
31
|
-
if (typeof codeAttr.value === 'string') {
|
|
32
|
-
code = codeAttr.value
|
|
33
|
-
} else if (codeAttr.value?.type === 'mdxJsxAttributeValueExpression') {
|
|
34
|
-
const expr = codeAttr.value.value ?? ''
|
|
35
|
-
code = expr.match(/^[`'"]([\s\S]+)[`'"]$/)?.[1] ?? expr
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!code) return
|
|
40
|
-
|
|
41
|
-
const options: any =
|
|
42
|
-
typeof codeTheme === 'object'
|
|
43
|
-
? {
|
|
44
|
-
themes: { light: codeTheme.light, dark: codeTheme.dark },
|
|
45
|
-
lang: 'tsx',
|
|
46
|
-
}
|
|
47
|
-
: { theme: codeTheme, lang: 'tsx' }
|
|
48
|
-
|
|
49
|
-
const html = highlighter.codeToHtml(code, options)
|
|
50
|
-
|
|
51
|
-
node.attributes = (node.attributes ?? []).filter(
|
|
52
|
-
(a: any) => a.name !== 'highlightedHtml',
|
|
53
|
-
)
|
|
54
|
-
node.attributes.push({
|
|
55
|
-
type: 'mdxJsxAttribute',
|
|
56
|
-
name: 'highlightedHtml',
|
|
57
|
-
value: html,
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
}
|
package/src/node/plugin/entry.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { normalizePath } from '../utils'
|
|
2
|
-
import type { BoltdocsConfig } from '../config'
|
|
3
|
-
import type { BoltdocsPluginOptions } from './types'
|
|
4
|
-
import path from 'path'
|
|
5
|
-
import fs from 'fs'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Generates the raw source code for the virtual entry file (`\0virtual:boltdocs-entry`).
|
|
9
|
-
* This code initializes the client-side React application.
|
|
10
|
-
*
|
|
11
|
-
* @param options - Plugin options containing potential custom overrides (like `homePage` or `customCss`)
|
|
12
|
-
* @param config - The resolved Boltdocs configuration containing custom plugins and components
|
|
13
|
-
* @returns A string of JavaScript code to be evaluated by the browser
|
|
14
|
-
*/
|
|
15
|
-
export function generateEntryCode(
|
|
16
|
-
options: BoltdocsPluginOptions,
|
|
17
|
-
config?: BoltdocsConfig,
|
|
18
|
-
): string {
|
|
19
|
-
const homeImport = options.homePage
|
|
20
|
-
? `import HomePage from '${normalizePath(options.homePage)}';`
|
|
21
|
-
: ''
|
|
22
|
-
|
|
23
|
-
// Auto-import index.css if it exists
|
|
24
|
-
const cssPath = path.resolve(process.cwd(), 'index.css')
|
|
25
|
-
const cssImport = fs.existsSync(cssPath) ? "import './index.css';" : ''
|
|
26
|
-
|
|
27
|
-
let homeOption = options.homePage ? 'homePage: HomePage,' : ''
|
|
28
|
-
const pluginComponents =
|
|
29
|
-
config?.plugins?.flatMap((p) => Object.entries(p.components || {})) || []
|
|
30
|
-
|
|
31
|
-
const componentImports = pluginComponents
|
|
32
|
-
.map(
|
|
33
|
-
([
|
|
34
|
-
name,
|
|
35
|
-
path,
|
|
36
|
-
]) => `import * as _comp_${name} from '${normalizePath(path)}';
|
|
37
|
-
const ${name} = _comp_${name}.default || _comp_${name}['${name}'] || _comp_${name};`,
|
|
38
|
-
)
|
|
39
|
-
.join('\n')
|
|
40
|
-
const componentMap = pluginComponents.map(([name]) => name).join(', ')
|
|
41
|
-
|
|
42
|
-
const docsDirName = path.basename(options.docsDir || 'docs')
|
|
43
|
-
const docsDir = path.resolve(process.cwd(), options.docsDir || 'docs')
|
|
44
|
-
|
|
45
|
-
// Detect external pages module
|
|
46
|
-
const externalModulePath = ['tsx', 'ts', 'jsx', 'js']
|
|
47
|
-
.map((ext) => path.resolve(docsDir, `pages-external/index.${ext}`))
|
|
48
|
-
.find((p) => fs.existsSync(p))
|
|
49
|
-
|
|
50
|
-
const externalModuleImport = externalModulePath
|
|
51
|
-
? `import * as _external_module from '${normalizePath(externalModulePath)}';`
|
|
52
|
-
: ''
|
|
53
|
-
|
|
54
|
-
// Prioritize homePage from external module if it exists
|
|
55
|
-
homeOption = externalModulePath
|
|
56
|
-
? 'homePage: _external_module.homePage || HomePage,'
|
|
57
|
-
: options.homePage
|
|
58
|
-
? 'homePage: HomePage,'
|
|
59
|
-
: ''
|
|
60
|
-
|
|
61
|
-
const externalOption = externalModulePath
|
|
62
|
-
? 'externalPages: _external_module.pages, externalLayout: _external_module.layout,'
|
|
63
|
-
: ''
|
|
64
|
-
|
|
65
|
-
return `
|
|
66
|
-
import { createBoltdocsApp as _createApp } from 'boltdocs/client';
|
|
67
|
-
import _routes from 'virtual:boltdocs-routes';
|
|
68
|
-
import _config from 'virtual:boltdocs-config';
|
|
69
|
-
import _user_mdx_components from 'virtual:boltdocs-mdx-components';
|
|
70
|
-
${cssImport}
|
|
71
|
-
${homeImport}
|
|
72
|
-
${componentImports}
|
|
73
|
-
${externalModuleImport}
|
|
74
|
-
|
|
75
|
-
_createApp({
|
|
76
|
-
target: '#root',
|
|
77
|
-
routes: _routes,
|
|
78
|
-
docsDirName: '${docsDirName}',
|
|
79
|
-
config: _config,
|
|
80
|
-
modules: import.meta.glob('/${docsDirName}/**/*.{md,mdx}'),
|
|
81
|
-
hot: import.meta.hot,
|
|
82
|
-
${homeOption}
|
|
83
|
-
${externalOption}
|
|
84
|
-
components: { ${componentMap}${componentMap ? ', ' : ''} ...(_user_mdx_components || {}) },
|
|
85
|
-
});
|
|
86
|
-
`
|
|
87
|
-
}
|
package/src/node/plugin/html.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { BoltdocsConfig } from '../config'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Provides a default HTML template if none is found in the project root.
|
|
5
|
-
*/
|
|
6
|
-
export function getHtmlTemplate(config: BoltdocsConfig): string {
|
|
7
|
-
const title = config.theme?.title || 'Boltdocs'
|
|
8
|
-
return `<!doctype html>
|
|
9
|
-
<html lang="en">
|
|
10
|
-
<head>
|
|
11
|
-
<meta charset="UTF-8" />
|
|
12
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
13
|
-
<title>${title}</title>
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<div id="root"></div>
|
|
17
|
-
</body>
|
|
18
|
-
</html>`
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Injects OpenGraph, Twitter, and generic SEO meta tags into the final HTML output.
|
|
23
|
-
* Also ensures the virtual entry file is injected if it's missing (e.g., standard Vite index.html).
|
|
24
|
-
*
|
|
25
|
-
* @param html - {string} The original HTML string
|
|
26
|
-
* @param config - {BoltdocsConfig} The resolved Boltdocs configuration containing site metadata
|
|
27
|
-
* @returns {string} The modified HTML string with injected tags
|
|
28
|
-
*/
|
|
29
|
-
export function injectHtmlMeta(html: string, config: BoltdocsConfig): string {
|
|
30
|
-
const theme = config.theme
|
|
31
|
-
const title = theme?.title || 'Boltdocs'
|
|
32
|
-
const description = theme?.description || ''
|
|
33
|
-
|
|
34
|
-
// Determine favicon
|
|
35
|
-
let favicon = theme?.favicon
|
|
36
|
-
if (!favicon && theme?.logo) {
|
|
37
|
-
if (typeof theme.logo === 'string') {
|
|
38
|
-
favicon = theme.logo
|
|
39
|
-
} else {
|
|
40
|
-
favicon = theme.logo.light || theme.logo.dark
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const seoTags = [
|
|
45
|
-
favicon ? `<link rel="icon" href="${favicon}">` : '',
|
|
46
|
-
`<meta name="description" content="${description}">`,
|
|
47
|
-
`<meta property="og:title" content="${title}">`,
|
|
48
|
-
`<meta property="og:description" content="${description}">`,
|
|
49
|
-
theme?.ogImage
|
|
50
|
-
? `<meta property="og:image" content="${theme.ogImage}">`
|
|
51
|
-
: '',
|
|
52
|
-
`<meta property="og:type" content="website">`,
|
|
53
|
-
`<meta name="twitter:card" content="summary_large_image">`,
|
|
54
|
-
`<meta name="twitter:title" content="${title}">`,
|
|
55
|
-
`<meta name="twitter:description" content="${description}">`,
|
|
56
|
-
theme?.ogImage
|
|
57
|
-
? `<meta name="twitter:image" content="${theme.ogImage}">`
|
|
58
|
-
: '',
|
|
59
|
-
`<meta name="generator" content="Boltdocs">`,
|
|
60
|
-
]
|
|
61
|
-
.filter(Boolean)
|
|
62
|
-
.join('\n ')
|
|
63
|
-
|
|
64
|
-
const themeScript = `
|
|
65
|
-
<script>
|
|
66
|
-
(function() {
|
|
67
|
-
try {
|
|
68
|
-
var stored = localStorage.getItem("boltdocs-theme");
|
|
69
|
-
var theme = stored || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
|
|
70
|
-
if (theme === "light") {
|
|
71
|
-
document.documentElement.classList.add("theme-light");
|
|
72
|
-
document.documentElement.dataset.theme = "light";
|
|
73
|
-
} else {
|
|
74
|
-
document.documentElement.classList.remove("theme-light");
|
|
75
|
-
document.documentElement.dataset.theme = "dark";
|
|
76
|
-
}
|
|
77
|
-
} catch (e) {}
|
|
78
|
-
})();
|
|
79
|
-
</script>
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
// Use regex to replace title or inject it if missing
|
|
83
|
-
if (html.includes('<title>')) {
|
|
84
|
-
html = html.replace(/<title>.*?<\/title>/, `<title>${title}</title>`)
|
|
85
|
-
} else {
|
|
86
|
-
html = html.replace('</head>', ` <title>${title}</title>\n </head>`)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
html = html.replace('</head>', ` ${seoTags}\n${themeScript} </head>`)
|
|
90
|
-
|
|
91
|
-
if (!html.includes('src/main') && !html.includes('virtual:boltdocs-entry')) {
|
|
92
|
-
html = html.replace(
|
|
93
|
-
'</body>',
|
|
94
|
-
' <script type="module">import "virtual:boltdocs-entry";</script>\n </body>',
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return html
|
|
99
|
-
}
|