ui-thing 0.2.9 → 0.3.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 (38) hide show
  1. package/.claude/settings.local.json +5 -0
  2. package/.github/workflows/main.yml +7 -4
  3. package/.github/workflows/test.yml +7 -4
  4. package/.prettierrc +1 -1
  5. package/CHANGELOG.md +52 -0
  6. package/README.md +208 -21
  7. package/bun.lock +171 -134
  8. package/dist/index.js +28 -25
  9. package/dist/index.js.map +1 -1
  10. package/package.json +15 -14
  11. package/src/commands/add.ts +41 -12
  12. package/src/commands/block.ts +5 -3
  13. package/src/commands/list.ts +48 -0
  14. package/src/commands/prose.ts +7 -3
  15. package/src/commands/remove.ts +109 -0
  16. package/src/commands/theme.ts +5 -14
  17. package/src/commands/update.ts +81 -0
  18. package/src/index.ts +6 -0
  19. package/src/types.ts +12 -0
  20. package/src/utils/config.ts +9 -16
  21. package/src/utils/constants.ts +1 -0
  22. package/src/utils/fetchBlockCategories.ts +13 -11
  23. package/src/utils/fetchBlocks.ts +13 -11
  24. package/src/utils/fetchComponents.ts +13 -11
  25. package/src/utils/fetchProseComponents.ts +13 -11
  26. package/src/utils/installPackages.ts +30 -4
  27. package/src/utils/installValidator.ts +3 -3
  28. package/src/utils/logger.ts +9 -0
  29. package/src/utils/uiConfigPrompt.ts +3 -6
  30. package/tests/commands/add.test.ts +136 -0
  31. package/tests/commands/list.test.ts +111 -0
  32. package/tests/commands/remove.test.ts +151 -0
  33. package/tests/commands/update.test.ts +127 -0
  34. package/tests/utils/fetchBlockCategories.test.ts +14 -2
  35. package/tests/utils/fetchBlocks.test.ts +14 -2
  36. package/tests/utils/fetchComponents.test.ts +10 -4
  37. package/tests/utils/fetchProseComponents.test.ts +14 -2
  38. package/tests/utils/installPackages.test.ts +36 -3
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Er}from"commander";var lo="0.2.8";import U from"path";import{updateConfig as xo}from"c12/update";import{Command as we}from"commander";import{consola as K}from"consola";import k from"kleur";import N from"lodash";import X from"prompts";import{join as bo}from"path";import{loadConfig as ce}from"c12";import x from"fs-extra";import ne from"lodash";import{loadFile as ae,writeFile as ie}from"magicast";import{addNuxtModule as se}from"magicast/helpers";import le from"prompts";var F="ui-thing.config.ts",ho={theme:"zinc",tailwindCSSLocation:"assets/css/tailwind.css",componentsLocation:"components/Ui",composablesLocation:"composables",pluginsLocation:"plugins",utilsLocation:"utils",force:!0,useDefaultFilename:!0,packageManager:"npm"},po={theme:"zinc",tailwindCSSLocation:"app/assets/css/tailwind.css",componentsLocation:"app/components/Ui",composablesLocation:"app/composables",pluginsLocation:"app/plugins",utilsLocation:"app/utils",force:!0,useDefaultFilename:!0,packageManager:"npm"},uo=["tailwindcss","motion-v","@tailwindcss/vite","reka-ui","tailwind-variants","tailwind-merge","@nuxt/fonts","@nuxtjs/color-mode","@nuxt/icon","@vueuse/nuxt","@tailwindcss/forms"],mo=["typescript","tw-animate-css"],O=["prettier-plugin-tailwindcss","prettier","@ianvs/prettier-plugin-sort-imports"],fo=["@nuxtjs/color-mode","motion-v/nuxt","@vueuse/nuxt","@nuxt/icon","@nuxt/fonts"],C=[{title:"Npm",value:"npm"},{title:"Yarn",value:"yarn"},{title:"Pnpm",value:"pnpm"},{title:"Bun",value:"bun"}],T=[{title:"Zinc",value:"zinc"},{title:"Slate",value:"slate"},{title:"Stone",value:"stone"},{title:"Gray",value:"gray"},{title:"Neutral",value:"neutral"},{title:"Red",value:"red"},{title:"Rose",value:"rose"},{title:"Orange",value:"orange"},{title:"Green",value:"green"},{title:"Blue",value:"blue"},{title:"Yellow",value:"yellow"},{title:"Violet",value:"violet"}];import re from"fs";function ko(){try{let o=JSON.parse(re.readFileSync("package.json","utf-8")),r=o.dependencies?.nuxt||o.devDependencies?.nuxt;if(r)return/^[~^>=<\s]*4/.test(r)?4:3}catch{return 4}return 4}import go from"kleur";import te from"prompts";var yo=async o=>{let r=await te([{name:"theme",type:"autocomplete",message:"Which theme do you want to start with?",choices:T},{name:"tailwindCSSLocation",type:"text",message:"Where is your tailwind.css file located?",initial:(e,t)=>o==3?"assets/css/tailwind.css":"app/assets/css/tailwind.css"},{name:"componentsLocation",type:"text",message:"Where should your components be stored?",initial:(e,t)=>o==3?"components/Ui":"app/components/Ui"},{name:"composablesLocation",type:"text",message:"Where should your composables be stored?",initial:(e,t)=>o==3?"composables":"app/composables"},{name:"pluginsLocation",type:"text",message:"Where should your plugins be stored?",initial:(e,t)=>o==3?"plugins":"app/plugins"},{name:"utilsLocation",type:"text",message:"Where should your utils be stored?",initial:(e,t)=>o==3?"utils":"app/utils"},{name:"force",type:"confirm",message:"Should we just replace component files if they already exist?",initial:!0},{name:"useDefaultFilename",type:"confirm",message:"Would you like to use the default filename when adding components?",initial:!0},{name:"packageManager",type:"select",message:"Which package manager do you use?",choices:C}]);return!r||Object.keys(r).length<9?(console.log(go.red(go.bold("Incomplete configuration submitted. Exiting..."))),process.exit(0)):r};var vo=process.cwd(),u=async o=>{let r=x.existsSync(F),e={},t=Number(o?.nuxtVersion)||ko();if(!r||o?.force){if(e=o?.yes?t===4?po:ho:await yo(t),await x.writeFile(F,`export default ${JSON.stringify(e,null,2)}`),e.packageManager==="pnpm"){let n=x.existsSync(".npmrc"),a=!0;if(n){let{confirmCreateNpmrc:i}=await le({type:"confirm",name:"confirmCreateNpmrc",message:"A .npmrc file already exists. Overwrite it?",initial:!1});a=i}a&&await x.writeFile(".npmrc",`shamefully-hoist=true
3
- strict-peer-dependencies=false
4
- `)}}else e=(await ce({configFile:F.replace(".ts","")})).config;return ne.isEmpty(e)?u({force:!0}):(de(e),e)},de=o=>{let r=(e,t=!1)=>{e&&(t?x.ensureDirSync(e):x.ensureFileSync(e))};r(o.tailwindCSSLocation),r(o.pluginsLocation,!0),r(o.componentsLocation,!0),r(o.composablesLocation,!0),r(o.utilsLocation,!0)},A=async o=>{if(!o)return;let r=typeof o=="string"?[o]:o,e=await ae(bo(vo,"nuxt.config.ts"));r.forEach(t=>se(e,t)),await ie(e,bo(vo,"nuxt.config.ts"))};var g=async()=>{let o=await u(),r={nuxtVersion:3,theme:"string",tailwindCSSLocation:"string",componentsLocation:"string",composablesLocation:"string",utilsLocation:"string",force:!0,useDefaultFilename:!0,packageManager:"string"},e=[];for(let t of Object.keys(r))o[t]===void 0&&e.push(t);return!(e.length>1)};import he from"axios";import pe from"dotenv";import ue from"ora";pe.config();var wo=async()=>{let o=ue("Fetching components...").start(),{data:r}=await he.get(process.env.COMPONENTS_API||"https://uithing.com/api/components");return o.succeed("Components fetched."),r};import V from"fs";var y=async o=>{try{return await V.promises.access(o,V.constants.F_OK||V.constants.W_OK),!0}catch{return!1}};import{execa as z}from"execa";import P from"lodash";import me from"ora";var f=async(o,r,e)=>{typeof r=="string"&&(r=[r]),typeof e=="string"&&(e=[e]);let t=me("Installing dependencies...").start();!P.isUndefined(r)&&!P.isEmpty(r)&&await z(o,[o==="yarn"?"add":"install",...r]),t.text="Installing dev dependencies...",!P.isUndefined(e)&&!P.isEmpty(e)&&await z(o,[o==="yarn"?"add":"install","-D",...e]),t.text="Running nuxt prepare...",await z`npx -y nuxt prepare`,t.succeed("Installed dependencies!")};import fe from"prompts";var Co=async o=>{let r={yup:["yup","@vee-validate/yup"],zod:["zod","@vee-validate/zod"],joi:["joi","@vee-validate/joi"],valibot:["valibot","@vee-validate/valibot"]},{validator:e}=await fe({type:"select",name:"validator",message:"Choose the validator package to use with Vee Validate: ",choices:[{title:"Yup",value:"yup"},{title:"Zod",value:"zod"},{title:"Joi",value:"joi"},{title:"Valibot",value:"valibot"}]});if(!e){console.log("No validator package selected");return}return console.log(`Selected ${e} as the validator package`),r[e]&&await f(o,r[e]),e};import ke from"boxen";import ge from"figlet";var ye=(o,r,e={})=>{let{box:t,figletFont:n}=e,a=ge.textSync(o,{font:n||"Standard"}),l=ke(a,{...{borderColor:"greenBright",padding:1,borderStyle:"round",titleAlignment:"center"},...t});return r?`${l}
5
- ${r}`:l},m=(o,r,e)=>{console.log(`
6
- `+ye(o,r,e))};import be from"prompts";var L=async(o,r=[])=>{if(o)return r.map(t=>t.value);let{components:e}=await be({type:"autocompleteMultiselect",name:"components",message:"Select the components you want to add",choices:r.map(t=>({title:t.name,value:t.value}))});return e};import q from"fs";import ve from"path";var S=async(o,r)=>{if(!await y(o)){let t=ve.dirname(o);q.existsSync(t)||q.mkdirSync(t,{recursive:!0})}q.writeFileSync(o,r)};var Z=[],_=process.cwd(),Y=o=>Z.find(r=>r.value.toLowerCase()===o.toLowerCase());async function So(o,r,e,t){if(await y(o)&&!e){let{value:a}=await X({type:"confirm",name:"value",message:t,initial:!1});if(!a)return K.info(`Skipped: ${k.cyan(U.basename(o))}`),!1}return await S(o,r),!0}async function J(o,r,e,t){for(let n of r){let a=U.join(_,e,n.fileName);await So(a,n.fileContent,t,`The ${o} file ${k.bold(n.fileName)} already exists. Overwrite?`)}}var Ce=async(o,r)=>{let e=await u();await g()||(e=await u({force:!0})),N.isEmpty(e)&&(K.info("Config file not set. Exiting..."),process.exit(0)),Z=await wo();let t=o;if(t.length===0){let c=await L(r.all,Z);(!c||c.length===0)&&(K.info("No components selected. Exiting..."),process.exit(0)),t=c}let n=t.filter(c=>!Y(c));n.length>0&&K.error(`Not found: ${k.bgRed(n.join(", "))}`);let a=t.map(c=>Y(c)).filter(Boolean);for(let c of[...a])c.components&&c.components.forEach(p=>{a.find(h=>h.value===p)||a.push(Y(p))});for(let c of a)for(let p of c.files){let h=e.componentsLocation,s=U.join(_,h,p.fileName);if(!e.useDefaultFilename){let{value:b}=await X({type:"text",name:"value",message:`Where should we add the file ${k.cyan(p.fileName)}?`,initial:h});b&&(h=b,s=U.join(_,h,p.fileName))}await So(s,p.fileContent,e.force,`The file ${k.bold(p.fileName)} already exists. Overwrite?`)&&((c.value==="vue-sonner"||c.value==="sonner")&&await xe(),c.value==="datatable"&&await Se(),await J("utils",c.utils,e.utilsLocation,e.force),await J("composables",c.composables,e.composablesLocation,e.force),await J("plugins",c.plugins,e.pluginsLocation??"",e.force))}await A(N.uniq(a.flatMap(c=>c.nuxtModules||[])));let i=N.uniq(a.flatMap(c=>c.deps||[])),l=N.uniq(a.flatMap(c=>c.devDeps||[]));if(i.length>0||l.length>0)if(r.all)await f(e.packageManager,i,l);else{let{confirmInstall:c}=await X({type:"confirm",name:"confirmInstall",message:`Install packages: ${k.cyan([...i,...l].join(", "))}?`,initial:!0});c&&await f(e.packageManager,i,l)}a.some(c=>c.askValidator)&&await Co(e.packageManager),m("All Done!",`Run the ${k.cyan("ui-thing@latest --help")} command to learn more.
7
- `,{box:{title:"Components Added"}});let d=N.compact(a.flatMap(c=>c.instructions));d.length>0&&(console.log(""),console.log(k.bgCyan(" Instructions ")),d.forEach(c=>console.log(`${k.cyan("-")} ${c}`)))},Eo=new we().name("add").command("add").description("Add a list of components to your project.").option("-a --all","Add all components to your project.",!1).argument("[componentNames...]","Components that you want to add.").action(Ce);async function xe(){await xo({configFile:"nuxt.config",cwd:_,onUpdate(o){o.imports||={imports:[]},o.imports.imports.find(r=>r.from==="vue-sonner"&&r.name==="toast")||o.imports.imports.push({from:"vue-sonner",name:"toast",as:"useSonner"})}})}async function Se(){await xo({configFile:"nuxt.config",cwd:_,onUpdate(o){o.app||={head:{script:[]}},["https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.12/pdfmake.min.js","https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.12/vfs_fonts.min.js"].forEach(e=>{o.app.head.script.find(t=>t.src===e)||o.app.head.script.push({src:e,defer:!0})})}})}import{spawnSync as Fe}from"child_process";import Q from"path";import{Command as Oe}from"commander";import{consola as E}from"consola";import D from"kleur";import No from"lodash";import R from"prompts";import Ee from"axios";import Ie from"dotenv";import Te from"ora";Ie.config();var Io=async()=>{let o=Te("Fetching block categories...").start(),{data:r}=await Ee.get(process.env.BLOCK_CATEGORIES_API||"https://uithing.com/api/blocks/categories");return o.succeed("Block categories fetched."),r};import Ne from"axios";import _e from"dotenv";import Me from"ora";_e.config();var To=async()=>{let o=Me("Fetching blocks...").start(),{data:r}=await Ne.get(process.env.BLOCKS_API||"https://uithing.com/api/blocks");return o.succeed("Blocks fetched."),r};var j=[],_o=process.cwd();function Ae(o){return o.componentsLocation?.startsWith("app/")?"app/components/Blocks":"components/Blocks"}async function Pe(o,r,e,t){if(await y(o)&&!e){let{value:a}=await R({type:"confirm",name:"value",message:t,initial:!1});if(!a)return E.info(`Skipped: ${D.cyan(Q.basename(o))}`),!1}return await S(o,r),!0}var Le=async(o,r)=>{let e=await u();await g()||(e=await u({force:!0})),No.isEmpty(e)&&(E.info("Config file not set. Exiting..."),process.exit(0));let t=await Io(),n=r.category;if(!n&&t?.length){let{category:s}=await R({type:"select",name:"category",message:"Choose a block category",choices:[{title:"All",value:"all"},...t.map(w=>({title:w,value:w}))],initial:0});n=s}j=await To();let a=j;n&&n!=="all"&&(a=j.filter(s=>s.category===n),a.length===0&&(E.warn(`No blocks found for category ${D.cyan(n)}. Falling back to all.`),a=j));let{selectedBlocks:i}=await R({type:"autocompleteMultiselect",name:"selectedBlocks",message:"Select the blocks you want to add",choices:a.map(s=>({title:s.name,value:s}))});(!i||i.length===0)&&(E.info("No blocks selected. Exiting..."),process.exit(0));let l=i,d=Ae(e),{blocksDir:c}=await R({type:"text",name:"blocksDir",message:"Where should we add the blocks?",initial:d}),p=c||d;for(let s of l){let w=Q.join(p,s.path),b=Q.join(_o,w);await Pe(b,s.file,e.force,`The block file ${D.bold(s.fileName)} already exists. Overwrite?`)}let h=No.uniq(l.flatMap(s=>s.components||[]));if(h.length>0){E.info(`Adding ${h.length} component(s) required by blocks...`);let s=Fe("npx",["ui-thing@latest","add",...h],{cwd:_o,stdio:"inherit"});s.error&&E.error("Failed to add components:",s.error.message)}m("Blocks added!",`Run the ${D.cyan("ui-thing@latest --help")} command to learn more.
8
- `,{box:{title:"Blocks Added"}})},Mo=new Oe().name("block").command("block").description("Add UI Thing blocks to your project.").option("-c --category <category>","Filter blocks by category before selection").action(Le);import ar from"path";import{updateConfig as ir}from"c12/update";import{Command as sr}from"commander";import Do from"fs-extra";import to from"kleur";import lr from"ora";var Ke=`@import "tailwindcss";
2
+ import{Command as Vr}from"commander";var go="0.3.0";import V from"path";import{updateConfig as Io}from"c12/update";import{Command as _e}from"commander";import{consola as A}from"consola";import E from"kleur";import M from"lodash";import H from"prompts";import{join as Co}from"path";import{loadConfig as pe}from"c12";import S from"fs-extra";import me from"lodash";import{loadFile as he,writeFile as ue}from"magicast";import{addNuxtModule as fe}from"magicast/helpers";var U="ui-thing.config.ts",K={theme:"zinc",tailwindCSSLocation:"assets/css/tailwind.css",componentsLocation:"components/Ui",composablesLocation:"composables",pluginsLocation:"plugins",utilsLocation:"utils",force:!0,useDefaultFilename:!0,packageManager:"npm"},D={theme:"zinc",tailwindCSSLocation:"app/assets/css/tailwind.css",componentsLocation:"app/components/Ui",composablesLocation:"app/composables",pluginsLocation:"app/plugins",utilsLocation:"app/utils",force:!0,useDefaultFilename:!0,packageManager:"npm"},yo=["tailwindcss","motion-v","@tailwindcss/vite","reka-ui","tailwind-variants","tailwind-merge","@nuxt/fonts","@nuxtjs/color-mode","@nuxt/icon","@vueuse/nuxt","@tailwindcss/forms"],bo=["typescript","tw-animate-css"],j=["prettier-plugin-tailwindcss","prettier","@ianvs/prettier-plugin-sort-imports"],vo=["@nuxtjs/color-mode","motion-v/nuxt","@vueuse/nuxt","@nuxt/icon","@nuxt/fonts"],y=[{title:"Npm",value:"npm"},{title:"Yarn",value:"yarn"},{title:"Pnpm",value:"pnpm"},{title:"Bun",value:"bun"},{title:"Deno",value:"deno"}],_=[{title:"Zinc",value:"zinc"},{title:"Slate",value:"slate"},{title:"Stone",value:"stone"},{title:"Gray",value:"gray"},{title:"Neutral",value:"neutral"},{title:"Red",value:"red"},{title:"Rose",value:"rose"},{title:"Orange",value:"orange"},{title:"Green",value:"green"},{title:"Blue",value:"blue"},{title:"Yellow",value:"yellow"},{title:"Violet",value:"violet"}];import le from"fs";function R(){try{let o=JSON.parse(le.readFileSync("package.json","utf-8")),e=o.dependencies?.nuxt||o.devDependencies?.nuxt;if(e)return/^[~^>=<\s]*4/.test(e)?4:3}catch{return 4}return 4}import de from"prompts";import{consola as F}from"consola";var d={info:(o,...e)=>F.info(o,...e),error:(o,...e)=>F.error(o,...e),warn:(o,...e)=>F.warn(o,...e),success:(o,...e)=>F.success(o,...e),log:(o,...e)=>F.log(o,...e)};var wo=async o=>{let e=await de([{name:"theme",type:"autocomplete",message:"Which theme do you want to start with?",choices:_},{name:"tailwindCSSLocation",type:"text",message:"Where is your tailwind.css file located?",initial:(r,n)=>o==3?"assets/css/tailwind.css":"app/assets/css/tailwind.css"},{name:"componentsLocation",type:"text",message:"Where should your components be stored?",initial:(r,n)=>o==3?"components/Ui":"app/components/Ui"},{name:"composablesLocation",type:"text",message:"Where should your composables be stored?",initial:(r,n)=>o==3?"composables":"app/composables"},{name:"pluginsLocation",type:"text",message:"Where should your plugins be stored?",initial:(r,n)=>o==3?"plugins":"app/plugins"},{name:"utilsLocation",type:"text",message:"Where should your utils be stored?",initial:(r,n)=>o==3?"utils":"app/utils"},{name:"force",type:"confirm",message:"Should we just replace component files if they already exist?",initial:!0},{name:"useDefaultFilename",type:"confirm",message:"Would you like to use the default filename when adding components?",initial:!0},{name:"packageManager",type:"select",message:"Which package manager do you use?",choices:y}]);return!e||Object.keys(e).length<9?(d.error("Incomplete configuration submitted. Exiting..."),process.exit(1)):e};var xo=process.cwd(),h=async o=>{let e=S.existsSync(U),r={},n=Number(o?.nuxtVersion)||R();if(!e||o?.force){if(r=o?.yes?n===4?D:K:await wo(n),await S.writeFile(U,`export default ${JSON.stringify(r,null,2)}`),r.packageManager==="pnpm"){let i=["shamefully-hoist=true","strict-peer-dependencies=false"],a="";S.existsSync(".npmrc")&&(a=await S.readFile(".npmrc","utf-8"));let l=i.filter(c=>!a.includes(c));if(l.length>0){let c=a&&!a.endsWith(`
3
+ `)?`
4
+ `:"";await S.writeFile(".npmrc",a+c+l.join(`
5
+ `)+`
6
+ `)}}}else r=(await pe({configFile:U.replace(".ts","")})).config;return me.isEmpty(r)?h({force:!0}):(ke(r),r)},ke=o=>{let e=(r,n=!1)=>{r&&(n?S.ensureDirSync(r):S.ensureFileSync(r))};e(o.tailwindCSSLocation),e(o.pluginsLocation,!0),e(o.componentsLocation,!0),e(o.composablesLocation,!0),e(o.utilsLocation,!0)},B=async o=>{if(!o)return;let e=typeof o=="string"?[o]:o,r=await he(Co(xo,"nuxt.config.ts"));e.forEach(n=>fe(r,n)),await ue(r,Co(xo,"nuxt.config.ts"))};var b=async()=>{let o=await h(),e={nuxtVersion:3,theme:"string",tailwindCSSLocation:"string",componentsLocation:"string",composablesLocation:"string",utilsLocation:"string",force:!0,useDefaultFilename:!0,packageManager:"string"},r=[];for(let n of Object.keys(e))o[n]===void 0&&r.push(n);return!(r.length>1)};import ge from"axios";import{consola as ye}from"consola";import be from"dotenv";import ve from"ora";be.config();var v=async()=>{let o=ve("Fetching components...").start();try{let{data:e}=await ge.get(process.env.COMPONENTS_API||"https://uithing.com/api/components");return o.succeed("Components fetched."),e}catch{o.fail("Failed to fetch components."),ye.error("Could not reach the UI Thing API. Check your network connection."),process.exit(1)}};import eo from"fs";var k=async o=>{try{return await eo.promises.access(o,eo.constants.F_OK||eo.constants.W_OK),!0}catch{return!1}};import{execa as $}from"execa";import W from"lodash";import we from"ora";var Ce={yarn:"add",bun:"add",pnpm:"add",npm:"install",deno:"add"},xe={yarn:"-D",bun:"-D",pnpm:"-D",npm:"-D",deno:"--dev"},So=(o,e)=>o==="deno"?e.map(r=>r.startsWith("npm:")?r:`npm:${r}`):e,g=async(o,e,r)=>{typeof e=="string"&&(e=[e]),typeof r=="string"&&(r=[r]);let n=Ce[o]??"install",i=xe[o]??"-D",a=we("Installing dependencies...").start();!W.isUndefined(e)&&!W.isEmpty(e)&&await $(o,[n,...So(o,e)]),a.text="Installing dev dependencies...",!W.isUndefined(r)&&!W.isEmpty(r)&&await $(o,[n,i,...So(o,r)]),a.text="Running nuxt prepare...",o==="deno"?await $("deno",["run","-A","npm:nuxt","prepare"]):await $`npx -y nuxt prepare`,a.succeed("Installed dependencies!")};import Se from"prompts";var Eo=async o=>{let e={yup:["yup","@vee-validate/yup"],zod:["zod","@vee-validate/zod"],joi:["joi","@vee-validate/joi"],valibot:["valibot","@vee-validate/valibot"]},{validator:r}=await Se({type:"select",name:"validator",message:"Choose the validator package to use with Vee Validate: ",choices:[{title:"Yup",value:"yup"},{title:"Zod",value:"zod"},{title:"Joi",value:"joi"},{title:"Valibot",value:"valibot"}]});if(!r){d.warn("No validator package selected");return}return d.info(`Selected ${r} as the validator package`),e[r]&&await g(o,e[r]),r};import Ee from"boxen";import Ie from"figlet";var Ne=(o,e,r={})=>{let{box:n,figletFont:i}=r,a=Ie.textSync(o,{font:i||"Standard"}),c=Ee(a,{...{borderColor:"greenBright",padding:1,borderStyle:"round",titleAlignment:"center"},...n});return e?`${c}
7
+ ${e}`:c},f=(o,e,r)=>{console.log(`
8
+ `+Ne(o,e,r))};import Te from"prompts";var G=async(o,e=[])=>{if(o)return e.map(n=>n.value);let{components:r}=await Te({type:"autocompleteMultiselect",name:"components",message:"Select the components you want to add",choices:e.map(n=>({title:n.name,value:n.value}))});return r};import ro from"fs";import Pe from"path";var w=async(o,e)=>{if(!await k(o)){let n=Pe.dirname(o);ro.existsSync(n)||ro.mkdirSync(n,{recursive:!0})}ro.writeFileSync(o,e)};var io=[],L=process.cwd(),to=o=>io.find(e=>e.value.toLowerCase()===o.toLowerCase());async function No(o,e,r,n){if(await k(o)&&!r){let{value:a}=await H({type:"confirm",name:"value",message:n,initial:!1});if(!a)return A.info(`Skipped: ${E.cyan(V.basename(o))}`),!1}return await w(o,e),!0}async function no(o,e,r,n){for(let i of e){let a=V.join(L,r,i.fileName);await No(a,i.fileContent,n,`The ${o} file ${E.bold(i.fileName)} already exists. Overwrite?`)}}var Fe=async(o,e)=>{let r;if(e.skipConfig){let p=R()===4?D:K,u=e.packageManager;if(!u){let{packageManager:m}=await H({type:"select",name:"packageManager",message:"Which package manager are you using?",choices:y});u=m??"npm"}r={...p,packageManager:u}}else r=await h(),await b()||(r=await h({force:!0})),M.isEmpty(r)&&(A.error("Config file not set. Exiting..."),process.exit(1));io=await v();let n=o;if(n.length===0){let t=await G(e.all,io);(!t||t.length===0)&&(A.info("No components selected. Exiting..."),process.exit(0)),n=t}let i=n.filter(t=>!to(t));i.length>0&&A.error(`Not found: ${E.bgRed(i.join(", "))}`);let a=n.map(t=>to(t)).filter(Boolean);for(let t of[...a])t.components&&t.components.forEach(p=>{a.find(u=>u.value===p)||a.push(to(p))});for(let t of a)for(let p of t.files){let u=r.componentsLocation,m=V.join(L,u,p.fileName);if(!r.useDefaultFilename){let{value:x}=await H({type:"text",name:"value",message:`Where should we add the file ${E.cyan(p.fileName)}?`,initial:u});x&&(u=x,m=V.join(L,u,p.fileName))}await No(m,p.fileContent,r.force,`The file ${E.bold(p.fileName)} already exists. Overwrite?`)&&((t.value==="vue-sonner"||t.value==="sonner")&&await Me(),t.value==="datatable"&&await Ae(),await no("utils",t.utils,r.utilsLocation,r.force),await no("composables",t.composables,r.composablesLocation,r.force),await no("plugins",t.plugins,r.pluginsLocation??"",r.force))}await B(M.uniq(a.flatMap(t=>t.nuxtModules||[])));let l=M.uniq(a.flatMap(t=>t.deps||[])),c=M.uniq(a.flatMap(t=>t.devDeps||[]));if(l.length>0||c.length>0)if(e.all)await g(r.packageManager,l,c);else{let{confirmInstall:t}=await H({type:"confirm",name:"confirmInstall",message:`Install packages: ${E.cyan([...l,...c].join(", "))}?`,initial:!0});t&&await g(r.packageManager,l,c)}a.some(t=>t.askValidator)&&await Eo(r.packageManager),f("All Done!",`Run the ${E.cyan("ui-thing@latest --help")} command to learn more.
9
+ `,{box:{title:"Components Added"}}),a.filter(t=>t.docsPath).forEach(t=>A.info(`Docs: https://uithing.com${t.docsPath}`));let s=M.compact(a.flatMap(t=>t.instructions));s.length>0&&(d.info("Instructions:"),s.forEach(t=>d.info(`- ${t}`)))},To=new _e().name("add").command("add").description("Add a list of components to your project.").option("-a --all","Add all components to your project.",!1).option("--skip-config","Add components without a ui-thing config file. Uses auto-detected Nuxt defaults.").option("--package-manager <pm>","Package manager to use when --skip-config is set.").argument("[componentNames...]","Components that you want to add.").action(Fe);async function Me(){await Io({configFile:"nuxt.config",cwd:L,onUpdate(o){o.imports||={imports:[]},o.imports.imports.find(e=>e.from==="vue-sonner"&&e.name==="toast")||o.imports.imports.push({from:"vue-sonner",name:"toast",as:"useSonner"})}})}async function Ae(){await Io({configFile:"nuxt.config",cwd:L,onUpdate(o){o.app||={head:{script:[]}},["https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.12/pdfmake.min.js","https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.12/vfs_fonts.min.js"].forEach(r=>{o.app.head.script.find(n=>n.src===r)||o.app.head.script.push({src:r,defer:!0})})}})}import{spawnSync as $e}from"child_process";import ao from"path";import{Command as We}from"commander";import{consola as I}from"consola";import q from"kleur";import Fo from"lodash";import Y from"prompts";import Le from"axios";import{consola as Oe}from"consola";import Ue from"dotenv";import Ke from"ora";Ue.config();var Po=async()=>{let o=Ke("Fetching block categories...").start();try{let{data:e}=await Le.get(process.env.BLOCK_CATEGORIES_API||"https://uithing.com/api/blocks/categories");return o.succeed("Block categories fetched."),e}catch{o.fail("Failed to fetch block categories."),Oe.error("Could not reach the UI Thing API. Check your network connection."),process.exit(1)}};import De from"axios";import{consola as je}from"consola";import Re from"dotenv";import Be from"ora";Re.config();var _o=async()=>{let o=Be("Fetching blocks...").start();try{let{data:e}=await De.get(process.env.BLOCKS_API||"https://uithing.com/api/blocks");return o.succeed("Blocks fetched."),e}catch{o.fail("Failed to fetch blocks."),je.error("Could not reach the UI Thing API. Check your network connection."),process.exit(1)}};var z=[],Mo=process.cwd();function Ge(o){return o.componentsLocation?.startsWith("app/")?"app/components/Blocks":"components/Blocks"}async function He(o,e,r,n){if(await k(o)&&!r){let{value:a}=await Y({type:"confirm",name:"value",message:n,initial:!1});if(!a)return I.info(`Skipped: ${q.cyan(ao.basename(o))}`),!1}return await w(o,e),!0}var Ve=async(o,e)=>{let r=await h();await b()||(r=await h({force:!0})),Fo.isEmpty(r)&&(I.error("Config file not set. Exiting..."),process.exit(1));let n=await Po(),i=e.category;if(!i&&n?.length){let{category:m}=await Y({type:"select",name:"category",message:"Choose a block category",choices:[{title:"All",value:"all"},...n.map(T=>({title:T,value:T}))],initial:0});i=m}z=await _o();let a=z;i&&i!=="all"&&(a=z.filter(m=>m.category===i),a.length===0&&(I.warn(`No blocks found for category ${q.cyan(i)}. Falling back to all.`),a=z));let{selectedBlocks:l}=await Y({type:"autocompleteMultiselect",name:"selectedBlocks",message:"Select the blocks you want to add",choices:a.map(m=>({title:m.name,value:m}))});(!l||l.length===0)&&(I.info("No blocks selected. Exiting..."),process.exit(0));let c=l,s=Ge(r),{blocksDir:t}=await Y({type:"text",name:"blocksDir",message:"Where should we add the blocks?",initial:s}),p=t||s;for(let m of c){let T=ao.join(p,m.path),x=ao.join(Mo,T);await He(x,m.file,r.force,`The block file ${q.bold(m.fileName)} already exists. Overwrite?`)}let u=Fo.uniq(c.flatMap(m=>m.components||[]));if(u.length>0){I.info(`Adding ${u.length} component(s) required by blocks...`);let m=$e("npx",["ui-thing@latest","add",...u],{cwd:Mo,stdio:"inherit"});m.error?I.error("Failed to spawn component installer:",m.error.message):m.status!==0&&I.error(`Component installer exited with code ${m.status}`)}f("Blocks added!",`Run the ${q.cyan("ui-thing@latest --help")} command to learn more.
10
+ `,{box:{title:"Blocks Added"}})},Ao=new We().name("block").command("block").description("Add UI Thing blocks to your project.").option("-c --category <category>","Filter blocks by category before selection").action(Ve);import gr from"path";import{updateConfig as yr}from"c12/update";import{Command as br}from"commander";import $o from"fs-extra";import po from"kleur";import vr from"ora";var ze=`@import "tailwindcss";
9
11
  @import "tw-animate-css";
10
12
 
11
13
  @plugin "@tailwindcss/forms" {
@@ -130,7 +132,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
130
132
  --gradient-rust: oklch(55.695% 0.19944 34.155);
131
133
  }
132
134
 
133
- `,Ue=`@layer base {
135
+ `,qe=`@layer base {
134
136
  * {
135
137
  @apply border-border outline-ring/50;
136
138
  }
@@ -181,7 +183,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
181
183
  display: none;
182
184
  }
183
185
  }
184
- `,B=o=>(Fo[o]||(o="ZINC"),`${Ke}${Fo[o]}${Ue}`),je=`
186
+ `,J=o=>(Lo[o]||(o="ZINC"),`${ze}${Lo[o]}${qe}`),Ye=`
185
187
  :root {
186
188
  --radius: 0.65rem;
187
189
  --background: oklch(1 0 0);
@@ -251,7 +253,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
251
253
  --sidebar-ring: oklch(0.556 0 0);
252
254
  }
253
255
 
254
- `,De=`
256
+ `,Je=`
255
257
  :root {
256
258
  --radius: 0.625rem;
257
259
  --background: oklch(1 0 0);
@@ -321,7 +323,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
321
323
  --sidebar-ring: oklch(0.551 0.027 264.364);
322
324
  }
323
325
 
324
- `,Re=`
326
+ `,Xe=`
325
327
  :root {
326
328
  --radius: 0.625rem;
327
329
  --background: oklch(1 0 0);
@@ -390,7 +392,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
390
392
  --sidebar-ring: oklch(0.553 0.013 58.071);
391
393
  }
392
394
 
393
- `,Be=`
395
+ `,Ze=`
394
396
  :root {
395
397
  --radius: 0.625rem;
396
398
  --background: oklch(1 0 0);
@@ -460,7 +462,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
460
462
  --sidebar-ring: oklch(0.551 0.027 264.364);
461
463
  }
462
464
 
463
- `,$e=`
465
+ `,Qe=`
464
466
  :root {
465
467
  --radius: 0.625rem;
466
468
  --background: oklch(1 0 0);
@@ -530,7 +532,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
530
532
  --sidebar-ring: oklch(0.556 0 0);
531
533
  }
532
534
 
533
- `,We=`
535
+ `,or=`
534
536
  :root {
535
537
  --radius: 0.65rem;
536
538
  --background: oklch(1 0 0);
@@ -600,7 +602,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
600
602
  --sidebar-ring: oklch(0.637 0.237 25.331);
601
603
  }
602
604
 
603
- `,Ge=`
605
+ `,er=`
604
606
  :root {
605
607
  --radius: 0.65rem;
606
608
  --background: oklch(1 0 0);
@@ -670,7 +672,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
670
672
  --sidebar-ring: oklch(0.645 0.246 16.439);
671
673
  }
672
674
 
673
- `,He=`
675
+ `,rr=`
674
676
  :root {
675
677
  --radius: 0.65rem;
676
678
  --background: oklch(1 0 0);
@@ -740,7 +742,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
740
742
  --sidebar-ring: oklch(0.646 0.222 41.116);
741
743
  }
742
744
 
743
- `,Ve=`
745
+ `,tr=`
744
746
  :root {
745
747
  --radius: 0.65rem;
746
748
  --background: oklch(1 0 0);
@@ -810,7 +812,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
810
812
  --sidebar-ring: oklch(0.527 0.154 150.069);
811
813
  }
812
814
 
813
- `,ze=`
815
+ `,nr=`
814
816
  :root {
815
817
  --radius: 0.65rem;
816
818
  --background: oklch(1 0 0);
@@ -880,7 +882,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
880
882
  --sidebar-ring: oklch(0.488 0.243 264.376);
881
883
  }
882
884
 
883
- `,qe=`
885
+ `,ir=`
884
886
  :root {
885
887
  --radius: 0.65rem;
886
888
  --background: oklch(1 0 0);
@@ -950,7 +952,7 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
950
952
  --sidebar-ring: oklch(0.554 0.135 66.442);
951
953
  }
952
954
 
953
- `,Ye=`
955
+ `,ar=`
954
956
  :root {
955
957
  --radius: 0.65rem;
956
958
  --background: oklch(1 0 0);
@@ -1020,17 +1022,18 @@ ${r}`:l},m=(o,r,e)=>{console.log(`
1020
1022
  --sidebar-ring: oklch(0.541 0.281 293.009);
1021
1023
  }
1022
1024
 
1023
- `,Fo={ZINC:je,SLATE:De,STONE:Re,GRAY:Be,NEUTRAL:$e,RED:We,ROSE:Ge,ORANGE:He,GREEN:Ve,BLUE:ze,YELLOW:qe,VIOLET:Ye};var Oo=`/**
1025
+ `,Lo={ZINC:Ye,SLATE:Je,STONE:Xe,GRAY:Ze,NEUTRAL:Qe,RED:or,ROSE:er,ORANGE:rr,GREEN:tr,BLUE:nr,YELLOW:ir,VIOLET:ar};var Oo=`/**
1024
1026
  * Utility function to return Tailwind CSS classes.
1025
1027
  */
1026
1028
  export const tw = <T extends TemplateStringsArray | string>(tailwindClasses: T) => tailwindClasses;
1027
- `;import{join as Je}from"path";import{$ as Xe}from"execa";import oo from"fs-extra";import Ze from"ora";import Ao from"prompts";var $={arrowParens:"always",endOfLine:"lf",plugins:["@ianvs/prettier-plugin-sort-imports","prettier-plugin-tailwindcss"],printWidth:100,semi:!0,singleQuote:!1,tabWidth:2,trailingComma:"es5",useTabs:!1,vueIndentScriptAndStyle:!0,tailwindFunctions:["tv","tw"],importOrder:["<BUILTIN_MODULES>","<THIRD_PARTY_MODULES>","<TYPES>","","^[.]"]};var W=async(o=process.cwd(),r=!0)=>{let e=Je(o,".prettierrc"),t=$;if(oo.existsSync(e)){let a=await oo.readFile(e,"utf-8"),i={};try{i=JSON.parse(a)}catch{console.warn("\u26A0\uFE0F Existing .prettierrc is not valid JSON \u2014 will prompt for overwrite.")}let l=await Ao({name:"merge",type:"select",message:"A prettier config file already exists. What would you like to do?",choices:[{title:"Merge configs",value:"merge"},{title:"Overwrite with new config",value:"overwrite"},{title:"Cancel",value:"cancel"}],initial:0});if(l.merge==="merge")t={...i,...$};else if(l.merge==="overwrite")t=$;else return!1}if(await oo.writeFile(e,JSON.stringify(t,null,2),"utf-8"),!r)return!0;let n=Ze("Formatting files with prettier...").start();return await Xe`npx prettier --write .`,n.succeed("Files formatted with prettier"),!0},Po=async()=>{let{addPrettier:o}=await Ao({name:"addPrettier",type:"confirm",message:"Would you like to add a Prettier configuration to your project?",initial:!0});return o};import{join as Qe}from"path";import{builders as or,loadFile as er,writeFile as rr}from"magicast";import{getDefaultExportOptions as tr}from"magicast/helpers";var Lo=async()=>{let o=Qe(process.cwd(),"nuxt.config.ts"),r=await er(o);if(!r.$code.includes("tailwindcss()")){let e=tr(r);e.vite||={},e.vite.plugins||=[],e.vite.plugins.push(or.functionCall("tailwindcss"))}r.imports.$items.find(e=>e.local==="tailwindcss")||r.imports.$prepend({from:"@tailwindcss/vite",local:"tailwindcss",imported:"default"}),await rr(r,o)};import nr from"fs-extra";var Ko={recommendations:["vue.volar","bradlc.vscode-tailwindcss","antfu.iconify","formulahendry.auto-close-tag","formulahendry.auto-rename-tag"]},Uo={"editor.formatOnSave":!0,"editor.quickSuggestions":{strings:"on"},"files.associations":{"*.css":"tailwindcss"},"tailwindCSS.classFunctions":["tw","clsx","tw\\.[a-z-]+"],"tailwindCSS.experimental.classRegex":[["\\btv\\(\\s*((?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`|[^)]*)*)\\)",`["']([^"']*)["']`],["\\btv\\(\\s*((?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`|[^)]*)*)\\)","`([^`]*)`"]]};import{merge as cr}from"es-toolkit";import eo from"fs-extra";function ro(o,r){let e={};if(eo.existsSync(o))try{e=eo.readJsonSync(o)}catch{console.warn(`\u26A0\uFE0F Could not parse ${o}, starting fresh.`)}let t=cr(e,r);eo.writeJsonSync(o,t,{spaces:2})}var jo=(o=".vscode")=>{nr.ensureDirSync(o),ro(`${o}/extensions.json`,Ko),ro(`${o}/settings.json`,Uo)};var dr=async o=>{let r=await u(o),e=lr("Updating nuxt.config...").start();await ir({cwd:process.cwd(),configFile:"nuxt.config",async onUpdate(n){n.modules||(n.modules=[]),n.imports||(n.imports={imports:[]});for(let d of fo)n.modules.includes(d)||n.modules.push(d);if(!n.colorMode){let d=ar.basename(process.cwd());n.colorMode={storageKey:`${d}-color-mode`,classSuffix:""}}n.icon||(n.icon={clientBundle:{scan:!0,sizeLimitKb:0},mode:"svg",class:"shrink-0",fetchTimeout:2e3,serverBundle:"local"}),n.imports.imports.find(d=>d.from==="tailwind-variants"&&d.name==="tv")||n.imports.imports.push({from:"tailwind-variants",name:"tv"}),n.imports.imports.find(d=>d.from==="tailwind-variants"&&d.name==="VariantProps")||n.imports.imports.push({from:"tailwind-variants",name:"VariantProps",type:!0}),n.css||=[];let a=r.tailwindCSSLocation?.split("app/")[1],i=`~/${a}`,l=`@/${a}`;!n.css.includes(i)&&!n.css.includes(l)&&n.css.push(i)}}),await Lo(),e.succeed("Updated nuxt.config!"),e.start("Adding initial Tailwind CSS file..."),Do.writeFileSync(r.tailwindCSSLocation,B(r.theme.toUpperCase()),"utf-8"),e.succeed("Added initial Tailwind CSS file!"),e.start("Adding Autocomplete helper..."),Do.writeFileSync(r.utilsLocation+"/tw-helper.ts",Oo,"utf-8"),e.succeed("Added Autocomplete helper!"),e.start("Merging VS Code settings..."),jo(),e.succeed("Merged VS Code settings!"),await f(r.packageManager,uo,mo),await Po()&&(await f(r.packageManager,[],O),await W()),m("Initialized",`Feel free to start adding components with the ${to.bgWhite(" add ")} command.`,{box:{title:"Complete"}})},Ro=new sr().command("init").name("init").summary("Initialize UI Thing in your Nuxt project.").description(`${to.bold("Initialize UI Thing in your Nuxt project.")}
1029
+ `;import{join as cr}from"path";import{$ as sr}from"execa";import co from"fs-extra";import lr from"ora";import Uo from"prompts";var X={arrowParens:"always",endOfLine:"lf",plugins:["@ianvs/prettier-plugin-sort-imports","prettier-plugin-tailwindcss"],printWidth:100,semi:!0,singleQuote:!1,tabWidth:2,trailingComma:"es5",useTabs:!1,vueIndentScriptAndStyle:!0,tailwindFunctions:["tv","tw"],importOrder:["<BUILTIN_MODULES>","<THIRD_PARTY_MODULES>","<TYPES>","","^[.]"]};var Z=async(o=process.cwd(),e=!0)=>{let r=cr(o,".prettierrc"),n=X;if(co.existsSync(r)){let a=await co.readFile(r,"utf-8"),l={};try{l=JSON.parse(a)}catch{console.warn("\u26A0\uFE0F Existing .prettierrc is not valid JSON \u2014 will prompt for overwrite.")}let c=await Uo({name:"merge",type:"select",message:"A prettier config file already exists. What would you like to do?",choices:[{title:"Merge configs",value:"merge"},{title:"Overwrite with new config",value:"overwrite"},{title:"Cancel",value:"cancel"}],initial:0});if(c.merge==="merge")n={...l,...X};else if(c.merge==="overwrite")n=X;else return!1}if(await co.writeFile(r,JSON.stringify(n,null,2),"utf-8"),!e)return!0;let i=lr("Formatting files with prettier...").start();return await sr`npx prettier --write .`,i.succeed("Files formatted with prettier"),!0},Ko=async()=>{let{addPrettier:o}=await Uo({name:"addPrettier",type:"confirm",message:"Would you like to add a Prettier configuration to your project?",initial:!0});return o};import{join as dr}from"path";import{builders as pr,loadFile as mr,writeFile as hr}from"magicast";import{getDefaultExportOptions as ur}from"magicast/helpers";var Do=async()=>{let o=dr(process.cwd(),"nuxt.config.ts"),e=await mr(o);if(!e.$code.includes("tailwindcss()")){let r=ur(e);r.vite||={},r.vite.plugins||=[],r.vite.plugins.push(pr.functionCall("tailwindcss"))}e.imports.$items.find(r=>r.local==="tailwindcss")||e.imports.$prepend({from:"@tailwindcss/vite",local:"tailwindcss",imported:"default"}),await hr(e,o)};import kr from"fs-extra";var jo={recommendations:["vue.volar","bradlc.vscode-tailwindcss","antfu.iconify","formulahendry.auto-close-tag","formulahendry.auto-rename-tag"]},Ro={"editor.formatOnSave":!0,"editor.quickSuggestions":{strings:"on"},"files.associations":{"*.css":"tailwindcss"},"tailwindCSS.classFunctions":["tw","clsx","tw\\.[a-z-]+"],"tailwindCSS.experimental.classRegex":[["\\btv\\(\\s*((?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`|[^)]*)*)\\)",`["']([^"']*)["']`],["\\btv\\(\\s*((?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`|[^)]*)*)\\)","`([^`]*)`"]]};import{merge as fr}from"es-toolkit";import so from"fs-extra";function lo(o,e){let r={};if(so.existsSync(o))try{r=so.readJsonSync(o)}catch{console.warn(`\u26A0\uFE0F Could not parse ${o}, starting fresh.`)}let n=fr(r,e);so.writeJsonSync(o,n,{spaces:2})}var Bo=(o=".vscode")=>{kr.ensureDirSync(o),lo(`${o}/extensions.json`,jo),lo(`${o}/settings.json`,Ro)};var wr=async o=>{let e=await h(o),r=vr("Updating nuxt.config...").start();await yr({cwd:process.cwd(),configFile:"nuxt.config",async onUpdate(i){i.modules||(i.modules=[]),i.imports||(i.imports={imports:[]});for(let s of vo)i.modules.includes(s)||i.modules.push(s);if(!i.colorMode){let s=gr.basename(process.cwd());i.colorMode={storageKey:`${s}-color-mode`,classSuffix:""}}i.icon||(i.icon={clientBundle:{scan:!0,sizeLimitKb:0},mode:"svg",class:"shrink-0",fetchTimeout:2e3,serverBundle:"local"}),i.imports.imports.find(s=>s.from==="tailwind-variants"&&s.name==="tv")||i.imports.imports.push({from:"tailwind-variants",name:"tv"}),i.imports.imports.find(s=>s.from==="tailwind-variants"&&s.name==="VariantProps")||i.imports.imports.push({from:"tailwind-variants",name:"VariantProps",type:!0}),i.css||=[];let a=e.tailwindCSSLocation?.split("app/")[1],l=`~/${a}`,c=`@/${a}`;!i.css.includes(l)&&!i.css.includes(c)&&i.css.push(l)}}),await Do(),r.succeed("Updated nuxt.config!"),r.start("Adding initial Tailwind CSS file..."),$o.writeFileSync(e.tailwindCSSLocation,J(e.theme.toUpperCase()),"utf-8"),r.succeed("Added initial Tailwind CSS file!"),r.start("Adding Autocomplete helper..."),$o.writeFileSync(e.utilsLocation+"/tw-helper.ts",Oo,"utf-8"),r.succeed("Added Autocomplete helper!"),r.start("Merging VS Code settings..."),Bo(),r.succeed("Merged VS Code settings!"),await g(e.packageManager,yo,bo),await Ko()&&(await g(e.packageManager,[],j),await Z()),f("Initialized",`Feel free to start adding components with the ${po.bgWhite(" add ")} command.`,{box:{title:"Complete"}})},Wo=new br().command("init").name("init").summary("Initialize UI Thing in your Nuxt project.").description(`${po.bold("Initialize UI Thing in your Nuxt project.")}
1028
1030
 
1029
1031
  \u2705 Add tailwindcss to your project
1030
1032
  \u2705 Update your nuxt.config file
1031
1033
  \u2705 Add the necessary dependencies
1032
- \u2705 Create a ${to.bold("ui-thing.config")} file with the default configuration`).option("-f --force","Overwrite config file if it exists.",!1).option("-y --yes","Skip prompts and use default values.",!1).option("-n --nuxtVersion <number>","Specify the Nuxt version you are using.").action(dr);import{Command as hr}from"commander";import pr from"prompts";var Bo=new hr().command("prettier").name("prettier").description("Adds prettier config to your project.").action(async()=>{if(!await W(void 0,!1)){m("Not Added","Prettier config was not added.",{box:{title:"Prettier Not Added",borderColor:"red"}});return}let{pkgManager:r}=await pr({name:"pkgManager",type:"select",message:"Which package manager are you using?",choices:C});if(!r)return process.exit(0);await f(r,void 0,O),m("All Done!","A .prettierrc file has been added to your project and the code formatted. Enjoy!",{box:{title:"Prettier Added"}})});import{spawnSync as kr}from"child_process";import H from"path";import{Command as gr}from"commander";import{consola as I}from"consola";import v from"kleur";import M from"lodash";import ao from"prompts";import ur from"axios";import mr from"dotenv";import fr from"ora";mr.config();var $o=async()=>{let o=fr("Fetching prose components...").start(),{data:r}=await ur.get(process.env.PROSE_COMPONENTS_API||"https://uithing.com/api/prose");return o.succeed("Prose components fetched."),r};var io=[],G=process.cwd(),co=o=>io.find(r=>r.value.toLowerCase()===o.toLowerCase());async function Wo(o,r,e,t){if(await y(o)&&!e){let{value:a}=await ao({type:"confirm",name:"value",message:t,initial:!1});if(!a)return I.info(`Skipped: ${v.cyan(H.basename(o))}`),!1}return await S(o,r),!0}async function no(o,r,e,t){if(!(!r||r.length===0))for(let n of r){let a=H.join(G,e,n.fileName);await Wo(a,n.fileContent,t,`The ${o} file ${v.bold(n.fileName)} already exists. Overwrite?`)}}var yr=async(o,r)=>{let e=await u();await g()||(e=await u({force:!0})),M.isEmpty(e)&&(I.info("Config file not set. Exiting..."),process.exit(0)),io=await $o();let t=o;if(t.length===0){let c=await L(r.all,io);(!c||c.length===0)&&(I.info("No components selected. Exiting..."),process.exit(0)),t=c}let n=t.filter(c=>!co(c));n.length>0&&I.error(`Not found: ${v.bgRed(n.join(", "))}`);let a=t.map(c=>co(c)).filter(Boolean);for(let c of[...a])c.prose&&c.prose.length>0&&c.prose.forEach(p=>{if(!a.find(h=>h.value===p)){let h=co(p);h&&a.push(h)}});for(let c of a){let p=c.file,h=e.componentsLocation,s=H.join(G,h,p.fileName);if(!e.useDefaultFilename){let{value:b}=await ao({type:"text",name:"value",message:`Where should we add the file ${v.cyan(p.fileName)}?`,initial:h});b&&(h=b,s=H.join(G,h,p.fileName))}await Wo(s,p.fileContent,e.force,`The file ${v.bold(p.fileName)} already exists. Overwrite?`)&&(await no("utils",c.utils,e.utilsLocation,e.force),await no("composables",c.composables,e.composablesLocation,e.force),await no("plugins",c.plugins,e.pluginsLocation??"",e.force))}await A(M.uniq(a.flatMap(c=>c.modules||[])));let i=M.uniq(a.flatMap(c=>c.deps||[])),l=M.uniq(a.flatMap(c=>c.devDeps||[]));if(i.length>0||l.length>0)if(r.all)await f(e.packageManager,i,l);else{let{confirmInstall:c}=await ao({type:"confirm",name:"confirmInstall",message:`Install packages: ${v.cyan([...i,...l].join(", "))}?`,initial:!0});c&&await f(e.packageManager,i,l)}let d=M.uniq(a.flatMap(c=>c.components||[]));if(d.length>0){I.info(`Adding ${d.length} component(s) required by prose...`);let c=kr("npx",["ui-thing@latest","add",...d],{cwd:G,stdio:"inherit"});c.error&&I.error("Failed to add components:",c.error.message)}m("Prose added!",`Run the ${v.cyan("ui-thing@latest --help")} command to learn more.
1033
- `,{box:{title:"Prose Components Added"}})},Go=new gr().name("prose").command("prose").description("Add prose components to your project.").option("-a --all","Add all prose components to your project.",!1).argument("[componentNames...]").action(yr);import{Command as br}from"commander";import{execa as vr}from"execa";import wr from"ora";import Cr from"prompts";import{join as Vo}from"path";import zo from"fs-extra";var Ho=`import type { MaybeRef } from "vue";
1034
+ \u2705 Create a ${po.bold("ui-thing.config")} file with the default configuration`).option("-f --force","Overwrite config file if it exists.",!1).option("-y --yes","Skip prompts and use default values.",!1).option("-n --nuxtVersion <number>","Specify the Nuxt version you are using.").action(wr);import Cr from"path";import{Command as xr}from"commander";var Sr=async o=>{let e=await h(),r=await v(),n=process.cwd(),i=r;if(o.installed){let a=await Promise.all(r.map(async l=>{if(!l.files||l.files.length===0)return!1;let c=Cr.join(n,e.componentsLocation,l.files[0].fileName);return k(c)}));i=r.filter((l,c)=>a[c])}if(i.length===0){d.info(o.installed?"No components installed.":"No components available.");return}i.forEach(a=>d.log(`${a.name} (${a.value})`)),d.success(`${i.length} component(s) found.`)},Go=new xr().command("list").name("list").description("List available or installed components.").option("-i --installed","Only show installed components.",!1).action(Sr);import{Command as Er}from"commander";import Ir from"prompts";var Ho=new Er().command("prettier").name("prettier").description("Adds prettier config to your project.").action(async()=>{if(!await Z(void 0,!1)){f("Not Added","Prettier config was not added.",{box:{title:"Prettier Not Added",borderColor:"red"}});return}let{pkgManager:e}=await Ir({name:"pkgManager",type:"select",message:"Which package manager are you using?",choices:y});if(!e)return process.exit(0);await g(e,void 0,j),f("All Done!","A .prettierrc file has been added to your project and the code formatted. Enjoy!",{box:{title:"Prettier Added"}})});import{spawnSync as Fr}from"child_process";import oo from"path";import{Command as Mr}from"commander";import{consola as C}from"consola";import N from"kleur";import O from"lodash";import uo from"prompts";import Nr from"axios";import{consola as Tr}from"consola";import Pr from"dotenv";import _r from"ora";Pr.config();var Vo=async()=>{let o=_r("Fetching prose components...").start();try{let{data:e}=await Nr.get(process.env.PROSE_COMPONENTS_API||"https://uithing.com/api/prose");return o.succeed("Prose components fetched."),e}catch{o.fail("Failed to fetch prose components."),Tr.error("Could not reach the UI Thing API. Check your network connection."),process.exit(1)}};var fo=[],Q=process.cwd(),mo=o=>fo.find(e=>e.value.toLowerCase()===o.toLowerCase());async function zo(o,e,r,n){if(await k(o)&&!r){let{value:a}=await uo({type:"confirm",name:"value",message:n,initial:!1});if(!a)return C.info(`Skipped: ${N.cyan(oo.basename(o))}`),!1}return await w(o,e),!0}async function ho(o,e,r,n){if(!(!e||e.length===0))for(let i of e){let a=oo.join(Q,r,i.fileName);await zo(a,i.fileContent,n,`The ${o} file ${N.bold(i.fileName)} already exists. Overwrite?`)}}var Ar=async(o,e)=>{let r=await h();await b()||(r=await h({force:!0})),O.isEmpty(r)&&(C.error("Config file not set. Exiting..."),process.exit(1)),fo=await Vo();let n=o;if(n.length===0){let t=await G(e.all,fo);(!t||t.length===0)&&(C.info("No components selected. Exiting..."),process.exit(0)),n=t}let i=n.filter(t=>!mo(t));i.length>0&&C.error(`Not found: ${N.bgRed(i.join(", "))}`);let a=n.map(t=>mo(t)).filter(Boolean);for(let t of[...a])t.prose&&t.prose.length>0&&t.prose.forEach(p=>{if(!a.find(u=>u.value===p)){let u=mo(p);u&&a.push(u)}});for(let t of a){let p=t.file,u=r.componentsLocation,m=oo.join(Q,u,p.fileName);if(!r.useDefaultFilename){let{value:x}=await uo({type:"text",name:"value",message:`Where should we add the file ${N.cyan(p.fileName)}?`,initial:u});x&&(u=x,m=oo.join(Q,u,p.fileName))}await zo(m,p.fileContent,r.force,`The file ${N.bold(p.fileName)} already exists. Overwrite?`)&&(await ho("utils",t.utils,r.utilsLocation,r.force),await ho("composables",t.composables,r.composablesLocation,r.force),await ho("plugins",t.plugins,r.pluginsLocation??"",r.force))}await B(O.uniq(a.flatMap(t=>t.modules||[])));let l=O.uniq(a.flatMap(t=>t.deps||[])),c=O.uniq(a.flatMap(t=>t.devDeps||[]));if(l.length>0||c.length>0)if(e.all)await g(r.packageManager,l,c);else{let{confirmInstall:t}=await uo({type:"confirm",name:"confirmInstall",message:`Install packages: ${N.cyan([...l,...c].join(", "))}?`,initial:!0});t&&await g(r.packageManager,l,c)}let s=O.uniq(a.flatMap(t=>t.components||[]));if(s.length>0){C.info(`Adding ${s.length} component(s) required by prose...`);let t=Fr("npx",["ui-thing@latest","add",...s],{cwd:Q,stdio:"inherit"});t.error?C.error("Failed to spawn component installer:",t.error.message):t.status!==0&&C.error(`Component installer exited with code ${t.status}`)}f("Prose added!",`Run the ${N.cyan("ui-thing@latest --help")} command to learn more.
1035
+ `,{box:{title:"Prose Components Added"}}),a.filter(t=>t.docsUrl).forEach(t=>C.info(`Docs: ${t.docsUrl}`))},qo=new Mr().name("prose").command("prose").description("Add prose components to your project.").option("-a --all","Add all prose components to your project.",!1).argument("[componentNames...]").action(Ar);import Lr from"fs/promises";import P from"path";import{Command as Or}from"commander";import Yo from"prompts";var Ur=async o=>{let e=await h(),r=await v(),n=process.cwd(),i=o;if(i.length===0){let c=(await Promise.all(r.map(async t=>{if(!t.files||t.files.length===0)return null;let p=P.join(n,e.componentsLocation,t.files[0].fileName);return await k(p)?t:null}))).filter(Boolean);if(c.length===0){d.info("No installed components found.");return}let{selected:s}=await Yo({type:"autocompleteMultiselect",name:"selected",message:"Select components to remove",choices:c.map(t=>({title:t.name,value:t.value}))});(!s||s.length===0)&&(d.info("No components selected. Exiting..."),process.exit(0)),i=s}let a=i.map(c=>r.find(s=>s.value.toLowerCase()===c.toLowerCase())).filter(Boolean);if(a.length===0&&(d.error("None of the specified components were found in the registry."),process.exit(1)),!(await Yo({type:"confirm",name:"confirmed",message:`Remove ${a.map(c=>c.name).join(", ")}?`,initial:!1}))?.confirmed){d.info("Cancelled.");return}for(let c of a){let s=[...c.files.map(t=>P.join(n,e.componentsLocation,t.fileName)),...c.utils.map(t=>P.join(n,e.utilsLocation,t.fileName)),...(c.composables??[]).map(t=>P.join(n,e.composablesLocation,t.fileName))];for(let t of s){if(!await k(t)){d.warn(`Skipped (not found): ${P.basename(t)}`);continue}await Lr.unlink(t),d.success(`Removed: ${P.basename(t)}`)}}f("Removed!",void 0,{box:{title:"Components Removed"}})},Jo=new Or().command("remove").name("remove").description(`Remove installed components from your project.
1036
+ Note: shared utility files used by multiple components are deleted \u2014 other components depending on them may break.`).argument("[componentNames...]","Components to remove.").action(Ur);import{Command as Kr}from"commander";import{execa as Dr}from"execa";import jr from"ora";import Rr from"prompts";import{join as Zo}from"path";import Qo from"fs-extra";var Xo=`import type { MaybeRef } from "vue";
1034
1037
 
1035
1038
  type KbdKeysSpecificMap = {
1036
1039
  meta: string;
@@ -1344,5 +1347,5 @@ export function defineShortcuts(config: MaybeRef<ShortcutsConfig>, options: Shor
1344
1347
  return useEventListener("keydown", onKeyDown);
1345
1348
  }
1346
1349
 
1347
- `;var qo=async(o=process.cwd())=>{let r=await u(),e=Vo(o,r.composablesLocation);await zo.ensureDir(e),await zo.writeFile(Vo(e,"shortcuts.ts"),Ho,"utf-8")};var Yo=new br().command("shortcuts").name("shortcuts").description("Add the shortcuts composables to your project.").action(async()=>{await qo();let{pkgManager:o}=await Cr({name:"pkgManager",type:"select",message:"Which package manager are you using?",choices:C});if(!o)return process.exit(0);let r=wr("Installing vueuse module...").start();await vr`npx -y nuxi@latest module add vueuse`,r.succeed("VueUse module installed successfully!"),m("All Done!","Check the composables folder for the shortcuts composables.",{box:{title:"Composable Added"}})});import{Command as xr}from"commander";import Jo from"fs-extra";import Xo from"kleur";import so from"lodash";import Zo from"prompts";var Sr=o=>T.some(r=>r.value===o?.toLowerCase()),Qo=new xr().command("theme").name("theme").description("Add a new theme to your project.").argument("[themeName]","The name of the theme you would like to add").action(async o=>{let r=await u();await g()||(r=await u({force:!0})),so.isEmpty(r)&&(console.log(Xo.red("Config file not set. Exiting...")),process.exit(0));let t=o&&Sr(o)?o.toLowerCase():void 0;if(!t){let{theme:n}=await Zo([{name:"theme",type:"autocomplete",message:"Which theme do you want to add?",choices:T}]);n||(console.log(Xo.red("No theme selected. Exiting...")),process.exit(0)),t=n}if(Jo.existsSync(r.tailwindCSSLocation)){let{force:n}=await Zo([{name:"force",type:"confirm",message:"The Tailwind CSS file already exists. Overwrite?",initial:!1}]);if(!n)return console.log("Exiting..."),process.exit(0)}Jo.writeFileSync(r.tailwindCSSLocation,B(t.toUpperCase()),"utf-8"),m(`${so.capitalize(t)}`,`${so.capitalize(t)} theme has been added to ${r.tailwindCSSLocation}`,{box:{title:"New Theme Added"}})});process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));process.on("SIGTSTP",()=>process.exit(0));var oe=new Er;console.clear();m("UI Thing",void 0,{box:{title:"Welcome"}});console.log();oe.name("ui-thing").description("CLI for adding ui-thing components to your Nuxt application").version(lo).addCommand(Ro).addCommand(Eo).addCommand(Go).addCommand(Mo).addCommand(Qo).addCommand(Yo).addCommand(Bo);oe.parse(process.argv);
1350
+ `;var oe=async(o=process.cwd())=>{let e=await h(),r=Zo(o,e.composablesLocation);await Qo.ensureDir(r),await Qo.writeFile(Zo(r,"shortcuts.ts"),Xo,"utf-8")};var ee=new Kr().command("shortcuts").name("shortcuts").description("Add the shortcuts composables to your project.").action(async()=>{await oe();let{pkgManager:o}=await Rr({name:"pkgManager",type:"select",message:"Which package manager are you using?",choices:y});if(!o)return process.exit(0);let e=jr("Installing vueuse module...").start();await Dr`npx -y nuxi@latest module add vueuse`,e.succeed("VueUse module installed successfully!"),f("All Done!","Check the composables folder for the shortcuts composables.",{box:{title:"Composable Added"}})});import{Command as Br}from"commander";import re from"fs-extra";import ko from"lodash";import te from"prompts";var $r=o=>_.some(e=>e.value===o?.toLowerCase()),ne=new Br().command("theme").name("theme").description("Add a new theme to your project.").argument("[themeName]","The name of the theme you would like to add").action(async o=>{let e=await h();await b()||(e=await h({force:!0})),ko.isEmpty(e)&&(d.error("Config file not set. Exiting..."),process.exit(1));let n=o&&$r(o)?o.toLowerCase():void 0;if(!n){let{theme:i}=await te([{name:"theme",type:"autocomplete",message:"Which theme do you want to add?",choices:_}]);i||(d.warn("No theme selected. Exiting..."),process.exit(0)),n=i}if(re.existsSync(e.tailwindCSSLocation)){let{force:i}=await te([{name:"force",type:"confirm",message:"The Tailwind CSS file already exists. Overwrite?",initial:!1}]);if(!i)return d.info("Exiting..."),process.exit(0)}re.writeFileSync(e.tailwindCSSLocation,J(n.toUpperCase()),"utf-8"),f(`${ko.capitalize(n)}`,`${ko.capitalize(n)} theme has been added to ${e.tailwindCSSLocation}`,{box:{title:"New Theme Added"}})});import ie from"path";import{Command as Wr}from"commander";import Gr from"prompts";var Hr=async o=>{let e=await h(),r=await v(),n=process.cwd(),i=o;if(i.length===0){let c=(await Promise.all(r.map(async t=>{if(!t.files||t.files.length===0)return null;let p=ie.join(n,e.componentsLocation,t.files[0].fileName);return await k(p)?t:null}))).filter(Boolean);if(c.length===0){d.info("No installed components found.");return}let{selected:s}=await Gr({type:"autocompleteMultiselect",name:"selected",message:"Select components to update",choices:c.map(t=>({title:t.name,value:t.value}))});(!s||s.length===0)&&(d.info("No components selected. Exiting..."),process.exit(0)),i=s}let a=i.filter(c=>!r.find(s=>s.value.toLowerCase()===c.toLowerCase()));a.length>0&&d.warn(`Component(s) not found in registry: ${a.join(", ")}`);let l=i.map(c=>r.find(s=>s.value.toLowerCase()===c.toLowerCase())).filter(Boolean);for(let c of l)for(let s of c.files){let t=ie.join(n,e.componentsLocation,s.fileName);await w(t,s.fileContent),d.success(`Updated: ${s.fileName}`)}f("Updated!",void 0,{box:{title:"Components Updated"}})},ae=new Wr().command("update").name("update").description("Re-fetch and overwrite installed components with the latest version.").argument("[componentNames...]","Components to update.").action(Hr);process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));process.on("SIGTSTP",()=>process.exit(0));var ce=new Vr;console.clear();f("UI Thing",void 0,{box:{title:"Welcome"}});console.log();ce.name("ui-thing").description("CLI for adding ui-thing components to your Nuxt application").version(go).addCommand(Wo).addCommand(To).addCommand(qo).addCommand(Ao).addCommand(ne).addCommand(Go).addCommand(ae).addCommand(Jo).addCommand(ee).addCommand(Ho);ce.parse(process.argv);
1348
1351
  //# sourceMappingURL=index.js.map