boltdocs 3.3.6 → 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.
- package/dist/{adapters-BKzKe2mO.mjs → adapters-BXiBWAKs.mjs} +1 -1
- package/dist/{adapters-DwDTQoCG.cjs → adapters-Czl3WtQt.cjs} +1 -1
- package/dist/{build-CxT38vPv.cjs → build-CNkXRdk8.cjs} +1 -1
- package/dist/{build-BJnL-FHG.mjs → build-CqUBsXVC.mjs} +1 -1
- package/dist/client/index.cjs +223 -51
- package/dist/client/index.d.cts +3 -3
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.js +226 -56
- package/dist/client/mdx.cjs +1 -1
- package/dist/client/mdx.js +1 -1
- package/dist/client/primitives.cjs +5 -5
- package/dist/client/primitives.d.cts +53 -34
- package/dist/client/primitives.d.ts +62 -43
- package/dist/client/primitives.js +4 -4
- package/dist/client/router.cjs +1 -1
- package/dist/client/router.d.cts +1 -1
- package/dist/client/router.d.ts +1 -1
- package/dist/client/router.js +1 -1
- package/dist/client/theme/reset.css +41 -0
- package/dist/{config-BJp3lGzE.cjs → config-B3SEoVjG.cjs} +2 -2
- package/dist/{config-BC_qhXws.cjs → config-Bfakeadu.cjs} +1 -1
- package/dist/{config-B3_iVsbi.mjs → config-CTcfF-0c.mjs} +2 -2
- package/dist/dev-D1DmOSjn.mjs +6 -0
- package/dist/dev-DH6cSge8.cjs +6 -0
- package/dist/{docs-layout-D3Fmb0Wd.js → docs-layout-CmntYM6p.js} +33 -33
- package/dist/{docs-layout-SgphExoE.cjs → docs-layout-DIgxJ5c7.cjs} +9 -9
- package/dist/{doctor-BqxOFRt3.cjs → doctor-BLxm2alc.cjs} +1 -1
- package/dist/{doctor-TS3JGNEU.cjs → doctor-Dd-JMTRo.cjs} +1 -1
- package/dist/{doctor-Cv5lXnay.mjs → doctor-DogHujrP.mjs} +1 -1
- package/dist/{image-Bkx85rsq.cjs → image-Bke2ojW1.cjs} +3 -3
- package/dist/{image-BAiDReNd.js → image-CaY2w0ua.js} +2 -1
- package/dist/index--xbYbT8N.d.ts +343 -0
- package/dist/{index-B1Mx0dHl.d.ts → index-B_o5y34l.d.cts} +89 -10
- package/dist/{index-DLaHgD-i.d.cts → index-Bx0CUd7Q.d.ts} +89 -10
- package/dist/index-RK7W_Fxy.d.cts +343 -0
- package/dist/{link-q1qHNGK_.js → link-CSe_oD8Y.js} +86 -113
- package/dist/{link-hLWOsx0x.cjs → link-Xb69Oy2F.cjs} +87 -143
- package/dist/{mdx-Qi0DmaY8.cjs → mdx-BCOrMd-P.cjs} +68 -16
- package/dist/{mdx-CJGWzBGy.js → mdx-BijiEbkp.js} +62 -15
- package/dist/{native-nLA4Jr0T.cjs → native-BbtRkce5.cjs} +1 -1
- package/dist/node/cli-entry.cjs +1 -1
- package/dist/node/cli-entry.mjs +1 -1
- package/dist/node/highlight.d.cts +2 -2
- package/dist/node/highlight.d.mts +2 -2
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +18 -39
- package/dist/node/index.d.mts +19 -40
- package/dist/node/index.mjs +1 -1
- package/dist/node/mdx/shiki-adapter.d.cts +1 -1
- package/dist/node/mdx/shiki-adapter.d.mts +1 -1
- package/dist/node-BgiLCa0I.cjs +39 -0
- package/dist/node-Da3tYBHo.mjs +39 -0
- package/dist/{package-Bah2tHjK.cjs → package-D1gVs5gQ.cjs} +1 -1
- package/dist/{package-D6bf68FR.mjs → package-YgQJn3Yh.mjs} +1 -1
- package/dist/pages-external-B_r6gvqP.cjs +6 -0
- package/dist/pages-external-jmK7AHaO.mjs +6 -0
- package/dist/{parser-CD8Oo8qh.mjs → parser-CvNZc5s3.mjs} +1 -1
- package/dist/{parser-vPaKvzLp.cjs → parser-DJLWTiO-.cjs} +1 -1
- package/dist/plugin-DW9K2fW5.mjs +69 -0
- package/dist/plugin-NwGKyTJX.cjs +69 -0
- package/dist/{plugin-context-b5qVVQSU.mjs → plugin-context-COh-cbsW.mjs} +1 -1
- package/dist/{plugin-context-BZs5lvDu.cjs → plugin-context-FIHaWn6r.cjs} +1 -1
- package/dist/{plugin-lifecycle-s89gzTlh.cjs → plugin-lifecycle-D9fTRaWY.cjs} +1 -1
- package/dist/{registry-B8pt41zj.d.cts → registry-BFmzj1yg.d.mts} +1 -1
- package/dist/{registry-BrrH2X9c.d.mts → registry-BoswPzYV.d.cts} +1 -1
- package/dist/{resolve-C5rT6B21.mjs → resolve-5puUe7eS.mjs} +1 -1
- package/dist/{resolve-BelytNYR.cjs → resolve-CF4ZLfqx.cjs} +1 -1
- package/dist/route-paths-B6ocUfNY.cjs +6 -0
- package/dist/route-paths-DyDji4bX.mjs +6 -0
- package/dist/{router-CZBxMRAH.js → router-B5e8k4qK.js} +175 -10
- package/dist/{router-C3kygdRK.cjs → router-DKC0Lu0n.cjs} +204 -9
- package/dist/{routes-Dq_2EUIB.cjs → routes-D55M8UrH.cjs} +1 -1
- package/dist/{routes-CzhKOw67.cjs → routes-DdE6Lfcl.cjs} +1 -1
- package/dist/{routes-Dw6g0bfF.mjs → routes-_I_8PQYF.mjs} +1 -1
- package/dist/{search-dialog-CguKVtUu.cjs → search-dialog-BOQRHKTb.cjs} +53 -20
- package/dist/{search-dialog-mYnqU4v7.js → search-dialog-BXil4_7P.js} +57 -24
- package/dist/{search-dialog-BYZS9aeO.cjs → search-dialog-CwlBd-Mu.cjs} +5 -5
- package/dist/{search-dialog-DQwod5Xc.js → search-dialog-D3Obh3eA.js} +1 -1
- package/dist/{search-dialog-DzObE-Ar.js → search-dialog-DeplpVEB.js} +3 -3
- package/dist/{search-dialog-QgKRRbsI.cjs → search-dialog-cHXR5zhL.cjs} +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/ssg-static-options-Br1_u9qp.mjs +6 -0
- package/dist/ssg-static-options-CVvGKM8i.cjs +6 -0
- package/dist/types-58Ac3UGI.d.cts +114 -0
- package/dist/types-BwnGf-1E.d.mts +114 -0
- package/dist/{virtual-modules-C3S3Nz8r.cjs → virtual-modules-C4-qxFlL.cjs} +1 -1
- package/dist/{virtual-modules-CaxqrFd6.mjs → virtual-modules-DiWUKJGP.mjs} +1 -1
- package/package.json +5 -3
- package/src/shared/types.ts +133 -987
- package/dist/dev-46NiL0MC.cjs +0 -6
- package/dist/dev-C4kjO5xs.mjs +0 -6
- package/dist/index-CgWkOCCn.d.cts +0 -1193
- package/dist/index-CuNSD3E2.d.ts +0 -1193
- package/dist/node-7Cfw6nMr.cjs +0 -23
- package/dist/node-CT2E84nY.mjs +0 -23
- package/dist/pages-external-BBw8ObVK.mjs +0 -6
- package/dist/pages-external-DPiPFxxP.cjs +0 -6
- package/dist/plugin-AgNI3ktz.cjs +0 -69
- package/dist/plugin-BAv_pYLt.mjs +0 -69
- package/dist/types-74i_xUe2.d.mts +0 -975
- package/dist/types-X_Pwk8Cg.d.cts +0 -975
- /package/dist/{audit-CMc_ydRr.mjs → audit-CYAkXXvP.mjs} +0 -0
- /package/dist/{audit-CHkGiV3c.cjs → audit-DxCZZTuX.cjs} +0 -0
- /package/dist/{csp-BiGAG8aF.cjs → csp-B-gc2Iha.cjs} +0 -0
- /package/dist/{csp-D0BOH8ae.mjs → csp-f8DOcI_7.mjs} +0 -0
- /package/dist/{generator-BCrZL53x.cjs → generator-CBAPKY6r.cjs} +0 -0
- /package/dist/{generator-CFukoGa0.mjs → generator-MRpn-yp6.mjs} +0 -0
- /package/dist/{handler-Lex5DbvG.mjs → handler-DBZqoWt2.mjs} +0 -0
- /package/dist/{handler-Ch-Q9NAB.cjs → handler-ryZR9Q41.cjs} +0 -0
- /package/dist/{index-HAwIo4nZ.d.mts → index-CPr34I2C.d.mts} +0 -0
- /package/dist/{native-BYKMke79.mjs → native-DZ6WMwjG.mjs} +0 -0
- /package/dist/{native-BOet8hpE.cjs → native-DeKxny_T.cjs} +0 -0
- /package/dist/{update-check-BXD1atVv.mjs → update-check-BXx8te9F.mjs} +0 -0
- /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"./chunk-BFSpntXv.mjs";import{a as t,d as n,g as r,u as i}from"./utils-8lzafE49.mjs";import{n as a}from"./pages-external-BBw8ObVK.mjs";import{n as o}from"./config-B3_iVsbi.mjs";import{i as s,n as c,r as l,s as u,t as d}from"./update-check-BXD1atVv.mjs";import f from"node:path";import p from"node:fs";import{badge as m,colorize as h,colors as g,confirm as _,error as v,info as y,section as b,success as x,tasks as ee,warn as S}from"@bdocs/dui";import{fdir as C}from"fdir";import te from"picomatch";import{distance as w}from"fastest-levenshtein";const T={$schema:`https://boltdocs.vercel.app/schemas/doctor-config.schema.json`,checks:{metadata:{enabled:!0,titleMin:10,titleMax:60,descriptionMin:50,required:[`title`,`description`],optional:[],validateDates:!1},links:{internal:!0,external:!1,timeout:1e4,concurrency:10,ignore:[]},i18n:{enabled:!0},performance:{enabled:!0,budgets:{maxJSBundleSize:`200kb`,maxCSSBundleSize:`30kb`,maxPageHTMLSize:`80kb`,maxImagesKB:500,maxBuildTime:3e4,maxFontCount:3}}},fix:{confirmChanges:!1,backupFiles:!1,backupPath:`.boltdocs/backups`},reporting:{format:`pretty`,outputFile:`.boltdocs/reports/doctor.json`,failOnError:!1,maxWarnings:-1},severity:{missingTranslation:`warning`,brokenLink:`high`,brokenAnchor:`warning`,largeFile:`warning`,orphanedPage:`low`,duplicateTitle:`low`,shortMetadata:`low`,missingMetadata:`warning`,malformedFrontmatter:`high`,invalidFrontmatter:`high`,budgetExceeded:`warning`},exclude:[]};function E(e,t){if(e==null)return t;if(typeof e==`number`)return e;let n=e.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);if(!n)return t;let r=Number.parseFloat(n[1]),i=n[2]||`b`;return Math.round(r*({b:1,kb:1024,mb:1024*1024,gb:1024*1024*1024}[i]||1))}function D(e,t,n){return e.doctorConfig.severity[t]||n}async function ne(e,t){p.existsSync(t)||p.mkdirSync(t,{recursive:!0});let n=f.basename(e),r=new Date().toISOString().replace(/[:.]/g,`-`),i=f.join(t,`${n}.${r}.bak`);p.copyFileSync(e,i)}const O=new Map;function k(e){let t=O.get(e);if(t)return t;let r=(async()=>{let t=await n(e,!1);return{raw:t.raw,data:t.data,content:t.content}})();return O.set(e,r),r}const A=new Map;function j(e){if(A.has(e))return A.get(e);let t=!1;try{t=p.existsSync(e)&&p.statSync(e).isFile()}catch{t=!1}return A.set(e,t),t}async function M(e){let t=f.resolve(e,`doctor.json`);if(p.existsSync(t))try{let e=JSON.parse(p.readFileSync(t,`utf-8`));return{...T,...e,checks:{...T.checks,...e.checks,metadata:{...T.checks.metadata,...e.checks?.metadata},links:{...T.checks.links,...e.checks?.links},i18n:{...T.checks.i18n,...e.checks?.i18n},performance:{...T.checks.performance,...e.checks?.performance,budgets:{...T.checks.performance?.budgets,...e.checks?.performance?.budgets}}},fix:{...T.fix,...e.fix},reporting:{...T.reporting,...e.reporting},severity:{...T.severity,...e.severity},exclude:[...T.exclude,...e.exclude||[]]}}catch(e){S(`Failed to parse doctor.json: ${e}`)}return T}async function N(e,n=process.cwd(),r,i){let o=f.resolve(n,`.boltdocs`,`generated`);p.existsSync(o)||p.mkdirSync(o,{recursive:!0});let s=i;s||=await new C().withFullPaths().filter(e=>e.endsWith(`.md`)||e.endsWith(`.mdx`)).crawl(e).withPromise();let c=r?.base||`/`,l=[];for(let n=0;n<s.length;n+=100){let r=s.slice(n,n+100),i=await Promise.all(r.map(async n=>{let r=f.isAbsolute(n)?n:f.resolve(e,n),i=f.relative(e,r),{data:a}=await k(r),o;return o=a.permalink?String(a.permalink).startsWith(`/`)?String(a.permalink):`/${a.permalink}`:t(i),c===`/`?o:(c.endsWith(`/`)?c:c+`/`)+(o.startsWith(`/`)?o.substring(1):o)}));l.push(...i)}l.includes(c)||l.push(c);let u=a(e,r);for(let e of u)l.includes(e)||l.push(e);let d={routes:Array.from(new Set(l)).sort(),timestamp:Date.now()};return p.writeFileSync(f.resolve(o,`link-tree.json`),JSON.stringify(d,null,2)),d}function P(e,t){if(e===t)return 1;if(!e||!t)return 0;let n=e.split(`/`).filter(Boolean),r=t.split(`/`).filter(Boolean),i=n[n.length-1]||``,a=r[r.length-1]||``;if(i===a){let e=0;for(let t of n)r.includes(t)&&e++;return e>=2?.99:.9}if(i.length>3&&a.length>3&&(a.startsWith(i)||i.startsWith(a))&&Math.min(i.length,a.length)/Math.max(i.length,a.length)>.5)return .88;let o=1-w(i,a)/Math.max(i.length,a.length);return o>.8?o*.95:1-w(e,t)/Math.max(e.length,t.length)}const F=new Map;function I(e,t){if(F.has(e))return F.get(e);let n=e.length,r=``,i=0;for(let a of t){if(a===e)continue;let t=a.length,o=Math.max(n,t);if(o===0)continue;let s=1-Math.abs(n-t)/o;if(s<=.8&&s<=i)continue;let c=P(e,a);c>i&&(i=c,r=a)}let a={bestMatch:r,similarity:i};return F.set(e,a),a}function L(e,t,n){let r=/```[\s\S]*?```/g,i=/`[^`\n]*`/g,a=0,o=[],s=t=>{e=e.replace(t,e=>(o.push(e),`__BD_CODE_MASK_${a++}__`))};return s(r),s(i),e.split(t).join(n).replace(/__BD_CODE_MASK_(\d+)__/g,(e,t)=>o[Number(t)]??``)}async function R(e){let t=[];if(!e.doctorConfig.checks.metadata.enabled)return t;let{titleMin:n,titleMax:a,descriptionMin:o}=e.doctorConfig.checks.metadata,s=new Map;for(let c of e.files){let l=i(f.relative(e.docsDir,c));try{let{raw:i,data:u}=await k(c);if(i.trim().startsWith(`---`)&&i.split(`---`).length>=3&&Object.keys(u).length===0){let n=D(e,`malformedFrontmatter`,`high`);n!==`off`&&t.push({file:l,level:n,message:`Malformed frontmatter (YAML parsing failed).`,suggestion:`Check your YAML syntax for indentation or unquoted special characters.`})}let d=r.safeParse(u);if(!d.success){let n=D(e,`invalidFrontmatter`,`high`);if(n!==`off`)for(let e of d.error.issues)t.push({file:l,level:n,message:`Invalid frontmatter field "${e.path.join(`.`)}": ${e.message}`,suggestion:`Ensure the field follows the correct type.`})}let f=Array.from(new Set([`title`,...e.doctorConfig.checks.metadata.required]));for(let n of f)if(u[n]===void 0){let r=D(e,`missingMetadata`,`warning`);r!==`off`&&t.push({file:l,level:r,message:`Missing required frontmatter field: "${n}".`,suggestion:`Add the "${n}" field to your frontmatter.`})}if(e.doctorConfig.checks.metadata.validateDates){let n=[`date`,`lastUpdated`,...e.doctorConfig.checks.metadata.optional.filter(e=>e.toLowerCase().includes(`date`))];for(let r of n)if(u[r]&&Number.isNaN(Date.parse(String(u[r])))){let n=D(e,`invalidFrontmatter`,`high`);n!==`off`&&t.push({file:l,level:n,message:`Invalid date format in field "${r}": "${u[r]}".`,suggestion:`Use a valid ISO date format (e.g., YYYY-MM-DD).`})}}if(u.title){let r=String(u.title);if(r.length<n){let i=D(e,`shortMetadata`,`low`);i!==`off`&&t.push({file:l,level:i,message:`Title is too short (${r.length} chars).`,suggestion:`Titles should be at least ${n} characters for better SEO.`})}else if(r.length>a){let n=D(e,`shortMetadata`,`low`);n!==`off`&&t.push({file:l,level:n,message:`Title is too long (${r.length} chars).`,suggestion:`Titles should be under ${a} characters.`})}let i=s.get(r)||[];i.push(l),s.set(r,i)}if(u.description&&String(u.description).length<o){let n=D(e,`shortMetadata`,`low`);n!==`off`&&t.push({file:l,level:n,message:`Description is very short.`,suggestion:`Descriptions should ideally be at least ${o} characters.`})}}catch(n){if(n instanceof Error){let r=D(e,`malformedFrontmatter`,`high`);r!==`off`&&t.push({file:l,level:r,message:`Malformed frontmatter (YAML error): ${n.message}`,suggestion:`Check your YAML syntax for indentation or unquoted special characters.`})}}}for(let[n,r]of s.entries())if(r.length>1){let i=D(e,`duplicateTitle`,`low`);if(i!==`off`)for(let e of r)t.push({file:e,level:i,message:`Duplicate title found: "${n}"`,suggestion:`Ensure each page has a unique title. Also used in: ${r.filter(t=>t!==e).join(`, `)}`})}return t}const z=/(?:\[([^\]]*)\]\(([^)\s]+)(?:\s+["'][^"']*["'])?\))|(?:href=["']([^"']+)["'])|(?:<Link\s+[^>]*?to=["'](\/[^"']+)["'])/g,B=[``,`.md`,`.mdx`,`/index.md`,`/index.mdx`];function V(e){let t=[],n=e=>{t.includes(e)||t.push(e)};n(e),e.endsWith(`/`)?n(e.slice(0,-1)):n(e+`/`);let r=e.replace(/\.(md|mdx)$/i,``);r!==e&&(n(r),n(r+`/`));let i=e.replace(/\/index\.(md|mdx)$/i,``);return i!==e&&(n(i),n(i+`/`)),n(e.endsWith(`/`)?e+`index`:e+`/index`),e.endsWith(`/index`)&&n(e.replace(/\/index$/,``)),t}async function H(e){let t=[],{internal:n,external:r,ignore:a,timeout:o,concurrency:s}=e.doctorConfig.checks.links;if(!n&&!r&&!e.options.checkExternal)return t;let c=new Set,l=5e5;for(let o of e.files){let s=i(f.relative(e.docsDir,o)),{content:u}=await k(o),d=[...(u.length>l?u.slice(0,l):u).replace(/<!--[\s\S]*?-->/g,``).replace(/```[\s\S]*?```/g,``).replace(/`[^`\n]*`/g,``).matchAll(z)];for(let i of d){let l=i[2]||i[3]||i[4],u=!!i[2],d=!!i[4];if(!l||a.some(e=>l.includes(e)))continue;if(/^(https?:|mailto:|tel:|data:|javascript:|blob:|ftp:)/i.test(l)){(r||e.options.checkExternal)&&c.add({url:l,file:o});continue}if(l.startsWith(`//`)){(r||e.options.checkExternal)&&c.add({url:l,file:o});continue}if(!n||l.startsWith(`#`))continue;let m;try{m=decodeURIComponent(l.split(`#`)[0].split(`?`)[0])}catch{m=l.split(`#`)[0].split(`?`)[0]}if(!m)continue;let h=!1,g=!1,_=``;if(m.startsWith(`/`)){let t=V(m);for(let n of t)if(e.routeIndex.has(n)||e.routeIndexWithSlash.has(n)||e.routeIndexWithoutSlash.has(n)){h=!0;break}if(!h&&e.basePrefix)for(let n of t){let t=e.basePrefix+(n.startsWith(`/`)?n:`/`+n);if(t!==n&&(e.routeIndex.has(t)||e.routeIndexWithSlash.has(t))){g=!0,_=t;break}}if(!h&&!g){let t=m.replace(/^\/+/,``),n=f.join(e.docsDir,t);h=B.some(e=>j(n+e))}}else{let e=f.resolve(f.dirname(o),m);h=B.some(t=>j(e+t))}if(!h){let{bestMatch:n,similarity:r}=I(m,e.linkTree.routes);g&&(n=_,r=1);let i=r>.6||g,a=r>.75&&n!==m||g,c=D(e,`brokenLink`,`high`);c!==`off`&&t.push({file:s,level:c,message:`Broken internal link: "${l}"`,suggestion:i?`Did you mean "${n}"?`:`Ensure the target exists or check for typos.`,fix:a?async()=>{let e=l.includes(`#`)?`#`+l.split(`#`)[1]:``,t=u?`(${l})`:d?`to="${l}"`:`href="${l}"`,r=u?`(${n}${e})`:d?`to="${n}${e}"`:`href="${n}${e}"`,i=L(p.readFileSync(o,`utf-8`),t,r);p.writeFileSync(o,i),O.delete(o)}:void 0})}}}if(c.size>0){y(g.gray(`Verifying ${c.size} external links...`));let n=new Map;for(let e of c)n.has(e.url)||n.set(e.url,[]),n.get(e.url).push(e.file);let r=async e=>{try{let t=new AbortController,n=setTimeout(()=>t.abort(),o),r=await fetch(e,{method:`HEAD`,signal:t.signal,headers:{"User-Agent":`boltdocs-doctor/1.0`}});return clearTimeout(n),!r.ok&&r.status!==404?{url:e,ok:(await fetch(e,{method:`GET`,signal:t.signal,headers:{"User-Agent":`boltdocs-doctor/1.0`}})).ok}:{url:e,ok:r.ok}}catch(t){return{url:e,ok:!1,error:t instanceof Error?t.message:String(t)}}},a=Array.from(n.keys()),l=[];for(let e=0;e<a.length;e+=s){let t=a.slice(e,e+s),n=await Promise.allSettled(t.map(r));l.push(...n.map(e=>e.status===`fulfilled`?e.value:{url:`unknown`,ok:!1,error:String(e.reason)}))}for(let r of l)if(!r.ok){let a=D(e,`brokenLink`,`warning`);if(a!==`off`){let o=n.get(r.url)||[];for(let n of o)t.push({file:i(f.relative(e.docsDir,n)),level:a,message:`Broken external link: "${r.url}"`,suggestion:`Verify the URL or update it if it's permanently down. Error: ${r.error||`Status >= 400`}`})}}}return t}async function U(e){let t=[];if(!e.doctorConfig.checks.i18n.enabled||!e.config.i18n)return t;let{defaultLocale:n,locales:r}=e.config.i18n,a=Object.keys(r),o=a.filter(e=>e!==n);if(o.length===0)return t;let s=f.resolve(e.docsDir),c=f.join(s,n),l=p.existsSync(c)&&p.statSync(c).isDirectory(),u=e=>{let t=f.resolve(e);if(t!==s&&!t.startsWith(s+f.sep))throw Error(`Refusing to write outside docs dir: ${t}`);return t};for(let r of e.files){let d=i(f.relative(e.docsDir,r)),m=d.split(`/`),h=m[0],g,_;if(a.includes(h)&&h!==n?(g=h,_=m.slice(1).join(`/`)):h===n&&l?(g=n,_=m.slice(1).join(`/`)):(g=n,_=d),_)if(g===n)for(let n of o){let i=f.join(s,n,_);if(!j(i)){let a=D(e,`missingTranslation`,`warning`);a!==`off`&&t.push({file:d,level:a,message:`Missing translation for locale "${n}"`,suggestion:`Create a version at "${n}/${_}".`,fix:async()=>{let e=u(i),t=f.dirname(e);p.existsSync(t)||p.mkdirSync(t,{recursive:!0}),p.copyFileSync(r,e)}})}}else{let i=f.join(s,_),a=l?f.join(c,_):``;if(!(j(i)||a!==``&&j(a))){let i=D(e,`missingTranslation`,`low`);i!==`off`&&t.push({file:d,level:i,message:`Orphaned translation (source missing in "${n}")`,suggestion:`Remove this file or create the source at "${n}/${_}".`,fix:async()=>{p.unlinkSync(u(r))}})}}}return t}async function W(e){let t=[];if(!e.config.theme?.sidebar)return t;let n=new Set,r=e.config.theme.sidebar;for(let[i,a]of Object.entries(r))for(let r of a){if(!r.text){let n=D(e,`invalidFrontmatter`,`warning`);n!==`off`&&t.push({file:`boltdocs.config.ts`,level:n,message:`Sidebar item in group "${i}" is missing a label.`,suggestion:`Add a "text" property to the sidebar item.`})}if(r.link&&(n.add(r.link),!e.routeIndex.has(r.link))){let{bestMatch:n,similarity:i}=I(r.link,e.linkTree.routes),a=i>.6,o=D(e,`brokenLink`,`high`);o!==`off`&&t.push({file:`boltdocs.config.ts`,level:o,message:`Broken sidebar link: "${r.link}"`,suggestion:a?`Did you mean "${n}"?`:`Ensure the route exists and is correctly formatted.`})}}for(let r of e.linkTree.routes)if(!(r===`/`||r===``)&&!n.has(r)){let n=D(e,`orphanedPage`,`low`);n!==`off`&&t.push({file:`Sidebar`,level:n,message:`Orphaned page found: "${r}" is not linked in the sidebar.`,suggestion:`Consider adding it to the sidebar for better discoverability.`})}return t}async function G(e){let t=[],n=e.doctorConfig.checks.performance;if(!n?.enabled)return t;let r=f.resolve(e.root,`.boltdocs`,`reports`,`performance.json`);if(!p.existsSync(r))return t.push({file:`(build)`,level:D(e,`budgetExceeded`,`warning`)??`warning`,message:"Performance metrics not found. Run `boltdocs build` first."}),t;let i;try{i=JSON.parse(p.readFileSync(r,`utf-8`))}catch{return t.push({file:`(build)`,level:D(e,`budgetExceeded`,`warning`)??`warning`,message:`Failed to parse performance metrics file.`}),t}let a=n.budgets,o=D(e,`budgetExceeded`,`warning`),s=E(a?.maxJSBundleSize,1/0),c=E(a?.maxCSSBundleSize,1/0),l=E(a?.maxPageHTMLSize,1/0),u=a?.maxImagesKB??1/0,d=a?.maxBuildTime??1/0,m=a?.maxFontCount??1/0;if(s!==1/0&&i.totalJSBundleSize>s){let e=(i.totalJSBundleSize/1024).toFixed(0),n=(s/1024).toFixed(0);t.push({file:`(build)`,level:o,message:`JS bundle size exceeds budget: ${e}kb > ${n}kb`,suggestion:`Code-split large dependencies or lazy-load route components.`})}if(c!==1/0&&i.totalCSSBundleSize>c){let e=(i.totalCSSBundleSize/1024).toFixed(0),n=(c/1024).toFixed(0);t.push({file:`(build)`,level:o,message:`CSS bundle size exceeds budget: ${e}kb > ${n}kb`,suggestion:`Remove unused styles or split CSS by route.`})}if(l!==1/0){for(let e of i.pages)if(e.htmlSize>l){let n=(e.htmlSize/1024).toFixed(0),r=(l/1024).toFixed(0);t.push({file:e.route,level:o,message:`Page HTML size exceeds budget: ${n}kb > ${r}kb`,suggestion:`Reduce the amount of inline content or split into sub-pages.`})}}let h=u*1024;if(u!==1/0&&i.totalImagesSize>h){let e=(i.totalImagesSize/1024).toFixed(0);t.push({file:`(build)`,level:o,message:`Image assets exceed budget: ${e}kb > ${u}kb`,suggestion:`Optimize images with lossy compression or use next-gen formats (webp/avif).`})}if(d!==1/0&&i.buildTime>d){let e=(i.buildTime/1e3).toFixed(1),n=(d/1e3).toFixed(1);t.push({file:`(build)`,level:o,message:`Build time exceeds budget: ${e}s > ${n}s`,suggestion:"Check for large unoptimized assets or increase `concurrency` in SSG options."})}return m!==1/0&&i.fontCount>m&&t.push({file:`(build)`,level:o,message:`Font files exceed budget: ${i.fontCount} > ${m}`,suggestion:`Reduce the number of font families or use variable fonts.`}),t}var K=e({DEFAULT_DOCTOR_CONFIG:()=>T,checkI18n:()=>U,checkLinks:()=>H,checkMetadata:()=>R,checkPerformance:()=>G,checkSidebar:()=>W,doctorAction:()=>J,doctorInit:()=>q,generateLinkTree:()=>N,loadDoctorConfig:()=>M});async function q(e){let t=f.resolve(e,`doctor.json`);if(p.existsSync(t)){S(`"doctor.json" already exists at ${e}.`);return}try{p.writeFileSync(t,JSON.stringify(T,null,2)),x(`Created "doctor.json" with default configuration.`)}catch(e){v(`Failed to create "doctor.json": ${e}`)}}async function J(e=process.cwd(),t={}){if(t.init){await q(e);return}d();try{let n=await M(e),{format:r}=n.reporting,i=performance.now(),a=await o(`docs`,e),d=f.resolve(e,`docs`);if(p.existsSync(d)||(r===`pretty`&&v(`Docs dir not found at ${d}`),process.exit(1)),r===`pretty`){let t=c?` ${s(`v${c}`)}`:``;console.log(`\n ${g.bold(`⚡`)} ${u(`boltdocs`)}${t} ${g.dim(`—`)} ${g.bold(`doctor`)} ${g.dim(`· documentation health check`)}\n`),console.log(` ${g.dim(`Docs dir ${d}`)}\n ${g.dim(`Reports ${e}/.boltdocs/reports/`)}\n`)}r===`pretty`&&y(g.dim(`🔍 Discovering files and routes...`));let S=te(n.exclude||[]),w=await new C().withFullPaths().filter(e=>{if(!(e.endsWith(`.md`)||e.endsWith(`.mdx`)))return!1;let t=f.relative(d,e).replace(/\\/g,`/`),n=t.split(`/`).some(e=>e.startsWith(`_`)&&e!==`_index.md`&&e!==`_index.mdx`);return!S(t)&&!n}).crawl(d).withPromise();for(let e of w)A.set(e,!0);let T=await N(d,e,a,w),E=a.base||`/`,D=E===`/`?``:E.endsWith(`/`)?E.slice(0,-1):E,O=new Set(T.routes),k=new Set(T.routes.map(e=>e.endsWith(`/`)?e:e+`/`)),j=new Set(T.routes.map(e=>e.endsWith(`/`)?e.slice(0,-1):e));r===`pretty`&&y(g.dim(`🧪 Running diagnostic checks in parallel...`));let P={root:e,docsDir:d,config:a,doctorConfig:n,linkTree:T,files:w,options:t,routeIndex:O,routeIndexWithSlash:k,routeIndexWithoutSlash:j,basePrefix:D};r===`pretty`&&y(g.dim(`🧪 Running diagnostic checks in parallel...`));let F=[R(P),H(P),U(P),W(P)];t.budget&&F.push(G(P));let[I,L,z,B,...V]=await Promise.all(F),K=t.budget?V[0]??[]:[],q=[...I,...L,...z,...B,...K];if(r===`pretty`){let e=e=>e>0?g.red(`${e} issue${e===1?``:`s`}`):g.green(`OK`),n=[{label:`Metadata checks ${e(I.length)}`,done:I.length===0},{label:`Link checks ${e(L.length)}`,done:L.length===0},{label:`i18n checks ${e(z.length)}`,done:z.length===0},{label:`Sidebar checks ${e(B.length)}`,done:B.length===0}];t.budget&&n.push({label:`Performance budget ${e(K.length)}`,done:K.length===0}),console.log(`\n${ee(n)}\n`)}let J=0;if(t.fix){for(let e of q)if(e.fix){if(P.doctorConfig.fix.confirmChanges&&!await _(`Fix issue in "${e.file}": ${e.message}?`))continue;if(P.doctorConfig.fix.backupFiles){let t=f.resolve(P.docsDir,e.file);p.existsSync(t)&&await ne(t,f.resolve(P.root,P.doctorConfig.fix.backupPath))}await e.fix(),J++}}let Y=((performance.now()-i)/1e3).toFixed(2),X=q.filter(e=>e.level===`high`).length,Z=q.filter(e=>e.level===`warning`).length,Q=q.filter(e=>e.level===`low`).length,$={summary:{total:q.length,high:X,warning:Z,low:Q,fixed:J,duration:Y},issues:q.map(e=>({...e,fix:void 0}))};if(n.reporting.outputFile){let t=f.resolve(e,n.reporting.outputFile);p.existsSync(f.dirname(t))||p.mkdirSync(f.dirname(t),{recursive:!0}),p.writeFileSync(t,JSON.stringify($,null,2))}if(r===`json`)console.log(JSON.stringify($,null,2));else if(r===`pretty`){let e=q.reduce((e,t)=>(e[t.file]||(e[t.file]=[]),e[t.file].push(t),e),{});if(q.length>0){console.log(b({title:`Issues`,colors:{title:l}}));for(let[n,r]of Object.entries(e)){let e=r.some(e=>e.level===`high`)?`high`:r.some(e=>e.level===`warning`)?`warning`:`low`,i=e.toUpperCase(),a=m(e===`high`?{label:i,status:`error`}:e===`warning`?{label:i,status:`warning`}:{label:i,colors:{text:`#ffffff`,bg:l}});console.log(`\n ${a} ${g.bold(n)}`);for(let e of r){let n=e.level===`high`?`✖`:e.level===`warning`?`⚠`:`ℹ`,r=e.level===`high`?g.red:e.level===`warning`?g.yellow:e=>h(e,l,`fg`);console.log(` ${r(n)} ${e.message}`),e.suggestion&&console.log(` ${g.dim(`💡 ${e.suggestion}`)}`),t.fix&&e.fix&&console.log(` ${g.green(`✅ Fixed automatically`)}`)}}console.log(``)}q.length===0?(console.log(` ${g.green.bold(`✨ Everything looks perfect!`)} ${g.dim(`— your documentation is in great shape.`)}`),console.log(` ${g.dim(`Scanned ${w.length} file${w.length===1?``:`s`} in ${Y}s`)}`)):(console.log(`\n${b({title:`Summary`,colors:{title:l}})}`),X>0&&console.log(` ${m({label:String(X),status:`error`})} ${g.bold(`high`)}`),Z>0&&console.log(` ${m({label:String(Z),status:`warning`})} ${g.bold(`warning`)}${Z===1?``:`s`}`),Q>0&&console.log(` ${m({label:String(Q),colors:{text:`#ffffff`,bg:l}})} ${g.bold(`low`)}`),console.log(` ${g.dim(`Scanned ${w.length} file${w.length===1?``:`s`} in ${Y}s`)}`),J>0&&x(`Successfully fixed ${J} issues automatically!`),X>0?v(`Please fix the critical errors before building for production.`):x(`No critical issues found. You are ready to go!`))}n.reporting.failOnError&&X>0&&process.exit(1),n.reporting.maxWarnings!==-1&&Z>n.reporting.maxWarnings&&(r===`pretty`&&v(`Failed: Too many warnings (${Z} > ${n.reporting.maxWarnings})`),process.exit(1))}catch(e){v(`Doctor failed: ${e}`),process.exit(1)}}export{N as n,K as t};
|
|
6
|
+
import{t as e}from"./chunk-BFSpntXv.mjs";import{a as t,d as n,g as r,u as i}from"./utils-8lzafE49.mjs";import{n as a}from"./pages-external-jmK7AHaO.mjs";import{n as o}from"./config-CTcfF-0c.mjs";import{i as s,n as c,r as l,s as u,t as d}from"./update-check-BXx8te9F.mjs";import f from"node:path";import p from"node:fs";import{badge as m,colorize as h,colors as g,confirm as _,error as v,info as y,section as b,success as x,tasks as ee,warn as S}from"@bdocs/dui";import{fdir as C}from"fdir";import te from"picomatch";import{distance as w}from"fastest-levenshtein";const T={$schema:`https://boltdocs.vercel.app/schemas/doctor-config.schema.json`,checks:{metadata:{enabled:!0,titleMin:10,titleMax:60,descriptionMin:50,required:[`title`,`description`],optional:[],validateDates:!1},links:{internal:!0,external:!1,timeout:1e4,concurrency:10,ignore:[]},i18n:{enabled:!0},performance:{enabled:!0,budgets:{maxJSBundleSize:`200kb`,maxCSSBundleSize:`30kb`,maxPageHTMLSize:`80kb`,maxImagesKB:500,maxBuildTime:3e4,maxFontCount:3}}},fix:{confirmChanges:!1,backupFiles:!1,backupPath:`.boltdocs/backups`},reporting:{format:`pretty`,outputFile:`.boltdocs/reports/doctor.json`,failOnError:!1,maxWarnings:-1},severity:{missingTranslation:`warning`,brokenLink:`high`,brokenAnchor:`warning`,largeFile:`warning`,orphanedPage:`low`,duplicateTitle:`low`,shortMetadata:`low`,missingMetadata:`warning`,malformedFrontmatter:`high`,invalidFrontmatter:`high`,budgetExceeded:`warning`},exclude:[]};function E(e,t){if(e==null)return t;if(typeof e==`number`)return e;let n=e.toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/);if(!n)return t;let r=Number.parseFloat(n[1]),i=n[2]||`b`;return Math.round(r*({b:1,kb:1024,mb:1024*1024,gb:1024*1024*1024}[i]||1))}function D(e,t,n){return e.doctorConfig.severity[t]||n}async function ne(e,t){p.existsSync(t)||p.mkdirSync(t,{recursive:!0});let n=f.basename(e),r=new Date().toISOString().replace(/[:.]/g,`-`),i=f.join(t,`${n}.${r}.bak`);p.copyFileSync(e,i)}const O=new Map;function k(e){let t=O.get(e);if(t)return t;let r=(async()=>{let t=await n(e,!1);return{raw:t.raw,data:t.data,content:t.content}})();return O.set(e,r),r}const A=new Map;function j(e){if(A.has(e))return A.get(e);let t=!1;try{t=p.existsSync(e)&&p.statSync(e).isFile()}catch{t=!1}return A.set(e,t),t}async function M(e){let t=f.resolve(e,`doctor.json`);if(p.existsSync(t))try{let e=JSON.parse(p.readFileSync(t,`utf-8`));return{...T,...e,checks:{...T.checks,...e.checks,metadata:{...T.checks.metadata,...e.checks?.metadata},links:{...T.checks.links,...e.checks?.links},i18n:{...T.checks.i18n,...e.checks?.i18n},performance:{...T.checks.performance,...e.checks?.performance,budgets:{...T.checks.performance?.budgets,...e.checks?.performance?.budgets}}},fix:{...T.fix,...e.fix},reporting:{...T.reporting,...e.reporting},severity:{...T.severity,...e.severity},exclude:[...T.exclude,...e.exclude||[]]}}catch(e){S(`Failed to parse doctor.json: ${e}`)}return T}async function N(e,n=process.cwd(),r,i){let o=f.resolve(n,`.boltdocs`,`generated`);p.existsSync(o)||p.mkdirSync(o,{recursive:!0});let s=i;s||=await new C().withFullPaths().filter(e=>e.endsWith(`.md`)||e.endsWith(`.mdx`)).crawl(e).withPromise();let c=r?.base||`/`,l=[];for(let n=0;n<s.length;n+=100){let r=s.slice(n,n+100),i=await Promise.all(r.map(async n=>{let r=f.isAbsolute(n)?n:f.resolve(e,n),i=f.relative(e,r),{data:a}=await k(r),o;return o=a.permalink?String(a.permalink).startsWith(`/`)?String(a.permalink):`/${a.permalink}`:t(i),c===`/`?o:(c.endsWith(`/`)?c:c+`/`)+(o.startsWith(`/`)?o.substring(1):o)}));l.push(...i)}l.includes(c)||l.push(c);let u=a(e,r);for(let e of u)l.includes(e)||l.push(e);let d={routes:Array.from(new Set(l)).sort(),timestamp:Date.now()};return p.writeFileSync(f.resolve(o,`link-tree.json`),JSON.stringify(d,null,2)),d}function P(e,t){if(e===t)return 1;if(!e||!t)return 0;let n=e.split(`/`).filter(Boolean),r=t.split(`/`).filter(Boolean),i=n[n.length-1]||``,a=r[r.length-1]||``;if(i===a){let e=0;for(let t of n)r.includes(t)&&e++;return e>=2?.99:.9}if(i.length>3&&a.length>3&&(a.startsWith(i)||i.startsWith(a))&&Math.min(i.length,a.length)/Math.max(i.length,a.length)>.5)return .88;let o=1-w(i,a)/Math.max(i.length,a.length);return o>.8?o*.95:1-w(e,t)/Math.max(e.length,t.length)}const F=new Map;function I(e,t){if(F.has(e))return F.get(e);let n=e.length,r=``,i=0;for(let a of t){if(a===e)continue;let t=a.length,o=Math.max(n,t);if(o===0)continue;let s=1-Math.abs(n-t)/o;if(s<=.8&&s<=i)continue;let c=P(e,a);c>i&&(i=c,r=a)}let a={bestMatch:r,similarity:i};return F.set(e,a),a}function L(e,t,n){let r=/```[\s\S]*?```/g,i=/`[^`\n]*`/g,a=0,o=[],s=t=>{e=e.replace(t,e=>(o.push(e),`__BD_CODE_MASK_${a++}__`))};return s(r),s(i),e.split(t).join(n).replace(/__BD_CODE_MASK_(\d+)__/g,(e,t)=>o[Number(t)]??``)}async function R(e){let t=[];if(!e.doctorConfig.checks.metadata.enabled)return t;let{titleMin:n,titleMax:a,descriptionMin:o}=e.doctorConfig.checks.metadata,s=new Map;for(let c of e.files){let l=i(f.relative(e.docsDir,c));try{let{raw:i,data:u}=await k(c);if(i.trim().startsWith(`---`)&&i.split(`---`).length>=3&&Object.keys(u).length===0){let n=D(e,`malformedFrontmatter`,`high`);n!==`off`&&t.push({file:l,level:n,message:`Malformed frontmatter (YAML parsing failed).`,suggestion:`Check your YAML syntax for indentation or unquoted special characters.`})}let d=r.safeParse(u);if(!d.success){let n=D(e,`invalidFrontmatter`,`high`);if(n!==`off`)for(let e of d.error.issues)t.push({file:l,level:n,message:`Invalid frontmatter field "${e.path.join(`.`)}": ${e.message}`,suggestion:`Ensure the field follows the correct type.`})}let f=Array.from(new Set([`title`,...e.doctorConfig.checks.metadata.required]));for(let n of f)if(u[n]===void 0){let r=D(e,`missingMetadata`,`warning`);r!==`off`&&t.push({file:l,level:r,message:`Missing required frontmatter field: "${n}".`,suggestion:`Add the "${n}" field to your frontmatter.`})}if(e.doctorConfig.checks.metadata.validateDates){let n=[`date`,`lastUpdated`,...e.doctorConfig.checks.metadata.optional.filter(e=>e.toLowerCase().includes(`date`))];for(let r of n)if(u[r]&&Number.isNaN(Date.parse(String(u[r])))){let n=D(e,`invalidFrontmatter`,`high`);n!==`off`&&t.push({file:l,level:n,message:`Invalid date format in field "${r}": "${u[r]}".`,suggestion:`Use a valid ISO date format (e.g., YYYY-MM-DD).`})}}if(u.title){let r=String(u.title);if(r.length<n){let i=D(e,`shortMetadata`,`low`);i!==`off`&&t.push({file:l,level:i,message:`Title is too short (${r.length} chars).`,suggestion:`Titles should be at least ${n} characters for better SEO.`})}else if(r.length>a){let n=D(e,`shortMetadata`,`low`);n!==`off`&&t.push({file:l,level:n,message:`Title is too long (${r.length} chars).`,suggestion:`Titles should be under ${a} characters.`})}let i=s.get(r)||[];i.push(l),s.set(r,i)}if(u.description&&String(u.description).length<o){let n=D(e,`shortMetadata`,`low`);n!==`off`&&t.push({file:l,level:n,message:`Description is very short.`,suggestion:`Descriptions should ideally be at least ${o} characters.`})}}catch(n){if(n instanceof Error){let r=D(e,`malformedFrontmatter`,`high`);r!==`off`&&t.push({file:l,level:r,message:`Malformed frontmatter (YAML error): ${n.message}`,suggestion:`Check your YAML syntax for indentation or unquoted special characters.`})}}}for(let[n,r]of s.entries())if(r.length>1){let i=D(e,`duplicateTitle`,`low`);if(i!==`off`)for(let e of r)t.push({file:e,level:i,message:`Duplicate title found: "${n}"`,suggestion:`Ensure each page has a unique title. Also used in: ${r.filter(t=>t!==e).join(`, `)}`})}return t}const z=/(?:\[([^\]]*)\]\(([^)\s]+)(?:\s+["'][^"']*["'])?\))|(?:href=["']([^"']+)["'])|(?:<Link\s+[^>]*?to=["'](\/[^"']+)["'])/g,B=[``,`.md`,`.mdx`,`/index.md`,`/index.mdx`];function V(e){let t=[],n=e=>{t.includes(e)||t.push(e)};n(e),e.endsWith(`/`)?n(e.slice(0,-1)):n(e+`/`);let r=e.replace(/\.(md|mdx)$/i,``);r!==e&&(n(r),n(r+`/`));let i=e.replace(/\/index\.(md|mdx)$/i,``);return i!==e&&(n(i),n(i+`/`)),n(e.endsWith(`/`)?e+`index`:e+`/index`),e.endsWith(`/index`)&&n(e.replace(/\/index$/,``)),t}async function H(e){let t=[],{internal:n,external:r,ignore:a,timeout:o,concurrency:s}=e.doctorConfig.checks.links;if(!n&&!r&&!e.options.checkExternal)return t;let c=new Set,l=5e5;for(let o of e.files){let s=i(f.relative(e.docsDir,o)),{content:u}=await k(o),d=[...(u.length>l?u.slice(0,l):u).replace(/<!--[\s\S]*?-->/g,``).replace(/```[\s\S]*?```/g,``).replace(/`[^`\n]*`/g,``).matchAll(z)];for(let i of d){let l=i[2]||i[3]||i[4],u=!!i[2],d=!!i[4];if(!l||a.some(e=>l.includes(e)))continue;if(/^(https?:|mailto:|tel:|data:|javascript:|blob:|ftp:)/i.test(l)){(r||e.options.checkExternal)&&c.add({url:l,file:o});continue}if(l.startsWith(`//`)){(r||e.options.checkExternal)&&c.add({url:l,file:o});continue}if(!n||l.startsWith(`#`))continue;let m;try{m=decodeURIComponent(l.split(`#`)[0].split(`?`)[0])}catch{m=l.split(`#`)[0].split(`?`)[0]}if(!m)continue;let h=!1,g=!1,_=``;if(m.startsWith(`/`)){let t=V(m);for(let n of t)if(e.routeIndex.has(n)||e.routeIndexWithSlash.has(n)||e.routeIndexWithoutSlash.has(n)){h=!0;break}if(!h&&e.basePrefix)for(let n of t){let t=e.basePrefix+(n.startsWith(`/`)?n:`/`+n);if(t!==n&&(e.routeIndex.has(t)||e.routeIndexWithSlash.has(t))){g=!0,_=t;break}}if(!h&&!g){let t=m.replace(/^\/+/,``),n=f.join(e.docsDir,t);h=B.some(e=>j(n+e))}}else{let e=f.resolve(f.dirname(o),m);h=B.some(t=>j(e+t))}if(!h){let{bestMatch:n,similarity:r}=I(m,e.linkTree.routes);g&&(n=_,r=1);let i=r>.6||g,a=r>.75&&n!==m||g,c=D(e,`brokenLink`,`high`);c!==`off`&&t.push({file:s,level:c,message:`Broken internal link: "${l}"`,suggestion:i?`Did you mean "${n}"?`:`Ensure the target exists or check for typos.`,fix:a?async()=>{let e=l.includes(`#`)?`#`+l.split(`#`)[1]:``,t=u?`(${l})`:d?`to="${l}"`:`href="${l}"`,r=u?`(${n}${e})`:d?`to="${n}${e}"`:`href="${n}${e}"`,i=L(p.readFileSync(o,`utf-8`),t,r);p.writeFileSync(o,i),O.delete(o)}:void 0})}}}if(c.size>0){y(g.gray(`Verifying ${c.size} external links...`));let n=new Map;for(let e of c)n.has(e.url)||n.set(e.url,[]),n.get(e.url).push(e.file);let r=async e=>{try{let t=new AbortController,n=setTimeout(()=>t.abort(),o),r=await fetch(e,{method:`HEAD`,signal:t.signal,headers:{"User-Agent":`boltdocs-doctor/1.0`}});return clearTimeout(n),!r.ok&&r.status!==404?{url:e,ok:(await fetch(e,{method:`GET`,signal:t.signal,headers:{"User-Agent":`boltdocs-doctor/1.0`}})).ok}:{url:e,ok:r.ok}}catch(t){return{url:e,ok:!1,error:t instanceof Error?t.message:String(t)}}},a=Array.from(n.keys()),l=[];for(let e=0;e<a.length;e+=s){let t=a.slice(e,e+s),n=await Promise.allSettled(t.map(r));l.push(...n.map(e=>e.status===`fulfilled`?e.value:{url:`unknown`,ok:!1,error:String(e.reason)}))}for(let r of l)if(!r.ok){let a=D(e,`brokenLink`,`warning`);if(a!==`off`){let o=n.get(r.url)||[];for(let n of o)t.push({file:i(f.relative(e.docsDir,n)),level:a,message:`Broken external link: "${r.url}"`,suggestion:`Verify the URL or update it if it's permanently down. Error: ${r.error||`Status >= 400`}`})}}}return t}async function U(e){let t=[];if(!e.doctorConfig.checks.i18n.enabled||!e.config.i18n)return t;let{defaultLocale:n,locales:r}=e.config.i18n,a=Object.keys(r),o=a.filter(e=>e!==n);if(o.length===0)return t;let s=f.resolve(e.docsDir),c=f.join(s,n),l=p.existsSync(c)&&p.statSync(c).isDirectory(),u=e=>{let t=f.resolve(e);if(t!==s&&!t.startsWith(s+f.sep))throw Error(`Refusing to write outside docs dir: ${t}`);return t};for(let r of e.files){let d=i(f.relative(e.docsDir,r)),m=d.split(`/`),h=m[0],g,_;if(a.includes(h)&&h!==n?(g=h,_=m.slice(1).join(`/`)):h===n&&l?(g=n,_=m.slice(1).join(`/`)):(g=n,_=d),_)if(g===n)for(let n of o){let i=f.join(s,n,_);if(!j(i)){let a=D(e,`missingTranslation`,`warning`);a!==`off`&&t.push({file:d,level:a,message:`Missing translation for locale "${n}"`,suggestion:`Create a version at "${n}/${_}".`,fix:async()=>{let e=u(i),t=f.dirname(e);p.existsSync(t)||p.mkdirSync(t,{recursive:!0}),p.copyFileSync(r,e)}})}}else{let i=f.join(s,_),a=l?f.join(c,_):``;if(!(j(i)||a!==``&&j(a))){let i=D(e,`missingTranslation`,`low`);i!==`off`&&t.push({file:d,level:i,message:`Orphaned translation (source missing in "${n}")`,suggestion:`Remove this file or create the source at "${n}/${_}".`,fix:async()=>{p.unlinkSync(u(r))}})}}}return t}async function W(e){let t=[];if(!e.config.theme?.sidebar)return t;let n=new Set,r=e.config.theme.sidebar;for(let[i,a]of Object.entries(r))for(let r of a){if(!r.text){let n=D(e,`invalidFrontmatter`,`warning`);n!==`off`&&t.push({file:`boltdocs.config.ts`,level:n,message:`Sidebar item in group "${i}" is missing a label.`,suggestion:`Add a "text" property to the sidebar item.`})}if(r.link&&(n.add(r.link),!e.routeIndex.has(r.link))){let{bestMatch:n,similarity:i}=I(r.link,e.linkTree.routes),a=i>.6,o=D(e,`brokenLink`,`high`);o!==`off`&&t.push({file:`boltdocs.config.ts`,level:o,message:`Broken sidebar link: "${r.link}"`,suggestion:a?`Did you mean "${n}"?`:`Ensure the route exists and is correctly formatted.`})}}for(let r of e.linkTree.routes)if(!(r===`/`||r===``)&&!n.has(r)){let n=D(e,`orphanedPage`,`low`);n!==`off`&&t.push({file:`Sidebar`,level:n,message:`Orphaned page found: "${r}" is not linked in the sidebar.`,suggestion:`Consider adding it to the sidebar for better discoverability.`})}return t}async function G(e){let t=[],n=e.doctorConfig.checks.performance;if(!n?.enabled)return t;let r=f.resolve(e.root,`.boltdocs`,`reports`,`performance.json`);if(!p.existsSync(r))return t.push({file:`(build)`,level:D(e,`budgetExceeded`,`warning`)??`warning`,message:"Performance metrics not found. Run `boltdocs build` first."}),t;let i;try{i=JSON.parse(p.readFileSync(r,`utf-8`))}catch{return t.push({file:`(build)`,level:D(e,`budgetExceeded`,`warning`)??`warning`,message:`Failed to parse performance metrics file.`}),t}let a=n.budgets,o=D(e,`budgetExceeded`,`warning`),s=E(a?.maxJSBundleSize,1/0),c=E(a?.maxCSSBundleSize,1/0),l=E(a?.maxPageHTMLSize,1/0),u=a?.maxImagesKB??1/0,d=a?.maxBuildTime??1/0,m=a?.maxFontCount??1/0;if(s!==1/0&&i.totalJSBundleSize>s){let e=(i.totalJSBundleSize/1024).toFixed(0),n=(s/1024).toFixed(0);t.push({file:`(build)`,level:o,message:`JS bundle size exceeds budget: ${e}kb > ${n}kb`,suggestion:`Code-split large dependencies or lazy-load route components.`})}if(c!==1/0&&i.totalCSSBundleSize>c){let e=(i.totalCSSBundleSize/1024).toFixed(0),n=(c/1024).toFixed(0);t.push({file:`(build)`,level:o,message:`CSS bundle size exceeds budget: ${e}kb > ${n}kb`,suggestion:`Remove unused styles or split CSS by route.`})}if(l!==1/0){for(let e of i.pages)if(e.htmlSize>l){let n=(e.htmlSize/1024).toFixed(0),r=(l/1024).toFixed(0);t.push({file:e.route,level:o,message:`Page HTML size exceeds budget: ${n}kb > ${r}kb`,suggestion:`Reduce the amount of inline content or split into sub-pages.`})}}let h=u*1024;if(u!==1/0&&i.totalImagesSize>h){let e=(i.totalImagesSize/1024).toFixed(0);t.push({file:`(build)`,level:o,message:`Image assets exceed budget: ${e}kb > ${u}kb`,suggestion:`Optimize images with lossy compression or use next-gen formats (webp/avif).`})}if(d!==1/0&&i.buildTime>d){let e=(i.buildTime/1e3).toFixed(1),n=(d/1e3).toFixed(1);t.push({file:`(build)`,level:o,message:`Build time exceeds budget: ${e}s > ${n}s`,suggestion:"Check for large unoptimized assets or increase `concurrency` in SSG options."})}return m!==1/0&&i.fontCount>m&&t.push({file:`(build)`,level:o,message:`Font files exceed budget: ${i.fontCount} > ${m}`,suggestion:`Reduce the number of font families or use variable fonts.`}),t}var K=e({DEFAULT_DOCTOR_CONFIG:()=>T,checkI18n:()=>U,checkLinks:()=>H,checkMetadata:()=>R,checkPerformance:()=>G,checkSidebar:()=>W,doctorAction:()=>J,doctorInit:()=>q,generateLinkTree:()=>N,loadDoctorConfig:()=>M});async function q(e){let t=f.resolve(e,`doctor.json`);if(p.existsSync(t)){S(`"doctor.json" already exists at ${e}.`);return}try{p.writeFileSync(t,JSON.stringify(T,null,2)),x(`Created "doctor.json" with default configuration.`)}catch(e){v(`Failed to create "doctor.json": ${e}`)}}async function J(e=process.cwd(),t={}){if(t.init){await q(e);return}d();try{let n=await M(e),{format:r}=n.reporting,i=performance.now(),a=await o(`docs`,e),d=f.resolve(e,`docs`);if(p.existsSync(d)||(r===`pretty`&&v(`Docs dir not found at ${d}`),process.exit(1)),r===`pretty`){let t=c?` ${s(`v${c}`)}`:``;console.log(`\n ${g.bold(`⚡`)} ${u(`boltdocs`)}${t} ${g.dim(`—`)} ${g.bold(`doctor`)} ${g.dim(`· documentation health check`)}\n`),console.log(` ${g.dim(`Docs dir ${d}`)}\n ${g.dim(`Reports ${e}/.boltdocs/reports/`)}\n`)}r===`pretty`&&y(g.dim(`🔍 Discovering files and routes...`));let S=te(n.exclude||[]),w=await new C().withFullPaths().filter(e=>{if(!(e.endsWith(`.md`)||e.endsWith(`.mdx`)))return!1;let t=f.relative(d,e).replace(/\\/g,`/`),n=t.split(`/`).some(e=>e.startsWith(`_`)&&e!==`_index.md`&&e!==`_index.mdx`);return!S(t)&&!n}).crawl(d).withPromise();for(let e of w)A.set(e,!0);let T=await N(d,e,a,w),E=a.base||`/`,D=E===`/`?``:E.endsWith(`/`)?E.slice(0,-1):E,O=new Set(T.routes),k=new Set(T.routes.map(e=>e.endsWith(`/`)?e:e+`/`)),j=new Set(T.routes.map(e=>e.endsWith(`/`)?e.slice(0,-1):e));r===`pretty`&&y(g.dim(`🧪 Running diagnostic checks in parallel...`));let P={root:e,docsDir:d,config:a,doctorConfig:n,linkTree:T,files:w,options:t,routeIndex:O,routeIndexWithSlash:k,routeIndexWithoutSlash:j,basePrefix:D};r===`pretty`&&y(g.dim(`🧪 Running diagnostic checks in parallel...`));let F=[R(P),H(P),U(P),W(P)];t.budget&&F.push(G(P));let[I,L,z,B,...V]=await Promise.all(F),K=t.budget?V[0]??[]:[],q=[...I,...L,...z,...B,...K];if(r===`pretty`){let e=e=>e>0?g.red(`${e} issue${e===1?``:`s`}`):g.green(`OK`),n=[{label:`Metadata checks ${e(I.length)}`,done:I.length===0},{label:`Link checks ${e(L.length)}`,done:L.length===0},{label:`i18n checks ${e(z.length)}`,done:z.length===0},{label:`Sidebar checks ${e(B.length)}`,done:B.length===0}];t.budget&&n.push({label:`Performance budget ${e(K.length)}`,done:K.length===0}),console.log(`\n${ee(n)}\n`)}let J=0;if(t.fix){for(let e of q)if(e.fix){if(P.doctorConfig.fix.confirmChanges&&!await _(`Fix issue in "${e.file}": ${e.message}?`))continue;if(P.doctorConfig.fix.backupFiles){let t=f.resolve(P.docsDir,e.file);p.existsSync(t)&&await ne(t,f.resolve(P.root,P.doctorConfig.fix.backupPath))}await e.fix(),J++}}let Y=((performance.now()-i)/1e3).toFixed(2),X=q.filter(e=>e.level===`high`).length,Z=q.filter(e=>e.level===`warning`).length,Q=q.filter(e=>e.level===`low`).length,$={summary:{total:q.length,high:X,warning:Z,low:Q,fixed:J,duration:Y},issues:q.map(e=>({...e,fix:void 0}))};if(n.reporting.outputFile){let t=f.resolve(e,n.reporting.outputFile);p.existsSync(f.dirname(t))||p.mkdirSync(f.dirname(t),{recursive:!0}),p.writeFileSync(t,JSON.stringify($,null,2))}if(r===`json`)console.log(JSON.stringify($,null,2));else if(r===`pretty`){let e=q.reduce((e,t)=>(e[t.file]||(e[t.file]=[]),e[t.file].push(t),e),{});if(q.length>0){console.log(b({title:`Issues`,colors:{title:l}}));for(let[n,r]of Object.entries(e)){let e=r.some(e=>e.level===`high`)?`high`:r.some(e=>e.level===`warning`)?`warning`:`low`,i=e.toUpperCase(),a=m(e===`high`?{label:i,status:`error`}:e===`warning`?{label:i,status:`warning`}:{label:i,colors:{text:`#ffffff`,bg:l}});console.log(`\n ${a} ${g.bold(n)}`);for(let e of r){let n=e.level===`high`?`✖`:e.level===`warning`?`⚠`:`ℹ`,r=e.level===`high`?g.red:e.level===`warning`?g.yellow:e=>h(e,l,`fg`);console.log(` ${r(n)} ${e.message}`),e.suggestion&&console.log(` ${g.dim(`💡 ${e.suggestion}`)}`),t.fix&&e.fix&&console.log(` ${g.green(`✅ Fixed automatically`)}`)}}console.log(``)}q.length===0?(console.log(` ${g.green.bold(`✨ Everything looks perfect!`)} ${g.dim(`— your documentation is in great shape.`)}`),console.log(` ${g.dim(`Scanned ${w.length} file${w.length===1?``:`s`} in ${Y}s`)}`)):(console.log(`\n${b({title:`Summary`,colors:{title:l}})}`),X>0&&console.log(` ${m({label:String(X),status:`error`})} ${g.bold(`high`)}`),Z>0&&console.log(` ${m({label:String(Z),status:`warning`})} ${g.bold(`warning`)}${Z===1?``:`s`}`),Q>0&&console.log(` ${m({label:String(Q),colors:{text:`#ffffff`,bg:l}})} ${g.bold(`low`)}`),console.log(` ${g.dim(`Scanned ${w.length} file${w.length===1?``:`s`} in ${Y}s`)}`),J>0&&x(`Successfully fixed ${J} issues automatically!`),X>0?v(`Please fix the critical errors before building for production.`):x(`No critical issues found. You are ready to go!`))}n.reporting.failOnError&&X>0&&process.exit(1),n.reporting.maxWarnings!==-1&&Z>n.reporting.maxWarnings&&(r===`pretty`&&v(`Failed: Too many warnings (${Z} > ${n.reporting.maxWarnings})`),process.exit(1))}catch(e){v(`Doctor failed: ${e}`),process.exit(1)}}export{N as n,K as t};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright (c) 2026 Jesus Alcala
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
const require_router = require('./router-
|
|
7
|
-
const require_link = require('./link-
|
|
6
|
+
const require_router = require('./router-DKC0Lu0n.cjs');
|
|
7
|
+
const require_link = require('./link-Xb69Oy2F.cjs');
|
|
8
8
|
let react = require("react");
|
|
9
9
|
react = require_router.__toESM(react);
|
|
10
10
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -338,7 +338,7 @@ Tooltip.Content = TooltipContent;
|
|
|
338
338
|
*/
|
|
339
339
|
function Image({ theme, className, src, alt, ...props }) {
|
|
340
340
|
const { resolvedTheme } = useTheme();
|
|
341
|
-
const config =
|
|
341
|
+
const config = require_router.useConfig();
|
|
342
342
|
if (theme && theme !== resolvedTheme) return null;
|
|
343
343
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
344
344
|
className: require_link.cn("max-w-full h-auto rounded-lg my-8", className),
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Copyright (c) 2026 Jesus Alcala
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { i as cn, j as Link, t as Link$1, u as resolvePublicAssetUrl } from "./link-CSe_oD8Y.js";
|
|
7
|
+
import { V as useConfig } from "./router-B5e8k4qK.js";
|
|
7
8
|
import * as React$1 from "react";
|
|
8
9
|
import { createContext, use, useEffect, useState } from "react";
|
|
9
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
|
|
2
|
+
import * as _$react from "react";
|
|
3
|
+
import React$1, { ComponentType, ReactNode } from "react";
|
|
4
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
5
|
+
import { AliasOptions, Plugin, UserConfig } from "vite";
|
|
6
|
+
import { BadgeValue, BoltdocsCollectionsConfig, BoltdocsConfigContract, BoltdocsI18nConfig, BoltdocsIntegrationsConfig, BoltdocsVersionsConfig, CodeHighlightConfig, CodeTheme, JsonLdObject, PluginDefinition, RedirectConfig, RedirectStatus, StructuredData } from "@bdocs/contracts";
|
|
7
|
+
|
|
8
|
+
//#region src/shared/types.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* Represents a single social link in the configuration.
|
|
11
|
+
*/
|
|
12
|
+
interface BoltdocsSocialLink {
|
|
13
|
+
icon: 'discord' | 'x' | 'github' | 'bluesky' | string;
|
|
14
|
+
link: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Theme-specific configuration options.
|
|
18
|
+
*/
|
|
19
|
+
interface BoltdocsThemeConfig {
|
|
20
|
+
title?: string | Record<string, string>;
|
|
21
|
+
description?: string | Record<string, string>;
|
|
22
|
+
logo?: string | {
|
|
23
|
+
dark: string;
|
|
24
|
+
light: string;
|
|
25
|
+
alt?: string;
|
|
26
|
+
width?: number;
|
|
27
|
+
height?: number;
|
|
28
|
+
};
|
|
29
|
+
navbar?: Array<{
|
|
30
|
+
label: string | Record<string, string>;
|
|
31
|
+
href: BoltdocsRoutePathWithFallback;
|
|
32
|
+
items?: Array<{
|
|
33
|
+
label: string | Record<string, string>;
|
|
34
|
+
href: BoltdocsRoutePathWithFallback;
|
|
35
|
+
}>;
|
|
36
|
+
}>;
|
|
37
|
+
sidebar?: Record<string, Array<{
|
|
38
|
+
text: string;
|
|
39
|
+
link: BoltdocsRoutePathWithFallback;
|
|
40
|
+
}>>;
|
|
41
|
+
sidebarGroups?: Record<string, {
|
|
42
|
+
title?: string | Record<string, string>;
|
|
43
|
+
icon?: string;
|
|
44
|
+
}>;
|
|
45
|
+
socialLinks?: BoltdocsSocialLink[];
|
|
46
|
+
editLink?: string;
|
|
47
|
+
communityHelp?: string;
|
|
48
|
+
version?: string;
|
|
49
|
+
githubRepo?: string;
|
|
50
|
+
favicon?: string;
|
|
51
|
+
tabs?: Array<{
|
|
52
|
+
id: string;
|
|
53
|
+
text: string | Record<string, string>;
|
|
54
|
+
icon?: string;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Legacy alias for `codeHighlighting.theme`. Kept for backwards
|
|
58
|
+
* compatibility — prefer `codeHighlighting`.
|
|
59
|
+
* @deprecated Use `codeHighlighting` instead.
|
|
60
|
+
*/
|
|
61
|
+
codeTheme?: CodeTheme;
|
|
62
|
+
/**
|
|
63
|
+
* Configures the markdown code highlighting engine. The engine is
|
|
64
|
+
* engine-agnostic: `engine` accepts a registry id (`'shiki'` by default),
|
|
65
|
+
* an adapter instance, or an adapter factory — so any highlighter can be
|
|
66
|
+
* plugged in without changes to the core.
|
|
67
|
+
*
|
|
68
|
+
* Shorthand: a plain string is a registry id, i.e. `'shiki'` is
|
|
69
|
+
* equivalent to `{ engine: 'shiki' }` (resolved by
|
|
70
|
+
* `normalizeCodeHighlightConfig()` at every read site).
|
|
71
|
+
*/
|
|
72
|
+
codeHighlighting?: CodeHighlightConfig | string;
|
|
73
|
+
}
|
|
74
|
+
interface BoltdocsPlugin extends PluginDefinition<BoltdocsConfig, IncomingMessage, ServerResponse> {
|
|
75
|
+
vitePlugins?: Plugin[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The root configuration object for Boltdocs.
|
|
79
|
+
*/
|
|
80
|
+
interface BoltdocsConfig extends BoltdocsConfigContract<BoltdocsPlugin> {
|
|
81
|
+
theme?: BoltdocsThemeConfig;
|
|
82
|
+
aliases?: AliasOptions;
|
|
83
|
+
vite?: UserConfig;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Global namespace for Boltdocs types that can be augmented by generated code.
|
|
87
|
+
* This allows for strictly typed locales and versions based on the project configuration.
|
|
88
|
+
*/
|
|
89
|
+
declare global {
|
|
90
|
+
namespace Boltdocs {
|
|
91
|
+
interface Types {}
|
|
92
|
+
/**
|
|
93
|
+
* Marker interface augmented by generated code to provide strict route path typing.
|
|
94
|
+
* When no types have been generated (e.g., before first dev server start),
|
|
95
|
+
* keyof is never, and BoltdocsRoutePath falls back to string.
|
|
96
|
+
*/
|
|
97
|
+
interface RoutePaths {}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
type BoltdocsTypes = Boltdocs.Types;
|
|
101
|
+
type BoltdocsRoutePath = keyof Boltdocs.RoutePaths;
|
|
102
|
+
type ExternalRouteReference = `/${string}` | `#${string}` | `?${string}` | `site:/${string}` | `site:${string}` | `http://${string}` | `https://${string}` | `//${string}`;
|
|
103
|
+
type BoltdocsRoutePathWithFallback = BoltdocsRoutePath | ExternalRouteReference | string;
|
|
104
|
+
type BoltdocsLocale = Boltdocs.Types extends {
|
|
105
|
+
Locale: infer L;
|
|
106
|
+
} ? L : string;
|
|
107
|
+
type BoltdocsVersion = Boltdocs.Types extends {
|
|
108
|
+
Version: infer V;
|
|
109
|
+
} ? V : string;
|
|
110
|
+
type UnpackMdxComponents<T> = T extends {
|
|
111
|
+
default: infer D;
|
|
112
|
+
} ? D : T;
|
|
113
|
+
type TransformMdxComponents<T> = { [K in keyof T as K extends `Frontmatter_${string}` ? never : K]: T[K] } & {
|
|
114
|
+
Frontmatter: { [K in keyof T as K extends `Frontmatter_${infer Name}` ? Name : never]: T[K] };
|
|
115
|
+
};
|
|
116
|
+
type BoltdocsMdxComponents = Boltdocs.Types extends {
|
|
117
|
+
MdxComponents: infer M;
|
|
118
|
+
} ? TransformMdxComponents<UnpackMdxComponents<M>> : Omit<Record<string, ComponentType<unknown>>, 'Frontmatter'> & {
|
|
119
|
+
Frontmatter: Record<string, ComponentType<unknown>>;
|
|
120
|
+
};
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/client/router/types.d.ts
|
|
123
|
+
interface LoaderFunctionArgs {
|
|
124
|
+
request: Request;
|
|
125
|
+
params: Record<string, string>;
|
|
126
|
+
}
|
|
127
|
+
type LoaderFunction<T = unknown> = (args: LoaderFunctionArgs) => Promise<T> | T;
|
|
128
|
+
type PrefetchFunction$1 = (to: string) => Promise<void>;
|
|
129
|
+
interface RouteMatch {
|
|
130
|
+
route: RouteRecord;
|
|
131
|
+
params: Record<string, string>;
|
|
132
|
+
pathname: string;
|
|
133
|
+
pathnameBase: string;
|
|
134
|
+
data?: Record<string, unknown>;
|
|
135
|
+
}
|
|
136
|
+
interface LazyRouteResult {
|
|
137
|
+
Component?: ComponentType<any>;
|
|
138
|
+
element?: ReactNode;
|
|
139
|
+
loader?: LoaderFunction;
|
|
140
|
+
ErrorBoundary?: ComponentType<any>;
|
|
141
|
+
}
|
|
142
|
+
/** Structurally compatible with react-router-dom's route objects */
|
|
143
|
+
interface RouteRecord {
|
|
144
|
+
path?: string;
|
|
145
|
+
index?: boolean;
|
|
146
|
+
id?: string;
|
|
147
|
+
element?: ReactNode;
|
|
148
|
+
Component?: ComponentType<any>;
|
|
149
|
+
loader?: LoaderFunction;
|
|
150
|
+
action?: (...args: any[]) => any;
|
|
151
|
+
ErrorBoundary?: ComponentType<any>;
|
|
152
|
+
hasErrorBoundary?: boolean;
|
|
153
|
+
HydrateFallback?: ComponentType<any>;
|
|
154
|
+
children?: RouteRecord[];
|
|
155
|
+
lazy?: () => Promise<LazyRouteResult>;
|
|
156
|
+
caseSensitive?: boolean;
|
|
157
|
+
shouldRevalidate?: (...args: any[]) => boolean;
|
|
158
|
+
getStaticPaths?: () => string[] | Promise<string[]>;
|
|
159
|
+
entry?: string;
|
|
160
|
+
/** Locale this route belongs to (used by i18n fallbacks) */
|
|
161
|
+
locale?: string;
|
|
162
|
+
}
|
|
163
|
+
interface RouterOptions {
|
|
164
|
+
routes: RouteRecord[];
|
|
165
|
+
basename?: string;
|
|
166
|
+
future?: Record<string, boolean>;
|
|
167
|
+
}
|
|
168
|
+
interface RouteRendererProps {
|
|
169
|
+
routes: RouteRecord[];
|
|
170
|
+
pathname?: string;
|
|
171
|
+
loaderData?: Record<string, unknown> | null;
|
|
172
|
+
/** Whether loaderData was explicitly produced for the initial SSR route. */
|
|
173
|
+
hasLoaderData?: boolean;
|
|
174
|
+
/** Resolved branch supplied by SSR so lazy MDX routes render without effects. */
|
|
175
|
+
resolvedBranch?: RouteRecord[];
|
|
176
|
+
basename?: string;
|
|
177
|
+
/** Default locale is omitted from external URLs. */
|
|
178
|
+
defaultLocale?: string;
|
|
179
|
+
/** Optional route prefetcher used by Link hover/focus interactions. */
|
|
180
|
+
prefetch?: PrefetchFunction$1;
|
|
181
|
+
/** Enables native View Transitions for route updates. */
|
|
182
|
+
viewTransitions?: boolean | {
|
|
183
|
+
enabled?: boolean;
|
|
184
|
+
types?: string[];
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
interface CreateRoutesResult {
|
|
188
|
+
routes: RouteRecord[];
|
|
189
|
+
RouteRenderer: ComponentType<RouteRendererProps>;
|
|
190
|
+
matchRouteBranch: (routes: RouteRecord[], pathname: string) => RouteRecord[];
|
|
191
|
+
matchRouteBranchWithParams: (routes: RouteRecord[], pathname: string, basename?: string) => Array<{
|
|
192
|
+
route: RouteRecord;
|
|
193
|
+
params: Record<string, string>;
|
|
194
|
+
}>;
|
|
195
|
+
resolveRouteBranch: (branch: RouteRecord[]) => Promise<RouteRecord[]>;
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/client/router/context.d.ts
|
|
199
|
+
interface LocationState {
|
|
200
|
+
pathname: string;
|
|
201
|
+
search: string;
|
|
202
|
+
hash: string;
|
|
203
|
+
}
|
|
204
|
+
type PrefetchFunction = (to: string) => Promise<void>;
|
|
205
|
+
type NavigateFunction = (to: string, options?: {
|
|
206
|
+
replace?: boolean;
|
|
207
|
+
state?: unknown; /** Disable the router transition when an outer transition owns the update. */
|
|
208
|
+
viewTransition?: boolean;
|
|
209
|
+
}) => void;
|
|
210
|
+
declare const defaultNavigate: NavigateFunction;
|
|
211
|
+
declare const LocationContext: _$react.Context<LocationState>;
|
|
212
|
+
declare const NavigateContext: _$react.Context<NavigateFunction>;
|
|
213
|
+
declare const PrefetchContext: _$react.Context<PrefetchFunction>;
|
|
214
|
+
declare const RouteDataContext: _$react.Context<Record<string, unknown> | null>;
|
|
215
|
+
declare const MatchesContext: _$react.Context<RouteMatch[]>;
|
|
216
|
+
interface LocationProviderProps {
|
|
217
|
+
pathname?: string;
|
|
218
|
+
children: React.ReactNode;
|
|
219
|
+
loaderData?: Record<string, unknown> | null;
|
|
220
|
+
matches?: RouteMatch[];
|
|
221
|
+
/** Base path of the application. Only links under this path are handled as SPA navigation. */
|
|
222
|
+
basename?: string;
|
|
223
|
+
/** Default locale is omitted from external URLs. */
|
|
224
|
+
defaultLocale?: string;
|
|
225
|
+
/** Optional route prefetcher used by Link hover/focus interactions. */
|
|
226
|
+
prefetch?: PrefetchFunction;
|
|
227
|
+
/** Enables the native View Transition API for route updates. */
|
|
228
|
+
viewTransitions?: boolean | {
|
|
229
|
+
enabled?: boolean;
|
|
230
|
+
types?: string[];
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
declare const LocationProvider: React.FC<LocationProviderProps>;
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/client/router/hooks.d.ts
|
|
236
|
+
declare function useLocation(): LocationState;
|
|
237
|
+
declare function useNavigate(): NavigateFunction;
|
|
238
|
+
declare function usePrefetch(): (to: string) => Promise<void>;
|
|
239
|
+
declare function useRouteData<T = Record<string, unknown>>(): T;
|
|
240
|
+
/** Alias for useRouteData — parity with react-router-dom's useLoaderData */
|
|
241
|
+
declare function useLoaderData<T = Record<string, unknown>>(): T;
|
|
242
|
+
declare function useMatches(): RouteMatch[];
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/client/router/outlet.d.ts
|
|
245
|
+
declare const OutletContext: _$react.Context<_$react.ReactNode>;
|
|
246
|
+
declare const Outlet: React.FC;
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/client/router/renderer.d.ts
|
|
249
|
+
interface RouteBranchMatch {
|
|
250
|
+
route: RouteRecord;
|
|
251
|
+
params: Record<string, string>;
|
|
252
|
+
}
|
|
253
|
+
declare function matchRouteBranchWithParams(routes: RouteRecord[], pathname: string, basename?: string): RouteBranchMatch[];
|
|
254
|
+
declare function matchRouteBranch(routes: RouteRecord[], pathname: string, basename?: string): RouteRecord[];
|
|
255
|
+
declare function resolveRouteBranch(branch: RouteRecord[]): Promise<RouteRecord[]>;
|
|
256
|
+
declare const RouteRenderer: React$1.FC<RouteRendererProps>;
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/client/router/utils.d.ts
|
|
259
|
+
declare function normalizeBasename(basename?: string): string;
|
|
260
|
+
declare function hasBasename(path: string, basename: string): boolean;
|
|
261
|
+
declare function stripBasename(path: string, basename: string): string;
|
|
262
|
+
declare function addBasename(path: string, basename: string): string;
|
|
263
|
+
//#endregion
|
|
264
|
+
//#region src/client/router/url-contract.d.ts
|
|
265
|
+
type UrlRouteKind = 'doc' | 'external' | 'collection';
|
|
266
|
+
interface UrlContractConfig {
|
|
267
|
+
base?: string;
|
|
268
|
+
i18n?: Pick<BoltdocsI18nConfig, 'defaultLocale' | 'locales'>;
|
|
269
|
+
versions?: Pick<BoltdocsVersionsConfig, 'defaultVersion' | 'prefix' | 'versions'>;
|
|
270
|
+
collections?: readonly string[] | BoltdocsCollectionsConfig;
|
|
271
|
+
}
|
|
272
|
+
interface UrlRouteHint {
|
|
273
|
+
path: string;
|
|
274
|
+
kind?: UrlRouteKind;
|
|
275
|
+
collection?: string;
|
|
276
|
+
}
|
|
277
|
+
interface ParsedUrl {
|
|
278
|
+
/** The normalized pathname, without query string or hash. */
|
|
279
|
+
pathname: string;
|
|
280
|
+
/** The normalized route content after removing structural prefixes. */
|
|
281
|
+
routePath: string;
|
|
282
|
+
/** Query string including `?`, when present. */
|
|
283
|
+
search: string;
|
|
284
|
+
/** Hash including `#`, when present. */
|
|
285
|
+
hash: string;
|
|
286
|
+
kind: UrlRouteKind;
|
|
287
|
+
locale?: string;
|
|
288
|
+
version?: string;
|
|
289
|
+
collection?: string;
|
|
290
|
+
/** Whether the input used the explicit `site:` protocol. */
|
|
291
|
+
siteProtocol: boolean;
|
|
292
|
+
/** Whether the input pathname contained the configured documentation base. */
|
|
293
|
+
hadBase: boolean;
|
|
294
|
+
}
|
|
295
|
+
interface BuildUrlOptions {
|
|
296
|
+
kind: UrlRouteKind;
|
|
297
|
+
/** Route content, e.g. `/guides/start`, `/about`, or `/my-post`. */
|
|
298
|
+
path?: string;
|
|
299
|
+
locale?: string;
|
|
300
|
+
version?: string;
|
|
301
|
+
collection?: string;
|
|
302
|
+
search?: string;
|
|
303
|
+
hash?: string;
|
|
304
|
+
/** The input pathname already contained the configured base. */
|
|
305
|
+
hadBase?: boolean;
|
|
306
|
+
}
|
|
307
|
+
interface ResolveUrlOptions {
|
|
308
|
+
/** Explicitly choose the route family when the path is ambiguous. */
|
|
309
|
+
kind?: UrlRouteKind;
|
|
310
|
+
/** Known route metadata used to classify paths outside `base`. */
|
|
311
|
+
routes?: readonly UrlRouteHint[];
|
|
312
|
+
/** Locale/version to apply when building a canonical target. */
|
|
313
|
+
locale?: string;
|
|
314
|
+
version?: string;
|
|
315
|
+
}
|
|
316
|
+
declare function normalizeUrlBase(base?: string): string;
|
|
317
|
+
declare function normalizeUrlPath(path: string): string;
|
|
318
|
+
declare function hasUrlBase(pathname: string, base?: string): boolean;
|
|
319
|
+
declare function stripUrlBase(pathname: string, base?: string): string;
|
|
320
|
+
declare function addUrlBase(pathname: string, base?: string): string;
|
|
321
|
+
declare function getConfiguredLocales(config: UrlContractConfig): string[];
|
|
322
|
+
declare function getConfiguredVersions(config: UrlContractConfig): string[];
|
|
323
|
+
declare function getVersionPrefixSegments(config: UrlContractConfig): string[];
|
|
324
|
+
declare function getVersionSegments(version: string | undefined, config: UrlContractConfig): string[];
|
|
325
|
+
declare function isConfiguredLocale(value: string | undefined, config: UrlContractConfig): value is string;
|
|
326
|
+
declare function isConfiguredVersion(value: string | undefined, config: UrlContractConfig): value is string;
|
|
327
|
+
declare function splitUrlReference(to: string): {
|
|
328
|
+
pathname: string;
|
|
329
|
+
search: string;
|
|
330
|
+
hash: string;
|
|
331
|
+
};
|
|
332
|
+
declare function stripSiteProtocol(to: string): {
|
|
333
|
+
value: string;
|
|
334
|
+
siteProtocol: boolean;
|
|
335
|
+
};
|
|
336
|
+
/** Returns true for URI schemes such as `mailto:`, `tel:`, or `data:`. */
|
|
337
|
+
declare function hasUriScheme(value: string): boolean;
|
|
338
|
+
declare function classifyUrlPath(pathname: string, config: UrlContractConfig, options?: Pick<ResolveUrlOptions, 'kind' | 'routes'>): UrlRouteKind;
|
|
339
|
+
declare function parseUrlReference(to: string, config: UrlContractConfig, options?: Pick<ResolveUrlOptions, 'kind' | 'routes'>): ParsedUrl;
|
|
340
|
+
declare function buildUrl(options: BuildUrlOptions, config: UrlContractConfig): string;
|
|
341
|
+
declare function resolveUrlReference(to: string, config: UrlContractConfig, options?: ResolveUrlOptions): string;
|
|
342
|
+
//#endregion
|
|
343
|
+
export { LazyRouteResult as $, matchRouteBranch as A, useRouteData as B, stripSiteProtocol as C, normalizeBasename as D, hasBasename as E, useLoaderData as F, MatchesContext as G, LocationProvider as H, useLocation as I, PrefetchContext as J, NavigateContext as K, useMatches as L, resolveRouteBranch as M, Outlet as N, stripBasename as O, OutletContext as P, CreateRoutesResult as Q, useNavigate as R, splitUrlReference as S, addBasename as T, LocationProviderProps as U, LocationContext as V, LocationState as W, RouteDataContext as X, PrefetchFunction as Y, defaultNavigate as Z, isConfiguredVersion as _, RedirectConfig as _t, UrlRouteHint as a, RouterOptions as at, parseUrlReference as b, buildUrl as c, BoltdocsIntegrationsConfig as ct, getConfiguredVersions as d, BoltdocsRoutePath as dt, LoaderFunction as et, getVersionPrefixSegments as f, BoltdocsRoutePathWithFallback as ft, isConfiguredLocale as g, JsonLdObject as gt, hasUrlBase as h, BoltdocsVersion as ht, UrlContractConfig as i, RouteRendererProps as it, matchRouteBranchWithParams as j, RouteRenderer as k, classifyUrlPath as l, BoltdocsLocale as lt, hasUriScheme as m, BoltdocsTypes as mt, ParsedUrl as n, RouteMatch as nt, UrlRouteKind as o, BadgeValue as ot, getVersionSegments as p, BoltdocsSocialLink as pt, NavigateFunction as q, ResolveUrlOptions as r, RouteRecord as rt, addUrlBase as s, BoltdocsConfig as st, BuildUrlOptions as t, LoaderFunctionArgs as tt, getConfiguredLocales as u, BoltdocsMdxComponents as ut, normalizeUrlBase as v, RedirectStatus as vt, stripUrlBase as w, resolveUrlReference as x, normalizeUrlPath as y, StructuredData as yt, usePrefetch as z };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import { Q as CreateRoutesResult,
|
|
3
|
-
import { ViteReactSSG } from "@bdocs/ssg";
|
|
2
|
+
import { Q as CreateRoutesResult, ct as BoltdocsIntegrationsConfig, ft as BoltdocsRoutePathWithFallback, gt as JsonLdObject, ht as BoltdocsVersion, lt as BoltdocsLocale, ot as BadgeValue, pt as BoltdocsSocialLink, st as BoltdocsConfig, ut as BoltdocsMdxComponents, yt as StructuredData$1 } from "./index-RK7W_Fxy.cjs";
|
|
4
3
|
import * as React$2 from "react";
|
|
5
4
|
import React$1, { ComponentType, JSXElementConstructor, ReactNode, SVGProps } from "react";
|
|
5
|
+
import { ViteReactSSG } from "@bdocs/ssg";
|
|
6
6
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
7
7
|
import { ClassValue } from "clsx";
|
|
8
8
|
|
|
@@ -272,19 +272,45 @@ type MdxPageProps = {
|
|
|
272
272
|
MDXComponent: React.ComponentType<React.PropsWithChildren<unknown>>;
|
|
273
273
|
mdxComponents: Record<string, React.ComponentType<HTMLElement>>;
|
|
274
274
|
collectionPostComponent?: React.ComponentType<any>;
|
|
275
|
+
/**
|
|
276
|
+
* Name of the collection this route belongs to, when it has one.
|
|
277
|
+
*
|
|
278
|
+
* The layout must not depend on data that arrives asynchronously. Route
|
|
279
|
+
* metadata is known synchronously from the route table, whereas the loader
|
|
280
|
+
* data is not: on the client the first render happens with no loader data,
|
|
281
|
+
* because the generated entry declares `hasLoaderData={false}`. Deciding the
|
|
282
|
+
* layout from the loader therefore picked the documentation layout for a
|
|
283
|
+
* collection post, while the server had rendered the collection layout. React
|
|
284
|
+
* saw two different first children and discarded the whole page (error #418).
|
|
285
|
+
*
|
|
286
|
+
* A project that declares a collection should not have to know this, so the
|
|
287
|
+
* route table supplies the answer directly and the loader is only a fallback
|
|
288
|
+
* for callers that render `MdxPage` directly.
|
|
289
|
+
*/
|
|
290
|
+
collection?: string;
|
|
291
|
+
/**
|
|
292
|
+
* Route metadata for the current page, when known synchronously.
|
|
293
|
+
*
|
|
294
|
+
* `usePost()` reads from `CurrentPostProvider`, and a collection layout calls
|
|
295
|
+
* it on its first render. Passing the route keeps that first render complete
|
|
296
|
+
* instead of rendering a header with no title and then filling it in.
|
|
297
|
+
*/
|
|
298
|
+
route?: ComponentRoute;
|
|
275
299
|
};
|
|
276
300
|
/**
|
|
277
301
|
* Renders an MDX page by consuming pre-loaded route data.
|
|
278
302
|
*
|
|
279
|
-
* - If the route belongs to a collection
|
|
280
|
-
*
|
|
281
|
-
*
|
|
303
|
+
* - If the route belongs to a collection, wraps the content with
|
|
304
|
+
* `CurrentPostProvider` so that `usePost()` (called without a slug) can read
|
|
305
|
+
* the current post's data from context.
|
|
282
306
|
* - Otherwise, renders the standard `DocPage` layout.
|
|
283
307
|
*/
|
|
284
308
|
declare function MdxPage({
|
|
285
309
|
MDXComponent,
|
|
286
310
|
mdxComponents: propComponents,
|
|
287
|
-
collectionPostComponent: CollectionPost
|
|
311
|
+
collectionPostComponent: CollectionPost,
|
|
312
|
+
collection,
|
|
313
|
+
route: routeProp
|
|
288
314
|
}: MdxPageProps): _$react_jsx_runtime0.JSX.Element | null;
|
|
289
315
|
//#endregion
|
|
290
316
|
//#region src/client/ssg/boltdocs-shell.d.ts
|
|
@@ -302,6 +328,50 @@ declare function BoltdocsShell({
|
|
|
302
328
|
contentClassName?: string;
|
|
303
329
|
}): _$react_jsx_runtime0.JSX.Element;
|
|
304
330
|
//#endregion
|
|
331
|
+
//#region src/client/collections/utils.d.ts
|
|
332
|
+
/**
|
|
333
|
+
* Formats a date to a human-readable string.
|
|
334
|
+
*
|
|
335
|
+
* Locale and time zone are pinned so the server and the browser produce
|
|
336
|
+
* identical text during hydration. See `formatDeterministicDate`.
|
|
337
|
+
*/
|
|
338
|
+
declare function formatDate(date: string | Date | undefined | null, options?: {
|
|
339
|
+
month?: 'numeric' | '2-digit' | 'long' | 'short';
|
|
340
|
+
day?: 'numeric' | '2-digit';
|
|
341
|
+
}): string;
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/client/utils/date.d.ts
|
|
344
|
+
/**
|
|
345
|
+
* Deterministic date formatting for server-rendered output.
|
|
346
|
+
*
|
|
347
|
+
* `toLocaleDateString` with no locale resolves against the *runtime* default,
|
|
348
|
+
* which is not the same in Node and in a browser: the server rendered
|
|
349
|
+
* "26 de septiembre de 2026" from an `es` system locale while the client
|
|
350
|
+
* produced "September 26, 2026". That is a text mismatch during hydration and
|
|
351
|
+
* React throws away the server HTML and re-renders the whole page.
|
|
352
|
+
*
|
|
353
|
+
* The time zone has to be pinned for the same reason. A frontmatter date such
|
|
354
|
+
* as `2026-09-27` parses as UTC midnight, so any zone behind UTC renders the
|
|
355
|
+
* previous day and any zone ahead renders the correct one, which is a second,
|
|
356
|
+
* environment-dependent mismatch.
|
|
357
|
+
*
|
|
358
|
+
* Both are therefore explicit here. Callers that genuinely want a different
|
|
359
|
+
* locale can pass one, and it is still deterministic because it is fixed in
|
|
360
|
+
* the markup rather than inferred.
|
|
361
|
+
*/
|
|
362
|
+
/**
|
|
363
|
+
* Formats a date as a stable, locale- and zone-pinned string.
|
|
364
|
+
*
|
|
365
|
+
* Returns an empty string for values that are not real dates so callers can
|
|
366
|
+
* render nothing rather than "Invalid Date".
|
|
367
|
+
*/
|
|
368
|
+
declare function formatDeterministicDate(date: string | number | Date | undefined | null, options?: {
|
|
369
|
+
locale?: string;
|
|
370
|
+
timeZone?: string;
|
|
371
|
+
month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';
|
|
372
|
+
day?: 'numeric' | '2-digit';
|
|
373
|
+
}): string;
|
|
374
|
+
//#endregion
|
|
305
375
|
//#region src/client/app/config-context.d.ts
|
|
306
376
|
/**
|
|
307
377
|
* Hook to access the Boltdocs configuration.
|
|
@@ -339,7 +409,13 @@ declare function useUI(): {
|
|
|
339
409
|
declare function useNavbar(): {
|
|
340
410
|
links: NavbarLink[];
|
|
341
411
|
title: string;
|
|
342
|
-
logo:
|
|
412
|
+
logo: {
|
|
413
|
+
light: string;
|
|
414
|
+
dark: null;
|
|
415
|
+
} | {
|
|
416
|
+
light: string;
|
|
417
|
+
dark: string;
|
|
418
|
+
} | null;
|
|
343
419
|
logoProps: {
|
|
344
420
|
alt: string;
|
|
345
421
|
width: number | undefined;
|
|
@@ -1220,10 +1296,13 @@ interface ViewTransitionRunner {
|
|
|
1220
1296
|
enabled: boolean;
|
|
1221
1297
|
/** Whether the current browser exposes the native API. */
|
|
1222
1298
|
supported: boolean;
|
|
1299
|
+
/** Whether the visitor asked the OS to reduce motion. */
|
|
1300
|
+
reducedMotion: boolean;
|
|
1223
1301
|
}
|
|
1224
1302
|
/**
|
|
1225
|
-
* Starts a native document transition when the browser supports it
|
|
1226
|
-
*
|
|
1303
|
+
* Starts a native document transition when the browser supports it and the
|
|
1304
|
+
* visitor has not asked for reduced motion. Otherwise the update still runs
|
|
1305
|
+
* normally and the function returns null.
|
|
1227
1306
|
*/
|
|
1228
1307
|
declare function startViewTransition(update: ViewTransitionUpdate, options?: ViewTransitionOptions): ViewTransitionHandle | null;
|
|
1229
1308
|
/**
|
|
@@ -1371,4 +1450,4 @@ declare function useCodeBlockFeedback(options?: UseCodeBlockFeedbackOptions): {
|
|
|
1371
1450
|
enabled: boolean;
|
|
1372
1451
|
};
|
|
1373
1452
|
//#endregion
|
|
1374
|
-
export { SidebarItem as $, cn as A, useUI as At, NotFound as B,
|
|
1453
|
+
export { SidebarItem as $, TabsProps as $t, cn as A, useUI as At, NotFound as B, CollectionPost$1 as Bt, createArticleStructuredData as C, usePageNav as Ct, defineStructuredData as D, useSearch as Dt, createWebSiteStructuredData as E, useTabs as Et, TimelineVariant as F, formatDate as Ft, Breadcrumbs as G, CollectionListLoaderData as Gt, CopyMarkdown as H, CollectionsData as Ht, usePost as I, ViteReactSSG as It, Sidebar$1 as J, LayoutProps as Jt, OnThisPage as K, CollectionPostLoaderData as Kt, usePosts as L, BoltdocsShell as Lt, TimelineBadgeConfig as M, useTheme as Mt, TimelineItemProps as N, useConfig as Nt, getTranslated as O, useSidebar as Ot, TimelineProps as P, formatDeterministicDate as Pt, SidebarHeader as Q, SiteConfig as Qt, useRecentPosts as R, MdxPage as Rt, WebSiteStructuredDataOptions as S, useBreadcrumbs as St, createStructuredData as T, useVersion as Tt, ErrorBoundary as U, CurrentPostProvider as Ut, SearchDialog as V, CollectionsContext as Vt, PageNav as W, BoltdocsTab as Wt, SidebarGroup as X, OnThisPageProps as Xt, SidebarContent as Y, NavbarLink as Yt, SidebarGroupRenderProps as Z, SidebarProps$1 as Zt, StructuredData as _, useTrackEvent as _t, useExpandable as a, SidebarLinkProps as at, BreadcrumbStructuredDataItem as b, useLocalizedTo as bt, getStarsRepo as c, SidebarSlots as ct, ViewTransitionHandle as d, Navbar as dt, SidebarItemProps as et, ViewTransitionOptions as f, DocsLayoutComponent as ft, useViewTransition as g, useAnalytics as gt, startViewTransition as h, useHeadings as ht, UseExpandableOptions as i, SidebarLink as it, Timeline as j, useMdxComponents as jt, resolvePublicAssetUrl as k, useNavbar as kt, copyToClipboard as l, SidebarSubGroup as lt, ViewTransitionUpdate as m, useMergedComponents as mt, UseCodeBlockFeedbackOptions as n, SidebarItems$1 as nt, useCopyButton as o, SidebarMobile as ot, ViewTransitionRunner as p, useFeedback as pt, Sidebar as q, ComponentRoute as qt, useCodeBlockFeedback as r, SidebarItemsProps as rt, useCodeBlock as s, SidebarRoot as st, CodeBlockFeedbackPayload as t, SidebarItemRenderProps as tt, reactToText as u, ComponentBase as ut, StructuredDataProps as v, useTrackPageView as vt, createBreadcrumbStructuredData as w, useI18n as wt, StructuredDataFactoryOptions as x, useRoutes as xt, ArticleStructuredDataOptions as y, useSearchHighlight as yt, Banner as z, createRoutes as zt };
|