yummaui 0.0.1 → 0.1.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/README.md +4 -0
- package/dist/cli.mjs +7 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,14 +44,18 @@ Pass `--force` to overwrite an existing config.
|
|
|
44
44
|
pnpm dlx yummaui add button
|
|
45
45
|
pnpm dlx yummaui add dialog tooltip
|
|
46
46
|
pnpm dlx yummaui add dialog-sign-in
|
|
47
|
+
pnpm dlx yummaui add --all
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
Components and blocks share one namespace. A component lands under its own name, so `add button` gives you `button.tsx`; a block keeps its whole id, so `add dialog-sign-in` gives you `dialog-sign-in.tsx` and the file still says what it is.
|
|
50
51
|
|
|
52
|
+
`--all` copies every component in one go. It is a flag rather than a name, because `add all` would read as though the registry contained a component called "all". Components only: a block is a specific composition, and pulls the components it is built from anyway, so name a block when you want one.
|
|
53
|
+
|
|
51
54
|
There is no way to ask for an example, deliberately. The difference between `autocomplete` and its large demo is `size="lg"` — a prop you pass, not a second file to own and keep in sync.
|
|
52
55
|
|
|
53
56
|
| Option | |
|
|
54
57
|
| --- | --- |
|
|
58
|
+
| `-a, --all` | Add every component |
|
|
55
59
|
| `--overwrite` | Replace files that already exist |
|
|
56
60
|
| `-y, --yes` | Skip prompts and take the defaults |
|
|
57
61
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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,writeFileSync as a}from"node:fs";import{dirname as o,join as s,relative as c,resolve as l}from"node:path";import*as u from"@clack/prompts";var d=`0.0
|
|
3
|
-
`)}`);let
|
|
4
|
-
`)}`)}if(
|
|
5
|
-
`));let s=await u.text({message:`Where should components go?`,placeholder:`components/ui`,defaultValue:`components/ui`});if(u.isCancel(s))return
|
|
2
|
+
import e from"picocolors";import{spawnSync as t}from"node:child_process";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{dirname as o,join as s,relative as c,resolve as l}from"node:path";import*as u from"@clack/prompts";var d=`0.1.0`;const f=`https://yummacss.com/ui/r`;var p=class extends Error{};async function m(e){let t;try{t=await fetch(e,{headers:{accept:`application/json`}})}catch(t){throw new p(`Could not reach the registry at ${e}. Are you online?`,{cause:t})}if(t.status===404)throw new p(`Not found: ${e}`);if(!t.ok)throw new p(`Registry returned ${t.status} for ${e}`);try{return await t.json()}catch(t){throw new p(`Registry sent invalid JSON from ${e}`,{cause:t})}}function h(e){return m(`${e}/index.json`)}function g(e,t){return m(`${e}/${t}.json`)}const _=`yummaui.json`,v={"pnpm-lock.yaml":`pnpm`,"bun.lockb":`bun`,"bun.lock":`bun`,"yarn.lock":`yarn`,"package-lock.json":`npm`};function y(e=process.cwd()){let t=l(e);for(;;){if(n(s(t,`package.json`)))return t;let e=o(t);if(e===t)return null;t=e}}function b(e){try{return JSON.parse(i(s(e,`package.json`),`utf8`))}catch{return{}}}function x(e){for(let[t,r]of Object.entries(v))if(n(s(e,t)))return r;let t=b(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 S(e){let t=b(e),r={...t.dependencies,...t.devDependencies};return r.next?[`app`,`src/app`].some(t=>n(s(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 C(e){for(let t of[`tsconfig.json`,`jsconfig.json`]){let r=s(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 w(e){return s(e,_)}function T(e){let t=w(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??f}}catch{return null}}function E(e,t){a(w(e),`${JSON.stringify(t,null,` `)}\n`)}function D(e,t){let n=b(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 O(e,t){return{command:e,args:e===`npm`?[`install`,...t]:[`add`,...t]}}function k(e=y()){switch(e?x(e):`npm`){case`pnpm`:return`pnpm dlx yummaui`;case`yarn`:return`yarn dlx yummaui`;case`bun`:return`bunx yummaui`;default:return`npx yummaui`}}function A(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 j(e,t,n){return n===`base`?`${t}.tsx`:`${e}.tsx`}function M(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 N(i){let{names:l,options:d}=A(i),f=y();if(!f)return u.log.error(`No package.json found. Run this inside a project.`),1;let m=f,v=T(m);if(!v)return u.log.error(`No ${_} found. Run ${e.cyan(`${k(m)} init`)} first.`),1;let{registry:b,componentsDir:S}=v;if(l.length===0&&!d.all)return u.log.error(`Nothing to add. Try: ${k(m)} add button`),1;u.intro(e.bgCyan(e.black(` Yumma UI `)));let C,w=u.spinner();w.start(`Fetching registry`);try{C=await h(v.registry)}catch(e){return w.stop(`Registry unavailable`,1),u.log.error(e instanceof p?e.message:String(e)),1}w.stop(`${C.components.length} components, ${C.blocks.length} blocks available`);let E=M(C,l,{all:d.all});if(`unknown`in E)return u.log.error(`Unknown component or block ${e.bold(E.unknown)}.`),E.unknown===`all`?u.log.info(`Every component is ${e.cyan(`--all`)}.`):F(C,E.unknown),1;let N=E.ids,P=[],I=new Map,L=new Set;async function R(e,t){if(L.has(e))return!0;L.add(e);let i;try{i=await g(b,e)}catch(e){return u.log.error(e instanceof p?e.message:String(e)),!1}for(let e of i.registryDependencies)if(!await R(e,!1))return!1;let l=s(m,S,j(i.id,i.component,i.variant)),f=c(m,l).replace(/\\/g,`/`);if(n(l)&&!d.overwrite){if(!t||d.yes)return u.log.warn(`Skipped ${f} (already exists)`),!0;let e=await u.confirm({message:`${f} already exists. Overwrite?`,initialValue:!1});if(u.isCancel(e))return u.cancel(`Cancelled.`),!1;if(!e)return u.log.warn(`Skipped ${f}`),!0}let h=i.files[0];if(!h)return u.log.error(`${e} has no files.`),!1;r(o(l),{recursive:!0}),a(l,h.content),P.push(f);for(let e of i.dependencies)I.set(e.name,e.version);return!0}for(let e of N)if(!await R(e,!0))return 1;if(P.length===0)return u.outro(`Nothing written.`),0;u.log.success(`Added\n${P.map(e=>` ${e}`).join(`
|
|
3
|
+
`)}`);let z=D(m,[...I].map(([e,t])=>({name:e,version:t}))),B=[...I.keys()].filter(e=>!z.some(t=>t.name===e));if(I.size>0){let t=[...B.map(t=>` ${e.green(`✔`)} ${t} ${e.dim(`already installed`)}`),...z.map(t=>` ${e.yellow(`+`)} ${t.name}@${t.version}`)];u.log.info(`Dependencies\n${t.join(`
|
|
4
|
+
`)}`)}if(z.length>0){let n=x(m),r=z.map(e=>`${e.name}@${e.version}`),i=d.yes;if(!i){let t=await u.confirm({message:`Install ${z.length} missing package${z.length>1?`s`:``} with ${e.bold(n)}?`});if(u.isCancel(t))return u.cancel(`Cancelled.`),1;i=t}if(i){let{command:e,args:i}=O(n,r),a=t(e,i,{cwd:m,stdio:`inherit`,shell:process.platform===`win32`});if(a.status!==0)return u.log.error(`${e} exited with ${a.status??`an error`}.`),1}else u.log.info(`Install manually:\n ${x(m)} add ${r.join(` `)}`)}return u.outro(`Done.`),0}function P(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 F(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:P(e,t)})).filter(e=>e.score<=2).sort((e,t)=>e.score-t.score).slice(0,5).map(e=>e.name);n.length?u.log.info(`Did you mean: ${n.join(`, `)}`):u.log.info(`Run ${k()} list to see everything.`)}async function I(t){let n=t.includes(`--force`),r=y();if(!r)return u.log.error(`No package.json found. Run this inside a project.`),1;if(u.intro(e.bgCyan(e.black(` Yumma UI `))),T(r)&&!n)return u.log.warn(`${_} already exists. Use --force to overwrite.`),u.outro(`Nothing to do.`),0;let i=S(r),a=x(r),o=C(r);u.log.step([i?`Detected ${e.bold(i)}`:`No framework detected`,`Detected ${e.bold(a)}`].join(`
|
|
5
|
+
`));let s=await u.text({message:`Where should components go?`,placeholder:`components/ui`,defaultValue:`components/ui`});if(u.isCancel(s))return L();let c=!1;if(o){let t=await u.confirm({message:`Use the ${e.bold(`"${o}/"`)} import alias?`});if(u.isCancel(t))return L();c=t}return E(r,{componentsDir:String(s),alias:c&&o?`${o}/${s}`:null,registry:f}),u.log.success(`Wrote ${e.bold(w(r))}`),u.outro(`Next: ${e.cyan(`${k(r)} add button`)}`),0}function L(){return u.cancel(`Cancelled.`),1}async function R(t){let n=t.find(e=>!e.startsWith(`-`)),r=y(),i=r&&T(r)?.registry||f,a;try{a=await h(i)}catch(t){return console.error(e.red(t instanceof p?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(`${k(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(`${k(r)} list <component>`)} to see its blocks\n`),0}const z=`
|
|
6
6
|
${e.bold(`yummaui`)} ${e.dim(`v${d}`)}
|
|
7
7
|
|
|
8
8
|
Copies Yumma UI components into your project. Never a dependency.
|
|
@@ -16,6 +16,7 @@ ${e.bold(`Commands`)}
|
|
|
16
16
|
list [component] Browse what is available
|
|
17
17
|
|
|
18
18
|
${e.bold(`Options`)}
|
|
19
|
+
-a, --all Add every component
|
|
19
20
|
--overwrite Replace files that already exist
|
|
20
21
|
-y, --yes Skip prompts, take the defaults
|
|
21
22
|
-h, --help Show this
|
|
@@ -24,5 +25,6 @@ ${e.bold(`Options`)}
|
|
|
24
25
|
${e.bold(`Examples`)}
|
|
25
26
|
npx yummaui add button
|
|
26
27
|
npx yummaui add dialog tooltip
|
|
28
|
+
npx yummaui add --all
|
|
27
29
|
npx yummaui list button
|
|
28
|
-
`;async function
|
|
30
|
+
`;async function B(){let t=process.argv.slice(2),n=t[0];if(!n||n===`-h`||n===`--help`)return console.log(z),0;if(n===`--version`||n===`-V`)return console.log(d),0;let r=t.slice(1);switch(n){case`init`:return I(r);case`add`:return N(r);case`list`:case`ls`:return R(r);default:return console.error(e.red(`Unknown command "${n}".`)),console.log(z),1}}B().then(e=>{process.exitCode=e}).catch(t=>{console.error(e.red(t instanceof Error?t.message:String(t))),process.exitCode=1});export{};
|