smoothui-cli 1.0.6 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +3 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import{confirm as De,isCancel as se,select as Fe,spinner as Ue}from"@clack/prompts";var _="https://smoothui.dev",M={"Basic UI":["accordion","animated-input","animated-progress-bar","animated-tabs","animated-toggle","basic-dropdown","basic-modal","basic-toast","notification-badge","searchable-dropdown","skeleton-loader","tweet-card"],Buttons:["button-copy","clip-corners-button","dot-morph-button","magnetic-button"],"Text Effects":["wave-text","reveal-text","typewriter-text","scramble-hover","scroll-reveal-paragraph"],AI:["ai-branch","ai-input"],"Cards & Layouts":["expandable-cards","glow-hover-card","scrollable-card-stack","switchboard-card","phototab","job-listing-component"],"Loaders & Effects":["grid-loader","siri-orb","cursor-follow","github-stars-animation"],Interactive:["animated-o-t-p-input","animated-tags","app-download-stack","apple-invites","contribution-graph","dynamic-island","figma-comment","image-metadata-preview","infinite-slider","interactive-image-selector","number-flow","power-off-slide","price-flow","rich-popover","reviews-carousel","social-selector","user-account-avatar"]},K=["src/components/ui","components/ui","src/components","components","app/components/ui"],Y=[{file:"bun.lockb",cmd:"bun"},{file:"pnpm-lock.yaml",cmd:"pnpm"},{file:"yarn.lock",cmd:"yarn"},{file:"package-lock.json",cmd:"npm"}],m={active:"\u25C6",done:"\u25C7",selected:"\u25CF",unselected:"\u25CB",cursor:"\u276F",success:"\u2713",error:"\u2717",bar:"\u2502"};import{createInterface as de,emitKeypressEvents as me}from"readline";import d from"picocolors";var fe=t=>{let e=new Map;for(let o of t){let n=o.category||"Other";e.has(n)||e.set(n,[]),e.get(n)?.push(o)}return e},ge=(t,e)=>{console.log(`${d.cyan(m.active)} ${t}`),console.log(`${d.dim(m.bar)}`),console.log(`${d.dim(m.bar)} Search: ${e}${d.dim("\u258C")}`),console.log(`${d.dim(m.bar)}`)},ue=(t,e,o)=>{let n=e?d.green(m.selected):d.dim(m.unselected),s=o?d.cyan(m.cursor):" ",r=o?d.cyan(t.label):t.label;console.log(`${d.dim(m.bar)} ${s} ${n} ${r}`)},he=t=>{console.log(`${d.dim(m.bar)}`),console.log(`${d.dim(m.bar)} ${d.dim(`${t} selected \u2502 \u2191\u2193 navigate \u2502 space select \u2502 enter confirm \u2502 esc cancel`)}`)},ye=(t,e,o)=>{let n=0,s=e.scrollOffset,r=e.scrollOffset+o;for(let[i,c]of t){if(n>=r)break;n>=s&&console.log(`${d.dim(m.bar)} ${d.bold(d.dim(i))}`),n++;for(let p of c){if(n>=r)break;if(n>=s){let a=e.selected.has(p.value),l=n-1===e.cursorIndex;ue(p,a,l)}n++}}},be=(t,e,o,n)=>()=>{let s=B(e,o.searchQuery);process.stdout.write("\x1B[2J\x1B[H"),ge(t,o.searchQuery);let r=fe(s);ye(r,o,n),he(o.selected.size)},B=(t,e)=>{if(!e)return t;let o=e.toLowerCase();return t.filter(n=>n.label.toLowerCase().includes(o)||n.category?.toLowerCase().includes(o))},xe=(t,e,o,n)=>{if(o<=0){e.cursorIndex=0,e.scrollOffset=0;return}t.name==="up"?(e.cursorIndex=Math.max(0,e.cursorIndex-1),e.cursorIndex<e.scrollOffset&&(e.scrollOffset=e.cursorIndex)):t.name==="down"&&(e.cursorIndex=Math.min(o-1,e.cursorIndex+1),e.cursorIndex>=e.scrollOffset+n&&(e.scrollOffset=e.cursorIndex-n+1))},ve=(t,e)=>{let o=e[t.cursorIndex];o&&(t.selected.has(o.value)?t.selected.delete(o.value):t.selected.add(o.value))},we=(t,e,o)=>{e.name==="backspace"?(o.searchQuery=o.searchQuery.slice(0,-1),o.cursorIndex=0,o.scrollOffset=0):t&&t.length===1&&!e.ctrl&&!e.meta&&(o.searchQuery+=t,o.cursorIndex=0,o.scrollOffset=0)},Q=(t,e)=>{e&&process.stdin.removeListener("keypress",e),process.stdin.isTTY&&process.stdin.setRawMode(!1),t.close()},H=t=>{let{message:e,items:o,maxVisible:n=10}=t;return new Promise(s=>{let r={selected:new Set,searchQuery:"",cursorIndex:0,scrollOffset:0},i=de({input:process.stdin,output:process.stdout});process.stdin.isTTY&&process.stdin.setRawMode(!0),me(process.stdin,i);let c=be(e,o,r,n),p=(a,l)=>{let x=B(o,r.searchQuery),v=x.length;if(l.name==="escape"||l.ctrl&&l.name==="c"){Q(i,p),s(null);return}if(l.name==="return"){Q(i,p),s([...r.selected]);return}l.name==="up"||l.name==="down"?xe(l,r,v,n):l.name==="space"?ve(r,x):we(a,l,r),c()};process.stdin.on("keypress",p),c()})};import w from"picocolors";var C=m,P=w.dim,Se=w.cyan,$e=w.green,Ie=w.red,We=w.yellow,N=w.bold,D=w.gray;function T(t,e){console.log(`${t} ${e}`)}function R(t){T(Se(C.active),t)}function b(t){T(P(C.done),t)}function J(t){T($e(C.success),t)}function j(t){T(Ie(C.error),t)}function f(t=""){console.log(`${P(C.bar)} ${t}`)}function I(){console.log(),R(N("SmoothUI")),console.log()}import{existsSync as E,readFileSync as W}from"fs";import{join as A}from"path";var Oe=/^(npm|pnpm|yarn|bun)@/,Ce=()=>{let t=process.cwd();for(let{file:o,cmd:n}of Y)if(E(A(t,o)))return n;let e=A(t,"package.json");if(E(e))try{let o=JSON.parse(W(e,"utf-8"));if(o.packageManager){let n=o.packageManager.match(Oe);if(n)return n[1]}}catch{}return"npm"},Pe=()=>{let t=process.cwd();for(let e of K)if(E(A(t,e)))return e;return null},Re=()=>{let t=process.cwd(),e=["tsconfig.json","jsconfig.json"];for(let o of e){let n=A(t,o);if(E(n))try{let r=W(n,"utf-8").replace(/\/\*[\s\S]*?\*\/|\/\/.*/g,""),c=JSON.parse(r).compilerOptions?.paths;if(c){for(let[p,a]of Object.entries(c))if(p.endsWith("/*")&&Array.isArray(a))return p.slice(0,-2)}}catch{}}return"@"},q=()=>({componentPath:Pe()||"components/ui",alias:Re(),packageManager:Ce()});import{spawnSync as z}from"child_process";import{existsSync as V,mkdirSync as je,readFileSync as ot,writeFileSync as ke}from"fs";import{dirname as Me,isAbsolute as Te,relative as Ee,resolve as X}from"path";var Ae=(t,e)=>e==="@"?t:t.replace(/@\/components\//g,`${e}/components/`);var Z=async(t,e,o,n)=>{let s=[],r=[],i=o,c=X(process.cwd(),e.componentPath);for(let p of t.files){let a=p.target||p.path;a.startsWith("components/")&&(a=a.slice(11));let l=X(c,a),x=Ee(c,l);if(x.startsWith("..")||Te(x))throw new Error(`Invalid registry file path: ${a}`);let v=Me(l);if(V(v)||je(v,{recursive:!0}),V(l)&&!i){let g=await n(a);if(g==="skip"){r.push(a);continue}g==="all"&&(i=!0)}let k=Ae(p.content,e.alias);ke(l,k,"utf-8"),s.push(a)}return{written:s,skipped:r}},ee=(t,e,o)=>{let n=!0;if(t.length>0){let s={npm:["npm","install",...t],pnpm:["pnpm","add",...t],yarn:["yarn","add",...t],bun:["bun","add",...t]},[r,...i]=s[o];z(r,i,{stdio:"pipe"}).status!==0&&(n=!1)}if(e.length>0){let s={npm:["npm","install","-D",...e],pnpm:["pnpm","add","-D",...e],yarn:["yarn","add","-D",...e],bun:["bun","add","-d",...e]},[r,...i]=s[o];z(r,i,{stdio:"pipe"}).status!==0&&(n=!1)}return n};var te=process.env.SMOOTHUI_REGISTRY_URL||_,Le=/\/r\/([^/]+)\.json$/;async function Ne(){let t=`${te}/r/registry.json`,e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch registry: ${e.status}`);return e.json()}async function oe(t){let e=`${te}/r/${t}.json`,o=await fetch(e);if(!o.ok)throw new Error(`Component "${t}" not found`);return o.json()}function ne(t){let e=t.match(Le);return e?e[1]:t}async function L(){return(await Ne()).items.map(e=>e.name)}async function F(t,e=new Set){let o=await oe(t);e.add(t);let n=[];if(o.registryDependencies)for(let s of o.registryDependencies){let r=ne(s);if(e.has(r)||!s.includes("smoothui.dev"))continue;let i=await F(r,e);n.push(i)}return{component:o,children:n}}function U(t){let e=[t.component];for(let o of t.children)e.push(...U(o));return e}function re(t){let e=new Set,o=new Set,n=new Set(["react","react-dom","next","tailwindcss","@types/react","@types/react-dom","@types/node","typescript"]);for(let s of t){for(let r of s.dependencies||[])n.has(r)||e.add(r);for(let r of s.devDependencies||[])n.has(r)||o.add(r)}return{dependencies:[...e],devDependencies:[...o]}}function G(t,e="",o=!0){f(`${e}${o?"\u2514\u2500":"\u251C\u2500"} ${t.component.name}`);let s=e+(o?" ":"\u2502 "),r=[...t.component.dependencies||[]].filter(i=>!["react","react-dom","next"].includes(i));r.length>0&&t.children.length===0&&f(`${s}\u2514\u2500 ${D(`npm: ${r.join(", ")}`)}`);for(let i=0;i<t.children.length;i++){let c=t.children[i],p=i===t.children.length-1&&r.length===0;G(c,s,p)}r.length>0&&t.children.length>0&&f(`${s}\u2514\u2500 ${D(`npm: ${r.join(", ")}`)}`)}async function ie(t,e){I();let o=q();e.path&&(o.componentPath=e.path),b(`Detected: ${o.componentPath}/ (${o.packageManager})`),console.log();let n=t;if(n.length===0){let h=(await L()).map(u=>{let $="Other";for(let[le,pe]of Object.entries(M))if(pe.includes(u)){$=le;break}return{value:u,label:u,category:$}}),y=await H({message:"Select components to install:",items:h});if(!y||y.length===0){console.log(),b("No components selected.");return}n=y,b(`Selected: ${n.join(", ")}`),console.log()}R("Resolving dependencies..."),f();let s=[],r=new Set;for(let g of n)if(!r.has(g))try{let h=await F(g),y=U(h);for(let u of y)r.has(u.name)||(r.add(u.name),s.push(u));G(h)}catch(h){j(`Failed to resolve ${g}: ${h.message}`);return}f();let{dependencies:i,devDependencies:c}=re(s),p=[...i,...c],a=s.length,l=i.length+c.length,x=l>0?`Install ${a} component${a>1?"s":""} + ${l} npm package${l>1?"s":""}?`:`Install ${a} component${a>1?"s":""}?`,v=await De({message:x});if(se(v)||!v){b("Installation cancelled.");return}console.log();let k=e.force??!1;for(let g of s){let{written:h,skipped:y}=await Z(g,o,k,async u=>{let $=await Fe({message:`File exists: ${u}`,options:[{value:"overwrite",label:"Overwrite"},{value:"skip",label:"Skip"},{value:"all",label:"Overwrite all"}]});return se($)?"skip":($==="all"&&(k=!0),$)});for(let u of h)b(`Written: ${o.componentPath}/${u}`);for(let u of y)b(`Skipped: ${u}`)}if(i.length>0||c.length>0){let g=Ue();if(g.start(`Installing ${p.join(", ")}`),ee(i,c,o.packageManager))g.stop(`Installed: ${p.join(", ")}`);else if(g.stop("Failed to install dependencies"),i.length>0&&f(`Run manually: ${o.packageManager} add ${i.join(" ")}`),c.length>0){let y=o.packageManager==="bun"?"-d":"-D";f(`Run manually: ${o.packageManager} add ${y} ${c.join(" ")}`)}}console.log(),J(`Done! ${a} component${a>1?"s":""} installed.`)}async function ce(t){let e=await L();if(t.json){console.log(JSON.stringify(e,null,2));return}I(),R(`Available components (${e.length})`),f();let o=new Map;for(let n of e){let s="Other";for(let[i,c]of Object.entries(M))if(c.includes(n)){s=i;break}let r=o.get(s);r?r.push(n):o.set(s,[n])}for(let[n,s]of o){f(N(P(n)));for(let r of s.sort())f(` ${r}`);f()}b(`Use ${P("npx smoothui add <component>")} to install`)}var O=process.argv.slice(2),S=O[0];function ae(){I(),console.log("Usage: npx smoothui <command> [options]"),console.log(),console.log("Commands:"),console.log(" add [components...] Add components to your project"),console.log(" list List available components"),console.log(),console.log("Options:"),console.log(" --path <path> Custom component install path"),console.log(" --force Overwrite existing files without asking"),console.log(" --json Output as JSON (list command)"),console.log(" --help Show this help message"),console.log(),console.log("Examples:"),console.log(" npx smoothui add siri-orb"),console.log(" npx smoothui add siri-orb grid-loader"),console.log(" npx smoothui add # Interactive mode"),console.log(" npx smoothui list")}async function Ge(){try{if(!S||S==="--help"||S==="-h"){ae();return}if(S==="add"){let t=[],e,o=!1;for(let n=1;n<O.length;n++){let s=O[n];s==="--path"&&O[n+1]?(e=O[n+1],n++):s==="--force"||s==="-f"?o=!0:s.startsWith("-")||t.push(s)}await ie(t,{path:e,force:o});return}if(S==="list"||S==="ls"){let t=O.includes("--json");await ce({json:t});return}j(`Unknown command: ${S}`),ae(),process.exit(1)}catch(t){let e=t instanceof Error?t.message:String(t);j(e||"An unknown error occurred"),process.exit(1)}}Ge();
2
+ import{confirm as et,isCancel as be,select as tt,spinner as nt}from"@clack/prompts";var X="https://smoothui.dev",D={"Basic UI":["accordion","animated-input","animated-progress-bar","animated-tabs","animated-toggle","basic-dropdown","basic-modal","basic-toast","notification-badge","searchable-dropdown","skeleton-loader","tweet-card"],Buttons:["button-copy","clip-corners-button","dot-morph-button","magnetic-button"],"Text Effects":["wave-text","reveal-text","typewriter-text","scramble-hover","scroll-reveal-paragraph"],AI:["ai-branch","ai-input"],"Cards & Layouts":["expandable-cards","glow-hover-card","scrollable-card-stack","switchboard-card","phototab","job-listing-component"],"Loaders & Effects":["grid-loader","siri-orb","cursor-follow","github-stars-animation"],Interactive:["animated-o-t-p-input","animated-tags","app-download-stack","apple-invites","contribution-graph","dynamic-island","figma-comment","image-metadata-preview","infinite-slider","interactive-image-selector","number-flow","power-off-slide","price-flow","rich-popover","reviews-carousel","social-selector","user-account-avatar"]},Z=["src/components/ui","components/ui","src/components","components","app/components/ui"],ee=[{file:"bun.lockb",cmd:"bun"},{file:"pnpm-lock.yaml",cmd:"pnpm"},{file:"yarn.lock",cmd:"yarn"},{file:"package-lock.json",cmd:"npm"}],te={active:"\u25C6",done:"\u25C7",selected:"\u25CF",unselected:"\u25CB",cursor:"\u276F",success:"\u2713",error:"\u2717",bar:"\u2502"};import{createInterface as je,emitKeypressEvents as Ee}from"readline";import{Writable as Te}from"stream";import m from"picocolors";var Ae=new Te({write(e,t,n){n()}}),Pe=m.green("\u25C6"),ke=m.red("\u25A0"),Oe=m.green("\u25C7"),Me=m.green("\u25CF"),Le=m.dim("\u25CB"),x=m.dim("\u2502"),ne=e=>{let{message:t,items:n,maxVisible:o=8}=e;return new Promise(s=>{let r=je({input:process.stdin,output:Ae,terminal:!1});process.stdin.isTTY&&process.stdin.setRawMode(!0),Ee(process.stdin,r);let c="",a=0,d=new Set,l=0,y=(p,i)=>{if(!i)return!0;let b=i.toLowerCase();return p.label.toLowerCase().includes(b)||p.value.toLowerCase().includes(b)},I=()=>n.filter(p=>y(p,c)),j=()=>{if(l>0){process.stdout.write(`\x1B[${l}A`);for(let p=0;p<l;p++)process.stdout.write("\x1B[2K\x1B[1B");process.stdout.write(`\x1B[${l}A`)}},h=(p="active")=>{j();let i=[],b=I(),A=p==="active"?Pe:p==="cancel"?ke:Oe;if(i.push(`${A} ${m.bold(t)}`),p==="active"){let K=`${x} ${m.dim("Search:")} ${c}${m.inverse(" ")}`;i.push(K),i.push(`${x} ${m.dim("\u2191\u2193 move, space select, enter confirm")}`),i.push(`${x}`);let R=Math.max(0,Math.min(a-Math.floor(o/2),b.length-o)),q=Math.min(b.length,R+o),z=b.slice(R,q);if(b.length===0)i.push(`${x} ${m.dim("No matches found")}`);else{for(let $=0;$<z.length;$++){let L=z[$],xe=R+$,ye=d.has(L.value),Q=xe===a,Se=ye?Me:Le,Re=Q?m.underline(L.label):L.label,Ce=L.hint?m.dim(` (${L.hint})`):"",Ie=Q?m.cyan("\u276F"):" ";i.push(`${x} ${Ie} ${Se} ${Re}${Ce}`)}let C=R,M=b.length-q;if(C>0||M>0){let $=[];C>0&&$.push(`\u2191 ${C} more`),M>0&&$.push(`\u2193 ${M} more`),i.push(`${x} ${m.dim($.join(" "))}`)}}if(i.push(`${x}`),d.size===0)i.push(`${x} ${m.dim("Selected: (none)")}`);else{let C=n.filter($=>d.has($.value)).map($=>$.label),M=C.length<=3?C.join(", "):`${C.slice(0,3).join(", ")} +${C.length-3} more`;i.push(`${x} ${m.green("Selected:")} ${M}`)}i.push(`${m.dim("\u2514")}`)}else if(p==="submit"){let K=n.filter(R=>d.has(R.value)).map(R=>R.label);i.push(`${x} ${m.dim(K.join(", "))}`)}else p==="cancel"&&i.push(`${x} ${m.strikethrough(m.dim("Cancelled"))}`);process.stdout.write(`${i.join(`
3
+ `)}
4
+ `),l=i.length},f=()=>{process.stdin.removeListener("keypress",g),process.stdin.isTTY&&process.stdin.setRawMode(!1),r.close()},v=()=>{h("submit"),f(),s([...d])},w=()=>{h("cancel"),f(),s(null)},g=(p,i)=>{if(!i)return;let b=I();if(i.name==="return"){v();return}if(i.name==="escape"||i.ctrl&&i.name==="c"){w();return}if(i.name==="up"){a=Math.max(0,a-1),h();return}if(i.name==="down"){a=Math.min(b.length-1,a+1),h();return}if(i.name==="space"){let A=b[a];A&&(d.has(A.value)?d.delete(A.value):d.add(A.value)),h();return}if(i.name==="backspace"){c=c.slice(0,-1),a=0,h();return}i.sequence&&!i.ctrl&&!i.meta&&i.sequence.length===1&&(c+=i.sequence,a=0,h())};process.stdin.on("keypress",g),h()})};import E from"picocolors";var N=te,P=E.dim,Ne=E.cyan,_e=E.green,De=E.red,mt=E.yellow,se=E.bold,H=E.gray,Fe=["\x1B[38;5;252m","\x1B[38;5;249m","\x1B[38;5;246m","\x1B[38;5;243m","\x1B[38;5;240m","\x1B[38;5;237m"],Ue="\x1B[0m",oe=["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551","\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D"],Ge="1.1.1";function F(e,t){console.log(`${e} ${t}`)}function U(e){F(Ne(N.active),e)}function S(e){F(P(N.done),e)}function re(e){F(_e(N.success),e)}function _(e){F(De(N.error),e)}function u(e=""){console.log(`${P(N.bar)} ${e}`)}function k(){console.log();for(let e=0;e<oe.length;e++)console.log(`${Fe[e]}${oe[e]}${Ue}`);console.log(),console.log(` ${P(`v${Ge}`)}`),console.log()}import{existsSync as G,readFileSync as ie}from"fs";import{join as Y}from"path";var Ye=/^(npm|pnpm|yarn|bun)@/,Be=()=>{let e=process.cwd();for(let{file:n,cmd:o}of ee)if(G(Y(e,n)))return o;let t=Y(e,"package.json");if(G(t))try{let n=JSON.parse(ie(t,"utf-8"));if(n.packageManager){let o=n.packageManager.match(Ye);if(o)return o[1]}}catch{}return"npm"},Ke=()=>{let e=process.cwd();for(let t of Z)if(G(Y(e,t)))return t;return null},He=()=>{let e=process.cwd(),t=["tsconfig.json","jsconfig.json"];for(let n of t){let o=Y(e,n);if(G(o))try{let r=ie(o,"utf-8").replace(/\/\*[\s\S]*?\*\/|\/\/.*/g,""),a=JSON.parse(r).compilerOptions?.paths;if(a){for(let[d,l]of Object.entries(a))if(d.endsWith("/*")&&Array.isArray(l))return d.slice(0,-2)}}catch{}}return"@"},ce=()=>({componentPath:Ke()||"components/ui",alias:He(),packageManager:Be()});import{spawnSync as ae}from"child_process";import{existsSync as le,mkdirSync as Ve,readFileSync as vt,writeFileSync as We}from"fs";import{dirname as Je,isAbsolute as qe,relative as ze,resolve as pe}from"path";var Qe=(e,t)=>t==="@"?e:e.replace(/@\/components\//g,`${t}/components/`);var me=async(e,t,n,o)=>{let s=[],r=[],c=n,a=pe(process.cwd(),t.componentPath);for(let d of e.files){let l=d.target||d.path;l.startsWith("components/")&&(l=l.slice(11));let y=pe(a,l),I=ze(a,y);if(I.startsWith("..")||qe(I))throw new Error(`Invalid registry file path: ${l}`);let j=Je(y);if(le(j)||Ve(j,{recursive:!0}),le(y)&&!c){let f=await o(l);if(f==="skip"){r.push(l);continue}f==="all"&&(c=!0)}let h=Qe(d.content,t.alias);We(y,h,"utf-8"),s.push(l)}return{written:s,skipped:r}},de=(e,t,n)=>{let o=!0;if(e.length>0){let s={npm:["npm","install",...e],pnpm:["pnpm","add",...e],yarn:["yarn","add",...e],bun:["bun","add",...e]},[r,...c]=s[n];ae(r,c,{stdio:"pipe"}).status!==0&&(o=!1)}if(t.length>0){let s={npm:["npm","install","-D",...t],pnpm:["pnpm","add","-D",...t],yarn:["yarn","add","-D",...t],bun:["bun","add","-d",...t]},[r,...c]=s[n];ae(r,c,{stdio:"pipe"}).status!==0&&(o=!1)}return o};var fe=process.env.SMOOTHUI_REGISTRY_URL||X,Xe=/\/r\/([^/]+)\.json$/;async function Ze(){let e=`${fe}/r/registry.json`,t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch registry: ${t.status}`);return t.json()}async function ge(e){let t=`${fe}/r/${e}.json`,n=await fetch(t);if(!n.ok)throw new Error(`Component "${e}" not found`);return n.json()}function ue(e){let t=e.match(Xe);return t?t[1]:e}async function B(){return(await Ze()).items.map(t=>t.name)}async function V(e,t=new Set){let n=await ge(e);t.add(e);let o=[];if(n.registryDependencies)for(let s of n.registryDependencies){let r=ue(s);if(t.has(r)||!s.includes("smoothui.dev"))continue;let c=await V(r,t);o.push(c)}return{component:n,children:o}}function W(e){let t=[e.component];for(let n of e.children)t.push(...W(n));return t}function he(e){let t=new Set,n=new Set,o=new Set(["react","react-dom","next","tailwindcss","@types/react","@types/react-dom","@types/node","typescript"]);for(let s of e){for(let r of s.dependencies||[])o.has(r)||t.add(r);for(let r of s.devDependencies||[])o.has(r)||n.add(r)}return{dependencies:[...t],devDependencies:[...n]}}function J(e,t="",n=!0){u(`${t}${n?"\u2514\u2500":"\u251C\u2500"} ${e.component.name}`);let s=t+(n?" ":"\u2502 "),r=[...e.component.dependencies||[]].filter(c=>!["react","react-dom","next"].includes(c));r.length>0&&e.children.length===0&&u(`${s}\u2514\u2500 ${H(`npm: ${r.join(", ")}`)}`);for(let c=0;c<e.children.length;c++){let a=e.children[c],d=c===e.children.length-1&&r.length===0;J(a,s,d)}r.length>0&&e.children.length>0&&u(`${s}\u2514\u2500 ${H(`npm: ${r.join(", ")}`)}`)}async function $e(e,t){k();let n=ce();t.path&&(n.componentPath=t.path),S(`Detected: ${n.componentPath}/ (${n.packageManager})`),console.log();let o=e;if(o.length===0){let v=(await B()).map(g=>{let p="Other";for(let[i,b]of Object.entries(D))if(b.includes(g)){p=i;break}return{value:g,label:g,category:p}}),w=await ne({message:"Select components to install:",items:v});if(!w||w.length===0){console.log(),S("No components selected.");return}o=w,S(`Selected: ${o.join(", ")}`),console.log()}U("Resolving dependencies..."),u();let s=[],r=new Set;for(let f of o)if(!r.has(f))try{let v=await V(f),w=W(v);for(let g of w)r.has(g.name)||(r.add(g.name),s.push(g));J(v)}catch(v){_(`Failed to resolve ${f}: ${v.message}`);return}u();let{dependencies:c,devDependencies:a}=he(s),d=[...c,...a],l=s.length,y=c.length+a.length,I=y>0?`Install ${l} component${l>1?"s":""} + ${y} npm package${y>1?"s":""}?`:`Install ${l} component${l>1?"s":""}?`,j=await et({message:I});if(be(j)||!j){S("Installation cancelled.");return}console.log();let h=t.force??!1;for(let f of s){let{written:v,skipped:w}=await me(f,n,h,async g=>{let p=await tt({message:`File exists: ${g}`,options:[{value:"overwrite",label:"Overwrite"},{value:"skip",label:"Skip"},{value:"all",label:"Overwrite all"}]});return be(p)?"skip":(p==="all"&&(h=!0),p)});for(let g of v)S(`Written: ${n.componentPath}/${g}`);for(let g of w)S(`Skipped: ${g}`)}if(c.length>0||a.length>0){let f=nt();if(f.start(`Installing ${d.join(", ")}`),de(c,a,n.packageManager))f.stop(`Installed: ${d.join(", ")}`);else if(f.stop("Failed to install dependencies"),c.length>0&&u(`Run manually: ${n.packageManager} add ${c.join(" ")}`),a.length>0){let w=n.packageManager==="bun"?"-d":"-D";u(`Run manually: ${n.packageManager} add ${w} ${a.join(" ")}`)}}console.log(),re(`Done! ${l} component${l>1?"s":""} installed.`)}async function ve(e){let t=await B();if(e.json){console.log(JSON.stringify(t,null,2));return}k(),U(`Available components (${t.length})`),u();let n=new Map;for(let o of t){let s="Other";for(let[c,a]of Object.entries(D))if(a.includes(o)){s=c;break}let r=n.get(s);r?r.push(o):n.set(s,[o])}for(let[o,s]of n){u(se(P(o)));for(let r of s.sort())u(` ${r}`);u()}S(`Use ${P("npx smoothui add <component>")} to install`)}var O=process.argv.slice(2),T=O[0];function we(){k(),console.log("Usage: npx smoothui <command> [options]"),console.log(),console.log("Commands:"),console.log(" add [components...] Add components to your project"),console.log(" list List available components"),console.log(),console.log("Options:"),console.log(" --path <path> Custom component install path"),console.log(" --force Overwrite existing files without asking"),console.log(" --json Output as JSON (list command)"),console.log(" --help Show this help message"),console.log(),console.log("Examples:"),console.log(" npx smoothui add siri-orb"),console.log(" npx smoothui add siri-orb grid-loader"),console.log(" npx smoothui add # Interactive mode"),console.log(" npx smoothui list")}async function ot(){try{if(!T||T==="--help"||T==="-h"){we();return}if(T==="add"){let e=[],t,n=!1;for(let o=1;o<O.length;o++){let s=O[o];s==="--path"&&O[o+1]?(t=O[o+1],o++):s==="--force"||s==="-f"?n=!0:s.startsWith("-")||e.push(s)}await $e(e,{path:t,force:n});return}if(T==="list"||T==="ls"){let e=O.includes("--json");await ve({json:e});return}_(`Unknown command: ${T}`),we(),process.exit(1)}catch(e){let t=e instanceof Error?e.message:String(e);_(t||"An unknown error occurred"),process.exit(1)}}ot();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoothui-cli",
3
- "version": "1.0.6",
3
+ "version": "1.1.1",
4
4
  "author": "educalvolpz",
5
5
  "description": "CLI to install SmoothUI components - beautifully designed React components with smooth animations",
6
6
  "private": false,