@veluai/velu 0.2.15 → 0.2.19

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 CHANGED
@@ -1,34 +1,36 @@
1
1
  #!/usr/bin/env node
2
- var hn=Object.defineProperty;var A=(e,t)=>()=>(e&&(t=e(e=0)),t);var Fe=(e,t)=>{for(var r in t)hn(e,r,{get:t[r],enumerable:!0})};var ct={};Fe(ct,{initProject:()=>xn});import D from"node:fs/promises";import X from"node:path";import{fileURLToPath as yn}from"node:url";async function xn(e,t){try{if((await D.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 D.mkdir(e,{recursive:!0}),await D.cp(bn,e,{recursive:!0});let r=X.join(e,"velu.json"),n=JSON.parse(await D.readFile(r,"utf-8"));n.name=t,await D.writeFile(r,JSON.stringify(n,null,2)+`
3
- `,"utf-8");let o=await lt(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 lt(e,t=e,r=[]){let n=await D.readdir(e,{withFileTypes:!0});for(let o of n){let i=X.join(e,o.name);o.isDirectory()?await lt(i,t,r):r.push(X.relative(t,i).split(X.sep).join("/"))}return r.sort()}var vn,bn,ut=A(()=>{vn=X.dirname(yn(import.meta.url)),bn=X.resolve(vn,"..","templates","starter")});function te(e){if(!e||typeof e!="object")return null;let t=[];if(e.socials&&typeof e.socials=="object")for(let[n,o]of Object.entries(e.socials))typeof o!="string"||!o.trim()||t.push({kind:$n[n]??n,href:o.trim()});let r=Array.isArray(e.links)?e.links.filter(n=>n&&typeof n=="object").map(n=>({title:(n.header??n.title??"").trim(),items:(Array.isArray(n.items)?n.items:[]).filter(o=>o&&o.label).map(o=>({label:o.label,href:o.href??"#"}))})).filter(n=>n.title||n.items.length):[];return!t.length&&!r.length?null:{socials:t,links:r}}function Ne(e){return/^(https?:)?\/\//.test(e)||/^(mailto|tel):/.test(e)}function ne(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:Ne(o.href.trim())})),r=null,n=e.primary;if(n&&typeof n=="object"&&typeof n.href=="string"&&n.href.trim()){let o=n.href.trim();r=n.type==="github"?{kind:"github",label:n.label??"GitHub",href:o,external:Ne(o)}:{kind:"button",label:n.label??"",href:o,external:Ne(o)}}return!t.length&&!r?null:{links:t,primary:r}}function Ie(e){if(e==null)return{options:[...pt],display:"header"};if(typeof e!="object")return{options:[],display:"header"};let t=e.display==="toc"?"toc":"header",r=Array.isArray(e.options)?e.options:pt,n=[];for(let o of r)typeof o=="string"?wn.has(o)&&n.push(o):o&&typeof o=="object"&&o.title&&o.href&&n.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:n,display:t}}function I(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 re(e){if(!e||typeof e!="object")return null;let t=typeof e.apiBase=="string"&&e.apiBase.trim()?e.apiBase.trim().replace(/\/+$/,""):null,r=typeof e.host=="string"&&e.host.trim()?e.host.trim():null,n=Array.isArray(e.suggestions)?e.suggestions.filter(o=>typeof o=="string"&&o.trim()).map(o=>o.trim()).slice(0,6):[];return!t&&!n.length?null:{apiBase:t,host:r,suggestions:n}}var $n,wn,pt,he=A(()=>{$n={twitter:"x","x-twitter":"x"};wn=new Set(["copy","assistant","view","download-pdf","download-spec","chatgpt","claude","perplexity","grok","aistudio","devin","windsurf","mcp","add-mcp","cursor","vscode","devin-mcp"]),pt=["copy","view","chatgpt","claude"]});import Sn from"node:fs/promises";import Re from"node:path";function ft(e){if(!e.favicon)return null;let t=Re.extname(e.favicon).toLowerCase();return{url:Ue+t,type:jn[t]||""}}function oe(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?.(),r=(e.dark??e.light)?.trim?.();return!t||!r?null:{light:t,dark:r,href:e.href?.trim?.()||"/"}}return null}function On(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 Me(e={},t){let r=e.colors?.primary??kn;return{name:e.name??t??"docs",url:typeof e.url=="string"&&e.url.trim()?e.url.trim().replace(/\/+$/,""):null,seo:On(e.seo),assistant:re(e.assistant),thumbnails:e.thumbnails&&typeof e.thumbnails=="object"&&typeof e.thumbnails.background=="string"?{background:e.thumbnails.background}:null,colors:{primary:r,light:e.colors?.light??r,dark:e.colors?.dark??r},favicon:e.favicon??null,api:I(e.api),logo:oe(e.logo),footer:te(e.footer),navbar:ne(e.navbar),font:{family:e.font?.family??An},navigation:e.navigation??null}}async function mt(e){let t=Re.join(e,"velu.json"),r;try{r=await Sn.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 n;try{n=JSON.parse(r)}catch(o){throw new Error(`velu.json is not valid JSON: ${o.message}`)}return Me(n,Re.basename(e))}function dt(e){let{colors:t,font:r}=e;return[":root:root {",` --accent-color: ${t.light};`,` --font-sans: "${r.family}", sans-serif;`,"}",':root:root[data-theme="dark"] {',` --accent-color: ${t.dark};`,"}"].join(`
4
- `)}var kn,An,ye,ve,Ue,jn,ie=A(()=>{he();he();kn="#dc143c",An="Google Sans Flex",ye="/@velu-logo-light",ve="/@velu-logo-dark",Ue="/@velu-favicon",jn={".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 Tn}from"unist-util-visit";import{toString as Ln}from"mdast-util-to-string";import Pn from"github-slugger";import{valueToEstree as _n}from"estree-util-value-to-estree";function se(){return e=>{let t=new Pn,r=[];Tn(e,"heading",a=>{let s=Ln(a);r.push({depth:a.depth,id:t.slug(s),label:s})});let n={children:[]},o=[{node:n,depth:0}];for(let a of r){for(;o.length>1&&o[o.length-1].depth>=a.depth;)o.pop();let s={id:a.id,label:a.label},l=o[o.length-1].node;l.children||(l.children=[]),l.children.push(s),o.push({node:s,depth:a.depth})}let i=n.children;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:"toc"},init:_n(i)}]}}]}}})}}var ze=A(()=>{});import Cn from"github-slugger";import En from"iso-639-1";function Nn(e){let t=String(e).toLowerCase();return En.getNativeName(t)||e}function be(e){return new Cn().slug(String(e??""))}function In(e){let t=String(e).replace(/^\/+|\/+$/g,"").split("/").filter(Boolean);return t[t.length-1]==="index"&&t.pop(),"/"+t.join("/")}function gt(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 M(e){let t={kind:"root",children:ae(e??{})};return vt(t.children),t}function ae(e){let t=Array.isArray(e.anchors)?e.anchors.map(Bn):[];if(Array.isArray(e.products))return[...t,...e.products.map(Rn)];if(Array.isArray(e.versions))return[...t,...e.versions.map(Un)];if(Array.isArray(e.languages))return[...t,...e.languages.map(Mn)];if(Array.isArray(e.tabs))return[...t,...e.tabs.map(zn)];let r=[...t];return Array.isArray(e.groups)&&r.push(...e.groups.map(ht)),Array.isArray(e.pages)&&r.push(...e.pages.map(yt)),r}function Rn(e){return{kind:"product",label:e.name??e.product,slug:be(e.product),icon:e.icon,color:e.color,default:!!e.default,children:ae(e)}}function Un(e){return{kind:"version",label:e.version,slug:be(e.version),default:!!e.default,children:ae(e)}}function Mn(e){let t=String(e.language);return{kind:"language",code:t,label:Nn(t),slug:be(t),default:!!e.default,children:ae(e)}}function zn(e){return{kind:"tab",label:e.tab,slug:be(e.tab),icon:e.icon,href:e.href,children:ae(e)}}function Bn(e){return{kind:"anchor",label:e.anchor,icon:e.icon,href:e.href,color:e.color}}function ht(e){let t=(e.pages??[]).map(yt);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 yt(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 vt(e){for(let t of Fn){let r=e.filter(n=>n.kind===t);r.length&&!r.some(n=>n.default)&&(r[0].default=!0)}for(let t of e)t.children&&vt(t.children)}function W(e){let t=[],r=(n,o,i)=>{if(n.kind==="page"){t.push({pagePath:n.pagePath,url:Gn(n.pagePath,o),ctx:{...o},ancestors:i,node:n});return}let a=o;n.kind==="product"?a={...o,product:n.default?null:n.slug}:n.kind==="version"?a={...o,version:n.default?null:n.slug}:n.kind==="language"&&(a={...o,language:n.default?null:n.slug});let s=n.kind==="root"?i:[...i,n];for(let l of n.children??[])r(l,a,s)};return r(e,{product:null,version:null,language:null},[]),t}function Gn(e,t){let r=[t.product,t.version,t.language].filter(Boolean),n=In(e).split("/").filter(Boolean);return"/"+[...r,...n].join("/")}var Fn,B=A(()=>{Fn=["product","version","language"]});import Jn from"node:fs";import bt from"node:path";function z(e,t){let r=[],n=[],o=new Set;for(let i of W(e)){if(i.node?.api){o.add(i.url);continue}if(o.has(i.url)){r.push(`duplicate URL "${i.url}" (page "${i.pagePath}") \u2014 keeping the first occurrence`);continue}o.add(i.url);let a=i.pagePath.replace(/^\/+|\/+$/g,""),s=bt.join(t,...a.split("/"))+".mdx",l=Jn.existsSync(s);l||r.push(`page "${i.pagePath}" \u2192 ${bt.relative(t,s)} not found`),n.push({pagePath:i.pagePath,url:i.url,fileAbsPath:s,exists:l})}return{pageEntries:n,warnings:r}}var le=A(()=>{B()});function G(e){return!e||typeof e!="object"?e||{}:Array.isArray(e.allOf)?e.allOf.reduce((t,r)=>{let n=G(r);return{...t,...n,properties:{...t.properties||{},...n.properties||{}},required:[...t.required||[],...n.required||[]]}},{...e,allOf:void 0}):Array.isArray(e.oneOf)&&e.oneOf.length?G(e.oneOf[0]):Array.isArray(e.anyOf)&&e.anyOf.length?G(e.anyOf[0]):e}function ce(e){let t=G(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`${ce(t.items||{})}[]`;let r=t.type||(t.properties?"object":"any");return t.format?`${r}<${t.format}>`:r}function Y(e,t=0){let r=G(e);if(!r||typeof r!="object")return null;if(r.example!==void 0)return r.example;if(r.default!==void 0)return r.default;if(Array.isArray(r.enum)&&r.enum.length)return r.enum[0];if(t>=6)return r.type==="object"?{}:null;switch(r.type){case"object":{let n={};for(let[o,i]of Object.entries(r.properties||{}))n[o]=Y(i,t+1);return n}case"array":return[Y(r.items||{},t+1)];case"integer":case"number":return 0;case"boolean":return!0;default:return qn(r)}}function qn(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 Be(e){let t=G(e);if(!t||t.type!=="object"||!t.properties)return t&&(t.type||t.items)?[{name:"body",type:ce(t),required:!1,description:t.description||""}]:[];let r=new Set(t.required||[]);return Object.entries(t.properties).map(([n,o])=>{let i=G(o);return{name:n,type:ce(i),required:r.has(n),description:i.description||"",enum:Array.isArray(i.enum)?i.enum:void 0,deprecated:i.deprecated||void 0}})}function Hn(e){let t=e.schema||{};return{name:e.name,in:e.in,required:e.in==="path"?!0:!!e.required,type:ce(t),description:e.description||"",enum:Array.isArray(t.enum)?t.enum:void 0,example:Y(t),deprecated:e.deprecated||void 0}}function $t(e){if(!e||typeof e!="object")return null;let t=Object.keys(e),r=t.find(n=>/json/i.test(n))||t[0];return r?{contentType:r,media:e[r]}:null}function Dn(e){if(!e)return null;let t=$t(e.content);if(!t)return null;let r=t.media.schema||{};return{required:!!e.required,description:e.description||"",contentType:t.contentType,fields:Be(r),example:t.media.example??Y(r)}}function Xn(e){return!e||typeof e!="object"?[]:Object.entries(e).map(([t,r])=>{let n=$t(r?.content),o=n?.media?.schema||{};return{status:t,description:r?.description||"",contentType:n?.contentType||null,fields:n?Be(o):[],example:n?n.media.example??Y(o):null}})}function Wn(e,t){if(!Array.isArray(e)||!t)return[];let r=[],n=new Set;for(let o of e)for(let i of Object.keys(o||{})){let a=t[i];!a||n.has(i)||(n.add(i),r.push(Yn(i,a)))}return r.filter(Boolean)}function Yn(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 xt(e){return String(e).replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function Kn(e){let{method:t,path:r,op:n,sharedParams:o,servers:i,schemes:a}=e,s=[...o||[],...n.parameters||[]],l={path:[],query:[],header:[],cookie:[]};for(let c of s)c&&l[c.in]&&l[c.in].push(Hn(c));let p=n.security??e.globalSecurity;return{id:n.operationId?xt(n.operationId):`${t}-${xt(r)}`,method:t.toUpperCase(),path:r,title:n.summary||n.operationId||`${t.toUpperCase()} ${r}`,description:n.description||n.summary||"",tags:Array.isArray(n.tags)&&n.tags.length?n.tags:["API"],deprecated:n.deprecated||!1,auth:Wn(p,a),parameters:l,body:Dn(n.requestBody),responses:Xn(n.responses),servers:(i||[]).map(c=>c.url).filter(Boolean)}}function Zn(e,t,r,n,o,i,a){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 l=(n.servers||i||[]).filter(Boolean);l.length&&(s.servers=l);let p={};Array.isArray(o)&&o.length&&(p.parameters=o),p[r]=n,s.paths={[t]:p};let c=n.security??e.security;if(a&&Array.isArray(c)&&c.length){let u={};for(let x of c)for(let d of Object.keys(x||{}))a[d]&&(u[d]=a[d]);Object.keys(u).length&&(e.swagger?s.securityDefinitions=u:s.components={securitySchemes:u})}return s}function wt(e){let t=[],r=[],n=e.components?.securitySchemes||e.securityDefinitions||{},o=e.security||[],i=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]);for(let[a,s]of Object.entries(e.paths||{})){if(!s||typeof s!="object")continue;let l=s.parameters||[],p=s.servers||i;for(let c of Vn){let u=s[c];!u||typeof u!="object"||(t.push(Kn({method:c,path:a,op:u,sharedParams:l,servers:u.servers||p,globalSecurity:o,schemes:n})),r.push(Zn(e,a,c,u,l,u.servers||p,n)))}}return{operations:t,segments:r}}function Ge(e){let t=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]),{operations:r,segments:n}=wt(e);return{title:e.info?.title||"API Reference",version:e.info?.version||"",servers:t.map(o=>o.url).filter(Boolean),operations:r,segments:n}}var Vn,Je=A(()=>{Vn=["get","post","put","patch","delete","options","head","trace"]});import Qn from"@apidevtools/swagger-parser";async function er(e){return Qn.dereference(e)}async function St(e){return Ge(await er(e))}var kt=A(()=>{Je();Je()});function tr(e,{server:t}={}){let n=`${(t||e.servers?.[0]||"").replace(/\/+$/,"")}${e.path}`,o={};for(let a of e.auth||[])a.in==="header"&&(o[a.name]=a.prefix?`${a.prefix} <token>`:"<token>");for(let a of e.parameters?.header||[])o[a.name]||(o[a.name]=String(a.example??`<${a.type}>`));let i=!!e.body;return i&&(o["Content-Type"]=e.body.contentType||"application/json"),{method:e.method,url:n,headers:o,body:i?e.body.example??{}:null}}function nr(e){let t=`curl --request ${e.method} \\
5
- --url ${e.url}`;for(let[r,n]of Object.entries(e.headers))t+=` \\
6
- --header '${r}: ${n}'`;return e.body!=null&&(t+=` \\
7
- --data '${JSON.stringify(e.body)}'`),t}function rr(e){let t=[` method: '${e.method}'`];if(Object.keys(e.headers).length){let r=Object.entries(e.headers).map(([n,o])=>` '${n}': '${o}'`).join(`,
2
+ var En=Object.defineProperty;var A=(e,t)=>()=>(e&&(t=e(e=0)),t);var ye=(e,t)=>{for(var n in t)En(e,n,{get:t[n],enumerable:!0})};var vt={};ye(vt,{initProject:()=>Un});import Y from"node:fs/promises";import W from"node:path";import{fileURLToPath as Cn}from"node:url";async function Un(e,t){try{if((await Y.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 Y.mkdir(e,{recursive:!0}),await Y.cp(Nn,e,{recursive:!0});let n=W.join(e,"velu.json"),r=JSON.parse(await Y.readFile(n,"utf-8"));r.name=t,await Y.writeFile(n,JSON.stringify(r,null,2)+`
3
+ `,"utf-8");let o=await yt(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 yt(e,t=e,n=[]){let r=await Y.readdir(e,{withFileTypes:!0});for(let o of r){let i=W.join(e,o.name);o.isDirectory()?await yt(i,t,n):n.push(W.relative(t,i).split(W.sep).join("/"))}return n.sort()}var Fn,Nn,bt=A(()=>{Fn=W.dirname(Cn(import.meta.url)),Nn=W.resolve(Fn,"..","templates","starter")});var Be={};ye(Be,{currentVersion:()=>Ie,getLatestVersion:()=>ze,isNewer:()=>Me,maybeAutoUpdate:()=>Xn,updateCommand:()=>Wn});import{spawnSync as $t}from"node:child_process";import{readFileSync as wt,writeFileSync as Rn,mkdirSync as In}from"node:fs";import{fileURLToPath as Mn}from"node:url";import{homedir as zn,tmpdir as Bn}from"node:os";import Re from"node:path";import N from"node:process";function Ie(){try{return JSON.parse(wt(new URL("../package.json",import.meta.url),"utf8")).version}catch{return"unknown"}}function Hn(e,t){let n=i=>String(i).split("-")[0].split(".").map(a=>Number(a)||0),r=n(e),o=n(t);for(let i=0;i<3;i++){let a=(r[i]||0)-(o[i]||0);if(a!==0)return a<0?-1:1}return 0}function Me(e,t){return!e||!t||t==="unknown"?!1:Hn(e,t)>0}function St(){let e=Re.join(zn()||Bn(),".velu");return Re.join(e,"update-check.json")}function xt(){try{return JSON.parse(wt(St(),"utf8"))}catch{return null}}function qn(e){try{let t=St();In(Re.dirname(t),{recursive:!0}),Rn(t,JSON.stringify(e))}catch{}}async function Dn(){let e=`${Gn}/-/package/${ve}/dist-tags`,t=new AbortController,n=setTimeout(()=>t.abort(),Jn);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 ze({force:e=!1}={}){if(!e){let n=xt();if(n?.latest&&Date.now()-(n.checkedAt||0)<Vn)return n.latest}let t=await Dn();return t?(qn({latest:t,checkedAt:Date.now()}),t):xt()?.latest??null}function kt(){let e=N.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=Mn(import.meta.url).replace(/\\/g,"/")}catch{}return t.includes("/pnpm/")?"pnpm":t.includes("/yarn/")||t.includes("/.yarn/")?"yarn":t.includes("/.bun/")?"bun":"npm"}function Yn(e){let t=`${ve}@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 At(e){let[t,n]=Yn(e);return $t(t,n,{stdio:"inherit",shell:N.platform==="win32"}).status===0}async function Wn(){let e=Ie(),t=await ze({force:!0});if(t&&!Me(t,e)){console.log(`velu is already up to date (v${e}).`);return}let n=kt();console.log(t?`Updating velu ${e} \u2192 ${t} (via ${n})\u2026`:`Could not reach the npm registry; installing ${ve}@latest (via ${n}) anyway\u2026`),At(n)?console.log('\u2713 Updated. Run "velu version" to confirm.'):(console.error("Update failed. You can update manually with:"),console.error(` npm install -g ${ve}@latest`),N.exitCode=1)}async function Xn(){if(N.env.VELU_NO_UPDATE==="1"||N.env.VELU_UPDATED==="1"||!N.stdout.isTTY)return;let e=Ie();if(e==="unknown")return;let t=null;try{t=await ze()}catch{return}if(!Me(t,e))return;let n=kt();if(console.log(`
4
+ New velu version available: ${e} \u2192 ${t}. Updating\u2026`),!At(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(N.execPath,N.argv.slice(1),{stdio:"inherit",env:{...N.env,VELU_UPDATED:"1"}});N.exit(r.status??0)}var ve,Gn,Vn,Jn,Ge=A(()=>{ve="@veluai/velu",Gn="https://registry.npmjs.org",Vn=720*60*1e3,Jn=3e3});function Je({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 ne(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:Kn[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 Ve(e){return/^(https?:)?\/\//.test(e)||/^(mailto|tel):/.test(e)}function re(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:Ve(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:Ve(o)}:{kind:"button",label:r.label??"",href:o,external:Ve(o)}}return!t.length&&!n?null:{links:t,primary:n}}function He(e){if(e==null)return{options:[...jt],display:"header"};if(typeof e!="object")return{options:[],display:"header"};let t=e.display==="toc"?"toc":"header",n=Array.isArray(e.options)?e.options:jt,r=[];for(let o of n)typeof o=="string"?Zn.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 R(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 oe(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 Kn,Zn,jt,be=A(()=>{Kn={twitter:"x","x-twitter":"x"};Zn=new Set(["copy","assistant","view","download-pdf","download-spec","chatgpt","claude","perplexity","grok","aistudio","devin","windsurf","mcp","add-mcp","cursor","vscode","devin-mcp"]),jt=["copy","view","chatgpt","claude"]});import Qn from"node:fs/promises";import qe from"node:path";function Ot(e){if(!e.favicon)return null;let t=qe.extname(e.favicon).toLowerCase();return{url:De+t,type:nr[t]||""}}function ie(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 rr(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 Ye(e={},t){let n=e.colors?.primary??er;return{name:e.name??t??"docs",url:typeof e.url=="string"&&e.url.trim()?e.url.trim().replace(/\/+$/,""):null,seo:rr(e.seo),assistant:oe(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:R(e.api),logo:ie(e.logo),footer:ne(e.footer),navbar:re(e.navbar),font:{family:e.font?.family??tr},navigation:e.navigation??null}}async function Tt(e){let t=qe.join(e,"velu.json"),n;try{n=await Qn.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 Ye(r,qe.basename(e))}function Lt(e){let{colors:t,font:n}=e;return Je({light:t.light,dark:t.dark,family:n.family})}var er,tr,xe,$e,De,nr,se=A(()=>{be();be();er="#dc143c",tr="Google Sans Flex",xe="/@velu-logo-light",$e="/@velu-logo-dark",De="/@velu-favicon",nr={".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 or}from"unist-util-visit";import{toString as ir}from"mdast-util-to-string";import sr from"github-slugger";import{valueToEstree as ar}from"estree-util-value-to-estree";function ae(){return e=>{let t=new sr,n=[];or(e,"heading",a=>{let s=ir(a);n.push({depth:a.depth,id:t.slug(s),label:s})});let r={children:[]},o=[{node:r,depth:0}];for(let a of n){for(;o.length>1&&o[o.length-1].depth>=a.depth;)o.pop();let s={id:a.id,label:a.label},l=o[o.length-1].node;l.children||(l.children=[]),l.children.push(s),o.push({node:s,depth:a.depth})}let i=r.children;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:"toc"},init:ar(i)}]}}]}}})}}var We=A(()=>{});import lr from"github-slugger";import cr from"iso-639-1";function pr(e){let t=String(e).toLowerCase();return cr.getNativeName(t)||e}function we(e){return new lr().slug(String(e??""))}function fr(e){let t=String(e).replace(/^\/+|\/+$/g,"").split("/").filter(Boolean);return t[t.length-1]==="index"&&t.pop(),"/"+t.join("/")}function _t(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 z(e){let t={kind:"root",children:le(e??{})};return Ct(t.children),t}function le(e){let t=Array.isArray(e.anchors)?e.anchors.map(yr):[];if(Array.isArray(e.products))return[...t,...e.products.map(mr)];if(Array.isArray(e.versions))return[...t,...e.versions.map(dr)];if(Array.isArray(e.languages))return[...t,...e.languages.map(gr)];if(Array.isArray(e.tabs))return[...t,...e.tabs.map(hr)];let n=[...t];return Array.isArray(e.groups)&&n.push(...e.groups.map(Pt)),Array.isArray(e.pages)&&n.push(...e.pages.map(Et)),n}function mr(e){return{kind:"product",label:e.name??e.product,slug:we(e.product),icon:e.icon,color:e.color,default:!!e.default,children:le(e)}}function dr(e){return{kind:"version",label:e.version,slug:we(e.version),default:!!e.default,children:le(e)}}function gr(e){let t=String(e.language);return{kind:"language",code:t,label:pr(t),slug:we(t),default:!!e.default,children:le(e)}}function hr(e){return{kind:"tab",label:e.tab,slug:we(e.tab),icon:e.icon,href:e.href,children:le(e)}}function yr(e){return{kind:"anchor",label:e.anchor,icon:e.icon,href:e.href,color:e.color}}function Pt(e){let t=(e.pages??[]).map(Et);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 Et(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}:Pt(e)}function Ct(e){for(let t of ur){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&&Ct(t.children)}function X(e){let t=[],n=(r,o,i)=>{if(r.kind==="page"){t.push({pagePath:r.pagePath,url:vr(r.pagePath,o),ctx:{...o},ancestors:i,node:r});return}let a=o;r.kind==="product"?a={...o,product:r.default?null:r.slug}:r.kind==="version"?a={...o,version:r.default?null:r.slug}:r.kind==="language"&&(a={...o,language:r.default?null:r.slug});let s=r.kind==="root"?i:[...i,r];for(let l of r.children??[])n(l,a,s)};return n(e,{product:null,version:null,language:null},[]),t}function vr(e,t){let n=[t.product,t.version,t.language].filter(Boolean),r=fr(e).split("/").filter(Boolean);return"/"+[...n,...r].join("/")}var ur,G=A(()=>{ur=["product","version","language"]});import br from"node:fs";import Ft from"node:path";function B(e,t){let n=[],r=[],o=new Set;for(let i of X(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 a=i.pagePath.replace(/^\/+|\/+$/g,""),s=Ft.join(t,...a.split("/"))+".mdx",l=br.existsSync(s);l||n.push(`page "${i.pagePath}" \u2192 ${Ft.relative(t,s)} not found`),r.push({pagePath:i.pagePath,url:i.url,fileAbsPath:s,exists:l})}return{pageEntries:r,warnings:n}}var ce=A(()=>{G()});function V(e){return!e||typeof e!="object"?e||{}:Array.isArray(e.allOf)?e.allOf.reduce((t,n)=>{let r=V(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?V(e.oneOf[0]):Array.isArray(e.anyOf)&&e.anyOf.length?V(e.anyOf[0]):e}function ue(e){let t=V(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`${ue(t.items||{})}[]`;let n=t.type||(t.properties?"object":"any");return t.format?`${n}<${t.format}>`:n}function K(e,t=0){let n=V(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]=K(i,t+1);return r}case"array":return[K(n.items||{},t+1)];case"integer":case"number":return 0;case"boolean":return!0;default:return $r(n)}}function $r(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 Xe(e){let t=V(e);if(!t||t.type!=="object"||!t.properties)return t&&(t.type||t.items)?[{name:"body",type:ue(t),required:!1,description:t.description||""}]:[];let n=new Set(t.required||[]);return Object.entries(t.properties).map(([r,o])=>{let i=V(o);return{name:r,type:ue(i),required:n.has(r),description:i.description||"",enum:Array.isArray(i.enum)?i.enum:void 0,deprecated:i.deprecated||void 0}})}function wr(e){let t=e.schema||{};return{name:e.name,in:e.in,required:e.in==="path"?!0:!!e.required,type:ue(t),description:e.description||"",enum:Array.isArray(t.enum)?t.enum:void 0,example:K(t),deprecated:e.deprecated||void 0}}function Ut(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 Sr(e){if(!e)return null;let t=Ut(e.content);if(!t)return null;let n=t.media.schema||{};return{required:!!e.required,description:e.description||"",contentType:t.contentType,fields:Xe(n),example:t.media.example??K(n)}}function kr(e){return!e||typeof e!="object"?[]:Object.entries(e).map(([t,n])=>{let r=Ut(n?.content),o=r?.media?.schema||{};return{status:t,description:n?.description||"",contentType:r?.contentType||null,fields:r?Xe(o):[],example:r?r.media.example??K(o):null}})}function Ar(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 a=t[i];!a||r.has(i)||(r.add(i),n.push(jr(i,a)))}return n.filter(Boolean)}function jr(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 Nt(e){return String(e).replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function Or(e){let{method:t,path:n,op:r,sharedParams:o,servers:i,schemes:a}=e,s=[...o||[],...r.parameters||[]],l={path:[],query:[],header:[],cookie:[]};for(let c of s)c&&l[c.in]&&l[c.in].push(wr(c));let p=r.security??e.globalSecurity;return{id:r.operationId?Nt(r.operationId):`${t}-${Nt(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:Ar(p,a),parameters:l,body:Sr(r.requestBody),responses:kr(r.responses),servers:(i||[]).map(c=>c.url).filter(Boolean)}}function Tr(e,t,n,r,o,i,a){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 l=(r.servers||i||[]).filter(Boolean);l.length&&(s.servers=l);let p={};Array.isArray(o)&&o.length&&(p.parameters=o),p[n]=r,s.paths={[t]:p};let c=r.security??e.security;if(a&&Array.isArray(c)&&c.length){let u={};for(let b of c)for(let d of Object.keys(b||{}))a[d]&&(u[d]=a[d]);Object.keys(u).length&&(e.swagger?s.securityDefinitions=u:s.components={securitySchemes:u})}return s}function Rt(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[a,s]of Object.entries(e.paths||{})){if(!s||typeof s!="object")continue;let l=s.parameters||[],p=s.servers||i;for(let c of xr){let u=s[c];!u||typeof u!="object"||(t.push(Or({method:c,path:a,op:u,sharedParams:l,servers:u.servers||p,globalSecurity:o,schemes:r})),n.push(Tr(e,a,c,u,l,u.servers||p,r)))}}return{operations:t,segments:n}}function Ke(e){let t=e.servers||(e.host?[{url:`https://${e.host}${e.basePath||""}`}]:[]),{operations:n,segments:r}=Rt(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 xr,Ze=A(()=>{xr=["get","post","put","patch","delete","options","head","trace"]});import Lr from"@apidevtools/swagger-parser";async function _r(e){return Lr.dereference(e)}async function It(e){return Ke(await _r(e))}var Mt=A(()=>{Ze();Ze()});function Pr(e,{server:t}={}){let r=`${(t||e.servers?.[0]||"").replace(/\/+$/,"")}${e.path}`,o={};for(let a of e.auth||[])a.in==="header"&&(o[a.name]=a.prefix?`${a.prefix} <token>`:"<token>");for(let a of e.parameters?.header||[])o[a.name]||(o[a.name]=String(a.example??`<${a.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 Er(e){let t=`curl --request ${e.method} \\
7
+ --url ${e.url}`;for(let[n,r]of Object.entries(e.headers))t+=` \\
8
+ --header '${n}: ${r}'`;return e.body!=null&&(t+=` \\
9
+ --data '${JSON.stringify(e.body)}'`),t}function Cr(e){let t=[` method: '${e.method}'`];if(Object.keys(e.headers).length){let n=Object.entries(e.headers).map(([r,o])=>` '${r}': '${o}'`).join(`,
8
10
  `);t.push(` headers: {
9
- ${r}
10
- }`)}return e.body!=null&&t.push(` body: JSON.stringify(${Ve(e.body," ")})`),[`const res = await fetch('${e.url}', {`,t.join(`,
11
+ ${n}
12
+ }`)}return e.body!=null&&t.push(` body: JSON.stringify(${Qe(e.body," ")})`),[`const res = await fetch('${e.url}', {`,t.join(`,
11
13
  `),"});","const data = await res.json();"].join(`
12
- `)}function or(e){let t=["import requests","",`url = "${e.url}"`];if(Object.keys(e.headers).length){let n=Object.entries(e.headers).map(([o,i])=>` "${o}": "${i}"`).join(`,
14
+ `)}function Fr(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(`,
13
15
  `);t.push(`headers = {
14
- ${n}
15
- }`)}let r=["url"];return e.body!=null&&(t.push(`payload = ${Ve(e.body,"")}`),r.push("json=payload")),Object.keys(e.headers).length&&r.push("headers=headers"),t.push("",`response = requests.${e.method.toLowerCase()}(${r.join(", ")})`,"print(response.json())"),t.join(`
16
- `)}function ir(e){let t=e.method.charAt(0)+e.method.slice(1).toLowerCase(),r=["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[n,o]of Object.entries(e.headers))r.push(`request['${n}'] = '${o}'`);return e.body!=null&&r.push(`request.body = ${Ve(e.body,"")}.to_json`),r.push("","response = http.request(request)","puts response.body"),r.join(`
17
- `)}function jt(e,{server:t,languages:r=qe}={}){let n=tr(e,{server:t});return r.filter(o=>At[o]).map(o=>({key:o,label:sr[o],language:ar[o],code:At[o](n)}))}var Ve,At,sr,ar,qe,Ot=A(()=>{Ve=(e,t)=>JSON.stringify(e,null,2).split(`
18
- `).map((r,n)=>n===0?r:t+r).join(`
19
- `);At={curl:nr,javascript:rr,python:or,ruby:ir},sr={curl:"cURL",javascript:"JavaScript",python:"Python",ruby:"Ruby"},ar={curl:"bash",javascript:"javascript",python:"python",ruby:"ruby"},qe=["curl","javascript","python","ruby"]});function Tt(e,t){if(!t||typeof t!="object")return e;let r=I(t);return{server:t.server!=null?r.server:e?.server??null,proxy:t.playground!=null?r.proxy:e?.proxy!==!1,languages:t.examples?.languages!=null?r.languages:e?.languages}}function lr(e,{base:t,api:r,ops:n}){let o=r?.server,i=r?.languages||qe,a={proxy:r?.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 l=[];for(let[p,c]of s){let u=c.map(({op:x,segment:d})=>{let $=`${t}/${He(p)}/${x.id}`;return n[$]={operation:x,samples:jt(x,{server:o||x.servers?.[0],languages:i}),segment:d,title:x.title,description:x.description,method:x.method,api:a},{apiPage:$,label:x.title,method:x.method}});l.push({group:p,pages:u})}return l}async function Lt(e,{loadOps:t,base:r,api:n,ops:o}){let i=Array.isArray(e)?e:[e],a=[];for(let s of i){let{operations:l,segments:p,servers:c}=await t(s);l.forEach((u,x)=>{!u.servers?.length&&c?.length&&(u.servers=c),a.push({op:u,segment:p[x]})})}return lr(a,{base:r,api:n,ops:o})}async function Pt(e,t){if(!e||typeof e!="object")return e;if(typeof e.tab=="string"&&e.openapi){let n=He(e.tab),o=Tt(t.api,e.api),i=await Lt(e.openapi,{...t,base:n,api:o}),{openapi:a,api:s,...l}=e;return{...l,groups:[...l.groups||[],...i]}}if(typeof e.group=="string"&&e.openapi){let n=He(e.group),o=Tt(t.api,e.api),i=await Lt(e.openapi,{...t,base:n,api:o}),{openapi:a,api:s,...l}=e,p=i.flatMap(c=>c.pages);return{...l,pages:[...l.pages||[],...p]}}let r={...e};for(let n of["products","versions","languages","tabs","groups"])Array.isArray(e[n])&&(r[n]=await Promise.all(e[n].map(o=>Pt(o,t))));return r}async function _t(e,{api:t,loadOps:r}){let n={};return!e||typeof e!="object"?{nav:e,ops:n}:{nav:await Pt(e,{api:t,loadOps:r,ops:n}),ops:n}}var He,Ct=A(()=>{he();Ot();He=e=>String(e??"").replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"x"});import cr from"node:path";function ur(e,t){return/^https?:\/\//.test(e)?e:cr.resolve(t,e.replace(/^\/+/,""))}async function xe(e,{targetDir:t,api:r}={}){return _t(e,{api:r,loadOps:n=>St(ur(n,t))})}var De=A(()=>{kt();Ct()});import pr from"node:fs";import ue from"node:path";function Nt(e){return{name:"velu-site",resolveId(t){return t===Ft?Et:null},async load(t){return t!==Et?null:fr(e)}}}async function fr(e){let t={};try{t=JSON.parse(pr.readFileSync(ue.join(e,"velu.json"),"utf-8"))}catch{}let r=I(t.api),n=t.navigation??{},o={};try{let b=await xe(t.navigation??{},{targetDir:e,api:r});n=b.nav,o=b.ops}catch(b){console.warn(`[velu] openapi: ${b.message}`)}let i=M(n),{pageEntries:a,warnings:s}=z(i,e);for(let b of s)console.warn(`[velu] nav: ${b}`);let l=oe(t.logo),p={name:t.name??ue.basename(e),logo:l?{light:ye,dark:ve,href:l.href,mono:l.light===l.dark}:null,footer:te(t.footer),navbar:ne(t.navbar),contextual:Ie(t.contextual),assistant:re(t.assistant)},c=[],u=[],x=0;for(let b of a){if(!b.exists)continue;let y=JSON.stringify(b.fileAbsPath.split(ue.sep).join("/")),f=JSON.stringify(ue.relative(e,b.fileAbsPath).split(ue.sep).join("/")),g=`__p${x++}`;c.push(`import * as ${g} from ${y};`),u.push(` ${JSON.stringify(b.url)}: { Component: ${g}.default, frontmatter: ${g}.frontmatter, toc: ${g}.toc, relPath: ${f} },`)}let d=new Set(a.filter(b=>b.exists).map(b=>b.url));for(let b of a)!b.exists&&!d.has(b.url)&&u.push(` ${JSON.stringify(b.url)}: { missing: true },`);let $=[],m=[],L=[],h=!1,w=0;for(let b of W(i)){if(!b.node?.api)continue;let y=o[b.pagePath];if(!y)continue;h=!0;let f=`__op${w}`,g=`__samples${w}`,v=`__api${w}`;w+=1,$.push(`const ${f} = ${JSON.stringify(y.operation)};`),$.push(`const ${g} = ${JSON.stringify(y.samples)};`),L.push(`{ id: ${JSON.stringify(y.operation.id)}, method: ${JSON.stringify(y.operation.method)}, title: ${JSON.stringify(y.operation.title)}, url: ${JSON.stringify(b.url)}, operation: ${f}, samples: ${g}, api: ${JSON.stringify(y.api||{proxy:!0,server:null})} }`),m.push(`function ${v}(){ return React.createElement(ApiReferencePage, { operation: ${f}, samples: ${g}, apiOperations: __apiOperations, api: ${JSON.stringify(y.api||{proxy:!0,server:null})} }); }`),u.push(` ${JSON.stringify(b.url)}: { Component: ${v}, frontmatter: { title: ${JSON.stringify(y.title)}, description: ${JSON.stringify(y.description)} }, toc: [], operation: ${f}, samples: ${g}, api: true },`)}h&&($.push(`const __apiOperations = [
16
+ ${r}
17
+ }`)}let n=["url"];return e.body!=null&&(t.push(`payload = ${Qe(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 Nr(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 = ${Qe(e.body,"")}.to_json`),n.push("","response = http.request(request)","puts response.body"),n.join(`
19
+ `)}function Bt(e,{server:t,languages:n=et}={}){let r=Pr(e,{server:t});return n.filter(o=>zt[o]).map(o=>({key:o,label:Ur[o],language:Rr[o],code:zt[o](r)}))}var Qe,zt,Ur,Rr,et,Gt=A(()=>{Qe=(e,t)=>JSON.stringify(e,null,2).split(`
20
+ `).map((n,r)=>r===0?n:t+n).join(`
21
+ `);zt={curl:Er,javascript:Cr,python:Fr,ruby:Nr},Ur={curl:"cURL",javascript:"JavaScript",python:"Python",ruby:"Ruby"},Rr={curl:"bash",javascript:"javascript",python:"python",ruby:"ruby"},et=["curl","javascript","python","ruby"]});function Vt(e,t){if(!t||typeof t!="object")return e;let n=R(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 Ir(e,{base:t,api:n,ops:r}){let o=n?.server,i=n?.languages||et,a={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 l=[];for(let[p,c]of s){let u=c.map(({op:b,segment:d})=>{let x=`${t}/${tt(p)}/${b.id}`;return r[x]={operation:b,samples:Bt(b,{server:o||b.servers?.[0],languages:i}),segment:d,title:b.title,description:b.description,method:b.method,api:a},{apiPage:x,label:b.title,method:b.method}});l.push({group:p,pages:u})}return l}async function Jt(e,{loadOps:t,base:n,api:r,ops:o}){let i=Array.isArray(e)?e:[e],a=[];for(let s of i){let{operations:l,segments:p,servers:c}=await t(s);l.forEach((u,b)=>{!u.servers?.length&&c?.length&&(u.servers=c),a.push({op:u,segment:p[b]})})}return Ir(a,{base:n,api:r,ops:o})}async function Ht(e,t){if(!e||typeof e!="object")return e;if(typeof e.tab=="string"&&e.openapi){let r=tt(e.tab),o=Vt(t.api,e.api),i=await Jt(e.openapi,{...t,base:r,api:o}),{openapi:a,api:s,...l}=e;return{...l,groups:[...l.groups||[],...i]}}if(typeof e.group=="string"&&e.openapi){let r=tt(e.group),o=Vt(t.api,e.api),i=await Jt(e.openapi,{...t,base:r,api:o}),{openapi:a,api:s,...l}=e,p=i.flatMap(c=>c.pages);return{...l,pages:[...l.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=>Ht(o,t))));return n}async function qt(e,{api:t,loadOps:n}){let r={};return!e||typeof e!="object"?{nav:e,ops:r}:{nav:await Ht(e,{api:t,loadOps:n,ops:r}),ops:r}}var tt,Dt=A(()=>{be();Gt();tt=e=>String(e??"").replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"x"});import Mr from"node:path";function zr(e,t){return/^https?:\/\//.test(e)?e:Mr.resolve(t,e.replace(/^\/+/,""))}async function Se(e,{targetDir:t,api:n}={}){return qt(e,{api:n,loadOps:r=>It(zr(r,t))})}var nt=A(()=>{Mt();Dt()});import Br from"node:fs";import pe from"node:path";function Xt(e){return{name:"velu-site",resolveId(t){return t===Wt?Yt:null},async load(t){return t!==Yt?null:Gr(e)}}}async function Gr(e){let t={};try{t=JSON.parse(Br.readFileSync(pe.join(e,"velu.json"),"utf-8"))}catch{}let n=R(t.api),r=t.navigation??{},o={};try{let $=await Se(t.navigation??{},{targetDir:e,api:n});r=$.nav,o=$.ops}catch($){console.warn(`[velu] openapi: ${$.message}`)}let i=z(r),{pageEntries:a,warnings:s}=B(i,e);for(let $ of s)console.warn(`[velu] nav: ${$}`);let l=ie(t.logo),p={name:t.name??pe.basename(e),logo:l?{light:xe,dark:$e,href:l.href,mono:l.light===l.dark}:null,footer:ne(t.footer),navbar:re(t.navbar),contextual:He(t.contextual),assistant:oe(t.assistant)},c=[],u=[],b=0;for(let $ of a){if(!$.exists)continue;let y=JSON.stringify($.fileAbsPath.split(pe.sep).join("/")),f=JSON.stringify(pe.relative(e,$.fileAbsPath).split(pe.sep).join("/")),g=`__p${b++}`;c.push(`import * as ${g} from ${y};`),u.push(` ${JSON.stringify($.url)}: { Component: ${g}.default, frontmatter: ${g}.frontmatter, toc: ${g}.toc, relPath: ${f} },`)}let d=new Set(a.filter($=>$.exists).map($=>$.url));for(let $ of a)!$.exists&&!d.has($.url)&&u.push(` ${JSON.stringify($.url)}: { missing: true },`);let x=[],m=[],L=[],h=!1,w=0;for(let $ of X(i)){if(!$.node?.api)continue;let y=o[$.pagePath];if(!y)continue;h=!0;let f=`__op${w}`,g=`__samples${w}`,v=`__api${w}`;w+=1,x.push(`const ${f} = ${JSON.stringify(y.operation)};`),x.push(`const ${g} = ${JSON.stringify(y.samples)};`),L.push(`{ id: ${JSON.stringify(y.operation.id)}, method: ${JSON.stringify(y.operation.method)}, title: ${JSON.stringify(y.operation.title)}, url: ${JSON.stringify($.url)}, operation: ${f}, samples: ${g}, api: ${JSON.stringify(y.api||{proxy:!0,server:null})} }`),m.push(`function ${v}(){ return React.createElement(ApiReferencePage, { operation: ${f}, samples: ${g}, apiOperations: __apiOperations, api: ${JSON.stringify(y.api||{proxy:!0,server:null})} }); }`),u.push(` ${JSON.stringify($.url)}: { Component: ${v}, frontmatter: { title: ${JSON.stringify(y.title)}, description: ${JSON.stringify(y.description)} }, toc: [], operation: ${f}, samples: ${g}, api: true },`)}h&&(x.push(`const __apiOperations = [
20
22
  ${L.join(`,
21
23
  `)}
22
- ];`),$.push(m.join(`
24
+ ];`),x.push(m.join(`
23
25
  `)));let F=[];return h&&(F.push("import React from 'react';"),F.push("import { ApiReferencePage } from 'velu-ui';")),["// AUTO-GENERATED by vite-plugin-velu-site. Do not edit.",F.join(`
24
26
  `),c.join(`
25
- `),$.join(`
27
+ `),x.join(`
26
28
  `),"","export const pages = {",u.join(`
27
29
  `),"};",`export const navigation = ${JSON.stringify(i)};`,`export const site = ${JSON.stringify(p)};`,""].join(`
28
- `)}var Ft,Et,It=A(()=>{B();le();ie();De();Ft="virtual:velu-site",Et="\0"+Ft});import{visit as mr}from"unist-util-visit";function dr(e,t){let r=Rt(e).replace(/[?#].*$/,""),n=Rt(t).replace(/\/+$/,"");return n&&r.toLowerCase().startsWith(n.toLowerCase())?r.slice(n.length).replace(/^\/+/,""):null}function Ut(e,t){return()=>(r,n)=>{typeof e=="function"&&mr(r,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 a=e(o.name,i,{checkRequired:!1});if(a){let s=new Error(a.title);throw s.veluIssue={...a,file:dr(n?.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 Rt,Mt=A(()=>{Rt=e=>String(e||"").replace(/\\/g,"/")});import $e from"node:path";import gr from"node:fs";import{createRequire as hr}from"node:module";import yr from"@tailwindcss/vite";import vr from"@vitejs/plugin-react";import br from"@mdx-js/rollup";import xr from"remark-frontmatter";import $r from"remark-mdx-frontmatter";import wr from"remark-gfm";import Sr from"rehype-slug";function kr(e){let r=hr(import.meta.url).resolve("@mdx-js/react"),n=$e.resolve(e,"runtime","velu-ui"),o=gr.existsSync(n)?n:$e.resolve(e,"..","velu-ui","src");return[{find:"@mdx-js/react",replacement:r},{find:/^velu-ui$/,replacement:$e.join(o,"index.js")},{find:/^velu-ui\//,replacement:o+"/"}]}function zt({targetDir:e,VITE_ROOT:t,validateProps:r}){return{root:t,plugins:[Nt(e),br({remarkPlugins:[xr,$r,wr,se,Ut(r,e)],rehypePlugins:[Sr],providerImportSource:"@mdx-js/react"}),vr(),yr({optimize:!1})],cacheDir:$e.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:kr(t),dedupe:["react","react-dom","@mdx-js/react"]}}}var Bt=A(()=>{ze();It();Mt()});function j(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 Ar(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 r=Array.from({length:t.length+1},(o,i)=>i),n=new Array(t.length+1);for(let o=1;o<=e.length;o++){n[0]=o;for(let i=1;i<=t.length;i++){let a=e[o-1]===t[i-1]?0:1;n[i]=Math.min(n[i-1]+1,r[i]+1,r[i-1]+a)}[r,n]=[n,r]}return r[t.length]}function we(e,t=[]){if(!e)return null;let r=String(e).toLowerCase(),n=null,o=1/0;for(let a of t){let s=Ar(r,String(a).toLowerCase());s<o&&(o=s,n=a)}let i=Math.min(3,Math.max(2,Math.floor(r.length/4)));return o<=i?n:null}function jr(e,t){return e==="warning"?E(t,C.yellow,"\u26A0"):e==="info"?E(t,C.cyan,"\u2139"):E(t,C.red,"\u2716")}function We(e,{color:t=!1}={}){let r=Xe[e.category]||e.category,n=e.line?`${e.line}${e.column?`:${e.column}`:""}`:"",o=e.file?`${e.file}${n?`:${n}`:""}`:n,i=[];if(i.push(`${jr(e.severity,t)} ${E(t,C.bold,r)}`+(o?` ${E(t,C.dim,o)}`:"")),e.title&&i.push(` ${e.title}`),e.detail&&e.detail!==e.title&&i.push(` ${E(t,C.dim,e.detail)}`),e.frame)for(let a of String(e.frame).split(`
29
- `))i.push(` ${a}`);return e.suggestion&&i.push(` ${E(t,C.cyan,`Did you mean <${e.suggestion}>?`)}`),e.hint&&i.push(` ${E(t,C.dim,`\u2192 ${e.hint}`)}`),i.join(`
30
- `)}function Se(e,{color:t=!1}={}){if(!e.length)return E(t,C.cyan,"\u2713 No issues found.");let r=new Map;for(let s of e){let l=s.file||"velu.json";r.has(l)||r.set(l,[]),r.get(l).push(s)}let n=[];for(let[s,l]of r){n.push(E(t,C.bold,s));for(let p of l)n.push(We({...p,file:null},{color:t}).replace(/^/gm," "));n.push("")}let o=e.filter(s=>s.severity!=="warning"&&s.severity!=="info").length,i=e.length-o,a=`${o} error${o===1?"":"s"}`+(i?`, ${i} warning${i===1?"":"s"}`:"");return n.push(E(t,o?C.red:C.yellow,a)),n.join(`
31
- `)}var Xe,C,E,J=A(()=>{Xe={"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"};C={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m",bold:"\x1B[1m"},E=(e,t,r)=>e?`${t}${r}${C.reset}`:r});function Or(e){let t=e,r=0;for(;t&&t.cause&&r<3&&!(t.loc||t.line||/`[^`]+` to be defined/.test(t.message||""));)t=t.cause,r+=1;return t||e}function Ye(e,t){if(!e)return null;let r=Gt(e).replace(/[?#].*$/,""),n=t?Gt(t).replace(/\/+$/,""):"";return n&&r.toLowerCase().startsWith(n.toLowerCase())?r.slice(n.length).replace(/^\/+/,""):!/^([a-zA-Z]:\/|\/)/.test(r)&&!/node_modules/.test(r)?r:null}function Tr(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 Lr(e){let t=/\((\d+):(\d+)(?:-\d+:\d+)?\)\s*$/.exec(String(e||""));return t?{line:Number(t[1]),column:Number(t[2])}:null}function Pr(e){return String(e||"").replace(/\s*\(\d+:\d+(?:-\d+:\d+)?\)\s*$/,"").trim()}function Cr(e,t){if(!e||!t)return null;let r=String(e);return/node_modules|[\\/]vite[\\/]|@veluai[\\/]/.test(r)?null:r}function pe(e,t={}){let{projectDir:r="",knownComponents:n=[],file:o=null}=t,i=null;for(let h=e,w=0;h&&w<6;h=h.cause,w+=1)if(h.veluIssue){i=h.veluIssue;break}if(i)return j({...i,file:i.file||o});let a=Or(e)||{},s=a.message||String(e||""),l=/Expected component `([^`]+)` to be defined/.exec(s);if(l){let h=l[1],w=/referenced in your code at `(\d+):(\d+)/.exec(s),F=/\bin `([^`]+)`/.exec(s),b=F?Ye(F[1],r):null;return j({category:"unknown-component",file:b||o,line:w?Number(w[1]):null,column:w?Number(w[2]):null,title:`<${h}> is not a built-in component`,detail:"",hint:"Components are built in \u2014 check the spelling and capitalization (you don\u2019t import them).",suggestion:we(h,n)})}let p=a.loc||(a.line!=null?{line:a.line,column:a.column,file:a.file}:null)||Lr(a.reason||s),c=a.id||p&&p.file||a.file||null,u=Ye(c,r)||o,x=!!u&&Ye(c,r)!=null,d=Cr(a.frame,x||!!o),$=Tr(Pr(a.reason||s)),m=_r.test(s),L=a.source==="remark-frontmatter"||/\byaml\b|frontmatter/i.test(s)||p&&p.line===1&&/unexpected|expected/i.test(s)&&/---/.test(s);return p||m||d&&x?j({category:L?"frontmatter":"mdx-syntax",file:u,line:p?p.line:null,column:p?p.column:null,frame:d,title:$||(L?"Invalid frontmatter":"MDX syntax error"),detail:"",hint:L?"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)?j({category:"invalid-props",file:u,title:"A component received an invalid value",detail:$,hint:"Check the props/options you passed to a component on this page."}):j({category:"render-crash",file:u,title:"This page failed to render",detail:$,hint:"Set VELU_DEBUG=1 for the full stack trace."})}var Gt,_r,Ke=A(()=>{J();Gt=e=>String(e).replace(/\\/g,"/");_r=/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 Er(e){let t=Xe[e.category]||e.category,r=e.file?`${e.file}${e.line?`:${e.line}${e.column?`:${e.column}`:""}`:""}`:"",n=[];return n.push('<div class="velu-err-card">'),n.push('<div class="velu-err-head">'),n.push(`<span class="velu-err-pill">${R(t)}</span>`),n.push("</div>"),e.title&&n.push(`<div class="velu-err-title">${R(e.title)}</div>`),r&&n.push(`<a class="velu-err-loc" title="${R(r)}">${R(r)}</a>`),e.detail&&n.push(`<div class="velu-err-detail">${R(e.detail)}</div>`),e.frame&&n.push(`<pre class="velu-err-frame">${R(e.frame)}</pre>`),e.suggestion&&n.push(`<div class="velu-err-suggest">Did you mean <code>&lt;${R(e.suggestion)}&gt;</code>?</div>`),e.hint&&n.push(`<div class="velu-err-hint">${R(e.hint)}</div>`),n.push("</div>"),n.join("")}function Ze(e,t={}){let r=Array.isArray(e)?e:[e],n=t.title||(r.length>1?`${r.length} problems to fix`:"There\u2019s a problem to fix"),o=r.map(Er).join(`
30
+ `)}var Wt,Yt,Kt=A(()=>{G();ce();se();nt();Wt="virtual:velu-site",Yt="\0"+Wt});import{visit as Vr}from"unist-util-visit";function Jr(e,t){let n=Zt(e).replace(/[?#].*$/,""),r=Zt(t).replace(/\/+$/,"");return r&&n.toLowerCase().startsWith(r.toLowerCase())?n.slice(r.length).replace(/^\/+/,""):null}function Qt(e,t){return()=>(n,r)=>{typeof e=="function"&&Vr(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 a=e(o.name,i,{checkRequired:!1});if(a){let s=new Error(a.title);throw s.veluIssue={...a,file:Jr(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 Zt,en=A(()=>{Zt=e=>String(e||"").replace(/\\/g,"/")});import ke from"node:path";import Hr from"node:fs";import{createRequire as qr}from"node:module";import Dr from"@tailwindcss/vite";import Yr from"@vitejs/plugin-react";import Wr from"@mdx-js/rollup";import Xr from"remark-frontmatter";import Kr from"remark-mdx-frontmatter";import Zr from"remark-gfm";import Qr from"rehype-slug";function eo(e){let n=qr(import.meta.url).resolve("@mdx-js/react"),r=ke.resolve(e,"runtime","velu-ui"),o=Hr.existsSync(r)?r:ke.resolve(e,"..","velu-ui","src");return[{find:"@mdx-js/react",replacement:n},{find:/^velu-ui$/,replacement:ke.join(o,"index.js")},{find:/^velu-ui\//,replacement:o+"/"}]}function tn({targetDir:e,VITE_ROOT:t,validateProps:n}){return{root:t,plugins:[Xt(e),Wr({remarkPlugins:[Xr,Kr,Zr,ae,Qt(n,e)],rehypePlugins:[Qr],providerImportSource:"@mdx-js/react"}),Yr(),Dr({optimize:!1})],cacheDir:ke.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:eo(t),dedupe:["react","react-dom","@mdx-js/react"]}}}var nn=A(()=>{We();Kt();en()});function j(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 to(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 a=e[o-1]===t[i-1]?0:1;r[i]=Math.min(r[i-1]+1,n[i]+1,n[i-1]+a)}[n,r]=[r,n]}return n[t.length]}function Ae(e,t=[]){if(!e)return null;let n=String(e).toLowerCase(),r=null,o=1/0;for(let a of t){let s=to(n,String(a).toLowerCase());s<o&&(o=s,r=a)}let i=Math.min(3,Math.max(2,Math.floor(n.length/4)));return o<=i?r:null}function no(e,t){return e==="warning"?C(t,E.yellow,"\u26A0"):e==="info"?C(t,E.cyan,"\u2139"):C(t,E.red,"\u2716")}function ot(e,{color:t=!1}={}){let n=rt[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(`${no(e.severity,t)} ${C(t,E.bold,n)}`+(o?` ${C(t,E.dim,o)}`:"")),e.title&&i.push(` ${e.title}`),e.detail&&e.detail!==e.title&&i.push(` ${C(t,E.dim,e.detail)}`),e.frame)for(let a of String(e.frame).split(`
31
+ `))i.push(` ${a}`);return e.suggestion&&i.push(` ${C(t,E.cyan,`Did you mean <${e.suggestion}>?`)}`),e.hint&&i.push(` ${C(t,E.dim,`\u2192 ${e.hint}`)}`),i.join(`
32
+ `)}function je(e,{color:t=!1}={}){if(!e.length)return C(t,E.cyan,"\u2713 No issues found.");let n=new Map;for(let s of e){let l=s.file||"velu.json";n.has(l)||n.set(l,[]),n.get(l).push(s)}let r=[];for(let[s,l]of n){r.push(C(t,E.bold,s));for(let p of l)r.push(ot({...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,a=`${o} error${o===1?"":"s"}`+(i?`, ${i} warning${i===1?"":"s"}`:"");return r.push(C(t,o?E.red:E.yellow,a)),r.join(`
33
+ `)}var rt,E,C,J=A(()=>{rt={"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"};E={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m",bold:"\x1B[1m"},C=(e,t,n)=>e?`${t}${n}${E.reset}`:n});function ro(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 it(e,t){if(!e)return null;let n=rn(e).replace(/[?#].*$/,""),r=t?rn(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 oo(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 io(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 lo(e,t){if(!e||!t)return null;let n=String(e);return/node_modules|[\\/]vite[\\/]|@veluai[\\/]/.test(n)?null:n}function fe(e,t={}){let{projectDir:n="",knownComponents:r=[],file:o=null}=t,i=null;for(let h=e,w=0;h&&w<6;h=h.cause,w+=1)if(h.veluIssue){i=h.veluIssue;break}if(i)return j({...i,file:i.file||o});let a=ro(e)||{},s=a.message||String(e||""),l=/Expected component `([^`]+)` to be defined/.exec(s);if(l){let h=l[1],w=/referenced in your code at `(\d+):(\d+)/.exec(s),F=/\bin `([^`]+)`/.exec(s),$=F?it(F[1],n):null;return j({category:"unknown-component",file:$||o,line:w?Number(w[1]):null,column:w?Number(w[2]):null,title:`<${h}> is not a built-in component`,detail:"",hint:"Components are built in \u2014 check the spelling and capitalization (you don\u2019t import them).",suggestion:Ae(h,r)})}let p=a.loc||(a.line!=null?{line:a.line,column:a.column,file:a.file}:null)||io(a.reason||s),c=a.id||p&&p.file||a.file||null,u=it(c,n)||o,b=!!u&&it(c,n)!=null,d=lo(a.frame,b||!!o),x=oo(so(a.reason||s)),m=ao.test(s),L=a.source==="remark-frontmatter"||/\byaml\b|frontmatter/i.test(s)||p&&p.line===1&&/unexpected|expected/i.test(s)&&/---/.test(s);return p||m||d&&b?j({category:L?"frontmatter":"mdx-syntax",file:u,line:p?p.line:null,column:p?p.column:null,frame:d,title:x||(L?"Invalid frontmatter":"MDX syntax error"),detail:"",hint:L?"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)?j({category:"invalid-props",file:u,title:"A component received an invalid value",detail:x,hint:"Check the props/options you passed to a component on this page."}):j({category:"render-crash",file:u,title:"This page failed to render",detail:x,hint:"Set VELU_DEBUG=1 for the full stack trace."})}var rn,ao,st=A(()=>{J();rn=e=>String(e).replace(/\\/g,"/");ao=/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 co(e){let t=rt[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">${I(t)}</span>`),r.push("</div>"),e.title&&r.push(`<div class="velu-err-title">${I(e.title)}</div>`),n&&r.push(`<a class="velu-err-loc" title="${I(n)}">${I(n)}</a>`),e.detail&&r.push(`<div class="velu-err-detail">${I(e.detail)}</div>`),e.frame&&r.push(`<pre class="velu-err-frame">${I(e.frame)}</pre>`),e.suggestion&&r.push(`<div class="velu-err-suggest">Did you mean <code>&lt;${I(e.suggestion)}&gt;</code>?</div>`),e.hint&&r.push(`<div class="velu-err-hint">${I(e.hint)}</div>`),r.push("</div>"),r.join("")}function at(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(co).join(`
32
34
  `);return`<!doctype html>
33
35
  <html lang="en">
34
36
  <head>
@@ -95,26 +97,26 @@ ${L.join(`,
95
97
  <body>
96
98
  <div class="velu-err-wrap">
97
99
  <div class="velu-err-brand">velu</div>
98
- <h1 class="velu-err-h">${R(n)}</h1>
100
+ <h1 class="velu-err-h">${I(r)}</h1>
99
101
  ${o}
100
102
  <div class="velu-err-foot">Fix the file and save \u2014 this page reloads automatically.</div>
101
103
  </div>
102
104
  </body>
103
- </html>`}var R,Jt=A(()=>{J();R=e=>String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")});var V,Qe=A(()=>{V=["Callout","Card","CardGroup","Accordion","AccordionGroup","Columns","Field","Prompt","Steps","Step","Tree","Folder","File","Image","CodeBlock","CodeGroup","MethodBadge","ApiPath","TryItBar","ApiField","ApiClient","ApiSidebar"]});import ke from"node:fs";import me from"node:path";import{fileURLToPath as Fr}from"node:url";import Nr from"iso-639-1";function fe(e,t){if(!t)return null;let r=e.indexOf(`"${t}"`);return r===-1?null:e.slice(0,r).split(`
104
- `).length}function Ur(e,t){return t==null||t<0?null:e.slice(0,t).split(`
105
- `).length}function et(e,t){if(!t)return null;let r=e.indexOf(`"${t}"`);return r===-1?null:e.slice(0,r).split(`
106
- `).length}function Mr(e,t,r){let n=[];return s(e,t,"",null),n;function o(l){if(l&&l.$ref){let p=l.$ref.replace(/^#\//,"").split("/"),c=r;for(let u of p)c=c?.[u];return c||{}}return l}function i(l){return Array.isArray(l)?"array":l===null?"null":typeof l}function a(l,p){let c=n.length;s(l,p,"",null,!0);let u=n.length===c;return u||(n.length=c),u}function s(l,p,c,u,x){let d=o(p);if(d){if(d.oneOf){d.oneOf.some(m=>a(l,m))||n.push({path:c,key:u,message:"value does not match any allowed shape"});return}if(d.type&&i(l)!==d.type){n.push({path:c,key:u,message:`expected ${d.type}, got ${i(l)}`});return}if(d.type==="string"&&d.minLength!=null&&l.length<d.minLength&&n.push({path:c,key:u,message:"must not be empty"}),d.type==="object"&&i(l)==="object"){for(let m of d.required||[])m in l||n.push({path:c?`${c}.${m}`:m,key:m,message:`missing required "${m}"`});let $=d.properties||{};if(d.additionalProperties===!1)for(let m of Object.keys(l))m in $||n.push({path:c?`${c}.${m}`:m,key:m,message:`unknown field "${m}"`});for(let[m,L]of Object.entries($))m in l&&s(l[m],L,c?`${c}.${m}`:m,m,x)}d.type==="array"&&Array.isArray(l)&&d.items&&l.forEach(($,m)=>s($,d.items,`${c}[${m}]`,u,x))}}}function zr(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 Ae(e){let t=[],r=me.join(e,"velu.json"),n;try{n=ke.readFileSync(r,"utf-8")}catch(s){return s.code==="ENOENT"?t.push(j({category:"config-json",file:"velu.json",title:"No velu.json found",hint:"Run `velu init <name>` to scaffold a project."})):t.push(j({category:"config-json",file:"velu.json",title:"Could not read velu.json"})),t}let o;try{o=JSON.parse(n)}catch(s){let l=/position (\d+)/.exec(s.message||""),p=l?Ur(n,Number(l[1])):null;return t.push(j({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(ke.readFileSync(Rr,"utf-8"))}catch{}if(i)for(let s of Mr(o,i,i)){let l=/^unknown field/.test(s.message);t.push(j({category:"config-schema",severity:l?"warning":"error",file:"velu.json",line:fe(n,s.key),title:s.path?`${s.path}: ${s.message}`:s.message,hint:l?"Remove it, or check the spelling against the velu.json schema.":""}))}for(let s of["primary","light","dark"]){let l=o.colors?.[s];l!=null&&!zr(l)&&t.push(j({category:"config-schema",severity:"warning",file:"velu.json",line:fe(n,s),title:`colors.${s}: "${l}" 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=me.resolve(e,o.favicon.replace(/^\/+/,""));ke.existsSync(s)||t.push(j({category:"config-asset",file:"velu.json",line:fe(n,"favicon"),title:`favicon not found: ${o.favicon}`,hint:"The path is relative to the project root."}))}let a=oe(o.logo);if(a){let s=new Map;for(let l of["light","dark"]){let p=a[l];p&&s.set(p,[...s.get(p)||[],l])}for(let[l,p]of s)if(!ke.existsSync(me.resolve(e,l.replace(/^\/+/,"")))){let c=p.length===2?"logo":`logo (${p[0]})`;t.push(j({category:"config-asset",file:"velu.json",line:et(n,l),title:`${c} not found: ${l}`,hint:"The path is relative to the project root."}))}}if(o.navigation&&typeof o.navigation=="object"){let s;try{s=M(o.navigation)}catch(l){t.push(j({category:"config-nav",file:"velu.json",line:fe(n,"navigation"),title:"navigation could not be processed",detail:String(l.message||"")})),s=null}if(s){let{pageEntries:l,warnings:p}=z(s,e);for(let c of p){let u=/not found$/.test(c),x=/page "([^"]+)"/.exec(c),d=x?et(n,x[1]):null;t.push(j({category:"config-nav",severity:u?"error":"warning",file:"velu.json",line:d,title:c,hint:u?"Create the .mdx file, or remove the page from navigation.":""}))}Br(s,n,t)}}return t}function Br(e,t,r){let n=new Set,o=i=>{if(!(!i||typeof i!="object")){if(i.language&&!n.has(i.language)){n.add(i.language);let a=String(i.language).toLowerCase();Nr.validate(a)||r.push(j({category:"config-nav",severity:"warning",file:"velu.json",line:et(t,i.language)||fe(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 a of Object.values(i))Array.isArray(a)?a.forEach(o):a&&typeof a=="object"&&o(a)}};o(e)}var Ir,Rr,tt=A(()=>{J();B();le();ie();Ir=me.dirname(Fr(import.meta.url)),Rr=me.resolve(Ir,"..","..","schema","velu.schema.json")});import Gr from"node:fs/promises";import Jr from"node:fs";import q from"node:path";import{fileURLToPath as Vr,pathToFileURL as qr}from"node:url";import{compile as Hr}from"@mdx-js/mdx";import Dr from"remark-frontmatter";import Xr from"remark-mdx-frontmatter";import Wr from"remark-gfm";import Yr from"rehype-slug";import{visit as Kr}from"unist-util-visit";function nt(){if(je)return je;let e=q.dirname(Vr(import.meta.url)),t=[q.resolve(e,"..","runtime","velu-ui"),q.resolve(e,"..","..","runtime","velu-ui"),q.resolve(e,"..","..","..","velu-ui","src")],r=null;for(let n of t){let o=q.join(n,"lib","component-schemas.js");if(Jr.existsSync(o)){r=o;break}}return je=r?import(qr(r).href).then(n=>n.validateProps).catch(()=>null):Promise.resolve(null),je}function Zr(e){let t={};for(let r of e.attributes||[])r.type==="mdxJsxAttribute"&&(r.value==null?t[r.name]=!0:typeof r.value=="string"&&(t[r.name]=r.value));return t}function Qr(e,t){return()=>r=>{Kr(r,n=>{if((n.type==="mdxJsxFlowElement"||n.type==="mdxJsxTextElement")&&typeof n.name=="string"&&/^[A-Z]/.test(n.name)&&!n.name.includes(".")&&e.push({name:n.name,props:Zr(n),line:n.position?.start?.line??null,column:n.position?.start?.column??null}),n.type==="mdxjsEsm"&&typeof n.value=="string")for(let o of n.value.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g))t.add(o[1])})}}async function eo(e,t){let r=[],n;try{n=await Gr.readFile(t.fileAbsPath,"utf-8")}catch{return r}let o=q.relative(e,t.fileAbsPath).split(q.sep).join("/"),i=[],a=new Set;try{await Hr({value:n,path:t.fileAbsPath},{remarkPlugins:[Dr,Xr,Wr,se,Qr(i,a)],rehypePlugins:[Yr],providerImportSource:"@mdx-js/react"})}catch(c){return r.push(pe(c,{projectDir:e,knownComponents:V,file:o})),r}let s=new Set(V),l=await nt(),p=new Set;for(let c of i)if(!a.has(c.name)){if(!s.has(c.name)){if(p.has(c.name))continue;p.add(c.name),r.push(j({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:we(c.name,V)}));continue}if(l){let u=l(c.name,c.props,{checkRequired:!1});u&&r.push(j({...u,file:o,line:c.line,column:c.column}))}}return r}async function Vt(e,t){let r=t.filter(s=>s.exists),n=[],o=8,i=0;async function a(){for(;i<r.length;){let s=r[i++],l=await eo(e,s);for(let p of l)n.push(p)}}return await Promise.all(Array.from({length:Math.min(o,r.length)},a)),n}var je,rt=A(()=>{ze();J();Ke();Qe()});import Oe from"node:fs";import ot from"node:path";import Dt from"js-yaml";function it(e,t,r){if(r>24||e===null||typeof e!="object")return r>24&&e&&typeof e=="object"?null:e;if(t.has(e))return null;t.add(e);let n;if(Array.isArray(e))n=e.map(o=>it(o,t,r+1));else{n={};for(let[o,i]of Object.entries(e))n[o]=it(i,t,r+1)}return t.delete(e),n}function Xt(e){return Dt.dump(it(e,new Set,0),{noRefs:!0,lineWidth:100,skipInvalid:!0})}function Wt(e){let t=String(e).replace(/\.md$/i,"");return t===""||t==="/"||t==="/index"?"/":t.replace(/\/+$/,"")||"/"}function to(e){return e==="/"?"/index.md":`${e}.md`}function st(e,t){if(t==="api")return`# ${qt}
107
- ${e}`;let r=e.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),n=`> ${qt}
105
+ </html>`}var I,on=A(()=>{J();I=e=>String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")});var H,lt=A(()=>{H=["Callout","Card","CardGroup","Accordion","AccordionGroup","Columns","Field","Prompt","Steps","Step","Tree","Folder","File","Image","CodeBlock","CodeGroup","MethodBadge","ApiPath","TryItBar","ApiField","ApiClient","ApiSidebar"]});import Oe from"node:fs";import de from"node:path";import{fileURLToPath as uo}from"node:url";import po from"iso-639-1";function me(e,t){if(!t)return null;let n=e.indexOf(`"${t}"`);return n===-1?null:e.slice(0,n).split(`
106
+ `).length}function go(e,t){return t==null||t<0?null:e.slice(0,t).split(`
107
+ `).length}function ct(e,t){if(!t)return null;let n=e.indexOf(`"${t}"`);return n===-1?null:e.slice(0,n).split(`
108
+ `).length}function ho(e,t,n){let r=[];return s(e,t,"",null),r;function o(l){if(l&&l.$ref){let p=l.$ref.replace(/^#\//,"").split("/"),c=n;for(let u of p)c=c?.[u];return c||{}}return l}function i(l){return Array.isArray(l)?"array":l===null?"null":typeof l}function a(l,p){let c=r.length;s(l,p,"",null,!0);let u=r.length===c;return u||(r.length=c),u}function s(l,p,c,u,b){let d=o(p);if(d){if(d.oneOf){d.oneOf.some(m=>a(l,m))||r.push({path:c,key:u,message:"value does not match any allowed shape"});return}if(d.type&&i(l)!==d.type){r.push({path:c,key:u,message:`expected ${d.type}, got ${i(l)}`});return}if(d.type==="string"&&d.minLength!=null&&l.length<d.minLength&&r.push({path:c,key:u,message:"must not be empty"}),d.type==="object"&&i(l)==="object"){for(let m of d.required||[])m in l||r.push({path:c?`${c}.${m}`:m,key:m,message:`missing required "${m}"`});let x=d.properties||{};if(d.additionalProperties===!1)for(let m of Object.keys(l))m in x||r.push({path:c?`${c}.${m}`:m,key:m,message:`unknown field "${m}"`});for(let[m,L]of Object.entries(x))m in l&&s(l[m],L,c?`${c}.${m}`:m,m,b)}d.type==="array"&&Array.isArray(l)&&d.items&&l.forEach((x,m)=>s(x,d.items,`${c}[${m}]`,u,b))}}}function yo(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 Te(e){let t=[],n=de.join(e,"velu.json"),r;try{r=Oe.readFileSync(n,"utf-8")}catch(s){return s.code==="ENOENT"?t.push(j({category:"config-json",file:"velu.json",title:"No velu.json found",hint:"Run `velu init <name>` to scaffold a project."})):t.push(j({category:"config-json",file:"velu.json",title:"Could not read velu.json"})),t}let o;try{o=JSON.parse(r)}catch(s){let l=/position (\d+)/.exec(s.message||""),p=l?go(r,Number(l[1])):null;return t.push(j({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(Oe.readFileSync(mo,"utf-8"))}catch{}if(i)for(let s of ho(o,i,i)){let l=/^unknown field/.test(s.message);t.push(j({category:"config-schema",severity:l?"warning":"error",file:"velu.json",line:me(r,s.key),title:s.path?`${s.path}: ${s.message}`:s.message,hint:l?"Remove it, or check the spelling against the velu.json schema.":""}))}for(let s of["primary","light","dark"]){let l=o.colors?.[s];l!=null&&!yo(l)&&t.push(j({category:"config-schema",severity:"warning",file:"velu.json",line:me(r,s),title:`colors.${s}: "${l}" 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=de.resolve(e,o.favicon.replace(/^\/+/,""));Oe.existsSync(s)||t.push(j({category:"config-asset",file:"velu.json",line:me(r,"favicon"),title:`favicon not found: ${o.favicon}`,hint:"The path is relative to the project root."}))}let a=ie(o.logo);if(a){let s=new Map;for(let l of["light","dark"]){let p=a[l];p&&s.set(p,[...s.get(p)||[],l])}for(let[l,p]of s)if(!Oe.existsSync(de.resolve(e,l.replace(/^\/+/,"")))){let c=p.length===2?"logo":`logo (${p[0]})`;t.push(j({category:"config-asset",file:"velu.json",line:ct(r,l),title:`${c} not found: ${l}`,hint:"The path is relative to the project root."}))}}if(o.navigation&&typeof o.navigation=="object"){let s;try{s=z(o.navigation)}catch(l){t.push(j({category:"config-nav",file:"velu.json",line:me(r,"navigation"),title:"navigation could not be processed",detail:String(l.message||"")})),s=null}if(s){let{pageEntries:l,warnings:p}=B(s,e);for(let c of p){let u=/not found$/.test(c),b=/page "([^"]+)"/.exec(c),d=b?ct(r,b[1]):null;t.push(j({category:"config-nav",severity:u?"error":"warning",file:"velu.json",line:d,title:c,hint:u?"Create the .mdx file, or remove the page from navigation.":""}))}vo(s,r,t)}}return t}function vo(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 a=String(i.language).toLowerCase();po.validate(a)||n.push(j({category:"config-nav",severity:"warning",file:"velu.json",line:ct(t,i.language)||me(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 a of Object.values(i))Array.isArray(a)?a.forEach(o):a&&typeof a=="object"&&o(a)}};o(e)}var fo,mo,ut=A(()=>{J();G();ce();se();fo=de.dirname(uo(import.meta.url)),mo=de.resolve(fo,"..","..","schema","velu.schema.json")});import bo from"node:fs/promises";import xo from"node:fs";import q from"node:path";import{fileURLToPath as $o,pathToFileURL as wo}from"node:url";import{compile as So}from"@mdx-js/mdx";import ko from"remark-frontmatter";import Ao from"remark-mdx-frontmatter";import jo from"remark-gfm";import Oo from"rehype-slug";import{visit as To}from"unist-util-visit";function pt(){if(Le)return Le;let e=q.dirname($o(import.meta.url)),t=[q.resolve(e,"..","runtime","velu-ui"),q.resolve(e,"..","..","runtime","velu-ui"),q.resolve(e,"..","..","..","velu-ui","src")],n=null;for(let r of t){let o=q.join(r,"lib","component-schemas.js");if(xo.existsSync(o)){n=o;break}}return Le=n?import(wo(n).href).then(r=>r.validateProps).catch(()=>null):Promise.resolve(null),Le}function Lo(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 _o(e,t){return()=>n=>{To(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:Lo(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 Po(e,t){let n=[],r;try{r=await bo.readFile(t.fileAbsPath,"utf-8")}catch{return n}let o=q.relative(e,t.fileAbsPath).split(q.sep).join("/"),i=[],a=new Set;try{await So({value:r,path:t.fileAbsPath},{remarkPlugins:[ko,Ao,jo,ae,_o(i,a)],rehypePlugins:[Oo],providerImportSource:"@mdx-js/react"})}catch(c){return n.push(fe(c,{projectDir:e,knownComponents:H,file:o})),n}let s=new Set(H),l=await pt(),p=new Set;for(let c of i)if(!a.has(c.name)){if(!s.has(c.name)){if(p.has(c.name))continue;p.add(c.name),n.push(j({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:Ae(c.name,H)}));continue}if(l){let u=l(c.name,c.props,{checkRequired:!1});u&&n.push(j({...u,file:o,line:c.line,column:c.column}))}}return n}async function sn(e,t){let n=t.filter(s=>s.exists),r=[],o=8,i=0;async function a(){for(;i<n.length;){let s=n[i++],l=await Po(e,s);for(let p of l)r.push(p)}}return await Promise.all(Array.from({length:Math.min(o,n.length)},a)),r}var Le,ft=A(()=>{We();J();st();lt()});import _e from"node:fs";import mt from"node:path";import cn from"js-yaml";function dt(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=>dt(o,t,n+1));else{r={};for(let[o,i]of Object.entries(e))r[o]=dt(i,t,n+1)}return t.delete(e),r}function un(e){return cn.dump(dt(e,new Set,0),{noRefs:!0,lineWidth:100,skipInvalid:!0})}function pn(e){let t=String(e).replace(/\.md$/i,"");return t===""||t==="/"||t==="/index"?"/":t.replace(/\/+$/,"")||"/"}function Eo(e){return e==="/"?"/index.md":`${e}.md`}function gt(e,t){if(t==="api")return`# ${an}
109
+ ${e}`;let n=e.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),r=`> ${an}
108
110
 
109
- `;return r?e.slice(0,r[0].length)+n+e.slice(r[0].length):n+e}function ro(e){return e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,"")}function oo(e){try{let t=Oe.readFileSync(e,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!t)return{};let r=Dt.load(t[1]);return r&&typeof r=="object"?r:{}}catch{return{}}}async function de(e){let t={};try{t=JSON.parse(Oe.readFileSync(ot.join(e,"velu.json"),"utf-8"))}catch{return{name:ot.basename(e),baseUrl:"",pages:[]}}let r=t.name??ot.basename(e),n=typeof t.url=="string"?t.url.replace(/\/+$/,""):"",o=I(t.api),i=t.navigation??{},a={};try{let u=await xe(t.navigation??{},{targetDir:e,api:o});i=u.nav,a=u.ops}catch(u){console.warn(`[velu] openapi: ${u.message}`)}let s=M(i),{pageEntries:l}=z(s,e),p=new Map(l.map(u=>[u.url,u])),c=[];for(let u of W(s)){if(!u.url)continue;let x=u.ancestors.filter(h=>h.kind==="group").pop(),d=u.ancestors.filter(h=>h.kind==="tab").pop(),$=x?.label||d?.label||"Pages",m=u.ancestors.filter(h=>h.kind==="tab"||h.kind==="group").map(h=>h.label),L=u.ancestors.filter(h=>h.kind==="language").pop()?.code||null;if(u.node?.api){let h=a[u.pagePath];if(!h)continue;let w=h.title||Ht(u.url);c.push({url:u.url,title:w,description:h.description||"",group:$,breadcrumb:[...m,w],lang:L,frontmatter:{title:h.title,description:h.description},source:{kind:"api",segment:h.segment}})}else{let h=p.get(u.url);if(!h||!h.exists)continue;let w=oo(h.fileAbsPath),F=w.title||Ht(u.url);c.push({url:u.url,title:F,description:w.description||"",group:$,breadcrumb:[...m,F],lang:L,frontmatter:w,source:{kind:"mdx",fileAbsPath:h.fileAbsPath}})}}return{name:r,baseUrl:n,pages:c}}function Le(e){return new Map(e.pages.map(t=>[t.url,{...t.source,title:t.title}]))}async function io(e){return Le(await de(e))}async function at(e,t,r){let o=(r||await io(e)).get(t);if(!o)return null;if(o.kind==="mdx")try{return{body:Oe.readFileSync(o.fileAbsPath,"utf-8"),contentType:"text/markdown; charset=utf-8",kind:"mdx"}}catch{return null}return o.segment?{body:Xt(o.segment),contentType:"text/yaml; charset=utf-8",kind:"api"}:null}async function Yt(e,t){let r=t||await de(e),n=s=>r.baseUrl?r.baseUrl+s:s,o=[`# ${r.name}`,"",`> Documentation index for ${r.name}. Append \`.md\` to any page URL (or send \`Accept: text/markdown\`) for its Markdown; fetch ${Te} for the whole site in one document.`,""],i=[],a=new Map;for(let s of r.pages)a.has(s.group)||(a.set(s.group,[]),i.push(s.group)),a.get(s.group).push(s);for(let s of i){o.push(`## ${s}`,"");for(let l of a.get(s))o.push(`- [${l.title}](${n(to(l.url))})${l.description?`: ${l.description}`:""}`);o.push("")}return o.join(`
110
- `)}async function Kt(e,t){let r=t||await de(e),n=[`# ${r.name}`,"",`> Full documentation \u2014 every page concatenated. Index: ${K}`];for(let o of r.pages)if(n.push("","---","",`# ${o.title}`,`Source: ${o.url}`,""),o.source.kind==="mdx")try{n.push(ro(Oe.readFileSync(o.source.fileAbsPath,"utf-8")).trim())}catch{}else o.source.segment&&n.push("```yaml",Xt(o.source.segment).trim(),"```");return n.join(`
111
+ `;return n?e.slice(0,n[0].length)+r+e.slice(n[0].length):r+e}function Fo(e){return e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,"")}function No(e){try{let t=_e.readFileSync(e,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!t)return{};let n=cn.load(t[1]);return n&&typeof n=="object"?n:{}}catch{return{}}}async function ge(e){let t={};try{t=JSON.parse(_e.readFileSync(mt.join(e,"velu.json"),"utf-8"))}catch{return{name:mt.basename(e),baseUrl:"",pages:[]}}let n=t.name??mt.basename(e),r=typeof t.url=="string"?t.url.replace(/\/+$/,""):"",o=R(t.api),i=t.navigation??{},a={};try{let u=await Se(t.navigation??{},{targetDir:e,api:o});i=u.nav,a=u.ops}catch(u){console.warn(`[velu] openapi: ${u.message}`)}let s=z(i),{pageEntries:l}=B(s,e),p=new Map(l.map(u=>[u.url,u])),c=[];for(let u of X(s)){if(!u.url)continue;let b=u.ancestors.filter(h=>h.kind==="group").pop(),d=u.ancestors.filter(h=>h.kind==="tab").pop(),x=b?.label||d?.label||"Pages",m=u.ancestors.filter(h=>h.kind==="tab"||h.kind==="group").map(h=>h.label),L=u.ancestors.filter(h=>h.kind==="language").pop()?.code||null;if(u.node?.api){let h=a[u.pagePath];if(!h)continue;let w=h.title||ln(u.url);c.push({url:u.url,title:w,description:h.description||"",group:x,breadcrumb:[...m,w],lang:L,frontmatter:{title:h.title,description:h.description},source:{kind:"api",segment:h.segment}})}else{let h=p.get(u.url);if(!h||!h.exists)continue;let w=No(h.fileAbsPath),F=w.title||ln(u.url);c.push({url:u.url,title:F,description:w.description||"",group:x,breadcrumb:[...m,F],lang:L,frontmatter:w,source:{kind:"mdx",fileAbsPath:h.fileAbsPath}})}}return{name:n,baseUrl:r,pages:c}}function Ee(e){return new Map(e.pages.map(t=>[t.url,{...t.source,title:t.title}]))}async function Uo(e){return Ee(await ge(e))}async function ht(e,t,n){let o=(n||await Uo(e)).get(t);if(!o)return null;if(o.kind==="mdx")try{return{body:_e.readFileSync(o.fileAbsPath,"utf-8"),contentType:"text/markdown; charset=utf-8",kind:"mdx"}}catch{return null}return o.segment?{body:un(o.segment),contentType:"text/yaml; charset=utf-8",kind:"api"}:null}async function fn(e,t){let n=t||await ge(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 ${Pe} for the whole site in one document.`,""],i=[],a=new Map;for(let s of n.pages)a.has(s.group)||(a.set(s.group,[]),i.push(s.group)),a.get(s.group).push(s);for(let s of i){o.push(`## ${s}`,"");for(let l of a.get(s))o.push(`- [${l.title}](${r(Eo(l.url))})${l.description?`: ${l.description}`:""}`);o.push("")}return o.join(`
112
+ `)}async function mn(e,t){let n=t||await ge(e),r=[`# ${n.name}`,"",`> Full documentation \u2014 every page concatenated. Index: ${Z}`];for(let o of n.pages)if(r.push("","---","",`# ${o.title}`,`Source: ${o.url}`,""),o.source.kind==="mdx")try{r.push(Fo(_e.readFileSync(o.source.fileAbsPath,"utf-8")).trim())}catch{}else o.source.segment&&r.push("```yaml",un(o.source.segment).trim(),"```");return r.join(`
111
113
  `)+`
112
- `}var K,Te,no,Z,qt,Ht,Zt=A(()=>{B();le();ie();De();K="/llms.txt",Te="/llms-full.txt",no=`<${K}>; rel="llms-txt", <${Te}>; rel="llms-full-txt"`,Z={Link:no,"X-Llms-Txt":K},qt=`Full documentation index: ${K}`;Ht=e=>(e.split("/").filter(Boolean).pop()||"Home").replace(/[-_]+/g," ").replace(/\b\w/g,r=>r.toUpperCase())});var sn={};Fe(sn,{startDevServer:()=>So});import Qt from"node:fs/promises";import Q from"node:fs";import so from"node:http";import{spawn as ao}from"node:child_process";import P from"node:path";import{fileURLToPath as lo}from"node:url";import co from"chokidar";import en from"express";import{createServer as uo,searchForWorkspaceRoot as po}from"vite";function yo(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 tn(e,t){let r=We(e,{color:!!process.stderr.isTTY});console.error(`
113
- `+r+`
114
- `),process.env.VELU_DEBUG&&t&&console.error(t)}function vo(){try{return JSON.parse(Q.readFileSync(P.join(Pe,"package.json"),"utf8")).version||"unknown"}catch{return"unknown"}}function bo(e,t){let r=P.resolve(e,".velu"),n=P.resolve(r,".velu-version"),o=null;try{o=Q.readFileSync(n,"utf8").trim()}catch{}if(o!==t){if(o!==null)try{Q.rmSync(P.join(r,"vite-cache"),{recursive:!0,force:!0}),console.log("[velu] new version detected \u2014 refreshing the preview cache\u2026")}catch{}try{Q.mkdirSync(r,{recursive:!0}),Q.writeFileSync(n,t)}catch{}}}async function nn(e){try{return await mt(e)}catch{return Me({},P.basename(e))}}async function rn(e,t){let r=await e.moduleGraph.getModuleByUrl(t,!0),n=new Map,o=new Set;async function i(a){if(!(!a||o.has(a.url))){if(o.add(a.url),a.id&&mo.test(a.id)){let s=a.url.includes("?")?"&":"?",l=await e.transformRequest(`${a.url}${s}direct`);l?.code&&n.set(a.url,l.code)}for(let s of a.importedModules)await i(s)}}return await i(r),[...n.values()].join(`
115
- `)}function wo(e,t){let r=()=>{process.stdout.isTTY&&!process.env.VELU_NO_BELL&&process.stdout.write("\x07")},n=process.stdout.isTTY,o=u=>n&&process.stdout.write(`\x1B]${u}\x1B\\`),i=()=>{o(`0;\u23F3 ${t}`),o("9;4;3;0")},a=()=>{o(`0;${t}`),o("9;4;0;0")};if(n&&process.once("exit",()=>o("9;4;0;0")),i(),!e)return console.log("Starting Velu\u2026"),{ready:u=>{console.log(`Velu ready \u2192 ${u}`),a(),r()}};let s="\x1B[38;2;220;20;60m",l="\x1B[0m";console.log("");for(let u of xo)console.log(`${s}${u}${l}`);console.log("");let p=null;try{p=ao(process.execPath,["-e",$o],{stdio:["ignore","inherit","ignore"]}),p.on("error",()=>{})}catch{}let c=()=>{if(p){try{p.kill()}catch{}p=null}};return process.once("exit",c),{ready:u=>{c(),process.stdout.write("\x1B[2K\r"),console.log(` \x1B[32m\u2713${l} Velu ready \u2192 \x1B[36m${u}${l}`),a(),r()}}}async function So(e){let t=!!process.env.VELU_PROFILE,r=performance.now(),n=(y,f)=>t&&console.log(`[velu-profile] ${y}: ${(performance.now()-f).toFixed(0)}ms`),o=wo(!!process.stdout.isTTY&&!t,P.basename(e)),i=await nn(e),a=s();function s(){let f=Ae(e).filter(g=>g.severity==="error"&&(g.category==="config-json"||g.category==="config-schema"));return f.length&&console.error(`
116
- `+Se(f,{color:!!process.stderr.isTTY})+`
117
- `),f}let l=e;try{l=Q.realpathSync(e)}catch{}let p=0,c=y=>{let f=performance.now();if(f-p<500)return;p=f;let g=pe(y,{projectDir:l,knownComponents:V});tn(g,y)};process.on("unhandledRejection",c),process.on("uncaughtException",c);let u=Number(process.env.PORT)||8358,x=await nt();bo(e,vo());let d=en(),$=so.createServer(d),m=await uo({...zt({targetDir:e,VITE_ROOT:Pe,validateProps:x}),appType:"custom",logLevel:t?"info":"warn",server:{middlewareMode:!0,fs:{allow:[po(Pe),e,l]},hmr:{server:$}}});n("vite server created",r),d.use(m.middlewares),d.get(new RegExp(`^${Ue}(\\.[a-z0-9]+)?$`,"i"),async(y,f)=>{if(!i.favicon)return f.status(404).end();let g=P.resolve(e,i.favicon.replace(/^\//,""));f.sendFile(g,v=>{v&&f.status(404).end()})});let L=y=>(f,g)=>{let v=i.logo?.[y];if(!v)return g.status(404).end();g.sendFile(P.resolve(e,v.replace(/^\//,"")),O=>{O&&g.status(404).end()})};d.get(ye,L("light")),d.get(ve,L("dark")),d.post("/@velu-api-proxy",en.json({limit:"8mb"}),async(y,f)=>{let{method:g="GET",url:v,headers:O={},body:S}=y.body||{};if(typeof v!="string"||!/^https?:\/\//i.test(v))return f.status(400).json({error:"A valid http(s) target URL is required."});try{let k=await fetch(v,{method:g,headers:O,body:S!=null&&S!==""?S:void 0}),N=await k.text(),H=k.headers.get("content-type")||"",T={};k.headers.forEach((ee,Ee)=>{T[Ee]=ee});let U=N;if(/json/i.test(H))try{U=JSON.parse(N)}catch{}f.json({status:k.status,statusText:k.statusText,headers:T,body:U})}catch(k){f.json({error:`Request failed: ${k.message}`})}});let h=null,w=async()=>h||=await de(e);d.get(/\.md$/i,async(y,f,g)=>{try{let v=await w(),O=await at(e,Wt(decodeURIComponent(y.path)),Le(v));if(!O)return g();f.status(200).set({"Content-Type":O.contentType,...Z}).end(st(O.body,O.kind))}catch{g()}}),d.get(K,async(y,f,g)=>{try{let v=await Yt(e,await w());f.status(200).set({"Content-Type":"text/plain; charset=utf-8",...Z}).end(v)}catch{g()}}),d.get(Te,async(y,f,g)=>{try{let v=await Kt(e,await w());f.status(200).set({"Content-Type":"text/plain; charset=utf-8",...Z}).end(v)}catch{g()}}),d.use("*",async(y,f,g)=>{let v=y.originalUrl,O=performance.now();if(/text\/markdown/i.test(y.headers.accept||""))try{let S=await w(),k=await at(e,gt(v),Le(S));if(k)return f.status(200).set({"Content-Type":k.contentType,...Z}).end(st(k.body,k.kind))}catch{}if(a.length)return f.status(200).set({"Content-Type":"text/html"}).end(Ze(a,{title:"Fix velu.json to continue"}));try{let S=performance.now(),k=await Qt.readFile(on,"utf-8");k=await m.transformIndexHtml(v,k),n(`transformIndexHtml ${v}`,S);let N="/src/runtime/server-entry.jsx";S=performance.now();let{render:H}=await m.ssrLoadModule(N);n(`ssrLoadModule ${v} (1st req includes dep pre-bundle)`,S),S=performance.now();let T=await H(v);n(`render ${v}`,S),S=performance.now();let U=await rn(m,N);n(`collectSsrCss ${v}`,S);let ee=U?`<style data-velu-ssr>${U}</style>`:"",Ee=`<style data-velu-config>
118
- ${dt(i)}
119
- </style>`,fn=go.has(i.font.family)?"":yo(i.font.family),ge=ft(i),mn=ge?`<link rel="icon"${ge.type?` type="${ge.type}"`:""} href="${ge.url}" />`:"",dn=[ee,Ee,fn,mn].filter(Boolean).join(`
120
- `),gn=k.replace("<!--app-title-->",ho(i.name)).replace("<!--app-head-->",dn).replace("<!--app-html-->",T);f.status(200).set({"Content-Type":"text/html",...Z}).end(gn),n(`TOTAL ${v}`,O)}catch(S){m.ssrFixStacktrace(S);let k=pe(S,{projectDir:l,knownComponents:V});tn(k,S),f.status(200).set({"Content-Type":"text/html"}).end(Ze([k]))}}),co.watch(e,{ignoreInitial:!0,ignored:/(^|[\\/])(node_modules|\.git|\.velu)([\\/]|$)/,awaitWriteFinish:{stabilityThreshold:100,pollInterval:20}}).on("all",async(y,f)=>{console.log(`[velu-cli] content ${y}: ${P.relative(e,f)}`);let g=P.basename(f)==="velu.json",v=f.endsWith(".mdx"),O=g||v&&(y==="add"||y==="unlink");if((O||v||/\.(ya?ml|json)$/i.test(f))&&(h=null),g&&(i=await nn(e),a=s()),O)m.moduleGraph.invalidateAll();else if(v){let S=f.split(P.sep).join("/"),k=m.moduleGraph.getModulesByFile(S);if(k)for(let N of k)m.moduleGraph.invalidateModule(N)}m.ws.send({type:"full-reload"})});async function b(y){let f=new Set,g=12,v=0,O=[],S=()=>v<g?(v+=1,Promise.resolve()):new Promise(T=>O.push(T)).then(()=>{v+=1}),k=()=>{v-=1,O.shift()?.()},N=T=>/[\\/]\.velu[\\/]vite-cache[\\/]|[\\/]deps[\\/]/.test(T)||/[\\/]node_modules[\\/]/.test(T)&&!/velu-ui/.test(T);async function H(T){if(!(!T||f.has(T)||N(T))){f.add(T);try{await S();try{await m.transformRequest(T,{ssr:!1})}finally{k()}let U=await m.moduleGraph.getModuleByUrl(T,!1);U?.importedModules?.size&&await Promise.all([...U.importedModules].map(ee=>H(ee.url)))}catch{}}}return await H(y),f.size}$.listen(u,async()=>{let y=performance.now(),f=0;try{let{render:g}=await m.ssrLoadModule("/src/runtime/server-entry.jsx");await b("/src/runtime/client-entry.jsx"),typeof m.waitForRequestsIdle=="function"&&await m.waitForRequestsIdle();let[v]=await Promise.allSettled([b("/src/runtime/client-entry.jsx"),g("/"),m.transformIndexHtml("/",await Qt.readFile(on,"utf-8")),rn(m,"/src/runtime/server-entry.jsx")]).then(O=>O.map(S=>S.status==="fulfilled"?S.value:0));f=v}catch(g){t&&console.log("[velu-profile] warmup error:",g?.message)}n(`cold-start warm-up (${f} client modules)`,y),o.ready(`http://localhost:${u}`)})}var fo,mo,go,ho,Pe,on,xo,$o,an=A(()=>{ie();Bt();Ke();Jt();J();Qe();tt();rt();Zt();B();fo=P.dirname(lo(import.meta.url)),mo=/\.(css|less|sass|scss|styl|stylus|pcss|postcss)(\?|$)/,go=new Set(["Google Sans Flex","Google Sans Code","Outfit"]),ho=e=>String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");Pe=P.resolve(fo,".."),on=P.resolve(Pe,"src","template.html"),xo=[" _ __ __","| | / /__ / /_ __","| | / / _ \\/ / / / /","| |/ / __/ / /_/ /","|___/\\___/_/\\__,_/"],$o="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 cn={};Fe(cn,{default:()=>Oo,runValidate:()=>ln});import ko from"node:fs";import Ao from"node:path";function jo(e){try{let t=JSON.parse(ko.readFileSync(Ao.join(e,"velu.json"),"utf-8"));if(!t.navigation||typeof t.navigation!="object")return[];let r=M(t.navigation);return z(r,e).pageEntries}catch{return[]}}async function ln(e){let t=Ae(e),r=jo(e),n=await Vt(e,r),o=[...t,...n],i=!!process.stdout.isTTY;return console.log(Se(o,{color:i})),o.some(s=>s.severity!=="warning"&&s.severity!=="info")?1:0}var Oo,un=A(()=>{B();le();tt();rt();J();Oo=ln});import _e from"node:path";import _ from"node:process";import{readFileSync as To}from"node:fs";var[,,pn,Ce]=_.argv;function Lo(){try{return JSON.parse(To(new URL("../package.json",import.meta.url),"utf8")).version}catch{return"unknown"}}function Po(){let e=_.argv.slice(3);for(let t=0;t<e.length;t++){let r=e[t];if(r==="--out"){t++;continue}if(!r.startsWith("-"))return r}}async function _o(){switch(pn){case"--version":case"-v":case"version":{console.log(Lo());break}case"init":{Ce||(console.error("Usage: velu init <project-name>"),_.exit(1));let e=Ce,t=_e.resolve(_.cwd(),e),{initProject:r}=await Promise.resolve().then(()=>(ut(),ct));await r(t,e);break}case"dev":{let e=_e.resolve(_.cwd(),Ce??"."),{startDevServer:t}=await Promise.resolve().then(()=>(an(),sn));await t(e);break}case"validate":{let e=_e.resolve(_.cwd(),Ce??"."),{runValidate:t}=await Promise.resolve().then(()=>(un(),cn)),r=await t(e);_.exit(r);break}case"build":{let e=_e.resolve(_.cwd(),Po()??"."),t=_.argv.indexOf("--out"),r=t>-1?_.argv[t+1]:void 0,n=new URL(["..","src","build","index.js"].join("/"),import.meta.url).href,o=a=>import(a),i;try{({runBuild:i}=await o(n))}catch{console.error("velu build is an internal command, not available in this distribution."),_.exit(1)}await i(e,{out:r});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"),_.exit(pn?1:0)}}_o().catch(e=>{console.error(_.env.VELU_DEBUG?e:`Error: ${e.message}`),_.exit(1)});
114
+ `}var Z,Pe,Co,Q,an,ln,dn=A(()=>{G();ce();se();nt();Z="/llms.txt",Pe="/llms-full.txt",Co=`<${Z}>; rel="llms-txt", <${Pe}>; rel="llms-full-txt"`,Q={Link:Co,"X-Llms-Txt":Z},an=`Full documentation index: ${Z}`;ln=e=>(e.split("/").filter(Boolean).pop()||"Home").replace(/[-_]+/g," ").replace(/\b\w/g,n=>n.toUpperCase())});var wn={};ye(wn,{startDevServer:()=>Zo});import gn from"node:fs/promises";import ee from"node:fs";import Ro from"node:http";import{spawn as Io}from"node:child_process";import _ from"node:path";import{fileURLToPath as Mo}from"node:url";import zo from"chokidar";import hn from"express";import{createServer as Bo,searchForWorkspaceRoot as Go}from"vite";function Do(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 yn(e,t){let n=ot(e,{color:!!process.stderr.isTTY});console.error(`
115
+ `+n+`
116
+ `),process.env.VELU_DEBUG&&t&&console.error(t)}function vn(){try{return JSON.parse(ee.readFileSync(_.join(Ce,"package.json"),"utf8")).version||"unknown"}catch{return"unknown"}}function Yo(e,t){let n=_.resolve(e,".velu"),r=_.resolve(n,".velu-version"),o=null;try{o=ee.readFileSync(r,"utf8").trim()}catch{}if(o!==t){if(o!==null)try{ee.rmSync(_.join(n,"vite-cache"),{recursive:!0,force:!0}),console.log("[velu] new version detected \u2014 refreshing the preview cache\u2026")}catch{}try{ee.mkdirSync(n,{recursive:!0}),ee.writeFileSync(r,t)}catch{}}}async function bn(e){try{return await Tt(e)}catch{return Ye({},_.basename(e))}}async function xn(e,t){let n=await e.moduleGraph.getModuleByUrl(t,!0),r=new Map,o=new Set;async function i(a){if(!(!a||o.has(a.url))){if(o.add(a.url),a.id&&Jo.test(a.id)){let s=a.url.includes("?")?"&":"?",l=await e.transformRequest(`${a.url}${s}direct`);l?.code&&r.set(a.url,l.code)}for(let s of a.importedModules)await i(s)}}return await i(n),[...r.values()].join(`
117
+ `)}function Ko(e,t,n){let r=()=>{process.stdout.isTTY&&!process.env.VELU_NO_BELL&&process.stdout.write("\x07")},o=process.stdout.isTTY,i=x=>o&&process.stdout.write(`\x1B]${x}\x1B\\`),a=()=>{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")),a();let l=n&&n!=="unknown"?`v${n}`:"";if(!e)return console.log(`Starting Velu${l?" "+l:""}\u2026`),{ready:x=>{console.log(`Velu${l?" "+l:""} ready \u2192 ${x}`),s(),r()}};let p="\x1B[38;2;220;20;60m",c="\x1B[0m",u="\x1B[2m";console.log("");for(let x of Wo)console.log(`${p}${x}${c}`);l&&console.log(` ${u}${l}${c}`),console.log("");let b=null;try{b=Io(process.execPath,["-e",Xo],{stdio:["ignore","inherit","ignore"]}),b.on("error",()=>{})}catch{}let d=()=>{if(b){try{b.kill()}catch{}b=null}};return process.once("exit",d),{ready:x=>{d(),process.stdout.write("\x1B[2K\r"),console.log(` \x1B[32m\u2713${c} Velu${l?" "+l:""} ready \u2192 \x1B[36m${x}${c}`),s(),r()}}}async function Zo(e){let t=!!process.env.VELU_PROFILE,n=performance.now(),r=(y,f)=>t&&console.log(`[velu-profile] ${y}: ${(performance.now()-f).toFixed(0)}ms`),o=Ko(!!process.stdout.isTTY&&!t,_.basename(e),vn()),i=await bn(e),a=s();function s(){let f=Te(e).filter(g=>g.severity==="error"&&(g.category==="config-json"||g.category==="config-schema"));return f.length&&console.error(`
118
+ `+je(f,{color:!!process.stderr.isTTY})+`
119
+ `),f}let l=e;try{l=ee.realpathSync(e)}catch{}let p=0,c=y=>{let f=performance.now();if(f-p<500)return;p=f;let g=fe(y,{projectDir:l,knownComponents:H});yn(g,y)};process.on("unhandledRejection",c),process.on("uncaughtException",c);let u=Number(process.env.PORT)||8358,b=await pt();Yo(e,vn());let d=hn(),x=Ro.createServer(d),m=await Bo({...tn({targetDir:e,VITE_ROOT:Ce,validateProps:b}),appType:"custom",logLevel:t?"info":"warn",server:{middlewareMode:!0,fs:{allow:[Go(Ce),e,l]},hmr:{server:x}}});r("vite server created",n),d.use(m.middlewares),d.get(new RegExp(`^${De}(\\.[a-z0-9]+)?$`,"i"),async(y,f)=>{if(!i.favicon)return f.status(404).end();let g=_.resolve(e,i.favicon.replace(/^\//,""));f.sendFile(g,v=>{v&&f.status(404).end()})});let L=y=>(f,g)=>{let v=i.logo?.[y];if(!v)return g.status(404).end();g.sendFile(_.resolve(e,v.replace(/^\//,"")),O=>{O&&g.status(404).end()})};d.get(xe,L("light")),d.get($e,L("dark")),d.post("/@velu-api-proxy",hn.json({limit:"8mb"}),async(y,f)=>{let{method:g="GET",url:v,headers:O={},body:S}=y.body||{};if(typeof v!="string"||!/^https?:\/\//i.test(v))return f.status(400).json({error:"A valid http(s) target URL is required."});try{let k=await fetch(v,{method:g,headers:O,body:S!=null&&S!==""?S:void 0}),U=await k.text(),D=k.headers.get("content-type")||"",T={};k.headers.forEach((te,Ue)=>{T[Ue]=te});let M=U;if(/json/i.test(D))try{M=JSON.parse(U)}catch{}f.json({status:k.status,statusText:k.statusText,headers:T,body:M})}catch(k){f.json({error:`Request failed: ${k.message}`})}});let h=null,w=async()=>h||=await ge(e);d.get(/\.md$/i,async(y,f,g)=>{try{let v=await w(),O=await ht(e,pn(decodeURIComponent(y.path)),Ee(v));if(!O)return g();f.status(200).set({"Content-Type":O.contentType,...Q}).end(gt(O.body,O.kind))}catch{g()}}),d.get(Z,async(y,f,g)=>{try{let v=await fn(e,await w());f.status(200).set({"Content-Type":"text/plain; charset=utf-8",...Q}).end(v)}catch{g()}}),d.get(Pe,async(y,f,g)=>{try{let v=await mn(e,await w());f.status(200).set({"Content-Type":"text/plain; charset=utf-8",...Q}).end(v)}catch{g()}}),d.use("*",async(y,f,g)=>{let v=y.originalUrl,O=performance.now();if(/text\/markdown/i.test(y.headers.accept||""))try{let S=await w(),k=await ht(e,_t(v),Ee(S));if(k)return f.status(200).set({"Content-Type":k.contentType,...Q}).end(gt(k.body,k.kind))}catch{}if(a.length)return f.status(200).set({"Content-Type":"text/html"}).end(at(a,{title:"Fix velu.json to continue"}));try{let S=performance.now(),k=await gn.readFile($n,"utf-8");k=await m.transformIndexHtml(v,k),r(`transformIndexHtml ${v}`,S);let U="/src/runtime/server-entry.jsx";S=performance.now();let{render:D}=await m.ssrLoadModule(U);r(`ssrLoadModule ${v} (1st req includes dep pre-bundle)`,S),S=performance.now();let T=await D(v);r(`render ${v}`,S),S=performance.now();let M=await xn(m,U);r(`collectSsrCss ${v}`,S);let te=M?`<style data-velu-ssr>${M}</style>`:"",Ue=`<style data-velu-config>
120
+ ${Lt(i)}
121
+ </style>`,Tn=Ho.has(i.font.family)?"":Do(i.font.family),he=Ot(i),Ln=he?`<link rel="icon"${he.type?` type="${he.type}"`:""} href="${he.url}" />`:"",_n=[te,Ue,Tn,Ln].filter(Boolean).join(`
122
+ `),Pn=k.replace("<!--app-title-->",qo(i.name)).replace("<!--app-head-->",_n).replace("<!--app-html-->",T);f.status(200).set({"Content-Type":"text/html",...Q}).end(Pn),r(`TOTAL ${v}`,O)}catch(S){m.ssrFixStacktrace(S);let k=fe(S,{projectDir:l,knownComponents:H});yn(k,S),f.status(200).set({"Content-Type":"text/html"}).end(at([k]))}}),zo.watch(e,{ignoreInitial:!0,ignored:/(^|[\\/])(node_modules|\.git|\.velu)([\\/]|$)/,awaitWriteFinish:{stabilityThreshold:100,pollInterval:20}}).on("all",async(y,f)=>{console.log(`[velu-cli] content ${y}: ${_.relative(e,f)}`);let g=_.basename(f)==="velu.json",v=f.endsWith(".mdx"),O=g||v&&(y==="add"||y==="unlink");if((O||v||/\.(ya?ml|json)$/i.test(f))&&(h=null),g&&(i=await bn(e),a=s()),O)m.moduleGraph.invalidateAll();else if(v){let S=f.split(_.sep).join("/"),k=m.moduleGraph.getModulesByFile(S);if(k)for(let U of k)m.moduleGraph.invalidateModule(U)}m.ws.send({type:"full-reload"})});async function $(y){let f=new Set,g=12,v=0,O=[],S=()=>v<g?(v+=1,Promise.resolve()):new Promise(T=>O.push(T)).then(()=>{v+=1}),k=()=>{v-=1,O.shift()?.()},U=T=>/[\\/]\.velu[\\/]vite-cache[\\/]|[\\/]deps[\\/]/.test(T)||/[\\/]node_modules[\\/]/.test(T)&&!/velu-ui/.test(T);async function D(T){if(!(!T||f.has(T)||U(T))){f.add(T);try{await S();try{await m.transformRequest(T,{ssr:!1})}finally{k()}let M=await m.moduleGraph.getModuleByUrl(T,!1);M?.importedModules?.size&&await Promise.all([...M.importedModules].map(te=>D(te.url)))}catch{}}}return await D(y),f.size}x.listen(u,async()=>{let y=performance.now(),f=0;try{let{render:g}=await m.ssrLoadModule("/src/runtime/server-entry.jsx");await $("/src/runtime/client-entry.jsx"),typeof m.waitForRequestsIdle=="function"&&await m.waitForRequestsIdle();let[v]=await Promise.allSettled([$("/src/runtime/client-entry.jsx"),g("/"),m.transformIndexHtml("/",await gn.readFile($n,"utf-8")),xn(m,"/src/runtime/server-entry.jsx")]).then(O=>O.map(S=>S.status==="fulfilled"?S.value:0));f=v}catch(g){t&&console.log("[velu-profile] warmup error:",g?.message)}r(`cold-start warm-up (${f} client modules)`,y),o.ready(`http://localhost:${u}`)})}var Vo,Jo,Ho,qo,Ce,$n,Wo,Xo,Sn=A(()=>{se();nn();st();on();J();lt();ut();ft();dn();G();Vo=_.dirname(Mo(import.meta.url)),Jo=/\.(css|less|sass|scss|styl|stylus|pcss|postcss)(\?|$)/,Ho=new Set(["Google Sans Flex","Google Sans Code","Outfit"]),qo=e=>String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");Ce=_.resolve(Vo,".."),$n=_.resolve(Ce,"src","template.html"),Wo=[" _ __ __","| | / /__ / /_ __","| | / / _ \\/ / / / /","| |/ / __/ / /_/ /","|___/\\___/_/\\__,_/"],Xo="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 An={};ye(An,{default:()=>ni,runValidate:()=>kn});import Qo from"node:fs";import ei from"node:path";function ti(e){try{let t=JSON.parse(Qo.readFileSync(ei.join(e,"velu.json"),"utf-8"));if(!t.navigation||typeof t.navigation!="object")return[];let n=z(t.navigation);return B(n,e).pageEntries}catch{return[]}}async function kn(e){let t=Te(e),n=ti(e),r=await sn(e,n),o=[...t,...r],i=!!process.stdout.isTTY;return console.log(je(o,{color:i})),o.some(s=>s.severity!=="warning"&&s.severity!=="info")?1:0}var ni,jn=A(()=>{G();ce();ut();ft();J();ni=kn});import Fe from"node:path";import P from"node:process";import{readFileSync as ri}from"node:fs";var[,,On,Ne]=P.argv;function oi(){try{return JSON.parse(ri(new URL("../package.json",import.meta.url),"utf8")).version}catch{return"unknown"}}function ii(){let e=P.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 si(){switch(On){case"--version":case"-v":case"version":{console.log(oi());break}case"init":{Ne||(console.error("Usage: velu init <project-name>"),P.exit(1));let e=Ne,t=Fe.resolve(P.cwd(),e),{initProject:n}=await Promise.resolve().then(()=>(bt(),vt));await n(t,e);break}case"dev":{let{maybeAutoUpdate:e}=await Promise.resolve().then(()=>(Ge(),Be));await e();let t=Fe.resolve(P.cwd(),Ne??"."),{startDevServer:n}=await Promise.resolve().then(()=>(Sn(),wn));await n(t);break}case"update":{let{updateCommand:e}=await Promise.resolve().then(()=>(Ge(),Be));await e();break}case"validate":{let e=Fe.resolve(P.cwd(),Ne??"."),{runValidate:t}=await Promise.resolve().then(()=>(jn(),An)),n=await t(e);P.exit(n);break}case"build":{let e=Fe.resolve(P.cwd(),ii()??"."),t=P.argv.indexOf("--out"),n=t>-1?P.argv[t+1]:void 0,r=new URL(["..","src","build","index.js"].join("/"),import.meta.url).href,o=a=>import(a),i;try{({runBuild:i}=await o(r))}catch{console.error("velu build is an internal command, not available in this distribution."),P.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"),P.exit(On?1:0)}}si().catch(e=>{console.error(P.env.VELU_DEBUG?e:`Error: ${e.message}`),P.exit(1)});
package/package.json CHANGED
@@ -1,64 +1,64 @@
1
- {
2
- "name": "@veluai/velu",
3
- "version": "0.2.15",
4
- "type": "module",
5
- "bin": "./dist/cli.js",
6
- "publishConfig": {
7
- "access": "public"
8
- },
9
- "files": [
10
- "dist/**",
11
- "src/runtime/**",
12
- "src/navigation.js",
13
- "src/template.html",
14
- "src/lib/issues.js",
15
- "src/lib/extract-mdx-error.js",
16
- "src/lib/known-components.js",
17
- "runtime/velu-ui/**",
18
- "schema/**",
19
- "templates/**"
20
- ],
21
- "scripts": {
22
- "build": "node scripts/build.mjs",
23
- "prepack": "node scripts/build.mjs",
24
- "build:preview-runtime": "vite build -c vite.preview.config.mjs",
25
- "test:parity": "node scripts/parity-test.mjs"
26
- },
27
- "dependencies": {
28
- "@apidevtools/swagger-parser": "^10.1.0",
29
- "@icons-pack/react-simple-icons": ">=13.0.0 <13.13.0",
30
- "@mdx-js/mdx": "^3.1.1",
31
- "@mdx-js/react": "^3.1.1",
32
- "@mdx-js/rollup": "^3.1.1",
33
- "@tailwindcss/vite": "^4.1.0",
34
- "@vitejs/plugin-react": "^4.3.4",
35
- "chokidar": "^3.6.0",
36
- "estree-util-value-to-estree": "^3.5.0",
37
- "express": "^4.21.1",
38
- "github-slugger": "^2.0.0",
39
- "iso-639-1": "^3.1.5",
40
- "js-yaml": "^4.1.0",
41
- "lucide-react": "^0.460.0",
42
- "mdast-util-to-string": "^4.0.0",
43
- "prism-react-renderer": "^2.4.0",
44
- "prismjs": "^1.29.0",
45
- "react": "^18.3.1",
46
- "react-dom": "^18.3.1",
47
- "react-router-dom": "^6.28.0",
48
- "rehype-slug": "^6.0.0",
49
- "remark-frontmatter": "^5.0.0",
50
- "remark-gfm": "^4.0.1",
51
- "remark-mdx-frontmatter": "^5.2.0",
52
- "tailwindcss": "^4.1.0",
53
- "unist-util-visit": "^5.1.0",
54
- "vite": "^5.4.11"
55
- },
56
- "devDependencies": {
57
- "@fontsource/outfit": "^5.0.0",
58
- "@resvg/resvg-js": "^2.6.2",
59
- "esbuild": "^0.28.0",
60
- "pagefind": "^1.3.0",
61
- "playwright": "^1.48.0",
62
- "satori": "^0.12.0"
63
- }
64
- }
1
+ {
2
+ "name": "@veluai/velu",
3
+ "version": "0.2.19",
4
+ "type": "module",
5
+ "bin": "./dist/cli.js",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "files": [
10
+ "dist/**",
11
+ "src/runtime/**",
12
+ "src/navigation.js",
13
+ "src/template.html",
14
+ "src/lib/issues.js",
15
+ "src/lib/extract-mdx-error.js",
16
+ "src/lib/known-components.js",
17
+ "runtime/velu-ui/**",
18
+ "schema/**",
19
+ "templates/**"
20
+ ],
21
+ "scripts": {
22
+ "build": "node scripts/build.mjs",
23
+ "prepack": "node scripts/build.mjs",
24
+ "build:preview-runtime": "vite build -c vite.preview.config.mjs",
25
+ "test:parity": "node scripts/parity-test.mjs"
26
+ },
27
+ "dependencies": {
28
+ "@apidevtools/swagger-parser": "^10.1.0",
29
+ "@icons-pack/react-simple-icons": ">=13.0.0 <13.13.0",
30
+ "@mdx-js/mdx": "^3.1.1",
31
+ "@mdx-js/react": "^3.1.1",
32
+ "@mdx-js/rollup": "^3.1.1",
33
+ "@tailwindcss/vite": "^4.1.0",
34
+ "@vitejs/plugin-react": "^4.3.4",
35
+ "chokidar": "^3.6.0",
36
+ "estree-util-value-to-estree": "^3.5.0",
37
+ "express": "^4.21.1",
38
+ "github-slugger": "^2.0.0",
39
+ "iso-639-1": "^3.1.5",
40
+ "js-yaml": "^4.1.0",
41
+ "lucide-react": "^0.460.0",
42
+ "mdast-util-to-string": "^4.0.0",
43
+ "prism-react-renderer": "^2.4.0",
44
+ "prismjs": "^1.29.0",
45
+ "react": "^18.3.1",
46
+ "react-dom": "^18.3.1",
47
+ "react-router-dom": "^6.28.0",
48
+ "rehype-slug": "^6.0.0",
49
+ "remark-frontmatter": "^5.0.0",
50
+ "remark-gfm": "^4.0.1",
51
+ "remark-mdx-frontmatter": "^5.2.0",
52
+ "tailwindcss": "^4.1.0",
53
+ "unist-util-visit": "^5.1.0",
54
+ "vite": "^5.4.11"
55
+ },
56
+ "devDependencies": {
57
+ "@fontsource/outfit": "^5.0.0",
58
+ "@resvg/resvg-js": "^2.6.2",
59
+ "esbuild": "^0.28.0",
60
+ "pagefind": "^1.3.0",
61
+ "playwright": "^1.48.0",
62
+ "satori": "^0.12.0"
63
+ }
64
+ }
@@ -56,13 +56,16 @@ function Icon({ icon }) {
56
56
 
57
57
  function Endpoint({ endpoint }) {
58
58
  const { activeHref, Link } = React.useContext(Ctx);
59
- const { method = 'GET', label, href = '#', active } = endpoint;
59
+ const { method, label, href = '#', active, icon } = endpoint;
60
60
  const isActive = Boolean(
61
61
  active || (href != null && href === activeHref),
62
62
  );
63
63
  const cls = `velu-api-sidebar__item${
64
64
  isActive ? ' velu-api-sidebar__item--active' : ''
65
65
  }`;
66
+ // A plain page sitting in an API tab (e.g. an "Introduction") has no HTTP
67
+ // method — show its icon (if any) where the method pill would be, never a
68
+ // stray badge.
66
69
  return (
67
70
  <li>
68
71
  <Link
@@ -70,7 +73,7 @@ function Endpoint({ endpoint }) {
70
73
  href={href}
71
74
  aria-current={isActive ? 'page' : undefined}
72
75
  >
73
- <MethodBadge method={method} />
76
+ {method ? <MethodBadge method={method} /> : <Icon icon={icon} />}
74
77
  <span className="velu-api-sidebar__label">{label}</span>
75
78
  </Link>
76
79
  </li>
@@ -92,7 +92,7 @@ function ExternalIcon() {
92
92
  /** Recursive node. depth 0 = top-level; depth >= 1 = nested (subitem style). */
93
93
  function Node({ item, depth }) {
94
94
  const { activeHref, Link } = React.useContext(SidebarCtx);
95
- const { label, href = '#', icon, external, items, method } = item;
95
+ const { label, href = '#', icon, external, items } = item;
96
96
  const base = depth === 0 ? 'velu-sidebar__item' : 'velu-sidebar__subitem';
97
97
 
98
98
  if (items && items.length) {
@@ -130,15 +130,7 @@ function Node({ item, depth }) {
130
130
  aria-current={active ? 'page' : undefined}
131
131
  {...linkProps}
132
132
  >
133
- {method ? (
134
- <span
135
- className={`velu-sidebar__method velu-method-badge--${String(method).toLowerCase()}`}
136
- >
137
- {method}
138
- </span>
139
- ) : (
140
- <Icon icon={icon} />
141
- )}
133
+ <Icon icon={icon} />
142
134
  <span className="velu-sidebar__label">{label}</span>
143
135
  {external ? <ExternalIcon /> : null}
144
136
  </LinkTag>
@@ -29,6 +29,7 @@ export { default as ApiClient } from './components/ApiClient.jsx';
29
29
  export { default as ApiSidebar } from './components/ApiSidebar.jsx';
30
30
  export { default as ApiReferencePage } from './components/ApiReferencePage.jsx';
31
31
  export { default as ApiSamples } from './components/ApiSamples.jsx';
32
+ export { setApiProxyTransport } from './lib/api-send.js';
32
33
  export { default as NotFound } from './components/NotFound.jsx';
33
34
  export { default as AskBar } from './components/AskBar.jsx';
34
35
  export { default as Chatbot } from './components/Chatbot.jsx';
@@ -44,6 +45,7 @@ export {
44
45
  export { default as Search } from './components/Search.jsx';
45
46
  export { default as pagefindSearch } from './lib/pagefind.js';
46
47
  export { createDocsAssistant } from './lib/docs-assistant.js';
48
+ export { createPageFeedback } from './lib/page-feedback.js';
47
49
  export { default as Image } from './components/Image.jsx';
48
50
  export {
49
51
  default as CodeBlock,
@@ -8,6 +8,19 @@
8
8
  const PROXY_URL = '/@velu-api-proxy';
9
9
  const BODY_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
10
10
 
11
+ // Pluggable proxy transport. The dev server and the built site both proxy via
12
+ // the same-origin HTTP endpoint (PROXY_URL). The instant preview, however,
13
+ // runs in a sandboxed iframe with no server behind that URL, so it registers a
14
+ // transport here that forwards the request to the editor host over postMessage
15
+ // (which proxies it server-side and replies). The real site never registers
16
+ // one, so it keeps using PROXY_URL. A transport receives the built request
17
+ // ({ method, url, headers, body }) and resolves the SAME shape the HTTP proxy
18
+ // returns: { status, statusText, headers, body } | { error }.
19
+ let proxyTransport = null;
20
+ export function setApiProxyTransport(fn) {
21
+ proxyTransport = typeof fn === 'function' ? fn : null;
22
+ }
23
+
11
24
  // Compose the concrete request (url + headers + body) from the operation and
12
25
  // the user-entered values: { auth, path, query, header } maps + bodyText.
13
26
  function buildRequest({ operation, server, values, bodyText }) {
@@ -56,6 +69,19 @@ async function readBody(res) {
56
69
  export async function sendApiRequest({ operation, server, proxy = true, values, bodyText }) {
57
70
  const req = buildRequest({ operation, server, values, bodyText });
58
71
 
72
+ // Proxied send. A registered transport (the instant preview's host bridge)
73
+ // takes precedence over the same-origin HTTP proxy — same return shape.
74
+ if (proxy && proxyTransport) {
75
+ const payload = await proxyTransport(req);
76
+ if (payload && payload.error) return { error: payload.error };
77
+ return {
78
+ status: payload?.status,
79
+ statusText: payload?.statusText || '',
80
+ headers: payload?.headers || {},
81
+ body: payload?.body,
82
+ };
83
+ }
84
+
59
85
  if (proxy) {
60
86
  const res = await fetch(PROXY_URL, {
61
87
  method: 'POST',
@@ -0,0 +1,72 @@
1
+ /**
2
+ * page-feedback — runtime client for the "Was this page helpful?" widget on a
3
+ * published docs site. POSTs to the backend's PUBLIC feedback API:
4
+ *
5
+ * POST /api/v1/public/feedback ({ page_url, helpful, reason_text, details })
6
+ *
7
+ * Same contract as docs-assistant: the tenant is resolved from the
8
+ * `X-Velu-Site-Host` header (falls back to Origin), and the httponly visitor
9
+ * cookie rides along via `credentials: 'include'` (so the API must be same-site
10
+ * with the docs — true for *.getvelu.com subdomains).
11
+ *
12
+ * `createPageFeedback({ apiBase, host })` returns `{ submit }`, shaped to wire
13
+ * straight into <PageFeedback onVote onSubmit>. Returns null without an apiBase
14
+ * (dev preview / unconfigured site) so the widget stays purely visual.
15
+ */
16
+
17
+ const trimSlash = (s) => String(s || '').replace(/\/+$/, '');
18
+
19
+ function siteHost(explicit) {
20
+ if (explicit) return explicit;
21
+ return typeof window !== 'undefined' ? window.location.host : '';
22
+ }
23
+
24
+ // The page the feedback is about. Drop hash + query here; the backend
25
+ // normalizes again server-side so per-page aggregation stays clean.
26
+ function currentPageUrl() {
27
+ if (typeof window === 'undefined') return '';
28
+ const { origin, pathname } = window.location;
29
+ return origin + pathname;
30
+ }
31
+
32
+ export function createPageFeedback({ apiBase, host } = {}) {
33
+ const base = trimSlash(apiBase);
34
+ if (!base) return null;
35
+ const url = `${base}/api/v1/public/feedback`;
36
+
37
+ /**
38
+ * Send one feedback submission.
39
+ * - helpful: boolean (Yes / No)
40
+ * - reason: short label from the "No" form (optional)
41
+ * - detail: free-text elaboration (optional)
42
+ * Best-effort: a failed request never disrupts the reader.
43
+ */
44
+ async function submit({ helpful, reason, detail } = {}) {
45
+ const body = {
46
+ page_url: currentPageUrl(),
47
+ helpful: !!helpful,
48
+ // reason_text is required by the API (min length 1); fall back to a
49
+ // sensible default when the reader didn't pick a reason (e.g. on "Yes").
50
+ reason_text:
51
+ (reason && String(reason).trim()) || (helpful ? 'Helpful' : 'Not helpful'),
52
+ details: detail ? String(detail) : null,
53
+ };
54
+ try {
55
+ await fetch(url, {
56
+ method: 'POST',
57
+ credentials: 'include',
58
+ headers: {
59
+ 'Content-Type': 'application/json',
60
+ 'X-Velu-Site-Host': siteHost(host),
61
+ },
62
+ body: JSON.stringify(body),
63
+ });
64
+ } catch {
65
+ /* feedback is best-effort — swallow network errors */
66
+ }
67
+ }
68
+
69
+ return { submit };
70
+ }
71
+
72
+ export default createPageFeedback;
package/src/navigation.js CHANGED
@@ -297,6 +297,12 @@ export function resolve(url, tree, pagesMap = {}) {
297
297
  pagesMap,
298
298
  ctx,
299
299
  );
300
+ // Whether THIS tab's sidebar holds any API page. The chrome uses it to
301
+ // pick ONE sidebar style for the whole tab (flat API list vs nested docs
302
+ // list) rather than flipping per selected page — so a tab that mixes an
303
+ // intro page with generated API operations reads as a single, stable
304
+ // sidebar. Derived from the sidebar items (the API ones carry `method`).
305
+ const sidebarHasApi = sidebarSectionsHaveApi(sidebarSections);
300
306
  // Anchors are gathered from every container along the active path —
301
307
  // root (global), the active product/version/language, and the active
302
308
  // tab — so global anchors show on every page while tab-scoped ones
@@ -359,6 +365,7 @@ export function resolve(url, tree, pagesMap = {}) {
359
365
  url: norm,
360
366
  frontmatter: pagesMap[norm]?.frontmatter ?? {},
361
367
  sidebarSections,
368
+ sidebarHasApi,
362
369
  anchors,
363
370
  tabs,
364
371
  activeTab,
@@ -375,6 +382,15 @@ export function resolve(url, tree, pagesMap = {}) {
375
382
  };
376
383
  }
377
384
 
385
+ /** True when any item in the sidebar (at any nesting depth) is an API page —
386
+ * i.e. carries an HTTP `method`. Lets the chrome render the whole tab with
387
+ * the API sidebar style instead of switching per selected page. */
388
+ function sidebarSectionsHaveApi(sections) {
389
+ const walk = (items) =>
390
+ (items ?? []).some((it) => it.method || (it.items && walk(it.items)));
391
+ return sections.some((s) => walk(s.items));
392
+ }
393
+
378
394
  /** Flatten sidebar sections (incl. nested groups) to an ordered list of
379
395
  * page links {label, href} — the page reading order for prev/next. */
380
396
  function flattenSidebar(sections) {
@@ -41,6 +41,7 @@ import {
41
41
  Search,
42
42
  pagefindSearch,
43
43
  createDocsAssistant,
44
+ createPageFeedback,
44
45
  Logo,
45
46
  SocialLinks,
46
47
  Tree,
@@ -63,6 +64,25 @@ import ErrorBoundary from './ErrorBoundary.jsx';
63
64
  // preview. Identical on SSR + client in each mode, so no hydration mismatch.
64
65
  const IS_DEV_PREVIEW = import.meta.env.DEV;
65
66
 
67
+ // Flatten a sidebar section's items (which may nest into sub-groups) into the
68
+ // flat endpoint list <ApiSidebar> wants. API tabs are flat in practice; this
69
+ // only guards the rare case of a normal nested group living beside generated
70
+ // API operations in the same tab, so its leaf pages still get a working link.
71
+ function sectionToEndpoints(items) {
72
+ const out = [];
73
+ for (const it of items ?? []) {
74
+ if (it.items) out.push(...sectionToEndpoints(it.items));
75
+ else
76
+ out.push({
77
+ method: it.method,
78
+ label: it.label,
79
+ href: it.href,
80
+ icon: it.icon,
81
+ });
82
+ }
83
+ return out;
84
+ }
85
+
66
86
  const CALLOUT_TYPES = [
67
87
  'note',
68
88
  'warning',
@@ -760,6 +780,17 @@ function DocsPage() {
760
780
  return createDocsAssistant({ apiBase, host: site.assistant?.host });
761
781
  }, []);
762
782
 
783
+ // Page-feedback backend: reuses the same injected apiBase as the assistant
784
+ // (baked into every published velu.json), so the "Was this page helpful?"
785
+ // widget can POST to /api/v1/public/feedback. Null in the dev preview, where
786
+ // the widget stays purely visual.
787
+ const pageFeedback = React.useMemo(() => {
788
+ if (IS_DEV_PREVIEW) return null;
789
+ const apiBase = site.assistant?.apiBase;
790
+ if (!apiBase) return null;
791
+ return createPageFeedback({ apiBase, host: site.assistant?.host });
792
+ }, []);
793
+
763
794
  const frontmatter = entry?.frontmatter ?? {};
764
795
  const PageComponent = entry?.Component ?? null;
765
796
  const pageToc = entry?.toc ?? [];
@@ -1345,16 +1376,16 @@ function DocsPage() {
1345
1376
  scrollPaddingBlockEnd: 'var(--s1)',
1346
1377
  }}
1347
1378
  >
1348
- {entry?.api ? (
1379
+ {/* Sidebar STYLE is chosen per-tab, not per-page: if this tab
1380
+ holds any API page, the whole tab uses the flat API sidebar
1381
+ (so opening an intro page next to API operations doesn't flip
1382
+ the sidebar shape). */}
1383
+ {nav?.sidebarHasApi ? (
1349
1384
  <ApiSidebar
1350
1385
  sections={(nav?.sidebarSections ?? []).map((s) => ({
1351
1386
  title: s.title,
1352
1387
  icon: s.icon,
1353
- endpoints: (s.items ?? []).map((it) => ({
1354
- method: it.method,
1355
- label: it.label,
1356
- href: it.href,
1357
- })),
1388
+ endpoints: sectionToEndpoints(s.items),
1358
1389
  }))}
1359
1390
  activeHref={pathname}
1360
1391
  linkComponent={RouterLink}
@@ -1553,7 +1584,18 @@ function DocsPage() {
1553
1584
  {/* Page-foot feedback widget — ref'd so the sticky AskBar
1554
1585
  above can hide as the user scrolls near it. */}
1555
1586
  <div ref={feedbackRef} style={{ marginTop: 'var(--s3)' }}>
1556
- <PageFeedback />
1587
+ {/* key resets the widget's vote state on page change. "Yes"
1588
+ submits immediately; "No" submits once its form is sent.
1589
+ Handlers are no-ops in the dev preview (pageFeedback null). */}
1590
+ <PageFeedback
1591
+ key={pathname}
1592
+ onVote={(v) => {
1593
+ if (v === 'yes') pageFeedback?.submit({ helpful: true });
1594
+ }}
1595
+ onSubmit={({ reason, detail }) =>
1596
+ pageFeedback?.submit({ helpful: false, reason, detail })
1597
+ }
1598
+ />
1557
1599
  </div>
1558
1600
  {/* Previous / next page navigation — derived from the
1559
1601
  sidebar reading order of the active section. */}