yummaui 0.3.0 → 0.5.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.
Files changed (3) hide show
  1. package/README.md +31 -17
  2. package/dist/cli.mjs +37 -30
  3. package/package.json +8 -4
package/README.md CHANGED
@@ -13,7 +13,7 @@ pnpm dlx yummaui init
13
13
  ```
14
14
 
15
15
  ```bash
16
- pnpm dlx yummaui add <component...>
16
+ pnpm dlx yummaui add [components]
17
17
  ```
18
18
 
19
19
  ## Commands
@@ -30,34 +30,47 @@ Detects your framework, package manager and import alias, then writes a `yummaui
30
30
  }
31
31
  ```
32
32
 
33
- Pass `--force` to overwrite an existing config.
33
+ Pass `--force` to replace an existing config, and `-y` to take the defaults.
34
34
 
35
- ### `add <component...>`
35
+ If Yumma CSS is not set up yet, `init` and `add` offer to do it: install
36
+ `yummacss` and `@yummacss/vite` or `@yummacss/postcss`, register the plugin,
37
+ write `yumma.config.mjs`, and add `@yummacss;` to your stylesheet. Each change
38
+ is printed as it happens.
39
+
40
+ ### `add [components]`
36
41
 
37
42
  ```bash
38
43
  pnpm dlx yummaui add button
39
44
  pnpm dlx yummaui add dialog tooltip
40
- pnpm dlx yummaui add dialog-sign-in
41
45
  pnpm dlx yummaui add --all
46
+ pnpm dlx yummaui add
47
+ pnpm dlx yummaui add button --style compact --radius small
42
48
  ```
43
49
 
44
- | Option | |
45
- |---------------|------------------------------------|
46
- | `-a, --all` | Add every component |
47
- | `--overwrite` | Replace files that already exist |
48
- | `-y, --yes` | Skip prompts and take the defaults |
50
+ | Option | |
51
+ |--------------------|---------------------------------------------------|
52
+ | `-a, --all` | Add every component |
53
+ | `--style <name>` | `soft`, `compact` or `squircle` |
54
+ | `--radius <step>` | `none`, `small`, `medium`, `large` or `extra` |
55
+ | `--overwrite` | Replace files that already exist |
56
+ | `-y, --yes` | Skip prompts and take the defaults |
57
+
58
+ With no names, `add` opens a list to search and pick from.
59
+
60
+ A style and radius set as `style` and `radius` in `yummaui.json` apply to
61
+ every `add`; the flags win over them. Each style takes some radius steps and
62
+ refuses the rest, and `add` says why.
49
63
 
50
- ### `list [component]`
64
+ ### `list`
51
65
 
52
66
  ```bash
53
67
  pnpm dlx yummaui list
54
- pnpm dlx yummaui list button
55
68
  ```
56
69
 
57
70
  ### `prune`
58
71
 
59
72
  Finds component files nothing in your project reaches, and only ever considers
60
- files `add` wrote — your own components in the same folder are left alone.
73
+ files `add` wrote: your own components in the same folder are left alone.
61
74
 
62
75
  ```bash
63
76
  pnpm dlx yummaui prune # list them
@@ -69,18 +82,19 @@ pnpm dlx yummaui prune --write # delete them, after confirming
69
82
  | `--write` | Delete, instead of only listing |
70
83
  | `-y, --yes` | Skip the confirmation |
71
84
 
72
- A block imports the component it is built on, so "is anything importing this
73
- file" would keep a whole unused chain alive. `prune` asks whether a file is
74
- reachable from outside `componentsDir` instead: adding `dialog-sign-in` and
75
- never using it makes `dialog`, `checkbox` and `field` unused too.
85
+ A component can import another, so "is anything importing this file" would
86
+ keep a whole unused chain alive. `prune` asks whether a file is reachable from
87
+ outside `componentsDir` instead.
76
88
 
77
89
  ## Registry
78
90
 
79
91
  The CLI reads a static JSON registry published by the docs site:
80
92
 
81
93
  ```
82
- https://yummacss.com/ui/r/index.json every component and block
94
+ https://yummacss.com/ui/r/index.json every component
83
95
  https://yummacss.com/ui/r/<id>.json one component's source and dependencies
96
+ https://yummacss.com/ui/r/styles.json the styles and the radius steps each takes
97
+ https://yummacss.com/ui/r/<style>-<radius>/<id>.json the same, rewritten for a style
84
98
  ```
85
99
 
86
100
  ## License
package/dist/cli.mjs CHANGED
@@ -1,36 +1,43 @@
1
1
  #!/usr/bin/env node
2
- import e from"picocolors";import{spawnSync as t}from"node:child_process";import{existsSync as n,mkdirSync as r,readFileSync as i,readdirSync as a,rmSync as o,writeFileSync as s}from"node:fs";import{dirname as c,join as l,relative as u,resolve as d,sep as f}from"node:path";import*as p from"@clack/prompts";var m=`0.3.0`;const h=`https://yummacss.com/ui/r`;var g=class extends Error{};async function _(e){let t;try{t=await fetch(e,{headers:{accept:`application/json`}})}catch(t){throw new g(`Could not reach the registry at ${e}. Are you online?`,{cause:t})}if(t.status===404)throw new g(`Not found: ${e}`);if(!t.ok)throw new g(`Registry returned ${t.status} for ${e}`);try{return await t.json()}catch(t){throw new g(`Registry sent invalid JSON from ${e}`,{cause:t})}}function v(e){return _(`${e}/index.json`)}function ee(e,t){return _(`${e}/${t}.json`)}const y=`yummaui.json`,b={"pnpm-lock.yaml":`pnpm`,"bun.lockb":`bun`,"bun.lock":`bun`,"yarn.lock":`yarn`,"package-lock.json":`npm`};function x(e=process.cwd()){let t=d(e);for(;;){if(n(l(t,`package.json`)))return t;let e=c(t);if(e===t)return null;t=e}}function S(e){try{return JSON.parse(i(l(e,`package.json`),`utf8`))}catch{return{}}}function C(e){for(let[t,r]of Object.entries(b))if(n(l(e,t)))return r;let t=S(e).packageManager;if(typeof t==`string`){let e=t.split(`@`)[0];if(e===`pnpm`||e===`npm`||e===`yarn`||e===`bun`)return e}return`npm`}function w(e){let t=S(e),r={...t.dependencies,...t.devDependencies};return r.next?[`app`,`src/app`].some(t=>n(l(e,t)))?`Next.js (App Router)`:`Next.js (Pages Router)`:r.astro?`Astro`:r[`react-router`]||r[`@remix-run/react`]?`React Router`:r.vite?`Vite`:null}function T(e){for(let t of[`tsconfig.json`,`jsconfig.json`]){let r=l(e,t);if(n(r))try{let e=i(r,`utf8`).replace(/\/\*[\s\S]*?\*\//g,``).replace(/(^|\s)\/\/.*$/gm,`$1`);if(JSON.parse(e)?.compilerOptions?.paths?.[`@/*`])return`@`}catch{}}return null}function E(e){return l(e,y)}function D(e){let t=E(e);if(!n(t))return null;try{let e=JSON.parse(i(t,`utf8`));return{componentsDir:e.componentsDir??`components/ui`,alias:e.alias??null,registry:e.registry??h}}catch{return null}}function O(e,t){s(E(e),`${JSON.stringify(t,null,` `)}\n`)}function k(e,t){let n=S(e),r=new Set([...Object.keys(n.dependencies??{}),...Object.keys(n.devDependencies??{}),...Object.keys(n.peerDependencies??{})]);return t.filter(e=>!r.has(e.name))}function A(e,t){return{command:e,args:e===`npm`?[`install`,...t]:[`add`,...t]}}function j(e=x()){switch(e?C(e):`npm`){case`pnpm`:return`pnpm dlx yummaui`;case`yarn`:return`yarn dlx yummaui`;case`bun`:return`bunx yummaui`;default:return`npx yummaui`}}const M=`yumma.config.mjs`;function N(e){return e?e.startsWith(`Next.js`)?`@yummacss/postcss`:`@yummacss/vite`:null}function P(e){let t=S(e),r=new Set([...Object.keys(t.dependencies??{}),...Object.keys(t.devDependencies??{})]),i=N(w(e));return{core:r.has(`yummacss`),plugin:i?{name:i,installed:r.has(i)}:null,config:n(l(e,M))}}function F(e){let t=[];return e.core||t.push(`yummacss`),e.plugin&&!e.plugin.installed&&t.push(e.plugin.name),e.config||t.push(M),t}function I(t){let n=F(P(t));if(n.length===0)return;let r=n.map(t=>` ${e.yellow(`+`)} ${t}`);p.log.warn([`Yumma CSS is not set up here, so these components render unstyled.`,...r,``,` ${e.cyan(`https://yummacss.com/docs/installation`)}`].join(`
3
- `))}function L(e){let t=[],n={all:!1,overwrite:!1,yes:!1};for(let r=0;r<e.length;r++){let i=e[r];i===`--all`||i===`-a`?n.all=!0:i===`--overwrite`?n.overwrite=!0:i===`--yes`||i===`-y`?n.yes=!0:i.startsWith(`-`)||t.push(i)}return{names:t,options:n}}function R(e,t,n){return n===`base`?`${t}.tsx`:`${e}.tsx`}function z(e,t,n={}){let r=[];n.all&&r.push(...e.components.map(e=>e.base));for(let n of t){let t=e.components.find(e=>e.component===n);if(t){r.push(t.base);continue}let i=e.blocks.find(e=>e.id===n);if(i){r.push(i.id);continue}return{unknown:n}}return{ids:[...new Set(r)]}}async function B(i){let{names:a,options:o}=L(i),d=x();if(!d)return p.log.error(`No package.json found. Run this inside a project.`),1;let f=d,m=D(f);if(!m)return p.log.error(`No ${y} found. Run ${e.cyan(`${j(f)} init`)} first.`),1;let{registry:h,componentsDir:_}=m;if(a.length===0&&!o.all)return p.log.error(`Nothing to add. Try: ${j(f)} add button`),1;p.intro(e.bgCyan(e.black(` Yumma UI `)));let b,S=p.spinner();S.start(`Fetching registry`);try{b=await v(m.registry)}catch(e){return S.stop(`Registry unavailable`,1),p.log.error(e instanceof g?e.message:String(e)),1}S.stop(`${b.components.length} components, ${b.blocks.length} blocks available`);let w=z(b,a,{all:o.all});if(`unknown`in w)return p.log.error(`Unknown component or block ${e.bold(w.unknown)}.`),w.unknown===`all`?p.log.info(`Every component is ${e.cyan(`--all`)}.`):ne(b,w.unknown),1;let T=w.ids,E=[],O=new Map,M=new Set;async function N(e,t){if(M.has(e))return!0;M.add(e);let i;try{i=await ee(h,e)}catch(e){return p.log.error(e instanceof g?e.message:String(e)),!1}for(let e of i.registryDependencies)if(!await N(e,!1))return!1;let a=l(f,_,R(i.id,i.component,i.variant)),d=u(f,a).replace(/\\/g,`/`);if(n(a)&&!o.overwrite){if(!t||o.yes)return p.log.warn(`Skipped ${d} (already exists)`),!0;let e=await p.confirm({message:`${d} already exists. Overwrite?`,initialValue:!1});if(p.isCancel(e))return p.cancel(`Cancelled.`),!1;if(!e)return p.log.warn(`Skipped ${d}`),!0}let m=i.files[0];if(!m)return p.log.error(`${e} has no files.`),!1;r(c(a),{recursive:!0}),s(a,m.content),E.push(d);for(let e of i.dependencies)O.set(e.name,e.version);return!0}for(let e of T)if(!await N(e,!0))return 1;if(E.length===0)return p.outro(`Nothing written.`),0;p.log.success(`Added\n${E.map(e=>` ${e}`).join(`
4
- `)}`);let P=k(f,[...O].map(([e,t])=>({name:e,version:t}))),F=[...O.keys()].filter(e=>!P.some(t=>t.name===e));if(O.size>0){let t=[...F.map(t=>` ${e.green(`✔`)} ${t} ${e.dim(`already installed`)}`),...P.map(t=>` ${e.yellow(`+`)} ${t.name}@${t.version}`)];p.log.info(`Dependencies\n${t.join(`
5
- `)}`)}if(P.length>0){let n=C(f),r=P.map(e=>`${e.name}@${e.version}`),i=o.yes;if(!i){let t=await p.confirm({message:`Install ${P.length} missing package${P.length>1?`s`:``} with ${e.bold(n)}?`});if(p.isCancel(t))return p.cancel(`Cancelled.`),1;i=t}if(i){let{command:e,args:i}=A(n,r),a=t(e,i,{cwd:f,stdio:`inherit`,shell:process.platform===`win32`});if(a.status!==0)return p.log.error(`${e} exited with ${a.status??`an error`}.`),1}else p.log.info(`Install manually:\n ${C(f)} add ${r.join(` `)}`)}return I(f),p.outro(`Done.`),0}function te(e,t){let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=[r];for(let a=1;a<=t.length;a++){let o=e[r-1]===t[a-1]?0:1;i[a]=Math.min(i[a-1]+1,n[a]+1,n[a-1]+o)}n=i}return n[t.length]}function ne(e,t){let n=[...e.components.map(e=>e.component),...e.blocks.map(e=>e.id)].map(e=>({name:e,score:e.includes(t)||t.includes(e)?0:te(e,t)})).filter(e=>e.score<=2).sort((e,t)=>e.score-t.score).slice(0,5).map(e=>e.name);n.length?p.log.info(`Did you mean: ${n.join(`, `)}`):p.log.info(`Run ${j()} list to see everything.`)}async function V(t){let n=t.includes(`--force`),r=x();if(!r)return p.log.error(`No package.json found. Run this inside a project.`),1;if(p.intro(e.bgCyan(e.black(` Yumma UI `))),D(r)&&!n)return p.log.warn(`${y} already exists. Use --force to overwrite.`),p.outro(`Nothing to do.`),0;let i=w(r),a=C(r),o=T(r);p.log.step([i?`Detected ${e.bold(i)}`:`No framework detected`,`Detected ${e.bold(a)}`].join(`
6
- `));let s=await p.text({message:`Where should components go?`,placeholder:`components/ui`,defaultValue:`components/ui`});if(p.isCancel(s))return H();let c=!1;if(o){let t=await p.confirm({message:`Use the ${e.bold(`"${o}/"`)} import alias?`});if(p.isCancel(t))return H();c=t}return O(r,{componentsDir:String(s),alias:c&&o?`${o}/${s}`:null,registry:h}),p.log.success(`Wrote ${e.bold(E(r))}`),I(r),p.outro(`Next: ${e.cyan(`${j(r)} add button`)}`),0}function H(){return p.cancel(`Cancelled.`),1}async function U(t){let n=t.find(e=>!e.startsWith(`-`)),r=x(),i=r&&D(r)?.registry||h,a;try{a=await v(i)}catch(t){return console.error(e.red(t instanceof g?t.message:String(t))),1}if(n){let t=a.components.find(e=>e.component===n);if(!t)return console.error(e.red(`Unknown component ${n}.`)),1;let i=a.blocks.filter(e=>e.component===n);if(console.log(`\n${e.bold(t.title)} ${e.dim(t.component)}\n`),console.log(` ${e.dim(`${j(r)} add ${t.component}`)}\n`),console.log(` ${e.dim(`Every variation is a prop. Read its API at`)} ${e.cyan(`https://yummacss.com/ui/components/${t.component}`)}\n`),i.length){console.log(` ${e.bold(`${i.length} block${i.length>1?`s`:``} built on it`)}`);for(let t of i)console.log(` ${t.id.padEnd(26)}${e.dim(`add ${t.id}`)}`);console.log()}return 0}console.log(`\n${e.bold(`${a.components.length} components`)}\n`);let o=a.components.map(e=>e.component);for(let e=0;e<o.length;e+=2)console.log(` ${(o[e]??``).padEnd(24)}${o[e+1]??``}`);console.log(`\n${e.bold(`${a.blocks.length} blocks`)}\n`);let s=a.blocks.map(e=>e.id);for(let e=0;e<s.length;e+=2)console.log(` ${(s[e]??``).padEnd(30)}${s[e+1]??``}`);return console.log(`\n ${e.dim(`${j(r)} list <component>`)} to see its blocks\n`),0}const W=[`.astro`,`.cjs`,`.cts`,`.js`,`.jsx`,`.md`,`.mdx`,`.mjs`,`.mts`,`.svelte`,`.ts`,`.tsx`,`.vue`],G=new Set([`node_modules`,`.git`]),K=[/\bfrom\s*["']([^"'\n]+)["']/g,/\bimport\s*\(\s*["']([^"'\n]+)["']/g,/\brequire\s*\(\s*["']([^"'\n]+)["']/g,/\bimport\s+["']([^"'\n]+)["']/g];function q(e){let t=new Set;for(let n of K){n.lastIndex=0;for(let r of e.matchAll(n))r[1]&&t.add(r[1])}return[...t]}const J=/\b(?:from|import\s*\(|require\s*\()\s*`/;function Y(e){return J.test(e)}function X(e){let t=e.split(f).join(`/`).replace(/^\.\//,``);for(let e of W)if(t.endsWith(e))return t.slice(0,-e.length);return t}function Z(e,t,n){let r=d(n.root,n.componentsDir);if(n.alias){let t=`${n.alias}/`;if(e===n.alias)return`index`;if(e.startsWith(t)){let n=e.slice(t.length);return n?X(n):`index`}}if(!e.startsWith(`.`))return null;let i=u(r,d(c(t),e));return i?i===`..`||i.startsWith(`..${f}`)?null:X(i):`index`}function re(e,t){return X(u(d(t.root,t.componentsDir),e))}function Q(e,t,n=[]){let r;try{r=a(e,{withFileTypes:!0})}catch{return n}for(let i of r){let r=l(e,i.name);if(i.isDirectory()){if(G.has(i.name)||r===t)continue;Q(r,t,n)}else if(i.isFile()){let e=i.name.lastIndexOf(`.`);e>0&&W.includes(i.name.slice(e))&&n.push(r)}}return n}function ie(e){let t=new Set;for(let n of e.components)t.add(`${n.component}.tsx`);for(let n of e.blocks)t.add(`${n.id}.tsx`);return t}function ae(e,t){let n=d(e.root,e.componentsDir),r=Q(n,``),a=Q(e.root,n),o=new Map,s=new Set,c=new Map,l=[];for(let n of r){let r=re(n,e);n.endsWith(`.tsx`)&&!r.includes(`/`)&&t.has(`${r}.tsx`)?o.set(r,n):s.add(r);let a=i(n,`utf8`);Y(a)&&l.push(n);let u=new Set;for(let t of q(a)){let r=Z(t,n,e);r&&u.add(r)}c.set(r,u)}for(let t of a){let n=i(t,`utf8`);Y(n)&&l.push(t);for(let r of q(n)){let n=Z(r,t,e);n&&s.add(n)}}let u=new Set,f=[...s];for(;f.length>0;){let e=f.pop();if(!u.has(e)){u.add(e);for(let t of c.get(e)??[])u.has(t)||f.push(t)}}let p=[];for(let[e,t]of o)u.has(e)||p.push(t);return{unused:p.sort(),kept:o.size-p.length,foreign:r.length-o.size,scanned:r.length+a.length,computed:l}}function oe(e){return{write:e.includes(`--write`),yes:e.includes(`--yes`)||e.includes(`-y`)}}async function se(t){let n=oe(t),r=x();if(!r)return p.log.error(`No package.json found. Run this inside a project.`),1;let i=D(r);if(!i)return p.log.error(`No ${y} found. Run ${e.cyan(`${j(r)} init`)} first.`),1;p.intro(e.bgCyan(e.black(` Yumma UI `)));let a,s=p.spinner();s.start(`Fetching registry`);try{a=await v(i.registry)}catch(e){return s.stop(`Registry unavailable`,1),p.log.error(e instanceof g?e.message:String(e)),1}s.stop(`Reading the project`);let c=ae({root:r,componentsDir:i.componentsDir,alias:i.alias},ie(a)),l=e=>u(r,e).replace(/\\/g,`/`);if(c.computed.length>0&&p.log.warn(`Imports built at runtime in ${c.computed.length} file${c.computed.length>1?`s`:``}; anything they name is invisible here:\n${c.computed.slice(0,5).map(e=>` ${l(e)}`).join(`
7
- `)}`),c.unused.length===0)return p.log.info(`${c.kept} installed, all reachable. ${c.scanned} files scanned.`),p.outro(`Nothing to prune.`),0;if(p.log.info(`Unreachable from outside ${e.bold(i.componentsDir)}\n${c.unused.map(t=>` ${e.yellow(l(t))}`).join(`
8
- `)}`),p.log.step(`${c.unused.length} unused, ${c.kept} in use`+(c.foreign>0?`, ${c.foreign} not ours`:``)),!n.write)return p.outro(`Delete them with ${e.cyan(`${j(r)} prune --write`)}`),0;if(!n.yes){let e=await p.confirm({message:`Delete ${c.unused.length} file${c.unused.length>1?`s`:``}?`,initialValue:!1});if(p.isCancel(e))return p.cancel(`Cancelled.`),1;if(!e)return p.outro(`Nothing deleted.`),0}for(let e of c.unused)o(e,{force:!0});return p.log.success(`Deleted ${c.unused.length}`),p.outro(`Done.`),0}const $=()=>{let t=j();return`
9
- ${e.bold(`yummaui`)} ${e.dim(`v${m}`)}
2
+ import{parseArgs as e,styleText as t}from"node:util";import{existsSync as n,mkdirSync as r,readFileSync as i,readdirSync as a,rmSync as o,writeFileSync as s}from"node:fs";import{dirname as c,join as l,relative as u,resolve as d,sep as f}from"node:path";import*as p from"@clack/prompts";import{distance as m}from"fastest-levenshtein";import{spawn as h}from"node:child_process";import{generateCode as g,loadFile as _}from"magicast";import{addVitePlugin as v,getConfigFromVariableDeclaration as y,getDefaultExportOptions as b}from"magicast/helpers";var x=`0.5.0`;const S=`https://yummacss.com/ui/r`;var C=class extends Error{};async function w(e){let t;try{t=await fetch(e,{headers:{accept:`application/json`}})}catch(t){throw new C(`Could not reach the registry at ${e}. Are you online?`,{cause:t})}if(t.status===404)throw new C(`Not found: ${e}`);if(!t.ok)throw new C(`Registry returned ${t.status} for ${e}`);try{return await t.json()}catch(t){throw new C(`Registry sent invalid JSON from ${e}`,{cause:t})}}function ee(e){return w(`${e}/index.json`)}function te(e,t){return w(`${e}/${t}.json`)}function ne(e){return w(`${e}/styles.json`)}function re(e,t,n){let r=t??e.default,i=e.styles[r];if(!i)return{error:`There is no ${r} style. Try one of: ${Object.keys(e.styles).join(`, `)}.`};let a=n??i.radius;return i.allow.includes(a)?{folder:`${r}-${a}`}:{error:`${i.refused[a]??`${i.name} does not take ${a}.`} ${i.name} takes: ${i.allow.join(`, `)}.`}}const T=`yummaui.json`,E=`yumma.config.mjs`,D=`https://yummacss.com/docs/installation`,O=`@yummacss;`,ie={"pnpm-lock.yaml":`pnpm`,"bun.lockb":`bun`,"bun.lock":`bun`,"yarn.lock":`yarn`,"package-lock.json":`npm`};function k(e=process.cwd()){let t=d(e);for(;;){if(n(l(t,`package.json`)))return t;let e=c(t);if(e===t)return null;t=e}}function A(e){try{return JSON.parse(i(l(e,`package.json`),`utf8`))}catch{return{}}}function j(e){for(let[t,r]of Object.entries(ie))if(n(l(e,t)))return r;let t=A(e).packageManager;if(typeof t==`string`){let e=t.split(`@`)[0];if(e===`pnpm`||e===`npm`||e===`yarn`||e===`bun`)return e}return`npm`}function ae(e){let t=A(e),r={...t.dependencies,...t.devDependencies};return r.next?[`app`,`src/app`].some(t=>n(l(e,t)))?`Next.js (App Router)`:`Next.js (Pages Router)`:r.astro?`Astro`:r[`react-router`]||r[`@remix-run/react`]?`React Router`:r.vite?`Vite`:null}function oe(e){for(let t of[`tsconfig.json`,`jsconfig.json`]){let r=l(e,t);if(n(r))try{let e=i(r,`utf8`).replace(/\/\*[\s\S]*?\*\//g,``).replace(/(^|\s)\/\/.*$/gm,`$1`);if(JSON.parse(e)?.compilerOptions?.paths?.[`@/*`])return`@`}catch{}}return null}function se(e){return l(e,T)}function M(e){let t=se(e);if(!n(t))return null;try{let e=JSON.parse(i(t,`utf8`));return{componentsDir:e.componentsDir??`components/ui`,alias:e.alias??null,registry:e.registry??S,...e.style?{style:e.style}:{},...e.radius?{radius:e.radius}:{}}}catch{return null}}function ce(e,t){s(se(e),`${JSON.stringify(t,null,` `)}\n`)}function le(e,t){let n=A(e),r=new Set([...Object.keys(n.dependencies??{}),...Object.keys(n.devDependencies??{}),...Object.keys(n.peerDependencies??{})]);return t.filter(e=>!r.has(e.name))}function N(e,t,n=!1){return{command:e,args:[e===`npm`?`install`:`add`,...n?[`-D`]:[],...t]}}function P(e=k()){switch(e?j(e):`npm`){case`pnpm`:return`pnpm dlx yummaui`;case`yarn`:return`yarn dlx yummaui`;case`bun`:return`bunx yummaui`;default:return`npx yummaui`}}const ue=e=>n=>t(e,n),F=process.stdout.hasColors?.(2**24)?24:process.stdout.hasColors?.()?4:0,I=(e,n)=>r=>F===24?`\x1b[${e}m${r}\x1b[39m`:t(n,r),L=`38;2;190;198;242`,de=`38;2;225;212;168`,fe=`38;2;168;225;173`,pe=`38;2;225;168;168`,R={bold:ue(`bold`),dim:ue(`dim`),accent:I(L,`blue`),success:I(fe,`green`),warning:I(de,`yellow`),danger:I(pe,`red`),badge:e=>F===24?`\x1b[1;97;48;2;76;95;199m${e}\x1b[0m`:t([`bold`,`whiteBright`,`bgBlue`],e)},me={31:pe,32:fe,33:de,35:L,36:L},he=RegExp(`\x1B\\[(3[1-6])m`,`g`);function ge(){if(F!==24)return;let e=process.stdout.write.bind(process.stdout);process.stdout.write=((t,...n)=>e(typeof t==`string`?t.replace(he,(e,t)=>me[t]?`\x1b[${me[t]}m`:e):t,...n))}const z=(e,t)=>`${e} ${t}${e===1?``:t.endsWith(`s`)?`es`:`s`}`;function B(e,t){let[n,...r]=t.split(`
3
+ `);return[`${R.dim(e.padEnd(11))}${n}`,...r.map(e=>`${` `.repeat(11)}${e}`)].join(`
4
+ `)}const V=e=>(t,n)=>p.log.message(B(t,n),{symbol:e,spacing:0}),H={done:V(R.success(p.S_STEP_SUBMIT)),info:V(p.S_INFO),warn:V(R.warning(p.S_WARN)),error:V(R.danger(p.S_ERROR))},U=B;function W(){p.intro(`${F?R.badge(` yummaui `):`yummaui`} ${R.dim(x)}`)}function _e(){p.log.message(``,{symbol:R.dim(p.S_BAR),spacing:0})}function G(e,t){p.outro(B(e,t))}function K(e){return p.cancel(B(`error`,e instanceof Error?e.message:String(e))),1}function q(){return p.cancel(B(`cancelled`,``)),1}function ve(){let e=k();if(!e)return Y.project.missing;let t=M(e);return t?{root:e,config:t}:Y.project.noConfig(P(e))}async function J(e){let t=p.spinner();t.start(B(`registry`,Y.registry.reading));try{let n=await ee(e);return t.stop(B(`registry`,Y.registry.found(n.components.length))),n}catch(e){throw t.error(B(`registry`,Y.registry.unavailable)),e}}const Y={cli:{unknownOption:(e=``)=>`Unknown option ${e}.`,unknownCommand:(e=``)=>`Unknown command "${e}".`,seeHelp:e=>`Run ${e} --help.`},help:(e,t)=>{let n=(e,t)=>` ${R.accent(e.padEnd(24))}${t}`;return`
5
+ ${R.bold(`yummaui`)} ${R.dim(`v${t}`)} Copies Yumma UI components into your project.
10
6
 
11
- Copies Yumma UI components into your project. Never a dependency.
7
+ ${R.bold(`Usage`)} ${e} <command> [options]
12
8
 
13
- ${e.bold(`Usage`)}
14
- ${t} <command> [options]
9
+ ${R.bold(`Commands`)}
10
+ ${n(`init`,`Write yummaui.json and set up Yumma CSS`)}
11
+ ${n(`add [components]`,`Copy components in, or pick from a list`)}
12
+ ${n(`list`,`Show every component`)}
13
+ ${n(`prune`,`Find components nothing uses`)}
15
14
 
16
- ${e.bold(`Commands`)}
17
- init Set up yummaui.json in this project
18
- add <component...> Copy a component in
19
- list [component] Browse what is available
20
- prune Find components nothing uses
15
+ ${R.bold(`Options`)}
16
+ ${n(`-a, --all`,`add: every component`)}
17
+ ${n(`--style <name>`,`add: soft, compact or squircle`)}
18
+ ${n(`--radius <step>`,`add: none, small, medium, large or extra`)}
19
+ ${n(`--overwrite`,`add: replace files that exist`)}
20
+ ${n(`--write`,`prune: delete what it finds`)}
21
+ ${n(`--force`,`init: replace yummaui.json`)}
22
+ ${n(`-y, --yes`,`Skip prompts and take the defaults`)}
21
23
 
22
- ${e.bold(`Options`)}
23
- -a, --all Add every component
24
- --overwrite Replace files that already exist
25
- --write prune: delete, instead of only listing
26
- -y, --yes Skip prompts, take the defaults
27
- -h, --help Show this
28
- --version Show the version
24
+ ${R.bold(`Examples`)}
25
+ ${e} add button tooltip
26
+ ${e} add button --style compact --radius small
27
+ ${e} prune --write
28
+ `},project:{missing:`No package.json found. Run this inside a project.`,noConfig:e=>`No ${T} found. Run ${R.accent(`${e} init`)} first.`},registry:{reading:`Reading`,found:e=>z(e,`component`),unavailable:`Unavailable`},init:{exists:()=>`${T} exists. ${R.accent(`--force`)} replaces it.`,detected:(e,t,n)=>`${e??`No framework`} with ${t}${n?`, imports through ${n}/`:``}`,where:`Where do components go?`,useAlias:e=>`Import them through ${R.bold(`${e}/`)}?`},add:{nameOne:e=>`Name a component: ${e} add button`,pick:`Which components?`,search:`Type to search`,unknown:(e,t,n)=>`There is no ${R.bold(e)} component. ${t.length?`Did you mean ${t.join(`, `)}?`:`${n} list shows them all.`}`,empty:e=>`${e} has no files.`,replace:e=>`${e} exists. Replace it?`,kept:e=>`${e} ${R.dim(`already there`)}`,nothing:`Nothing written. --overwrite replaces them.`,next:e=>`Import from ${R.accent(e)}`},install:{ask:(e,t)=>`${e.join(`, `)} with ${t}?`,yourself:e=>R.accent(e),failed:e=>`${e} could not install them.`,running:e=>`Running ${e}`,noStart:e=>`Could not start ${e}.`,exited:(e,t)=>`${e} exited with ${t}`},setup:{ask:`Yumma CSS is not set up here. Set it up now?`,unstyled:()=>`Yumma CSS is not set up here, so components render unstyled\n${R.accent(D)}`,declined:()=>`Components render unstyled until it is\n${R.accent(D)}`,docs:()=>R.accent(D),registered:(e,t)=>`${e} registers ${t}`,marked:e=>`${e} starts with ${O}`,noVite:`Add yummacss() from @yummacss/vite to your Vite plugins`,noBuild:`Add @yummacss/vite or @yummacss/postcss to your build`,noStylesheet:`Add ${O} to the stylesheet your app loads`,failed:e=>`Could not change ${e}. The docs have the line to add.`},list:{next:e=>`${R.accent(`${e} add <component>`)} ${R.dim(`yummacss.com/ui`)}`},prune:{clean:(e,t)=>`Nothing to prune. All ${e} in use, across ${z(t,`file`)}.`,hidden:e=>`${z(e,`file`)} build an import at runtime, so what they load cannot be seen`,next:e=>`Delete them: ${R.accent(`${e} prune --write`)}`,ask:e=>`${z(e,`file`)}?`,kept:`Nothing deleted.`,deleted:e=>`${z(e,`file`)} deleted.`}};function ye(e,t,n,r=!1){let i=n.map(e=>e.slice(0,e.lastIndexOf(`@`))),{command:a,args:o}=N(t,n,r),s=p.taskLog({title:U(`install`,Y.install.running(t)),limit:8}),c=h(a,o,{cwd:e,shell:process.platform===`win32`});for(let e of[c.stdout,c.stderr])e.on(`data`,e=>{for(let t of e.toString().split(/\r?\n/))t.trim()&&s.message(t)});return new Promise(e=>{c.on(`error`,()=>{s.error(U(`install`,Y.install.noStart(a))),e(!1)}),c.on(`close`,t=>{t===0?s.success(U(`install`,i.join(`, `))):s.error(U(`install`,Y.install.exited(a,t)),{showLog:!0}),e(t===0)})})}const X=(e,t)=>t.find(t=>n(l(e,t)))??null,Z=(e,t,n)=>i(l(e,t),`utf8`).includes(n);function be(e){return e?e.startsWith(`Next.js`)?`postcss`:`vite`:null}function xe(e,t){let r=t.split(`/`)[0]??`src`,i=n(l(e,`src`))?[`src`]:[`app`,`pages`,`components`,r].filter(t=>n(l(e,t)));return i.includes(r)||i.push(r),[...new Set(i)].map(e=>`./${e}/**/*.{js,jsx,ts,tsx,mdx}`)}function Se(e,t){if(t===`postcss`)return X(e,[`app/globals.css`,`src/app/globals.css`,`styles/globals.css`,`src/styles/globals.css`]);let r=X(e,[`main`,`index`].flatMap(e=>[`tsx`,`ts`,`jsx`,`js`].map(t=>`src/${e}.${t}`)));if(r){let t=i(l(e,r),`utf8`),a=/import\s+["'](\.{1,2}\/[^"']+\.css)["']/.exec(t)?.[1];if(a){let t=u(e,l(e,c(r),a));if(n(l(e,t)))return t.replace(/\\/g,`/`)}}return X(e,[`src/index.css`,`src/style.css`,`src/styles.css`,`src/App.css`])}function Ce(e){return`import { defineConfig } from "yummacss";
29
29
 
30
- ${e.bold(`Examples`)}
31
- ${t} add button
32
- ${t} add dialog tooltip
33
- ${t} add --all
34
- ${t} list button
35
- ${t} prune
36
- `};async function ce(){let t=process.argv.slice(2),n=t[0];if(!n||n===`-h`||n===`--help`)return console.log($()),0;if(n===`--version`||n===`-V`)return console.log(m),0;let r=t.slice(1);switch(n){case`init`:return V(r);case`add`:return B(r);case`list`:case`ls`:return U(r);case`prune`:return se(r);default:return console.error(e.red(`Unknown command "${n}".`)),console.log($()),1}}ce().then(e=>{process.exitCode=e}).catch(t=>{console.error(e.red(t instanceof Error?t.message:String(t))),process.exitCode=1});export{};
30
+ export default defineConfig({
31
+ source: [${e.map(e=>`"${e}"`).join(`, `)}],
32
+ });
33
+ `}const we=(e,t)=>s(t,g(e).code);function Te(e){let t=b(e),{config:n,declaration:r}=t.$type===`identifier`?y(e):{config:t,declaration:null};if(!n)throw Error(`no config object`);if(t=n,t.plugins??={},t.plugins[`@yummacss/postcss`]={},r){if(r.init?.type!==`ObjectExpression`)throw Error(`config is not an object literal`);r.init=g(t).code}}function Ee(e,t){let r=A(e),a=new Set([...Object.keys(r.dependencies??{}),...Object.keys(r.devDependencies??{})]),o=be(ae(e)),c=o&&`@yummacss/${o}`,u={packages:[],steps:[],manual:[]};if(a.has(`yummacss`)||u.packages.push(`yummacss`),c&&!a.has(c)&&u.packages.push(c),o===`postcss`){let t=X(e,[`postcss.config.mjs`,`postcss.config.js`,`postcss.config.cjs`]);t?Z(e,t,`@yummacss/postcss`)||u.steps.push({stage:`edit`,file:t,apply:async()=>{let n=await _(l(e,t));return Te(n),we(n,l(e,t)),Y.setup.registered(t,`@yummacss/postcss`)}}):u.steps.push({stage:`write`,file:`postcss.config.mjs`,apply:async()=>(s(l(e,`postcss.config.mjs`),`export default {
34
+ plugins: {
35
+ "@yummacss/postcss": {},
36
+ },
37
+ };
38
+ `),`postcss.config.mjs`)})}else if(o===`vite`){let t=X(e,[`ts`,`mts`,`js`,`mjs`].map(e=>`vite.config.${e}`));t?Z(e,t,`@yummacss/vite`)||u.steps.push({stage:`edit`,file:t,apply:async()=>{let n=await _(l(e,t));return v(n,{from:`@yummacss/vite`,constructor:`yummacss`}),we(n,l(e,t)),Y.setup.registered(t,`yummacss()`)}}):u.manual.push(Y.setup.noVite)}else u.manual.push(Y.setup.noBuild);n(l(e,E))||u.steps.push({stage:`write`,file:E,apply:async()=>(s(l(e,E),Ce(xe(e,t))),E)});let d=o&&Se(e,o);return d?Z(e,d,`@yummacss`)||u.steps.push({stage:`edit`,file:d,apply:async()=>{let t=l(e,d);return s(t,`${O}\n\n${i(t,`utf8`)}`),Y.setup.marked(d)}}):u.manual.push(Y.setup.noStylesheet),u}async function De(e,t,n){let r=Ee(e,t);if(!r.packages.length&&!r.steps.length&&!r.manual.length)return!0;if(!n&&!process.stdout.isTTY)return H.warn(`check`,Y.setup.unstyled()),!0;if(!n){let e=await p.confirm({message:U(`setup`,Y.setup.ask)});if(p.isCancel(e))return q(),!1;if(!e)return H.warn(`check`,Y.setup.declined()),!0}if(r.packages.length&&!await ye(e,j(e),r.packages,!0))return!1;for(let e of r.steps)try{H.done(e.stage,await e.apply())}catch{H.warn(e.stage,Y.setup.failed(e.file))}for(let e of r.manual)H.warn(`manual`,e);return r.manual.length&&H.info(`docs`,Y.setup.docs()),!0}function Oe(e,t,n){return n===`base`?`${t}.tsx`:`${e}.tsx`}function ke(e,t,n={}){let r=[];n.all&&r.push(...e.components.map(e=>e.base));for(let n of t){let t=e.components.find(e=>e.component===n);if(!t)return{unknown:n};r.push(t.base)}return{ids:[...new Set(r)]}}function Ae(e,t){return e.components.map(({component:e})=>({component:e,score:e.includes(t)||t.includes(e)?0:m(e,t)})).filter(e=>e.score<=2).sort((e,t)=>e.score-t.score).slice(0,5).map(e=>e.component)}async function je(e,t){W();let i=ve();if(typeof i==`string`)return K(i);let{root:a,config:o}=i,d;try{d=await J(o.registry)}catch(e){return K(e)}if(e.length===0&&!t.all){if(t.yes||!process.stdout.isTTY)return K(Y.add.nameOne(P(a)));let n=await p.autocompleteMultiselect({message:Y.add.pick,placeholder:Y.add.search,options:d.components.map(e=>({value:e.component,label:e.component})),required:!0});if(p.isCancel(n))return q();e=n}let f=ke(d,e,{all:t.all});if(`unknown`in f){let e=Ae(d,f.unknown);return K(Y.add.unknown(f.unknown,e,P(a)))}let m=o.registry,h=t.style??o.style??null,g=t.radius??o.radius??null;if(h||g)try{let e=re(await ne(o.registry),h,g);if(`error`in e)return K(e.error);m=`${o.registry}/${e.folder}`,H.info(`style`,e.folder)}catch(e){return K(e)}let _=[],v=new Set;async function y(e){if(v.has(e))return;v.add(e);let t=await te(m,e);for(let e of t.registryDependencies)await y(e);_.push(t)}try{for(let e of f.ids)await y(e)}catch(e){return K(e)}let b=[],x=[],S=new Map;for(let e of _){let i=e.files[0];if(!i)return K(Y.add.empty(e.id));let d=l(a,o.componentsDir,Oe(e.id,e.component,e.variant)),m=u(a,d).replace(/\\/g,`/`);if(n(d)&&!t.overwrite){if(!f.ids.includes(e.id)||t.yes||!process.stdout.isTTY){x.push(m);continue}let n=await p.confirm({message:U(`write`,Y.add.replace(m)),initialValue:!1});if(p.isCancel(n))return q();if(!n){x.push(m);continue}}r(c(d),{recursive:!0}),s(d,i.content),b.push(m);for(let t of e.dependencies)S.set(t.name,t.version)}if(b.length>0&&H.done(`write`,b.join(`
39
+ `)),x.length>0&&H.warn(`kept`,x.map(Y.add.kept).join(`
40
+ `)),b.length===0)return G(`next`,Y.add.nothing),0;let C=le(a,[...S].map(([e,t])=>({name:e,version:t})));if(C.length>0){let e=j(a),n=C.map(e=>`${e.name}@${e.version}`),r=C.map(e=>e.name),i=t.yes===!0;if(!i){let t=await p.confirm({message:U(`install`,Y.install.ask(r,e))});if(p.isCancel(t))return q();i=t}if(i){if(!await ye(a,e,n))return K(Y.install.failed(e))}else{let{command:t,args:r}=N(e,n);H.info(`install`,Y.install.yourself([t,...r].join(` `)))}}return await De(a,o.componentsDir,t.yes===!0)?(G(`next`,Y.add.next(o.alias??o.componentsDir)),0):1}async function Me(e){W(),_e();let t=k();if(!t)return K(Y.project.missing);if(M(t)&&!e.force)return G(`next`,Y.init.exists()),0;let r=ae(t),i=oe(t);H.info(`project`,Y.init.detected(r,j(t),i));let a=n(l(t,`src`))?`src/components/ui`:`components/ui`,o=e.yes?a:await p.text({message:Y.init.where,placeholder:a,defaultValue:a});if(p.isCancel(o))return q();let s=!!i;if(i&&!e.yes){let e=await p.confirm({message:Y.init.useAlias(i)});if(p.isCancel(e))return q();s=e}return ce(t,{componentsDir:o,alias:s?`${i}/${o}`:null,registry:S}),H.done(`write`,T),await De(t,o,e.yes===!0)?(G(`next`,R.accent(`${P(t)} add`)),0):1}async function Ne(){W();let e=k(),t=e&&M(e)?.registry||S,n;try{n=await J(t)}catch(e){return K(e)}let r=n.components.map(e=>e.component),i=Math.max(...r.map(e=>e.length))+2,a=[];for(let e=0;e<r.length;e+=3)a.push(r.slice(e,e+3).map(e=>e.padEnd(i)).join(``).trimEnd());return H.done(`available`,a.join(`
41
+ `)),G(`next`,Y.list.next(P(e))),0}const Pe=[`.astro`,`.cjs`,`.cts`,`.js`,`.jsx`,`.md`,`.mdx`,`.mjs`,`.mts`,`.svelte`,`.ts`,`.tsx`,`.vue`],Fe=new Set([`node_modules`,`.git`]),Ie=[/\bfrom\s*["']([^"'\n]+)["']/g,/\bimport\s*\(\s*["']([^"'\n]+)["']/g,/\brequire\s*\(\s*["']([^"'\n]+)["']/g,/\bimport\s+["']([^"'\n]+)["']/g];function Le(e){let t=new Set;for(let n of Ie){n.lastIndex=0;for(let r of e.matchAll(n))r[1]&&t.add(r[1])}return[...t]}const Re=/\b(?:from|import\s*\(|require\s*\()\s*`/;function ze(e){return Re.test(e)}function Q(e){let t=e.split(f).join(`/`).replace(/^\.\//,``);for(let e of Pe)if(t.endsWith(e))return t.slice(0,-e.length);return t}function Be(e,t,n){let r=d(n.root,n.componentsDir);if(n.alias){let t=`${n.alias}/`;if(e===n.alias)return`index`;if(e.startsWith(t)){let n=e.slice(t.length);return n?Q(n):`index`}}if(!e.startsWith(`.`))return null;let i=u(r,d(c(t),e));return i?i===`..`||i.startsWith(`..${f}`)?null:Q(i):`index`}function Ve(e,t){return Q(u(d(t.root,t.componentsDir),e))}function $(e,t,n=[]){let r;try{r=a(e,{withFileTypes:!0})}catch{return n}for(let i of r){let r=l(e,i.name);if(i.isDirectory()){if(Fe.has(i.name)||r===t)continue;$(r,t,n)}else if(i.isFile()){let e=i.name.lastIndexOf(`.`);e>0&&Pe.includes(i.name.slice(e))&&n.push(r)}}return n}function He(e){let t=new Set;for(let n of e.components)t.add(`${n.component}.tsx`);return t}function Ue(e,t){let n=d(e.root,e.componentsDir),r=$(n,``),a=$(e.root,n),o=new Map,s=new Set,c=new Map,l=[];for(let n of r){let r=Ve(n,e);n.endsWith(`.tsx`)&&!r.includes(`/`)&&t.has(`${r}.tsx`)?o.set(r,n):s.add(r);let a=i(n,`utf8`);ze(a)&&l.push(n);let u=new Set;for(let t of Le(a)){let r=Be(t,n,e);r&&u.add(r)}c.set(r,u)}for(let t of a){let n=i(t,`utf8`);ze(n)&&l.push(t);for(let r of Le(n)){let n=Be(r,t,e);n&&s.add(n)}}let u=new Set,f=[...s];for(;f.length>0;){let e=f.pop();if(!u.has(e)){u.add(e);for(let t of c.get(e)??[])u.has(t)||f.push(t)}}let p=[];for(let[e,t]of o)u.has(e)||p.push(t);return{unused:p.sort(),kept:o.size-p.length,foreign:r.length-o.size,scanned:r.length+a.length,computed:l}}async function We(e){W();let t=ve();if(typeof t==`string`)return K(t);let{root:n,config:r}=t,i;try{i=await J(r.registry)}catch(e){return K(e)}let a=Ue({root:n,componentsDir:r.componentsDir,alias:r.alias},He(i)),s=e=>u(n,e).replace(/\\/g,`/`);if(a.computed.length>0&&H.warn(`hidden`,`${Y.prune.hidden(a.computed.length)}\n${a.computed.slice(0,5).map(e=>R.dim(s(e))).join(`
42
+ `)}`),a.unused.length===0)return G(`next`,Y.prune.clean(a.kept,a.scanned)),0;if(H.warn(`unused`,a.unused.map(s).join(`
43
+ `)),!e.write)return G(`next`,Y.prune.next(P(n))),0;if(!e.yes){let e=await p.confirm({message:U(`delete`,Y.prune.ask(a.unused.length)),initialValue:!1});if(p.isCancel(e))return q();if(!e)return G(`next`,Y.prune.kept),0}for(let e of a.unused)o(e,{force:!0});return G(`delete`,Y.prune.deleted(a.unused.length)),0}const Ge={all:{type:`boolean`,short:`a`},style:{type:`string`},radius:{type:`string`},overwrite:{type:`boolean`},write:{type:`boolean`},force:{type:`boolean`},yes:{type:`boolean`,short:`y`},help:{type:`boolean`,short:`h`},version:{type:`boolean`,short:`V`}},Ke=t=>e({args:t,options:Ge,allowPositionals:!0}),qe=()=>Y.help(P(),x);async function Je(){ge();let e;try{e=Ke(process.argv.slice(2))}catch(e){let t=e.code===`ERR_PARSE_ARGS_UNKNOWN_OPTION`,n=String(e).match(/'(-[^']+)'/)?.[1];return console.error(R.danger(t?Y.cli.unknownOption(n):String(e.message))),console.error(Y.cli.seeHelp(P())),1}let{values:t,positionals:n}=e,[r,...i]=n;if(t.version)return console.log(x),0;switch(t.help?void 0:r){case`init`:return Me(t);case`add`:return je(i,t);case`list`:case`ls`:return Ne();case`prune`:return We(t);case void 0:return console.log(qe()),0;default:return console.error(R.danger(Y.cli.unknownCommand(r))),console.log(qe()),1}}Je().then(e=>{process.exitCode=e}).catch(e=>{console.error(R.danger(e instanceof Error?e.message:String(e))),process.exitCode=1});export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yummaui",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Add Yumma UI components to your project.",
5
5
  "keywords": [
6
6
  "yummacss",
@@ -12,7 +12,7 @@
12
12
  "homepage": "https://yummacss.com/ui",
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/yummacss/yummui.git"
15
+ "url": "git+https://github.com/yummacss/yummaui.git"
16
16
  },
17
17
  "license": "MIT",
18
18
  "author": "Renildo Pereira",
@@ -20,12 +20,16 @@
20
20
  "bin": {
21
21
  "yummaui": "./dist/cli.mjs"
22
22
  },
23
+ "engines": {
24
+ "node": ">=20.12"
25
+ },
23
26
  "files": [
24
27
  "dist"
25
28
  ],
26
29
  "dependencies": {
27
- "@clack/prompts": "^0.11.0",
28
- "picocolors": "^1.1.1"
30
+ "@clack/prompts": "^1.8.1",
31
+ "fastest-levenshtein": "^1.0.16",
32
+ "magicast": "^0.5.5"
29
33
  },
30
34
  "devDependencies": {
31
35
  "@biomejs/biome": "^2.4.1",