boltdocs 2.5.5 → 2.6.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.
- package/bin/boltdocs.js +2 -2
- package/dist/client/index.cjs +6 -0
- package/dist/client/index.d.cts +1560 -0
- package/dist/client/index.d.ts +1219 -922
- package/dist/client/index.js +6 -1
- package/dist/client/theme/neutral.css +428 -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 +519 -0
- package/dist/node/index.d.mts +374 -422
- package/dist/node/index.mjs +6 -1
- package/dist/node-BgvNl2Ay.mjs +89 -0
- package/dist/node-vkbb0MK7.cjs +89 -0
- package/dist/package-CR0HF9x3.mjs +6 -0
- package/dist/package-Dgmsc_l5.cjs +6 -0
- package/dist/search-dialog-3lvKsbVG.js +6 -0
- package/dist/search-dialog-DMK5OpgH.cjs +6 -0
- package/dist/use-search-C9bxCqfF.js +6 -0
- package/dist/use-search-DcfZSunO.cjs +6 -0
- package/package.json +26 -25
- package/src/client/app/config-context.tsx +38 -5
- package/src/client/app/doc-page.tsx +34 -0
- package/src/client/app/mdx-component.tsx +2 -3
- package/src/client/app/mdx-components-context.tsx +27 -2
- package/src/client/app/routes-context.tsx +34 -0
- package/src/client/app/scroll-handler.tsx +7 -4
- package/src/client/app/theme-context.tsx +71 -67
- package/src/client/components/default-layout.tsx +34 -33
- package/src/client/components/docs-layout.tsx +1 -2
- package/src/client/components/icons-dev.tsx +36 -5
- package/src/client/components/mdx/admonition.tsx +11 -27
- package/src/client/components/mdx/badge.tsx +1 -1
- package/src/client/components/mdx/button.tsx +3 -3
- package/src/client/components/mdx/card.tsx +1 -1
- package/src/client/components/mdx/code-block.tsx +90 -80
- package/src/client/components/mdx/component-preview.tsx +1 -5
- package/src/client/components/mdx/component-props.tsx +1 -1
- package/src/client/components/mdx/field.tsx +4 -5
- package/src/client/components/mdx/file-tree.tsx +6 -3
- package/src/client/components/mdx/hooks/use-code-block.ts +2 -2
- package/src/client/components/mdx/image.tsx +1 -1
- package/src/client/components/mdx/link.tsx +2 -2
- package/src/client/components/mdx/list.tsx +1 -1
- package/src/client/components/mdx/table.tsx +1 -1
- package/src/client/components/mdx/tabs.tsx +1 -1
- package/src/client/components/primitives/breadcrumbs.tsx +1 -7
- package/src/client/components/primitives/button-group.tsx +1 -1
- package/src/client/components/primitives/button.tsx +1 -1
- package/src/client/components/primitives/code-block.tsx +113 -0
- package/src/client/components/primitives/link.tsx +23 -41
- package/src/client/components/primitives/menu.tsx +5 -6
- package/src/client/components/primitives/navbar.tsx +6 -18
- package/src/client/components/primitives/navigation-menu.tsx +4 -4
- package/src/client/components/primitives/on-this-page.tsx +6 -10
- package/src/client/components/primitives/page-nav.tsx +4 -9
- package/src/client/components/primitives/popover.tsx +1 -1
- package/src/client/components/primitives/search-dialog.tsx +3 -6
- package/src/client/components/primitives/sidebar.tsx +80 -22
- package/src/client/components/primitives/skeleton.tsx +1 -1
- package/src/client/components/primitives/tabs.tsx +4 -11
- package/src/client/components/primitives/tooltip.tsx +3 -3
- package/src/client/components/ui-base/breadcrumbs.tsx +4 -6
- package/src/client/components/ui-base/copy-markdown.tsx +2 -7
- package/src/client/components/ui-base/github-stars.tsx +2 -2
- package/src/client/components/ui-base/head.tsx +58 -51
- package/src/client/components/ui-base/loading.tsx +2 -2
- package/src/client/components/ui-base/navbar.tsx +12 -14
- package/src/client/components/ui-base/not-found.tsx +1 -1
- package/src/client/components/ui-base/on-this-page.tsx +6 -6
- package/src/client/components/ui-base/page-nav.tsx +4 -8
- package/src/client/components/ui-base/search-dialog.tsx +10 -8
- package/src/client/components/ui-base/sidebar.tsx +76 -23
- package/src/client/components/ui-base/tabs.tsx +9 -8
- package/src/client/components/ui-base/theme-toggle.tsx +2 -2
- package/src/client/hooks/use-i18n.ts +3 -3
- package/src/client/hooks/use-localized-to.ts +1 -1
- package/src/client/hooks/use-navbar.ts +8 -6
- package/src/client/hooks/use-routes.ts +19 -11
- package/src/client/hooks/use-search.ts +1 -1
- package/src/client/hooks/use-sidebar.ts +48 -2
- package/src/client/hooks/use-tabs.ts +6 -2
- package/src/client/hooks/use-version.ts +3 -3
- package/src/client/index.ts +22 -22
- package/src/client/ssg/boltdocs-shell.tsx +127 -0
- package/src/client/ssg/create-routes.tsx +179 -0
- package/src/client/ssg/index.ts +3 -0
- package/src/client/ssg/mdx-page.tsx +37 -0
- package/src/client/store/boltdocs-context.tsx +66 -0
- package/src/client/theme/neutral.css +90 -50
- package/src/client/types.ts +5 -33
- package/src/client/utils/react-to-text.ts +34 -0
- package/CHANGELOG.md +0 -98
- package/dist/cache-3FOEPC2P.mjs +0 -1
- package/dist/chunk-5B5NKOW6.mjs +0 -77
- package/dist/chunk-J2PTDWZM.mjs +0 -1
- package/dist/chunk-TP5KMRD3.mjs +0 -1
- package/dist/chunk-Y4RE5KI7.mjs +0 -1
- package/dist/client/index.d.mts +0 -1263
- package/dist/client/index.mjs +0 -1
- package/dist/client/ssr.d.mts +0 -78
- package/dist/client/ssr.d.ts +0 -78
- package/dist/client/ssr.js +0 -1
- package/dist/client/ssr.mjs +0 -1
- package/dist/node/cli-entry.d.ts +0 -1
- package/dist/node/cli-entry.js +0 -82
- package/dist/node/index.d.ts +0 -567
- package/dist/node/index.js +0 -77
- package/dist/package-QFIAETHR.mjs +0 -1
- package/dist/search-dialog-O6VLVSOA.mjs +0 -1
- package/src/client/app/index.tsx +0 -345
- package/src/client/app/mdx-page.tsx +0 -15
- package/src/client/app/preload.tsx +0 -66
- package/src/client/app/router.tsx +0 -30
- package/src/client/integrations/codesandbox.ts +0 -179
- package/src/client/integrations/index.ts +0 -1
- package/src/client/ssr.tsx +0 -65
- 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 -478
- 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,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standard Security Headers for hardened web applications.
|
|
3
|
-
* Recommended by OWASP and industry best practices to prevent common web attacks.
|
|
4
|
-
*
|
|
5
|
-
* These can be applied as middleware in HTTP servers or as metadata in SSG deployments.
|
|
6
|
-
*/
|
|
7
|
-
export const SECURITY_HEADERS = {
|
|
8
|
-
/** Prevents MIME type sniffing by the browser. */
|
|
9
|
-
'X-Content-Type-Options': 'nosniff',
|
|
10
|
-
|
|
11
|
-
/** Prevents the page from being embedded in iframes (anti-clickjacking). */
|
|
12
|
-
'X-Frame-Options': 'DENY',
|
|
13
|
-
|
|
14
|
-
/** Enables XSS filtering in modern browsers (legacy support). */
|
|
15
|
-
'X-XSS-Protection': '1; mode=block',
|
|
16
|
-
|
|
17
|
-
/** Controls how much referrer information is sent with requests. */
|
|
18
|
-
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
|
19
|
-
|
|
20
|
-
/** Restricts access to sensitive browser features (camera, mic, geo). */
|
|
21
|
-
'Permissions-Policy': 'camera=(), microphone=(), geolocation=()',
|
|
22
|
-
|
|
23
|
-
/** Enforces HTTPS for the domain and all subdomains for 1 year. */
|
|
24
|
-
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
|
|
25
|
-
} as const;
|
|
26
|
-
|
|
27
|
-
export type SecurityHeaderKey = keyof typeof SECURITY_HEADERS;
|
package/src/node/ssg/index.ts
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import { generateRoutes } from '../routes'
|
|
4
|
-
import { escapeHtml, getTranslated } from '../utils'
|
|
5
|
-
import { fileURLToPath } from 'url'
|
|
6
|
-
import { createRequire } from 'module'
|
|
7
|
-
|
|
8
|
-
import type { SSGOptions } from './options'
|
|
9
|
-
import { replaceMetaTags } from './meta'
|
|
10
|
-
import { generateSitemap } from './sitemap'
|
|
11
|
-
import { generateRobotsTxt } from './robots'
|
|
12
|
-
|
|
13
|
-
// Re-export options for consumers
|
|
14
|
-
export type { SSGOptions }
|
|
15
|
-
|
|
16
|
-
// Polyfill __dirname and require for ESM
|
|
17
|
-
const _filename = fileURLToPath(import.meta.url)
|
|
18
|
-
const _dirname = path.dirname(_filename)
|
|
19
|
-
const _require = createRequire(import.meta.url)
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Generates static HTML files and a \`sitemap.xml\` for all documentation routes.
|
|
23
|
-
* Called automatically in the \`closeBundle\` hook of the Vite plugin during a production build.
|
|
24
|
-
*
|
|
25
|
-
* @param options - Configuration for paths and site metadata
|
|
26
|
-
*/
|
|
27
|
-
export async function generateStaticPages(options: SSGOptions): Promise<void> {
|
|
28
|
-
const { docsDir, docsDirName, outDir, config } = options
|
|
29
|
-
const routes = await generateRoutes(docsDir, config)
|
|
30
|
-
|
|
31
|
-
// Detect external routes to include in SSG
|
|
32
|
-
const externalModulePath = ['tsx', 'ts', 'jsx', 'js']
|
|
33
|
-
.map((ext) => path.resolve(docsDir, `pages-external/index.${ext}`))
|
|
34
|
-
.find((p) => fs.existsSync(p))
|
|
35
|
-
|
|
36
|
-
if (externalModulePath) {
|
|
37
|
-
try {
|
|
38
|
-
// We use a simple way to get the keys of the 'pages' export
|
|
39
|
-
// Since we can't easily execute TSX in this context without a bundler,
|
|
40
|
-
// we'll at least try to generate placeholder pages for them
|
|
41
|
-
// OR we can try to use 'esbuild' to get the exports
|
|
42
|
-
const content = fs.readFileSync(externalModulePath, 'utf-8')
|
|
43
|
-
const pagesMatch = content.match(/pages\s*:\s*{([^}]+)}/s)
|
|
44
|
-
if (pagesMatch) {
|
|
45
|
-
const paths = pagesMatch[1]
|
|
46
|
-
.split(',')
|
|
47
|
-
.map((line) => line.split(':')[0].trim().replace(/['"]/g, ''))
|
|
48
|
-
.filter((p) => p && p.startsWith('/'))
|
|
49
|
-
|
|
50
|
-
for (const p of paths) {
|
|
51
|
-
if (!routes.some((r) => r.path === p)) {
|
|
52
|
-
routes.push({
|
|
53
|
-
path: p,
|
|
54
|
-
title: p.slice(1).charAt(0).toUpperCase() + p.slice(2),
|
|
55
|
-
filePath: '',
|
|
56
|
-
componentPath: '',
|
|
57
|
-
_content: '',
|
|
58
|
-
} as any)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Always include home page if it might be custom
|
|
64
|
-
if (content.includes('homePage') && !routes.some((r) => r.path === '/')) {
|
|
65
|
-
routes.push({
|
|
66
|
-
path: '/',
|
|
67
|
-
title: 'Home',
|
|
68
|
-
filePath: '',
|
|
69
|
-
componentPath: '',
|
|
70
|
-
_content: '',
|
|
71
|
-
} as any)
|
|
72
|
-
}
|
|
73
|
-
} catch (e) {
|
|
74
|
-
console.warn('[boltdocs] Failed to parse external routes for SSG:', e)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Resolve the SSR module (compiled by tsup)
|
|
79
|
-
const ssrModulePath = path.resolve(_dirname, '../client/ssr.js')
|
|
80
|
-
if (!fs.existsSync(ssrModulePath)) {
|
|
81
|
-
console.error(
|
|
82
|
-
'[boltdocs] SSR module not found at',
|
|
83
|
-
ssrModulePath,
|
|
84
|
-
'- Did you build the core package?',
|
|
85
|
-
)
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Mock require so Node doesn't choke on virtual modules compiled externally
|
|
90
|
-
const Module = _require('module')
|
|
91
|
-
const originalRequire = Module.prototype.require
|
|
92
|
-
;(Module.prototype as any).require = function (id: string, ...args: any[]) {
|
|
93
|
-
if (id.startsWith('virtual:boltdocs-')) {
|
|
94
|
-
if (id === 'virtual:boltdocs-layout') {
|
|
95
|
-
return {
|
|
96
|
-
__esModule: true,
|
|
97
|
-
default: function SSG_Virtual_Layout(props: any) {
|
|
98
|
-
try {
|
|
99
|
-
const client = originalRequire.apply(this, [
|
|
100
|
-
path.resolve(_dirname, '../client/index.js'),
|
|
101
|
-
])
|
|
102
|
-
const Comp =
|
|
103
|
-
client.DefaultLayout || (({ children }: any) => children)
|
|
104
|
-
const React = originalRequire.apply(this, ['react'])
|
|
105
|
-
return React.createElement(Comp, props)
|
|
106
|
-
} catch (e) {
|
|
107
|
-
return props.children
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (id === 'virtual:boltdocs-mdx-components') {
|
|
114
|
-
return { __esModule: true, default: {} }
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (id === 'virtual:boltdocs-config') {
|
|
118
|
-
return { __esModule: true, default: config }
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Safe fallback for other virtual modules
|
|
122
|
-
return { __esModule: true, default: id.includes('routes') ? [] : {} }
|
|
123
|
-
}
|
|
124
|
-
return originalRequire.apply(this, [id, ...args])
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const { render } = _require(ssrModulePath)
|
|
128
|
-
|
|
129
|
-
// Restore require after loading the module
|
|
130
|
-
;(Module.prototype as any).require = originalRequire
|
|
131
|
-
|
|
132
|
-
// Read the built index.html as template
|
|
133
|
-
const templatePath = path.join(outDir, 'index.html')
|
|
134
|
-
if (!fs.existsSync(templatePath)) {
|
|
135
|
-
console.warn('[boltdocs] No index.html found in outDir, skipping SSG.')
|
|
136
|
-
return
|
|
137
|
-
}
|
|
138
|
-
const template = fs.readFileSync(templatePath, 'utf-8')
|
|
139
|
-
|
|
140
|
-
// Generate an HTML file for each route concurrently
|
|
141
|
-
await Promise.all(
|
|
142
|
-
routes.map(async (route) => {
|
|
143
|
-
const siteTitle =
|
|
144
|
-
getTranslated(config?.theme?.title, route.locale) || 'Boltdocs'
|
|
145
|
-
const siteDescription =
|
|
146
|
-
getTranslated(config?.theme?.description, route.locale) || ''
|
|
147
|
-
const pageTitle = `${route.title} | ${siteTitle}`
|
|
148
|
-
const pageDescription = route.description || siteDescription
|
|
149
|
-
|
|
150
|
-
// We mock the modules for SSR so it doesn't crash trying to dynamically import
|
|
151
|
-
const fakeModules: Record<string, any> = {}
|
|
152
|
-
fakeModules[`/${docsDirName}/${route.filePath}`] = { default: () => null } // Mock MDX component
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
const appHtml = await render({
|
|
156
|
-
path: route.path,
|
|
157
|
-
routes: routes,
|
|
158
|
-
config: config || {},
|
|
159
|
-
docsDirName: docsDirName,
|
|
160
|
-
modules: fakeModules,
|
|
161
|
-
homePage: undefined, // No custom home page for now
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const html = replaceMetaTags(template, {
|
|
165
|
-
title: escapeHtml(pageTitle),
|
|
166
|
-
description: escapeHtml(pageDescription),
|
|
167
|
-
})
|
|
168
|
-
.replace('<!--app-html-->', appHtml)
|
|
169
|
-
.replace(`<div id="root"></div>`, `<div id="root">${appHtml}</div>`)
|
|
170
|
-
|
|
171
|
-
const routeDir = path.join(outDir, route.path)
|
|
172
|
-
await fs.promises.mkdir(routeDir, { recursive: true })
|
|
173
|
-
await fs.promises.writeFile(
|
|
174
|
-
path.join(routeDir, 'index.html'),
|
|
175
|
-
html,
|
|
176
|
-
'utf-8',
|
|
177
|
-
)
|
|
178
|
-
} catch (e: any) {
|
|
179
|
-
console.error(
|
|
180
|
-
`[boltdocs] Error SSR rendering route ${route.path}:`,
|
|
181
|
-
e ? e.stack || e : e,
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
}),
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
// Generate sitemap.xml
|
|
188
|
-
const sitemap = generateSitemap(
|
|
189
|
-
routes.map((r) => r.path),
|
|
190
|
-
config,
|
|
191
|
-
)
|
|
192
|
-
fs.writeFileSync(path.join(outDir, 'sitemap.xml'), sitemap, 'utf-8')
|
|
193
|
-
|
|
194
|
-
// Generate robots.txt
|
|
195
|
-
const robots = generateRobotsTxt(config!)
|
|
196
|
-
fs.writeFileSync(path.join(outDir, 'robots.txt'), robots, 'utf-8')
|
|
197
|
-
|
|
198
|
-
console.log(
|
|
199
|
-
`[boltdocs] Generated ${routes.length} static pages + sitemap.xml + robots.txt`,
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
// Ensure all cache operations (like index persistence) are finished
|
|
203
|
-
const { flushCache } = await import('../cache')
|
|
204
|
-
await flushCache()
|
|
205
|
-
}
|
package/src/node/ssg/meta.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { escapeHtml } from '../utils'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Replaces placeholder or default meta tags in the HTML template with page-specific values.
|
|
5
|
-
*
|
|
6
|
-
* @param html - The base HTML template string
|
|
7
|
-
* @param meta - An object containing the derived `title` and `description` for the specific page
|
|
8
|
-
* @returns The final HTML string for that specific page
|
|
9
|
-
*/
|
|
10
|
-
export function replaceMetaTags(
|
|
11
|
-
html: string,
|
|
12
|
-
meta: { title: string; description: string },
|
|
13
|
-
): string {
|
|
14
|
-
const title = escapeHtml(meta.title)
|
|
15
|
-
const description = escapeHtml(meta.description)
|
|
16
|
-
|
|
17
|
-
return html
|
|
18
|
-
.replace(/<title>.*?<\/title>/, `<title>${title}</title>`)
|
|
19
|
-
.replace(
|
|
20
|
-
/(<meta name="description" content=")[^"]*(")/,
|
|
21
|
-
`$1${description}$2`,
|
|
22
|
-
)
|
|
23
|
-
.replace(/(<meta property="og:title" content=")[^"]*(")/, `$1${title}$2`)
|
|
24
|
-
.replace(
|
|
25
|
-
/(<meta property="og:description" content=")[^"]*(")/,
|
|
26
|
-
`$1${description}$2`,
|
|
27
|
-
)
|
|
28
|
-
.replace(/(<meta name="twitter:title" content=")[^"]*(")/, `$1${title}$2`)
|
|
29
|
-
.replace(
|
|
30
|
-
/(<meta name="twitter:description" content=")[^"]*(")/,
|
|
31
|
-
`$1${description}$2`,
|
|
32
|
-
)
|
|
33
|
-
}
|
package/src/node/ssg/options.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { BoltdocsConfig } from '../config'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Options for the Static Site Generation process.
|
|
5
|
-
*/
|
|
6
|
-
export interface SSGOptions {
|
|
7
|
-
/** The root directory containing markdown documentation files */
|
|
8
|
-
docsDir: string
|
|
9
|
-
/** The name of the documentation directory (e.g. 'docs') */
|
|
10
|
-
docsDirName: string
|
|
11
|
-
/** The output directory where Vite placed the compiled `index.html` and assets */
|
|
12
|
-
outDir: string
|
|
13
|
-
/** Pre-resolved config (avoids re-resolving during the SSG phase) */
|
|
14
|
-
config?: BoltdocsConfig
|
|
15
|
-
}
|
package/src/node/ssg/robots.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { BoltdocsConfig } from '../config'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generates the content for a robots.txt file based on the Boltdocs configuration.
|
|
5
|
-
*
|
|
6
|
-
* @param config - The resolved Boltdocs configuration
|
|
7
|
-
* @returns The formatted robots.txt string
|
|
8
|
-
*/
|
|
9
|
-
export function generateRobotsTxt(config: BoltdocsConfig): string {
|
|
10
|
-
if (typeof config.robots === 'string') {
|
|
11
|
-
return config.robots
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const siteUrl = config.siteUrl?.replace(/\/$/, '') || ''
|
|
15
|
-
const robots = config.robots || {}
|
|
16
|
-
const rules = (robots as any).rules || [
|
|
17
|
-
{
|
|
18
|
-
userAgent: '*',
|
|
19
|
-
allow: '/',
|
|
20
|
-
},
|
|
21
|
-
]
|
|
22
|
-
const sitemaps =
|
|
23
|
-
(robots as any).sitemaps || (siteUrl ? [`${siteUrl}/sitemap.xml`] : [])
|
|
24
|
-
|
|
25
|
-
let content = ''
|
|
26
|
-
|
|
27
|
-
for (const rule of rules) {
|
|
28
|
-
content += `User-agent: ${rule.userAgent}\n`
|
|
29
|
-
|
|
30
|
-
if (rule.disallow) {
|
|
31
|
-
const disallows = Array.isArray(rule.disallow)
|
|
32
|
-
? rule.disallow
|
|
33
|
-
: [rule.disallow]
|
|
34
|
-
for (const d of disallows) {
|
|
35
|
-
content += `Disallow: ${d}\n`
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (rule.allow) {
|
|
40
|
-
const allows = Array.isArray(rule.allow) ? rule.allow : [rule.allow]
|
|
41
|
-
for (const a of allows) {
|
|
42
|
-
content += `Allow: ${a}\n`
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
content += '\n'
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
for (const sitemap of sitemaps) {
|
|
49
|
-
content += `Sitemap: ${sitemap}\n`
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return content.trim()
|
|
53
|
-
}
|
package/src/node/ssg/sitemap.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { BoltdocsConfig } from '../config'
|
|
2
|
-
import { escapeXml } from '../utils'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generates a standard XML sitemap for search engine crawlers.
|
|
6
|
-
*
|
|
7
|
-
* @param routePaths - An array of existing URL paths (e.g., ['/docs/intro', '/docs/setup'])
|
|
8
|
-
* @param config - The Boltdocs configuration containing i18n and siteUrl settings
|
|
9
|
-
* @returns The formatted XML sitemap string
|
|
10
|
-
*/
|
|
11
|
-
export function generateSitemap(
|
|
12
|
-
routePaths: string[],
|
|
13
|
-
config?: BoltdocsConfig,
|
|
14
|
-
): string {
|
|
15
|
-
const baseUrl = config?.siteUrl?.replace(/\/$/, '') || 'https://example.com'
|
|
16
|
-
const today = new Date().toISOString().split('T')[0]
|
|
17
|
-
|
|
18
|
-
const rootEntries = [{ url: '/', priority: '1.0', changefreq: 'daily' }]
|
|
19
|
-
|
|
20
|
-
if (config?.i18n) {
|
|
21
|
-
const defaultLocale = config.i18n.defaultLocale
|
|
22
|
-
for (const locale of Object.keys(config.i18n.locales)) {
|
|
23
|
-
if (locale !== defaultLocale) {
|
|
24
|
-
rootEntries.push({
|
|
25
|
-
url: `/${locale}/`,
|
|
26
|
-
priority: '1.0',
|
|
27
|
-
changefreq: 'daily',
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const entries = [
|
|
34
|
-
...rootEntries,
|
|
35
|
-
...routePaths.map((p) => ({
|
|
36
|
-
url: p,
|
|
37
|
-
priority: '0.8',
|
|
38
|
-
changefreq: 'weekly',
|
|
39
|
-
})),
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
43
|
-
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
44
|
-
${entries
|
|
45
|
-
.map(
|
|
46
|
-
(e) => ` <url>
|
|
47
|
-
<loc>${escapeXml(baseUrl)}${escapeXml(e.url)}</loc>
|
|
48
|
-
<lastmod>${today}</lastmod>
|
|
49
|
-
<changefreq>${e.changefreq}</changefreq>
|
|
50
|
-
<priority>${e.priority}</priority>
|
|
51
|
-
</url>`,
|
|
52
|
-
)
|
|
53
|
-
.join('\n')}
|
|
54
|
-
</urlset>`
|
|
55
|
-
}
|