@veluai/velu 0.1.15 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +50 -23
- package/package.json +9 -3
- package/runtime/velu-ui/components/ApiClient.jsx +97 -11
- package/runtime/velu-ui/components/ApiReferencePage.jsx +384 -0
- package/runtime/velu-ui/components/ApiSamples.jsx +36 -0
- package/runtime/velu-ui/components/ContextMenu.jsx +272 -0
- package/runtime/velu-ui/components/NotFound.jsx +63 -0
- package/runtime/velu-ui/components/Sidebar.jsx +10 -2
- package/runtime/velu-ui/components/TryItBar.jsx +15 -3
- package/runtime/velu-ui/components/api-page.css +208 -0
- package/runtime/velu-ui/components/api.css +165 -9
- package/runtime/velu-ui/components/context-menu.css +170 -0
- package/runtime/velu-ui/components/docs-layout.css +18 -0
- package/runtime/velu-ui/components/not-found.css +94 -0
- package/runtime/velu-ui/components/powered-by.css +6 -0
- package/runtime/velu-ui/index.js +4 -0
- package/runtime/velu-ui/lib/api-send.js +92 -0
- package/runtime/velu-ui/lib/brand-icons.jsx +102 -0
- package/runtime/velu-ui/styles.css +3 -0
- package/schema/velu.schema.json +121 -0
- package/src/navigation.js +11 -2
- package/src/runtime/App.jsx +95 -6
- package/templates/starter/api-reference/introduction.mdx +29 -14
- package/templates/starter/openapi.json +160 -0
- package/templates/starter/velu.json +10 -2
- package/templates/starter/api-reference/endpoint/create.mdx +0 -24
- package/templates/starter/api-reference/endpoint/get.mdx +0 -27
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`,"utf-8");let
|
|
4
|
-
`)}var Lt,Ot,ne,oe,_t,re=k(()=>{Lt="#dc143c",Ot="Google Sans Flex",ne="/@velu-logo-light",oe="/@velu-logo-dark";_t={twitter:"x","x-twitter":"x"}});import Pt from"github-slugger";import Ct from"iso-639-1";function Et(e){let t=String(e).toLowerCase();return Ct.getNativeName(t)||e}function ie(e){return new Pt().slug(String(e??""))}function Nt(e){let t=String(e).replace(/^\/+|\/+$/g,"").split("/").filter(Boolean);return t[t.length-1]==="index"&&t.pop(),"/"+t.join("/")}function V(e){let t={kind:"root",children:K(e??{})};return Ge(t.children),t}function K(e){let t=Array.isArray(e.anchors)?e.anchors.map(Ut):[];if(Array.isArray(e.products))return[...t,...e.products.map(Ft)];if(Array.isArray(e.versions))return[...t,...e.versions.map(It)];if(Array.isArray(e.languages))return[...t,...e.languages.map(Rt)];if(Array.isArray(e.tabs))return[...t,...e.tabs.map(Mt)];let o=[...t];return Array.isArray(e.groups)&&o.push(...e.groups.map(Ue)),Array.isArray(e.pages)&&o.push(...e.pages.map(ze)),o}function Ft(e){return{kind:"product",label:e.name??e.product,slug:ie(e.product),icon:e.icon,color:e.color,default:!!e.default,children:K(e)}}function It(e){return{kind:"version",label:e.version,slug:ie(e.version),default:!!e.default,children:K(e)}}function Rt(e){let t=String(e.language);return{kind:"language",code:t,label:Et(t),slug:ie(t),default:!!e.default,children:K(e)}}function Mt(e){return{kind:"tab",label:e.tab,slug:ie(e.tab),icon:e.icon,href:e.href,children:K(e)}}function Ut(e){return{kind:"anchor",label:e.anchor,icon:e.icon,href:e.href,color:e.color}}function Ue(e){let t=(e.pages??[]).map(ze);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 ze(e){return typeof e=="string"?{kind:"page",pagePath:e}:Ue(e)}function Ge(e){for(let t of Tt){let o=e.filter(n=>n.kind===t);o.length&&!o.some(n=>n.default)&&(o[0].default=!0)}for(let t of e)t.children&&Ge(t.children)}function Ve(e){let t=[],o=(n,r,i)=>{if(n.kind==="page"){t.push({pagePath:n.pagePath,url:zt(n.pagePath,r),ctx:{...r},ancestors:i,node:n});return}let a=r;n.kind==="product"?a={...r,product:n.default?null:n.slug}:n.kind==="version"?a={...r,version:n.default?null:n.slug}:n.kind==="language"&&(a={...r,language:n.default?null:n.slug});let s=n.kind==="root"?i:[...i,n];for(let l of n.children??[])o(l,a,s)};return o(e,{product:null,version:null,language:null},[]),t}function zt(e,t){let o=[t.product,t.version,t.language].filter(Boolean),n=Nt(e).split("/").filter(Boolean);return"/"+[...o,...n].join("/")}var Tt,W=k(()=>{Tt=["product","version","language"]});import Gt from"node:fs";import Be from"node:path";function B(e,t){let o=[],n=[],r=new Set;for(let i of Ve(e)){if(r.has(i.url)){o.push(`duplicate URL "${i.url}" (page "${i.pagePath}") \u2014 keeping the first occurrence`);continue}r.add(i.url);let a=i.pagePath.replace(/^\/+|\/+$/g,""),s=Be.join(t,...a.split("/"))+".mdx",l=Gt.existsSync(s);l||o.push(`page "${i.pagePath}" \u2192 ${Be.relative(t,s)} not found`),n.push({pagePath:i.pagePath,url:i.url,fileAbsPath:s,exists:l})}return{pageEntries:n,warnings:o}}var se=k(()=>{W()});import Vt from"node:fs";import Z from"node:path";function He(e){return{name:"velu-site",resolveId(t){return t===qe?Je:null},load(t){return t!==Je?null:Bt(e)}}}function Bt(e){let t={};try{t=JSON.parse(Vt.readFileSync(Z.join(e,"velu.json"),"utf-8"))}catch{}let o=V(t.navigation??{}),{pageEntries:n,warnings:r}=B(o,e);for(let c of r)console.warn(`[velu] nav: ${c}`);let i=Y(t.logo),a={name:t.name??Z.basename(e),logo:i?{light:ne,dark:oe,href:i.href,mono:i.light===i.dark}:null,footer:ve(t.footer),navbar:ye(t.navbar)},s=[],l=[],u=0;for(let c of n)if(c.exists){let f=JSON.stringify(c.fileAbsPath.split(Z.sep).join("/")),A=JSON.stringify(Z.relative(e,c.fileAbsPath).split(Z.sep).join("/")),p=`__p${u++}`;s.push(`import * as ${p} from ${f};`),l.push(` ${JSON.stringify(c.url)}: { Component: ${p}.default, frontmatter: ${p}.frontmatter, toc: ${p}.toc, relPath: ${A} },`)}else l.push(` ${JSON.stringify(c.url)}: { missing: true },`);return["// AUTO-GENERATED by vite-plugin-velu-site. Do not edit.",s.join(`
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`)
|
|
9
|
-
|
|
10
|
-
`)}
|
|
2
|
+
var cn=Object.defineProperty;var j=(e,t)=>()=>(e&&(t=e(e=0)),t);var Pe=(e,t)=>{for(var n in t)cn(e,n,{get:t[n],enumerable:!0})};var rt={};Pe(rt,{initProject:()=>mn});import D from"node:fs/promises";import X from"node:path";import{fileURLToPath as un}from"node:url";async function mn(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(fn,e,{recursive:!0});let n=X.join(e,"velu.json"),r=JSON.parse(await D.readFile(n,"utf-8"));r.name=t,await D.writeFile(n,JSON.stringify(r,null,2)+`
|
|
3
|
+
`,"utf-8");let o=await nt(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 nt(e,t=e,n=[]){let r=await D.readdir(e,{withFileTypes:!0});for(let o of r){let i=X.join(e,o.name);o.isDirectory()?await nt(i,t,n):n.push(X.relative(t,i).split(X.sep).join("/"))}return n.sort()}var pn,fn,ot=j(()=>{pn=X.dirname(un(import.meta.url)),fn=X.resolve(pn,"..","templates","starter")});import dn from"node:fs/promises";import Ce from"node:path";function st(e){if(!e.favicon)return null;let t=Ce.extname(e.favicon).toLowerCase();return{url:Ee+t,type:yn[t]||""}}function te(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 Fe(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:vn[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 _e(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:_e(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:_e(o)}:{kind:"button",label:r.label??"",href:o,external:_e(o)}}return!t.length&&!n?null:{links:t,primary:n}}function at(e){if(e==null)return{options:[...it],display:"header"};if(typeof e!="object")return{options:[],display:"header"};let t=e.display==="toc"?"toc":"header",n=Array.isArray(e.options)?e.options:it,r=[];for(let o of n)typeof o=="string"?bn.has(o)&&r.push(o):o&&typeof o=="object"&&o.title&&o.href&&r.push({title:String(o.title),description:o.description?String(o.description):"",href:String(o.href),icon:typeof o.icon=="string"?o.icon:void 0});return{options:r,display:t}}function z(e){if(!e||typeof e!="object")return{server:null,proxy:!0,languages:void 0};let t=e.playground||{};return{server:typeof e.server=="string"?e.server.trim():null,proxy:t.proxy!==!1&&t.display!=="none",languages:Array.isArray(e.examples?.languages)?e.examples.languages:void 0}}function xn(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 Ie(e={},t){let n=e.colors?.primary??gn;return{name:e.name??t??"docs",url:typeof e.url=="string"&&e.url.trim()?e.url.trim().replace(/\/+$/,""):null,seo:xn(e.seo),thumbnails:e.thumbnails&&typeof e.thumbnails=="object"&&typeof e.thumbnails.background=="string"?{background:e.thumbnails.background}:null,colors:{primary:n,light:e.colors?.light??n,dark:e.colors?.dark??n},favicon:e.favicon??null,api:z(e.api),logo:te(e.logo),footer:Fe(e.footer),navbar:Ne(e.navbar),font:{family:e.font?.family??hn},navigation:e.navigation??null}}async function lt(e){let t=Ce.join(e,"velu.json"),n;try{n=await dn.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 Ie(r,Ce.basename(e))}function ct(e){let{colors:t,font:n}=e;return[":root:root {",` --accent-color: ${t.light};`,` --font-sans: "${n.family}", sans-serif;`,"}",':root:root[data-theme="dark"] {',` --accent-color: ${t.dark};`,"}"].join(`
|
|
4
|
+
`)}var gn,hn,me,de,Ee,yn,vn,bn,it,Y=j(()=>{gn="#dc143c",hn="Google Sans Flex",me="/@velu-logo-light",de="/@velu-logo-dark",Ee="/@velu-favicon",yn={".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"};vn={twitter:"x","x-twitter":"x"};bn=new Set(["copy","assistant","view","download-pdf","download-spec","chatgpt","claude","perplexity","grok","aistudio","devin","windsurf","mcp","add-mcp","cursor","vscode","devin-mcp"]),it=["copy","view","chatgpt","claude"]});import{visit as $n}from"unist-util-visit";import{toString as wn}from"mdast-util-to-string";import Sn from"github-slugger";import{valueToEstree as kn}from"estree-util-value-to-estree";function ne(){return e=>{let t=new Sn,n=[];$n(e,"heading",a=>{let s=wn(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:kn(i)}]}}]}}})}}var Re=j(()=>{});import jn from"github-slugger";import An from"iso-639-1";function Tn(e){let t=String(e).toLowerCase();return An.getNativeName(t)||e}function ge(e){return new jn().slug(String(e??""))}function Ln(e){let t=String(e).replace(/^\/+|\/+$/g,"").split("/").filter(Boolean);return t[t.length-1]==="index"&&t.pop(),"/"+t.join("/")}function ut(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 U(e){let t={kind:"root",children:re(e??{})};return mt(t.children),t}function re(e){let t=Array.isArray(e.anchors)?e.anchors.map(Fn):[];if(Array.isArray(e.products))return[...t,...e.products.map(Pn)];if(Array.isArray(e.versions))return[...t,...e.versions.map(_n)];if(Array.isArray(e.languages))return[...t,...e.languages.map(Cn)];if(Array.isArray(e.tabs))return[...t,...e.tabs.map(En)];let n=[...t];return Array.isArray(e.groups)&&n.push(...e.groups.map(pt)),Array.isArray(e.pages)&&n.push(...e.pages.map(ft)),n}function Pn(e){return{kind:"product",label:e.name??e.product,slug:ge(e.product),icon:e.icon,color:e.color,default:!!e.default,children:re(e)}}function _n(e){return{kind:"version",label:e.version,slug:ge(e.version),default:!!e.default,children:re(e)}}function Cn(e){let t=String(e.language);return{kind:"language",code:t,label:Tn(t),slug:ge(t),default:!!e.default,children:re(e)}}function En(e){return{kind:"tab",label:e.tab,slug:ge(e.tab),icon:e.icon,href:e.href,children:re(e)}}function Fn(e){return{kind:"anchor",label:e.anchor,icon:e.icon,href:e.href,color:e.color}}function pt(e){let t=(e.pages??[]).map(ft);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 ft(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 mt(e){for(let t of On){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&&mt(t.children)}function K(e){let t=[],n=(r,o,i)=>{if(r.kind==="page"){t.push({pagePath:r.pagePath,url:Nn(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 Nn(e,t){let n=[t.product,t.version,t.language].filter(Boolean),r=Ln(e).split("/").filter(Boolean);return"/"+[...n,...r].join("/")}var On,B=j(()=>{On=["product","version","language"]});import In from"node:fs";import dt from"node:path";function M(e,t){let n=[],r=[],o=new Set;for(let i of K(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=dt.join(t,...a.split("/"))+".mdx",l=In.existsSync(s);l||n.push(`page "${i.pagePath}" \u2192 ${dt.relative(t,s)} not found`),r.push({pagePath:i.pagePath,url:i.url,fileAbsPath:s,exists:l})}return{pageEntries:r,warnings:n}}var oe=j(()=>{B()});import Rn from"@apidevtools/swagger-parser";async function zn(e){return Rn.dereference(e)}function G(e){return!e||typeof e!="object"?e||{}:Array.isArray(e.allOf)?e.allOf.reduce((t,n)=>{let r=G(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?G(e.oneOf[0]):Array.isArray(e.anyOf)&&e.anyOf.length?G(e.anyOf[0]):e}function he(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`${he(t.items||{})}[]`;let n=t.type||(t.properties?"object":"any");return t.format?`${n}<${t.format}>`:n}function ie(e,t=0){let n=G(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>=Mn)return n.type==="object"?{}:null;switch(n.type){case"object":{let r={};for(let[o,i]of Object.entries(n.properties||{}))r[o]=ie(i,t+1);return r}case"array":return[ie(n.items||{},t+1)];case"integer":case"number":return 0;case"boolean":return!0;default:return Bn(n)}}function Bn(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 ht(e){let t=G(e);if(!t||t.type!=="object"||!t.properties)return t&&(t.type||t.items)?[{name:"body",type:he(t),required:!1,description:t.description||""}]:[];let n=new Set(t.required||[]);return Object.entries(t.properties).map(([r,o])=>{let i=G(o);return{name:r,type:he(i),required:n.has(r),description:i.description||"",enum:Array.isArray(i.enum)?i.enum:void 0,deprecated:i.deprecated||void 0}})}function Gn(e){let t=e.schema||{};return{name:e.name,in:e.in,required:e.in==="path"?!0:!!e.required,type:he(t),description:e.description||"",enum:Array.isArray(t.enum)?t.enum:void 0,example:ie(t),deprecated:e.deprecated||void 0}}function yt(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 Jn(e){if(!e)return null;let t=yt(e.content);if(!t)return null;let n=t.media.schema||{};return{required:!!e.required,description:e.description||"",contentType:t.contentType,fields:ht(n),example:t.media.example??ie(n)}}function Vn(e){return!e||typeof e!="object"?[]:Object.entries(e).map(([t,n])=>{let r=yt(n?.content),o=r?.media?.schema||{};return{status:t,description:n?.description||"",contentType:r?.contentType||null,fields:r?ht(o):[],example:r?r.media.example??ie(o):null}})}function qn(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(Hn(i,a)))}return n.filter(Boolean)}function Hn(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 gt(e){return String(e).replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function Dn(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 u of s)u&&l[u.in]&&l[u.in].push(Gn(u));let p=r.security??e.globalSecurity;return{id:r.operationId?gt(r.operationId):`${t}-${gt(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:qn(p,a),parameters:l,body:Jn(r.requestBody),responses:Vn(r.responses),servers:(i||[]).map(u=>u.url).filter(Boolean)}}function Xn(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 u=r.security??e.security;if(a&&Array.isArray(u)&&u.length){let c={};for(let b of u)for(let d of Object.keys(b||{}))a[d]&&(c[d]=a[d]);Object.keys(c).length&&(e.swagger?s.securityDefinitions=c:s.components={securitySchemes:c})}return s}function Yn(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 u of Un){let c=s[u];!c||typeof c!="object"||(t.push(Dn({method:u,path:a,op:c,sharedParams:l,servers:c.servers||p,globalSecurity:o,schemes:r})),n.push(Xn(e,a,u,c,l,c.servers||p,r)))}}return{operations:t,segments:n}}async function vt(e){let t=await zn(e),n=t.servers||(t.host?[{url:`https://${t.host}${t.basePath||""}`}]:[]),{operations:r,segments:o}=Yn(t);return{title:t.info?.title||"API Reference",version:t.info?.version||"",servers:n.map(i=>i.url).filter(Boolean),operations:r,segments:o}}var Un,Mn,bt=j(()=>{Un=["get","post","put","patch","delete","options","head","trace"],Mn=6});function Kn(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 Wn(e){let t=`curl --request ${e.method} \\
|
|
5
|
+
--url ${e.url}`;for(let[n,r]of Object.entries(e.headers))t+=` \\
|
|
6
|
+
--header '${n}: ${r}'`;return e.body!=null&&(t+=` \\
|
|
7
|
+
--data '${JSON.stringify(e.body)}'`),t}function Zn(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
|
+
`);t.push(` headers: {
|
|
9
|
+
${n}
|
|
10
|
+
}`)}return e.body!=null&&t.push(` body: JSON.stringify(${Ue(e.body," ")})`),[`const res = await fetch('${e.url}', {`,t.join(`,
|
|
11
|
+
`),"});","const data = await res.json();"].join(`
|
|
12
|
+
`)}function Qn(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
|
+
`);t.push(`headers = {
|
|
14
|
+
${r}
|
|
15
|
+
}`)}let n=["url"];return e.body!=null&&(t.push(`payload = ${Ue(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(`
|
|
16
|
+
`)}function er(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 = ${Ue(e.body,"")}.to_json`),n.push("","response = http.request(request)","puts response.body"),n.join(`
|
|
17
|
+
`)}function $t(e,{server:t,languages:n=Me}={}){let r=Kn(e,{server:t});return n.filter(o=>xt[o]).map(o=>({key:o,label:tr[o],language:nr[o],code:xt[o](r)}))}var Ue,xt,tr,nr,Me,wt=j(()=>{Ue=(e,t)=>JSON.stringify(e,null,2).split(`
|
|
18
|
+
`).map((n,r)=>r===0?n:t+n).join(`
|
|
19
|
+
`);xt={curl:Wn,javascript:Zn,python:Qn,ruby:er},tr={curl:"cURL",javascript:"JavaScript",python:"Python",ruby:"Ruby"},nr={curl:"bash",javascript:"javascript",python:"python",ruby:"ruby"},Me=["curl","javascript","python","ruby"]});import rr from"node:path";function St(e,t){if(!t||typeof t!="object")return e;let n=z(t);return{server:t.server!=null?n.server:e?.server??null,proxy:t.playground!=null?n.proxy:e?.proxy!==!1,languages:t.examples?.languages!=null?n.languages:e?.languages}}function or(e,t){return/^https?:\/\//.test(e)?e:rr.resolve(t,e.replace(/^\/+/,""))}function ir(e,{base:t,api:n,ops:r}){let o=n?.server,i=n?.languages||Me,a={proxy:n?.proxy!==!1,server:o??null},s=new Map;for(let p of e){let u=p.op.tags?.[0]||"API";s.has(u)||s.set(u,[]),s.get(u).push(p)}let l=[];for(let[p,u]of s){let c=u.map(({op:b,segment:d})=>{let $=`${t}/${ze(p)}/${b.id}`;return r[$]={operation:b,samples:$t(b,{server:o||b.servers?.[0],languages:i}),segment:d,title:b.title,description:b.description,method:b.method,api:a},{apiPage:$,label:b.title,method:b.method}});l.push({group:p,pages:c})}return l}async function kt(e,{targetDir: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:u}=await vt(or(s,t));l.forEach((c,b)=>{!c.servers?.length&&u?.length&&(c.servers=u),a.push({op:c,segment:p[b]})})}return ir(a,{base:n,api:r,ops:o})}async function jt(e,{targetDir:t,api:n,ops:r,baseHint:o}){if(!e||typeof e!="object")return e;if(typeof e.tab=="string"&&e.openapi){let a=ze(e.tab),s=St(n,e.api),l=await kt(e.openapi,{targetDir:t,base:a,api:s,ops:r}),{openapi:p,api:u,...c}=e;return{...c,groups:[...c.groups||[],...l]}}if(typeof e.group=="string"&&e.openapi){let a=ze(e.group),s=St(n,e.api),l=await kt(e.openapi,{targetDir:t,base:a,api:s,ops:r}),{openapi:p,api:u,...c}=e,b=l.flatMap(d=>d.pages);return{...c,pages:[...c.pages||[],...b]}}let i={...e};for(let a of["products","versions","languages","tabs","groups"])Array.isArray(e[a])&&(i[a]=await Promise.all(e[a].map(s=>jt(s,{targetDir:t,api:n,ops:r,baseHint:o}))));return i}async function ye(e,{targetDir:t,api:n}={}){let r={};return!e||typeof e!="object"?{nav:e,ops:r}:{nav:await jt(e,{targetDir:t,api:n,ops:r}),ops:r}}var ze,Be=j(()=>{Y();bt();wt();ze=e=>String(e??"").replace(/\{[^}]+\}/g,t=>t.slice(1,-1)).replace(/[^a-zA-Z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()||"x"});import sr from"node:fs";import se from"node:path";function Tt(e){return{name:"velu-site",resolveId(t){return t===Ot?At:null},async load(t){return t!==At?null:ar(e)}}}async function ar(e){let t={};try{t=JSON.parse(sr.readFileSync(se.join(e,"velu.json"),"utf-8"))}catch{}let n=z(t.api),r=t.navigation??{},o={};try{let x=await ye(t.navigation??{},{targetDir:e,api:n});r=x.nav,o=x.ops}catch(x){console.warn(`[velu] openapi: ${x.message}`)}let i=U(r),{pageEntries:a,warnings:s}=M(i,e);for(let x of s)console.warn(`[velu] nav: ${x}`);let l=te(t.logo),p={name:t.name??se.basename(e),logo:l?{light:me,dark:de,href:l.href,mono:l.light===l.dark}:null,footer:Fe(t.footer),navbar:Ne(t.navbar),contextual:at(t.contextual)},u=[],c=[],b=0;for(let x of a){if(!x.exists)continue;let y=JSON.stringify(x.fileAbsPath.split(se.sep).join("/")),f=JSON.stringify(se.relative(e,x.fileAbsPath).split(se.sep).join("/")),g=`__p${b++}`;u.push(`import * as ${g} from ${y};`),c.push(` ${JSON.stringify(x.url)}: { Component: ${g}.default, frontmatter: ${g}.frontmatter, toc: ${g}.toc, relPath: ${f} },`)}let d=new Set(a.filter(x=>x.exists).map(x=>x.url));for(let x of a)!x.exists&&!d.has(x.url)&&c.push(` ${JSON.stringify(x.url)}: { missing: true },`);let $=[],m=[],L=[],h=!1,w=0;for(let x of K(i)){if(!x.node?.api)continue;let y=o[x.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(x.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})} }); }`),c.push(` ${JSON.stringify(x.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 = [
|
|
20
|
+
${L.join(`,
|
|
21
|
+
`)}
|
|
22
|
+
];`),$.push(m.join(`
|
|
23
|
+
`)));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
|
+
`),u.join(`
|
|
25
|
+
`),$.join(`
|
|
26
|
+
`),"","export const pages = {",c.join(`
|
|
27
|
+
`),"};",`export const navigation = ${JSON.stringify(i)};`,`export const site = ${JSON.stringify(p)};`,""].join(`
|
|
28
|
+
`)}var Ot,At,Lt=j(()=>{B();oe();Y();Be();Ot="virtual:velu-site",At="\0"+Ot});import{visit as lr}from"unist-util-visit";function cr(e,t){let n=Pt(e).replace(/[?#].*$/,""),r=Pt(t).replace(/\/+$/,"");return r&&n.toLowerCase().startsWith(r.toLowerCase())?n.slice(r.length).replace(/^\/+/,""):null}function _t(e,t){return()=>(n,r)=>{typeof e=="function"&&lr(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:cr(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 Pt,Ct=j(()=>{Pt=e=>String(e||"").replace(/\\/g,"/")});import ve from"node:path";import ur from"node:fs";import{createRequire as pr}from"node:module";import fr from"@tailwindcss/vite";import mr from"@vitejs/plugin-react";import dr from"@mdx-js/rollup";import gr from"remark-frontmatter";import hr from"remark-mdx-frontmatter";import yr from"remark-gfm";import vr from"rehype-slug";function br(e){let n=pr(import.meta.url).resolve("@mdx-js/react"),r=ve.resolve(e,"runtime","velu-ui"),o=ur.existsSync(r)?r:ve.resolve(e,"..","velu-ui","src");return[{find:"@mdx-js/react",replacement:n},{find:/^velu-ui$/,replacement:ve.join(o,"index.js")},{find:/^velu-ui\//,replacement:o+"/"}]}function Et({targetDir:e,VITE_ROOT:t,validateProps:n}){return{root:t,plugins:[Tt(e),dr({remarkPlugins:[gr,hr,yr,ne,_t(n,e)],rehypePlugins:[vr],providerImportSource:"@mdx-js/react"}),mr(),fr({optimize:!1})],cacheDir:ve.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"],esbuildOptions:{loader:{".mdx":"jsx"}}},resolve:{alias:br(t),dedupe:["react","react-dom","@mdx-js/react"]}}}var Ft=j(()=>{Re();Lt();Ct()});function A(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 xr(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 be(e,t=[]){if(!e)return null;let n=String(e).toLowerCase(),r=null,o=1/0;for(let a of t){let s=xr(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 $r(e,t){return e==="warning"?E(t,_.yellow,"\u26A0"):e==="info"?E(t,_.cyan,"\u2139"):E(t,_.red,"\u2716")}function Je(e,{color:t=!1}={}){let n=Ge[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(`${$r(e.severity,t)} ${E(t,_.bold,n)}`+(o?` ${E(t,_.dim,o)}`:"")),e.title&&i.push(` ${e.title}`),e.detail&&e.detail!==e.title&&i.push(` ${E(t,_.dim,e.detail)}`),e.frame)for(let a of String(e.frame).split(`
|
|
29
|
+
`))i.push(` ${a}`);return e.suggestion&&i.push(` ${E(t,_.cyan,`Did you mean <${e.suggestion}>?`)}`),e.hint&&i.push(` ${E(t,_.dim,`\u2192 ${e.hint}`)}`),i.join(`
|
|
30
|
+
`)}function xe(e,{color:t=!1}={}){if(!e.length)return E(t,_.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(E(t,_.bold,s));for(let p of l)r.push(Je({...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(E(t,o?_.red:_.yellow,a)),r.join(`
|
|
31
|
+
`)}var Ge,_,E,J=j(()=>{Ge={"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"};_={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",cyan:"\x1B[36m",dim:"\x1B[2m",bold:"\x1B[1m"},E=(e,t,n)=>e?`${t}${n}${_.reset}`:n});function wr(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 Ve(e,t){if(!e)return null;let n=Nt(e).replace(/[?#].*$/,""),r=t?Nt(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 Sr(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 kr(e){let t=/\((\d+):(\d+)(?:-\d+:\d+)?\)\s*$/.exec(String(e||""));return t?{line:Number(t[1]),column:Number(t[2])}:null}function jr(e){return String(e||"").replace(/\s*\(\d+:\d+(?:-\d+:\d+)?\)\s*$/,"").trim()}function Or(e,t){if(!e||!t)return null;let n=String(e);return/node_modules|[\\/]vite[\\/]|@veluai[\\/]/.test(n)?null:n}function ae(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 A({...i,file:i.file||o});let a=wr(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),x=F?Ve(F[1],n):null;return A({category:"unknown-component",file:x||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:be(h,r)})}let p=a.loc||(a.line!=null?{line:a.line,column:a.column,file:a.file}:null)||kr(a.reason||s),u=a.id||p&&p.file||a.file||null,c=Ve(u,n)||o,b=!!c&&Ve(u,n)!=null,d=Or(a.frame,b||!!o),$=Sr(jr(a.reason||s)),m=Ar.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?A({category:L?"frontmatter":"mdx-syntax",file:c,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)?A({category:"invalid-props",file:c,title:"A component received an invalid value",detail:$,hint:"Check the props/options you passed to a component on this page."}):A({category:"render-crash",file:c,title:"This page failed to render",detail:$,hint:"Set VELU_DEBUG=1 for the full stack trace."})}var Nt,Ar,qe=j(()=>{J();Nt=e=>String(e).replace(/\\/g,"/");Ar=/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 Tr(e){let t=Ge[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><${I(e.suggestion)}></code>?</div>`),e.hint&&r.push(`<div class="velu-err-hint">${I(e.hint)}</div>`),r.push("</div>"),r.join("")}function He(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(Tr).join(`
|
|
11
32
|
`);return`<!doctype html>
|
|
12
33
|
<html lang="en">
|
|
13
34
|
<head>
|
|
@@ -74,20 +95,26 @@ var vt=Object.defineProperty;var k=(e,t)=>()=>(e&&(t=e(e=0)),t);var de=(e,t)=>{f
|
|
|
74
95
|
<body>
|
|
75
96
|
<div class="velu-err-wrap">
|
|
76
97
|
<div class="velu-err-brand">velu</div>
|
|
77
|
-
<h1 class="velu-err-h">${
|
|
78
|
-
${
|
|
98
|
+
<h1 class="velu-err-h">${I(r)}</h1>
|
|
99
|
+
${o}
|
|
79
100
|
<div class="velu-err-foot">Fix the file and save \u2014 this page reloads automatically.</div>
|
|
80
101
|
</div>
|
|
81
102
|
</body>
|
|
82
|
-
</html>`}var
|
|
83
|
-
`).length}function
|
|
84
|
-
`).length}function
|
|
85
|
-
`).length}function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
`)
|
|
91
|
-
${
|
|
92
|
-
|
|
93
|
-
`),
|
|
103
|
+
</html>`}var I,It=j(()=>{J();I=e=>String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")});var V,De=j(()=>{V=["Callout","Card","CardGroup","Accordion","AccordionGroup","Columns","Field","Prompt","Steps","Step","Tree","Folder","File","Image","CodeBlock","CodeGroup","MethodBadge","ApiPath","TryItBar","ApiField","ApiClient","ApiSidebar"]});import $e from"node:fs";import ce from"node:path";import{fileURLToPath as Lr}from"node:url";import Pr from"iso-639-1";function le(e,t){if(!t)return null;let n=e.indexOf(`"${t}"`);return n===-1?null:e.slice(0,n).split(`
|
|
104
|
+
`).length}function Er(e,t){return t==null||t<0?null:e.slice(0,t).split(`
|
|
105
|
+
`).length}function Xe(e,t){if(!t)return null;let n=e.indexOf(`"${t}"`);return n===-1?null:e.slice(0,n).split(`
|
|
106
|
+
`).length}function Fr(e,t,n){let r=[];return s(e,t,"",null),r;function o(l){if(l&&l.$ref){let p=l.$ref.replace(/^#\//,"").split("/"),u=n;for(let c of p)u=u?.[c];return u||{}}return l}function i(l){return Array.isArray(l)?"array":l===null?"null":typeof l}function a(l,p){let u=r.length;s(l,p,"",null,!0);let c=r.length===u;return c||(r.length=u),c}function s(l,p,u,c,b){let d=o(p);if(d){if(d.oneOf){d.oneOf.some(m=>a(l,m))||r.push({path:u,key:c,message:"value does not match any allowed shape"});return}if(d.type&&i(l)!==d.type){r.push({path:u,key:c,message:`expected ${d.type}, got ${i(l)}`});return}if(d.type==="string"&&d.minLength!=null&&l.length<d.minLength&&r.push({path:u,key:c,message:"must not be empty"}),d.type==="object"&&i(l)==="object"){for(let m of d.required||[])m in l||r.push({path:u?`${u}.${m}`:m,key:m,message:`missing required "${m}"`});let $=d.properties||{};if(d.additionalProperties===!1)for(let m of Object.keys(l))m in $||r.push({path:u?`${u}.${m}`:m,key:m,message:`unknown field "${m}"`});for(let[m,L]of Object.entries($))m in l&&s(l[m],L,u?`${u}.${m}`:m,m,b)}d.type==="array"&&Array.isArray(l)&&d.items&&l.forEach(($,m)=>s($,d.items,`${u}[${m}]`,c,b))}}}function Nr(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 we(e){let t=[],n=ce.join(e,"velu.json"),r;try{r=$e.readFileSync(n,"utf-8")}catch(s){return s.code==="ENOENT"?t.push(A({category:"config-json",file:"velu.json",title:"No velu.json found",hint:"Run `velu init <name>` to scaffold a project."})):t.push(A({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?Er(r,Number(l[1])):null;return t.push(A({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($e.readFileSync(Cr,"utf-8"))}catch{}if(i)for(let s of Fr(o,i,i)){let l=/^unknown field/.test(s.message);t.push(A({category:"config-schema",severity:l?"warning":"error",file:"velu.json",line:le(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&&!Nr(l)&&t.push(A({category:"config-schema",severity:"warning",file:"velu.json",line:le(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=ce.resolve(e,o.favicon.replace(/^\/+/,""));$e.existsSync(s)||t.push(A({category:"config-asset",file:"velu.json",line:le(r,"favicon"),title:`favicon not found: ${o.favicon}`,hint:"The path is relative to the project root."}))}let a=te(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(!$e.existsSync(ce.resolve(e,l.replace(/^\/+/,"")))){let u=p.length===2?"logo":`logo (${p[0]})`;t.push(A({category:"config-asset",file:"velu.json",line:Xe(r,l),title:`${u} not found: ${l}`,hint:"The path is relative to the project root."}))}}if(o.navigation&&typeof o.navigation=="object"){let s;try{s=U(o.navigation)}catch(l){t.push(A({category:"config-nav",file:"velu.json",line:le(r,"navigation"),title:"navigation could not be processed",detail:String(l.message||"")})),s=null}if(s){let{pageEntries:l,warnings:p}=M(s,e);for(let u of p){let c=/not found$/.test(u),b=/page "([^"]+)"/.exec(u),d=b?Xe(r,b[1]):null;t.push(A({category:"config-nav",severity:c?"error":"warning",file:"velu.json",line:d,title:u,hint:c?"Create the .mdx file, or remove the page from navigation.":""}))}Ir(s,r,t)}}return t}function Ir(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();Pr.validate(a)||n.push(A({category:"config-nav",severity:"warning",file:"velu.json",line:Xe(t,i.language)||le(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 _r,Cr,Ye=j(()=>{J();B();oe();Y();_r=ce.dirname(Lr(import.meta.url)),Cr=ce.resolve(_r,"..","..","schema","velu.schema.json")});import Rr from"node:fs/promises";import Ur from"node:fs";import q from"node:path";import{fileURLToPath as Mr,pathToFileURL as zr}from"node:url";import{compile as Br}from"@mdx-js/mdx";import Gr from"remark-frontmatter";import Jr from"remark-mdx-frontmatter";import Vr from"remark-gfm";import qr from"rehype-slug";import{visit as Hr}from"unist-util-visit";function Ke(){if(Se)return Se;let e=q.dirname(Mr(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(Ur.existsSync(o)){n=o;break}}return Se=n?import(zr(n).href).then(r=>r.validateProps).catch(()=>null):Promise.resolve(null),Se}function Dr(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 Xr(e,t){return()=>n=>{Hr(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:Dr(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 Yr(e,t){let n=[],r;try{r=await Rr.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 Br({value:r,path:t.fileAbsPath},{remarkPlugins:[Gr,Jr,Vr,ne,Xr(i,a)],rehypePlugins:[qr],providerImportSource:"@mdx-js/react"})}catch(u){return n.push(ae(u,{projectDir:e,knownComponents:V,file:o})),n}let s=new Set(V),l=await Ke(),p=new Set;for(let u of i)if(!a.has(u.name)){if(!s.has(u.name)){if(p.has(u.name))continue;p.add(u.name),n.push(A({category:"unknown-component",file:o,line:u.line,column:u.column,title:`<${u.name}> is not a built-in component`,hint:"Components are built in \u2014 check the spelling and capitalization (you don\u2019t import them).",suggestion:be(u.name,V)}));continue}if(l){let c=l(u.name,u.props,{checkRequired:!1});c&&n.push(A({...c,file:o,line:u.line,column:u.column}))}}return n}async function Rt(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 Yr(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 Se,We=j(()=>{Re();J();qe();De()});import ke from"node:fs";import Ze from"node:path";import zt from"js-yaml";function Qe(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=>Qe(o,t,n+1));else{r={};for(let[o,i]of Object.entries(e))r[o]=Qe(i,t,n+1)}return t.delete(e),r}function Bt(e){return zt.dump(Qe(e,new Set,0),{noRefs:!0,lineWidth:100,skipInvalid:!0})}function Gt(e){let t=String(e).replace(/\.md$/i,"");return t===""||t==="/"||t==="/index"?"/":t.replace(/\/+$/,"")||"/"}function Kr(e){return e==="/"?"/index.md":`${e}.md`}function et(e,t){if(t==="api")return`# ${Ut}
|
|
107
|
+
${e}`;let n=e.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),r=`> ${Ut}
|
|
108
|
+
|
|
109
|
+
`;return n?e.slice(0,n[0].length)+r+e.slice(n[0].length):r+e}function Zr(e){return e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,"")}function Qr(e){try{let t=ke.readFileSync(e,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!t)return{};let n=zt.load(t[1]);return n&&typeof n=="object"?n:{}}catch{return{}}}async function ue(e){let t={};try{t=JSON.parse(ke.readFileSync(Ze.join(e,"velu.json"),"utf-8"))}catch{return{name:Ze.basename(e),baseUrl:"",pages:[]}}let n=t.name??Ze.basename(e),r=typeof t.url=="string"?t.url.replace(/\/+$/,""):"",o=z(t.api),i=t.navigation??{},a={};try{let c=await ye(t.navigation??{},{targetDir:e,api:o});i=c.nav,a=c.ops}catch(c){console.warn(`[velu] openapi: ${c.message}`)}let s=U(i),{pageEntries:l}=M(s,e),p=new Map(l.map(c=>[c.url,c])),u=[];for(let c of K(s)){if(!c.url)continue;let b=c.ancestors.filter(h=>h.kind==="group").pop(),d=c.ancestors.filter(h=>h.kind==="tab").pop(),$=b?.label||d?.label||"Pages",m=c.ancestors.filter(h=>h.kind==="tab"||h.kind==="group").map(h=>h.label),L=c.ancestors.filter(h=>h.kind==="language").pop()?.code||null;if(c.node?.api){let h=a[c.pagePath];if(!h)continue;let w=h.title||Mt(c.url);u.push({url:c.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(c.url);if(!h||!h.exists)continue;let w=Qr(h.fileAbsPath),F=w.title||Mt(c.url);u.push({url:c.url,title:F,description:w.description||"",group:$,breadcrumb:[...m,F],lang:L,frontmatter:w,source:{kind:"mdx",fileAbsPath:h.fileAbsPath}})}}return{name:n,baseUrl:r,pages:u}}function Ae(e){return new Map(e.pages.map(t=>[t.url,{...t.source,title:t.title}]))}async function eo(e){return Ae(await ue(e))}async function tt(e,t,n){let o=(n||await eo(e)).get(t);if(!o)return null;if(o.kind==="mdx")try{return{body:ke.readFileSync(o.fileAbsPath,"utf-8"),contentType:"text/markdown; charset=utf-8",kind:"mdx"}}catch{return null}return o.segment?{body:Bt(o.segment),contentType:"text/yaml; charset=utf-8",kind:"api"}:null}async function Jt(e,t){let n=t||await ue(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 ${je} 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(Kr(l.url))})${l.description?`: ${l.description}`:""}`);o.push("")}return o.join(`
|
|
110
|
+
`)}async function Vt(e,t){let n=t||await ue(e),r=[`# ${n.name}`,"",`> Full documentation \u2014 every page concatenated. Index: ${W}`];for(let o of n.pages)if(r.push("","---","",`# ${o.title}`,`Source: ${o.url}`,""),o.source.kind==="mdx")try{r.push(Zr(ke.readFileSync(o.source.fileAbsPath,"utf-8")).trim())}catch{}else o.source.segment&&r.push("```yaml",Bt(o.source.segment).trim(),"```");return r.join(`
|
|
111
|
+
`)+`
|
|
112
|
+
`}var W,je,Wr,Z,Ut,Mt,qt=j(()=>{B();oe();Y();Be();W="/llms.txt",je="/llms-full.txt",Wr=`<${W}>; rel="llms-txt", <${je}>; rel="llms-full-txt"`,Z={Link:Wr,"X-Llms-Txt":W},Ut=`Full documentation index: ${W}`;Mt=e=>(e.split("/").filter(Boolean).pop()||"Home").replace(/[-_]+/g," ").replace(/\b\w/g,n=>n.toUpperCase())});var Zt={};Pe(Zt,{startDevServer:()=>vo});import Ht from"node:fs/promises";import Q from"node:fs";import to from"node:http";import{spawn as no}from"node:child_process";import P from"node:path";import{fileURLToPath as ro}from"node:url";import oo from"chokidar";import Dt from"express";import{createServer as io,searchForWorkspaceRoot as so}from"vite";function po(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 Xt(e,t){let n=Je(e,{color:!!process.stderr.isTTY});console.error(`
|
|
113
|
+
`+n+`
|
|
114
|
+
`),process.env.VELU_DEBUG&&t&&console.error(t)}function fo(){try{return JSON.parse(Q.readFileSync(P.join(Oe,"package.json"),"utf8")).version||"unknown"}catch{return"unknown"}}function mo(e,t){let n=P.resolve(e,".velu"),r=P.resolve(n,".velu-version"),o=null;try{o=Q.readFileSync(r,"utf8").trim()}catch{}if(o!==t){if(o!==null)try{Q.rmSync(P.join(n,"vite-cache"),{recursive:!0,force:!0}),console.log("[velu] new version detected \u2014 refreshing the preview cache\u2026")}catch{}try{Q.mkdirSync(n,{recursive:!0}),Q.writeFileSync(r,t)}catch{}}}async function Yt(e){try{return await lt(e)}catch{return Ie({},P.basename(e))}}async function Kt(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&&lo.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(`
|
|
115
|
+
`)}function yo(e,t){let n=()=>{process.stdout.isTTY&&!process.env.VELU_NO_BELL&&process.stdout.write("\x07")},r=process.stdout.isTTY,o=c=>r&&process.stdout.write(`\x1B]${c}\x1B\\`),i=()=>{o(`0;\u23F3 ${t}`),o("9;4;3;0")},a=()=>{o(`0;${t}`),o("9;4;0;0")};if(r&&process.once("exit",()=>o("9;4;0;0")),i(),!e)return console.log("Starting Velu\u2026"),{ready:c=>{console.log(`Velu ready \u2192 ${c}`),a(),n()}};let s="\x1B[38;2;220;20;60m",l="\x1B[0m";console.log("");for(let c of go)console.log(`${s}${c}${l}`);console.log("");let p=null;try{p=no(process.execPath,["-e",ho],{stdio:["ignore","inherit","ignore"]}),p.on("error",()=>{})}catch{}let u=()=>{if(p){try{p.kill()}catch{}p=null}};return process.once("exit",u),{ready:c=>{u(),process.stdout.write("\x1B[2K\r"),console.log(` \x1B[32m\u2713${l} Velu ready \u2192 \x1B[36m${c}${l}`),a(),n()}}}async function vo(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=yo(!!process.stdout.isTTY&&!t,P.basename(e)),i=await Yt(e),a=s();function s(){let f=we(e).filter(g=>g.severity==="error"&&(g.category==="config-json"||g.category==="config-schema"));return f.length&&console.error(`
|
|
116
|
+
`+xe(f,{color:!!process.stderr.isTTY})+`
|
|
117
|
+
`),f}let l=e;try{l=Q.realpathSync(e)}catch{}let p=0,u=y=>{let f=performance.now();if(f-p<500)return;p=f;let g=ae(y,{projectDir:l,knownComponents:V});Xt(g,y)};process.on("unhandledRejection",u),process.on("uncaughtException",u);let c=Number(process.env.PORT)||8358,b=await Ke();mo(e,fo());let d=Dt(),$=to.createServer(d),m=await io({...Et({targetDir:e,VITE_ROOT:Oe,validateProps:b}),appType:"custom",logLevel:t?"info":"warn",server:{middlewareMode:!0,fs:{allow:[so(Oe),e,l]},hmr:{server:$}}});r("vite server created",n),d.use(m.middlewares),d.get(new RegExp(`^${Ee}(\\.[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(me,L("light")),d.get(de,L("dark")),d.post("/@velu-api-proxy",Dt.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,Le)=>{T[Le]=ee});let R=N;if(/json/i.test(H))try{R=JSON.parse(N)}catch{}f.json({status:k.status,statusText:k.statusText,headers:T,body:R})}catch(k){f.json({error:`Request failed: ${k.message}`})}});let h=null,w=async()=>h||=await ue(e);d.get(/\.md$/i,async(y,f,g)=>{try{let v=await w(),O=await tt(e,Gt(decodeURIComponent(y.path)),Ae(v));if(!O)return g();f.status(200).set({"Content-Type":O.contentType,...Z}).end(et(O.body,O.kind))}catch{g()}}),d.get(W,async(y,f,g)=>{try{let v=await Jt(e,await w());f.status(200).set({"Content-Type":"text/plain; charset=utf-8",...Z}).end(v)}catch{g()}}),d.get(je,async(y,f,g)=>{try{let v=await Vt(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 tt(e,ut(v),Ae(S));if(k)return f.status(200).set({"Content-Type":k.contentType,...Z}).end(et(k.body,k.kind))}catch{}if(a.length)return f.status(200).set({"Content-Type":"text/html"}).end(He(a,{title:"Fix velu.json to continue"}));try{let S=performance.now(),k=await Ht.readFile(Wt,"utf-8");k=await m.transformIndexHtml(v,k),r(`transformIndexHtml ${v}`,S);let N="/src/runtime/server-entry.jsx";S=performance.now();let{render:H}=await m.ssrLoadModule(N);r(`ssrLoadModule ${v} (1st req includes dep pre-bundle)`,S),S=performance.now();let T=await H(v);r(`render ${v}`,S),S=performance.now();let R=await Kt(m,N);r(`collectSsrCss ${v}`,S);let ee=R?`<style data-velu-ssr>${R}</style>`:"",Le=`<style data-velu-config>
|
|
118
|
+
${ct(i)}
|
|
119
|
+
</style>`,on=co.has(i.font.family)?"":po(i.font.family),fe=st(i),sn=fe?`<link rel="icon"${fe.type?` type="${fe.type}"`:""} href="${fe.url}" />`:"",an=[ee,Le,on,sn].filter(Boolean).join(`
|
|
120
|
+
`),ln=k.replace("<!--app-title-->",uo(i.name)).replace("<!--app-head-->",an).replace("<!--app-html-->",T);f.status(200).set({"Content-Type":"text/html",...Z}).end(ln),r(`TOTAL ${v}`,O)}catch(S){m.ssrFixStacktrace(S);let k=ae(S,{projectDir:l,knownComponents:V});Xt(k,S),f.status(200).set({"Content-Type":"text/html"}).end(He([k]))}}),oo.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 Yt(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 x(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 R=await m.moduleGraph.getModuleByUrl(T,!1);R?.importedModules?.size&&await Promise.all([...R.importedModules].map(ee=>H(ee.url)))}catch{}}}return await H(y),f.size}$.listen(c,async()=>{let y=performance.now(),f=0;try{let{render:g}=await m.ssrLoadModule("/src/runtime/server-entry.jsx");await x("/src/runtime/client-entry.jsx"),typeof m.waitForRequestsIdle=="function"&&await m.waitForRequestsIdle();let[v]=await Promise.allSettled([x("/src/runtime/client-entry.jsx"),g("/"),m.transformIndexHtml("/",await Ht.readFile(Wt,"utf-8")),Kt(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:${c}`)})}var ao,lo,co,uo,Oe,Wt,go,ho,Qt=j(()=>{Y();Ft();qe();It();J();De();Ye();We();qt();B();ao=P.dirname(ro(import.meta.url)),lo=/\.(css|less|sass|scss|styl|stylus|pcss|postcss)(\?|$)/,co=new Set(["Google Sans Flex","Google Sans Code","Outfit"]),uo=e=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");Oe=P.resolve(ao,".."),Wt=P.resolve(Oe,"src","template.html"),go=[" _ __ __","| | / /__ / /_ __","| | / / _ \\/ / / / /","| |/ / __/ / /_/ /","|___/\\___/_/\\__,_/"],ho="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 tn={};Pe(tn,{default:()=>wo,runValidate:()=>en});import bo from"node:fs";import xo from"node:path";function $o(e){try{let t=JSON.parse(bo.readFileSync(xo.join(e,"velu.json"),"utf-8"));if(!t.navigation||typeof t.navigation!="object")return[];let n=U(t.navigation);return M(n,e).pageEntries}catch{return[]}}async function en(e){let t=we(e),n=$o(e),r=await Rt(e,n),o=[...t,...r],i=!!process.stdout.isTTY;return console.log(xe(o,{color:i})),o.some(s=>s.severity!=="warning"&&s.severity!=="info")?1:0}var wo,nn=j(()=>{B();oe();Ye();We();J();wo=en});import Te from"node:path";import C from"node:process";import{readFileSync as So}from"node:fs";var[,,rn,pe]=C.argv;function ko(){try{return JSON.parse(So(new URL("../package.json",import.meta.url),"utf8")).version}catch{return"unknown"}}async function jo(){switch(rn){case"--version":case"-v":case"version":{console.log(ko());break}case"init":{pe||(console.error("Usage: velu init <project-name>"),C.exit(1));let e=pe,t=Te.resolve(C.cwd(),e),{initProject:n}=await Promise.resolve().then(()=>(ot(),rt));await n(t,e);break}case"dev":{let e=Te.resolve(C.cwd(),pe??"."),{startDevServer:t}=await Promise.resolve().then(()=>(Qt(),Zt));await t(e);break}case"validate":{let e=Te.resolve(C.cwd(),pe??"."),{runValidate:t}=await Promise.resolve().then(()=>(nn(),tn)),n=await t(e);C.exit(n);break}case"build":{let e=Te.resolve(C.cwd(),pe??"."),t=C.argv.indexOf("--out"),n=t>-1?C.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."),C.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"),C.exit(rn?1:0)}}jo().catch(e=>{console.error(C.env.VELU_DEBUG?e:`Error: ${e.message}`),C.exit(1)});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veluai/velu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": "./dist/cli.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "node scripts/build.mjs",
|
|
23
|
-
"prepack": "node scripts/build.mjs"
|
|
23
|
+
"prepack": "node scripts/build.mjs",
|
|
24
|
+
"test:parity": "node scripts/parity-test.mjs"
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
27
|
+
"@apidevtools/swagger-parser": "^10.1.0",
|
|
26
28
|
"@icons-pack/react-simple-icons": ">=13.0.0 <13.13.0",
|
|
27
29
|
"@mdx-js/mdx": "^3.1.1",
|
|
28
30
|
"@mdx-js/react": "^3.1.1",
|
|
@@ -34,6 +36,7 @@
|
|
|
34
36
|
"express": "^4.21.1",
|
|
35
37
|
"github-slugger": "^2.0.0",
|
|
36
38
|
"iso-639-1": "^3.1.5",
|
|
39
|
+
"js-yaml": "^4.1.0",
|
|
37
40
|
"lucide-react": "^0.460.0",
|
|
38
41
|
"mdast-util-to-string": "^4.0.0",
|
|
39
42
|
"prism-react-renderer": "^2.4.0",
|
|
@@ -50,7 +53,10 @@
|
|
|
50
53
|
"vite": "^5.4.11"
|
|
51
54
|
},
|
|
52
55
|
"devDependencies": {
|
|
56
|
+
"@fontsource/outfit": "^5.0.0",
|
|
57
|
+
"@resvg/resvg-js": "^2.6.2",
|
|
53
58
|
"esbuild": "^0.28.0",
|
|
54
|
-
"playwright": "^1.48.0"
|
|
59
|
+
"playwright": "^1.48.0",
|
|
60
|
+
"satori": "^0.12.0"
|
|
55
61
|
}
|
|
56
62
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
2
2
|
import resolveIcon from '../lib/resolveIcon.jsx';
|
|
3
3
|
import Cluster from '../primitives/Cluster.jsx';
|
|
4
4
|
import MethodBadge from './MethodBadge.jsx';
|
|
@@ -46,8 +46,13 @@ export default function ApiClient({
|
|
|
46
46
|
label,
|
|
47
47
|
path = '',
|
|
48
48
|
description,
|
|
49
|
+
operations = [],
|
|
50
|
+
activeId,
|
|
51
|
+
onSelectOperation,
|
|
49
52
|
onSend,
|
|
53
|
+
sending = false,
|
|
50
54
|
onClose,
|
|
55
|
+
response,
|
|
51
56
|
aside,
|
|
52
57
|
children,
|
|
53
58
|
className = '',
|
|
@@ -56,6 +61,29 @@ export default function ApiClient({
|
|
|
56
61
|
const key = String(method).toLowerCase();
|
|
57
62
|
const cls = `velu-api-client velu-api-client--${key} ${className}`.trim();
|
|
58
63
|
|
|
64
|
+
// The operation dropdown is interactive only when there's more than one
|
|
65
|
+
// operation to switch between and a handler to call.
|
|
66
|
+
const canSwitch =
|
|
67
|
+
Array.isArray(operations) && operations.length > 1 && typeof onSelectOperation === 'function';
|
|
68
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
69
|
+
const opRef = useRef(null);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!menuOpen) return undefined;
|
|
73
|
+
const onDown = (e) => {
|
|
74
|
+
if (opRef.current && !opRef.current.contains(e.target)) setMenuOpen(false);
|
|
75
|
+
};
|
|
76
|
+
const onKey = (e) => {
|
|
77
|
+
if (e.key === 'Escape') setMenuOpen(false);
|
|
78
|
+
};
|
|
79
|
+
document.addEventListener('mousedown', onDown);
|
|
80
|
+
document.addEventListener('keydown', onKey);
|
|
81
|
+
return () => {
|
|
82
|
+
document.removeEventListener('mousedown', onDown);
|
|
83
|
+
document.removeEventListener('keydown', onKey);
|
|
84
|
+
};
|
|
85
|
+
}, [menuOpen]);
|
|
86
|
+
|
|
59
87
|
return (
|
|
60
88
|
<div className={cls} {...rest}>
|
|
61
89
|
{/* Close button row — only when shown as a modal (onClose set). */}
|
|
@@ -82,27 +110,82 @@ export default function ApiClient({
|
|
|
82
110
|
align="flex-start"
|
|
83
111
|
className="velu-api-client__head"
|
|
84
112
|
>
|
|
85
|
-
<div className="velu-api-client__op">
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
113
|
+
<div className="velu-api-client__op" ref={opRef}>
|
|
114
|
+
{canSwitch ? (
|
|
115
|
+
<button
|
|
116
|
+
type="button"
|
|
117
|
+
className="velu-api-client__op-btn"
|
|
118
|
+
onClick={() => setMenuOpen((v) => !v)}
|
|
119
|
+
aria-haspopup="listbox"
|
|
120
|
+
aria-expanded={menuOpen}
|
|
121
|
+
>
|
|
122
|
+
<MethodBadge method={method} />
|
|
123
|
+
{label && (
|
|
124
|
+
<span className="velu-api-client__op-label">{label}</span>
|
|
125
|
+
)}
|
|
126
|
+
<span className="velu-api-client__op-chevron" aria-hidden="true">
|
|
127
|
+
{resolveIcon('chevron-down', { size: '1em' })}
|
|
128
|
+
</span>
|
|
129
|
+
</button>
|
|
130
|
+
) : (
|
|
131
|
+
<>
|
|
132
|
+
<MethodBadge method={method} />
|
|
133
|
+
{label && (
|
|
134
|
+
<span className="velu-api-client__op-label">{label}</span>
|
|
135
|
+
)}
|
|
136
|
+
<span className="velu-api-client__op-chevron" aria-hidden="true">
|
|
137
|
+
{resolveIcon('chevron-down', { size: '1em' })}
|
|
138
|
+
</span>
|
|
139
|
+
</>
|
|
140
|
+
)}
|
|
141
|
+
{canSwitch && menuOpen && (
|
|
142
|
+
<ul
|
|
143
|
+
className="velu-api-client__op-menu velu-hide-scrollbar"
|
|
144
|
+
role="listbox"
|
|
145
|
+
>
|
|
146
|
+
{operations.map((o) => (
|
|
147
|
+
<li key={o.id}>
|
|
148
|
+
<button
|
|
149
|
+
type="button"
|
|
150
|
+
role="option"
|
|
151
|
+
aria-selected={o.id === activeId}
|
|
152
|
+
className={`velu-api-client__op-item${
|
|
153
|
+
o.id === activeId ? ' velu-api-client__op-item--active' : ''
|
|
154
|
+
}`}
|
|
155
|
+
onClick={() => {
|
|
156
|
+
onSelectOperation(o.id);
|
|
157
|
+
setMenuOpen(false);
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
<MethodBadge method={o.method} />
|
|
161
|
+
<span className="velu-api-client__op-item-label">
|
|
162
|
+
{o.title}
|
|
163
|
+
</span>
|
|
164
|
+
</button>
|
|
165
|
+
</li>
|
|
166
|
+
))}
|
|
167
|
+
</ul>
|
|
89
168
|
)}
|
|
90
|
-
<span className="velu-api-client__op-chevron" aria-hidden="true">
|
|
91
|
-
{resolveIcon('chevron-down', { size: '1em' })}
|
|
92
|
-
</span>
|
|
93
169
|
</div>
|
|
94
170
|
<TryItBar
|
|
95
171
|
method={method}
|
|
96
172
|
path={path}
|
|
97
173
|
cta="Send"
|
|
98
174
|
onTry={onSend}
|
|
175
|
+
loading={sending}
|
|
99
176
|
className="velu-api-client__bar"
|
|
100
177
|
/>
|
|
101
178
|
</Cluster>
|
|
102
179
|
|
|
103
|
-
{/*
|
|
104
|
-
|
|
105
|
-
|
|
180
|
+
{/* Body grid (areas: form / response / aside). Desktop: form fills the
|
|
181
|
+
left column, response + aside stack in the right. Mobile (single
|
|
182
|
+
column): the live response moves ABOVE the form so a Send result is
|
|
183
|
+
visible without scrolling past the inputs; the form and code samples
|
|
184
|
+
follow. See api.css. */}
|
|
185
|
+
<div
|
|
186
|
+
className="velu-api-client__body"
|
|
187
|
+
data-has-response={response != null ? 'true' : undefined}
|
|
188
|
+
>
|
|
106
189
|
<div className="velu-api-client__left">
|
|
107
190
|
{label && (
|
|
108
191
|
<h3 className="velu-api-client__title">{label}</h3>
|
|
@@ -112,6 +195,9 @@ export default function ApiClient({
|
|
|
112
195
|
)}
|
|
113
196
|
{children}
|
|
114
197
|
</div>
|
|
198
|
+
{response != null && (
|
|
199
|
+
<div className="velu-api-client__response">{response}</div>
|
|
200
|
+
)}
|
|
115
201
|
{aside != null && (
|
|
116
202
|
<div className="velu-api-client__right">{aside}</div>
|
|
117
203
|
)}
|