boltdocs 2.5.5 → 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.
Files changed (96) hide show
  1. package/bin/boltdocs.js +1 -1
  2. package/dist/cache-Cr8W2zgZ.cjs +6 -0
  3. package/dist/cache-DFdakSmR.mjs +6 -0
  4. package/dist/client/index.d.mts +1276 -861
  5. package/dist/client/index.d.ts +1276 -861
  6. package/dist/client/index.js +6 -1
  7. package/dist/client/index.mjs +6 -1
  8. package/dist/client/ssr.cjs +6 -0
  9. package/dist/client/ssr.d.cts +80 -0
  10. package/dist/client/ssr.d.mts +63 -61
  11. package/dist/client/ssr.mjs +6 -1
  12. package/dist/client/theme/neutral.css +388 -0
  13. package/dist/node/cli-entry.cjs +8 -0
  14. package/dist/node/cli-entry.d.cts +2 -0
  15. package/dist/node/cli-entry.d.mts +2 -1
  16. package/dist/node/cli-entry.mjs +7 -5
  17. package/dist/node/index.cjs +6 -0
  18. package/dist/node/index.d.cts +574 -0
  19. package/dist/node/index.d.mts +385 -378
  20. package/dist/node/index.mjs +6 -1
  21. package/dist/node-CWXme96p.mjs +73 -0
  22. package/dist/node-VYfhzGrh.cjs +73 -0
  23. package/dist/package-BY8Jd2j4.cjs +6 -0
  24. package/dist/package-OFZf0s2j.mjs +6 -0
  25. package/dist/search-dialog-BeNyI_KQ.mjs +6 -0
  26. package/dist/search-dialog-dYsCAk5S.js +6 -0
  27. package/dist/use-search-D25n0PrV.mjs +6 -0
  28. package/dist/use-search-WuzdH1cJ.js +6 -0
  29. package/package.json +16 -12
  30. package/src/client/app/index.tsx +15 -12
  31. package/src/client/components/default-layout.tsx +21 -19
  32. package/src/client/hooks/use-i18n.ts +1 -1
  33. package/src/client/hooks/use-routes.ts +1 -1
  34. package/src/client/hooks/use-version.ts +1 -1
  35. package/src/client/store/boltdocs-context.tsx +119 -0
  36. package/CHANGELOG.md +0 -98
  37. package/dist/cache-3FOEPC2P.mjs +0 -1
  38. package/dist/chunk-5B5NKOW6.mjs +0 -77
  39. package/dist/chunk-J2PTDWZM.mjs +0 -1
  40. package/dist/chunk-TP5KMRD3.mjs +0 -1
  41. package/dist/chunk-Y4RE5KI7.mjs +0 -1
  42. package/dist/client/ssr.d.ts +0 -78
  43. package/dist/client/ssr.js +0 -1
  44. package/dist/node/cli-entry.d.ts +0 -1
  45. package/dist/node/cli-entry.js +0 -82
  46. package/dist/node/index.d.ts +0 -567
  47. package/dist/node/index.js +0 -77
  48. package/dist/package-QFIAETHR.mjs +0 -1
  49. package/dist/search-dialog-O6VLVSOA.mjs +0 -1
  50. package/src/client/store/use-boltdocs-store.ts +0 -44
  51. package/src/node/cache.ts +0 -408
  52. package/src/node/cli/build.ts +0 -53
  53. package/src/node/cli/dev.ts +0 -22
  54. package/src/node/cli/doctor.ts +0 -243
  55. package/src/node/cli/index.ts +0 -9
  56. package/src/node/cli/ui.ts +0 -54
  57. package/src/node/cli-entry.ts +0 -24
  58. package/src/node/config.ts +0 -382
  59. package/src/node/errors.ts +0 -44
  60. package/src/node/index.ts +0 -84
  61. package/src/node/mdx/cache.ts +0 -12
  62. package/src/node/mdx/highlighter.ts +0 -47
  63. package/src/node/mdx/index.ts +0 -122
  64. package/src/node/mdx/rehype-shiki.ts +0 -62
  65. package/src/node/mdx/remark-code-meta.ts +0 -35
  66. package/src/node/mdx/remark-shiki.ts +0 -61
  67. package/src/node/plugin/entry.ts +0 -87
  68. package/src/node/plugin/html.ts +0 -99
  69. package/src/node/plugin/index.ts +0 -478
  70. package/src/node/plugin/types.ts +0 -9
  71. package/src/node/plugins/index.ts +0 -17
  72. package/src/node/plugins/plugin-errors.ts +0 -62
  73. package/src/node/plugins/plugin-lifecycle.ts +0 -117
  74. package/src/node/plugins/plugin-sandbox.ts +0 -59
  75. package/src/node/plugins/plugin-store.ts +0 -54
  76. package/src/node/plugins/plugin-types.ts +0 -107
  77. package/src/node/plugins/plugin-validator.ts +0 -105
  78. package/src/node/routes/cache.ts +0 -28
  79. package/src/node/routes/index.ts +0 -293
  80. package/src/node/routes/parser.ts +0 -262
  81. package/src/node/routes/sorter.ts +0 -42
  82. package/src/node/routes/types.ts +0 -61
  83. package/src/node/schema/config.ts +0 -195
  84. package/src/node/schema/frontmatter.ts +0 -17
  85. package/src/node/search/index.ts +0 -55
  86. package/src/node/security/constants/index.ts +0 -10
  87. package/src/node/security/csp.ts +0 -31
  88. package/src/node/security/headers.ts +0 -27
  89. package/src/node/ssg/index.ts +0 -205
  90. package/src/node/ssg/meta.ts +0 -33
  91. package/src/node/ssg/options.ts +0 -15
  92. package/src/node/ssg/robots.ts +0 -53
  93. package/src/node/ssg/sitemap.ts +0 -55
  94. package/src/node/utils.ts +0 -349
  95. package/tsconfig.json +0 -26
  96. package/tsup.config.ts +0 -56
package/src/node/utils.ts DELETED
@@ -1,349 +0,0 @@
1
- import fs from 'fs'
2
- import matter from 'gray-matter'
3
- import DOMPurify from 'isomorphic-dompurify'
4
- import {
5
- MAX_PATH_LENGTH,
6
- ALLOWED_PATH_CHARS,
7
- MAX_FRONTMATTER_SIZE,
8
- } from './security/constants'
9
- import {
10
- FrontmatterSchema,
11
- type FrontmatterData,
12
- } from './schema/frontmatter'
13
-
14
- export {
15
- MAX_PATH_LENGTH,
16
- ALLOWED_PATH_CHARS,
17
- MAX_FRONTMATTER_SIZE,
18
- FrontmatterSchema,
19
- type FrontmatterData,
20
- }
21
- import { ValidationError } from './errors'
22
-
23
- // Removed centralized constants - now in security.config.ts
24
-
25
- /**
26
- * Normalizes a file path by replacing Windows backslashes with forward slashes.
27
- * Ensures consistent path handling across different operating systems.
28
- *
29
- * @param p - The file path to normalize
30
- * @returns The normalized path using forward slashes
31
- */
32
- export function normalizePath(p: string): string {
33
- return p.replace(/\\/g, '/')
34
- }
35
-
36
- /**
37
- * Strips a numeric prefix from a file or directory name (e.g., '1.guide' -> 'guide').
38
- *
39
- * @param name - The name to strip
40
- * @returns The name without the numeric prefix
41
- */
42
- export function stripNumberPrefix(name: string): string {
43
- return name.replace(/^\d+\./, '')
44
- }
45
-
46
- /**
47
- * Extracts the numeric prefix from a file or directory name if it exists.
48
- *
49
- * @param name - The name to parse
50
- * @returns The extracted number, or undefined if none exists
51
- */
52
- export function extractNumberPrefix(name: string): number | undefined {
53
- const match = name.match(/^(\d+)\./)
54
- return match ? parseInt(match[1], 10) : undefined
55
- }
56
-
57
- /**
58
- * Checks if a given file path points to a Markdown or MDX file.
59
- *
60
- * @param filePath - The path to check
61
- * @returns True if the file ends with .md or .mdx, false otherwise
62
- */
63
- export function isDocFile(filePath: string): boolean {
64
- return /\.mdx?$/.test(filePath)
65
- }
66
-
67
- /**
68
- * Retrieves the modification time (mtime) of a file in milliseconds.
69
- * Useful for caching strategies to detect if a file has changed.
70
- * Returns 0 if the file doesn't exist or cannot be accessed.
71
- *
72
- * @param filePath - The absolute path to the file
73
- * @returns The modification time in milliseconds, or 0 on error
74
- */
75
- export function getFileMtime(filePath: string): number {
76
- try {
77
- return fs.statSync(filePath).mtimeMs
78
- } catch {
79
- return 0
80
- }
81
- }
82
-
83
- /**
84
- * Parses frontmatter and markdown content from a file synchronously.
85
- * Uses `gray-matter` for parsing. Returns the parsed data and the remaining markdown content.
86
- *
87
- * @param filePath - The absolute path to the markdown/mdx file
88
- * @returns An object containing the parsed metadata (`data`) and the raw markdown (`content`)
89
- */
90
- export function parseFrontmatter(filePath: string): {
91
- data: Record<string, any>
92
- content: string
93
- } {
94
- const raw = fs.readFileSync(filePath, 'utf-8')
95
- try {
96
- const { data, content, matter: rawMatter } = matter(raw)
97
-
98
- // Security: Check frontmatter size
99
- if (rawMatter && rawMatter.length > MAX_FRONTMATTER_SIZE) {
100
- logSecurityEvent('FRONTMATTER_TOO_LARGE', 'Frontmatter block exceeds size limit', {
101
- size: rawMatter.length,
102
- file: filePath,
103
- })
104
- throw new ValidationError(
105
- `Security breach: Frontmatter size exceeds limit of ${MAX_FRONTMATTER_SIZE} bytes`,
106
- )
107
- }
108
-
109
- // Validation: Schema check
110
- const result = FrontmatterSchema.safeParse(data)
111
- if (!result.success) {
112
- // We could log this or throw, but for metadata we'll just filter invalid fields
113
- // or we can be strict as requested.
114
- // The task says "Integrar validación de esquema con Zod".
115
- // Let's log it.
116
- console.warn(`[VALIDATION][${filePath}] Invalid frontmatter fields detected.`)
117
- }
118
-
119
- // Explicitly allow only known fields from the schema for security (unless we use passthrough)
120
- const validatedData = result.success ? result.data : {}
121
-
122
- // Sanitization: Clean metadata fields
123
- const sanitizedData: any = { ...validatedData }
124
- if (sanitizedData.title) sanitizedData.title = stripHtmlTags(sanitizedData.title).trim()
125
- if (sanitizedData.description)
126
- sanitizedData.description = stripHtmlTags(sanitizedData.description).trim()
127
-
128
- return { data: sanitizedData, content }
129
- } catch (e) {
130
- if (e instanceof ValidationError) throw e
131
- // If frontmatter is malformed (e.g. while editing), return empty data and raw content
132
- return { data: {}, content: raw }
133
- }
134
- }
135
-
136
- /**
137
- * Escapes special HTML characters in a string to prevent XSS and ensure
138
- * safe injection into HTML attributes or text content.
139
- *
140
- * @param str - The raw string to escape
141
- * @returns The escaped string
142
- */
143
- export function escapeHtml(str: string): string {
144
- return str
145
- .replace(/&/g, '&amp;')
146
- .replace(/"/g, '&quot;')
147
- .replace(/'/g, '&apos;')
148
- .replace(/</g, '&lt;')
149
- .replace(/>/g, '&gt;')
150
- }
151
-
152
- /**
153
- * Alias for escapeHtml to be used in XML contexts (like sitemaps).
154
- *
155
- * @param str - The raw string to escape
156
- * @returns The escaped string
157
- */
158
- export function escapeXml(str: string): string {
159
- return escapeHtml(str)
160
- }
161
-
162
- /**
163
- * Converts a file path relative to the `docsDir` into a URL route path.
164
- * Handles removing extensions, converting `index` files to directory roots,
165
- * and ensuring proper slash formatting.
166
- *
167
- * @param relativePath - The file path relative to the documentation source directory (e.g., 'guide/index.md')
168
- * @returns The corresponding route path (e.g., '/guide')
169
- */
170
- export function fileToRoutePath(relativePath: string): string {
171
- // Strip number prefixes and sanitize each segment
172
- let cleanedPath = relativePath
173
- .split('/')
174
- .map((p) => stripNumberPrefix(sanitizeFilename(p)))
175
- .join('/')
176
-
177
- // Remove trailing slash if present
178
- let routePath = cleanedPath.replace(/\/$/, '')
179
-
180
- routePath = routePath.replace(/\.mdx?$/, '')
181
-
182
- // Handle index files → directory root
183
- if (routePath === 'index' || routePath.endsWith('/index')) {
184
- routePath = routePath.replace(/index$/, '')
185
- }
186
-
187
- // Ensure leading slash
188
- if (!routePath.startsWith('/')) {
189
- routePath = '/' + routePath
190
- }
191
-
192
- // Remove trailing slash (except for root '/')
193
- if (routePath.length > 1 && routePath.endsWith('/')) {
194
- routePath = routePath.slice(0, -1)
195
- }
196
-
197
- return routePath
198
- }
199
-
200
- /**
201
- * Sanitizes an HTML string using DOMPurify to prevent XSS.
202
- * By default, it allows a safe subset of HTML tags.
203
- *
204
- * @param html - The raw HTML string
205
- * @returns The sanitized HTML
206
- */
207
- export function sanitizeHtml(html: string): string {
208
- return DOMPurify.sanitize(html, {
209
- ALLOWED_TAGS: [
210
- 'b',
211
- 'i',
212
- 'em',
213
- 'strong',
214
- 'a',
215
- 'p',
216
- 'br',
217
- 'code',
218
- 'pre',
219
- 'span',
220
- 'div',
221
- 'h1',
222
- 'h2',
223
- 'h3',
224
- 'h4',
225
- 'h5',
226
- 'h6',
227
- 'ul',
228
- 'ol',
229
- 'li',
230
- 'table',
231
- 'thead',
232
- 'tbody',
233
- 'tr',
234
- 'th',
235
- 'td',
236
- 'blockquote',
237
- 'hr',
238
- ],
239
- ALLOWED_ATTR: ['href', 'title', 'target', 'class', 'id', 'src', 'alt', 'width', 'height'],
240
- FORCE_BODY: true,
241
- })
242
- }
243
-
244
- // Security Hook: Validate URL protocols in href/src
245
- DOMPurify.addHook('afterSanitizeAttributes', (node) => {
246
- // Check for href
247
- if (node.hasAttribute('href')) {
248
- const href = node.getAttribute('href')?.toLowerCase() || ''
249
- if (href.startsWith('javascript:') || href.startsWith('data:') || href.startsWith('vbscript:')) {
250
- node.removeAttribute('href')
251
- }
252
- }
253
- // Check for src
254
- if (node.hasAttribute('src')) {
255
- const src = node.getAttribute('src')?.toLowerCase() || ''
256
- if (src.startsWith('javascript:') || src.startsWith('data:') || src.startsWith('vbscript:')) {
257
- node.removeAttribute('src')
258
- }
259
- }
260
- })
261
-
262
- /**
263
- * Strips all HTML tags from a string, returning only the text content.
264
- * Uses DOMPurify for secure and complete tag removal.
265
- *
266
- * @param html - The string containing HTML tags
267
- * @returns The plain text content
268
- */
269
- export function stripHtmlTags(html: string): string {
270
- return DOMPurify.sanitize(html, { ALLOWED_TAGS: [], KEEP_CONTENT: true })
271
- }
272
-
273
- /**
274
- * Capitalizes the first letter of a given string.
275
- * Used primarily for generating default group titles.
276
- *
277
- * @param str - The string to capitalize
278
- * @returns The capitalized string
279
- */
280
- export function capitalize(str: string): string {
281
- return str.charAt(0).toUpperCase() + str.slice(1)
282
- }
283
-
284
- /**
285
- * Retrieves the correct translation from a value that can be either
286
- * a simple string or a map of locale-specific strings.
287
- * Node-side version for SSG and config resolution.
288
- *
289
- * @param value - The text to translate
290
- * @param locale - The current active locale (e.g., 'en', 'es')
291
- * @returns The translated string
292
- */
293
- export function getTranslated(
294
- value: string | Record<string, string> | undefined,
295
- locale?: string,
296
- ): string {
297
- if (!value) return ''
298
- if (typeof value === 'string') return value
299
-
300
- if (locale && value[locale]) {
301
- return value[locale]
302
- }
303
-
304
- // Fallback: Use the first available translation or an empty string
305
- const firstValue = Object.values(value)[0]
306
- return firstValue || ''
307
- }
308
- /**
309
- * Sanitizes a filename or path component by removing dangerous characters.
310
- * Prevents multiple dots to avoid path traversal tricks.
311
- *
312
- * @param name - The name to sanitize
313
- * @returns The sanitized name
314
- */
315
- export function sanitizeFilename(name: string): string {
316
- return name
317
- .replace(/[^a-zA-Z0-9\-_\/\.]/g, '') // Remove non-whitelisted characters
318
- .split('/')
319
- .filter((p) => p !== '..' && p !== '.') // Remove traversal and current dir indicators
320
- .map((p) => p.replace(/\.\.+/g, '.')) // Prevent multiple dots in segments
321
- .join('/')
322
- }
323
-
324
- /**
325
- * Logs a security violation with relevant metadata.
326
- * Redacts absolute paths to prevent information leakage.
327
- */
328
- export function logSecurityEvent(
329
- type: string,
330
- message: string,
331
- details: Record<string, any> = {},
332
- ): void {
333
- const timestamp = new Date().toISOString()
334
- const redactedDetails = { ...details }
335
-
336
- // Simple redaction logic for potential system paths
337
- for (const key in redactedDetails) {
338
- if (typeof redactedDetails[key] === 'string' && redactedDetails[key].includes(':')) {
339
- // Very basic redaction: just keep the filename part if it looks like a path
340
- redactedDetails[key] = redactedDetails[key].split(/[\\/]/).pop() || redactedDetails[key]
341
- }
342
- }
343
-
344
- console.error(
345
- `[SECURITY][${timestamp}] TYPE: ${type} | MESSAGE: ${message} | DETAILS: ${JSON.stringify(
346
- redactedDetails,
347
- )}`,
348
- )
349
- }
package/tsconfig.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "Bundler",
6
- "esModuleInterop": true,
7
- "strict": true,
8
- "skipLibCheck": true,
9
- "jsx": "react-jsx",
10
- "declaration": true,
11
- "outDir": "dist",
12
- "baseUrl": ".",
13
- "paths": {
14
- "@/*": ["src/*"],
15
- "@client/*": ["src/client/*"],
16
- "@node/*": ["src/node/*"],
17
- "@theme/*": ["src/client/theme/*"],
18
- "@components/*": ["src/client/components/*"],
19
- "@integrations/*": ["src/client/integrations/*"],
20
- "@hooks/*": ["src/client/hooks/*"],
21
- "@primitives/*": ["src/client/components/primitives/*"]
22
- }
23
- },
24
- "include": ["src"],
25
- "exclude": ["node_modules", "dist", "src/node/cli"]
26
- }
package/tsup.config.ts DELETED
@@ -1,56 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
- import type { Options } from 'tsup'
3
-
4
- const commonConfig: Options = {
5
- format: ['cjs', 'esm'],
6
- dts: true,
7
- tsconfig: './tsconfig.json',
8
- minify: true,
9
- minifySyntax: true,
10
- minifyWhitespace: true,
11
- minifyIdentifiers: true,
12
- shims: true,
13
- external: [
14
- 'vite',
15
- 'react',
16
- 'react-dom',
17
- 'react-router-dom',
18
- 'virtual:boltdocs-routes',
19
- 'virtual:boltdocs-config',
20
- 'virtual:boltdocs-layout',
21
- 'virtual:boltdocs-mdx-components',
22
- 'virtual:boltdocs-entry',
23
- /^virtual:boltdocs-/, // Broad catch-all for any virtual modules
24
- ],
25
- }
26
-
27
- export default defineConfig([
28
- // Node Build
29
- {
30
- ...commonConfig,
31
- clean: true,
32
- platform: 'node',
33
- entry: {
34
- 'node/index': 'src/node/index.ts',
35
- 'node/cli-entry': 'src/node/cli-entry.ts',
36
- },
37
- },
38
- // Client Build
39
- {
40
- ...commonConfig,
41
- clean: false, // Don't clean the outDir twice
42
- platform: 'browser',
43
- entry: {
44
- 'client/index': 'src/client/index.ts',
45
- },
46
- },
47
- // SSR Build (Needs Node platform for Server-Side Rendering)
48
- {
49
- ...commonConfig,
50
- clean: false, // Don't clean the outDir
51
- platform: 'node',
52
- entry: {
53
- 'client/ssr': 'src/client/ssr.tsx',
54
- },
55
- },
56
- ])