untitledui
Version:
The Untitled UI CLI tool helps you quickly scaffold projects with Untitled UI React and add components and page examples to your existing projects with an interactive interface in seconds.
90 lines (86 loc) • 45.8 kB
JavaScript
import{Command as V3}from"commander";import W1 from"async-retry";import D from"chalk";import{Command as g1}from"commander";import{execa as I0}from"execa";import*as F from"fs";import K0 from"ora";import d1 from"os";import*as C from"path";import p from"prompts";import{Project as h1}from"ts-morph";import r0 from"node-fetch";import{Readable as R1,pipeline as y1}from"stream";import{x as N1}from"tar";import{promisify as A1}from"util";var v1=A1(y1);async function n0(z,B){try{let Q=await D1(B);await v1(Q,N1({cwd:z,strip:1}))}catch(Q){throw new Error(`Failed to download or extract repository from API: ${Q instanceof Error?Q.message:Q}`)}}async function D1(z){let B=`https://www.untitledui.com/react/api/download-repo?template=${z.template}`;try{let Q=await r0(B,{method:"GET",headers:{"Content-Type":"application/json",Accept:"application/octet-stream"}});if(Q.status===403||Q.status===404)throw new Error("Repository not found");if(!Q.ok)throw new Error(`Failed to download from API. Status: ${Q.status} ${Q.statusText}`);if(!Q.body)throw new Error("Response body is empty");return R1.from(Q.body)}catch(Q){throw new Error(`Error downloading tarball: ${Q instanceof Error?Q.message:Q}`)}}async function J0(z){let B=`https://www.untitledui.com/react/api/validate-key?key=${z}`;try{return(await r0(B)).status===200}catch{return!1}}import _1 from"node-fetch";var i0={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function b0(z,B,Q){let $=B.map((q)=>{if(q.includes("modals/"))if(q.includes("-modal"))return q;else return q+"-modal";return q});try{let q=await _1("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:z,components:$,key:Q})});if(!q.ok)console.log(i0?.[q.statusText]||i0.no_components_found),process.exit(1);return await q.json()}catch(q){return null}}import E0 from"node-fetch";var Z0={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function p0(z,B=""){let Q=`https://www.untitledui.com/react/api/components/list?key=${B}&type=${z}`;try{let Z=await E0(Q),$=await Z.json();if(!Z.ok)console.log(Z0?.[Z.statusText]||Z0.no_components_found),process.exit(1);if(!$?.components?.length)return null;return $}catch(Z){return console.error(Z),null}}async function t0(z,B="",Q){let Z=`https://www.untitledui.com/react/api/components/list?key=${B}&type=${z}&subfolders=${Q.join(",")}`;try{let $=await E0(Z);if(!$.ok)console.log(Z0?.[$.statusText]||Z0.no_components_found),process.exit(1);let q=await $.json();if(!q?.components?.length)return null;return q}catch($){return console.error($),null}}async function o0(z=""){let B=`https://www.untitledui.com/react/api/components/list?key=${z}`;try{let Q=await E0(B);if(!Q.ok)console.log(Z0?.[Q.statusText]||Z0.no_components_found),process.exit(1);let Z=await Q.json();if(!Z?.types?.length)return null;return Z}catch(Q){return console.error(Q),null}}import T0 from"fast-glob";import*as j0 from"fs";import*as c from"path";import{Project as P1}from"ts-morph";import{loadConfig as $1}from"tsconfig-paths";import E1 from"prettier";async function e0(z,B="typescript"){try{return await E1.format(z,{parser:B,printWidth:160,tabWidth:4})}catch(Q){return console.error("Error formatting with Prettier:",Q),z}}import h from"chalk";import r from"fast-glob";import*as m from"fs";import*as f from"path";import{loadConfig as H0}from"tsconfig-paths";import z1 from"fs";import T1 from"path";function B1(z=""){let B=T1.join(z,"package.json");if(!z1.existsSync(B))return null;else return JSON.parse(z1.readFileSync(B,"utf-8"))}import x1 from"path";import{createMatchPath as w1}from"tsconfig-paths";function Q1(z,B){let Q=x1.posix.join(z,"index"),Z=w1(B.absoluteBaseUrl,B.paths)(Q,void 0,()=>!0,[".ts",".tsx",".jsx",".js",".css"]);if(Z)return Z.split("/").slice(0,-1).join("/");else return}var g=["**/node_modules/**",".next","public","dist","build"],M0=!1,Y1={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function i(z){let B=m.existsSync(f.resolve(z,"src")),Q=m.existsSync(f.resolve(z,`${B?"src/":""}app`)),[Z,$,q,L,b]=await Promise.all([r.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:z,deep:2,ignore:g}),S1(z),F1(z),C1(z),B1(z)]),U=m.existsSync(f.resolve(z,"components.json")),V=null;if(U)V=JSON.parse(m.readFileSync(f.resolve(z,"components.json"),"utf-8"));let J=r.sync(["**/**/theme.css"],{cwd:z,absolute:!0,onlyFiles:!0,ignore:g}),H=J?.[0]&&m.readFileSync(J[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0,u={tailwind:{config:q||void 0,brandColor:H?.replace(/--color-([^-]+(?:-[^-]+)?)-\d+:.*/,"$1")||void 0},examples:V?.examples||void 0,aliases:V?.aliases||L||{},paths:await k1(V?.aliases||{})||{},isTsx:$,isSrcDir:B,isAppDir:Q,isComponentsJson:!!U,framework:"other"};if(Z.find((G)=>G.startsWith("next.config."))?.length)return u.framework=Q?"next-app":"next-pages",u;else if(Z.find((G)=>G.startsWith("vite.config."))?.length)return u.framework="vite",u;else if(Object.keys(b?.dependencies||{}).includes("react"))return u.framework="next-pages",u;else if(Z?.length||m.existsSync(f.resolve(z,"package.json")))return u.framework="other",u;return null}async function S1(z){return(await r.glob("tsconfig.*",{cwd:z,deep:2,ignore:g})).length>0}async function k1(z){let B={},Q=[],Z=Object.entries(z).filter(([,U])=>U);if(Z.length===0)return null;let $=process.cwd(),L=H0($).resultType==="success",b=await Z1($);if(!b){if(!M0){if(M0=!0,process.stdout.write("\r\x1B[K"),L)console.log(h.yellow(`
⚠ Could not resolve path aliases from components.json - no paths configured in tsconfig.json.`));else console.log(h.yellow(`
⚠ Could not resolve path aliases from components.json - tsconfig.json not found.`));console.log(h.dim(` The following aliases will be used for imports but files will be placed in default locations:
`)),Z.forEach(([U,V])=>{console.log(h.dim(` ${U}: ${V}`))}),console.log(h.dim(`
To fix this, add matching paths to your tsconfig.json.
`))}return null}for(let[U,V]of Object.entries(z))if(V){let J=await Q1(V.replace(/\/\*$/,""),b);if(J)B[U]=f.relative(process.cwd(),J);else Q.push(`${U}: ${V}`)}if(Q.length>0&&!M0)M0=!0,process.stdout.write("\r\x1B[K"),console.log(h.yellow(`
⚠ Could not resolve the following path aliases from tsconfig.json:`)),Q.forEach((U)=>{console.log(h.dim(` ${U}`))}),console.log(h.dim(`
These aliases will be used for imports but files will be placed in default locations.`)),console.log(h.dim(` To fix this, add matching paths to your tsconfig.json.
`));return B}async function Z1(z){let[B,Q]=await Promise.all([r.glob("next.config.*",{cwd:z,deep:1,ignore:g}),r.glob("vite.config.*",{cwd:z,deep:1,ignore:g})]),Z=B.length>0,$=Q.length>0,q=null;if(Z)q=H0(z);else if($){if(q=H0(z),q?.resultType==="failed"||!Object.keys(q.paths||{}).length){let L=await r.glob(["tsconfig.app.*","*/tsconfig.app.*"],{cwd:z,deep:1,onlyFiles:!0,absolute:!0,ignore:g}),[b]=L;if(b)try{let V=function(u){return u.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1")},U=m.readFileSync(b,"utf-8"),J=V(U),H=JSON.parse(J);if(H.compilerOptions?.paths)q={resultType:"success",paths:H?.compilerOptions?.paths,baseUrl:H.compilerOptions.baseUrl||".",configFileAbsolutePath:b,absoluteBaseUrl:f.resolve(z,H.compilerOptions.baseUrl||".")}}catch{}}}else q=H0(z);if(!q||q?.resultType==="failed"||!Object.keys(q.paths).length)return null;return q}async function F1(z){let B=await r.glob("tailwind.config.*",{cwd:z,deep:2,ignore:g});if(!B.length)return null;return B[0]}async function C1(z){let B=await Z1(z);if(!B)return null;let Q={},Z={app:/\/?app\/\*$/,components:/\/?components\/\*$/,utils:/\/?utils\/\*$/,styles:/\/?styles\/\*$/,hooks:/\/?hooks\/\*$/,src:/^(\.\/src\/\*|\.\/\*|\/src\/\*|src\/\*|\/\*|\*)$/};for(let[$,q]of Object.entries(B.paths)){let L=$.replace(/\/\*$/,"/");for(let[b,U]of Object.entries(Z))if(q.some((V)=>U.test(V))){Q[b]=L;break}}return Q||null}function $0(z,B){let Q=$1(z),Z=T0.sync(["tailwind.config.*","**/globals.css","package.json"],{cwd:z,deep:4,absolute:!0,onlyFiles:!0,ignore:g}),$=T0.sync("**/{layout,_app,main}.tsx",{cwd:B?c.posix.join(z,B):z,deep:4,absolute:!0,onlyFiles:!0,ignore:g});return{tailwindFile:Z.find((L)=>L.includes("tailwind.config.")),cssFile:Z.find((L)=>L.includes("globals.css")),packageJson:Z.find((L)=>L.includes("package.json")),tsConfig:Q?.resultType==="success"?Q?.configFileAbsolutePath:void 0,layoutFile:$.find((L)=>L.includes("layout")),appFile:$.find((L)=>L.includes("_app")),mainFile:$.find((L)=>L.includes("main"))}}function q0(z,B,Q={}){if(z.startsWith("@/components/")){if(Q?.components)return z.replace(/^@\/components\//,c.posix.join(Q.components,"/"));if(B)return z.replace(/^@\/components\//,c.posix.join("@",B,"/"))}if(z.startsWith("@/app/")&&Q?.app)return z.replace(/^@\/app\//,c.posix.join(Q.app,"/"));if(z.startsWith("@/utils/")&&Q?.utils)return z.replace(/^@\/utils\//,c.posix.join(Q.utils,"/"));if(z.startsWith("@/hooks/")&&Q?.hooks)return z.replace(/^@\/hooks\//,c.posix.join(Q.hooks,"/"));if(z.startsWith("@/styles/")&&Q?.styles)return z.replace(/^@\/styles\//,c.posix.join(Q.styles,"/"));if(z.startsWith("@/")&&Q?.src)return z.replace(/^@\//,c.posix.join(Q.src,"/"));return z}async function q1(z,B,Q="@/*"){let Z=await $1(z);if(Z?.resultType==="failed")return null;let $={};if(!Object.keys(Z.paths).length){Z.paths={[Q]:[`./${B?"src/":""}*`]},$.src=Q.replace(/\/\*$/,"");let q=await j0.promises.readFile(Z.configFileAbsolutePath,"utf-8"),L,b=/(?:\/\/\s*)?"paths":\s*\{(?:[^{}]|\{[^}]*\})*\}/;if(!b.test(q))L=q.replace(/"compilerOptions":\s*{/,`"compilerOptions": {
"paths": ${JSON.stringify(Z.paths)},`);else L=q.replace(b,`"paths": ${JSON.stringify(Z.paths)}`);let V=new P1,J=await e0(L,"json");return V.createSourceFile(Z.configFileAbsolutePath,J,{overwrite:!0}),await V.save(),$}return $||null}function X1(z){let B=T0.sync(["vite.config.*"],{cwd:z,absolute:!0,onlyFiles:!0,ignore:g})?.[0];if(!B)return!1;try{let Q=j0.readFileSync(B,"utf-8");return O1(Q)}catch{return!1}}function O1(z){let B=z.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"");if(!["tailwindcss","@tailwindcss/vite","tailwind("].some((q)=>B.includes(q)))return!1;return["plugins:","postcss:","css:"].some((q)=>B.includes(q))}function k(){if("bun/1.2.20 npm/? node/v24.3.0 darwin arm64".startsWith("yarn"))return"yarn";if("bun/1.2.20 npm/? node/v24.3.0 darwin arm64".startsWith("pnpm"))return"pnpm";if("bun/1.2.20 npm/? node/v24.3.0 darwin arm64".startsWith("bun"))return"bun";return"npm"}function X0(){switch(k()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function U1(){switch(k()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}function G0(z){return z.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}import l from"path";function u0(z,B,Q){let Z=z.replace(/^(components|utils|hooks|styles)\//,"");if(z.includes("components")&&B?.components)return l.relative(process.cwd(),l.posix.join(B.components,Z));if(z.includes("utils")&&B?.utils)return l.relative(process.cwd(),l.posix.join(B.utils,Z));if(z.includes("hooks")&&B?.hooks)return l.relative(process.cwd(),l.posix.join(B.hooks,Z));if(z.includes("styles")&&B?.styles)return l.relative(process.cwd(),l.posix.join(B.styles,Z));return l.posix.join(Q?"src":"",Z)}var f1=C.join(d1.homedir(),".untitledui"),t=C.join(f1,"config.json"),K={components:[],path:"",type:void 0,license:""};if(F.existsSync(t)){let z=JSON.parse(F.readFileSync(t,"utf-8"));K.license=z.license}var U0=(z)=>{if(z.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
`),process.exit(1)},K1=new g1().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-a, --all","add all available components",!1).option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the component to.").option("-d, --dir <directory>","the directory where the project is located.").option("-t, --type <base|marketing|shared-assets|application|foundations>","the type of the component to add.").action(async(z,B)=>{if(z)K.components=z;if(B)K.all=B.all,K.dir=B.dir,K.path=B.path,K.overwrite=B.overwrite,K.license=B.license||K.license;try{await x0(K)}catch(Q){console.error(D.red(Q))}});async function x0(z){if(z)K={...K,...z};let B=K0().start(),Q=C.posix.join(process.cwd(),K.dir||"");if(!F.existsSync(C.resolve(Q,"package.json")))B.warn("This command should be run in a project directory."),process.exit(1);let $=await i(Q);if(K.license){if(!await J0(K.license))B.fail("Invalid license key"),process.exit(1);if(!F.existsSync(t)){let M=C.dirname(t);F.mkdirSync(M,{recursive:!0}),F.writeFileSync(t,JSON.stringify({license:K.license},null,2))}if(JSON.parse(F.readFileSync(t,"utf-8")).license!==K.license)F.writeFileSync(t,JSON.stringify({license:K.license},null,2),"utf-8")}B.stop();let q=[];if(K.components.length){let Y=await b0(K.type,K.components,K.license);if(Y&&Y.pro&&Y.pro.length>0){if(console.log(),Y.pro.length===1){let X=Y.pro[0]?.split("/")[1]||Y.pro[0];console.log(D.yellow(`\uD83D\uDD12 The ${D.cyan(X)} component requires PRO access.`))}else console.log(D.yellow("\uD83D\uDD12 The following components require PRO access:")),Y.pro.forEach((X)=>{let M=X?.split("/")[1]||X;console.log(` • ${D.cyan(M)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${D.green("→")} If you've already purchased: ${D.cyan(`${X0()} untitledui@latest login`)}`),console.log(` ${D.green("→")} To purchase PRO components: ${D.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(!Y?.components.length)console.log("No components found"),process.exit(1);q.push(...Y.components)}if(!K?.type&&!K?.components.length){let Y=await o0(K.license);if(!Y)console.log("No component types found"),process.exit(1);let X=await p({type:"select",name:"type",onState:U0,message:`What type of ${D.cyan("component")} are you adding?`,choices:Y?.types.map((M)=>({title:M,value:M}))});K.type=X.type}if(!K?.path&&!$?.paths?.components){let Y=await p({type:"text",name:"path",onState:U0,message:`Where would you like to add the ${D.cyan("components")}?`,initial:"components"});K.path=Y.path}if(K?.path&&$&&$.paths)$.paths.components=C.posix.join($?.isSrcDir?"src":"",K.path);if($&&!Object.keys($?.aliases).length){let Y=/^[^*"]+\/\*\s*$/,X=await p({type:"text",name:"aliasPrefix",onState:U0,initial:"@/*",message:`What is the ${D.cyan("import alias")} for your project?`,validate:(M)=>Y.test(M)?!0:"Import alias must follow the pattern <prefix>/*"});$.aliases=await q1(Q,$?.isSrcDir,X?.aliasPrefix)}if(!K?.components.length){let Y=await p0(K?.type,K.license);if(!Y)console.log("No components found"),process.exit(1);let X=await p({type:"multiselect",name:"components",onState:U0,message:`Which ${D.cyan("components")} would you like to add?`,choices:Y?.components?.map((y)=>({title:y?.name+(y?.count?` (${y?.count} variants)`:"")||"example",value:y||"example",selected:K.components.includes(y.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!X.components||!X.components.length)console.log("No option selected. Exiting..."),process.exit(1);let M=X.components.filter((y)=>y?.type==="file").map((y)=>y.name),x=X.components.filter((y)=>y?.type==="dir").map((y)=>y.name),A=[];if(x.length){let y=await t0(K?.type,K.license,x);if(y&&y.components.length)for(let I of y.components){let[E,_]=Object.entries(I)[0]||[],P=await p({type:"select",name:"component",onState:U0,message:`Which ${D.cyan("variant")} from ${D.cyan(E)} would you like to add?`,choices:_?.map((O)=>({title:O?.name.replace(/-modal/g,"")||"example",value:O?.name||"example",selected:K.components.includes(O.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!P.component)console.log("No variant selected for "+D.cyan(E));A.push(E+"/"+P.component)}else console.log("No variants found")}K.components=[...A,...M]}if(!K.components?.length)B.warn("No components selected. Exiting."),process.exit(1);let L=$0(Q),b=new Set,U=new Set,V=new Set,J=new h1({tsConfigFilePath:L?.tsConfig});if(B.start(),K.type&&K.components.length){let Y=await b0(K.type,K.components,K.license);if(!Y?.components.length)console.log("No components found"),process.exit(1);q.push(...Y.components)}let H=new Set;if(q.forEach((Y)=>{Y?.components?.forEach((X)=>{H.add({name:X.name,path:X.path})})}),B.stop(),H.size){let Y=Array.from(H).filter((X)=>!F.existsSync(C.posix.join(Q,`${$?.isSrcDir?"src":""}`,X?.path?.replace(/components\//,K.path+"/"))));if(Y?.length){let X=await p({type:"multiselect",name:"baseComponents",onState:U0,message:"Select which base components you want to add",choices:Y.map((M)=>({title:M?.name,value:M?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(K.baseComponents=X.baseComponents,!Y.length&&!X.baseComponents?.length)B.warn("No components selected")}}if(B.start(),K?.baseComponents?.length){let Y=await b0("",K.baseComponents,K.license);if(!Y||!Y?.components.length)console.log("No base components found");else q.push(...Y.components)}B.stop();let u=new Set;for(let Y of q){let X=K0(`Adding ${Y.name}...`).start(),M=Y.files;Y?.dependencies?.forEach((A)=>U.add(A)),Y?.devDependencies?.forEach((A)=>V.add(A));let x=!1;try{for(let{path:A,code:y}of M||[]){let I=C.posix.join(Q,u0(A,$?.paths,$?.isSrcDir)),E=$?.framework==="vite"?y.replace(`"use client";
`,""):y,_=G0(E),P=C.dirname(I);if(F.existsSync(I)&&!K.overwrite&&!u.has(I)){if(F.readFileSync(I,"utf-8")!==_)b.add({code:_,path:I}),x=!0}else if(!u.has(I)){F.mkdirSync(P,{recursive:!0}),F.writeFileSync(I,_),u.add(I);let O=J.addSourceFileAtPath(C.resolve(I));O.getImportDeclarations().forEach((s)=>{let s0=s.getModuleSpecifierValue();s.setModuleSpecifier(q0(s0,K.path,$?.aliases))}),await O.save()}}if(x)X.warn(`Some files of ${D.yellow(Y.name)} already exist`);else X.succeed(`${D.green(Y.name)} is added successfully`)}catch(A){X.fail(`
Failed to add the component ${D.red(Y.name)}`),console.error(D.red(A)),process.exit(1)}}if(b.size&&!K?.overwrite){console.log(`
Following files already exist in the directory.`),b.forEach((X)=>{console.log(D.green(`- ${C.relative(Q,X.path)}`))});let Y=await p({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0});if(Y.overwrite===void 0)console.log(`
Use ${D.cyan("--overwrite")} or ${D.cyan("-o")} flag to overwrite existing files, or run with ${D.cyan("node")} instead of ${D.cyan("bun")}.`),process.exit(1);if(Y.overwrite){let X=K0("Overwriting files").start();b.forEach((M)=>{let x=J.addSourceFileAtPath(C.resolve(M.path));x.replaceWithText(M.code),x.getImportDeclarations().forEach((A)=>{let y=A.getModuleSpecifierValue();A.setModuleSpecifier(q0(y,K.path,$?.aliases))}),x.saveSync()}),X.succeed("Files are overwritten")}}let G=k();if(U?.size){let Y=K0("Installing component dependencies").start();await W1(()=>I0(G,[G==="npm"?"install":"add",...U],{cwd:Q}).catch(async(X)=>{if(X.message.includes("peer"))Y.warn("Component dependencies conflict detected. Retrying with --legacy-peer-deps..."),Y.start("Installing component dependencies with --legacy-peer-deps flag"),await I0(G,[G==="npm"?"install":"add",...U,"--legacy-peer-deps"],{cwd:Q})}),{retries:1}),Y.succeed("Component dependencies are installed")}if(V?.size){let Y=K0("Installing component devDependencies").start();await W1(()=>I0(G,[G==="npm"?"install":"add","-D",...V],{cwd:Q}).catch(async(X)=>{if(X.message.includes("peer"))Y.warn("Component devDependencies conflict detected. Retrying with --legacy-peer-deps..."),Y.start("Installing component devDependencies with --legacy-peer-deps flag"),await I0(G,[G==="npm"?"install":"add","-D",...V,"--legacy-peer-deps"],{cwd:Q})}),{retries:1}),Y.succeed("Component devDependencies are installed")}if(K.message!==void 0){if(K.message)console.log(K.message);return}process.exit(0)}import k0 from"chalk";import{Command as a1}from"commander";import*as a from"fs";import s1 from"http";import r1 from"open";import n1 from"ora";import i1 from"os";import*as C0 from"path";import{URL as p1}from"url";import*as R0 from"fs";import*as o from"path";import{fileURLToPath as m1}from"url";var c1=m1(import.meta.url),w0=o.dirname(c1);function l1(){let z=[o.join(w0,"..","templates","auth-template.html"),o.join(w0,"templates","auth-template.html"),o.join(process.cwd(),"node_modules","untitledui","templates","auth-template.html"),o.join(w0,"..","..","templates","auth-template.html")];for(let B of z)if(R0.existsSync(B))return B;throw new Error("Auth template file not found. Please ensure the CLI package is properly installed.")}function L1(){try{let z=l1();return R0.readFileSync(z,"utf-8")}catch(z){return console.warn("Warning: Using fallback auth template. Some styling may be missing."),`<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{TITLE}}</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", sans-serif;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: #ffffff;
margin: 0;
padding: 20px;
}
.container {
text-align: center;
max-width: 400px;
}
.title {
font-size: 24px;
font-weight: 600;
color: #181d27;
margin-bottom: 16px;
}
.description {
font-size: 16px;
color: #535862;
line-height: 1.4;
}
@media (prefers-color-scheme: dark) {
body { background-color: #0c0e12; }
.title { color: #fafafa; }
.description { color: #94979c; }
}
</style>
</head>
<body>
<div class="container">
<h1 class="title">{{HEADING}}</h1>
<p class="description">{{DESCRIPTION}}</p>
{{AUTO_CLOSE_SCRIPT}}
</div>
</body>
</html>`}}function V1(){return L1().replace("{{TITLE}}","Authentication successful").replace("{{HEADING}}","Authentication successful").replace("{{DESCRIPTION}}","You can now close this tab and return to your terminal.").replace("{{AUTO_CLOSE_SCRIPT}}","<script>setTimeout(() => window.close(), 10000);</script>")}function y0(z){return L1().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",z).replace("{{AUTO_CLOSE_SCRIPT}}","")}var F0=C0.join(i1.homedir(),".untitledui"),S0=C0.join(F0,"config.json"),J1=new a1().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let z=n1("Starting authentication...").start();try{await t1(z),z.succeed("Authentication completed successfully!"),console.log(k0.green(`
✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch(B){z.fail(`Authentication failed: ${B instanceof Error?B.message:B}`),process.exit(1)}});async function t1(z){return new Promise((B,Q)=>{let Z=s1.createServer(($,q)=>{let L=new p1($.url,"http://localhost");if(L.pathname==="/callback"){let b=L.searchParams.get("apiKey"),U=L.searchParams.get("error");if(U){q.writeHead(400,{"Content-Type":"text/html"}),q.end(y0(decodeURIComponent(U))),Z.close(),Q(new Error(decodeURIComponent(U)));return}if(!b){q.writeHead(400,{"Content-Type":"text/html"}),q.end(y0("No Access Token received")),Z.close(),Q(new Error("No Access Token received"));return}try{o1(b),q.writeHead(200,{"Content-Type":"text/html"}),q.end(V1()),Z.close(),B()}catch(V){q.writeHead(500,{"Content-Type":"text/html"}),q.end(y0("Failed to save authentication data")),Z.close(),Q(V)}}else q.writeHead(404),q.end("Not found")});Z.listen(0,"localhost",()=>{let L=`https://www.untitledui.com/react/api/cli-auth?port=${Z.address().port}`;z.text="Opening browser for authentication...",r1(L).catch((b)=>{console.log(k0.yellow(`
Failed to open browser automatically: ${b.message}`)),console.log(k0.cyan(`Please manually open: ${L}
`))}),z.text="Waiting for authentication in browser..."}),setTimeout(()=>{Z.close(),Q(new Error("Authentication timeout. Please try again."))},300000)})}function o1(z){if(!a.existsSync(F0))a.mkdirSync(F0,{recursive:!0});let B={};if(a.existsSync(S0))try{B=JSON.parse(a.readFileSync(S0,"utf-8"))}catch{B={}}B.license=z,a.writeFileSync(S0,JSON.stringify(B,null,2),"utf-8")}import c0 from"async-retry";import j from"chalk";import{Command as q3}from"commander";import{execa as _0}from"execa";import*as S from"fs";import V0 from"ora";import X3 from"os";import*as N from"path";import B0 from"prompts";import{Project as U3}from"ts-morph";import e1 from"node-fetch";async function N0(z,B){try{let Z=await e1("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:z,key:B})});if(!Z.ok){if(Z.status===401||Z.status===403)return{type:"error",status:Z.status,message:"PRO access required"};return console.error(`API error: ${Z.status} - ${Z.statusText}`),null}return await Z.json()}catch(Z){return console.error(Z?.message||"Error fetching example data."),null}}import L0 from"async-retry";import w from"chalk";import{Command as z3}from"commander";import{execa as e}from"execa";import h0 from"fast-glob";import T from"fs";import W0 from"ora";import B3 from"os";import*as v from"path";import D0 from"prompts";import{Project as Q3}from"ts-morph";import{fileURLToPath as Y3}from"url";import*as A0 from"fs";import*as b1 from"path";function P0(z,B){let Q=b1.join(z,"package.json");if(!A0.existsSync(Q))return B;let Z=JSON.parse(A0.readFileSync(Q,"utf-8")),$={...Z.dependencies,...Z.devDependencies},q=[];for(let L of B){let b=$[L];if(!b){q.push(L);continue}if(L==="tailwindcss"){let U=b.match(/\d+/);if((U?parseInt(U[0],10):0)<4)q.push(L)}}return q}import O0 from"chalk";import*as n from"fs";import*as v0 from"path";function g0(z){if(!n.existsSync(v0.resolve(z)))console.log(O0.red(`Error: CSS file not found at ${z}`)),process.exit(1);let B=n.readFileSync(v0.resolve(z),"utf-8"),Q=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,Z={},$;while(($=Q.exec(B))!==null)if($[1]&&$[2])Z[$[1]]=$[2];return Z}function d0(z,B,Q){let Z=v0.resolve(Q);if(!n.existsSync(Z)){console.log(O0.red(`Error: CSS file not found at ${Z}`));return}let $=n.readFileSync(Z,"utf-8"),q=g0(Q),L={},b={};for(let[V,J]of Object.entries(q))if(V.startsWith(`--color-${z}-`)){let H=V.replace(`--color-${z}-`,"");L[H]=V}else if(V.startsWith(`--color-${B}-`)){let H=V.replace(`--color-${B}-`,"");b[H]=J}let U=!1;for(let[V,J]of Object.entries(L))if(b[V]){let H=b[V],u=new RegExp(`(${J}):\\s*rgb\\([^)]*\\);?`,"g");if(u.test($))$=$.replace(u,`$1: ${H};`),U=!0;else console.log(O0.yellow(`No match found for ${J}`))}if(U)n.writeFileSync(Z,$,"utf-8")}var Z3=Y3(import.meta.url),M1=v.dirname(Z3),$3=v.join(B3.homedir(),".untitledui"),z0=v.join($3,"config.json"),j1="vite",G1="nextjs",H1={[G1]:"Next.js",[j1]:"Vite"},d="",R={color:"",template:"",framework:void 0};if(T.existsSync(z0)){let z=JSON.parse(T.readFileSync(z0,"utf-8"));R.license=z.license}var f0=(z)=>{if(z.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
`),process.exit(1)},u1=new z3().name("init").description("initialize a new project or adjust an existing one").argument("[directory]").usage("[directory] [options]").helpOption("-h, --help","display this help message.").option("--vite","initialize a Vite project.",!1).option("--nextjs","initialize a Next.js project.",!1).option("-o, --overwrite","overwrite existing files.",!1).option("--colors-list","show the colors list.",!1).option("-c, --color <color-name>","specify a color for the project.").action(async(z,B)=>{if(z)d=z;if(B){if(R.color=B.color,R.template=B.template,R.overwrite=B.overwrite,R.colorsList=B.colorsList,R.license=B.license||R.license,R.vite=B.vite,R.nextjs=B.nextjs,B.vite)R.framework=j1;if(B.nextjs)R.framework=G1}try{await m0(B),process.exit(0)}catch(Q){console.error(w.red(Q)),process.exit(1)}});async function m0(z,B=null){let Q=process.cwd(),Z=T.existsSync(v.resolve(Q,"package.json")),$=v.resolve(v.join(M1,"../config/styles","theme.css")),q=g0($??""),L=Array.from(new Set(Object.keys(q).map((J)=>J?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),b=W0().start(),U=await i(Q);if(R.license){if(!T.existsSync(z0)){let H=v.dirname(z0);T.mkdirSync(H,{recursive:!0}),T.writeFileSync(z0,JSON.stringify({license:R.license},null,2))}if(JSON.parse(T.readFileSync(z0,"utf-8")).license!==R.license)T.writeFileSync(z0,JSON.stringify({license:R.license},null,2))}if(!Z){if(b.stop(),!d){let H=await D0({onState:f0,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof H.path==="string")d=H.path.trim()}if(B)B.projectPath=d;let J=T.existsSync(v.resolve(v.posix.join(Q,d,"package.json")));if(T.existsSync(v.resolve(v.posix.join(Q,d)))&&J)b.fail(w.red("Directory already exists!")),process.exit(1);if(R.vite&&R.nextjs||!R.framework){let H=await D0({type:"select",name:"framework",onState:f0,message:`Which ${w.cyan("framework")} would you like to use?`,choices:Object.entries(H1).map(([u,G])=>({title:G,value:u}))});R.framework=H.framework}b.succeed("Framework is selected: "+w.green(H1[R.framework]))}else if(U?.framework==="other")b.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${w.cyan("https://www.untitled.com/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(U?.framework.startsWith("next")||U?.framework.startsWith("vite"))if(!B&&!U.tailwind.brandColor)b.succeed(w.yellow(`Detected ${Y1[U.framework]} project, proceeding with the setup...`));else b.stop();if(R.colorsList||!R.color&&!U?.tailwind.brandColor){let J=await D0({type:"select",name:"color",onState:f0,initial:z.color??"",message:`Which ${w.cyan("color")} would you like to use as the ${w.cyanBright("brand")} color?`,choices:L.map((H)=>({title:H,value:H}))});if(R.color=J.color,R.colorsList&&U)U.tailwind.brandColor=J.color}let V=v.posix.join(Q,d||"");if(d&&!Z){let J=v.resolve(d);console.log(`
Creating a new project in ${w.blue(d)}`);let H=W0("Downloading and extracting the repository...").start();try{T.mkdirSync(J,{recursive:!0}),await L0(()=>n0(J,{template:R.framework}),{retries:2}),H.succeed("Files are downloaded and extracted successfully!");let u=W0({text:"Installing dependencies..."}).start(),G=h0.sync(["**/styles/theme.css"],{cwd:J,absolute:!0,onlyFiles:!0})[0];if(d0("brand",R.color||"",G??""),await L0(()=>e(k(),["install"],{cwd:V}).catch(async(Y)=>{if(Y.message.includes("peer"))u.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),u.start("Installing dependencies with --legacy-peer-deps flag"),await e(k(),["install","--legacy-peer-deps"],{cwd:V})}),{retries:1}),await L0(()=>e("git",["init"],{cwd:V}),{retries:1}),u.succeed("Dependencies are installed"),!B)console.log(`
Your project is ready, to get started run the following commands:
cd ${w.cyan(d)}
${w.cyan(U1())}`)}catch(u){if(H.fail(w.red(`
Failed to download and extract the repository`)),u instanceof Error)console.error(u.message);else console.error(`
`);T.rmdirSync(J,{recursive:!0}),process.exit(1)}}else{let J=W0(),H=new Set,u=U?.examples||"",G=$0(Q,u),Y=v.resolve(v.join(M1,"../config")),X=h0.sync(["**"],{cwd:Y,onlyFiles:!0,ignore:g}),M=P0(Q,["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"]),x=P0(Q,["@tailwindcss/postcss","postcss"]);if(!B&&!U?.tailwind.brandColor)J.start("Copying files to the project directory");if(X.forEach((I)=>{let E=I.includes("postcss.config"),_=v.posix.join(v.posix.join(Y),I),P=v.posix.join(Q,E?I:u0(I,U?.paths,U?.isSrcDir));if(T.existsSync(P)){if(R?.overwrite)T.copyFileSync(_,P);else{let O=T.readFileSync(P,"utf-8"),s=T.readFileSync(_,"utf-8");if(O!==s){if(I.endsWith("theme.css")&&U?.tailwind.brandColor)return;H.add({targetFile:P,sourceFile:_})}}return}T.mkdirSync(v.dirname(P),{recursive:!0}),T.writeFileSync(P,""),T.copyFileSync(_,P)}),J.stop(),H.size&&!R?.overwrite){if(console.log(`
`),J.fail("Following files already exist in the directory."),H.forEach((E)=>{console.log(`- ${w.green(E.targetFile)}`)}),(await D0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let E=W0("Overwriting files").start();H.forEach((_)=>{T.copyFileSync(_.sourceFile,_.targetFile)}),E.succeed("Files are overwritten")}}if(G?.tailwindFile)console.log(`
Tailwind config file exists in the project directory. You can add it to your globals.css as follows:`),console.log(`
${w.cyan(`@config "../${U?.isSrcDir?"../":""}${v.relative(Q,G.tailwindFile)}";`)}
`);if(U?.framework==="vite"){if(!X1(Q))console.log(`
Tailwind CSS is not configured in your Vite project. Please refer to the documentation ${w.cyan("https://www.untitled.com/react/integrations/vite")} for manual installation.
`)}let A=G?.layoutFile||G?.appFile||U?.framework==="vite"&&G?.mainFile||"";if(A){let E=new Q3({tsConfigFilePath:v.resolve(G?.tsConfig||"")}).addSourceFileAtPath(v.resolve(A)),_="styles/globals.css";if(!E.getImportDeclarations().some((O)=>{let s=O.getModuleSpecifierValue();return/(?:styles\/)?globals\.css$/.test(s)})){let O=U?.aliases?.styles||U?.aliases?.src||"",s=U?.aliases?.styles?`${O}globals.css`:`${O}styles/globals.css`;E.addImportDeclaration({moduleSpecifier:s})}E.saveSync()}let y=h0.sync(["**/theme.css"],{cwd:Q,absolute:!0,onlyFiles:!0,ignore:g});if(!y?.length)return J.fail(`Failed to copy ${w.cyan("theme.css")} file.
Ensure that the ${w.cyan("theme.css")} file exists in the project directory under your ${w.yellow("styles")} folder.`);if((R.color||!U?.tailwind.brandColor)&&d0("brand",R.color||"brand",y[0]??""),M.length||x.length){let I=W0().start("Installing dependencies");M.length&&await L0(()=>e(k(),[k()==="npm"?"install":"add",...M],{cwd:V}).catch(async(E)=>{if(E.message.includes("peer"))I.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),I.start("Installing dependencies with --legacy-peer-deps flag"),await e(k(),[k()==="npm"?"install":"add",...M,"--legacy-peer-deps"],{cwd:V})}),{retries:1}),x.length&&await L0(()=>e(k(),[k()==="npm"?"install":"add","-D",...x],{cwd:V}).catch(async(E)=>{if(E.message.includes("peer"))I.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),I.start("Installing dependencies with --legacy-peer-deps flag"),await e(k(),[k()==="npm"?"install":"add","-D",...x,"--legacy-peer-deps"],{cwd:V})}),{retries:1}),I.succeed("Dependencies are installed")}if(!B&&!U?.tailwind.brandColor)J.succeed(w.green("Project setup is completed!"));if(B&&Z){b.stop(),J.stop();return}else console.log(`
Your project is ready, you can now start adding components.`)}}var W3=N.join(X3.homedir(),".untitledui"),Y0=N.join(W3,"config.json"),W={path:"",example:"",license:"",components:[]},l0={};if(S.existsSync(Y0)){let z=JSON.parse(S.readFileSync(Y0,"utf-8"));W.license=z.license}var Q0=(z)=>{if(z.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
`),process.exit(1)},I1=new q3().name("example").description("add an example to the project").argument("[example]","the example to add").option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the component to.").option("-e, --example-path <example-path>","the path to add the example file to.").action(async(z,B)=>{if(z)W.example=z;if(B)W.path=B.path,W.overwrite=B.overwrite,W.examplePath=B.examplePath,W.license=B.license||W.license;try{await m0(B,l0),await K3()}catch(Q){console.error(j.red(Q))}});async function K3(){let z=V0().start(),B=N.posix.join(process.cwd(),l0?.projectPath||"");if(!S.existsSync(N.posix.join(N.resolve(B,"package.json"))))z.warn("This command should be run in a project directory."),process.exit(1);let Z=await i(B);if(W.license){if(!await J0(W.license))z.fail("Invalid license key"),process.exit(1);if(!S.existsSync(Y0)){let M=N.dirname(Y0);S.mkdirSync(M,{recursive:!0}),S.writeFileSync(Y0,JSON.stringify({license:W.license},null,2))}if(JSON.parse(S.readFileSync(Y0,"utf-8")).license!==W.license)S.writeFileSync(Y0,JSON.stringify({license:W.license},null,2),"utf-8")}if(z.stop(),!W.example){let Y=await B0({type:"select",name:"example",onState:Q0,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});W.example=Y.example}let $=null;if(W.example){let Y=await N0(W.example,W.license);if(Y?.type==="error"&&(Y.status===401||Y.status===403))console.log(),console.log(j.yellow(`\uD83D\uDD12 The ${j.cyan(W.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${j.green("→")} If you've already purchased: ${j.cyan(`${X0()} untitledui@latest login`)}`),console.log(` ${j.green("→")} To purchase PRO examples: ${j.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(Y?.type==="directory"){let X=await B0({type:"select",name:"example",onState:Q0,message:`Select a folder or file in "${W.example}"`,choices:Y.results.map((M)=>({title:M,value:M}))});if(!X.example)return;if(W.example=X.example,Y=await N0(X.example,W.license),Y?.type==="error"&&(Y.status===401||Y.status===403))console.log(),console.log(j.yellow(`\uD83D\uDD12 The ${j.cyan(X.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${j.green("→")} If you've already purchased: ${j.cyan(`${X0()} untitledui@latest login`)}`),console.log(` ${j.green("→")} To purchase PRO examples: ${j.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(Y?.type==="json-files"){let X=await B0({type:"select",name:"example",onState:Q0,message:`Select which example you want to add from "${W.example}"`,choices:Y.results.map((M)=>({title:M,value:`${W.example}/${M}`}))});if(!X.example)return;if(W.example=X.example,Y=await N0(X.example,W.license),Y?.type==="error"&&(Y.status===401||Y.status===403))console.log(),console.log(j.yellow(`\uD83D\uDD12 The ${j.cyan(X.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${j.green("→")} If you've already purchased: ${j.cyan(`${X0()} untitledui@latest login`)}`),console.log(` ${j.green("→")} To purchase PRO examples: ${j.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(Y?.type==="json-file")$=Y.content}if(!$)z.fail("No example found"),process.exit(1);let q=Z?.examples||"";if(q){let Y=await i(N.posix.join(B,q));if(Y)Z={...Y,aliases:Z?.aliases||{}};W.examplePath=q}if(!W?.examplePath){let Y=Z?.isAppDir?"app":"pages",X=Z?.isSrcDir?N.posix.join("src",Y):Y,M=await B0({type:"text",name:"examplePath",onState:Q0,message:`Where would you like to add the ${j.cyan(W?.example)} example?`,initial:X});W.examplePath=M.examplePath}else if(!S.existsSync(N.posix.join(B,W.examplePath)))S.mkdirSync(N.posix.join(B,W.examplePath),{recursive:!0}),console.log(j.green(`Created directory ${W.examplePath}`));if(!W?.path&&!Z?.paths?.components){let Y=await B0({type:"text",name:"path",onState:Q0,message:`Where would you like to add the ${j.cyan("components")}?`,initial:"components"});W.path=Y.path}if(W?.path&&Z?.paths&&!Z.paths.components)Z.paths.components=N.posix.join(Z?.isSrcDir?"src":"",W.path);if(!W?.path&&Z?.paths?.components)W.path=Z.paths.components.replace(/^src\//,"");let L=$.components.filter((Y)=>!S.existsSync(N.posix.join(B,`${Z?.isSrcDir?"src":""}`,Y?.path?.replace(/components\//,W.path+"/"))));if(L?.length){let Y=await B0({type:"multiselect",name:"components",onState:Q0,message:`Select which components you want to add from ${j.cyan($.name)} example`,choices:L.map((X)=>({title:X?.name,value:X?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(W.components=Y.components,!L.length&&!Y.components?.length)z.warn("No components selected")}let b=$0(B),U=new Set,V=new U3({tsConfigFilePath:b?.tsConfig}),J=V0(`Adding ${W?.example}...`).start(),H="",u=new Set($.components.filter((Y)=>W.components?.includes(Y.name)).map((Y)=>N.dirname(Y.path)));try{for(let{path:Y,code:X}of $.files||[]){let M=N.dirname(Y);if(Array.from(u).some((_)=>M===_||M.startsWith(_+"/")))continue;let A=N.posix.join(B,`${Z?.isSrcDir?"src":""}`,Y.replace(/components\//,W.path+"/")),y=Z?.framework==="vite"?X.replace(`"use client";
`,""):X,I=G0(y);if(Y.includes("examples")){let _=N.basename(Y);A=N.posix.join(B,W?.examplePath??"",_),H=N.posix.join(W?.examplePath??"",_)}let E=N.dirname(A);if(S.existsSync(A)&&!W.overwrite){if(S.readFileSync(A,"utf-8")!==I)U.add({code:I,path:A})}else{S.mkdirSync(E,{recursive:!0}),S.writeFileSync(A,I);let _=V.addSourceFileAtPath(N.resolve(A));_.getImportDeclarations().forEach((P)=>{let O=P.getModuleSpecifierValue();P.setModuleSpecifier(q0(O,W.path,Z?.aliases))}),await _.save()}}if(U.size)J.warn(`Some files of ${j.yellow(W?.example)} already exist`);else J.succeed(`${j.green(W?.example)} is added successfully`)}catch(Y){J.fail(`
Failed to add the component ${j.red(W?.example)}`),console.error(j.red(Y)),process.exit(1)}if(U.size&&!W?.overwrite){console.log(`
Following files already exist in the directory.`),U.forEach((X)=>{console.log(j.green(`- ${N.relative(B,X.path)}`))});let Y=await B0({type:"confirm",name:"overwrite",onState:Q0,message:"Do you want to overwrite the existing files?",initial:!0});if(Y.overwrite===void 0)console.log(`
Use ${j.cyan("--overwrite")} or ${j.cyan("-o")} flag to overwrite existing files, or run with ${j.cyan("node")} instead of ${j.cyan("bun")}.`),process.exit(1);if(Y.overwrite){let X=V0("Overwriting files").start();U.forEach((M)=>{let x=V.addSourceFileAtPath(N.resolve(M.path));x.replaceWithText(M.code),x.getImportDeclarations().forEach((A)=>{let y=A.getModuleSpecifierValue();A.setModuleSpecifier(q0(y,W.path,Z?.aliases))}),x.saveSync()}),X.succeed("Files are overwritten")}}let G=k();if($?.dependencies?.length){let Y=V0("Installing example dependencies").start();await c0(()=>_0(G,[G==="npm"?"install":"add",...$.dependencies],{cwd:B}).catch(async(X)=>{if(X.message.includes("peer"))Y.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),Y.start("Installing dependencies with --legacy-peer-deps flag"),await _0(G,[G==="npm"?"install":"add",...$.dependencies,"--legacy-peer-deps"],{cwd:B})}),{retries:1}),Y.succeed("Example dependencies are installed")}if($?.devDependencies?.length){let Y=V0("Installing example devDependencies").start();await c0(()=>_0(G,[G==="npm"?"install":"add","-D",...$.devDependencies],{cwd:B}).catch(async(X)=>{if(X.message.includes("peer"))Y.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),Y.start("Installing devDependencies with --legacy-peer-deps flag"),await _0(G,[G==="npm"?"install":"add","-D",...$.devDependencies,"--legacy-peer-deps"],{cwd:B})}),{retries:1}),Y.succeed("Example devDependencies are installed")}if(W?.components?.length)await c0(()=>x0({components:W.components,dir:l0?.projectPath||"",path:W.path,message:""}),{retries:1});console.log(`
\uD83C\uDF89 Example ${j.green(W.example)} has been added to ${j.green(H)}`),process.exit(0)}var a0={name:"untitledui",version:"0.1.48",main:"dist/index.mjs",description:"The Untitled UI CLI tool helps you quickly scaffold projects with Untitled UI React and add components and page examples to your existing projects with an interactive interface in seconds.",type:"module",publishConfig:{access:"public"},scripts:{test:'echo "Error: no test specified" && exit 1',dev:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=http://localhost:3000/react/api --watch",build:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=https://www.untitledui.com/react/api","publish:npm":"bun run build && npm publish --access public",start:"node dist/index.mjs"},bugs:{url:"https://github.com/untitleduico/react/issues"},homepage:"https://github.com/untitleduico/react#readme",keywords:["untitledui","untitled-ui","untitledui","untitledui-cli","untitledui-react","untitledui-components","untitledui-examples","untitledui-vite","untitledui-nextjs","cli","tailwindcss","nextjs","react","components","examples","vite"],files:["dist","config","templates","README.md"],author:{name:"Untitled UI",url:"https://www.untitledui.com/react"},contributors:[{name:"Dilshod Turobov",url:"https://x.com/deebovv"},{name:"Jordan Hughes",url:"https://x.com/jordanphughes"}],license:"MIT",bin:{untitledui:"dist/index.mjs"},exports:"./dist/index.mjs",dependencies:{"async-retry":"^1.3.3",chalk:"^5.6.2",commander:"^13.1.0",execa:"^7.2.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",open:"^10.2.0",ora:"^8.2.0",prettier:"^3.7.4",prompts:"^2.4.2",tar:"^7.5.2","ts-morph":"^25.0.1","tsconfig-paths":"^4.2.0","update-check":"^1.5.4"},devDependencies:{"@types/async-retry":"^1.4.9","@types/prompts":"^2.4.9","@types/tar":"^6.1.13","type-fest":"^4.41.0",typescript:"^5.9.3"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function J3(){let z=new V3().name(a0.name).version(a0.version);z.addCommand(u1).addCommand(K1).addCommand(I1).addCommand(J1),z.parse()}J3();