@veluai/velu 0.2.30 → 0.2.32
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/cli.js +30 -30
- package/package.json +1 -1
- package/runtime/velu-ui/components/Chatbot.jsx +12 -3
- package/runtime/velu-ui/components/CodeBlock.jsx +32 -9
- package/runtime/velu-ui/components/Icon.jsx +64 -0
- package/runtime/velu-ui/components/Image.jsx +1 -1
- package/runtime/velu-ui/components/code-block.css +8 -0
- package/runtime/velu-ui/components/icon.css +9 -0
- package/runtime/velu-ui/components/image.css +11 -4
- package/runtime/velu-ui/index.js +1 -0
- package/runtime/velu-ui/lib/component-schemas.js +1 -0
- package/runtime/velu-ui/mdx-components.jsx +15 -6
- package/runtime/velu-ui/styles.css +1 -0
- package/src/lib/known-components.js +1 -0
- package/src/runtime/App.jsx +31 -1
package/dist/cli.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`,"utf-8");let o=await
|
|
4
|
-
New velu version available: ${e} \u2192 ${t}. Updating\u2026`),!
|
|
5
|
-
`);let r=
|
|
6
|
-
`)}function ae(e){if(!e||typeof e!="object")return null;let t=[];if(e.socials&&typeof e.socials=="object")for(let[r,o]of Object.entries(e.socials))typeof o!="string"||!o.trim()||t.push({kind:cr[r]??r,href:o.trim()});let n=Array.isArray(e.links)?e.links.filter(r=>r&&typeof r=="object").map(r=>({title:(r.header??r.title??"").trim(),items:(Array.isArray(r.items)?r.items:[]).filter(o=>o&&o.label).map(o=>({label:o.label,href:o.href??"#"}))})).filter(r=>r.title||r.items.length):[];return!t.length&&!n.length?null:{socials:t,links:n}}function Ye(e){return/^(https?:)?\/\//.test(e)||/^(mailto|tel):/.test(e)}function le(e){if(!e||typeof e!="object")return null;let t=(Array.isArray(e.links)?e.links:[]).filter(o=>o&&typeof o.href=="string"&&o.href.trim()).map(o=>({label:o.label??"",href:o.href.trim(),icon:o.icon??null,external:Ye(o.href.trim())})),n=null,r=e.primary;if(r&&typeof r=="object"&&typeof r.href=="string"&&r.href.trim()){let o=r.href.trim();n=r.type==="github"?{kind:"github",label:r.label??"GitHub",href:o,external:Ye(o)}:{kind:"button",label:r.label??"",href:o,external:Ye(o)}}return!t.length&&!n?null:{links:t,primary:n}}function Ke(e){if(e==null)return{options:[...Ut],display:"header"};if(typeof e!="object")return{options:[],display:"header"};let t=e.display==="toc"?"toc":"header",n=Array.isArray(e.options)?e.options:Ut,r=[];for(let o of n)typeof o=="string"?ur.has(o)&&r.push(o):o&&typeof o=="object"&&o.title&&o.href&&r.push({title:String(o.title),description:o.description?String(o.description):"",href:String(o.href),icon:typeof o.icon=="string"?o.icon:void 0});return{options:r,display:t}}function z(e){if(!e||typeof e!="object")return{server:null,proxy:!0,languages:void 0};let t=e.playground||{};return{server:typeof e.server=="string"?e.server.trim():null,proxy:t.proxy!==!1&&t.display!=="none",languages:Array.isArray(e.examples?.languages)?e.examples.languages:void 0}}function ce(e){if(!e||typeof e!="object")return null;let t=typeof e.apiBase=="string"&&e.apiBase.trim()?e.apiBase.trim().replace(/\/+$/,""):null,n=typeof e.host=="string"&&e.host.trim()?e.host.trim():null,r=Array.isArray(e.suggestions)?e.suggestions.filter(o=>typeof o=="string"&&o.trim()).map(o=>o.trim()).slice(0,6):[];return!t&&!r.length?null:{apiBase:t,host:n,suggestions:r}}var cr,ur,Ut,ke=A(()=>{cr={twitter:"x","x-twitter":"x"};ur=new Set(["copy","assistant","view","download-pdf","download-spec","chatgpt","claude","perplexity","grok","aistudio","devin","windsurf","mcp","add-mcp","cursor","vscode","devin-mcp"]),Ut=["copy","view","chatgpt","claude"]});import pr from"node:fs/promises";import Ze from"node:path";function Ft(e){if(!e.favicon)return null;let t=Ze.extname(e.favicon).toLowerCase();return{url:Qe+t,type:dr[t]||""}}function ue(e){if(typeof e=="string"){let t=e.trim();return t?{light:t,dark:t,href:"/"}:null}if(e&&typeof e=="object"){let t=(e.light??e.dark)?.trim?.(),n=(e.dark??e.light)?.trim?.();return!t||!n?null:{light:t,dark:n,href:e.href?.trim?.()||"/"}}return null}function gr(e){return!e||typeof e!="object"?{metatags:{},indexing:"navigable"}:{metatags:e.metatags&&typeof e.metatags=="object"?e.metatags:{},indexing:e.indexing==="all"?"all":"navigable"}}function et(e={},t){let n=e.colors?.primary??fr;return{name:e.name??t??"docs",url:typeof process.env.VELU_SITE_URL=="string"&&process.env.VELU_SITE_URL.trim()?process.env.VELU_SITE_URL.trim().replace(/\/+$/,""):null,seo:gr(e.seo),assistant:ce(e.assistant),thumbnails:e.thumbnails&&typeof e.thumbnails=="object"&&typeof e.thumbnails.background=="string"?{background:e.thumbnails.background}:null,colors:{primary:n,light:e.colors?.light??n,dark:e.colors?.dark??n},favicon:e.favicon??null,api:z(e.api),logo:ue(e.logo),footer:ae(e.footer),navbar:le(e.navbar),font:{family:e.font?.family??mr},navigation:e.navigation??null}}async function Nt(e){let t=Ze.join(e,"velu.json"),n;try{n=await pr.readFile(t,"utf-8")}catch(o){throw o.code==="ENOENT"?new Error(`No velu.json found in ${e}. Run \`velu init <name>\` to scaffold one.`):o}let r;try{r=JSON.parse(n)}catch(o){throw new Error(`velu.json is not valid JSON: ${o.message}`)}return et(r,Ze.basename(e))}function Rt(e){let{colors:t,font:n}=e;return Xe({light:t.light,dark:t.dark,family:n.family})}var fr,mr,Ae,je,Qe,dr,pe=A(()=>{ke();ke();fr="#dc143c",mr="Google Sans Flex",Ae="/@velu-logo-light",je="/@velu-logo-dark",Qe="/@velu-favicon",dr={".svg":"image/svg+xml",".ico":"image/x-icon",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif"}});import{visit as It}from"unist-util-visit";import{toString as hr}from"mdast-util-to-string";import yr from"github-slugger";import{valueToEstree as vr}from"estree-util-value-to-estree";function br(e){return`update-${String(e||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"item"}`}function Mt(e,t){let n=(e.attributes||[]).find(r=>r&&r.type==="mdxJsxAttribute"&&r.name===t);if(n)return typeof n.value=="string"?n.value:void 0}function xr(e){let t=(e.attributes||[]).find(l=>l&&l.type==="mdxJsxAttribute"&&l.name==="tags");if(!t)return[];if(typeof t.value=="string")return[t.value];let n=t.value&&t.value.value?String(t.value.value):"",r=[],o=/["'`]([^"'`]+)["'`]/g,i;for(;i=o.exec(n);)r.push(i[1]);return r}function fe(){return e=>{let t=new yr,n=[];It(e,"heading",a=>{let p=hr(a);n.push({depth:a.depth,id:t.slug(p),label:p})});let r=[],o=[],i=new Set;if(It(e,"mdxJsxFlowElement",a=>{if(a.name!=="Update")return;let p=Mt(a,"label")??Mt(a,"date");p&&r.push({id:br(p),label:p});for(let c of xr(a)){let u=c.trim().toLowerCase();c.trim()&&!i.has(u)&&(i.add(u),o.push(c.trim()))}}),r.length){zt(e,r),Bt(e,"changelog",{tags:o});return}let l={children:[]},s=[{node:l,depth:0}];for(let a of n){for(;s.length>1&&s[s.length-1].depth>=a.depth;)s.pop();let p={id:a.id,label:a.label},c=s[s.length-1].node;c.children||(c.children=[]),c.children.push(p),s.push({node:p,depth:a.depth})}zt(e,l.children)}}function zt(e,t){Bt(e,"toc",t)}function Bt(e,t,n){e.children.unshift({type:"mdxjsEsm",value:"",data:{estree:{type:"Program",sourceType:"module",body:[{type:"ExportNamedDeclaration",specifiers:[],declaration:{type:"VariableDeclaration",kind:"const",declarations:[{type:"VariableDeclarator",id:{type:"Identifier",name:t},init:vr(n)}]}}]}}})}var tt=A(()=>{});import $r from"github-slugger";import wr from"iso-639-1";function kr(e){let t=String(e).toLowerCase();return wr.getNativeName(t)||e}function Te(e){return new $r().slug(String(e??""))}function Ar(e){let t=String(e).replace(/^\/+|\/+$/g,"").split("/").filter(Boolean);return t[t.length-1]==="index"&&t.pop(),"/"+t.join("/")}function Vt(e){let t=String(e).split("#")[0].split("?")[0];try{t=decodeURI(t)}catch{}return t.startsWith("/")||(t="/"+t),t.length>1&&(t=t.replace(/\/+$/,"")),t||"/"}function G(e){let t={kind:"root",children:me(e??{})};return Ht(t.children),t}function me(e){let t=Array.isArray(e.anchors)?e.anchors.map(_r):[];if(Array.isArray(e.products))return[...t,...e.products.map(jr)];if(Array.isArray(e.versions))return[...t,...e.versions.map(Tr)];if(Array.isArray(e.languages))return[...t,...e.languages.map(Lr)];if(Array.isArray(e.tabs))return[...t,...e.tabs.map(Or)];let n=[...t];return Array.isArray(e.groups)&&n.push(...e.groups.map(Gt)),Array.isArray(e.pages)&&n.push(...e.pages.map(Jt)),n}function jr(e){return{kind:"product",label:e.name??e.product,slug:Te(e.product),icon:e.icon,color:e.color,default:!!e.default,children:me(e)}}function Tr(e){return{kind:"version",label:e.version,slug:Te(e.version),default:!!e.default,children:me(e)}}function Lr(e){let t=String(e.language);return{kind:"language",code:t,label:kr(t),slug:Te(t),default:!!e.default,children:me(e)}}function Or(e){return{kind:"tab",label:e.tab,slug:Te(e.tab),icon:e.icon,href:e.href,children:me(e)}}function _r(e){return{kind:"anchor",label:e.anchor,icon:e.icon,href:e.href,color:e.color}}function Gt(e){let t=(e.pages??[]).map(Jt);return e.root&&t.unshift({kind:"page",pagePath:e.root}),{kind:"group",label:e.group,icon:e.icon,expanded:!!e.expanded,root:e.root,children:t}}function Jt(e){return typeof e=="string"?{kind:"page",pagePath:e}:e&&e.apiPage?{kind:"page",pagePath:e.apiPage,label:e.label,method:e.method,api:!0}:Gt(e)}function Ht(e){for(let t of Sr){let n=e.filter(r=>r.kind===t);n.length&&!n.some(r=>r.default)&&(n[0].default=!0)}for(let t of e)t.children&&Ht(t.children)}function ee(e){let t=[],n=(r,o,i)=>{if(r.kind==="page"){t.push({pagePath:r.pagePath,url:Er(r.pagePath,o),ctx:{...o},ancestors:i,node:r});return}let l=o;r.kind==="product"?l={...o,product:r.default?null:r.slug}:r.kind==="version"?l={...o,version:r.default?null:r.slug}:r.kind==="language"&&(l={...o,language:r.default?null:r.slug});let s=r.kind==="root"?i:[...i,r];for(let a of r.children??[])n(a,l,s)};return n(e,{product:null,version:null,language:null},[]),t}function Er(e,t){let n=[t.product,t.version,t.language].filter(Boolean),r=Ar(e).split("/").filter(Boolean);return"/"+[...n,...r].join("/")}var Sr,H=A(()=>{Sr=["product","version","language"]});import Pr from"node:fs";import Dt from"node:path";function J(e,t){let n=[],r=[],o=new Set;for(let i of ee(e)){if(i.node?.api){o.add(i.url);continue}if(o.has(i.url)){n.push(`duplicate URL "${i.url}" (page "${i.pagePath}") \u2014 keeping the first occurrence`);continue}o.add(i.url);let l=i.pagePath.replace(/^\/+|\/+$/g,""),s=Dt.join(t,...l.split("/"))+".mdx",a=Pr.existsSync(s);a||n.push(`page "${i.pagePath}" \u2192 ${Dt.relative(t,s)} not found`),r.push({pagePath:i.pagePath,url:i.url,fileAbsPath:s,exists:a})}return{pageEntries:r,warnings:n}}var de=A(()=>{H()});function D(e){return!e||typeof e!="object"?e||{}:Array.isArray(e.allOf)?e.allOf.reduce((t,n)=>{let r=D(n);return{...t,...r,properties:{...t.properties||{},...r.properties||{}},required:[...t.required||[],...r.required||[]]}},{...e,allOf:void 0}):Array.isArray(e.oneOf)&&e.oneOf.length?D(e.oneOf[0]):Array.isArray(e.anyOf)&&e.anyOf.length?D(e.anyOf[0]):e}function ge(e){let t=D(e);if(!t||typeof t!="object")return"any";if(Array.isArray(t.enum)&&t.enum.length)return`enum<${typeof t.enum[0]}>`;if(t.type==="array")return`${ge(t.items||{})}[]`;let n=t.type||(t.properties?"object":"any");return t.format?`${n}<${t.format}>`:n}function te(e,t=0){let n=D(e);if(!n||typeof n!="object")return null;if(n.example!==void 0)return n.example;if(n.default!==void 0)return n.default;if(Array.isArray(n.enum)&&n.enum.length)return n.enum[0];if(t>=6)return n.type==="object"?{}:null;switch(n.type){case"object":{let r={};for(let[o,i]of Object.entries(n.properties||{}))r[o]=te(i,t+1);return r}case"array":return[te(n.items||{},t+1)];case"integer":case"number":return 0;case"boolean":return!0;default:return Ur(n)}}function Ur(e){switch(e.format){case"date-time":return"2024-01-01T00:00:00Z";case"date":return"2024-01-01";case"email":return"user@example.com";case"uuid":return"3fa85f64-5717-4562-b3fc-2c963f66afa6";case"uri":case"url":return"https://example.com";default:return"<string>"}}function nt(e){let t=D(e);if(!t||t.type!=="object"||!t.properties)return t&&(t.type||t.items)?[{name:"body",type:ge(t),required:!1,description:t.description||""}]:[];let n=new Set(t.required||[]);return Object.entries(t.properties).map(([r,o])=>{let i=D(o);return{name:r,type:ge(i),required:n.has(r),description:i.description||"",enum:Array.isArray(i.enum)?i.enum:void 0,deprecated:i.deprecated||void 0}})}function Fr(e){let t=e.schema||{};return{name:e.name,in:e.in,required:e.in==="path"?!0:!!e.required,type:ge(t),description:e.description||"",enum:Array.isArray(t.enum)?t.enum:void 0,example:te(t),deprecated:e.deprecated||void 0}}function Wt(e){if(!e||typeof e!="object")return null;let t=Object.keys(e),n=t.find(r=>/json/i.test(r))||t[0];return n?{contentType:n,media:e[n]}:null}function Nr(e){if(!e)return null;let t=Wt(e.content);if(!t)return null;let n=t.media.schema||{};return{required:!!e.required,description:e.description||"",contentType:t.contentType,fields:nt(n),example:t.media.example??te(n)}}function Rr(e){return!e||typeof e!="object"?[]:Object.entries(e).map(([t,n])=>{let r=Wt(n?.content),o=r?.media?.schema||{};return{status:t,description:n?.description||"",contentType:r?.contentType||null,fields:r?nt(o):[],example:r?r.media.example??te(o):null}})}function Ir(e,t){if(!Array.isArray(e)||!t)return[];let n=[],r=new Set;for(let o of e)for(let i of Object.keys(o||{})){let l=t[i];!l||r.has(i)||(r.add(i),n.push(Mr(i,l)))}return n.filter(Boolean)}function Mr(e,t){return t.type==="http"&&/bearer/i.test(t.scheme||"")?{name:"Authorization",in:"header",required:!0,type:"string",prefix:"Bearer",description:t.description||"Bearer authentication token."}:t.type==="http"&&/basic/i.test(t.scheme||"")?{name:"Authorization",in:"header",required:!0,type:"string",prefix:"Basic",description:t.description||"Basic authentication credentials."}:t.type==="apiKey"?{name:t.name||e,in:t.in||"header",required:!0,type:"string",description:t.description||"API key."}:t.type==="oauth2"||t.type==="openIdConnect"?{name:"Authorization",in:"header",required:!0,type:"string",prefix:"Bearer",description:t.description||"OAuth 2.0 access token."}:{name:e,in:"header",required:!0,type:"string",description:t.description||""}}function qt(e){return String(e).replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function zr(e){let{method:t,path:n,op:r,sharedParams:o,servers:i,schemes:l}=e,s=[...o||[],...r.parameters||[]],a={path:[],query:[],header:[],cookie:[]};for(let c of s)c&&a[c.in]&&a[c.in].push(Fr(c));let p=r.security??e.globalSecurity;return{id:r.operationId?qt(r.operationId):`${t}-${qt(n)}`,method:t.toUpperCase(),path:n,title:r.summary||r.operationId||`${t.toUpperCase()} ${n}`,description:r.description||r.summary||"",tags:Array.isArray(r.tags)&&r.tags.length?r.tags:["API"],deprecated:r.deprecated||!1,auth:Ir(p,l),parameters:a,body:Nr(r.requestBody),responses:Rr(r.responses),servers:(i||[]).map(c=>c.url).filter(Boolean)}}function Br(e,t,n,r,o,i,l){let s={};e.openapi?s.openapi=e.openapi:e.swagger?s.swagger=e.swagger:s.openapi="3.0.0",s.info=e.info||{title:"API Reference",version:"1.0.0"};let a=(r.servers||i||[]).filter(Boolean);a.length&&(s.servers=a);let p={};Array.isArray(o)&&o.length&&(p.parameters=o),p[n]=r,s.paths={[t]:p};let c=r.security??e.security;if(l&&Array.isArray(c)&&c.length){let u={};for(let y of c)for(let f of Object.keys(y||{}))l[f]&&(u[f]=l[f]);Object.keys(u).length&&(e.swagger?s.securityDefinitions=u:s.components={securitySchemes:u})}return s}function Yt(e){let t=[],n=[],r=e.components?.securitySchemes||e.securityDefinitions||{},o=e.security||[],i=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]);for(let[l,s]of Object.entries(e.paths||{})){if(!s||typeof s!="object")continue;let a=s.parameters||[],p=s.servers||i;for(let c of Cr){let u=s[c];!u||typeof u!="object"||(t.push(zr({method:c,path:l,op:u,sharedParams:a,servers:u.servers||p,globalSecurity:o,schemes:r})),n.push(Br(e,l,c,u,a,u.servers||p,r)))}}return{operations:t,segments:n}}function rt(e){let t=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]),{operations:n,segments:r}=Yt(e);return{title:e.info?.title||"API Reference",version:e.info?.version||"",servers:t.map(o=>o.url).filter(Boolean),operations:n,segments:r}}var Cr,ot=A(()=>{Cr=["get","post","put","patch","delete","options","head","trace"]});import Vr from"@apidevtools/swagger-parser";async function Gr(e){return Vr.dereference(e)}async function Xt(e){return rt(await Gr(e))}var Kt=A(()=>{ot();ot()});function Jr(e,{server:t}={}){let r=`${(t||e.servers?.[0]||"").replace(/\/+$/,"")}${e.path}`,o={};for(let l of e.auth||[])l.in==="header"&&(o[l.name]=l.prefix?`${l.prefix} <token>`:"<token>");for(let l of e.parameters?.header||[])o[l.name]||(o[l.name]=String(l.example??`<${l.type}>`));let i=!!e.body;return i&&(o["Content-Type"]=e.body.contentType||"application/json"),{method:e.method,url:r,headers:o,body:i?e.body.example??{}:null}}function Hr(e){let t=`curl --request ${e.method} \\
|
|
2
|
+
var Dn=Object.defineProperty;var A=(e,t)=>()=>(e&&(t=e(e=0)),t);var we=(e,t)=>{for(var n in t)Dn(e,n,{get:t[n],enumerable:!0})};var Tt={};we(Tt,{initProject:()=>Xn});import Z from"node:fs/promises";import Q from"node:path";import{fileURLToPath as qn}from"node:url";async function Xn(e,t){try{if((await Z.readdir(e)).length>0)throw new Error(`Directory "${t}" already exists and is not empty. Choose a different name or remove the folder first.`)}catch(i){if(i.code!=="ENOENT")throw i}await Z.mkdir(e,{recursive:!0}),await Z.cp(Yn,e,{recursive:!0});let n=Q.join(e,"velu.json"),r=JSON.parse(await Z.readFile(n,"utf-8"));r.name=t,await Z.writeFile(n,JSON.stringify(r,null,2)+`
|
|
3
|
+
`,"utf-8");let o=await jt(e);console.log(`[velu] created ${t}/`);for(let i of o)console.log(` ${i}`);console.log(""),console.log("Next steps:"),console.log(` cd ${t}`),console.log(" velu dev")}async function jt(e,t=e,n=[]){let r=await Z.readdir(e,{withFileTypes:!0});for(let o of r){let i=Q.join(e,o.name);o.isDirectory()?await jt(i,t,n):n.push(Q.relative(t,i).split(Q.sep).join("/"))}return n.sort()}var Wn,Yn,Lt=A(()=>{Wn=Q.dirname(qn(import.meta.url)),Yn=Q.resolve(Wn,"..","templates","starter")});var qe={};we(qe,{currentVersion:()=>Je,getLatestVersion:()=>De,isNewer:()=>He,maybeAutoUpdate:()=>ur,updateCommand:()=>cr});import{spawnSync as _t}from"node:child_process";import{readFileSync as Et,writeFileSync as Kn,mkdirSync as Zn}from"node:fs";import{fileURLToPath as Qn}from"node:url";import{homedir as er,tmpdir as tr}from"node:os";import Ge from"node:path";import I from"node:process";function Je(){try{return JSON.parse(Et(new URL("../package.json",import.meta.url),"utf8")).version}catch{return"unknown"}}function ir(e,t){let n=i=>String(i).split("-")[0].split(".").map(l=>Number(l)||0),r=n(e),o=n(t);for(let i=0;i<3;i++){let l=(r[i]||0)-(o[i]||0);if(l!==0)return l<0?-1:1}return 0}function He(e,t){return!e||!t||t==="unknown"?!1:ir(e,t)>0}function Pt(){let e=Ge.join(er()||tr(),".velu");return Ge.join(e,"update-check.json")}function Ot(){try{return JSON.parse(Et(Pt(),"utf8"))}catch{return null}}function sr(e){try{let t=Pt();Zn(Ge.dirname(t),{recursive:!0}),Kn(t,JSON.stringify(e))}catch{}}async function ar(){let e=`${nr}/-/package/${Se}/dist-tags`,t=new AbortController,n=setTimeout(()=>t.abort(),or);try{let r=await fetch(e,{signal:t.signal,headers:{accept:"application/json"}});if(!r.ok)return null;let o=await r.json();return o&&typeof o.latest=="string"?o.latest:null}catch{return null}finally{clearTimeout(n)}}async function De({force:e=!1}={}){if(!e){let n=Ot();if(n?.latest&&Date.now()-(n.checkedAt||0)<rr)return n.latest}let t=await ar();return t?(sr({latest:t,checkedAt:Date.now()}),t):Ot()?.latest??null}function Ct(){let e=I.env.npm_config_user_agent||"";if(e.startsWith("pnpm"))return"pnpm";if(e.startsWith("yarn"))return"yarn";if(e.startsWith("bun"))return"bun";let t="";try{t=Qn(import.meta.url).replace(/\\/g,"/")}catch{}return t.includes("/pnpm/")?"pnpm":t.includes("/yarn/")||t.includes("/.yarn/")?"yarn":t.includes("/.bun/")?"bun":"npm"}function lr(e){let t=`${Se}@latest`;switch(e){case"pnpm":return["pnpm",["add","-g",t]];case"yarn":return["yarn",["global","add",t]];case"bun":return["bun",["add","-g",t]];default:return["npm",["install","-g",t]]}}function Ut(e){let[t,n]=lr(e);return _t(t,n,{stdio:"inherit",shell:I.platform==="win32"}).status===0}async function cr(){let e=Je(),t=await De({force:!0});if(t&&!He(t,e)){console.log(`velu is already up to date (v${e}).`);return}let n=Ct();console.log(t?`Updating velu ${e} \u2192 ${t} (via ${n})\u2026`:`Could not reach the npm registry; installing ${Se}@latest (via ${n}) anyway\u2026`),Ut(n)?console.log('\u2713 Updated. Run "velu version" to confirm.'):(console.error("Update failed. You can update manually with:"),console.error(` npm install -g ${Se}@latest`),I.exitCode=1)}async function ur(){if(I.env.VELU_NO_UPDATE==="1"||I.env.VELU_UPDATED==="1"||!I.stdout.isTTY)return;let e=Je();if(e==="unknown")return;let t=null;try{t=await De()}catch{return}if(!He(t,e))return;let n=Ct();if(console.log(`
|
|
4
|
+
New velu version available: ${e} \u2192 ${t}. Updating\u2026`),!Ut(n)){console.log("Auto-update failed; continuing on the current version. Run `velu update` to retry.\n");return}console.log(`Restarting on the new version\u2026
|
|
5
|
+
`);let r=_t(I.execPath,I.argv.slice(1),{stdio:"inherit",env:{...I.env,VELU_UPDATED:"1"}});I.exit(r.status??0)}var Se,nr,rr,or,We=A(()=>{Se="@veluai/velu",nr="https://registry.npmjs.org",rr=720*60*1e3,or=3e3});function Xe({light:e,dark:t,family:n}){return[":root:root {",` --accent-color: ${e};`,` --font-sans: "${n}", sans-serif;`,"}",':root:root[data-theme="dark"] {',` --accent-color: ${t};`,"}"].join(`
|
|
6
|
+
`)}function ae(e){if(!e||typeof e!="object")return null;let t=[];if(e.socials&&typeof e.socials=="object")for(let[r,o]of Object.entries(e.socials))typeof o!="string"||!o.trim()||t.push({kind:pr[r]??r,href:o.trim()});let n=Array.isArray(e.links)?e.links.filter(r=>r&&typeof r=="object").map(r=>({title:(r.header??r.title??"").trim(),items:(Array.isArray(r.items)?r.items:[]).filter(o=>o&&o.label).map(o=>({label:o.label,href:o.href??"#"}))})).filter(r=>r.title||r.items.length):[];return!t.length&&!n.length?null:{socials:t,links:n}}function Ye(e){return/^(https?:)?\/\//.test(e)||/^(mailto|tel):/.test(e)}function le(e){if(!e||typeof e!="object")return null;let t=(Array.isArray(e.links)?e.links:[]).filter(o=>o&&typeof o.href=="string"&&o.href.trim()).map(o=>({label:o.label??"",href:o.href.trim(),icon:o.icon??null,external:Ye(o.href.trim())})),n=null,r=e.primary;if(r&&typeof r=="object"&&typeof r.href=="string"&&r.href.trim()){let o=r.href.trim();n=r.type==="github"?{kind:"github",label:r.label??"GitHub",href:o,external:Ye(o)}:{kind:"button",label:r.label??"",href:o,external:Ye(o)}}return!t.length&&!n?null:{links:t,primary:n}}function Ke(e){if(e==null)return{options:[...Ft],display:"header"};if(typeof e!="object")return{options:[],display:"header"};let t=e.display==="toc"?"toc":"header",n=Array.isArray(e.options)?e.options:Ft,r=[];for(let o of n)typeof o=="string"?fr.has(o)&&r.push(o):o&&typeof o=="object"&&o.title&&o.href&&r.push({title:String(o.title),description:o.description?String(o.description):"",href:String(o.href),icon:typeof o.icon=="string"?o.icon:void 0});return{options:r,display:t}}function z(e){if(!e||typeof e!="object")return{server:null,proxy:!0,languages:void 0};let t=e.playground||{};return{server:typeof e.server=="string"?e.server.trim():null,proxy:t.proxy!==!1&&t.display!=="none",languages:Array.isArray(e.examples?.languages)?e.examples.languages:void 0}}function ce(e){if(!e||typeof e!="object")return null;let t=typeof e.apiBase=="string"&&e.apiBase.trim()?e.apiBase.trim().replace(/\/+$/,""):null,n=typeof e.host=="string"&&e.host.trim()?e.host.trim():null,r=Array.isArray(e.suggestions)?e.suggestions.filter(o=>typeof o=="string"&&o.trim()).map(o=>o.trim()).slice(0,6):[];return!t&&!r.length?null:{apiBase:t,host:n,suggestions:r}}var pr,fr,Ft,ke=A(()=>{pr={twitter:"x","x-twitter":"x"};fr=new Set(["copy","assistant","view","download-pdf","download-spec","chatgpt","claude","perplexity","grok","aistudio","devin","windsurf","mcp","add-mcp","cursor","vscode","devin-mcp"]),Ft=["copy","view","chatgpt","claude"]});import mr from"node:fs/promises";import Ze from"node:path";function Nt(e){if(!e.favicon)return null;let t=Ze.extname(e.favicon).toLowerCase();return{url:Qe+t,type:hr[t]||""}}function ue(e){if(typeof e=="string"){let t=e.trim();return t?{light:t,dark:t,href:"/"}:null}if(e&&typeof e=="object"){let t=(e.light??e.dark)?.trim?.(),n=(e.dark??e.light)?.trim?.();return!t||!n?null:{light:t,dark:n,href:e.href?.trim?.()||"/"}}return null}function yr(e){return!e||typeof e!="object"?{metatags:{},indexing:"navigable"}:{metatags:e.metatags&&typeof e.metatags=="object"?e.metatags:{},indexing:e.indexing==="all"?"all":"navigable"}}function et(e={},t){let n=e.colors?.primary??dr;return{name:e.name??t??"docs",url:typeof process.env.VELU_SITE_URL=="string"&&process.env.VELU_SITE_URL.trim()?process.env.VELU_SITE_URL.trim().replace(/\/+$/,""):null,seo:yr(e.seo),assistant:ce(e.assistant),thumbnails:e.thumbnails&&typeof e.thumbnails=="object"&&typeof e.thumbnails.background=="string"?{background:e.thumbnails.background}:null,colors:{primary:n,light:e.colors?.light??n,dark:e.colors?.dark??n},favicon:e.favicon??null,api:z(e.api),logo:ue(e.logo),footer:ae(e.footer),navbar:le(e.navbar),font:{family:e.font?.family??gr},navigation:e.navigation??null}}async function Rt(e){let t=Ze.join(e,"velu.json"),n;try{n=await mr.readFile(t,"utf-8")}catch(o){throw o.code==="ENOENT"?new Error(`No velu.json found in ${e}. Run \`velu init <name>\` to scaffold one.`):o}let r;try{r=JSON.parse(n)}catch(o){throw new Error(`velu.json is not valid JSON: ${o.message}`)}return et(r,Ze.basename(e))}function It(e){let{colors:t,font:n}=e;return Xe({light:t.light,dark:t.dark,family:n.family})}var dr,gr,Ae,je,Qe,hr,pe=A(()=>{ke();ke();dr="#dc143c",gr="Google Sans Flex",Ae="/@velu-logo-light",je="/@velu-logo-dark",Qe="/@velu-favicon",hr={".svg":"image/svg+xml",".ico":"image/x-icon",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif"}});import{visit as Mt}from"unist-util-visit";import{toString as vr}from"mdast-util-to-string";import br from"github-slugger";import{valueToEstree as xr}from"estree-util-value-to-estree";function $r(e){return`update-${String(e||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"item"}`}function zt(e,t){let n=(e.attributes||[]).find(r=>r&&r.type==="mdxJsxAttribute"&&r.name===t);if(n)return typeof n.value=="string"?n.value:void 0}function wr(e){let t=(e.attributes||[]).find(l=>l&&l.type==="mdxJsxAttribute"&&l.name==="tags");if(!t)return[];if(typeof t.value=="string")return[t.value];let n=t.value&&t.value.value?String(t.value.value):"",r=[],o=/["'`]([^"'`]+)["'`]/g,i;for(;i=o.exec(n);)r.push(i[1]);return r}function fe(){return e=>{let t=new br,n=[];Mt(e,"heading",a=>{let p=vr(a);n.push({depth:a.depth,id:t.slug(p),label:p})});let r=[],o=[],i=new Set;if(Mt(e,"mdxJsxFlowElement",a=>{if(a.name!=="Update")return;let p=zt(a,"label")??zt(a,"date");p&&r.push({id:$r(p),label:p});for(let c of wr(a)){let u=c.trim().toLowerCase();c.trim()&&!i.has(u)&&(i.add(u),o.push(c.trim()))}}),r.length){Bt(e,r),Vt(e,"changelog",{tags:o});return}let l={children:[]},s=[{node:l,depth:0}];for(let a of n){for(;s.length>1&&s[s.length-1].depth>=a.depth;)s.pop();let p={id:a.id,label:a.label},c=s[s.length-1].node;c.children||(c.children=[]),c.children.push(p),s.push({node:p,depth:a.depth})}Bt(e,l.children)}}function Bt(e,t){Vt(e,"toc",t)}function Vt(e,t,n){e.children.unshift({type:"mdxjsEsm",value:"",data:{estree:{type:"Program",sourceType:"module",body:[{type:"ExportNamedDeclaration",specifiers:[],declaration:{type:"VariableDeclaration",kind:"const",declarations:[{type:"VariableDeclarator",id:{type:"Identifier",name:t},init:xr(n)}]}}]}}})}var tt=A(()=>{});import{visit as Sr}from"unist-util-visit";function nt(){return e=>{Sr(e,"code",t=>{let n=(t.meta||"").trim();if(!n)return;let r={},o=n.match(/\btitle="([^"]*)"/);o&&(r["data-title"]=o[1],n=(n.slice(0,o.index)+n.slice(o.index+o[0].length)).trim());let i=n.match(/\{([\d,\s-]+)\}/);i&&(r["data-highlight"]=i[1].replace(/\s+/g,""),n=(n.slice(0,i.index)+n.slice(i.index+i[0].length)).trim()),n=n.replace(/\blineNumbers\b/,()=>(r["data-line-numbers"]="","")).trim(),n&&(r["data-filename"]=n),Object.keys(r).length&&(t.data=t.data||{},t.data.hProperties={...t.data.hProperties||{},...r})})}}var Gt=A(()=>{});import kr from"github-slugger";import Ar from"iso-639-1";function Tr(e){let t=String(e).toLowerCase();return Ar.getNativeName(t)||e}function Te(e){return new kr().slug(String(e??""))}function Lr(e){let t=String(e).replace(/^\/+|\/+$/g,"").split("/").filter(Boolean);return t[t.length-1]==="index"&&t.pop(),"/"+t.join("/")}function Jt(e){let t=String(e).split("#")[0].split("?")[0];try{t=decodeURI(t)}catch{}return t.startsWith("/")||(t="/"+t),t.length>1&&(t=t.replace(/\/+$/,"")),t||"/"}function G(e){let t={kind:"root",children:me(e??{})};return qt(t.children),t}function me(e){let t=Array.isArray(e.anchors)?e.anchors.map(Cr):[];if(Array.isArray(e.products))return[...t,...e.products.map(Or)];if(Array.isArray(e.versions))return[...t,...e.versions.map(_r)];if(Array.isArray(e.languages))return[...t,...e.languages.map(Er)];if(Array.isArray(e.tabs))return[...t,...e.tabs.map(Pr)];let n=[...t];return Array.isArray(e.groups)&&n.push(...e.groups.map(Ht)),Array.isArray(e.pages)&&n.push(...e.pages.map(Dt)),n}function Or(e){return{kind:"product",label:e.name??e.product,slug:Te(e.product),icon:e.icon,color:e.color,default:!!e.default,children:me(e)}}function _r(e){return{kind:"version",label:e.version,slug:Te(e.version),default:!!e.default,children:me(e)}}function Er(e){let t=String(e.language);return{kind:"language",code:t,label:Tr(t),slug:Te(t),default:!!e.default,children:me(e)}}function Pr(e){return{kind:"tab",label:e.tab,slug:Te(e.tab),icon:e.icon,href:e.href,children:me(e)}}function Cr(e){return{kind:"anchor",label:e.anchor,icon:e.icon,href:e.href,color:e.color}}function Ht(e){let t=(e.pages??[]).map(Dt);return e.root&&t.unshift({kind:"page",pagePath:e.root}),{kind:"group",label:e.group,icon:e.icon,expanded:!!e.expanded,root:e.root,children:t}}function Dt(e){return typeof e=="string"?{kind:"page",pagePath:e}:e&&e.apiPage?{kind:"page",pagePath:e.apiPage,label:e.label,method:e.method,api:!0}:Ht(e)}function qt(e){for(let t of jr){let n=e.filter(r=>r.kind===t);n.length&&!n.some(r=>r.default)&&(n[0].default=!0)}for(let t of e)t.children&&qt(t.children)}function ee(e){let t=[],n=(r,o,i)=>{if(r.kind==="page"){t.push({pagePath:r.pagePath,url:Ur(r.pagePath,o),ctx:{...o},ancestors:i,node:r});return}let l=o;r.kind==="product"?l={...o,product:r.default?null:r.slug}:r.kind==="version"?l={...o,version:r.default?null:r.slug}:r.kind==="language"&&(l={...o,language:r.default?null:r.slug});let s=r.kind==="root"?i:[...i,r];for(let a of r.children??[])n(a,l,s)};return n(e,{product:null,version:null,language:null},[]),t}function Ur(e,t){let n=[t.product,t.version,t.language].filter(Boolean),r=Lr(e).split("/").filter(Boolean);return"/"+[...n,...r].join("/")}var jr,H=A(()=>{jr=["product","version","language"]});import Fr from"node:fs";import Wt from"node:path";function J(e,t){let n=[],r=[],o=new Set;for(let i of ee(e)){if(i.node?.api){o.add(i.url);continue}if(o.has(i.url)){n.push(`duplicate URL "${i.url}" (page "${i.pagePath}") \u2014 keeping the first occurrence`);continue}o.add(i.url);let l=i.pagePath.replace(/^\/+|\/+$/g,""),s=Wt.join(t,...l.split("/"))+".mdx",a=Fr.existsSync(s);a||n.push(`page "${i.pagePath}" \u2192 ${Wt.relative(t,s)} not found`),r.push({pagePath:i.pagePath,url:i.url,fileAbsPath:s,exists:a})}return{pageEntries:r,warnings:n}}var de=A(()=>{H()});function D(e){return!e||typeof e!="object"?e||{}:Array.isArray(e.allOf)?e.allOf.reduce((t,n)=>{let r=D(n);return{...t,...r,properties:{...t.properties||{},...r.properties||{}},required:[...t.required||[],...r.required||[]]}},{...e,allOf:void 0}):Array.isArray(e.oneOf)&&e.oneOf.length?D(e.oneOf[0]):Array.isArray(e.anyOf)&&e.anyOf.length?D(e.anyOf[0]):e}function ge(e){let t=D(e);if(!t||typeof t!="object")return"any";if(Array.isArray(t.enum)&&t.enum.length)return`enum<${typeof t.enum[0]}>`;if(t.type==="array")return`${ge(t.items||{})}[]`;let n=t.type||(t.properties?"object":"any");return t.format?`${n}<${t.format}>`:n}function te(e,t=0){let n=D(e);if(!n||typeof n!="object")return null;if(n.example!==void 0)return n.example;if(n.default!==void 0)return n.default;if(Array.isArray(n.enum)&&n.enum.length)return n.enum[0];if(t>=6)return n.type==="object"?{}:null;switch(n.type){case"object":{let r={};for(let[o,i]of Object.entries(n.properties||{}))r[o]=te(i,t+1);return r}case"array":return[te(n.items||{},t+1)];case"integer":case"number":return 0;case"boolean":return!0;default:return Rr(n)}}function Rr(e){switch(e.format){case"date-time":return"2024-01-01T00:00:00Z";case"date":return"2024-01-01";case"email":return"user@example.com";case"uuid":return"3fa85f64-5717-4562-b3fc-2c963f66afa6";case"uri":case"url":return"https://example.com";default:return"<string>"}}function rt(e){let t=D(e);if(!t||t.type!=="object"||!t.properties)return t&&(t.type||t.items)?[{name:"body",type:ge(t),required:!1,description:t.description||""}]:[];let n=new Set(t.required||[]);return Object.entries(t.properties).map(([r,o])=>{let i=D(o);return{name:r,type:ge(i),required:n.has(r),description:i.description||"",enum:Array.isArray(i.enum)?i.enum:void 0,deprecated:i.deprecated||void 0}})}function Ir(e){let t=e.schema||{};return{name:e.name,in:e.in,required:e.in==="path"?!0:!!e.required,type:ge(t),description:e.description||"",enum:Array.isArray(t.enum)?t.enum:void 0,example:te(t),deprecated:e.deprecated||void 0}}function Xt(e){if(!e||typeof e!="object")return null;let t=Object.keys(e),n=t.find(r=>/json/i.test(r))||t[0];return n?{contentType:n,media:e[n]}:null}function Mr(e){if(!e)return null;let t=Xt(e.content);if(!t)return null;let n=t.media.schema||{};return{required:!!e.required,description:e.description||"",contentType:t.contentType,fields:rt(n),example:t.media.example??te(n)}}function zr(e){return!e||typeof e!="object"?[]:Object.entries(e).map(([t,n])=>{let r=Xt(n?.content),o=r?.media?.schema||{};return{status:t,description:n?.description||"",contentType:r?.contentType||null,fields:r?rt(o):[],example:r?r.media.example??te(o):null}})}function Br(e,t){if(!Array.isArray(e)||!t)return[];let n=[],r=new Set;for(let o of e)for(let i of Object.keys(o||{})){let l=t[i];!l||r.has(i)||(r.add(i),n.push(Vr(i,l)))}return n.filter(Boolean)}function Vr(e,t){return t.type==="http"&&/bearer/i.test(t.scheme||"")?{name:"Authorization",in:"header",required:!0,type:"string",prefix:"Bearer",description:t.description||"Bearer authentication token."}:t.type==="http"&&/basic/i.test(t.scheme||"")?{name:"Authorization",in:"header",required:!0,type:"string",prefix:"Basic",description:t.description||"Basic authentication credentials."}:t.type==="apiKey"?{name:t.name||e,in:t.in||"header",required:!0,type:"string",description:t.description||"API key."}:t.type==="oauth2"||t.type==="openIdConnect"?{name:"Authorization",in:"header",required:!0,type:"string",prefix:"Bearer",description:t.description||"OAuth 2.0 access token."}:{name:e,in:"header",required:!0,type:"string",description:t.description||""}}function Yt(e){return String(e).replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function Gr(e){let{method:t,path:n,op:r,sharedParams:o,servers:i,schemes:l}=e,s=[...o||[],...r.parameters||[]],a={path:[],query:[],header:[],cookie:[]};for(let c of s)c&&a[c.in]&&a[c.in].push(Ir(c));let p=r.security??e.globalSecurity;return{id:r.operationId?Yt(r.operationId):`${t}-${Yt(n)}`,method:t.toUpperCase(),path:n,title:r.summary||r.operationId||`${t.toUpperCase()} ${n}`,description:r.description||r.summary||"",tags:Array.isArray(r.tags)&&r.tags.length?r.tags:["API"],deprecated:r.deprecated||!1,auth:Br(p,l),parameters:a,body:Mr(r.requestBody),responses:zr(r.responses),servers:(i||[]).map(c=>c.url).filter(Boolean)}}function Jr(e,t,n,r,o,i,l){let s={};e.openapi?s.openapi=e.openapi:e.swagger?s.swagger=e.swagger:s.openapi="3.0.0",s.info=e.info||{title:"API Reference",version:"1.0.0"};let a=(r.servers||i||[]).filter(Boolean);a.length&&(s.servers=a);let p={};Array.isArray(o)&&o.length&&(p.parameters=o),p[n]=r,s.paths={[t]:p};let c=r.security??e.security;if(l&&Array.isArray(c)&&c.length){let u={};for(let y of c)for(let f of Object.keys(y||{}))l[f]&&(u[f]=l[f]);Object.keys(u).length&&(e.swagger?s.securityDefinitions=u:s.components={securitySchemes:u})}return s}function Kt(e){let t=[],n=[],r=e.components?.securitySchemes||e.securityDefinitions||{},o=e.security||[],i=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]);for(let[l,s]of Object.entries(e.paths||{})){if(!s||typeof s!="object")continue;let a=s.parameters||[],p=s.servers||i;for(let c of Nr){let u=s[c];!u||typeof u!="object"||(t.push(Gr({method:c,path:l,op:u,sharedParams:a,servers:u.servers||p,globalSecurity:o,schemes:r})),n.push(Jr(e,l,c,u,a,u.servers||p,r)))}}return{operations:t,segments:n}}function ot(e){let t=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]),{operations:n,segments:r}=Kt(e);return{title:e.info?.title||"API Reference",version:e.info?.version||"",servers:t.map(o=>o.url).filter(Boolean),operations:n,segments:r}}var Nr,it=A(()=>{Nr=["get","post","put","patch","delete","options","head","trace"]});import Hr from"@apidevtools/swagger-parser";async function Dr(e){return Hr.dereference(e)}async function Zt(e){return ot(await Dr(e))}var Qt=A(()=>{it();it()});function qr(e,{server:t}={}){let r=`${(t||e.servers?.[0]||"").replace(/\/+$/,"")}${e.path}`,o={};for(let l of e.auth||[])l.in==="header"&&(o[l.name]=l.prefix?`${l.prefix} <token>`:"<token>");for(let l of e.parameters?.header||[])o[l.name]||(o[l.name]=String(l.example??`<${l.type}>`));let i=!!e.body;return i&&(o["Content-Type"]=e.body.contentType||"application/json"),{method:e.method,url:r,headers:o,body:i?e.body.example??{}:null}}function Wr(e){let t=`curl --request ${e.method} \\
|
|
7
7
|
--url ${e.url}`;for(let[n,r]of Object.entries(e.headers))t+=` \\
|
|
8
8
|
--header '${n}: ${r}'`;return e.body!=null&&(t+=` \\
|
|
9
|
-
--data '${JSON.stringify(e.body)}'`),t}function
|
|
9
|
+
--data '${JSON.stringify(e.body)}'`),t}function Yr(e){let t=[` method: '${e.method}'`];if(Object.keys(e.headers).length){let n=Object.entries(e.headers).map(([r,o])=>` '${r}': '${o}'`).join(`,
|
|
10
10
|
`);t.push(` headers: {
|
|
11
11
|
${n}
|
|
12
|
-
}`)}return e.body!=null&&t.push(` body: JSON.stringify(${
|
|
12
|
+
}`)}return e.body!=null&&t.push(` body: JSON.stringify(${st(e.body," ")})`),[`const res = await fetch('${e.url}', {`,t.join(`,
|
|
13
13
|
`),"});","const data = await res.json();"].join(`
|
|
14
|
-
`)}function
|
|
14
|
+
`)}function Xr(e){let t=["import requests","",`url = "${e.url}"`];if(Object.keys(e.headers).length){let r=Object.entries(e.headers).map(([o,i])=>` "${o}": "${i}"`).join(`,
|
|
15
15
|
`);t.push(`headers = {
|
|
16
16
|
${r}
|
|
17
|
-
}`)}let n=["url"];return e.body!=null&&(t.push(`payload = ${
|
|
18
|
-
`)}function
|
|
19
|
-
`)}function
|
|
17
|
+
}`)}let n=["url"];return e.body!=null&&(t.push(`payload = ${st(e.body,"")}`),n.push("json=payload")),Object.keys(e.headers).length&&n.push("headers=headers"),t.push("",`response = requests.${e.method.toLowerCase()}(${n.join(", ")})`,"print(response.json())"),t.join(`
|
|
18
|
+
`)}function Kr(e){let t=e.method.charAt(0)+e.method.slice(1).toLowerCase(),n=["require 'net/http'","require 'json'","",`uri = URI("${e.url}")`,"http = Net::HTTP.new(uri.host, uri.port)","http.use_ssl = true",`request = Net::HTTP::${t}.new(uri)`];for(let[r,o]of Object.entries(e.headers))n.push(`request['${r}'] = '${o}'`);return e.body!=null&&n.push(`request.body = ${st(e.body,"")}.to_json`),n.push("","response = http.request(request)","puts response.body"),n.join(`
|
|
19
|
+
`)}function tn(e,{server:t,languages:n=at}={}){let r=qr(e,{server:t});return n.filter(o=>en[o]).map(o=>({key:o,label:Zr[o],language:Qr[o],code:en[o](r)}))}var st,en,Zr,Qr,at,nn=A(()=>{st=(e,t)=>JSON.stringify(e,null,2).split(`
|
|
20
20
|
`).map((n,r)=>r===0?n:t+n).join(`
|
|
21
|
-
`);
|
|
21
|
+
`);en={curl:Wr,javascript:Yr,python:Xr,ruby:Kr},Zr={curl:"cURL",javascript:"JavaScript",python:"Python",ruby:"Ruby"},Qr={curl:"bash",javascript:"javascript",python:"python",ruby:"ruby"},at=["curl","javascript","python","ruby"]});function rn(e,t){if(!t||typeof t!="object")return e;let n=z(t);return{server:t.server!=null?n.server:e?.server??null,proxy:t.playground!=null?n.proxy:e?.proxy!==!1,languages:t.examples?.languages!=null?n.languages:e?.languages}}function eo(e,{base:t,api:n,ops:r}){let o=n?.server,i=n?.languages||at,l={proxy:n?.proxy!==!1,server:o??null},s=new Map;for(let p of e){let c=p.op.tags?.[0]||"API";s.has(c)||s.set(c,[]),s.get(c).push(p)}let a=[];for(let[p,c]of s){let u=c.map(({op:y,segment:f})=>{let b=`${t}/${lt(p)}/${y.id}`;return r[b]={operation:y,samples:tn(y,{server:o||y.servers?.[0],languages:i}),segment:f,title:y.title,description:y.description,method:y.method,api:l},{apiPage:b,label:y.title,method:y.method}});a.push({group:p,pages:u})}return a}async function on(e,{loadOps:t,base:n,api:r,ops:o}){let i=Array.isArray(e)?e:[e],l=[];for(let s of i){let{operations:a,segments:p,servers:c}=await t(s);a.forEach((u,y)=>{!u.servers?.length&&c?.length&&(u.servers=c),l.push({op:u,segment:p[y]})})}return eo(l,{base:n,api:r,ops:o})}async function sn(e,t){if(!e||typeof e!="object")return e;if(typeof e.tab=="string"&&e.openapi){let r=lt(e.tab),o=rn(t.api,e.api),i=await on(e.openapi,{...t,base:r,api:o}),{openapi:l,api:s,...a}=e;return{...a,groups:[...a.groups||[],...i]}}if(typeof e.group=="string"&&e.openapi){let r=lt(e.group),o=rn(t.api,e.api),i=await on(e.openapi,{...t,base:r,api:o}),{openapi:l,api:s,...a}=e,p=i.flatMap(c=>c.pages);return{...a,pages:[...a.pages||[],...p]}}let n={...e};for(let r of["products","versions","languages","tabs","groups"])Array.isArray(e[r])&&(n[r]=await Promise.all(e[r].map(o=>sn(o,t))));return n}async function an(e,{api:t,loadOps:n}){let r={};return!e||typeof e!="object"?{nav:e,ops:r}:{nav:await sn(e,{api:t,loadOps:n,ops:r}),ops:r}}var lt,ln=A(()=>{ke();nn();lt=e=>String(e??"").replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"x"});import to from"node:path";function no(e,t){return/^https?:\/\//.test(e)?e:to.resolve(t,e.replace(/^\/+/,""))}async function Le(e,{targetDir:t,api:n}={}){return an(e,{api:n,loadOps:r=>Zt(no(r,t))})}var ct=A(()=>{Qt();ln()});import ro from"node:fs";import he from"node:path";function pn(e){return{name:"velu-site",resolveId(t){return t===un?cn:null},async load(t){return t!==cn?null:oo(e)}}}async function oo(e){let t={};try{t=JSON.parse(ro.readFileSync(he.join(e,"velu.json"),"utf-8"))}catch{}let n=z(t.api),r=t.navigation??{},o={};try{let $=await Le(t.navigation??{},{targetDir:e,api:n});r=$.nav,o=$.ops}catch($){console.warn(`[velu] openapi: ${$.message}`)}let i=G(r),{pageEntries:l,warnings:s}=J(i,e);for(let $ of s)console.warn(`[velu] nav: ${$}`);let a=ue(t.logo),p={name:t.name??he.basename(e),logo:a?{light:Ae,dark:je,href:a.href,mono:a.light===a.dark}:null,footer:ae(t.footer),navbar:le(t.navbar),contextual:Ke(t.contextual),assistant:ce(t.assistant)},c=[],u=[],y=0;for(let $ of l){if(!$.exists)continue;let P=JSON.stringify($.fileAbsPath.split(he.sep).join("/")),M=JSON.stringify(he.relative(e,$.fileAbsPath).split(he.sep).join("/")),E=`__p${y++}`;c.push(`import * as ${E} from ${P};`),u.push(` ${JSON.stringify($.url)}: { Component: ${E}.default, frontmatter: ${E}.frontmatter, toc: ${E}.toc, changelog: ${E}.changelog, relPath: ${M} },`)}let f=new Set(l.filter($=>$.exists).map($=>$.url));for(let $ of l)!$.exists&&!f.has($.url)&&u.push(` ${JSON.stringify($.url)}: { missing: true },`);let b=[],g=[],_=[],d=!1,j=0;for(let $ of ee(i)){if(!$.node?.api)continue;let P=o[$.pagePath];if(!P)continue;d=!0;let M=`__op${j}`,E=`__samples${j}`,Be=`__api${j}`;j+=1,b.push(`const ${M} = ${JSON.stringify(P.operation)};`),b.push(`const ${E} = ${JSON.stringify(P.samples)};`),_.push(`{ id: ${JSON.stringify(P.operation.id)}, method: ${JSON.stringify(P.operation.method)}, title: ${JSON.stringify(P.operation.title)}, url: ${JSON.stringify($.url)}, operation: ${M}, samples: ${E}, api: ${JSON.stringify(P.api||{proxy:!0,server:null})} }`),g.push(`function ${Be}(){ return React.createElement(ApiReferencePage, { operation: ${M}, samples: ${E}, apiOperations: __apiOperations, api: ${JSON.stringify(P.api||{proxy:!0,server:null})} }); }`),u.push(` ${JSON.stringify($.url)}: { Component: ${Be}, frontmatter: { title: ${JSON.stringify(P.title)}, description: ${JSON.stringify(P.description)} }, toc: [], operation: ${M}, samples: ${E}, api: true },`)}d&&(b.push(`const __apiOperations = [
|
|
22
22
|
${_.join(`,
|
|
23
23
|
`)}
|
|
24
24
|
];`),b.push(g.join(`
|
|
@@ -27,10 +27,10 @@ ${_.join(`,
|
|
|
27
27
|
`),b.join(`
|
|
28
28
|
`),"","export const pages = {",u.join(`
|
|
29
29
|
`),"};",`export const navigation = ${JSON.stringify(i)};`,`export const site = ${JSON.stringify(p)};`,"if (site.logo) {"," const __veluBase = (import.meta.env.BASE_URL || '/').replace(/\\/$/, '');"," site.logo = { ...site.logo, light: __veluBase + site.logo.light, dark: __veluBase + site.logo.dark };","}",""].join(`
|
|
30
|
-
`)}var
|
|
30
|
+
`)}var un,cn,fn=A(()=>{H();de();pe();ct();un="virtual:velu-site",cn="\0"+un});import{visit as io}from"unist-util-visit";function so(e,t){let n=mn(e).replace(/[?#].*$/,""),r=mn(t).replace(/\/+$/,"");return r&&n.toLowerCase().startsWith(r.toLowerCase())?n.slice(r.length).replace(/^\/+/,""):null}function dn(e,t){return()=>(n,r)=>{typeof e=="function"&&io(n,o=>{if(o.type!=="mdxJsxFlowElement"&&o.type!=="mdxJsxTextElement"||typeof o.name!="string"||!/^[A-Z]/.test(o.name)||o.name.includes("."))return;let i={};for(let s of o.attributes||[])s.type==="mdxJsxAttribute"&&(s.value==null?i[s.name]=!0:typeof s.value=="string"&&(i[s.name]=s.value));let l=e(o.name,i,{checkRequired:!1});if(l){let s=new Error(l.title);throw s.veluIssue={...l,file:so(r?.path,t),line:o.position?.start?.line??null,column:o.position?.start?.column??null},s.loc={line:s.veluIssue.line,column:s.veluIssue.column},s}})}}var mn,gn=A(()=>{mn=e=>String(e||"").replace(/\\/g,"/")});import Oe from"node:path";import ao from"node:fs";import{createRequire as lo}from"node:module";import co from"@tailwindcss/vite";import uo from"@vitejs/plugin-react";import po from"@mdx-js/rollup";import fo from"remark-frontmatter";import mo from"remark-mdx-frontmatter";import go from"remark-gfm";import ho from"rehype-slug";function yo(e){let n=lo(import.meta.url).resolve("@mdx-js/react"),r=Oe.resolve(e,"runtime","velu-ui"),o=ao.existsSync(r)?r:Oe.resolve(e,"..","velu-ui","src");return[{find:"@mdx-js/react",replacement:n},{find:/^velu-ui$/,replacement:Oe.join(o,"index.js")},{find:/^velu-ui\//,replacement:o+"/"}]}function hn({targetDir:e,VITE_ROOT:t,validateProps:n,basePath:r}){return{root:t,base:r?`${r}/`:"/",plugins:[pn(e),po({remarkPlugins:[fo,mo,go,nt,fe,dn(n,e)],rehypePlugins:[ho],providerImportSource:"@mdx-js/react"}),uo(),co({optimize:!1})],cacheDir:Oe.resolve(e,".velu","vite-cache"),optimizeDeps:{include:["react","react-dom","react-dom/client","react-router-dom","@mdx-js/react","lucide-react","prism-react-renderer","iso-639-1","github-slugger"],exclude:["tailwindcss","@tailwindcss/oxide","playwright","playwright-core","@apidevtools/swagger-parser","satori","@resvg/resvg-js","pagefind"],esbuildOptions:{loader:{".mdx":"jsx"}}},resolve:{alias:yo(t),dedupe:["react","react-dom","@mdx-js/react"]}}}var yn=A(()=>{tt();Gt();fn();gn()});function T(e){return{category:"render-crash",severity:"error",file:null,line:null,column:null,frame:null,title:"Something went wrong",detail:"",hint:"",suggestion:null,...e}}function vo(e,t){if(e=String(e),t=String(t),e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;let n=Array.from({length:t.length+1},(o,i)=>i),r=new Array(t.length+1);for(let o=1;o<=e.length;o++){r[0]=o;for(let i=1;i<=t.length;i++){let l=e[o-1]===t[i-1]?0:1;r[i]=Math.min(r[i-1]+1,n[i]+1,n[i-1]+l)}[n,r]=[r,n]}return n[t.length]}function _e(e,t=[]){if(!e)return null;let n=String(e).toLowerCase(),r=null,o=1/0;for(let l of t){let s=vo(n,String(l).toLowerCase());s<o&&(o=s,r=l)}let i=Math.min(3,Math.max(2,Math.floor(n.length/4)));return o<=i?r:null}function bo(e,t){return e==="warning"?N(t,F.yellow,"\u26A0"):e==="info"?N(t,F.cyan,"\u2139"):N(t,F.red,"\u2716")}function pt(e,{color:t=!1}={}){let n=ut[e.category]||e.category,r=e.line?`${e.line}${e.column?`:${e.column}`:""}`:"",o=e.file?`${e.file}${r?`:${r}`:""}`:r,i=[];if(i.push(`${bo(e.severity,t)} ${N(t,F.bold,n)}`+(o?` ${N(t,F.dim,o)}`:"")),e.title&&i.push(` ${e.title}`),e.detail&&e.detail!==e.title&&i.push(` ${N(t,F.dim,e.detail)}`),e.frame)for(let l of String(e.frame).split(`
|
|
31
31
|
`))i.push(` ${l}`);return e.suggestion&&i.push(` ${N(t,F.cyan,`Did you mean <${e.suggestion}>?`)}`),e.hint&&i.push(` ${N(t,F.dim,`\u2192 ${e.hint}`)}`),i.join(`
|
|
32
|
-
`)}function Ee(e,{color:t=!1}={}){if(!e.length)return N(t,F.cyan,"\u2713 No issues found.");let n=new Map;for(let s of e){let a=s.file||"velu.json";n.has(a)||n.set(a,[]),n.get(a).push(s)}let r=[];for(let[s,a]of n){r.push(N(t,F.bold,s));for(let p of a)r.push(
|
|
33
|
-
`)}var
|
|
32
|
+
`)}function Ee(e,{color:t=!1}={}){if(!e.length)return N(t,F.cyan,"\u2713 No issues found.");let n=new Map;for(let s of e){let a=s.file||"velu.json";n.has(a)||n.set(a,[]),n.get(a).push(s)}let r=[];for(let[s,a]of n){r.push(N(t,F.bold,s));for(let p of a)r.push(pt({...p,file:null},{color:t}).replace(/^/gm," "));r.push("")}let o=e.filter(s=>s.severity!=="warning"&&s.severity!=="info").length,i=e.length-o,l=`${o} error${o===1?"":"s"}`+(i?`, ${i} warning${i===1?"":"s"}`:"");return r.push(N(t,o?F.red:F.yellow,l)),r.join(`
|
|
33
|
+
`)}var ut,F,N,q=A(()=>{ut={"mdx-syntax":"MDX syntax",frontmatter:"Frontmatter","unknown-component":"Unknown component","invalid-props":"Invalid options","render-crash":"Render error","config-json":"velu.json","config-schema":"velu.json","config-nav":"Navigation","config-asset":"Asset"};F={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m",bold:"\x1B[1m"},N=(e,t,n)=>e?`${t}${n}${F.reset}`:n});function xo(e){let t=e,n=0;for(;t&&t.cause&&n<3&&!(t.loc||t.line||/`[^`]+` to be defined/.test(t.message||""));)t=t.cause,n+=1;return t||e}function ft(e,t){if(!e)return null;let n=vn(e).replace(/[?#].*$/,""),r=t?vn(t).replace(/\/+$/,""):"";return r&&n.toLowerCase().startsWith(r.toLowerCase())?n.slice(r.length).replace(/^\/+/,""):!/^([a-zA-Z]:\/|\/)/.test(n)&&!/node_modules/.test(n)?n:null}function $o(e){return e?String(e).replace(/([a-zA-Z]:\\|\/)[^\s'"()]+/g,t=>/node_modules|[\\/]vite[\\/]|@veluai|velu-cli|velu-ui/.test(t)?"\u2026":t).trim():""}function wo(e){let t=/\((\d+):(\d+)(?:-\d+:\d+)?\)\s*$/.exec(String(e||""));return t?{line:Number(t[1]),column:Number(t[2])}:null}function So(e){return String(e||"").replace(/\s*\(\d+:\d+(?:-\d+:\d+)?\)\s*$/,"").trim()}function Ao(e,t){if(!e||!t)return null;let n=String(e);return/node_modules|[\\/]vite[\\/]|@veluai[\\/]/.test(n)?null:n}function ye(e,t={}){let{projectDir:n="",knownComponents:r=[],file:o=null}=t,i=null;for(let d=e,j=0;d&&j<6;d=d.cause,j+=1)if(d.veluIssue){i=d.veluIssue;break}if(i)return T({...i,file:i.file||o});let l=xo(e)||{},s=l.message||String(e||""),a=/Expected component `([^`]+)` to be defined/.exec(s);if(a){let d=a[1],j=/referenced in your code at `(\d+):(\d+)/.exec(s),w=/\bin `([^`]+)`/.exec(s),$=w?ft(w[1],n):null;return T({category:"unknown-component",file:$||o,line:j?Number(j[1]):null,column:j?Number(j[2]):null,title:`<${d}> is not a built-in component`,detail:"",hint:"Components are built in \u2014 check the spelling and capitalization (you don\u2019t import them).",suggestion:_e(d,r)})}let p=l.loc||(l.line!=null?{line:l.line,column:l.column,file:l.file}:null)||wo(l.reason||s),c=l.id||p&&p.file||l.file||null,u=ft(c,n)||o,y=!!u&&ft(c,n)!=null,f=Ao(l.frame,y||!!o),b=$o(So(l.reason||s)),g=ko.test(s),_=l.source==="remark-frontmatter"||/\byaml\b|frontmatter/i.test(s)||p&&p.line===1&&/unexpected|expected/i.test(s)&&/---/.test(s);return p||g||f&&y?T({category:_?"frontmatter":"mdx-syntax",file:u,line:p?p.line:null,column:p?p.column:null,frame:f,title:b||(_?"Invalid frontmatter":"MDX syntax error"),detail:"",hint:_?"Check the YAML between the --- markers \u2014 indentation, quotes, and colons.":"Make sure every <Component> has a matching closing tag and that { } braces are balanced."}):/\.map is not a function|is not iterable|reading '|undefined \(reading/i.test(s)?T({category:"invalid-props",file:u,title:"A component received an invalid value",detail:b,hint:"Check the props/options you passed to a component on this page."}):T({category:"render-crash",file:u,title:"This page failed to render",detail:b,hint:"Set VELU_DEBUG=1 for the full stack trace."})}var vn,ko,mt=A(()=>{q();vn=e=>String(e).replace(/\\/g,"/");ko=/closing tag|unexpected closing|could not parse (?:expression|import|export)|unexpected character|unexpected end of|expected a closing|expected the closing|unexpected `|in expression|misnested|before name/i});function jo(e){let t=ut[e.category]||e.category,n=e.file?`${e.file}${e.line?`:${e.line}${e.column?`:${e.column}`:""}`:""}`:"",r=[];return r.push('<div class="velu-err-card">'),r.push('<div class="velu-err-head">'),r.push(`<span class="velu-err-pill">${B(t)}</span>`),r.push("</div>"),e.title&&r.push(`<div class="velu-err-title">${B(e.title)}</div>`),n&&r.push(`<a class="velu-err-loc" title="${B(n)}">${B(n)}</a>`),e.detail&&r.push(`<div class="velu-err-detail">${B(e.detail)}</div>`),e.frame&&r.push(`<pre class="velu-err-frame">${B(e.frame)}</pre>`),e.suggestion&&r.push(`<div class="velu-err-suggest">Did you mean <code><${B(e.suggestion)}></code>?</div>`),e.hint&&r.push(`<div class="velu-err-hint">${B(e.hint)}</div>`),r.push("</div>"),r.join("")}function dt(e,t={}){let n=Array.isArray(e)?e:[e],r=t.title||(n.length>1?`${n.length} problems to fix`:"There\u2019s a problem to fix"),o=n.map(jo).join(`
|
|
34
34
|
`);return`<!doctype html>
|
|
35
35
|
<html lang="en">
|
|
36
36
|
<head>
|
|
@@ -102,16 +102,16 @@ ${_.join(`,
|
|
|
102
102
|
<div class="velu-err-foot">Fix the file and save \u2014 this page reloads automatically.</div>
|
|
103
103
|
</div>
|
|
104
104
|
</body>
|
|
105
|
-
</html>`}var B,
|
|
106
|
-
`).length}function
|
|
107
|
-
`).length}function
|
|
108
|
-
`).length}function
|
|
109
|
-
${e}`;let n=e.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),r=`> ${
|
|
105
|
+
</html>`}var B,bn=A(()=>{q();B=e=>String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")});var W,gt=A(()=>{W=["Callout","Card","CardGroup","Accordion","AccordionGroup","Columns","Field","Prompt","Steps","Step","Tree","Folder","File","Update","Icon","Image","CodeBlock","CodeGroup","MethodBadge","ApiPath","TryItBar","ApiField","ApiClient","ApiSidebar"]});import Pe from"node:fs";import be from"node:path";import{fileURLToPath as To}from"node:url";import Lo from"iso-639-1";function ve(e,t){if(!t)return null;let n=e.indexOf(`"${t}"`);return n===-1?null:e.slice(0,n).split(`
|
|
106
|
+
`).length}function Eo(e,t){return t==null||t<0?null:e.slice(0,t).split(`
|
|
107
|
+
`).length}function ht(e,t){if(!t)return null;let n=e.indexOf(`"${t}"`);return n===-1?null:e.slice(0,n).split(`
|
|
108
|
+
`).length}function Po(e,t,n){let r=[];return s(e,t,"",null),r;function o(a){if(a&&a.$ref){let p=a.$ref.replace(/^#\//,"").split("/"),c=n;for(let u of p)c=c?.[u];return c||{}}return a}function i(a){return Array.isArray(a)?"array":a===null?"null":typeof a}function l(a,p){let c=r.length;s(a,p,"",null,!0);let u=r.length===c;return u||(r.length=c),u}function s(a,p,c,u,y){let f=o(p);if(f){if(f.oneOf){f.oneOf.some(g=>l(a,g))||r.push({path:c,key:u,message:"value does not match any allowed shape"});return}if(f.type&&i(a)!==f.type){r.push({path:c,key:u,message:`expected ${f.type}, got ${i(a)}`});return}if(f.type==="string"&&f.minLength!=null&&a.length<f.minLength&&r.push({path:c,key:u,message:"must not be empty"}),f.type==="object"&&i(a)==="object"){for(let g of f.required||[])g in a||r.push({path:c?`${c}.${g}`:g,key:g,message:`missing required "${g}"`});let b=f.properties||{};if(f.additionalProperties===!1)for(let g of Object.keys(a))g in b||r.push({path:c?`${c}.${g}`:g,key:g,message:`unknown field "${g}"`});for(let[g,_]of Object.entries(b))g in a&&s(a[g],_,c?`${c}.${g}`:g,g,y)}f.type==="array"&&Array.isArray(a)&&f.items&&a.forEach((b,g)=>s(b,f.items,`${c}[${g}]`,u,y))}}}function Co(e){if(typeof e!="string")return!1;let t=e.trim();return/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(t)||/^(rgb|rgba|hsl|hsla|color|oklch|lab|lch)\(/i.test(t)||/^[a-z][a-z0-9-]*$/i.test(t)}function Ce(e){let t=[],n=be.join(e,"velu.json"),r;try{r=Pe.readFileSync(n,"utf-8")}catch(s){return s.code==="ENOENT"?t.push(T({category:"config-json",file:"velu.json",title:"No velu.json found",hint:"Run `velu init <name>` to scaffold a project."})):t.push(T({category:"config-json",file:"velu.json",title:"Could not read velu.json"})),t}let o;try{o=JSON.parse(r)}catch(s){let a=/position (\d+)/.exec(s.message||""),p=a?Eo(r,Number(a[1])):null;return t.push(T({category:"config-json",file:"velu.json",line:p,title:"velu.json is not valid JSON",detail:String(s.message||"").replace(/\s+in JSON.*$/,""),hint:"Check for a trailing comma, a missing quote, or an unclosed brace."})),t}let i=null;try{i=JSON.parse(Pe.readFileSync(_o,"utf-8"))}catch{}if(i)for(let s of Po(o,i,i)){let a=/^unknown field/.test(s.message);t.push(T({category:"config-schema",severity:a?"warning":"error",file:"velu.json",line:ve(r,s.key),title:s.path?`${s.path}: ${s.message}`:s.message,hint:a?"Remove it, or check the spelling against the velu.json schema.":""}))}for(let s of["primary","light","dark"]){let a=o.colors?.[s];a!=null&&!Co(a)&&t.push(T({category:"config-schema",severity:"warning",file:"velu.json",line:ve(r,s),title:`colors.${s}: "${a}" doesn\u2019t look like a CSS color`,hint:"Use a hex value like #dc143c, an rgb()/hsl() function, or a CSS color name."}))}if(typeof o.favicon=="string"&&o.favicon.trim()){let s=be.resolve(e,o.favicon.replace(/^\/+/,""));Pe.existsSync(s)||t.push(T({category:"config-asset",file:"velu.json",line:ve(r,"favicon"),title:`favicon not found: ${o.favicon}`,hint:"The path is relative to the project root."}))}let l=ue(o.logo);if(l){let s=new Map;for(let a of["light","dark"]){let p=l[a];p&&s.set(p,[...s.get(p)||[],a])}for(let[a,p]of s)if(!Pe.existsSync(be.resolve(e,a.replace(/^\/+/,"")))){let c=p.length===2?"logo":`logo (${p[0]})`;t.push(T({category:"config-asset",file:"velu.json",line:ht(r,a),title:`${c} not found: ${a}`,hint:"The path is relative to the project root."}))}}if(o.navigation&&typeof o.navigation=="object"){let s;try{s=G(o.navigation)}catch(a){t.push(T({category:"config-nav",file:"velu.json",line:ve(r,"navigation"),title:"navigation could not be processed",detail:String(a.message||"")})),s=null}if(s){let{pageEntries:a,warnings:p}=J(s,e);for(let c of p){let u=/not found$/.test(c),y=/page "([^"]+)"/.exec(c),f=y?ht(r,y[1]):null;t.push(T({category:"config-nav",severity:u?"error":"warning",file:"velu.json",line:f,title:c,hint:u?"Create the .mdx file, or remove the page from navigation.":""}))}Uo(s,r,t)}}return t}function Uo(e,t,n){let r=new Set,o=i=>{if(!(!i||typeof i!="object")){if(i.language&&!r.has(i.language)){r.add(i.language);let l=String(i.language).toLowerCase();Lo.validate(l)||n.push(T({category:"config-nav",severity:"warning",file:"velu.json",line:ht(t,i.language)||ve(t,"language"),title:`"${i.language}" is not a valid ISO 639-1 language code`,hint:'Use a two-letter code like "en", "fr", or "ja".'}))}for(let l of Object.values(i))Array.isArray(l)?l.forEach(o):l&&typeof l=="object"&&o(l)}};o(e)}var Oo,_o,yt=A(()=>{q();H();de();pe();Oo=be.dirname(To(import.meta.url)),_o=be.resolve(Oo,"..","..","schema","velu.schema.json")});import Fo from"node:fs/promises";import No from"node:fs";import Y from"node:path";import{fileURLToPath as Ro,pathToFileURL as Io}from"node:url";import{compile as Mo}from"@mdx-js/mdx";import zo from"remark-frontmatter";import Bo from"remark-mdx-frontmatter";import Vo from"remark-gfm";import Go from"rehype-slug";import{visit as Jo}from"unist-util-visit";function vt(){if(Ue)return Ue;let e=Y.dirname(Ro(import.meta.url)),t=[Y.resolve(e,"..","runtime","velu-ui"),Y.resolve(e,"..","..","runtime","velu-ui"),Y.resolve(e,"..","..","..","velu-ui","src")],n=null;for(let r of t){let o=Y.join(r,"lib","component-schemas.js");if(No.existsSync(o)){n=o;break}}return Ue=n?import(Io(n).href).then(r=>r.validateProps).catch(()=>null):Promise.resolve(null),Ue}function Ho(e){let t={};for(let n of e.attributes||[])n.type==="mdxJsxAttribute"&&(n.value==null?t[n.name]=!0:typeof n.value=="string"&&(t[n.name]=n.value));return t}function Do(e,t){return()=>n=>{Jo(n,r=>{if((r.type==="mdxJsxFlowElement"||r.type==="mdxJsxTextElement")&&typeof r.name=="string"&&/^[A-Z]/.test(r.name)&&!r.name.includes(".")&&e.push({name:r.name,props:Ho(r),line:r.position?.start?.line??null,column:r.position?.start?.column??null}),r.type==="mdxjsEsm"&&typeof r.value=="string")for(let o of r.value.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g))t.add(o[1])})}}async function qo(e,t){let n=[],r;try{r=await Fo.readFile(t.fileAbsPath,"utf-8")}catch{return n}let o=Y.relative(e,t.fileAbsPath).split(Y.sep).join("/"),i=[],l=new Set;try{await Mo({value:r,path:t.fileAbsPath},{remarkPlugins:[zo,Bo,Vo,fe,Do(i,l)],rehypePlugins:[Go],providerImportSource:"@mdx-js/react"})}catch(c){return n.push(ye(c,{projectDir:e,knownComponents:W,file:o})),n}let s=new Set(W),a=await vt(),p=new Set;for(let c of i)if(!l.has(c.name)){if(!s.has(c.name)){if(p.has(c.name))continue;p.add(c.name),n.push(T({category:"unknown-component",file:o,line:c.line,column:c.column,title:`<${c.name}> is not a built-in component`,hint:"Components are built in \u2014 check the spelling and capitalization (you don\u2019t import them).",suggestion:_e(c.name,W)}));continue}if(a){let u=a(c.name,c.props,{checkRequired:!1});u&&n.push(T({...u,file:o,line:c.line,column:c.column}))}}return n}async function xn(e,t){let n=t.filter(s=>s.exists),r=[],o=8,i=0;async function l(){for(;i<n.length;){let s=n[i++],a=await qo(e,s);for(let p of a)r.push(p)}}return await Promise.all(Array.from({length:Math.min(o,n.length)},l)),r}var Ue,bt=A(()=>{tt();q();mt();gt()});import xe from"node:fs";import xt from"node:path";import Sn from"js-yaml";function $t(e,t,n){if(n>24||e===null||typeof e!="object")return n>24&&e&&typeof e=="object"?null:e;if(t.has(e))return null;t.add(e);let r;if(Array.isArray(e))r=e.map(o=>$t(o,t,n+1));else{r={};for(let[o,i]of Object.entries(e))r[o]=$t(i,t,n+1)}return t.delete(e),r}function kn(e){return Sn.dump($t(e,new Set,0),{noRefs:!0,lineWidth:100,skipInvalid:!0})}function An(e){let t=String(e).replace(/\.md$/i,"");return t===""||t==="/"||t==="/index"?"/":t.replace(/\/+$/,"")||"/"}function Wo(e){return e==="/"?"/index.md":`${e}.md`}function wt(e,t){if(t==="api")return`# ${$n}
|
|
109
|
+
${e}`;let n=e.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),r=`> ${$n}
|
|
110
110
|
|
|
111
|
-
`;return n?e.slice(0,n[0].length)+r+e.slice(n[0].length):r+e}function
|
|
112
|
-
`)}async function
|
|
111
|
+
`;return n?e.slice(0,n[0].length)+r+e.slice(n[0].length):r+e}function Xo(e){return e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,"")}function Ko(e){try{let t=xe.readFileSync(e,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!t)return{};let n=Sn.load(t[1]);return n&&typeof n=="object"?n:{}}catch{return{}}}async function oe(e){let t={};try{t=JSON.parse(xe.readFileSync(xt.join(e,"velu.json"),"utf-8"))}catch{return{name:xt.basename(e),baseUrl:"",pages:[]}}let n=t.name??xt.basename(e),r=typeof process.env.VELU_SITE_URL=="string"?process.env.VELU_SITE_URL.replace(/\/+$/,""):"",o=z(t.api),i=t.navigation??{},l={};try{let u=await Le(t.navigation??{},{targetDir:e,api:o});i=u.nav,l=u.ops}catch(u){console.warn(`[velu] openapi: ${u.message}`)}let s=G(i),{pageEntries:a}=J(s,e),p=new Map(a.map(u=>[u.url,u])),c=[];for(let u of ee(s)){if(!u.url)continue;let y=u.ancestors.filter(d=>d.kind==="group").pop(),f=u.ancestors.filter(d=>d.kind==="tab").pop(),b=y?.label||f?.label||"Pages",g=u.ancestors.filter(d=>d.kind==="tab"||d.kind==="group").map(d=>d.label),_=u.ancestors.filter(d=>d.kind==="language").pop()?.code||null;if(u.node?.api){let d=l[u.pagePath];if(!d)continue;let j=d.title||wn(u.url);c.push({url:u.url,title:j,description:d.description||"",group:b,breadcrumb:[...g,j],lang:_,frontmatter:{title:d.title,description:d.description},source:{kind:"api",segment:d.segment}})}else{let d=p.get(u.url);if(!d||!d.exists)continue;let j=Ko(d.fileAbsPath),w=j.title||wn(u.url);c.push({url:u.url,title:w,description:j.description||"",group:b,breadcrumb:[...g,w],lang:_,frontmatter:j,source:{kind:"mdx",fileAbsPath:d.fileAbsPath}})}}return{name:n,baseUrl:r,pages:c}}function Re(e){return new Map(e.pages.map(t=>[t.url,{...t.source,title:t.title}]))}async function Zo(e){return Re(await oe(e))}async function St(e,t,n){let o=(n||await Zo(e)).get(t);if(!o)return null;if(o.kind==="mdx")try{return{body:xe.readFileSync(o.fileAbsPath,"utf-8"),contentType:"text/markdown; charset=utf-8",kind:"mdx"}}catch{return null}return o.segment?{body:kn(o.segment),contentType:"text/yaml; charset=utf-8",kind:"api"}:null}async function jn(e,t){let n=t||await oe(e),r=s=>n.baseUrl?n.baseUrl+s:s,o=[`# ${n.name}`,"",`> Documentation index for ${n.name}. Append \`.md\` to any page URL (or send \`Accept: text/markdown\`) for its Markdown; fetch ${Ne} for the whole site in one document.`,""],i=[],l=new Map;for(let s of n.pages)l.has(s.group)||(l.set(s.group,[]),i.push(s.group)),l.get(s.group).push(s);for(let s of i){o.push(`## ${s}`,"");for(let a of l.get(s))o.push(`- [${a.title}](${r(Wo(a.url))})${a.description?`: ${a.description}`:""}`);o.push("")}return o.join(`
|
|
112
|
+
`)}async function Tn(e,t){let n=t||await oe(e),r=[`# ${n.name}`,"",`> Full documentation \u2014 every page concatenated. Index: ${ne}`];for(let o of n.pages)if(r.push("","---","",`# ${o.title}`,`Source: ${o.url}`,""),o.source.kind==="mdx")try{r.push(Xo(xe.readFileSync(o.source.fileAbsPath,"utf-8")).trim())}catch{}else o.source.segment&&r.push("```yaml",kn(o.source.segment).trim(),"```");return r.join(`
|
|
113
113
|
`)+`
|
|
114
|
-
`}async function
|
|
114
|
+
`}async function Ln(e,t){let n=t||await oe(e),r=n.baseUrl||"",o=[];for(let s of n.pages){if(s.source.kind!=="mdx")continue;let a="";try{a=xe.readFileSync(s.source.fileAbsPath,"utf-8")}catch{continue}let p=/<Update\b([^>]*)>([\s\S]*?)<\/Update>/gi,c;for(;c=p.exec(a);){let u=c[1]||"",y=c[2]||"",f=Fe(u,"label")||Fe(u,"date")||"Update",b=Fe(u,"description")||ei(y)||f,g=`${r}${s.url}#${Qo(f)}`,_=Fe(u,"date")||f,d=new Date(_),j=Number.isNaN(d.getTime())?null:d.toUTCString();o.push({title:f,link:g,description:b,pubDate:j})}}if(!o.length)return null;let i=r||"/",l=o.map(s=>` <item>
|
|
115
115
|
<title>${X(s.title)}</title>
|
|
116
116
|
<link>${X(s.link)}</link>
|
|
117
117
|
<guid isPermaLink="true">${X(s.link)}</guid>
|
|
@@ -128,12 +128,12 @@ ${e}`;let n=e.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),r=`> ${bn}
|
|
|
128
128
|
`+l+`
|
|
129
129
|
</channel>
|
|
130
130
|
</rss>
|
|
131
|
-
`}var ne,Ne,
|
|
131
|
+
`}var ne,Ne,Yo,re,$n,wn,X,Qo,Fe,ei,On=A(()=>{H();de();pe();ct();ne="/llms.txt",Ne="/llms-full.txt",Yo=`<${ne}>; rel="llms-txt", <${Ne}>; rel="llms-full-txt"`,re={Link:Yo,"X-Llms-Txt":ne},$n=`Full documentation index: ${ne}`;wn=e=>(e.split("/").filter(Boolean).pop()||"Home").replace(/[-_]+/g," ").replace(/\b\w/g,n=>n.toUpperCase());X=e=>String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""),Qo=e=>`update-${String(e||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"item"}`,Fe=(e,t)=>{let n=e.match(new RegExp(`${t}\\s*=\\s*["']([^"']*)["']`,"i"));return n?n[1]:void 0},ei=e=>String(e||"").replace(/```[\s\S]*?```/g,"").replace(/<[^>]+>/g," ").replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/[#*`_>]/g,"").replace(/\s+/g," ").trim().slice(0,500)});var Nn={};we(Nn,{startDevServer:()=>yi});import _n from"node:fs/promises";import ie from"node:fs";import ti from"node:http";import{spawn as ni}from"node:child_process";import C from"node:path";import{fileURLToPath as ri}from"node:url";import oi from"chokidar";import kt from"express";import{createServer as ii,createLogger as si,searchForWorkspaceRoot as ai}from"vite";function fi(e){return`<link rel="stylesheet" href="${`https://fonts.googleapis.com/css2?family=${encodeURIComponent(e).replace(/%20/g,"+")}:wght@300;400;500;600;700&display=swap`}" />`}function En(e,t){let n=pt(e,{color:!!process.stderr.isTTY});console.error(`
|
|
132
132
|
`+n+`
|
|
133
|
-
`),process.env.VELU_DEBUG&&t&&console.error(t)}function
|
|
134
|
-
`)}function
|
|
133
|
+
`),process.env.VELU_DEBUG&&t&&console.error(t)}function Pn(){try{return JSON.parse(ie.readFileSync(C.join(Ie,"package.json"),"utf8")).version||"unknown"}catch{return"unknown"}}function mi(e,t){let n=C.resolve(e,".velu"),r=C.resolve(n,".velu-version"),o=null;try{o=ie.readFileSync(r,"utf8").trim()}catch{}if(o!==t){if(o!==null)try{ie.rmSync(C.join(n,"vite-cache"),{recursive:!0,force:!0}),console.log("[velu] new version detected \u2014 refreshing the preview cache\u2026")}catch{}try{ie.mkdirSync(n,{recursive:!0}),ie.writeFileSync(r,t)}catch{}}}async function Cn(e){try{return await Rt(e)}catch{return et({},C.basename(e))}}async function Un(e,t){let n=await e.moduleGraph.getModuleByUrl(t,!0),r=new Map,o=new Set;async function i(l){if(!(!l||o.has(l.url))){if(o.add(l.url),l.id&&ci.test(l.id)){let s=l.url.includes("?")?"&":"?",a=await e.transformRequest(`${l.url}${s}direct`);a?.code&&r.set(l.url,a.code)}for(let s of l.importedModules)await i(s)}}return await i(n),[...r.values()].join(`
|
|
134
|
+
`)}function hi(e,t,n){let r=()=>{process.stdout.isTTY&&!process.env.VELU_NO_BELL&&process.stdout.write("\x07")},o=process.stdout.isTTY,i=b=>o&&process.stdout.write(`\x1B]${b}\x1B\\`),l=()=>{i(`0;\u23F3 ${t}`),i("9;4;3;0")},s=()=>{i(`0;${t}`),i("9;4;0;0")};o&&process.once("exit",()=>i("9;4;0;0")),l();let a=n&&n!=="unknown"?`v${n}`:"";if(!e)return console.log(`Starting Velu${a?" "+a:""}\u2026`),{ready:b=>{console.log(`Velu${a?" "+a:""} ready \u2192 ${b}`),s(),r()}};let p="\x1B[38;2;220;20;60m",c="\x1B[0m",u="\x1B[2m";console.log("");for(let b of di)console.log(`${p}${b}${c}`);a&&console.log(` ${u}${a}${c}`),console.log("");let y=null;try{y=ni(process.execPath,["-e",gi],{stdio:["ignore","inherit","ignore"]}),y.on("error",()=>{})}catch{}let f=()=>{if(y){try{y.kill()}catch{}y=null}};return process.once("exit",f),{ready:b=>{f(),process.stdout.write("\x1B[2K\r"),console.log(` \x1B[32m\u2713${c} Velu${a?" "+a:""} ready \u2192 \x1B[36m${b}${c}`),s(),r()}}}async function yi(e){let t=!!process.env.VELU_PROFILE,n=performance.now(),r=(v,m)=>t&&console.log(`[velu-profile] ${v}: ${(performance.now()-m).toFixed(0)}ms`),o=hi(!!process.stdout.isTTY&&!t,C.basename(e),Pn()),i=await Cn(e),l=s();function s(){let m=Ce(e).filter(x=>x.severity==="error"&&(x.category==="config-json"||x.category==="config-schema"));return m.length&&console.error(`
|
|
135
135
|
`+Ee(m,{color:!!process.stderr.isTTY})+`
|
|
136
|
-
`),m}let a=e;try{a=ie.realpathSync(e)}catch{}let p=0,c=v=>{let m=performance.now();if(m-p<500)return;p=m;let x=ye(v,{projectDir:a,knownComponents:W});
|
|
137
|
-
${
|
|
138
|
-
</style>`,
|
|
139
|
-
`),
|
|
136
|
+
`),m}let a=e;try{a=ie.realpathSync(e)}catch{}let p=0,c=v=>{let m=performance.now();if(m-p<500)return;p=m;let x=ye(v,{projectDir:a,knownComponents:W});En(x,v)};process.on("unhandledRejection",c),process.on("uncaughtException",c);let u=Number(process.env.PORT)||8358,y=await vt();mi(e,Pn());let f=kt(),b=ti.createServer(f),g=si(t?"info":"warn"),_=v=>typeof v=="string"&&v.includes("Failed to load source map"),d=g.warn.bind(g),j=g.warnOnce.bind(g);g.warn=(v,m)=>{_(v)||d(v,m)},g.warnOnce=(v,m)=>{_(v)||j(v,m)};let w=await ii({...hn({targetDir:e,VITE_ROOT:Ie,validateProps:y}),appType:"custom",logLevel:t?"info":"warn",customLogger:g,server:{middlewareMode:!0,fs:{allow:[ai(Ie),e,a]},hmr:{server:b}}});r("vite server created",n),f.use(w.middlewares);let $=C.join(e,"public");f.use(kt.static($)),f.get(new RegExp(`^${Qe}(\\.[a-z0-9]+)?$`,"i"),async(v,m)=>{if(!i.favicon)return m.status(404).end();let x=C.resolve(e,i.favicon.replace(/^\//,""));m.sendFile(x,h=>{h&&m.status(404).end()})});let P=v=>(m,x)=>{let h=i.logo?.[v];if(!h)return x.status(404).end();x.sendFile(C.resolve(e,h.replace(/^\//,"")),L=>{L&&x.status(404).end()})};f.get(Ae,P("light")),f.get(je,P("dark")),f.post("/@velu-api-proxy",kt.json({limit:"8mb"}),async(v,m)=>{let{method:x="GET",url:h,headers:L={},body:S}=v.body||{};if(typeof h!="string"||!/^https?:\/\//i.test(h))return m.status(400).json({error:"A valid http(s) target URL is required."});try{let k=await fetch(h,{method:x,headers:L,body:S!=null&&S!==""?S:void 0}),R=await k.text(),K=k.headers.get("content-type")||"",O={};k.headers.forEach((se,Ve)=>{O[Ve]=se});let V=R;if(/json/i.test(K))try{V=JSON.parse(R)}catch{}m.json({status:k.status,statusText:k.statusText,headers:O,body:V})}catch(k){m.json({error:`Request failed: ${k.message}`})}});let M=null,E=async()=>M||=await oe(e);f.get(/\.md$/i,async(v,m,x)=>{try{let h=await E(),L=await St(e,An(decodeURIComponent(v.path)),Re(h));if(!L)return x();m.status(200).set({"Content-Type":L.contentType,...re}).end(wt(L.body,L.kind))}catch{x()}}),f.get(ne,async(v,m,x)=>{try{let h=await jn(e,await E());m.status(200).set({"Content-Type":"text/plain; charset=utf-8",...re}).end(h)}catch{x()}}),f.get(Ne,async(v,m,x)=>{try{let h=await Tn(e,await E());m.status(200).set({"Content-Type":"text/plain; charset=utf-8",...re}).end(h)}catch{x()}}),f.get("/rss.xml",async(v,m,x)=>{try{let h=await Ln(e,await E());if(!h)return x();m.status(200).set({"Content-Type":"application/rss+xml; charset=utf-8"}).end(h)}catch{x()}}),f.use("*",async(v,m,x)=>{let h=v.originalUrl,L=performance.now();if(/text\/markdown/i.test(v.headers.accept||""))try{let S=await E(),k=await St(e,Jt(h),Re(S));if(k)return m.status(200).set({"Content-Type":k.contentType,...re}).end(wt(k.body,k.kind))}catch{}if(l.length)return m.status(200).set({"Content-Type":"text/html"}).end(dt(l,{title:"Fix velu.json to continue"}));try{let S=performance.now(),k=await _n.readFile(Fn,"utf-8");k=await w.transformIndexHtml(h,k),r(`transformIndexHtml ${h}`,S);let R="/src/runtime/server-entry.jsx";S=performance.now();let{render:K}=await w.ssrLoadModule(R);r(`ssrLoadModule ${h} (1st req includes dep pre-bundle)`,S),S=performance.now();let O=await K(h);r(`render ${h}`,S),S=performance.now();let V=await Un(w,R);r(`collectSsrCss ${h}`,S);let se=V?`<style data-velu-ssr>${V}</style>`:"",Ve=`<style data-velu-config>
|
|
137
|
+
${It(i)}
|
|
138
|
+
</style>`,Vn=ui.has(i.font.family)?"":fi(i.font.family),$e=Nt(i),Gn=$e?`<link rel="icon"${$e.type?` type="${$e.type}"`:""} href="${$e.url}" />`:"",Jn=[se,Ve,Vn,Gn].filter(Boolean).join(`
|
|
139
|
+
`),Hn=k.replace("<!--app-title-->",pi(i.name)).replace("<!--app-head-->",Jn).replace("<!--app-html-->",O);m.status(200).set({"Content-Type":"text/html",...re}).end(Hn),r(`TOTAL ${h}`,L)}catch(S){w.ssrFixStacktrace(S);let k=ye(S,{projectDir:a,knownComponents:W});if(/failed to load url|does the file exist|cannot find module|ERR_MODULE_NOT_FOUND/i.test(String(S&&S.message))){try{w.moduleGraph.invalidateAll()}catch{}k.hint="The dev server cache is out of sync \u2014 this usually happens after files are added, removed, or moved. Reload the page; if it persists, stop velu dev, delete the .velu folder in your project, and restart."}En(k,S),m.status(200).set({"Content-Type":"text/html"}).end(dt([k]))}}),oi.watch(e,{ignoreInitial:!0,ignored:/(^|[\\/])(node_modules|\.git|\.velu)([\\/]|$)/,awaitWriteFinish:{stabilityThreshold:100,pollInterval:20}}).on("all",async(v,m)=>{console.log(`[velu-cli] content ${v}: ${C.relative(e,m)}`);let x=C.basename(m)==="velu.json",h=m.endsWith(".mdx"),L=x||h&&(v==="add"||v==="unlink");if((L||h||/\.(ya?ml|json)$/i.test(m))&&(M=null),x&&(i=await Cn(e),l=s()),L)w.moduleGraph.invalidateAll();else if(h){let S=m.split(C.sep).join("/"),k=w.moduleGraph.getModulesByFile(S);if(k)for(let R of k)w.moduleGraph.invalidateModule(R)}w.ws.send({type:"full-reload"})});async function At(v){let m=new Set,x=12,h=0,L=[],S=()=>h<x?(h+=1,Promise.resolve()):new Promise(O=>L.push(O)).then(()=>{h+=1}),k=()=>{h-=1,L.shift()?.()},R=O=>/[\\/]\.velu[\\/]vite-cache[\\/]|[\\/]deps[\\/]/.test(O)||/[\\/]node_modules[\\/]/.test(O)&&!/velu-ui/.test(O);async function K(O){if(!(!O||m.has(O)||R(O))){m.add(O);try{await S();try{await w.transformRequest(O,{ssr:!1})}finally{k()}let V=await w.moduleGraph.getModuleByUrl(O,!1);V?.importedModules?.size&&await Promise.all([...V.importedModules].map(se=>K(se.url)))}catch{}}}return await K(v),m.size}b.listen(u,async()=>{let v=performance.now(),m=0;try{let{render:x}=await w.ssrLoadModule("/src/runtime/server-entry.jsx");await At("/src/runtime/client-entry.jsx"),typeof w.waitForRequestsIdle=="function"&&await w.waitForRequestsIdle();let[h]=await Promise.allSettled([At("/src/runtime/client-entry.jsx"),x("/"),w.transformIndexHtml("/",await _n.readFile(Fn,"utf-8")),Un(w,"/src/runtime/server-entry.jsx")]).then(L=>L.map(S=>S.status==="fulfilled"?S.value:0));m=h}catch(x){t&&console.log("[velu-profile] warmup error:",x?.message)}r(`cold-start warm-up (${m} client modules)`,v),o.ready(`http://localhost:${u}`)})}var li,ci,ui,pi,Ie,Fn,di,gi,Rn=A(()=>{pe();yn();mt();bn();q();gt();yt();bt();On();H();li=C.dirname(ri(import.meta.url)),ci=/\.(css|less|sass|scss|styl|stylus|pcss|postcss)(\?|$)/,ui=new Set(["Google Sans Flex","Google Sans Code","Outfit"]),pi=e=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");Ie=C.resolve(li,".."),Fn=C.resolve(Ie,"src","template.html"),di=[" _ __ __","| | / /__ / /_ __","| | / / _ \\/ / / / /","| |/ / __/ / /_/ /","|___/\\___/_/\\__,_/"],gi="const F=['\u280B','\u2819','\u2839','\u2838','\u283C','\u2834','\u2826','\u2827','\u2807','\u280F'],M=['Starting Velu','Setting up your preview','Preparing your docs','Warming things up','Almost ready'];let f=0,m=0;const t=Date.now();const C='\\x1b[38;2;220;20;60m',R='\\x1b[0m',D='\\x1b[2m';const d=()=>{const s=(Date.now()-t)/1000|0;process.stdout.write('\\x1b[2K\\r '+C+F[f]+R+' '+M[m]+'\\u2026 '+D+s+'s'+R);f=(f+1)%F.length;};d();setInterval(d,90);setInterval(()=>{if(m<M.length-1)m++;},4000);"});var Mn={};we(Mn,{default:()=>$i,runValidate:()=>In});import vi from"node:fs";import bi from"node:path";function xi(e){try{let t=JSON.parse(vi.readFileSync(bi.join(e,"velu.json"),"utf-8"));if(!t.navigation||typeof t.navigation!="object")return[];let n=G(t.navigation);return J(n,e).pageEntries}catch{return[]}}async function In(e){let t=Ce(e),n=xi(e),r=await xn(e,n),o=[...t,...r],i=!!process.stdout.isTTY;return console.log(Ee(o,{color:i})),o.some(s=>s.severity!=="warning"&&s.severity!=="info")?1:0}var $i,zn=A(()=>{H();de();yt();bt();q();$i=In});import Me from"node:path";import U from"node:process";import{readFileSync as wi}from"node:fs";var[,,Bn,ze]=U.argv;function Si(){try{return JSON.parse(wi(new URL("../package.json",import.meta.url),"utf8")).version}catch{return"unknown"}}function ki(){let e=U.argv.slice(3);for(let t=0;t<e.length;t++){let n=e[t];if(n==="--out"){t++;continue}if(!n.startsWith("-"))return n}}async function Ai(){switch(Bn){case"--version":case"-v":case"version":{console.log(Si());break}case"init":{ze||(console.error("Usage: velu init <project-name>"),U.exit(1));let e=ze,t=Me.resolve(U.cwd(),e),{initProject:n}=await Promise.resolve().then(()=>(Lt(),Tt));await n(t,e);break}case"dev":{let{maybeAutoUpdate:e}=await Promise.resolve().then(()=>(We(),qe));await e();let t=Me.resolve(U.cwd(),ze??"."),{startDevServer:n}=await Promise.resolve().then(()=>(Rn(),Nn));await n(t);break}case"update":{let{updateCommand:e}=await Promise.resolve().then(()=>(We(),qe));await e();break}case"validate":{let e=Me.resolve(U.cwd(),ze??"."),{runValidate:t}=await Promise.resolve().then(()=>(zn(),Mn)),n=await t(e);U.exit(n);break}case"build":{let e=Me.resolve(U.cwd(),ki()??"."),t=U.argv.indexOf("--out"),n=t>-1?U.argv[t+1]:void 0,r=new URL(["..","src","build","index.js"].join("/"),import.meta.url).href,o=l=>import(l),i;try{({runBuild:i}=await o(r))}catch{console.error("velu build is an internal command, not available in this distribution."),U.exit(1)}await i(e,{out:n});break}default:console.log("Usage:"),console.log(" velu init <project-name> scaffold a new docs project"),console.log(" velu dev [dir] start the dev preview server"),console.log(" velu validate [dir] check velu.json + content for problems"),console.log(" velu update update velu to the latest version"),U.exit(Bn?1:0)}}Ai().catch(e=>{console.error(U.env.VELU_DEBUG?e:`Error: ${e.message}`),U.exit(1)});
|
package/package.json
CHANGED
|
@@ -179,8 +179,9 @@ function citeTitle(s) {
|
|
|
179
179
|
return seg.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
/* Source click: SPA-navigate same-origin targets via onNavigate (
|
|
183
|
-
|
|
182
|
+
/* Source click: SPA-navigate same-origin targets via onNavigate (host decides
|
|
183
|
+
whether to keep the panel open — desktop multi-cite hops vs mobile sheet
|
|
184
|
+
close); otherwise let the <a href> navigate. */
|
|
184
185
|
function onSourceClick(e, s, onNavigate) {
|
|
185
186
|
const href = sourceHref(s);
|
|
186
187
|
if (!href) { e.preventDefault(); return; }
|
|
@@ -189,7 +190,15 @@ function onSourceClick(e, s, onNavigate) {
|
|
|
189
190
|
const u = new URL(href, window.location.origin);
|
|
190
191
|
if (u.origin === window.location.origin) {
|
|
191
192
|
e.preventDefault();
|
|
192
|
-
|
|
193
|
+
// Prefer the docs route path (e.g. "/installation") over the absolute
|
|
194
|
+
// URL pathname ("/docs/installation"). React Router's basename is
|
|
195
|
+
// already "/docs" on subpath hosts — passing the full pathname makes
|
|
196
|
+
// navigate() produce /docs/docs/... and 404.
|
|
197
|
+
const route =
|
|
198
|
+
s?.path && s.path.startsWith('/')
|
|
199
|
+
? `${s.path}${u.search || ''}${u.hash || ''}`
|
|
200
|
+
: `${u.pathname}${u.search}${u.hash}`;
|
|
201
|
+
onNavigate(route);
|
|
193
202
|
}
|
|
194
203
|
} catch { /* malformed — fall back to href */ }
|
|
195
204
|
}
|
|
@@ -290,17 +290,37 @@ function useScrollEdges(ref) {
|
|
|
290
290
|
return { canLeft, canRight, update };
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
// Normalize a CodeGroup child to plain block props, whether it was authored as
|
|
294
|
+
// an explicit <CodeBlock> OR as a fenced ``` block. A fenced block is rendered
|
|
295
|
+
// by MDX as a <pre> (the `pre` override) wrapping a <code> element, so we pull
|
|
296
|
+
// language + code + meta (data-* stamped by remark-code-meta) off that <code>.
|
|
297
|
+
// Returns null for anything that isn't a code block (stray text/whitespace).
|
|
298
|
+
function codeBlockProps(child) {
|
|
299
|
+
if (!isValidElement(child)) return null;
|
|
300
|
+
if (child.type === CodeBlock || child.type?.displayName === 'CodeBlock') {
|
|
301
|
+
return child.props;
|
|
302
|
+
}
|
|
303
|
+
const codeEl = Children.toArray(child.props?.children)[0];
|
|
304
|
+
const cp = isValidElement(codeEl) ? codeEl.props : null;
|
|
305
|
+
if (!cp || !/language-/.test(cp.className || '')) return null;
|
|
306
|
+
const m = /language-(\S+)/.exec(cp.className || '');
|
|
307
|
+
return {
|
|
308
|
+
language: m ? m[1] : 'text',
|
|
309
|
+
title: cp['data-title'] || cp['data-filename'],
|
|
310
|
+
lineNumbers: 'data-line-numbers' in cp,
|
|
311
|
+
highlight: cp['data-highlight'],
|
|
312
|
+
children:
|
|
313
|
+
typeof cp.children === 'string' ? cp.children.replace(/\n$/, '') : cp.children,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
293
317
|
export function CodeGroup({
|
|
294
318
|
children,
|
|
295
319
|
className = '',
|
|
296
320
|
defaultIndex = 0,
|
|
297
321
|
...rest
|
|
298
322
|
}) {
|
|
299
|
-
const blocks = Children.toArray(children).filter(
|
|
300
|
-
(c) =>
|
|
301
|
-
isValidElement(c) &&
|
|
302
|
-
(c.type === CodeBlock || c.type?.displayName === 'CodeBlock'),
|
|
303
|
-
);
|
|
323
|
+
const blocks = Children.toArray(children).map(codeBlockProps).filter(Boolean);
|
|
304
324
|
const [active, setActive] = useState(defaultIndex);
|
|
305
325
|
const tabsRef = useRef(null);
|
|
306
326
|
const { canLeft, canRight } = useScrollEdges(tabsRef);
|
|
@@ -312,7 +332,7 @@ export function CodeGroup({
|
|
|
312
332
|
lineNumbers = false,
|
|
313
333
|
highlight,
|
|
314
334
|
children: code,
|
|
315
|
-
} = block
|
|
335
|
+
} = block;
|
|
316
336
|
const cls = `velu-code-block velu-code-block--group ${className}`.trim();
|
|
317
337
|
|
|
318
338
|
function scrollDir(dir) {
|
|
@@ -338,15 +358,18 @@ export function CodeGroup({
|
|
|
338
358
|
role="tablist"
|
|
339
359
|
>
|
|
340
360
|
{blocks.map((b, i) => {
|
|
341
|
-
const
|
|
342
|
-
|
|
361
|
+
const tabIcon = pickIcon({
|
|
362
|
+
icon: b.icon,
|
|
363
|
+
withIcon: b.withIcon,
|
|
364
|
+
language: b.language,
|
|
365
|
+
});
|
|
343
366
|
return (
|
|
344
367
|
<Tab
|
|
345
368
|
key={i}
|
|
346
369
|
active={i === active}
|
|
347
370
|
onClick={() => setActive(i)}
|
|
348
371
|
icon={tabIcon}
|
|
349
|
-
label={title || `Tab ${i + 1}`}
|
|
372
|
+
label={b.title || b.filename || `Tab ${i + 1}`}
|
|
350
373
|
/>
|
|
351
374
|
);
|
|
352
375
|
})}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import resolveIcon from '../lib/resolveIcon.jsx';
|
|
3
|
+
|
|
4
|
+
const IMAGE_SOURCE_RE = /^(?:(?:https?:)?\/\/|\/|\.\.?\/|data:image\/)|\.(?:avif|gif|jpe?g|png|svg|webp)(?:[?#].*)?$/i;
|
|
5
|
+
|
|
6
|
+
function cssSize(size) {
|
|
7
|
+
return typeof size === 'number' ? `${size}px` : size;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Icon — an inline Lucide icon or image-backed icon.
|
|
12
|
+
*
|
|
13
|
+
* The public prop shape follows Mintlify's common Icon API. Velu's icon
|
|
14
|
+
* library is Lucide, so `iconType` is accepted for migration compatibility
|
|
15
|
+
* but intentionally has no effect (it only selects Font Awesome variants).
|
|
16
|
+
*/
|
|
17
|
+
export default function Icon({
|
|
18
|
+
icon,
|
|
19
|
+
size = 16,
|
|
20
|
+
color,
|
|
21
|
+
className = '',
|
|
22
|
+
iconType: _iconType,
|
|
23
|
+
style,
|
|
24
|
+
'aria-label': ariaLabel,
|
|
25
|
+
...rest
|
|
26
|
+
}) {
|
|
27
|
+
if (icon == null || icon === '') return null;
|
|
28
|
+
|
|
29
|
+
const dimension = cssSize(size);
|
|
30
|
+
const classes = `velu-icon ${className}`.trim();
|
|
31
|
+
const sharedStyle = {
|
|
32
|
+
width: dimension,
|
|
33
|
+
height: dimension,
|
|
34
|
+
...style,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (typeof icon === 'string' && IMAGE_SOURCE_RE.test(icon)) {
|
|
38
|
+
return (
|
|
39
|
+
<img
|
|
40
|
+
src={icon}
|
|
41
|
+
alt={ariaLabel || ''}
|
|
42
|
+
className={classes}
|
|
43
|
+
style={sharedStyle}
|
|
44
|
+
aria-hidden={ariaLabel ? undefined : true}
|
|
45
|
+
{...rest}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return resolveIcon(icon, {
|
|
51
|
+
size,
|
|
52
|
+
color: color || 'currentColor',
|
|
53
|
+
className: classes,
|
|
54
|
+
style: {
|
|
55
|
+
color: color || undefined,
|
|
56
|
+
...sharedStyle,
|
|
57
|
+
},
|
|
58
|
+
role: ariaLabel ? 'img' : undefined,
|
|
59
|
+
'aria-label': ariaLabel,
|
|
60
|
+
'aria-hidden': ariaLabel ? undefined : true,
|
|
61
|
+
focusable: 'false',
|
|
62
|
+
...rest,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -133,7 +133,7 @@ export default function Image({
|
|
|
133
133
|
variantClass = 'velu-image--chrome';
|
|
134
134
|
} else if (chrome === 'frame') {
|
|
135
135
|
body = <DeviceFrame src={src} alt={effectiveAlt} />;
|
|
136
|
-
variantClass = 'velu-image--chrome';
|
|
136
|
+
variantClass = 'velu-image--chrome velu-image--frame';
|
|
137
137
|
} else {
|
|
138
138
|
body = (
|
|
139
139
|
<img
|
|
@@ -179,6 +179,14 @@
|
|
|
179
179
|
min-inline-size: 0;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
/* Prism grammar names are emitted as token classes. Some of them (for
|
|
183
|
+
example Markdown's `table`) collide with Tailwind display utilities, which
|
|
184
|
+
would turn individual syntax spans into layout boxes. Tokens are always
|
|
185
|
+
inline content regardless of the grammar class attached to them. */
|
|
186
|
+
.velu-code-block__pre .token {
|
|
187
|
+
display: inline;
|
|
188
|
+
}
|
|
189
|
+
|
|
182
190
|
/* ── Syntax token colors ────────────────────────────────────────────────── */
|
|
183
191
|
/* Github-light-ish in light mode, github-dark-ish in dark mode.
|
|
184
192
|
Token classes come from prism-react-renderer's getTokenProps. */
|
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
(effect/tint/shine/content) for chrome bar + device bezel — SVG
|
|
5
5
|
feTurbulence→feDisplacementMap provides the actual refraction. */
|
|
6
6
|
|
|
7
|
-
.velu-image {
|
|
7
|
+
:where(.velu-image) {
|
|
8
8
|
display: block;
|
|
9
|
-
|
|
9
|
+
/* Reset <figure>'s browser margin without outranking the shared
|
|
10
|
+
`.velu-prose > * + *` rhythm. Components should own their internal
|
|
11
|
+
layout; the prose container owns spacing between sibling blocks. */
|
|
12
|
+
margin: 0;
|
|
10
13
|
}
|
|
11
14
|
/* Chrome variants: figure hugs the contained card so the caption
|
|
12
15
|
naturally centers under it instead of under the full content column. */
|
|
@@ -14,6 +17,9 @@
|
|
|
14
17
|
inline-size: fit-content;
|
|
15
18
|
margin-inline: auto;
|
|
16
19
|
}
|
|
20
|
+
.velu-image--frame {
|
|
21
|
+
inline-size: 100%;
|
|
22
|
+
}
|
|
17
23
|
|
|
18
24
|
.velu-image__img {
|
|
19
25
|
display: block;
|
|
@@ -209,18 +215,19 @@
|
|
|
209
215
|
position: relative;
|
|
210
216
|
display: flex;
|
|
211
217
|
justify-content: center;
|
|
218
|
+
box-sizing: border-box;
|
|
219
|
+
inline-size: 100%;
|
|
212
220
|
padding: var(--s-1);
|
|
213
221
|
border-radius: var(--radius-lg);
|
|
214
222
|
overflow: hidden;
|
|
215
223
|
background: var(--surface-color);
|
|
216
|
-
max-inline-size: 18rem;
|
|
217
224
|
margin-inline: auto;
|
|
218
225
|
}
|
|
219
226
|
/* Bezel: concentric with outer card. */
|
|
220
227
|
.velu-image__frame-bezel {
|
|
221
228
|
position: relative;
|
|
222
229
|
z-index: 1;
|
|
223
|
-
inline-size:
|
|
230
|
+
inline-size: 100%;
|
|
224
231
|
max-inline-size: 100%;
|
|
225
232
|
border-radius: calc(var(--radius-lg) - var(--s-1));
|
|
226
233
|
}
|
package/runtime/velu-ui/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { default as ContextMenu } from './components/ContextMenu.jsx';
|
|
|
8
8
|
export { default as Toc } from './components/Toc.jsx';
|
|
9
9
|
export { default as TocBar } from './components/TocBar.jsx';
|
|
10
10
|
export { default as Callout } from './components/Callout.jsx';
|
|
11
|
+
export { default as Icon } from './components/Icon.jsx';
|
|
11
12
|
export { default as ErrorCard } from './components/ErrorCard.jsx';
|
|
12
13
|
export { default as Logo } from './components/Logo.jsx';
|
|
13
14
|
export { default as SocialLinks } from './components/SocialLinks.jsx';
|
|
@@ -18,6 +18,7 @@ const SCHEMAS = {
|
|
|
18
18
|
Callout: { enums: { type: { values: CALLOUT_TYPES, caseSensitive: true } } },
|
|
19
19
|
MethodBadge: { enums: { method: { values: METHOD_NAMES, caseSensitive: false } } },
|
|
20
20
|
ApiPath: { enums: { method: { values: METHOD_NAMES, caseSensitive: false } } },
|
|
21
|
+
Icon: { required: ['icon'] },
|
|
21
22
|
Image: { required: ['src'] },
|
|
22
23
|
};
|
|
23
24
|
|
|
@@ -8,6 +8,7 @@ import Prompt from './components/Prompt.jsx';
|
|
|
8
8
|
import Steps, { Step } from './components/Steps.jsx';
|
|
9
9
|
import Tree, { Folder, File } from './components/Tree.jsx';
|
|
10
10
|
import Update from './components/Update.jsx';
|
|
11
|
+
import Icon from './components/Icon.jsx';
|
|
11
12
|
import Image from './components/Image.jsx';
|
|
12
13
|
import CodeBlock, { CodeGroup } from './components/CodeBlock.jsx';
|
|
13
14
|
import MethodBadge from './components/MethodBadge.jsx';
|
|
@@ -41,15 +42,22 @@ import { validateProps } from './lib/component-schemas.js';
|
|
|
41
42
|
and forward children verbatim to CodeBlock. */
|
|
42
43
|
function PreOverride({ children }) {
|
|
43
44
|
const child = React.Children.only(children);
|
|
44
|
-
const
|
|
45
|
-
const m = /language-(\S+)/.exec(className);
|
|
45
|
+
const p = child?.props || {};
|
|
46
|
+
const m = /language-(\S+)/.exec(p.className || '');
|
|
46
47
|
const language = m ? m[1] : undefined;
|
|
47
48
|
const code =
|
|
48
|
-
typeof
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
typeof p.children === 'string' ? p.children.replace(/\n$/, '') : p.children;
|
|
50
|
+
// Fence meta (filename/title, line numbers, highlight) is stamped onto the
|
|
51
|
+
// <code> element as data-* by the remark-code-meta plugin (velu-cli). Forward
|
|
52
|
+
// it so a plain ```lang block can still carry a header + line highlighting.
|
|
51
53
|
return (
|
|
52
|
-
<CodeBlock
|
|
54
|
+
<CodeBlock
|
|
55
|
+
language={language}
|
|
56
|
+
filename={p['data-filename']}
|
|
57
|
+
title={p['data-title']}
|
|
58
|
+
lineNumbers={'data-line-numbers' in p}
|
|
59
|
+
highlight={p['data-highlight']}
|
|
60
|
+
>
|
|
53
61
|
{code}
|
|
54
62
|
</CodeBlock>
|
|
55
63
|
);
|
|
@@ -93,6 +101,7 @@ export const defaultMdxComponents = {
|
|
|
93
101
|
Folder,
|
|
94
102
|
File,
|
|
95
103
|
Update,
|
|
104
|
+
Icon: checked('Icon', Icon),
|
|
96
105
|
Image: checked('Image', Image),
|
|
97
106
|
CodeBlock,
|
|
98
107
|
CodeGroup,
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
@import './components/context-menu.css';
|
|
25
25
|
@import './components/accordion.css';
|
|
26
26
|
@import './components/card.css';
|
|
27
|
+
@import './components/icon.css';
|
|
27
28
|
@import './components/image.css';
|
|
28
29
|
@import './components/code-block.css';
|
|
29
30
|
@import './components/field.css';
|
package/src/runtime/App.jsx
CHANGED
|
@@ -1277,6 +1277,16 @@ function DocsPage() {
|
|
|
1277
1277
|
`inset-block-end: 0` override still wins. */
|
|
1278
1278
|
'--velu-aside-bottom': `calc(${footerOverlap}px + var(--s4))`,
|
|
1279
1279
|
}}
|
|
1280
|
+
// Close the mobile drawer as soon as a nav link is activated.
|
|
1281
|
+
// The pathname effect below also closes it on route change; this
|
|
1282
|
+
// covers same-route hash jumps and feels snappier on touch devices.
|
|
1283
|
+
onClick={(e) => {
|
|
1284
|
+
if (!drawerOpen) return;
|
|
1285
|
+
const a = e.target.closest?.('a[href]');
|
|
1286
|
+
if (!a) return;
|
|
1287
|
+
setDrawerOpen(false);
|
|
1288
|
+
setNavOpen(false);
|
|
1289
|
+
}}
|
|
1280
1290
|
>
|
|
1281
1291
|
{/* Drawer body — Stack with 32px gap composes the slots
|
|
1282
1292
|
(topbar / tab-dropdown / context / nav). The aside is a flex
|
|
@@ -1732,7 +1742,27 @@ function DocsPage() {
|
|
|
1732
1742
|
loadConversation={assistant?.loadConversation}
|
|
1733
1743
|
suggestions={site.assistant?.suggestions}
|
|
1734
1744
|
onNavigate={(to) => {
|
|
1735
|
-
|
|
1745
|
+
// Strip the Vite base path so react-router basename is not applied
|
|
1746
|
+
// twice (e.g. "/docs/installation" → "/installation" when
|
|
1747
|
+
// BASE_PATH="/docs"). Absolute Ask-AI citation URLs include /docs.
|
|
1748
|
+
let dest = to || '/';
|
|
1749
|
+
if (BASE_PATH) {
|
|
1750
|
+
if (dest === BASE_PATH || dest === `${BASE_PATH}/`) dest = '/';
|
|
1751
|
+
else if (dest.startsWith(`${BASE_PATH}/`)) {
|
|
1752
|
+
dest = dest.slice(BASE_PATH.length) || '/';
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
navigate(dest);
|
|
1756
|
+
// Ask AI becomes a bottom sheet below 1024px (chatbot.css) and covers
|
|
1757
|
+
// the article — close it so the user lands on the linked page, not
|
|
1758
|
+
// behind the sheet. Desktop keeps the panel open so multi-cite hops
|
|
1759
|
+
// stay convenient.
|
|
1760
|
+
if (
|
|
1761
|
+
typeof window !== 'undefined' &&
|
|
1762
|
+
window.matchMedia('(max-width: 1024px)').matches
|
|
1763
|
+
) {
|
|
1764
|
+
setChatOpen(false);
|
|
1765
|
+
}
|
|
1736
1766
|
// After the destination page mounts, scroll to the cited section
|
|
1737
1767
|
// (its heading id) — or the top of the page when there's no anchor.
|
|
1738
1768
|
const hash = to.includes('#') ? to.slice(to.indexOf('#') + 1) : '';
|