boltdocs 2.4.1 → 2.5.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 (113) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cache-3FOEPC2P.mjs +1 -0
  3. package/dist/chunk-ITFGVXPE.mjs +1 -0
  4. package/dist/chunk-TP5KMRD3.mjs +1 -0
  5. package/dist/chunk-UD2LQG2M.mjs +75 -0
  6. package/dist/chunk-Y4RE5KI7.mjs +1 -0
  7. package/dist/client/index.d.mts +1225 -14
  8. package/dist/client/index.d.ts +1225 -14
  9. package/dist/client/index.js +1 -1
  10. package/dist/client/index.mjs +1 -1
  11. package/dist/client/ssr.js +1 -1
  12. package/dist/client/ssr.mjs +1 -1
  13. package/dist/node/cli-entry.js +37 -35
  14. package/dist/node/cli-entry.mjs +1 -1
  15. package/dist/node/index.d.mts +263 -1
  16. package/dist/node/index.d.ts +263 -1
  17. package/dist/node/index.js +34 -32
  18. package/dist/node/index.mjs +1 -1
  19. package/dist/package-TWC3BMZ7.mjs +1 -0
  20. package/dist/search-dialog-YBM4GYDR.mjs +1 -0
  21. package/package.json +46 -76
  22. package/src/client/components/primitives/breadcrumbs.tsx +10 -10
  23. package/src/client/components/primitives/index.ts +17 -16
  24. package/src/client/components/primitives/menu.tsx +11 -14
  25. package/src/client/components/primitives/navbar.tsx +29 -29
  26. package/src/client/components/primitives/navigation-menu.tsx +7 -9
  27. package/src/client/components/primitives/on-this-page.tsx +16 -18
  28. package/src/client/components/primitives/page-nav.tsx +10 -13
  29. package/src/client/components/primitives/search-dialog.tsx +17 -19
  30. package/src/client/components/primitives/sidebar.tsx +8 -10
  31. package/src/client/components/primitives/tabs.tsx +10 -12
  32. package/src/client/components/primitives/tooltip.tsx +3 -5
  33. package/src/client/components/ui-base/breadcrumbs.tsx +12 -15
  34. package/src/client/components/ui-base/copy-markdown.tsx +8 -10
  35. package/src/client/components/ui-base/navbar.tsx +10 -10
  36. package/src/client/components/ui-base/on-this-page.tsx +13 -12
  37. package/src/client/components/ui-base/page-nav.tsx +15 -15
  38. package/src/client/components/ui-base/search-dialog.tsx +13 -20
  39. package/src/client/components/ui-base/sidebar.tsx +9 -9
  40. package/src/client/components/ui-base/tabs.tsx +6 -7
  41. package/src/client/components/ui-base/theme-toggle.tsx +11 -11
  42. package/src/client/hooks/index.ts +12 -12
  43. package/src/client/index.ts +34 -11
  44. package/src/node/config.ts +48 -6
  45. package/src/node/errors.ts +44 -0
  46. package/src/node/index.ts +29 -2
  47. package/src/node/mdx/index.ts +9 -2
  48. package/src/node/plugin/index.ts +72 -4
  49. package/src/node/plugins/index.ts +17 -0
  50. package/src/node/plugins/plugin-errors.ts +62 -0
  51. package/src/node/plugins/plugin-lifecycle.ts +117 -0
  52. package/src/node/plugins/plugin-sandbox.ts +59 -0
  53. package/src/node/plugins/plugin-store.ts +54 -0
  54. package/src/node/plugins/plugin-types.ts +107 -0
  55. package/src/node/plugins/plugin-validator.ts +105 -0
  56. package/src/node/routes/parser.ts +35 -5
  57. package/src/node/schema/config.ts +208 -0
  58. package/src/node/schema/frontmatter.ts +17 -0
  59. package/src/node/security/constants/index.ts +10 -0
  60. package/src/node/security/csp.ts +31 -0
  61. package/src/node/security/headers.ts +27 -0
  62. package/src/node/utils.ts +153 -5
  63. package/tsup.config.ts +0 -6
  64. package/dist/base-ui/index.d.mts +0 -25
  65. package/dist/base-ui/index.d.ts +0 -25
  66. package/dist/base-ui/index.js +0 -1
  67. package/dist/base-ui/index.mjs +0 -1
  68. package/dist/cache-P6WK424C.mjs +0 -1
  69. package/dist/chunk-2DI3OGHV.mjs +0 -1
  70. package/dist/chunk-2Z5T6EAU.mjs +0 -1
  71. package/dist/chunk-64AJ5QLT.mjs +0 -1
  72. package/dist/chunk-DDX52BX4.mjs +0 -1
  73. package/dist/chunk-HRZDSFR5.mjs +0 -1
  74. package/dist/chunk-JD3RSDE4.mjs +0 -1
  75. package/dist/chunk-JZXLCA2E.mjs +0 -1
  76. package/dist/chunk-NBCYHLAA.mjs +0 -1
  77. package/dist/chunk-PPVDMDEL.mjs +0 -1
  78. package/dist/chunk-T3W44KWY.mjs +0 -1
  79. package/dist/chunk-UBE4CKOA.mjs +0 -1
  80. package/dist/chunk-UWT4AJTH.mjs +0 -73
  81. package/dist/chunk-WWJ7WKDI.mjs +0 -1
  82. package/dist/chunk-Y4RRHPXC.mjs +0 -1
  83. package/dist/client/types.d.mts +0 -3
  84. package/dist/client/types.d.ts +0 -3
  85. package/dist/client/types.js +0 -1
  86. package/dist/client/types.mjs +0 -0
  87. package/dist/copy-markdown--9yjpbyy.d.mts +0 -15
  88. package/dist/copy-markdown-l2MYkcG7.d.ts +0 -15
  89. package/dist/hooks/index.d.mts +0 -137
  90. package/dist/hooks/index.d.ts +0 -137
  91. package/dist/hooks/index.js +0 -1
  92. package/dist/hooks/index.mjs +0 -1
  93. package/dist/integrations/index.d.mts +0 -48
  94. package/dist/integrations/index.d.ts +0 -48
  95. package/dist/integrations/index.js +0 -1
  96. package/dist/integrations/index.mjs +0 -1
  97. package/dist/link-DfBwCeZc.d.mts +0 -68
  98. package/dist/link-DfBwCeZc.d.ts +0 -68
  99. package/dist/loading-BwUos0wZ.d.mts +0 -57
  100. package/dist/loading-nlnUD01v.d.ts +0 -57
  101. package/dist/mdx/index.d.mts +0 -178
  102. package/dist/mdx/index.d.ts +0 -178
  103. package/dist/mdx/index.js +0 -1
  104. package/dist/mdx/index.mjs +0 -1
  105. package/dist/primitives/index.d.mts +0 -292
  106. package/dist/primitives/index.d.ts +0 -292
  107. package/dist/primitives/index.js +0 -1
  108. package/dist/primitives/index.mjs +0 -1
  109. package/dist/search-dialog-OONKKC5H.mjs +0 -1
  110. package/dist/types-opDA2E9-.d.mts +0 -394
  111. package/dist/types-opDA2E9-.d.ts +0 -394
  112. package/dist/use-routes-DNwgTRpU.d.ts +0 -29
  113. package/dist/use-routes-DrT80Eom.d.mts +0 -29
@@ -1,5 +1,97 @@
1
1
  import * as vite from 'vite';
2
2
  import { Plugin, InlineConfig } from 'vite';
3
+ import { z } from 'zod';
4
+
5
+ /**
6
+ * Permissions that a plugin can request to access specific Boltdocs capabilities.
7
+ */
8
+ type PluginPermission = 'fs:read' | 'fs:write' | 'vite:config' | 'mdx:remark' | 'mdx:rehype' | 'components' | 'hooks:build' | 'hooks:dev';
9
+ /**
10
+ * Shared context injected into every plugin lifecycle hook.
11
+ */
12
+ interface PluginContext {
13
+ /** The full, resolved Boltdocs configuration (Readonly) */
14
+ readonly config: BoltdocsConfig;
15
+ /** A plugin-specific logger */
16
+ readonly logger: PluginLogger;
17
+ /** A shared store for dependency injection and state sharing between plugins */
18
+ readonly store: PluginStore;
19
+ /** Metadata about the current plugin */
20
+ readonly meta: PluginMeta;
21
+ }
22
+ /**
23
+ * Simple logger interface for plugins.
24
+ */
25
+ interface PluginLogger {
26
+ info(message: string): void;
27
+ warn(message: string): void;
28
+ error(message: string | Error): void;
29
+ debug(message: string): void;
30
+ }
31
+ /**
32
+ * A shared key-value store that allows plugins to share state and configuration.
33
+ */
34
+ interface PluginStore {
35
+ /** Get a value from the store. Keys are namespaced by plugin internally. */
36
+ get<T = unknown>(pluginName: string, key: string): T | undefined;
37
+ /** Set a value in the store. */
38
+ set(pluginName: string, key: string, value: unknown): void;
39
+ /** Check if a key exists in the store. */
40
+ has(pluginName: string, key: string): boolean;
41
+ }
42
+ /**
43
+ * Metadata for a plugin, used for identification and compatibility checks.
44
+ */
45
+ interface PluginMeta {
46
+ /** Unique identifier for the plugin */
47
+ name: string;
48
+ /** Version of the plugin itself (semver) */
49
+ version?: string;
50
+ /** Minimum required version of Boltdocs (semver range) */
51
+ boltdocsVersion?: string;
52
+ }
53
+ /**
54
+ * Lifecycle hooks that a plugin can implement to hook into the build and dev processes.
55
+ */
56
+ interface PluginLifecycleHooks {
57
+ /** Called before the build process starts */
58
+ beforeBuild?: (ctx: PluginContext) => Promise<void> | void;
59
+ /** Called after the build process finishes successfully */
60
+ afterBuild?: (ctx: PluginContext) => Promise<void> | void;
61
+ /** Called before the dev server starts */
62
+ beforeDev?: (ctx: PluginContext) => Promise<void> | void;
63
+ /** Called after the dev server is ready (configureServer) */
64
+ afterDev?: (ctx: PluginContext) => Promise<void> | void;
65
+ /** Called when the final Boltdocs config is resolved */
66
+ configResolved?: (ctx: PluginContext, config: BoltdocsConfig) => void;
67
+ /** Called when the build is closing */
68
+ buildEnd?: (ctx: PluginContext) => Promise<void> | void;
69
+ }
70
+ /**
71
+ * The extended, secure Boltdocs plugin interface.
72
+ */
73
+ interface SecureBoltdocsPlugin {
74
+ /** A unique name for the plugin (e.g., 'boltdocs-plugin-mermaid') */
75
+ name: string;
76
+ /** Whether to run this plugin before or after default ones */
77
+ enforce?: 'pre' | 'post';
78
+ /** Version of the plugin (optional, but recommended for security) */
79
+ version?: string;
80
+ /** Minimum compatible Boltdocs version (optional, semver range) */
81
+ boltdocsVersion?: string;
82
+ /** List of permissions this plugin requires to operate */
83
+ permissions?: PluginPermission[];
84
+ /** Optional remark plugins to add to the MDX pipeline (requires 'mdx:remark' permission) */
85
+ remarkPlugins?: unknown[];
86
+ /** Optional rehype plugins to add to the MDX pipeline (requires 'mdx:rehype' permission) */
87
+ rehypePlugins?: unknown[];
88
+ /** Optional Vite plugins to inject into the build process (requires 'vite:config' permission) */
89
+ vitePlugins?: Plugin[];
90
+ /** Optional custom React components to register in MDX. Map of Name -> Module Path. (requires 'components' permission) */
91
+ components?: Record<string, string>;
92
+ /** Implementation of lifecycle hooks (requires 'hooks:build' or 'hooks:dev' permissions) */
93
+ hooks?: PluginLifecycleHooks;
94
+ }
3
95
 
4
96
  /**
5
97
  * Represents a single social link in the configuration.
@@ -170,6 +262,12 @@ interface BoltdocsPlugin {
170
262
  name: string;
171
263
  /** Whether to run this plugin before or after default ones (optional) */
172
264
  enforce?: 'pre' | 'post';
265
+ /** Version of the plugin (optional) */
266
+ version?: string;
267
+ /** Minimum compatible Boltdocs version (optional, semver range) */
268
+ boltdocsVersion?: string;
269
+ /** List of permissions this plugin requires to operate */
270
+ permissions?: PluginPermission[];
173
271
  /** Optional remark plugins to add to the MDX pipeline */
174
272
  remarkPlugins?: unknown[];
175
273
  /** Optional rehype plugins to add to the MDX pipeline */
@@ -178,6 +276,8 @@ interface BoltdocsPlugin {
178
276
  vitePlugins?: Plugin[];
179
277
  /** Optional custom React components to register in MDX. Map of Name -> Module Path. */
180
278
  components?: Record<string, string>;
279
+ /** Implementation of lifecycle hooks */
280
+ hooks?: PluginLifecycleHooks;
181
281
  }
182
282
  /**
183
283
  * Configuration for external integrations (e.g., CodeSandbox).
@@ -191,6 +291,17 @@ interface BoltdocsIntegrationsConfig {
191
291
  config?: Record<string, unknown>;
192
292
  };
193
293
  }
294
+ /**
295
+ * Configuration for security-related settings.
296
+ */
297
+ interface BoltdocsSecurityConfig {
298
+ /** Map of standard security headers to override or supplement defaults */
299
+ headers?: Record<string, string>;
300
+ /** Whether to enable Content Security Policy (CSP) generation (default: false) */
301
+ enableCSP?: boolean;
302
+ /** Additional custom headers to inject into responses */
303
+ customHeaders?: Record<string, string>;
304
+ }
194
305
  /**
195
306
  * The root configuration object for Boltdocs.
196
307
  */
@@ -213,6 +324,8 @@ interface BoltdocsConfig {
213
324
  integrations?: BoltdocsIntegrationsConfig;
214
325
  /** Configuration for the robots.txt file */
215
326
  robots?: BoltdocsRobotsConfig;
327
+ /** Security-related settings and headers */
328
+ security?: BoltdocsSecurityConfig;
216
329
  /** Low-level Vite configuration overrides */
217
330
  vite?: vite.InlineConfig;
218
331
  }
@@ -309,6 +422,155 @@ interface RouteMeta {
309
422
  _rawContent?: string;
310
423
  }
311
424
 
425
+ /**
426
+ * Base class for all plugin-related errors in Boltdocs.
427
+ */
428
+ declare class PluginError extends Error {
429
+ readonly pluginName: string;
430
+ constructor(pluginName: string, message: string);
431
+ }
432
+ /**
433
+ * Specifically for schema or structure validation failures.
434
+ */
435
+ declare class PluginValidationError extends PluginError {
436
+ constructor(pluginName: string, message: string);
437
+ }
438
+ /**
439
+ * Specifically for version mismatch or compatibility issues.
440
+ */
441
+ declare class PluginCompatibilityError extends PluginError {
442
+ constructor(pluginName: string, message: string);
443
+ }
444
+ /**
445
+ * Specifically for attempts to use capabilities without proper permissions.
446
+ */
447
+ declare class PluginPermissionError extends PluginError {
448
+ constructor(pluginName: string, permission: string);
449
+ }
450
+ /**
451
+ * Specifically for errors that occur during the execution of a lifecycle hook.
452
+ */
453
+ declare class PluginHookError extends PluginError {
454
+ readonly hookName: string;
455
+ constructor(pluginName: string, hookName: string, originalError: Error);
456
+ }
457
+
458
+ /**
459
+ * Implementation of the shared plugin store.
460
+ * Uses a namespaced approach to prevent key collisions between plugins.
461
+ */
462
+ declare class BoltdocsPluginStore implements PluginStore {
463
+ private data;
464
+ /**
465
+ * Internal helper to create a namespaced key.
466
+ */
467
+ private getNamespaceKey;
468
+ /**
469
+ * Retrieves a value from the store. Returns a deep clone to prevent mutations (side-effects).
470
+ */
471
+ get<T = unknown>(pluginName: string, key: string): T | undefined;
472
+ /**
473
+ * Stores a value in the store. Key is automatically namespaced.
474
+ */
475
+ set(pluginName: string, key: string, value: unknown): void;
476
+ /**
477
+ * Checks for the existence of a key in the store.
478
+ */
479
+ has(pluginName: string, key: string): boolean;
480
+ }
481
+
482
+ /**
483
+ * Enhanced Zod schema for secure plugins.
484
+ */
485
+ declare const SecurePluginSchema: z.ZodObject<{
486
+ name: z.ZodString;
487
+ enforce: z.ZodOptional<z.ZodEnum<{
488
+ pre: "pre";
489
+ post: "post";
490
+ }>>;
491
+ remarkPlugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
492
+ rehypePlugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
493
+ vitePlugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
494
+ components: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
495
+ version: z.ZodOptional<z.ZodString>;
496
+ boltdocsVersion: z.ZodOptional<z.ZodString>;
497
+ permissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
498
+ hooks: z.ZodOptional<z.ZodObject<{
499
+ beforeBuild: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
500
+ afterBuild: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
501
+ beforeDev: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
502
+ afterDev: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
503
+ configResolved: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
504
+ buildEnd: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
505
+ }, z.core.$strip>>;
506
+ }, z.core.$strip>;
507
+ /**
508
+ * Validates a list of plugins for correctness, security, and compatibility.
509
+ */
510
+ declare function validatePlugins(plugins: any[], boltdocsVersion: string): SecureBoltdocsPlugin[];
511
+ /**
512
+ * Helper to check if a specific permission is granted to a plugin.
513
+ */
514
+ declare function hasPermission(plugin: SecureBoltdocsPlugin, permission: PluginPermission): boolean;
515
+
516
+ /**
517
+ * The Sandbox provides a protective layer that ensures plugins only use
518
+ * the capabilities they have explicitly requested permissions for.
519
+ */
520
+ declare class PluginSandbox {
521
+ /**
522
+ * Validates if a plugin has the required permission for a capability.
523
+ * Throws a PluginPermissionError if not granted.
524
+ */
525
+ static checkPermission(plugin: SecureBoltdocsPlugin, permission: PluginPermission): void;
526
+ /**
527
+ * Filters a plugin's capabilities based on its declared permissions.
528
+ * This is used when aggregating plugins (remark, rehype, vite, components).
529
+ */
530
+ static getSanitizedCapabilities(plugin: SecureBoltdocsPlugin): {
531
+ remarkPlugins: unknown[] | undefined;
532
+ rehypePlugins: unknown[] | undefined;
533
+ vitePlugins: vite.Plugin<any>[] | undefined;
534
+ components: Record<string, string> | undefined;
535
+ };
536
+ /**
537
+ * Wraps a hook execution with permission checks and error isolation.
538
+ */
539
+ static executeWithIsolation<T>(plugin: SecureBoltdocsPlugin, requiredPermission: PluginPermission, hookName: string, action: () => Promise<T> | T): Promise<T | undefined>;
540
+ }
541
+
542
+ /**
543
+ * Manages the lifecycle of all loaded plugins, ensuring hooks are executed
544
+ * in the correct order with proper error isolation and context.
545
+ */
546
+ declare class PluginLifecycleManager {
547
+ private plugins;
548
+ private config;
549
+ private store;
550
+ constructor(plugins: SecureBoltdocsPlugin[], config: BoltdocsConfig);
551
+ /**
552
+ * Runs a specific hook for all plugins that implement it.
553
+ */
554
+ runHook(hookName: keyof PluginLifecycleHooks, ...args: any[]): Promise<void>;
555
+ /**
556
+ * Sorts plugins based on their 'enforce' property (pre -> normal -> post).
557
+ */
558
+ private getSortedPlugins;
559
+ /**
560
+ * Creates a specialized context for a plugin.
561
+ */
562
+ private createContext;
563
+ /**
564
+ * Creates a namespaced logger for a plugin.
565
+ */
566
+ private createLogger;
567
+ }
568
+
569
+ /**
570
+ * Utility to create a Boltdocs plugin with full type safety.
571
+ */
572
+ declare function createPlugin(plugin: SecureBoltdocsPlugin): SecureBoltdocsPlugin;
573
+
312
574
  declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
313
575
  /**
314
576
  * Generates the complete Vite configuration for a Boltdocs project.
@@ -316,4 +578,4 @@ declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
316
578
  */
317
579
  declare function createViteConfig(root: string, mode?: 'development' | 'production'): Promise<InlineConfig>;
318
580
 
319
- export { type BoltdocsConfig, type BoltdocsPluginOptions, type BoltdocsThemeConfig, type RouteMeta, type SSGOptions, createViteConfig, boltdocs as default, defineConfig, generateStaticPages, resolveConfig };
581
+ export { type BoltdocsConfig, type BoltdocsPlugin, type BoltdocsPluginOptions, BoltdocsPluginStore, type BoltdocsThemeConfig, PluginCompatibilityError, type PluginContext, PluginError, PluginHookError, type PluginLifecycleHooks, PluginLifecycleManager, type PluginLogger, type PluginMeta, type PluginPermission, PluginPermissionError, PluginSandbox, type PluginStore, PluginValidationError, type RouteMeta, type SSGOptions, type SecureBoltdocsPlugin, SecurePluginSchema, createPlugin, createViteConfig, boltdocs as default, defineConfig, generateStaticPages, hasPermission, resolveConfig, validatePlugins };
@@ -1,5 +1,97 @@
1
1
  import * as vite from 'vite';
2
2
  import { Plugin, InlineConfig } from 'vite';
3
+ import { z } from 'zod';
4
+
5
+ /**
6
+ * Permissions that a plugin can request to access specific Boltdocs capabilities.
7
+ */
8
+ type PluginPermission = 'fs:read' | 'fs:write' | 'vite:config' | 'mdx:remark' | 'mdx:rehype' | 'components' | 'hooks:build' | 'hooks:dev';
9
+ /**
10
+ * Shared context injected into every plugin lifecycle hook.
11
+ */
12
+ interface PluginContext {
13
+ /** The full, resolved Boltdocs configuration (Readonly) */
14
+ readonly config: BoltdocsConfig;
15
+ /** A plugin-specific logger */
16
+ readonly logger: PluginLogger;
17
+ /** A shared store for dependency injection and state sharing between plugins */
18
+ readonly store: PluginStore;
19
+ /** Metadata about the current plugin */
20
+ readonly meta: PluginMeta;
21
+ }
22
+ /**
23
+ * Simple logger interface for plugins.
24
+ */
25
+ interface PluginLogger {
26
+ info(message: string): void;
27
+ warn(message: string): void;
28
+ error(message: string | Error): void;
29
+ debug(message: string): void;
30
+ }
31
+ /**
32
+ * A shared key-value store that allows plugins to share state and configuration.
33
+ */
34
+ interface PluginStore {
35
+ /** Get a value from the store. Keys are namespaced by plugin internally. */
36
+ get<T = unknown>(pluginName: string, key: string): T | undefined;
37
+ /** Set a value in the store. */
38
+ set(pluginName: string, key: string, value: unknown): void;
39
+ /** Check if a key exists in the store. */
40
+ has(pluginName: string, key: string): boolean;
41
+ }
42
+ /**
43
+ * Metadata for a plugin, used for identification and compatibility checks.
44
+ */
45
+ interface PluginMeta {
46
+ /** Unique identifier for the plugin */
47
+ name: string;
48
+ /** Version of the plugin itself (semver) */
49
+ version?: string;
50
+ /** Minimum required version of Boltdocs (semver range) */
51
+ boltdocsVersion?: string;
52
+ }
53
+ /**
54
+ * Lifecycle hooks that a plugin can implement to hook into the build and dev processes.
55
+ */
56
+ interface PluginLifecycleHooks {
57
+ /** Called before the build process starts */
58
+ beforeBuild?: (ctx: PluginContext) => Promise<void> | void;
59
+ /** Called after the build process finishes successfully */
60
+ afterBuild?: (ctx: PluginContext) => Promise<void> | void;
61
+ /** Called before the dev server starts */
62
+ beforeDev?: (ctx: PluginContext) => Promise<void> | void;
63
+ /** Called after the dev server is ready (configureServer) */
64
+ afterDev?: (ctx: PluginContext) => Promise<void> | void;
65
+ /** Called when the final Boltdocs config is resolved */
66
+ configResolved?: (ctx: PluginContext, config: BoltdocsConfig) => void;
67
+ /** Called when the build is closing */
68
+ buildEnd?: (ctx: PluginContext) => Promise<void> | void;
69
+ }
70
+ /**
71
+ * The extended, secure Boltdocs plugin interface.
72
+ */
73
+ interface SecureBoltdocsPlugin {
74
+ /** A unique name for the plugin (e.g., 'boltdocs-plugin-mermaid') */
75
+ name: string;
76
+ /** Whether to run this plugin before or after default ones */
77
+ enforce?: 'pre' | 'post';
78
+ /** Version of the plugin (optional, but recommended for security) */
79
+ version?: string;
80
+ /** Minimum compatible Boltdocs version (optional, semver range) */
81
+ boltdocsVersion?: string;
82
+ /** List of permissions this plugin requires to operate */
83
+ permissions?: PluginPermission[];
84
+ /** Optional remark plugins to add to the MDX pipeline (requires 'mdx:remark' permission) */
85
+ remarkPlugins?: unknown[];
86
+ /** Optional rehype plugins to add to the MDX pipeline (requires 'mdx:rehype' permission) */
87
+ rehypePlugins?: unknown[];
88
+ /** Optional Vite plugins to inject into the build process (requires 'vite:config' permission) */
89
+ vitePlugins?: Plugin[];
90
+ /** Optional custom React components to register in MDX. Map of Name -> Module Path. (requires 'components' permission) */
91
+ components?: Record<string, string>;
92
+ /** Implementation of lifecycle hooks (requires 'hooks:build' or 'hooks:dev' permissions) */
93
+ hooks?: PluginLifecycleHooks;
94
+ }
3
95
 
4
96
  /**
5
97
  * Represents a single social link in the configuration.
@@ -170,6 +262,12 @@ interface BoltdocsPlugin {
170
262
  name: string;
171
263
  /** Whether to run this plugin before or after default ones (optional) */
172
264
  enforce?: 'pre' | 'post';
265
+ /** Version of the plugin (optional) */
266
+ version?: string;
267
+ /** Minimum compatible Boltdocs version (optional, semver range) */
268
+ boltdocsVersion?: string;
269
+ /** List of permissions this plugin requires to operate */
270
+ permissions?: PluginPermission[];
173
271
  /** Optional remark plugins to add to the MDX pipeline */
174
272
  remarkPlugins?: unknown[];
175
273
  /** Optional rehype plugins to add to the MDX pipeline */
@@ -178,6 +276,8 @@ interface BoltdocsPlugin {
178
276
  vitePlugins?: Plugin[];
179
277
  /** Optional custom React components to register in MDX. Map of Name -> Module Path. */
180
278
  components?: Record<string, string>;
279
+ /** Implementation of lifecycle hooks */
280
+ hooks?: PluginLifecycleHooks;
181
281
  }
182
282
  /**
183
283
  * Configuration for external integrations (e.g., CodeSandbox).
@@ -191,6 +291,17 @@ interface BoltdocsIntegrationsConfig {
191
291
  config?: Record<string, unknown>;
192
292
  };
193
293
  }
294
+ /**
295
+ * Configuration for security-related settings.
296
+ */
297
+ interface BoltdocsSecurityConfig {
298
+ /** Map of standard security headers to override or supplement defaults */
299
+ headers?: Record<string, string>;
300
+ /** Whether to enable Content Security Policy (CSP) generation (default: false) */
301
+ enableCSP?: boolean;
302
+ /** Additional custom headers to inject into responses */
303
+ customHeaders?: Record<string, string>;
304
+ }
194
305
  /**
195
306
  * The root configuration object for Boltdocs.
196
307
  */
@@ -213,6 +324,8 @@ interface BoltdocsConfig {
213
324
  integrations?: BoltdocsIntegrationsConfig;
214
325
  /** Configuration for the robots.txt file */
215
326
  robots?: BoltdocsRobotsConfig;
327
+ /** Security-related settings and headers */
328
+ security?: BoltdocsSecurityConfig;
216
329
  /** Low-level Vite configuration overrides */
217
330
  vite?: vite.InlineConfig;
218
331
  }
@@ -309,6 +422,155 @@ interface RouteMeta {
309
422
  _rawContent?: string;
310
423
  }
311
424
 
425
+ /**
426
+ * Base class for all plugin-related errors in Boltdocs.
427
+ */
428
+ declare class PluginError extends Error {
429
+ readonly pluginName: string;
430
+ constructor(pluginName: string, message: string);
431
+ }
432
+ /**
433
+ * Specifically for schema or structure validation failures.
434
+ */
435
+ declare class PluginValidationError extends PluginError {
436
+ constructor(pluginName: string, message: string);
437
+ }
438
+ /**
439
+ * Specifically for version mismatch or compatibility issues.
440
+ */
441
+ declare class PluginCompatibilityError extends PluginError {
442
+ constructor(pluginName: string, message: string);
443
+ }
444
+ /**
445
+ * Specifically for attempts to use capabilities without proper permissions.
446
+ */
447
+ declare class PluginPermissionError extends PluginError {
448
+ constructor(pluginName: string, permission: string);
449
+ }
450
+ /**
451
+ * Specifically for errors that occur during the execution of a lifecycle hook.
452
+ */
453
+ declare class PluginHookError extends PluginError {
454
+ readonly hookName: string;
455
+ constructor(pluginName: string, hookName: string, originalError: Error);
456
+ }
457
+
458
+ /**
459
+ * Implementation of the shared plugin store.
460
+ * Uses a namespaced approach to prevent key collisions between plugins.
461
+ */
462
+ declare class BoltdocsPluginStore implements PluginStore {
463
+ private data;
464
+ /**
465
+ * Internal helper to create a namespaced key.
466
+ */
467
+ private getNamespaceKey;
468
+ /**
469
+ * Retrieves a value from the store. Returns a deep clone to prevent mutations (side-effects).
470
+ */
471
+ get<T = unknown>(pluginName: string, key: string): T | undefined;
472
+ /**
473
+ * Stores a value in the store. Key is automatically namespaced.
474
+ */
475
+ set(pluginName: string, key: string, value: unknown): void;
476
+ /**
477
+ * Checks for the existence of a key in the store.
478
+ */
479
+ has(pluginName: string, key: string): boolean;
480
+ }
481
+
482
+ /**
483
+ * Enhanced Zod schema for secure plugins.
484
+ */
485
+ declare const SecurePluginSchema: z.ZodObject<{
486
+ name: z.ZodString;
487
+ enforce: z.ZodOptional<z.ZodEnum<{
488
+ pre: "pre";
489
+ post: "post";
490
+ }>>;
491
+ remarkPlugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
492
+ rehypePlugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
493
+ vitePlugins: z.ZodOptional<z.ZodArray<z.ZodAny>>;
494
+ components: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
495
+ version: z.ZodOptional<z.ZodString>;
496
+ boltdocsVersion: z.ZodOptional<z.ZodString>;
497
+ permissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
498
+ hooks: z.ZodOptional<z.ZodObject<{
499
+ beforeBuild: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
500
+ afterBuild: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
501
+ beforeDev: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
502
+ afterDev: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
503
+ configResolved: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
504
+ buildEnd: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
505
+ }, z.core.$strip>>;
506
+ }, z.core.$strip>;
507
+ /**
508
+ * Validates a list of plugins for correctness, security, and compatibility.
509
+ */
510
+ declare function validatePlugins(plugins: any[], boltdocsVersion: string): SecureBoltdocsPlugin[];
511
+ /**
512
+ * Helper to check if a specific permission is granted to a plugin.
513
+ */
514
+ declare function hasPermission(plugin: SecureBoltdocsPlugin, permission: PluginPermission): boolean;
515
+
516
+ /**
517
+ * The Sandbox provides a protective layer that ensures plugins only use
518
+ * the capabilities they have explicitly requested permissions for.
519
+ */
520
+ declare class PluginSandbox {
521
+ /**
522
+ * Validates if a plugin has the required permission for a capability.
523
+ * Throws a PluginPermissionError if not granted.
524
+ */
525
+ static checkPermission(plugin: SecureBoltdocsPlugin, permission: PluginPermission): void;
526
+ /**
527
+ * Filters a plugin's capabilities based on its declared permissions.
528
+ * This is used when aggregating plugins (remark, rehype, vite, components).
529
+ */
530
+ static getSanitizedCapabilities(plugin: SecureBoltdocsPlugin): {
531
+ remarkPlugins: unknown[] | undefined;
532
+ rehypePlugins: unknown[] | undefined;
533
+ vitePlugins: vite.Plugin<any>[] | undefined;
534
+ components: Record<string, string> | undefined;
535
+ };
536
+ /**
537
+ * Wraps a hook execution with permission checks and error isolation.
538
+ */
539
+ static executeWithIsolation<T>(plugin: SecureBoltdocsPlugin, requiredPermission: PluginPermission, hookName: string, action: () => Promise<T> | T): Promise<T | undefined>;
540
+ }
541
+
542
+ /**
543
+ * Manages the lifecycle of all loaded plugins, ensuring hooks are executed
544
+ * in the correct order with proper error isolation and context.
545
+ */
546
+ declare class PluginLifecycleManager {
547
+ private plugins;
548
+ private config;
549
+ private store;
550
+ constructor(plugins: SecureBoltdocsPlugin[], config: BoltdocsConfig);
551
+ /**
552
+ * Runs a specific hook for all plugins that implement it.
553
+ */
554
+ runHook(hookName: keyof PluginLifecycleHooks, ...args: any[]): Promise<void>;
555
+ /**
556
+ * Sorts plugins based on their 'enforce' property (pre -> normal -> post).
557
+ */
558
+ private getSortedPlugins;
559
+ /**
560
+ * Creates a specialized context for a plugin.
561
+ */
562
+ private createContext;
563
+ /**
564
+ * Creates a namespaced logger for a plugin.
565
+ */
566
+ private createLogger;
567
+ }
568
+
569
+ /**
570
+ * Utility to create a Boltdocs plugin with full type safety.
571
+ */
572
+ declare function createPlugin(plugin: SecureBoltdocsPlugin): SecureBoltdocsPlugin;
573
+
312
574
  declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
313
575
  /**
314
576
  * Generates the complete Vite configuration for a Boltdocs project.
@@ -316,4 +578,4 @@ declare function boltdocs(options?: BoltdocsPluginOptions): Promise<Plugin[]>;
316
578
  */
317
579
  declare function createViteConfig(root: string, mode?: 'development' | 'production'): Promise<InlineConfig>;
318
580
 
319
- export { type BoltdocsConfig, type BoltdocsPluginOptions, type BoltdocsThemeConfig, type RouteMeta, type SSGOptions, createViteConfig, boltdocs as default, defineConfig, generateStaticPages, resolveConfig };
581
+ export { type BoltdocsConfig, type BoltdocsPlugin, type BoltdocsPluginOptions, BoltdocsPluginStore, type BoltdocsThemeConfig, PluginCompatibilityError, type PluginContext, PluginError, PluginHookError, type PluginLifecycleHooks, PluginLifecycleManager, type PluginLogger, type PluginMeta, type PluginPermission, PluginPermissionError, PluginSandbox, type PluginStore, PluginValidationError, type RouteMeta, type SSGOptions, type SecureBoltdocsPlugin, SecurePluginSchema, createPlugin, createViteConfig, boltdocs as default, defineConfig, generateStaticPages, hasPermission, resolveConfig, validatePlugins };