boltdocs 3.3.5 → 3.4.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 (126) hide show
  1. package/dist/{adapters-BKzKe2mO.mjs → adapters-BXiBWAKs.mjs} +1 -1
  2. package/dist/{adapters-DwDTQoCG.cjs → adapters-Czl3WtQt.cjs} +1 -1
  3. package/dist/{build-B672n0hL.cjs → build-CNkXRdk8.cjs} +1 -1
  4. package/dist/{build-BVoMHMhw.mjs → build-CqUBsXVC.mjs} +1 -1
  5. package/dist/client/index.cjs +245 -56
  6. package/dist/client/index.d.cts +3 -3
  7. package/dist/client/index.d.ts +3 -3
  8. package/dist/client/index.js +246 -60
  9. package/dist/client/mdx.cjs +1 -1
  10. package/dist/client/mdx.js +1 -1
  11. package/dist/client/primitives.cjs +5 -5
  12. package/dist/client/primitives.d.cts +92 -42
  13. package/dist/client/primitives.d.ts +101 -51
  14. package/dist/client/primitives.js +4 -4
  15. package/dist/client/router.cjs +1 -1
  16. package/dist/client/router.d.cts +1 -1
  17. package/dist/client/router.d.ts +1 -1
  18. package/dist/client/router.js +1 -1
  19. package/dist/client/theme/reset.css +41 -0
  20. package/dist/config-B3SEoVjG.cjs +7 -0
  21. package/dist/{config-PLvresCv.cjs → config-Bfakeadu.cjs} +1 -1
  22. package/dist/config-CTcfF-0c.mjs +7 -0
  23. package/dist/dev-D1DmOSjn.mjs +6 -0
  24. package/dist/dev-DH6cSge8.cjs +6 -0
  25. package/dist/{docs-layout-CbZ7LDRe.js → docs-layout-CmntYM6p.js} +46 -147
  26. package/dist/{docs-layout-vzfXed1Q.cjs → docs-layout-DIgxJ5c7.cjs} +23 -130
  27. package/dist/{doctor-DMECtdK6.cjs → doctor-BLxm2alc.cjs} +1 -1
  28. package/dist/{doctor-FuFY1jBz.cjs → doctor-Dd-JMTRo.cjs} +1 -1
  29. package/dist/{doctor-i8Qmd8DJ.mjs → doctor-DogHujrP.mjs} +1 -1
  30. package/dist/{image-Hnaa2bJd.cjs → image-Bke2ojW1.cjs} +3 -3
  31. package/dist/{image-B-NDSDuY.js → image-CaY2w0ua.js} +2 -1
  32. package/dist/index--xbYbT8N.d.ts +343 -0
  33. package/dist/{index-Bg-JtZeK.d.cts → index-B_o5y34l.d.cts} +112 -13
  34. package/dist/{index-B3o307nd.d.ts → index-Bx0CUd7Q.d.ts} +112 -13
  35. package/dist/index-RK7W_Fxy.d.cts +343 -0
  36. package/dist/{link-CgdI6O2o.js → link-CSe_oD8Y.js} +137 -139
  37. package/dist/{link-vZjmD-es.cjs → link-Xb69Oy2F.cjs} +144 -169
  38. package/dist/{mdx-D0Absdq5.cjs → mdx-BCOrMd-P.cjs} +68 -16
  39. package/dist/{mdx-BRT71V5Q.js → mdx-BijiEbkp.js} +62 -15
  40. package/dist/{native-nLA4Jr0T.cjs → native-BbtRkce5.cjs} +1 -1
  41. package/dist/node/cli-entry.cjs +1 -1
  42. package/dist/node/cli-entry.mjs +1 -1
  43. package/dist/node/highlight.d.cts +2 -2
  44. package/dist/node/highlight.d.mts +2 -2
  45. package/dist/node/index.cjs +1 -1
  46. package/dist/node/index.d.cts +19 -37
  47. package/dist/node/index.d.mts +20 -38
  48. package/dist/node/index.mjs +1 -1
  49. package/dist/node/mdx/shiki-adapter.cjs +1 -1
  50. package/dist/node/mdx/shiki-adapter.d.cts +7 -2
  51. package/dist/node/mdx/shiki-adapter.d.mts +7 -2
  52. package/dist/node/mdx/shiki-adapter.mjs +1 -1
  53. package/dist/node-BgiLCa0I.cjs +39 -0
  54. package/dist/node-Da3tYBHo.mjs +39 -0
  55. package/dist/{package-CNqjEYE1.cjs → package-D1gVs5gQ.cjs} +1 -1
  56. package/dist/{package-sdcKhDhe.mjs → package-YgQJn3Yh.mjs} +1 -1
  57. package/dist/pages-external-B_r6gvqP.cjs +6 -0
  58. package/dist/pages-external-jmK7AHaO.mjs +6 -0
  59. package/dist/{parser-CD8Oo8qh.mjs → parser-CvNZc5s3.mjs} +1 -1
  60. package/dist/{parser-vPaKvzLp.cjs → parser-DJLWTiO-.cjs} +1 -1
  61. package/dist/plugin-DW9K2fW5.mjs +69 -0
  62. package/dist/plugin-NwGKyTJX.cjs +69 -0
  63. package/dist/{plugin-context-DuSg-Hax.mjs → plugin-context-COh-cbsW.mjs} +1 -1
  64. package/dist/{plugin-context-CscLcXjH.cjs → plugin-context-FIHaWn6r.cjs} +2 -2
  65. package/dist/{plugin-lifecycle-BywrEoWK.cjs → plugin-lifecycle-D9fTRaWY.cjs} +1 -1
  66. package/dist/{registry-BbB6NqSv.d.cts → registry-BFmzj1yg.d.mts} +1 -1
  67. package/dist/{registry-sJqDv0kE.d.mts → registry-BoswPzYV.d.cts} +1 -1
  68. package/dist/{resolve-C5rT6B21.mjs → resolve-5puUe7eS.mjs} +1 -1
  69. package/dist/{resolve-BelytNYR.cjs → resolve-CF4ZLfqx.cjs} +1 -1
  70. package/dist/route-paths-B6ocUfNY.cjs +6 -0
  71. package/dist/route-paths-DyDji4bX.mjs +6 -0
  72. package/dist/{router-CZBxMRAH.js → router-B5e8k4qK.js} +175 -10
  73. package/dist/{router-C3kygdRK.cjs → router-DKC0Lu0n.cjs} +204 -9
  74. package/dist/{routes-C3_w9fLX.cjs → routes-D55M8UrH.cjs} +1 -1
  75. package/dist/routes-DdE6Lfcl.cjs +6 -0
  76. package/dist/routes-_I_8PQYF.mjs +6 -0
  77. package/dist/{search-dialog-x_qHU8ty.cjs → search-dialog-BOQRHKTb.cjs} +197 -24
  78. package/dist/{search-dialog-BqkzDTq2.js → search-dialog-BXil4_7P.js} +190 -29
  79. package/dist/search-dialog-CwlBd-Mu.cjs +747 -0
  80. package/dist/{search-dialog-B9mdxsUC.js → search-dialog-D3Obh3eA.js} +1 -1
  81. package/dist/search-dialog-DeplpVEB.js +717 -0
  82. package/dist/{search-dialog-DCtm2dyR.cjs → search-dialog-cHXR5zhL.cjs} +1 -1
  83. package/dist/server/index.cjs +1 -1
  84. package/dist/server/index.d.mts +1 -1
  85. package/dist/server/index.mjs +1 -1
  86. package/dist/ssg-static-options-Br1_u9qp.mjs +6 -0
  87. package/dist/ssg-static-options-CVvGKM8i.cjs +6 -0
  88. package/dist/types-58Ac3UGI.d.cts +114 -0
  89. package/dist/types-BwnGf-1E.d.mts +114 -0
  90. package/dist/virtual-modules-C4-qxFlL.cjs +40 -0
  91. package/dist/virtual-modules-DiWUKJGP.mjs +40 -0
  92. package/package.json +8 -5
  93. package/src/shared/types.ts +133 -987
  94. package/dist/config-CrsQJHQz.cjs +0 -7
  95. package/dist/config-DC0nMMk7.mjs +0 -7
  96. package/dist/dev-B49V6O6p.mjs +0 -6
  97. package/dist/dev-DbuhNcF5.cjs +0 -6
  98. package/dist/index-CgWkOCCn.d.cts +0 -1193
  99. package/dist/index-CuNSD3E2.d.ts +0 -1193
  100. package/dist/node-BljvHMpS.cjs +0 -23
  101. package/dist/node-CWxGw4H4.mjs +0 -23
  102. package/dist/pages-external-BBw8ObVK.mjs +0 -6
  103. package/dist/pages-external-DPiPFxxP.cjs +0 -6
  104. package/dist/plugin-BPcm1cU0.mjs +0 -69
  105. package/dist/plugin-WUhxnpko.cjs +0 -69
  106. package/dist/routes-C0kb4ue6.cjs +0 -6
  107. package/dist/routes-C4wrLWwu.mjs +0 -6
  108. package/dist/search-dialog-Bp_ouN1c.cjs +0 -550
  109. package/dist/search-dialog-an2BNMj6.js +0 -526
  110. package/dist/types-Db6zToZH.d.mts +0 -975
  111. package/dist/types-o7iZ2BAR.d.cts +0 -975
  112. package/dist/virtual-modules-B2X4Ht2r.mjs +0 -39
  113. package/dist/virtual-modules-DPsdHKcu.cjs +0 -39
  114. /package/dist/{audit-CMc_ydRr.mjs → audit-CYAkXXvP.mjs} +0 -0
  115. /package/dist/{audit-CHkGiV3c.cjs → audit-DxCZZTuX.cjs} +0 -0
  116. /package/dist/{csp-BiGAG8aF.cjs → csp-B-gc2Iha.cjs} +0 -0
  117. /package/dist/{csp-D0BOH8ae.mjs → csp-f8DOcI_7.mjs} +0 -0
  118. /package/dist/{generator-BCrZL53x.cjs → generator-CBAPKY6r.cjs} +0 -0
  119. /package/dist/{generator-CFukoGa0.mjs → generator-MRpn-yp6.mjs} +0 -0
  120. /package/dist/{handler-Lex5DbvG.mjs → handler-DBZqoWt2.mjs} +0 -0
  121. /package/dist/{handler-Ch-Q9NAB.cjs → handler-ryZR9Q41.cjs} +0 -0
  122. /package/dist/{index-HAwIo4nZ.d.mts → index-CPr34I2C.d.mts} +0 -0
  123. /package/dist/{native-BYKMke79.mjs → native-DZ6WMwjG.mjs} +0 -0
  124. /package/dist/{native-BOet8hpE.cjs → native-DeKxny_T.cjs} +0 -0
  125. /package/dist/{update-check-BXD1atVv.mjs → update-check-BXx8te9F.mjs} +0 -0
  126. /package/dist/{update-check-DFQZyoSU.cjs → update-check-CiIeC7CX.cjs} +0 -0
@@ -3,4 +3,4 @@
3
3
  * Copyright (c) 2026 Jesus Alcala
4
4
  * Licensed under the MIT License.
5
5
  */
6
- import{t as e}from"./handler-Lex5DbvG.mjs";const t={"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`,"Content-Type":`application/json`};async function n(n,r){if(Object.entries(t).forEach(([e,t])=>{r.setHeader(e,t)}),n.method===`OPTIONS`){r.status(200).end();return}if(n.method!==`POST`){r.status(405).json({error:`Method Not Allowed`});return}try{let t=await e(n.body,process.env);r.status(200).json(t)}catch(e){let t=e instanceof Error?e.message:`Failed to submit feedback`;return r.status(500).json({error:t})}}async function r(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function i(n,r={}){let i=(e,n=200)=>new Response(e?JSON.stringify(e):null,{status:n,headers:t});if(n.method===`OPTIONS`)return i(null);if(n.method!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e(await n.json(),{...process.env,...r}))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function a(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}export{n as i,i as n,r,a as t};
6
+ import{t as e}from"./handler-DBZqoWt2.mjs";const t={"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`,"Content-Type":`application/json`};async function n(n,r){if(Object.entries(t).forEach(([e,t])=>{r.setHeader(e,t)}),n.method===`OPTIONS`){r.status(200).end();return}if(n.method!==`POST`){r.status(405).json({error:`Method Not Allowed`});return}try{let t=await e(n.body,process.env);r.status(200).json(t)}catch(e){let t=e instanceof Error?e.message:`Failed to submit feedback`;return r.status(500).json({error:t})}}async function r(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function i(n,r={}){let i=(e,n=200)=>new Response(e?JSON.stringify(e):null,{status:n,headers:t});if(n.method===`OPTIONS`)return i(null);if(n.method!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e(await n.json(),{...process.env,...r}))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function a(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}export{n as i,i as n,r,a as t};
@@ -3,4 +3,4 @@
3
3
  * Copyright (c) 2026 Jesus Alcala
4
4
  * Licensed under the MIT License.
5
5
  */
6
- const e=require(`./handler-Ch-Q9NAB.cjs`),t={"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`,"Content-Type":`application/json`};async function n(n,r){if(Object.entries(t).forEach(([e,t])=>{r.setHeader(e,t)}),n.method===`OPTIONS`){r.status(200).end();return}if(n.method!==`POST`){r.status(405).json({error:`Method Not Allowed`});return}try{let t=await e.t(n.body,process.env);r.status(200).json(t)}catch(e){let t=e instanceof Error?e.message:`Failed to submit feedback`;return r.status(500).json({error:t})}}async function r(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e.t(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function i(n,r={}){let i=(e,n=200)=>new Response(e?JSON.stringify(e):null,{status:n,headers:t});if(n.method===`OPTIONS`)return i(null);if(n.method!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e.t(await n.json(),{...process.env,...r}))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function a(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e.t(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return a}});
6
+ const e=require(`./handler-ryZR9Q41.cjs`),t={"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`,"Content-Type":`application/json`};async function n(n,r){if(Object.entries(t).forEach(([e,t])=>{r.setHeader(e,t)}),n.method===`OPTIONS`){r.status(200).end();return}if(n.method!==`POST`){r.status(405).json({error:`Method Not Allowed`});return}try{let t=await e.t(n.body,process.env);r.status(200).json(t)}catch(e){let t=e instanceof Error?e.message:`Failed to submit feedback`;return r.status(500).json({error:t})}}async function r(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e.t(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function i(n,r={}){let i=(e,n=200)=>new Response(e?JSON.stringify(e):null,{status:n,headers:t});if(n.method===`OPTIONS`)return i(null);if(n.method!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e.t(await n.json(),{...process.env,...r}))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}async function a(n,r=process.env){let i=(e,n=200)=>({statusCode:n,headers:t,body:e?JSON.stringify(e):``});if(n.httpMethod===`OPTIONS`)return i(null,200);if(n.httpMethod!==`POST`)return i({error:`Method Not Allowed`},405);try{return i(await e.t(n.body?JSON.parse(n.body):{},r))}catch(e){return i({error:e instanceof Error?e.message:`Failed to submit feedback`},500)}}Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return a}});
@@ -3,4 +3,4 @@
3
3
  * Copyright (c) 2026 Jesus Alcala
4
4
  * Licensed under the MIT License.
5
5
  */
6
- const e=require(`./chunk-D1Md3oWO.cjs`),t=require(`./node-BljvHMpS.cjs`),n=require(`./node/cache.cjs`),r=require(`./update-check-DFQZyoSU.cjs`);let i=require(`node:path`);i=e.r(i);let a=require(`node:fs`);a=e.r(a);let o=require(`@bdocs/dui`),s=require(`vite`);const c=new Set([`Client build`,`Server build`,`Render pages`,`Static loader data`,`Build metrics`]);function l(e,t){let n=i.default.join(e,`.boltdocs`,`benchmarks`);a.default.existsSync(n)||a.default.mkdirSync(n,{recursive:!0});let r=i.default.join(n,`phases-report-${new Date().toISOString().replace(/[:.]/g,`-`).slice(0,19)}.json`),o={timestamp:new Date().toISOString(),root:e,...t,error:t.error?.message||t.error?.toString()};return a.default.writeFileSync(r,JSON.stringify(o,null,2)),r}async function u(e=process.cwd(),i={}){process.env.NODE_ENV=`production`,r.t();let a=process.env.BOLTDOCS_BENCHMARK_PHASES===`true`;try{let i=await t.c().run({root:e,timing:{}});if(a&&console.log(`[boltdocs] ${JSON.stringify({name:`Build pipeline`,success:i.success,steps:i.stepResults.map(e=>({name:e.name,duration:Math.round(e.duration),success:e.success,...e.details?{details:e.details}:{}}))})}`),!i.success){if((0,o.error)(`Build failed at step "${i.failedStep}":`,i.error),a){let t=l(e,i);console.log(`[benchmark] failure report written to ${t}`)}await n.flushCache(),process.exit(1)}if(a){let t=l(e,i);console.log(`[benchmark] phase report written to ${t}`),await n.flushCache(),process.exit(0)}let s=i.stepResults.filter(e=>!c.has(e.name)),u=i.stepResults.find(e=>e.name===`Build metrics`)?.metrics,d=e=>(e/1024).toFixed(0),f=e=>(e/1024/1024).toFixed(1),p=e=>e>1024*1024?`${f(e)} MB`:`${d(e)} kB`;console.log(r.a({totalMs:i.timing.total,steps:s.map(e=>({name:e.name,success:e.success,duration:e.duration,details:e.details})),pages:u?.totalPages,jsSize:u?p(u.jsSize):void 0,cssSize:u?p(u.cssSize):void 0,outDir:`dist/`})),await n.flushCache(),process.exit(0)}catch(e){(0,o.error)(`Build failed:`,e),await n.flushCache(),process.exit(1)}}async function d(e=process.cwd(),n={}){try{let i=await t.n(e,`production`,void 0,{skipTypes:!0,skipLinkTree:!0});i.logLevel=`warn`,i.clearScreen=!1,n.port!==void 0&&(i.preview=i.preview||{},i.preview.port=Number(n.port)),n.host!==void 0&&(i.preview=i.preview||{},i.preview.host=n.host);let a=performance.now(),o=(await(0,s.preview)(i)).resolvedUrls;console.log(r.c(o?.local?.[0]??`http://localhost:${n.port??4173}`,o?.network?.[0]??null,{readyIn:performance.now()-a}))}catch(e){(0,o.error)(`Failed to start preview server:`,e),process.exit(1)}}exports.buildAction=u,exports.previewAction=d;
6
+ const e=require(`./chunk-D1Md3oWO.cjs`),t=require(`./node-BgiLCa0I.cjs`),n=require(`./node/cache.cjs`),r=require(`./update-check-CiIeC7CX.cjs`);let i=require(`node:path`);i=e.r(i);let a=require(`node:fs`);a=e.r(a);let o=require(`@bdocs/dui`),s=require(`vite`);const c=new Set([`Client build`,`Server build`,`Render pages`,`Static loader data`,`Build metrics`]);function l(e,t){let n=i.default.join(e,`.boltdocs`,`benchmarks`);a.default.existsSync(n)||a.default.mkdirSync(n,{recursive:!0});let r=i.default.join(n,`phases-report-${new Date().toISOString().replace(/[:.]/g,`-`).slice(0,19)}.json`),o={timestamp:new Date().toISOString(),root:e,...t,error:t.error?.message||t.error?.toString()};return a.default.writeFileSync(r,JSON.stringify(o,null,2)),r}async function u(e=process.cwd(),i={}){process.env.NODE_ENV=`production`,r.t();let a=process.env.BOLTDOCS_BENCHMARK_PHASES===`true`;try{let i=await t.u().run({root:e,timing:{}});if(a&&console.log(`[boltdocs] ${JSON.stringify({name:`Build pipeline`,success:i.success,steps:i.stepResults.map(e=>({name:e.name,duration:Math.round(e.duration),success:e.success,...e.details?{details:e.details}:{}}))})}`),!i.success){if((0,o.error)(`Build failed at step "${i.failedStep}":`,i.error),a){let t=l(e,i);console.log(`[benchmark] failure report written to ${t}`)}await n.flushCache(),process.exit(1)}if(a){let t=l(e,i);console.log(`[benchmark] phase report written to ${t}`),await n.flushCache(),process.exit(0)}let s=i.stepResults.filter(e=>!c.has(e.name)),u=i.stepResults.find(e=>e.name===`Build metrics`)?.metrics,d=e=>(e/1024).toFixed(0),f=e=>(e/1024/1024).toFixed(1),p=e=>e>1024*1024?`${f(e)} MB`:`${d(e)} kB`;console.log(r.a({totalMs:i.timing.total,steps:s.map(e=>({name:e.name,success:e.success,duration:e.duration,details:e.details})),pages:u?.totalPages,jsSize:typeof u?.jsSize==`number`?p(u.jsSize):void 0,cssSize:typeof u?.cssSize==`number`?p(u.cssSize):void 0,outDir:`dist/`})),await n.flushCache(),process.exit(0)}catch(e){(0,o.error)(`Build failed:`,e),await n.flushCache(),process.exit(1)}}async function d(e=process.cwd(),n={}){try{let i=await t.n(e,`production`,void 0,{skipTypes:!0,skipLinkTree:!0});i.logLevel=`warn`,i.clearScreen=!1,n.port!==void 0&&(i.preview=i.preview||{},i.preview.port=Number(n.port)),n.host!==void 0&&(i.preview=i.preview||{},i.preview.host=n.host);let a=performance.now(),o=(await(0,s.preview)(i)).resolvedUrls;console.log(r.c(o?.local?.[0]??`http://localhost:${n.port??4173}`,o?.network?.[0]??null,{readyIn:performance.now()-a}))}catch(e){(0,o.error)(`Failed to start preview server:`,e),process.exit(1)}}exports.buildAction=u,exports.previewAction=d;
@@ -3,4 +3,4 @@
3
3
  * Copyright (c) 2026 Jesus Alcala
4
4
  * Licensed under the MIT License.
5
5
  */
6
- import{l as e,n as t}from"./node-CWxGw4H4.mjs";import{flushCache as n}from"./node/cache.mjs";import{a as r,c as i,t as a}from"./update-check-BXD1atVv.mjs";import o from"node:path";import s from"node:fs";import{error as c}from"@bdocs/dui";import{preview as l}from"vite";const u=new Set([`Client build`,`Server build`,`Render pages`,`Static loader data`,`Build metrics`]);function d(e,t){let n=o.join(e,`.boltdocs`,`benchmarks`);s.existsSync(n)||s.mkdirSync(n,{recursive:!0});let r=o.join(n,`phases-report-${new Date().toISOString().replace(/[:.]/g,`-`).slice(0,19)}.json`),i={timestamp:new Date().toISOString(),root:e,...t,error:t.error?.message||t.error?.toString()};return s.writeFileSync(r,JSON.stringify(i,null,2)),r}async function f(t=process.cwd(),i={}){process.env.NODE_ENV=`production`,a();let o=process.env.BOLTDOCS_BENCHMARK_PHASES===`true`;try{let i=await e().run({root:t,timing:{}});if(o&&console.log(`[boltdocs] ${JSON.stringify({name:`Build pipeline`,success:i.success,steps:i.stepResults.map(e=>({name:e.name,duration:Math.round(e.duration),success:e.success,...e.details?{details:e.details}:{}}))})}`),!i.success){if(c(`Build failed at step "${i.failedStep}":`,i.error),o){let e=d(t,i);console.log(`[benchmark] failure report written to ${e}`)}await n(),process.exit(1)}if(o){let e=d(t,i);console.log(`[benchmark] phase report written to ${e}`),await n(),process.exit(0)}let a=i.stepResults.filter(e=>!u.has(e.name)),s=i.stepResults.find(e=>e.name===`Build metrics`)?.metrics,l=e=>(e/1024).toFixed(0),f=e=>(e/1024/1024).toFixed(1),p=e=>e>1024*1024?`${f(e)} MB`:`${l(e)} kB`;console.log(r({totalMs:i.timing.total,steps:a.map(e=>({name:e.name,success:e.success,duration:e.duration,details:e.details})),pages:s?.totalPages,jsSize:s?p(s.jsSize):void 0,cssSize:s?p(s.cssSize):void 0,outDir:`dist/`})),await n(),process.exit(0)}catch(e){c(`Build failed:`,e),await n(),process.exit(1)}}async function p(e=process.cwd(),n={}){try{let r=await t(e,`production`,void 0,{skipTypes:!0,skipLinkTree:!0});r.logLevel=`warn`,r.clearScreen=!1,n.port!==void 0&&(r.preview=r.preview||{},r.preview.port=Number(n.port)),n.host!==void 0&&(r.preview=r.preview||{},r.preview.host=n.host);let a=performance.now(),o=(await l(r)).resolvedUrls;console.log(i(o?.local?.[0]??`http://localhost:${n.port??4173}`,o?.network?.[0]??null,{readyIn:performance.now()-a}))}catch(e){c(`Failed to start preview server:`,e),process.exit(1)}}export{f as buildAction,p as previewAction};
6
+ import{d as e,n as t}from"./node-Da3tYBHo.mjs";import{flushCache as n}from"./node/cache.mjs";import{a as r,c as i,t as a}from"./update-check-BXx8te9F.mjs";import o from"node:path";import s from"node:fs";import{error as c}from"@bdocs/dui";import{preview as l}from"vite";const u=new Set([`Client build`,`Server build`,`Render pages`,`Static loader data`,`Build metrics`]);function d(e,t){let n=o.join(e,`.boltdocs`,`benchmarks`);s.existsSync(n)||s.mkdirSync(n,{recursive:!0});let r=o.join(n,`phases-report-${new Date().toISOString().replace(/[:.]/g,`-`).slice(0,19)}.json`),i={timestamp:new Date().toISOString(),root:e,...t,error:t.error?.message||t.error?.toString()};return s.writeFileSync(r,JSON.stringify(i,null,2)),r}async function f(t=process.cwd(),i={}){process.env.NODE_ENV=`production`,a();let o=process.env.BOLTDOCS_BENCHMARK_PHASES===`true`;try{let i=await e().run({root:t,timing:{}});if(o&&console.log(`[boltdocs] ${JSON.stringify({name:`Build pipeline`,success:i.success,steps:i.stepResults.map(e=>({name:e.name,duration:Math.round(e.duration),success:e.success,...e.details?{details:e.details}:{}}))})}`),!i.success){if(c(`Build failed at step "${i.failedStep}":`,i.error),o){let e=d(t,i);console.log(`[benchmark] failure report written to ${e}`)}await n(),process.exit(1)}if(o){let e=d(t,i);console.log(`[benchmark] phase report written to ${e}`),await n(),process.exit(0)}let a=i.stepResults.filter(e=>!u.has(e.name)),s=i.stepResults.find(e=>e.name===`Build metrics`)?.metrics,l=e=>(e/1024).toFixed(0),f=e=>(e/1024/1024).toFixed(1),p=e=>e>1024*1024?`${f(e)} MB`:`${l(e)} kB`;console.log(r({totalMs:i.timing.total,steps:a.map(e=>({name:e.name,success:e.success,duration:e.duration,details:e.details})),pages:s?.totalPages,jsSize:typeof s?.jsSize==`number`?p(s.jsSize):void 0,cssSize:typeof s?.cssSize==`number`?p(s.cssSize):void 0,outDir:`dist/`})),await n(),process.exit(0)}catch(e){c(`Build failed:`,e),await n(),process.exit(1)}}async function p(e=process.cwd(),n={}){try{let r=await t(e,`production`,void 0,{skipTypes:!0,skipLinkTree:!0});r.logLevel=`warn`,r.clearScreen=!1,n.port!==void 0&&(r.preview=r.preview||{},r.preview.port=Number(n.port)),n.host!==void 0&&(r.preview=r.preview||{},r.preview.host=n.host);let a=performance.now(),o=(await l(r)).resolvedUrls;console.log(i(o?.local?.[0]??`http://localhost:${n.port??4173}`,o?.network?.[0]??null,{readyIn:performance.now()-a}))}catch(e){c(`Failed to start preview server:`,e),process.exit(1)}}export{f as buildAction,p as previewAction};
@@ -4,18 +4,20 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7
- const require_router = require('../router-C3kygdRK.cjs');
8
- const require_link = require('../link-vZjmD-es.cjs');
9
- const require_image = require('../image-Hnaa2bJd.cjs');
10
- const require_mdx = require('../mdx-D0Absdq5.cjs');
11
- const require_docs_layout = require('../docs-layout-vzfXed1Q.cjs');
12
- const require_search_dialog = require('../search-dialog-Bp_ouN1c.cjs');
13
- const require_search_dialog$1 = require('../search-dialog-x_qHU8ty.cjs');
7
+ const require_router = require('../router-DKC0Lu0n.cjs');
8
+ const require_link = require('../link-Xb69Oy2F.cjs');
9
+ const require_image = require('../image-Bke2ojW1.cjs');
10
+ const require_mdx = require('../mdx-BCOrMd-P.cjs');
11
+ const require_docs_layout = require('../docs-layout-DIgxJ5c7.cjs');
12
+ const require_search_dialog = require('../search-dialog-CwlBd-Mu.cjs');
13
+ const require_search_dialog$1 = require('../search-dialog-BOQRHKTb.cjs');
14
14
  let react = require("react");
15
15
  let react_jsx_runtime = require("react/jsx-runtime");
16
16
  let react_aria_components = require("react-aria-components");
17
17
  let react_helmet_async = require("react-helmet-async");
18
18
  react_helmet_async = require_router.__toESM(react_helmet_async);
19
+ let virtual_boltdocs_client_registry = require("virtual:boltdocs-client-registry");
20
+ virtual_boltdocs_client_registry = require_router.__toESM(virtual_boltdocs_client_registry);
19
21
  let virtual_boltdocs_mdx_components = require("virtual:boltdocs-mdx-components");
20
22
  virtual_boltdocs_mdx_components = require_router.__toESM(virtual_boltdocs_mdx_components);
21
23
  let virtual_boltdocs_page_source = require("virtual:boltdocs-page-source");
@@ -309,7 +311,7 @@ function stringifyMetaValue(value) {
309
311
  }
310
312
  function Head({ siteTitle, siteDescription, routes }) {
311
313
  const location = require_router.useLocation();
312
- const config = require_link.useConfig();
314
+ const config = require_router.useConfig();
313
315
  const { currentLocale, currentRoute } = require_search_dialog.useRoutes();
314
316
  const route = (0, react.useMemo)(() => {
315
317
  if (currentRoute) return currentRoute;
@@ -455,6 +457,20 @@ function useCurrentPostData() {
455
457
  return (0, react.use)(CurrentPostContext);
456
458
  }
457
459
 
460
+ //#endregion
461
+ //#region src/client/components/plugin-floating-slots.tsx
462
+ const floatingComponents = (virtual_boltdocs_client_registry.default["floating:after"] ?? []).map((entry) => ({
463
+ id: entry.id,
464
+ Component: (0, react.lazy)(entry.load)
465
+ }));
466
+ function PluginFloatingSlots() {
467
+ if (floatingComponents.length === 0) return null;
468
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
469
+ fallback: null,
470
+ children: floatingComponents.map(({ id, Component }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {}, id))
471
+ });
472
+ }
473
+
458
474
  //#endregion
459
475
  //#region src/client/ssg/boltdocs-shell.tsx
460
476
  /**
@@ -565,7 +581,7 @@ function BoltdocsShell({ config, routes, components = {}, collectionsData, conte
565
581
  routes,
566
582
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_image.ThemeProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_docs_layout.UIProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MdxComponentsProvider, {
567
583
  components: allComponents,
568
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_link.ConfigContext.Provider, {
584
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_router.ConfigContext.Provider, {
569
585
  value: config,
570
586
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CollectionsProvider, {
571
587
  collectionsData: collectionsData || {},
@@ -586,9 +602,9 @@ function BoltdocsShell({ config, routes, components = {}, collectionsData, conte
586
602
  siteDescription: config.theme?.description,
587
603
  routes
588
604
  }),
589
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.InternalErrorBoundary, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
605
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.InternalErrorBoundary, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
590
606
  className: require_link.cn("boltdocs-shell-content h-screen overflow-hidden", contentClassName),
591
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_router.Outlet, {})
607
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_router.Outlet, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PluginFloatingSlots, {})]
592
608
  }) })
593
609
  ]
594
610
  })
@@ -641,12 +657,12 @@ function DocPage({ route, content: Content, mdxComponents: propComponents }) {
641
657
  /**
642
658
  * Renders an MDX page by consuming pre-loaded route data.
643
659
  *
644
- * - If the route belongs to a collection (`data.collection` is set), wraps
645
- * the content with `CurrentPostProvider` so that `usePost()` (called without
646
- * a slug) can read the current post's data from context.
660
+ * - If the route belongs to a collection, wraps the content with
661
+ * `CurrentPostProvider` so that `usePost()` (called without a slug) can read
662
+ * the current post's data from context.
647
663
  * - Otherwise, renders the standard `DocPage` layout.
648
664
  */
649
- function MdxPage({ MDXComponent, mdxComponents: propComponents, collectionPostComponent: CollectionPost }) {
665
+ function MdxPage({ MDXComponent, mdxComponents: propComponents, collectionPostComponent: CollectionPost, collection, route: routeProp }) {
650
666
  const data = require_router.useLoaderData();
651
667
  const mdxComponents = {
652
668
  ...useMdxComponents(),
@@ -654,30 +670,37 @@ function MdxPage({ MDXComponent, mdxComponents: propComponents, collectionPostCo
654
670
  };
655
671
  if (!MDXComponent) return null;
656
672
  const collectionData = data || {};
657
- if (!!collectionData?.collection && !!collectionData?.route) {
673
+ const isCollection = collection ? true : !!collectionData?.collection && !!collectionData?.route;
674
+ /**
675
+ * The loader's own copy of the route, falling back to the route table so the
676
+ * first client render has the same metadata the server used.
677
+ */
678
+ const postRoute = collectionData.route ?? routeProp;
679
+ const postHeadings = collectionData.headings ?? routeProp?.headings ?? [];
680
+ if (isCollection) {
658
681
  const postElement = CollectionPost ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CollectionPost, {
659
682
  MDXComponent,
660
683
  mdxComponents
661
684
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DocPage, {
662
685
  route: {
663
- path: collectionData.route?.path || "",
664
- filePath: collectionData.route?.filePath || "",
665
- title: collectionData.route?.title,
666
- description: collectionData.route?.description,
667
- headings: collectionData.headings || [],
668
- locale: collectionData.route?.locale,
669
- version: collectionData.route?.version,
670
- lastUpdated: collectionData.route?.lastUpdated,
671
- frontmatter: collectionData.route?.frontmatter
686
+ path: postRoute?.path || "",
687
+ filePath: postRoute?.filePath || "",
688
+ title: postRoute?.title,
689
+ description: postRoute?.description,
690
+ headings: postHeadings,
691
+ locale: postRoute?.locale,
692
+ version: postRoute?.version,
693
+ lastUpdated: postRoute?.lastUpdated,
694
+ frontmatter: postRoute?.frontmatter
672
695
  },
673
696
  content: MDXComponent,
674
697
  mdxComponents
675
698
  });
676
699
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CurrentPostProvider, {
677
700
  value: {
678
- route: collectionData.route,
679
- headings: collectionData.headings,
680
- collection: collectionData.collection
701
+ route: postRoute,
702
+ headings: postHeadings,
703
+ collection: collection ?? collectionData.collection
681
704
  },
682
705
  children: postElement
683
706
  });
@@ -927,7 +950,7 @@ function GithubStars({ repo, className }) {
927
950
  //#endregion
928
951
  //#region src/client/hooks/use-navbar.ts
929
952
  function useNavbar() {
930
- const config = require_link.useConfig();
953
+ const config = require_router.useConfig();
931
954
  const { theme, resolvedTheme } = require_image.useTheme();
932
955
  const location = require_router.useLocation();
933
956
  const { currentLocale } = require_search_dialog.useRoutes();
@@ -989,7 +1012,13 @@ function useNavbar() {
989
1012
  return {
990
1013
  links,
991
1014
  title,
992
- logo: !logo ? null : typeof logo === "string" ? logo : resolvedTheme === "dark" ? logo.dark : logo.light,
1015
+ logo: !logo ? null : typeof logo === "string" ? {
1016
+ light: logo,
1017
+ dark: null
1018
+ } : {
1019
+ light: logo.light,
1020
+ dark: logo.dark
1021
+ },
993
1022
  logoProps: {
994
1023
  alt: (logo && typeof logo === "object" ? logo.alt : void 0) || title,
995
1024
  width: logo && typeof logo === "object" ? logo.width : void 0,
@@ -1152,6 +1181,7 @@ function Tabs({ tabs, routes, allRoutes, className }) {
1152
1181
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1153
1182
  className: require_link.cn("mx-auto max-w-(--breakpoint-3xl) px-4 md:px-6 select-none", className),
1154
1183
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_docs_layout.Tabs.List, {
1184
+ role: "none",
1155
1185
  className: "border-none py-0 scrollbar-hide relative flex flex-row items-center overflow-x-auto",
1156
1186
  children: [tabs.map((tab, index) => {
1157
1187
  const isActive = index === activeIndex;
@@ -1195,7 +1225,7 @@ function getBaseFilePath(filePath, version, locale) {
1195
1225
  */
1196
1226
  function useVersion() {
1197
1227
  const navigate = require_router.useNavigate();
1198
- const config = require_link.useConfig();
1228
+ const config = require_router.useConfig();
1199
1229
  const { allRoutes, currentRoute, currentVersion, currentLocale } = require_search_dialog.useRoutes();
1200
1230
  const versions = config.versions;
1201
1231
  const { setVersion } = require_link.useBoltdocsContext();
@@ -1264,7 +1294,7 @@ function VersionSelector({ className }) {
1264
1294
  function useI18n() {
1265
1295
  const navigate = require_router.useNavigate();
1266
1296
  const location = require_router.useLocation();
1267
- const config = require_link.useConfig();
1297
+ const config = require_router.useConfig();
1268
1298
  const { allRoutes, currentRoute, currentLocale, isCollectionPage } = require_search_dialog.useRoutes();
1269
1299
  const i18n = config.i18n;
1270
1300
  const { setLocale } = require_link.useBoltdocsContext();
@@ -1627,7 +1657,7 @@ function useHeadings() {
1627
1657
  * Resets automatically when navigating to a new page.
1628
1658
  */
1629
1659
  function useFeedback(options = {}) {
1630
- const config = require_link.useConfig();
1660
+ const config = require_router.useConfig();
1631
1661
  const { currentRoute } = require_search_dialog.useRoutes();
1632
1662
  const [rating, setRating] = (0, react.useState)(null);
1633
1663
  const [comment, setComment] = (0, react.useState)("");
@@ -1719,7 +1749,7 @@ function I18nSelector({ className }) {
1719
1749
 
1720
1750
  //#endregion
1721
1751
  //#region src/client/components/ui-base/navbar.tsx
1722
- const SearchDialog$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("../search-dialog-DCtm2dyR.cjs")).then((m) => ({ default: m.SearchDialog })));
1752
+ const SearchDialog$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("../search-dialog-cHXR5zhL.cjs")).then((m) => ({ default: m.SearchDialog })));
1723
1753
  function Navbar({ className }) {
1724
1754
  const { links, title, logo, logoProps, github, social, config } = useNavbar();
1725
1755
  const { routes, allRoutes, currentRoute, isCollectionPage, currentVersion, currentLocale } = require_search_dialog.useRoutes();
@@ -1740,7 +1770,9 @@ function Navbar({ className }) {
1740
1770
  children: isSidebarOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_link.X, { className: "w-5 h-5 text-body" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_link.Menu, { className: "w-5 h-5 text-body" })
1741
1771
  }),
1742
1772
  logo && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog$1.Navbar.Logo, {
1743
- src: logo,
1773
+ src: logo.light,
1774
+ srcLight: logo.light,
1775
+ srcDark: logo.dark,
1744
1776
  alt: logoProps?.alt || title,
1745
1777
  width: logoProps?.width ?? 24,
1746
1778
  height: logoProps?.height ?? 24,
@@ -1991,8 +2023,30 @@ const mergeSlots = (defaults, overrides) => {
1991
2023
  function SidebarMain({ routes, config, className }) {
1992
2024
  const { logo, title, logoProps } = useNavbar();
1993
2025
  const { closeSidebar } = require_docs_layout.useUI();
1994
- const SidebarLogo = logo ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1995
- src: require_link.resolvePublicAssetUrl(logo, config.base),
2026
+ /**
2027
+ * Both logo variants are rendered and CSS selects the visible one.
2028
+ *
2029
+ * Resolving the source from the theme would make the server and the browser
2030
+ * emit different `src` values, which is a hydration mismatch. The `dark`
2031
+ * class on `<html>` is set before first paint, so there is no flash.
2032
+ */
2033
+ const SidebarLogo = logo ? logo.dark && logo.dark !== logo.light ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2034
+ src: require_link.resolvePublicAssetUrl(logo.light, config.base),
2035
+ alt: logoProps?.alt || title,
2036
+ width: 24,
2037
+ height: 24,
2038
+ "data-logo-theme": "light",
2039
+ className: "rounded-xl dark:hidden"
2040
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2041
+ src: require_link.resolvePublicAssetUrl(logo.dark, config.base),
2042
+ alt: logoProps?.alt || title,
2043
+ width: 24,
2044
+ height: 24,
2045
+ "data-logo-theme": "dark",
2046
+ "aria-hidden": "true",
2047
+ className: "hidden rounded-xl dark:block"
2048
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2049
+ src: require_link.resolvePublicAssetUrl(logo.light, config.base),
1996
2050
  alt: logoProps?.alt || title,
1997
2051
  width: 24,
1998
2052
  height: 24,
@@ -2099,7 +2153,7 @@ function Banner({ children, className = "", dismissible = false, id = "boltdocs-
2099
2153
  //#endregion
2100
2154
  //#region src/client/components/ui-base/feedback.tsx
2101
2155
  function Feedback({ className }) {
2102
- if (!(require_link.useConfig().integrations?.feedback?.custom)?.enabled) return null;
2156
+ if (!(require_router.useConfig().integrations?.feedback?.custom)?.enabled) return null;
2103
2157
  const { rating, setRating, comment, setComment, loading, submitted, error, submit } = useFeedback();
2104
2158
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2105
2159
  className: require_link.cn("w-full max-w-2xl mt-12 mb-6 p-6 rounded-2xl border border-subtle bg-surface/50 backdrop-blur-xs select-none", className),
@@ -2123,7 +2177,7 @@ function Feedback({ className }) {
2123
2177
  className: "flex flex-col gap-4",
2124
2178
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2125
2179
  className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",
2126
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
2180
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2127
2181
  className: "text-base font-semibold text-default",
2128
2182
  children: "Was this page helpful?"
2129
2183
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -2183,7 +2237,7 @@ function Feedback({ className }) {
2183
2237
  //#endregion
2184
2238
  //#region src/client/components/ui-base/giscus.tsx
2185
2239
  function Giscus({ className }) {
2186
- const config = require_link.useConfig();
2240
+ const config = require_router.useConfig();
2187
2241
  const { resolvedTheme } = require_image.useTheme();
2188
2242
  const ref = (0, react.useRef)(null);
2189
2243
  const initializedRef = (0, react.useRef)(false);
@@ -2309,7 +2363,9 @@ const EagerMdxElement = ({ moduleLoader, moduleKey, route, components, collectio
2309
2363
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MdxPage, {
2310
2364
  MDXComponent,
2311
2365
  mdxComponents: components ?? {},
2312
- collectionPostComponent
2366
+ collectionPostComponent,
2367
+ collection: route.collection,
2368
+ route
2313
2369
  });
2314
2370
  };
2315
2371
  const NotFoundWrapper = () => {
@@ -2356,7 +2412,7 @@ function DocsLayout({ collectionsData }) {
2356
2412
 
2357
2413
  //#endregion
2358
2414
  //#region src/client/ssg/create-routes.utils.ts
2359
- function withBase(path, config) {
2415
+ function withBase$1(path, config) {
2360
2416
  const base = config.base || "/";
2361
2417
  if (path.startsWith(base)) return path;
2362
2418
  return `${base === "/" ? "" : base.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}` || "/";
@@ -2452,7 +2508,7 @@ function buildDocRoutes(options) {
2452
2508
  const docRoutes = docMetadata.map((route) => {
2453
2509
  const moduleKey = resolveModuleKey(route.filePath, moduleMap);
2454
2510
  const moduleLoader = moduleKey ? mdxModules[moduleKey] : null;
2455
- const fullPath = withBase(route.path === "" ? "/" : route.path, config);
2511
+ const fullPath = withBase$1(route.path === "" ? "/" : route.path, config);
2456
2512
  const path = fullPath === baseDocsPath ? "." : fullPath.startsWith(baseDocsPath + "/") ? fullPath.slice(baseDocsPath.length + 1) : fullPath;
2457
2513
  const routeRecord = {
2458
2514
  path,
@@ -2579,7 +2635,7 @@ function buildDocRoutes(options) {
2579
2635
  fallback: true,
2580
2636
  seo: {
2581
2637
  ...matchedMetaObj.seo,
2582
- canonical: config.siteUrl ? `${config.siteUrl.replace(/\/$/, "")}${withBase(bPath, config)}` : withBase(bPath, config)
2638
+ canonical: config.siteUrl ? `${config.siteUrl.replace(/\/$/, "")}${withBase$1(bPath, config)}` : withBase$1(bPath, config)
2583
2639
  }
2584
2640
  } : {
2585
2641
  path: bPath,
@@ -2646,7 +2702,7 @@ function buildDocRoutes(options) {
2646
2702
  //#endregion
2647
2703
  //#region src/client/ssg/external-page-wrapper.tsx
2648
2704
  function ExternalPageWrapper({ children }) {
2649
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2705
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
2650
2706
  className: "boltdocs-external-content h-screen overflow-y-auto",
2651
2707
  children
2652
2708
  });
@@ -2654,16 +2710,33 @@ function ExternalPageWrapper({ children }) {
2654
2710
 
2655
2711
  //#endregion
2656
2712
  //#region src/client/ssg/create-routes.external.tsx
2657
- function getLocales(config) {
2713
+ function getLocales$1(config) {
2658
2714
  if (!config.i18n) return [];
2659
2715
  return Array.isArray(config.i18n.locales) ? config.i18n.locales : Object.keys(config.i18n.locales);
2660
2716
  }
2717
+ /**
2718
+ * Lists the locale-prefixed variants of a path.
2719
+ *
2720
+ * The default locale is skipped on purpose. It is already the unprefixed path,
2721
+ * so prefixing it would mint a second URL for the same page: a site with
2722
+ * `defaultLocale: 'en'` would serve both `/about` and `/en/about`. That is not
2723
+ * a harmless duplicate. The docs site is served under a base, and the SSG path
2724
+ * collector prepends the base to the prefixed variant, so it emitted
2725
+ * `/docs/en/about` — a URL the client router never learns about, because the
2726
+ * base is not part of the route. Visitors landing there got a 404 on a page
2727
+ * the build had itself written.
2728
+ *
2729
+ * A developer configuring a second locale should not have to know this, so the
2730
+ * redundant variant is never generated in the first place.
2731
+ */
2661
2732
  function getLocalizedPaths(pathname, config) {
2662
2733
  const paths = [{
2663
2734
  path: pathname,
2664
2735
  locale: config.i18n?.defaultLocale
2665
2736
  }];
2666
- for (const locale of getLocales(config)) {
2737
+ const defaultLocale = config.i18n?.defaultLocale;
2738
+ for (const locale of getLocales$1(config)) {
2739
+ if (locale === defaultLocale) continue;
2667
2740
  const localizedPath = pathname === "/" ? `/${locale}` : `/${locale}${pathname}`;
2668
2741
  if (!paths.some((entry) => entry.path === localizedPath)) paths.push({
2669
2742
  path: localizedPath,
@@ -2787,7 +2860,7 @@ function buildExternalFileRoutes(options) {
2787
2860
  metadata
2788
2861
  };
2789
2862
  const EffectiveExternalLayout = externalLayout || (({ children }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children }));
2790
- const locales = getLocales(config);
2863
+ const locales = getLocales$1(config);
2791
2864
  const isLocalizedPath = (pathname) => locales.some((locale) => pathname === `/${locale}` || pathname.startsWith(`/${locale}/`));
2792
2865
  const localeOfPath = (pathname) => {
2793
2866
  const first = pathname.split("/").filter(Boolean)[0];
@@ -2842,7 +2915,7 @@ function getPostTimestamp(date) {
2842
2915
  function usePosts(collection = DEFAULT_COLLECTION, options) {
2843
2916
  const data = useCollectionsData();
2844
2917
  const { currentLocale, currentVersion } = require_search_dialog.useRoutes();
2845
- const config = require_link.useConfig();
2918
+ const config = require_router.useConfig();
2846
2919
  const posts = data[collection] || [];
2847
2920
  const defaultLocale = config.i18n?.defaultLocale;
2848
2921
  const defaultVersion = config.versions?.defaultVersion;
@@ -2945,7 +3018,7 @@ function getCollectionModule(route, moduleMap, mdxModules) {
2945
3018
  }
2946
3019
  function DefaultCollectionList() {
2947
3020
  const location = require_router.useLocation();
2948
- const config = require_link.useConfig();
3021
+ const config = require_router.useConfig();
2949
3022
  const loaderData = require_router.useLoaderData();
2950
3023
  const postsPerPage = config.collections?.postsPerPage ?? 10;
2951
3024
  const basePath = location.pathname.replace(/\/page\/\d+\/?$/, "").replace(/\/$/, "");
@@ -2982,7 +3055,7 @@ function DefaultCollectionList() {
2982
3055
  }),
2983
3056
  post.date && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
2984
3057
  className: "text-xs text-muted block mb-2",
2985
- children: new Date(post.date).toLocaleDateString()
3058
+ children: require_mdx.formatDeterministicDate(post.date, { month: "short" })
2986
3059
  }),
2987
3060
  post.excerpt && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2988
3061
  className: "text-sm text-body",
@@ -3224,6 +3297,106 @@ function buildCollectionRoutes(options) {
3224
3297
  };
3225
3298
  }
3226
3299
 
3300
+ //#endregion
3301
+ //#region src/client/ssg/create-routes.redirect.tsx
3302
+ function normalize(value) {
3303
+ const [withoutHash] = value.split("#");
3304
+ const queryIndex = withoutHash.indexOf("?");
3305
+ const rawPath = queryIndex === -1 ? withoutHash : withoutHash.slice(0, queryIndex);
3306
+ const query = queryIndex === -1 ? "" : withoutHash.slice(queryIndex);
3307
+ const collapsed = `/${rawPath}`.replace(/\/{2,}/g, "/");
3308
+ return `${collapsed === "/" ? "/" : collapsed.replace(/\/+$/, "")}${query}`;
3309
+ }
3310
+ function isExternalTarget(to) {
3311
+ return /^[a-z][a-z0-9+.-]*:/i.test(to) || to.startsWith("//");
3312
+ }
3313
+ function getLocales(config) {
3314
+ const locales = config.i18n?.locales;
3315
+ if (!locales) return [];
3316
+ return Array.isArray(locales) ? locales : Object.keys(locales);
3317
+ }
3318
+ function withBase(pathname, base) {
3319
+ if (base === "/" || !base) return pathname;
3320
+ const normalizedBase = `/${base.replace(/^\/+|\/+$/g, "")}`;
3321
+ if (pathname === "/") return normalizedBase;
3322
+ return `${normalizedBase}${pathname}`;
3323
+ }
3324
+ /**
3325
+ * Collapses redirect chains and rejects cycles in the browser as well, so a
3326
+ * misconfigured site fails visibly instead of trapping the visitor.
3327
+ */
3328
+ function buildRedirectMap(config) {
3329
+ const map = /* @__PURE__ */ new Map();
3330
+ const entries = config.redirects ?? [];
3331
+ for (const entry of entries) {
3332
+ const from = normalize(entry.from);
3333
+ const sources = entry.locale ? getLocales(config).map((locale) => from === `/${locale}` || from.startsWith(`/${locale}/`) ? from : from === "/" ? `/${locale}` : `/${locale}${from}`) : [from];
3334
+ for (const source of sources) {
3335
+ const to = isExternalTarget(entry.to) ? entry.to : withBase(normalize(entry.to), config.base ?? "/");
3336
+ map.set(source, to);
3337
+ }
3338
+ }
3339
+ for (const [source, direct] of map) {
3340
+ let current = direct;
3341
+ const seen = new Set([source]);
3342
+ for (let depth = 0; depth < 10; depth++) {
3343
+ const nextPath = current.split("?")[0];
3344
+ const next = map.get(nextPath);
3345
+ if (!next || seen.has(nextPath)) break;
3346
+ seen.add(nextPath);
3347
+ current = next;
3348
+ }
3349
+ map.set(source, current);
3350
+ }
3351
+ return map;
3352
+ }
3353
+ /**
3354
+ * Performs the redirect during render effects. A short delay lets the static
3355
+ * host serve the prerendered redirect document first on a cold load, while a
3356
+ * client-side navigation never flashes the destination page.
3357
+ */
3358
+ function RedirectBoundary({ to }) {
3359
+ const navigate = require_router.useNavigate();
3360
+ (0, react.useEffect)(() => {
3361
+ if (isExternalTarget(to)) {
3362
+ window.location.replace(to);
3363
+ return;
3364
+ }
3365
+ navigate(to, { replace: true });
3366
+ }, [navigate, to]);
3367
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("main", {
3368
+ className: "boltdocs-page w-full pt-4 pb-20 px-4 sm:px-8",
3369
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3370
+ className: "mx-auto w-full max-w-3xl sm:max-w-4xl",
3371
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
3372
+ className: "text-paragraph",
3373
+ children: [
3374
+ "Redirecting to ",
3375
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
3376
+ href: to,
3377
+ children: to
3378
+ }),
3379
+ "…"
3380
+ ]
3381
+ })
3382
+ })
3383
+ });
3384
+ }
3385
+ /**
3386
+ * Builds client-side redirect routes from `config.redirects`.
3387
+ *
3388
+ * Redirect sources are appended after the real routes so an existing page always
3389
+ * wins, and before the catch-all so a redirect is never shadowed by the 404.
3390
+ */
3391
+ function buildRedirectRoutes({ config }) {
3392
+ const map = buildRedirectMap(config);
3393
+ if (map.size === 0) return [];
3394
+ return [...map.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([from, to]) => ({
3395
+ path: from,
3396
+ element: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RedirectBoundary, { to })
3397
+ }));
3398
+ }
3399
+
3227
3400
  //#endregion
3228
3401
  //#region src/client/ssg/create-routes.tsx
3229
3402
  function createRoutes(options) {
@@ -3249,6 +3422,7 @@ function createRoutes(options) {
3249
3422
  };
3250
3423
  filteredExternalFileRoutes.children = externalFileRoutes.children.filter((route) => !route.path || acceptedExternalFilePaths.has(route.path));
3251
3424
  const collectionRoutes = buildCollectionRoutes(options);
3425
+ const redirectRoutes = buildRedirectRoutes({ config });
3252
3426
  const children = [
3253
3427
  {
3254
3428
  path: baseDocsPath,
@@ -3258,6 +3432,7 @@ function createRoutes(options) {
3258
3432
  ...externalRoutes.children,
3259
3433
  ...filteredExternalFileRoutes.children,
3260
3434
  ...collectionRoutes.children,
3435
+ ...redirectRoutes,
3261
3436
  {
3262
3437
  path: "*",
3263
3438
  element: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExternalPageWrapper, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EffectiveExternalLayout, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NotFoundWrapper, {}) }) })
@@ -3292,6 +3467,18 @@ function createRoutes(options) {
3292
3467
  };
3293
3468
  }
3294
3469
 
3470
+ //#endregion
3471
+ //#region src/client/collections/utils.ts
3472
+ /**
3473
+ * Formats a date to a human-readable string.
3474
+ *
3475
+ * Locale and time zone are pinned so the server and the browser produce
3476
+ * identical text during hydration. See `formatDeterministicDate`.
3477
+ */
3478
+ function formatDate(date, options = {}) {
3479
+ return require_mdx.formatDeterministicDate(date, options);
3480
+ }
3481
+
3295
3482
  //#endregion
3296
3483
  //#region src/client/components/docs-layout-default.tsx
3297
3484
  /**
@@ -3304,7 +3491,7 @@ function createRoutes(options) {
3304
3491
  */
3305
3492
  function DocsLayoutComponent({ children }) {
3306
3493
  const { routes: filteredRoutes, currentRoute, isCollectionPage } = require_search_dialog.useRoutes();
3307
- const config = require_link.useConfig();
3494
+ const config = require_router.useConfig();
3308
3495
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_docs_layout.DocsLayout, {
3309
3496
  className: "selection:bg-primary-500/10 selection:text-primary-500",
3310
3497
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Navbar, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_docs_layout.DocsLayout.Body, {
@@ -3462,6 +3649,8 @@ exports.createStructuredData = createStructuredData;
3462
3649
  exports.createWebSiteStructuredData = createWebSiteStructuredData;
3463
3650
  exports.defaultNavigate = require_router.defaultNavigate;
3464
3651
  exports.defineStructuredData = defineStructuredData;
3652
+ exports.formatDate = formatDate;
3653
+ exports.formatDeterministicDate = require_mdx.formatDeterministicDate;
3465
3654
  exports.getConfiguredLocales = require_router.getConfiguredLocales;
3466
3655
  exports.getConfiguredVersions = require_router.getConfiguredVersions;
3467
3656
  exports.getStarsRepo = getStarsRepo;
@@ -3484,7 +3673,7 @@ exports.resolvePublicAssetUrl = require_link.resolvePublicAssetUrl;
3484
3673
  exports.resolveRouteBranch = require_router.resolveRouteBranch;
3485
3674
  exports.resolveUrlReference = require_router.resolveUrlReference;
3486
3675
  exports.splitUrlReference = require_router.splitUrlReference;
3487
- exports.startViewTransition = require_link.startViewTransition;
3676
+ exports.startViewTransition = require_router.startViewTransition;
3488
3677
  exports.stripBasename = require_router.stripBasename;
3489
3678
  exports.stripSiteProtocol = require_router.stripSiteProtocol;
3490
3679
  exports.stripUrlBase = require_router.stripUrlBase;
@@ -3492,7 +3681,7 @@ exports.useAnalytics = useAnalytics;
3492
3681
  exports.useBreadcrumbs = useBreadcrumbs;
3493
3682
  exports.useCodeBlock = useCodeBlock;
3494
3683
  exports.useCodeBlockFeedback = require_mdx.useCodeBlockFeedback;
3495
- exports.useConfig = require_link.useConfig;
3684
+ exports.useConfig = require_router.useConfig;
3496
3685
  exports.useCopyButton = require_mdx.useCopyButton;
3497
3686
  exports.useExpandable = require_mdx.useExpandable;
3498
3687
  exports.useFeedback = useFeedback;
@@ -3514,7 +3703,7 @@ exports.useRecentPosts = useRecentPosts;
3514
3703
  exports.useRouteData = require_router.useRouteData;
3515
3704
  exports.useRoutes = require_search_dialog.useRoutes;
3516
3705
  exports.useSearch = require_search_dialog.useSearch;
3517
- exports.useSearchHighlight = require_docs_layout.useSearchHighlight;
3706
+ exports.useSearchHighlight = require_search_dialog$1.useSearchHighlight;
3518
3707
  exports.useSidebar = require_docs_layout.useSidebar;
3519
3708
  exports.useTabs = useTabs;
3520
3709
  exports.useTheme = require_image.useTheme;
@@ -3522,4 +3711,4 @@ exports.useTrackEvent = useTrackEvent;
3522
3711
  exports.useTrackPageView = useTrackPageView;
3523
3712
  exports.useUI = require_docs_layout.useUI;
3524
3713
  exports.useVersion = useVersion;
3525
- exports.useViewTransition = require_link.useViewTransition;
3714
+ exports.useViewTransition = require_router.useViewTransition;