boltdocs 3.0.2 → 3.1.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/README.md +2 -18
  2. package/dist/{adapters-C5AWWGfb.cjs → adapters-uGz-UKQa.cjs} +1 -1
  3. package/dist/{banner-DNSkgUsO.d.cts → banner-DdSgCs4G.d.cts} +1 -1
  4. package/dist/{banner-CfdalYLL.d.ts → banner-DjujkctF.d.ts} +1 -1
  5. package/dist/cache-B0C2i0yP.mjs +6 -0
  6. package/dist/cache-CfRTUzWC.cjs +6 -0
  7. package/dist/chunk-hT5z_Zn9-DsJawvsz.mjs +6 -0
  8. package/dist/chunk-hT5z_Zn9-SKz6VFXu.cjs +6 -0
  9. package/dist/client/index.cjs +227 -113
  10. package/dist/client/index.d.cts +57 -12
  11. package/dist/client/index.d.ts +57 -12
  12. package/dist/client/index.js +227 -114
  13. package/dist/client/mdx.cjs +1 -1
  14. package/dist/client/mdx.js +1 -1
  15. package/dist/client/primitives.cjs +4 -4
  16. package/dist/client/primitives.d.cts +1 -1
  17. package/dist/client/primitives.d.ts +1 -1
  18. package/dist/client/primitives.js +4 -4
  19. package/dist/client/theme/neutral.css +1 -3
  20. package/dist/{config-JGkMJoJQ.cjs → config-BxsogK5A.cjs} +1 -1
  21. package/dist/config-DAgpZyh6.mjs +7 -0
  22. package/dist/config-DrRQYDCI.cjs +7 -0
  23. package/dist/{docs-layout-3TpAt6MB.cjs → docs-layout-D1buSdua.cjs} +1 -1
  24. package/dist/{docs-layout-6FQ8__ok.js → docs-layout-DyLDBwS6.js} +1 -1
  25. package/dist/{doctor-DQxLM202.cjs → doctor-BadGEhXv.cjs} +1 -1
  26. package/dist/{doctor-BR1B2Mkz.cjs → doctor-DPDcRKM1.cjs} +1 -1
  27. package/dist/{doctor-3MheVMwd.mjs → doctor-vDsUDgqp.mjs} +1 -1
  28. package/dist/escape-string-regexp-AG8q1e25-9Un9V90q.mjs +6 -0
  29. package/dist/escape-string-regexp-AG8q1e25-bJ9Ixe7c.cjs +6 -0
  30. package/dist/esm-shims-DSep1HcR.mjs +6 -0
  31. package/dist/{icons-dev-kJyGWNeg.js → icons-dev-CHZOwhQA.js} +8 -3
  32. package/dist/{icons-dev-BryEFkJu.cjs → icons-dev-YtDoLUsb.cjs} +8 -3
  33. package/dist/{image-C9md50h2.js → image-5WsgWYTh.js} +2 -2
  34. package/dist/{image-CR6UlaI5.cjs → image-Hb105Gu6.cjs} +2 -2
  35. package/dist/lib-BR0SoanK-CLswltLI.cjs +6 -0
  36. package/dist/lib-BR0SoanK-DcYeDrE6.mjs +6 -0
  37. package/dist/lib-DPoCz1YB-CLYXwKST.cjs +6 -0
  38. package/dist/lib-DPoCz1YB-CyGOqgSO.mjs +6 -0
  39. package/dist/{mdx-DhyMkc35.js → mdx-Bv-pS6-O.js} +6 -2
  40. package/dist/{mdx-DJBg5DuL.cjs → mdx-CDUcJmye.cjs} +6 -2
  41. package/dist/micromark-util-character-5KqJafVT-C6gnc770.cjs +6 -0
  42. package/dist/micromark-util-character-5KqJafVT-DkPKsbgn.mjs +6 -0
  43. package/dist/node/cache.cjs +6 -0
  44. package/dist/node/cache.d.cts +83 -0
  45. package/dist/node/cache.d.mts +83 -0
  46. package/dist/node/cache.mjs +6 -0
  47. package/dist/node/cli-entry.cjs +3 -3
  48. package/dist/node/cli-entry.mjs +3 -3
  49. package/dist/node/index.cjs +1 -1
  50. package/dist/node/index.d.cts +10 -467
  51. package/dist/node/index.d.mts +12 -468
  52. package/dist/node/index.mjs +1 -1
  53. package/dist/node/mdx/shiki-adapter.cjs +6 -0
  54. package/dist/node/mdx/shiki-adapter.d.cts +3 -0
  55. package/dist/node/mdx/shiki-adapter.d.mts +3 -0
  56. package/dist/node/mdx/shiki-adapter.mjs +6 -0
  57. package/dist/node-BDBv8CT6.mjs +104 -0
  58. package/dist/node-DFV_FV0y.mjs +6 -0
  59. package/dist/node-DqsP7kXz.cjs +6 -0
  60. package/dist/node-yFmAavND.cjs +104 -0
  61. package/dist/{package-_dCCKVvG.mjs → package-CoHWTf0N.mjs} +1 -1
  62. package/dist/{package-CEDhVAfO.cjs → package-_-Oa8-qN.cjs} +1 -1
  63. package/dist/{parser-D0QHIQsi.mjs → parser-BZJgAa9E.mjs} +1 -1
  64. package/dist/{parser-CNIPHx4s.cjs → parser-DlanzESE.cjs} +1 -1
  65. package/dist/plugin-BVuwx5D9.cjs +73 -0
  66. package/dist/plugin-BoxD91Yh.mjs +73 -0
  67. package/dist/rehype-slug--ZOxZ-_K-BNeYC4aT.cjs +6 -0
  68. package/dist/rehype-slug--ZOxZ-_K-CjIQEJCs.mjs +6 -0
  69. package/dist/remark-frontmatter-wFYRLcCt-CutW0gA3.mjs +8 -0
  70. package/dist/remark-frontmatter-wFYRLcCt-ENB5qG3y.cjs +8 -0
  71. package/dist/remark-gfm-B8TMkQbX-CjUJo8Rd.cjs +21 -0
  72. package/dist/remark-gfm-B8TMkQbX-Ctu0VV1_.mjs +21 -0
  73. package/dist/rollup-DMqoG11U-CKcJ37u_.mjs +59 -0
  74. package/dist/rollup-DMqoG11U-DKdxvZIj.cjs +59 -0
  75. package/dist/routes-BN2XbGcT.mjs +6 -0
  76. package/dist/routes-Cnq8xTCv.cjs +6 -0
  77. package/dist/{routes-BajCwrvX.cjs → routes-D_S9kjkS.cjs} +1 -1
  78. package/dist/{search-dialog-CW1f6dn6.cjs → search-dialog-BIuxGQsg.cjs} +1 -1
  79. package/dist/{search-dialog-Cx7aGW3U.cjs → search-dialog-BbtxA1uT.cjs} +2 -2
  80. package/dist/{search-dialog-D4rplZMv.cjs → search-dialog-BpNULmrl.cjs} +1 -1
  81. package/dist/{search-dialog-DDopgbKM.js → search-dialog-DC7oXU-5.js} +2 -2
  82. package/dist/{search-dialog-DaeSPvEo.js → search-dialog-PJrFRU5G.js} +1 -1
  83. package/dist/{search-dialog-BNdRV60O.js → search-dialog-gp9lrJXm.js} +1 -1
  84. package/dist/server/index.cjs +1 -1
  85. package/dist/server/index.d.mts +1 -1
  86. package/dist/shiki-adapter-CK3llqw2.mjs +6 -0
  87. package/dist/shiki-adapter-fS94vy-z.d.mts +534 -0
  88. package/dist/shiki-adapter-l2kEP5rn.d.cts +534 -0
  89. package/dist/{sidebar-BAKgJ-Er.d.ts → sidebar-DH2iPKXM.d.cts} +187 -10
  90. package/dist/{sidebar-7gIifpBX.d.cts → sidebar-DknLUI1R.d.ts} +187 -10
  91. package/package.json +16 -5
  92. package/src/shared/types.ts +177 -10
  93. package/dist/cache-DETwlACe.cjs +0 -6
  94. package/dist/cache-SF59enb3.mjs +0 -6
  95. package/dist/config-B5uVv5q4.cjs +0 -7
  96. package/dist/config-D3_zDkHh.mjs +0 -7
  97. package/dist/node-B9JSyEIU.mjs +0 -105
  98. package/dist/node-Cedquois.cjs +0 -105
  99. package/dist/plugin-WYNORxp1.cjs +0 -68
  100. package/dist/plugin-YWNVRpws.mjs +0 -68
  101. package/dist/routes-CyrnmVuG.mjs +0 -6
  102. package/dist/routes-D6Tuu7Fs.cjs +0 -6
  103. package/dist/shiki-adapter-CXEGRnjr.mjs +0 -6
  104. package/dist/shiki-adapter-Mr8_oT_9.cjs +0 -6
  105. /package/dist/{csp-CBysWlAf.cjs → csp-BX06rvdg.cjs} +0 -0
  106. /package/dist/{csp-gaZ51xzq.mjs → csp-z2D0FuRW.mjs} +0 -0
  107. /package/dist/{generator-DtUU3Cfk.cjs → generator-BN75lJOv.cjs} +0 -0
  108. /package/dist/{handler-Dzf4dSnV.cjs → handler-1LRMYeI4.cjs} +0 -0
  109. /package/dist/{headers-CXyf0auY.mjs → headers-CL0pMcwm.mjs} +0 -0
  110. /package/dist/{headers-BXKxiPUv.cjs → headers-YpD10rDb.cjs} +0 -0
  111. /package/dist/{index-CdJv4ocW.d.mts → index-DJYJzs-Z.d.mts} +0 -0
  112. /package/dist/{meta-loader-C4Hu9RN9.mjs → meta-loader-Bq-MjTXB.mjs} +0 -0
  113. /package/dist/{meta-loader-C9MKjAs0.cjs → meta-loader-CTB62-Mo.cjs} +0 -0
@@ -1,10 +1,92 @@
1
1
 
2
2
  import * as React$2 from "react";
3
3
  import { ComponentType, ReactNode } from "react";
4
- import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
4
  import { Plugin } from "vite";
5
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
6
6
 
7
7
  //#region src/shared/types.d.ts
8
+ /**
9
+ * Metadata representing a single documentation route.
10
+ * This information is used to build the client-side router and the sidebar navigation.
11
+ */
12
+ interface RouteMeta {
13
+ /** The final URL path for the route (e.g., '/docs/guide/start') */
14
+ path: string;
15
+ /** The absolute filesystem path to the source markdown/mdx file */
16
+ componentPath: string;
17
+ /** The title of the page, usually extracted from frontmatter or the filename */
18
+ title: string;
19
+ /** The relative path from the docs directory, used for edit links */
20
+ filePath: string;
21
+ /** Optional description of the page (for SEO/meta tags) */
22
+ description?: string;
23
+ /** Optional explicit position for ordering in the sidebar */
24
+ sidebarPosition?: number;
25
+ /** The group (directory) this route belongs to */
26
+ group?: string;
27
+ /** The display title for the route's group */
28
+ groupTitle?: string;
29
+ /** Optional explicit position for ordering the group itself */
30
+ groupPosition?: number;
31
+ /** Optional icon for the route's group */
32
+ groupIcon?: string;
33
+ /** The sub-route group this route belongs to (from folders starting with _) */
34
+ subRouteGroup?: string;
35
+ /** Extracted markdown headings for search indexing */
36
+ headings?: {
37
+ level: number;
38
+ text: string;
39
+ id: string;
40
+ }[];
41
+ /** The locale this route belongs to, if i18n is configured */
42
+ locale?: string;
43
+ /** The version this route belongs to, if versioning is configured */
44
+ version?: string;
45
+ /** Optional badge to display next to the sidebar item (e.g., 'New', 'Experimental') */
46
+ badge?: BadgeValue;
47
+ /** Optional icon to display (Lucide icon name or raw SVG) */
48
+ icon?: string;
49
+ /** The tab this route belongs to, if tabs are configured */
50
+ tab?: string;
51
+ /** The collection this route belongs to (from [name] directories like [blog]) */
52
+ collection?: string;
53
+ /** Tags for blog posts or other taxonomy */
54
+ tags?: string[];
55
+ /** Author identifier for blog posts */
56
+ author?: string;
57
+ /** Draft flag — excluded from production builds */
58
+ draft?: boolean;
59
+ /** Feature flags required for this page to be visible */
60
+ featureFlags?: string[];
61
+ /** Short excerpt/summary for list displays */
62
+ excerpt?: string;
63
+ /** Cover image for blog posts */
64
+ coverImage?: string;
65
+ /** The extracted plain-text content of the page for search indexing */
66
+ _content?: string;
67
+ /** The raw markdown content of the page */
68
+ _rawContent?: string;
69
+ /** Extracted SEO and Open Graph metadata from frontmatter */
70
+ seo?: Record<string, any>;
71
+ /** The publication date */
72
+ date?: string | Date;
73
+ /** The last updated timestamp or date */
74
+ lastUpdated?: string | number | Date;
75
+ /** Optional category for the page */
76
+ category?: string;
77
+ /** Optional explicit order (alternative to sidebarPosition) */
78
+ order?: number;
79
+ /** Optional explicit label for the sidebar */
80
+ sidebarLabel?: string;
81
+ /** Whether the page is hidden from the sidebar */
82
+ sidebarHidden?: boolean;
83
+ /** Raw extensible frontmatter data for custom components and formatters */
84
+ frontmatter?: Record<string, any>;
85
+ /** Optional recursive child routes for deep sidebar hierarchies */
86
+ subRoutes?: RouteMeta[];
87
+ /** Clean URL segments stripped of locale/version prefixes */
88
+ slugParts?: string[];
89
+ }
8
90
  /**
9
91
  * Represents a single social link in the configuration.
10
92
  */
@@ -12,12 +94,6 @@ interface BoltdocsSocialLink {
12
94
  icon: 'discord' | 'x' | 'github' | 'bluesky' | string;
13
95
  link: string;
14
96
  }
15
- /**
16
- * Configuration for the site footer.
17
- */
18
- interface BoltdocsFooterConfig {
19
- text?: string;
20
- }
21
97
  /**
22
98
  * Theme-specific configuration options.
23
99
  */
@@ -48,7 +124,6 @@ interface BoltdocsThemeConfig {
48
124
  icon?: string;
49
125
  }>;
50
126
  socialLinks?: BoltdocsSocialLink[];
51
- footer?: BoltdocsFooterConfig;
52
127
  editLink?: string;
53
128
  communityHelp?: string;
54
129
  version?: string;
@@ -118,6 +193,85 @@ type BadgeValue = string | {
118
193
  text: string;
119
194
  expires?: string;
120
195
  };
196
+ /**
197
+ * Context provided to plugin lifecycle hooks.
198
+ */
199
+ interface PluginContext {
200
+ readonly config: BoltdocsConfig$1;
201
+ readonly logger: PluginLogger;
202
+ readonly store: PluginStore;
203
+ readonly meta: PluginMeta;
204
+ readonly docsDir: string;
205
+ readonly rootDir: string;
206
+ readonly outDir: string;
207
+ readonly routes: RouteMeta[];
208
+ }
209
+ /**
210
+ * Logger interface for plugin logging.
211
+ */
212
+ interface PluginLogger {
213
+ info(message: string): void;
214
+ warn(message: string): void;
215
+ error(message: string | Error): void;
216
+ debug(message: string): void;
217
+ }
218
+ /**
219
+ * Key-value store interface for plugins.
220
+ */
221
+ interface PluginStore {
222
+ get<T = unknown>(pluginName: string, key: string): T | undefined;
223
+ set(pluginName: string, key: string, value: unknown): void;
224
+ has(pluginName: string, key: string): boolean;
225
+ }
226
+ /**
227
+ * Plugin metadata provided in the context.
228
+ */
229
+ interface PluginMeta {
230
+ name: string;
231
+ version?: string;
232
+ boltdocsVersion?: string;
233
+ }
234
+ /**
235
+ * Plugin lifecycle hooks with full type safety.
236
+ */
237
+ interface PluginLifecycleHooks {
238
+ beforeBuild?: (ctx: PluginContext) => Promise<void> | void;
239
+ afterBuild?: (ctx: PluginContext) => Promise<void> | void;
240
+ beforeDev?: (ctx: PluginContext) => Promise<void> | void;
241
+ afterDev?: (ctx: PluginContext) => Promise<void> | void;
242
+ buildEnd?: (ctx: PluginContext) => Promise<void> | void;
243
+ transformSource?: (ctx: PluginContext, params: {
244
+ code: string;
245
+ filePath: string;
246
+ }) => Promise<{
247
+ code: string;
248
+ }> | {
249
+ code: string;
250
+ };
251
+ transformMdx?: (ctx: PluginContext, params: {
252
+ code: string;
253
+ filePath: string;
254
+ }) => Promise<{
255
+ code: string;
256
+ }> | {
257
+ code: string;
258
+ };
259
+ transformHtml?: (ctx: PluginContext, params: {
260
+ html: string;
261
+ path: string;
262
+ }) => Promise<{
263
+ html: string;
264
+ }> | {
265
+ html: string;
266
+ };
267
+ }
268
+ /**
269
+ * MDX processor configuration.
270
+ * When `processor` is set to 'satteri', the Sätteri Rust-based compiler is used.
271
+ */
272
+ interface BoltdocsMdxConfig {
273
+ processor?: 'unified' | 'satteri';
274
+ }
121
275
  /**
122
276
  * Defines a Boltdocs plugin.
123
277
  *
@@ -133,8 +287,8 @@ interface BoltdocsPlugin {
133
287
  rehypePlugins?: unknown[];
134
288
  vitePlugins?: Plugin[];
135
289
  components?: Record<string, string>;
136
- /** Lifecycle hooks — use the `PluginLifecycleHooks` type from the node API. */
137
- hooks?: Record<string, (ctx: unknown) => Promise<void> | void>;
290
+ /** Lifecycle hooks with full type safety */
291
+ hooks?: PluginLifecycleHooks;
138
292
  }
139
293
  /**
140
294
  * Configuration for the collections (blog) feature.
@@ -236,11 +390,20 @@ interface BoltdocsVercelConfig {
236
390
  analytics?: boolean;
237
391
  speedInsights?: boolean;
238
392
  }
393
+ interface BoltdocsPostHogConfig {
394
+ apiKey: string;
395
+ host?: string;
396
+ capturePageview?: boolean;
397
+ capturePageleave?: boolean;
398
+ sessionRecording?: boolean;
399
+ autocapture?: boolean;
400
+ }
239
401
  interface BoltdocsIntegrationsConfig {
240
402
  analytics?: {
241
403
  ga4?: BoltdocsGA4Config;
242
404
  vercel?: BoltdocsVercelConfig;
243
405
  gtm?: BoltdocsGTMConfig;
406
+ posthog?: BoltdocsPostHogConfig;
244
407
  };
245
408
  search?: {
246
409
  algolia?: BoltdocsAlgoliaConfig;
@@ -250,6 +413,15 @@ interface BoltdocsIntegrationsConfig {
250
413
  custom?: BoltdocsCustomFeedbackConfig;
251
414
  };
252
415
  }
416
+ /**
417
+ * Configuration for drafts visibility control.
418
+ */
419
+ interface BoltdocsDraftsConfig {
420
+ /** If true, drafts are visible in all environments. Default: false */
421
+ visible?: boolean;
422
+ /** Environments where drafts are visible (e.g. ['development', 'staging']). Default: [] */
423
+ environments?: string[];
424
+ }
253
425
  /**
254
426
  * The root configuration object for Boltdocs.
255
427
  */
@@ -260,12 +432,15 @@ interface BoltdocsConfig$1 {
260
432
  theme?: BoltdocsThemeConfig;
261
433
  i18n?: BoltdocsI18nConfig;
262
434
  versions?: BoltdocsVersionsConfig;
435
+ mdx?: BoltdocsMdxConfig;
263
436
  plugins?: BoltdocsPlugin[];
264
437
  collections?: BoltdocsCollectionsConfig;
265
438
  robots?: BoltdocsRobotsConfig;
266
439
  security?: BoltdocsSecurityConfig;
267
440
  seo?: BoltdocsSeoConfig;
268
441
  integrations?: BoltdocsIntegrationsConfig;
442
+ drafts?: BoltdocsDraftsConfig;
443
+ featureFlags?: Record<string, boolean | string>;
269
444
  directoryMeta?: Record<string, unknown>;
270
445
  vite?: unknown;
271
446
  }
@@ -375,6 +550,8 @@ interface ComponentRoute {
375
550
  };
376
551
  /** Draft flag */
377
552
  draft?: boolean;
553
+ /** Feature flags required for this page to be visible */
554
+ featureFlags?: string[];
378
555
  /** Short excerpt for list displays */
379
556
  excerpt?: string;
380
557
  /** Cover image for blog posts */
@@ -1,10 +1,92 @@
1
1
 
2
2
  import * as React$2 from "react";
3
3
  import { ComponentType, ReactNode } from "react";
4
- import { Plugin } from "vite";
5
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
+ import { Plugin } from "vite";
6
6
 
7
7
  //#region src/shared/types.d.ts
8
+ /**
9
+ * Metadata representing a single documentation route.
10
+ * This information is used to build the client-side router and the sidebar navigation.
11
+ */
12
+ interface RouteMeta {
13
+ /** The final URL path for the route (e.g., '/docs/guide/start') */
14
+ path: string;
15
+ /** The absolute filesystem path to the source markdown/mdx file */
16
+ componentPath: string;
17
+ /** The title of the page, usually extracted from frontmatter or the filename */
18
+ title: string;
19
+ /** The relative path from the docs directory, used for edit links */
20
+ filePath: string;
21
+ /** Optional description of the page (for SEO/meta tags) */
22
+ description?: string;
23
+ /** Optional explicit position for ordering in the sidebar */
24
+ sidebarPosition?: number;
25
+ /** The group (directory) this route belongs to */
26
+ group?: string;
27
+ /** The display title for the route's group */
28
+ groupTitle?: string;
29
+ /** Optional explicit position for ordering the group itself */
30
+ groupPosition?: number;
31
+ /** Optional icon for the route's group */
32
+ groupIcon?: string;
33
+ /** The sub-route group this route belongs to (from folders starting with _) */
34
+ subRouteGroup?: string;
35
+ /** Extracted markdown headings for search indexing */
36
+ headings?: {
37
+ level: number;
38
+ text: string;
39
+ id: string;
40
+ }[];
41
+ /** The locale this route belongs to, if i18n is configured */
42
+ locale?: string;
43
+ /** The version this route belongs to, if versioning is configured */
44
+ version?: string;
45
+ /** Optional badge to display next to the sidebar item (e.g., 'New', 'Experimental') */
46
+ badge?: BadgeValue;
47
+ /** Optional icon to display (Lucide icon name or raw SVG) */
48
+ icon?: string;
49
+ /** The tab this route belongs to, if tabs are configured */
50
+ tab?: string;
51
+ /** The collection this route belongs to (from [name] directories like [blog]) */
52
+ collection?: string;
53
+ /** Tags for blog posts or other taxonomy */
54
+ tags?: string[];
55
+ /** Author identifier for blog posts */
56
+ author?: string;
57
+ /** Draft flag — excluded from production builds */
58
+ draft?: boolean;
59
+ /** Feature flags required for this page to be visible */
60
+ featureFlags?: string[];
61
+ /** Short excerpt/summary for list displays */
62
+ excerpt?: string;
63
+ /** Cover image for blog posts */
64
+ coverImage?: string;
65
+ /** The extracted plain-text content of the page for search indexing */
66
+ _content?: string;
67
+ /** The raw markdown content of the page */
68
+ _rawContent?: string;
69
+ /** Extracted SEO and Open Graph metadata from frontmatter */
70
+ seo?: Record<string, any>;
71
+ /** The publication date */
72
+ date?: string | Date;
73
+ /** The last updated timestamp or date */
74
+ lastUpdated?: string | number | Date;
75
+ /** Optional category for the page */
76
+ category?: string;
77
+ /** Optional explicit order (alternative to sidebarPosition) */
78
+ order?: number;
79
+ /** Optional explicit label for the sidebar */
80
+ sidebarLabel?: string;
81
+ /** Whether the page is hidden from the sidebar */
82
+ sidebarHidden?: boolean;
83
+ /** Raw extensible frontmatter data for custom components and formatters */
84
+ frontmatter?: Record<string, any>;
85
+ /** Optional recursive child routes for deep sidebar hierarchies */
86
+ subRoutes?: RouteMeta[];
87
+ /** Clean URL segments stripped of locale/version prefixes */
88
+ slugParts?: string[];
89
+ }
8
90
  /**
9
91
  * Represents a single social link in the configuration.
10
92
  */
@@ -12,12 +94,6 @@ interface BoltdocsSocialLink {
12
94
  icon: 'discord' | 'x' | 'github' | 'bluesky' | string;
13
95
  link: string;
14
96
  }
15
- /**
16
- * Configuration for the site footer.
17
- */
18
- interface BoltdocsFooterConfig {
19
- text?: string;
20
- }
21
97
  /**
22
98
  * Theme-specific configuration options.
23
99
  */
@@ -48,7 +124,6 @@ interface BoltdocsThemeConfig {
48
124
  icon?: string;
49
125
  }>;
50
126
  socialLinks?: BoltdocsSocialLink[];
51
- footer?: BoltdocsFooterConfig;
52
127
  editLink?: string;
53
128
  communityHelp?: string;
54
129
  version?: string;
@@ -118,6 +193,85 @@ type BadgeValue = string | {
118
193
  text: string;
119
194
  expires?: string;
120
195
  };
196
+ /**
197
+ * Context provided to plugin lifecycle hooks.
198
+ */
199
+ interface PluginContext {
200
+ readonly config: BoltdocsConfig$1;
201
+ readonly logger: PluginLogger;
202
+ readonly store: PluginStore;
203
+ readonly meta: PluginMeta;
204
+ readonly docsDir: string;
205
+ readonly rootDir: string;
206
+ readonly outDir: string;
207
+ readonly routes: RouteMeta[];
208
+ }
209
+ /**
210
+ * Logger interface for plugin logging.
211
+ */
212
+ interface PluginLogger {
213
+ info(message: string): void;
214
+ warn(message: string): void;
215
+ error(message: string | Error): void;
216
+ debug(message: string): void;
217
+ }
218
+ /**
219
+ * Key-value store interface for plugins.
220
+ */
221
+ interface PluginStore {
222
+ get<T = unknown>(pluginName: string, key: string): T | undefined;
223
+ set(pluginName: string, key: string, value: unknown): void;
224
+ has(pluginName: string, key: string): boolean;
225
+ }
226
+ /**
227
+ * Plugin metadata provided in the context.
228
+ */
229
+ interface PluginMeta {
230
+ name: string;
231
+ version?: string;
232
+ boltdocsVersion?: string;
233
+ }
234
+ /**
235
+ * Plugin lifecycle hooks with full type safety.
236
+ */
237
+ interface PluginLifecycleHooks {
238
+ beforeBuild?: (ctx: PluginContext) => Promise<void> | void;
239
+ afterBuild?: (ctx: PluginContext) => Promise<void> | void;
240
+ beforeDev?: (ctx: PluginContext) => Promise<void> | void;
241
+ afterDev?: (ctx: PluginContext) => Promise<void> | void;
242
+ buildEnd?: (ctx: PluginContext) => Promise<void> | void;
243
+ transformSource?: (ctx: PluginContext, params: {
244
+ code: string;
245
+ filePath: string;
246
+ }) => Promise<{
247
+ code: string;
248
+ }> | {
249
+ code: string;
250
+ };
251
+ transformMdx?: (ctx: PluginContext, params: {
252
+ code: string;
253
+ filePath: string;
254
+ }) => Promise<{
255
+ code: string;
256
+ }> | {
257
+ code: string;
258
+ };
259
+ transformHtml?: (ctx: PluginContext, params: {
260
+ html: string;
261
+ path: string;
262
+ }) => Promise<{
263
+ html: string;
264
+ }> | {
265
+ html: string;
266
+ };
267
+ }
268
+ /**
269
+ * MDX processor configuration.
270
+ * When `processor` is set to 'satteri', the Sätteri Rust-based compiler is used.
271
+ */
272
+ interface BoltdocsMdxConfig {
273
+ processor?: 'unified' | 'satteri';
274
+ }
121
275
  /**
122
276
  * Defines a Boltdocs plugin.
123
277
  *
@@ -133,8 +287,8 @@ interface BoltdocsPlugin {
133
287
  rehypePlugins?: unknown[];
134
288
  vitePlugins?: Plugin[];
135
289
  components?: Record<string, string>;
136
- /** Lifecycle hooks — use the `PluginLifecycleHooks` type from the node API. */
137
- hooks?: Record<string, (ctx: unknown) => Promise<void> | void>;
290
+ /** Lifecycle hooks with full type safety */
291
+ hooks?: PluginLifecycleHooks;
138
292
  }
139
293
  /**
140
294
  * Configuration for the collections (blog) feature.
@@ -236,11 +390,20 @@ interface BoltdocsVercelConfig {
236
390
  analytics?: boolean;
237
391
  speedInsights?: boolean;
238
392
  }
393
+ interface BoltdocsPostHogConfig {
394
+ apiKey: string;
395
+ host?: string;
396
+ capturePageview?: boolean;
397
+ capturePageleave?: boolean;
398
+ sessionRecording?: boolean;
399
+ autocapture?: boolean;
400
+ }
239
401
  interface BoltdocsIntegrationsConfig {
240
402
  analytics?: {
241
403
  ga4?: BoltdocsGA4Config;
242
404
  vercel?: BoltdocsVercelConfig;
243
405
  gtm?: BoltdocsGTMConfig;
406
+ posthog?: BoltdocsPostHogConfig;
244
407
  };
245
408
  search?: {
246
409
  algolia?: BoltdocsAlgoliaConfig;
@@ -250,6 +413,15 @@ interface BoltdocsIntegrationsConfig {
250
413
  custom?: BoltdocsCustomFeedbackConfig;
251
414
  };
252
415
  }
416
+ /**
417
+ * Configuration for drafts visibility control.
418
+ */
419
+ interface BoltdocsDraftsConfig {
420
+ /** If true, drafts are visible in all environments. Default: false */
421
+ visible?: boolean;
422
+ /** Environments where drafts are visible (e.g. ['development', 'staging']). Default: [] */
423
+ environments?: string[];
424
+ }
253
425
  /**
254
426
  * The root configuration object for Boltdocs.
255
427
  */
@@ -260,12 +432,15 @@ interface BoltdocsConfig$1 {
260
432
  theme?: BoltdocsThemeConfig;
261
433
  i18n?: BoltdocsI18nConfig;
262
434
  versions?: BoltdocsVersionsConfig;
435
+ mdx?: BoltdocsMdxConfig;
263
436
  plugins?: BoltdocsPlugin[];
264
437
  collections?: BoltdocsCollectionsConfig;
265
438
  robots?: BoltdocsRobotsConfig;
266
439
  security?: BoltdocsSecurityConfig;
267
440
  seo?: BoltdocsSeoConfig;
268
441
  integrations?: BoltdocsIntegrationsConfig;
442
+ drafts?: BoltdocsDraftsConfig;
443
+ featureFlags?: Record<string, boolean | string>;
269
444
  directoryMeta?: Record<string, unknown>;
270
445
  vite?: unknown;
271
446
  }
@@ -375,6 +550,8 @@ interface ComponentRoute {
375
550
  };
376
551
  /** Draft flag */
377
552
  draft?: boolean;
553
+ /** Feature flags required for this page to be visible */
554
+ featureFlags?: string[];
378
555
  /** Short excerpt for list displays */
379
556
  excerpt?: string;
380
557
  /** Cover image for blog posts */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boltdocs",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "A lightweight documentation generator for React projects.",
5
5
  "main": "dist/node/index.mjs",
6
6
  "module": "dist/node/index.mjs",
@@ -22,6 +22,16 @@
22
22
  "import": "./dist/node/index.mjs",
23
23
  "require": "./dist/node/index.cjs"
24
24
  },
25
+ "./node/cache": {
26
+ "types": "./dist/node/cache.d.ts",
27
+ "import": "./dist/node/cache.mjs",
28
+ "require": "./dist/node/cache.cjs"
29
+ },
30
+ "./node/mdx/shiki-adapter": {
31
+ "types": "./dist/node/mdx/shiki-adapter.d.ts",
32
+ "import": "./dist/node/mdx/shiki-adapter.mjs",
33
+ "require": "./dist/node/mdx/shiki-adapter.cjs"
34
+ },
25
35
  "./server": {
26
36
  "types": "./dist/server/index.d.ts",
27
37
  "import": "./dist/server/index.mjs",
@@ -92,9 +102,9 @@
92
102
  "unist-util-visit": "5.1.0",
93
103
  "vite": "7.0.0 || 8.0.0",
94
104
  "zod": "4.3.6",
95
- "@bdocs/parser": "1.0.0",
96
- "@bdocs/ssg": "0.1.1",
97
- "@bdocs/plugin-image-optimizer": "0.2.1"
105
+ "@bdocs/parser": "1.1.0",
106
+ "@bdocs/plugin-image-optimizer": "0.2.1",
107
+ "@bdocs/ssg": "0.2.0"
98
108
  },
99
109
  "peerDependencies": {
100
110
  "react": "19.0.0",
@@ -114,7 +124,8 @@
114
124
  "jsdom": "^24.1.0",
115
125
  "tsdown": "0.21.7",
116
126
  "typescript": "5.9.3",
117
- "vitest": "^3.0.0"
127
+ "vitest": "^3.0.0",
128
+ "@bdocs/processor-satteri": "0.1.0"
118
129
  },
119
130
  "scripts": {
120
131
  "build": "tsdown --config-loader unrun",