untitledui 0.1.21 → 0.1.22

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.
@@ -88,8 +88,18 @@
88
88
  --drop-shadow-iphone-mockup: 20px 12px 18px rgba(16, 24, 40, 0.2);
89
89
 
90
90
  /* ANIMATIONS */
91
+ --animate-marquee: marquee 60s linear infinite;
91
92
  --animate-caret-blink: caret-blink 1s infinite;
92
93
 
94
+ @keyframes marquee {
95
+ 0% {
96
+ transform: translateX(0);
97
+ }
98
+ 100% {
99
+ transform: translateX(-100%);
100
+ }
101
+ }
102
+
93
103
  @keyframes caret-blink {
94
104
  0%,
95
105
  50% {
package/dist/index.mjs CHANGED
@@ -1,32 +1,32 @@
1
1
  #!/usr/bin/env node
2
- import{Command as p1}from"commander";import l0 from"async-retry";import _ from"chalk";import{Command as J1,Option as b1}from"commander";import{execa as L0}from"execa";import*as k from"fs";import W0 from"ora";import M1 from"os";import*as D from"path";import Z0 from"prompts";import{Project as H1}from"ts-morph";import W1 from"node-fetch";import{Readable as Y3,pipeline as Z1}from"stream";import{x as Q3}from"tar";import{promisify as $1}from"util";var Z3=$1(Z1);async function r(Q){let z=`https://www.untitledui.com/react/api/validate-key?key=${Q}`;try{return(await W1(z)).status===200}catch{return!1}}import X1 from"node-fetch";var O0={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function A0(Q,z,Y){try{let Z=await X1("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:Q,components:z,key:Y})});if(!Z.ok)console.log(O0?.[Z.statusText]||O0.no_components_found),process.exit(1);return await Z.json()}catch(Z){return null}}import E0 from"node-fetch";var i={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function d0(Q,z=""){let Y=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${Q}`;try{let X=await E0(Y),Z=await X.json();if(!X.ok)console.log(i?.[X.statusText]||i.no_components_found),process.exit(1);if(!Z?.components?.length)return null;return Z}catch(X){return console.error(X),null}}async function h0(Q,z="",Y){let X=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${Q}&subfolders=${Y.join(",")}`;try{let Z=await E0(X);if(!Z.ok)console.log(i?.[Z.statusText]||i.no_components_found),process.exit(1);let U=await Z.json();if(!U?.components?.length)return null;return U}catch(Z){return console.error(Z),null}}async function f0(Q=""){let z=`https://www.untitledui.com/react/api/components/list?key=${Q}`;try{let Y=await E0(z);if(!Y.ok)console.log(i?.[Y.statusText]||i.no_components_found),process.exit(1);let X=await Y.json();if(!X?.types?.length)return null;return X}catch(Y){return console.error(Y),null}}import L1 from"fast-glob";import*as I0 from"path";import{Project as j3}from"ts-morph";import{loadConfig as V1}from"tsconfig-paths";import L3 from"prettier";import U0 from"fast-glob";import*as q0 from"fs";import*as B0 from"path";import{loadConfig as q1}from"tsconfig-paths";var h=["**/node_modules/**",".next","public","dist","build"],m0={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function p(Q){let z=q0.existsSync(B0.resolve(Q,"src")),Y=q0.existsSync(B0.resolve(Q,`${z?"src/":""}app`)),[X,Z,U,b]=await Promise.all([U0.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:Q,deep:2,ignore:h}),B1(Q),U1(Q),K1(Q)]),M={framework:"other",isTsx:Z,tailwindFile:U||null,aliasPrefix:b,isSrcDir:z,isUsingAppDir:Y};if(X.find((J)=>J.startsWith("next.config."))?.length)return M.framework=Y?"next-app":"next-pages",M;else if(X.find((J)=>J.startsWith("vite.config."))?.length)return M.framework="vite",M;else if(X?.length||q0.existsSync(B0.resolve(Q,"package.json")))return M.framework="other",M;return null}async function B1(Q){return(await U0.glob("tsconfig.*",{cwd:Q,deep:2,ignore:h})).length>0}async function U1(Q){let z=await U0.glob("tailwind.config.*",{cwd:Q,deep:2,ignore:h});if(!z.length)return null;return z[0]}async function K1(Q){let z=await q1(Q);if(z?.resultType==="failed"||!Object.keys(z.paths).length)return null;let Y={};for(let[X,Z]of Object.entries(z.paths)){let U=X.replace(/\/\*$/,"/");if(Z.some((b)=>b.includes("/app/*")))Y.appPrefix=U;else if(Z.some((b)=>b.includes("/components/*")))Y.componentsPrefix=U;else if(Z.some((b)=>b.includes("/utils/*")))Y.utilsPrefix=U;else if(Z.some((b)=>b.includes("/styles/*")))Y.stylesPrefix=U;else if(Z.some((b)=>b.includes("./*")||b.includes("/src/*")))Y.srcPrefix=U}return Y||null}function o(Q){let z=V1(Q),Y=L1.sync(["tailwind.config.*","**/globals.css","**/{layout,_app,main}.tsx","package.json"],{cwd:Q,deep:4,absolute:!0,onlyFiles:!0,ignore:h}),X={tailwindFile:Y.find((Z)=>Z.includes("tailwind.config.")),cssFile:Y.find((Z)=>Z.includes("globals.css")),layoutFile:Y.find((Z)=>Z.includes("layout")),appFile:Y.find((Z)=>Z.includes("_app")),mainFile:Y.find((Z)=>Z.includes("main")),packageJson:Y.find((Z)=>Z.includes("package.json")),tsConfig:z?.resultType==="success"?z?.configFileAbsolutePath:void 0};if(z.resultType==="failed")throw new Error(`Failed to load tsconfig.json. ${z.message??""}`.trim());return X}function t(Q,z,Y={},X=""){if(Q.includes("components")){if(Y?.componentsPrefix)return Q.replace(/@\/components\//,I0.posix.join(Y?.componentsPrefix,z?z.replace(/components\//,""):"","/"));if(z){let Z=Y?.srcPrefix?I0.posix.join(Y?.srcPrefix,z,"/"):X;return Q.replace(/@\/components\//,Z)}}if(Q.includes("app")&&Y?.appPrefix)return Q.replace(/^@\/app\//,Y?.appPrefix);if(Q.includes("utils")&&Y?.utilsPrefix)return Q.replace(/^@\/utils\//,Y?.utilsPrefix);if(Q.includes("styles")&&Y?.stylesPrefix)return Q.replace(/^@\/styles\//,Y?.stylesPrefix);if(Y?.srcPrefix)return Q.replace(/^@\//,Y?.srcPrefix);return Q}function x(){if("bun/1.2.15 npm/? node/v22.6.0 darwin arm64".startsWith("yarn"))return"yarn";if("bun/1.2.15 npm/? node/v22.6.0 darwin arm64".startsWith("pnpm"))return"pnpm";if("bun/1.2.15 npm/? node/v22.6.0 darwin arm64".startsWith("bun"))return"bun";return"npm"}function e(){switch(x()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function c0(){switch(x()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}function K0(Q){return Q.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}var v1=D.join(M1.homedir(),".untitledui"),c=D.join(v1,"config.json"),K={components:[],path:"",type:void 0,license:""};if(k.existsSync(c)){let Q=JSON.parse(k.readFileSync(c,"utf-8"));K.license=Q.license}var V0=(Q)=>{if(Q.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
3
- `),process.exit(1)},a0=new J1().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.").addOption(new b1("-l, --license <license-key>","Add a license key for adding components.").hideHelp()).option("-t, --type <base|marketing|shared-assets|application|foundations>","the type of the component to add.").action(async(Q,z)=>{if(Q)K.components=Q;if(z)K.all=z.all,K.dir=z.dir,K.path=z.path,K.overwrite=z.overwrite,K.license=z.license||K.license;try{await R0(K)}catch(Y){console.error(_.red(Y))}});async function R0(Q){if(Q)K={...K,...Q};let z=W0().start(),Y=D.posix.join(process.cwd(),K.dir||"");if(!k.existsSync(D.resolve(Y,"package.json")))z.warn("This command should be run in a project directory."),process.exit(1);let Z=await p(Y);if(K.license){if(!await r(K.license))z.fail("Invalid license key"),process.exit(1);if(!k.existsSync(c)){let q=D.dirname(c);k.mkdirSync(q,{recursive:!0}),k.writeFileSync(c,JSON.stringify({license:K.license},null,2))}if(JSON.parse(k.readFileSync(c,"utf-8")).license!==K.license)k.writeFileSync(c,JSON.stringify({license:K.license},null,2),"utf-8")}z.stop();let U=[];if(K.components.length){let $=await A0(K.type,K.components,K.license);if($&&$.pro&&$.pro.length>0){if(console.log(),$.pro.length===1){let W=$.pro[0]?.split("/")[1]||$.pro[0];console.log(_.yellow(`\uD83D\uDD12 The ${_.cyan(W)} component requires PRO access.`))}else console.log(_.yellow("\uD83D\uDD12 The following components require PRO access:")),$.pro.forEach((W)=>{let q=W?.split("/")[1]||W;console.log(` • ${_.cyan(q)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${_.green("→")} If you've already purchased: ${_.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${_.green("→")} To purchase PRO components: ${_.cyan("https://www.untitledui.com/buy/react")}`),console.log()}if(!$?.components.length)console.log("No components found"),process.exit(1);U.push(...$.components)}if(!K?.type&&!K?.components.length){let $=await f0(K.license);if(!$)console.log("No component types found"),process.exit(1);let W=await Z0({type:"select",name:"type",onState:V0,message:`What type of ${_.cyan("component")} are you adding?`,choices:$?.types.map((q)=>({title:q,value:q}))});K.type=W.type}if(!K?.path){let $=await Z0({type:"text",name:"path",onState:V0,message:`Where would you like to add the ${_.cyan("components")}?`,initial:"components"});K.path=$.path}if(!K?.components.length){let $=await d0(K?.type,K.license);if(!$)console.log("No components found"),process.exit(1);let W=await Z0({type:"multiselect",name:"components",onState:V0,message:`Which ${_.cyan("components")} would you like to add?`,choices:$?.components?.map((V)=>({title:V?.name+(V?.count?` (${V?.count} variants)`:"")||"example",value:V||"example",selected:K.components.includes(V.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!W.components||!W.components.length)console.log("No option selected. Exiting..."),process.exit(1);let q=W.components.filter((V)=>V?.type==="file").map((V)=>V.name),L=W.components.filter((V)=>V?.type==="dir").map((V)=>V.name),S=[];if(L.length){let V=await h0(K?.type,K.license,L);if(V&&V.components.length)for(let C of V.components){let[u,g]=Object.entries(C)[0]||[],E=await Z0({type:"select",name:"component",onState:V0,message:`Which ${_.cyan("variant")} from ${_.cyan(u)} would you like to add?`,choices:g?.map((N)=>({title:N?.name||"example",value:N?.name||"example",selected:K.components.includes(N.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!E.component)console.log("No variant selected for "+_.cyan(u));S.push(u+"/"+E.component)}else console.log("No variants found")}K.components=[...S,...q]}if(!K.components?.length)z.warn("No components selected. Exiting."),process.exit(1);let b=o(Y),M=new Set,J=new Set,R=new Set,y=new H1({tsConfigFilePath:b?.tsConfig});if(K.type&&K.components.length){let $=await A0(K.type,K.components,K.license);if(!$?.components.length)console.log("No components found"),process.exit(1);U.push(...$.components)}if(U.forEach(($)=>{let W=W0(`Adding ${$.name}...`).start(),q=$.files;$.dependencies.forEach((L)=>J.add(L)),$.devDependencies.forEach((L)=>R.add(L));try{if(q?.forEach(async({path:L,code:S})=>{let V=D.posix.join(Y,`${Z?.isSrcDir&&"src"}`,L.replace(/components\//,K.path+"/")),C=Z?.framework==="vite"?S.replace(`"use client";
2
+ import{Command as p1}from"commander";import l0 from"async-retry";import _ from"chalk";import{Command as V1,Option as b1}from"commander";import{execa as K0}from"execa";import*as F from"fs";import W0 from"ora";import u1 from"os";import*as D from"path";import Z0 from"prompts";import{Project as M1}from"ts-morph";import W1 from"node-fetch";import{Readable as Y3,pipeline as Z1}from"stream";import{x as Q3}from"tar";import{promisify as $1}from"util";var Z3=$1(Z1);async function i(Q){let z=`https://www.untitledui.com/react/api/validate-key?key=${Q}`;try{return(await W1(z)).status===200}catch{return!1}}import X1 from"node-fetch";var O0={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function A0(Q,z,Y){try{let Z=await X1("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:Q,components:z,key:Y})});if(!Z.ok)console.log(O0?.[Z.statusText]||O0.no_components_found),process.exit(1);return await Z.json()}catch(Z){return null}}import G0 from"node-fetch";var r={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function d0(Q,z=""){let Y=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${Q}`;try{let X=await G0(Y),Z=await X.json();if(!X.ok)console.log(r?.[X.statusText]||r.no_components_found),process.exit(1);if(!Z?.components?.length)return null;return Z}catch(X){return console.error(X),null}}async function h0(Q,z="",Y){let X=`https://www.untitledui.com/react/api/components/list?key=${z}&type=${Q}&subfolders=${Y.join(",")}`;try{let Z=await G0(X);if(!Z.ok)console.log(r?.[Z.statusText]||r.no_components_found),process.exit(1);let B=await Z.json();if(!B?.components?.length)return null;return B}catch(Z){return console.error(Z),null}}async function f0(Q=""){let z=`https://www.untitledui.com/react/api/components/list?key=${Q}`;try{let Y=await G0(z);if(!Y.ok)console.log(r?.[Y.statusText]||r.no_components_found),process.exit(1);let X=await Y.json();if(!X?.types?.length)return null;return X}catch(Y){return console.error(Y),null}}import K1 from"fast-glob";import*as E0 from"path";import{Project as j3}from"ts-morph";import{loadConfig as L1}from"tsconfig-paths";import K3 from"prettier";import B0 from"fast-glob";import*as q0 from"fs";import*as U0 from"path";import{loadConfig as q1}from"tsconfig-paths";var h=["**/node_modules/**",".next","public","dist","build"],m0={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function p(Q){let z=q0.existsSync(U0.resolve(Q,"src")),Y=q0.existsSync(U0.resolve(Q,`${z?"src/":""}app`)),[X,Z,B,b]=await Promise.all([B0.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:Q,deep:2,ignore:h}),U1(Q),B1(Q),J1(Q)]),u={framework:"other",isTsx:Z,tailwindFile:B||null,aliasPrefix:b,isSrcDir:z,isUsingAppDir:Y};if(X.find((V)=>V.startsWith("next.config."))?.length)return u.framework=Y?"next-app":"next-pages",u;else if(X.find((V)=>V.startsWith("vite.config."))?.length)return u.framework="vite",u;else if(X?.length||q0.existsSync(U0.resolve(Q,"package.json")))return u.framework="other",u;return null}async function U1(Q){return(await B0.glob("tsconfig.*",{cwd:Q,deep:2,ignore:h})).length>0}async function B1(Q){let z=await B0.glob("tailwind.config.*",{cwd:Q,deep:2,ignore:h});if(!z.length)return null;return z[0]}async function J1(Q){let z=await q1(Q);if(z?.resultType==="failed"||!Object.keys(z.paths).length)return null;let Y={};for(let[X,Z]of Object.entries(z.paths)){let B=X.replace(/\/\*$/,"/");if(Z.some((b)=>b.includes("/app/*")))Y.appPrefix=B;else if(Z.some((b)=>b.includes("/components/*")))Y.componentsPrefix=B;else if(Z.some((b)=>b.includes("/utils/*")))Y.utilsPrefix=B;else if(Z.some((b)=>b.includes("/styles/*")))Y.stylesPrefix=B;else if(Z.some((b)=>b.includes("./*")||b.includes("/src/*")))Y.srcPrefix=B}return Y||null}function t(Q){let z=L1(Q),Y=K1.sync(["tailwind.config.*","**/globals.css","**/{layout,_app,main}.tsx","package.json"],{cwd:Q,deep:4,absolute:!0,onlyFiles:!0,ignore:h}),X={tailwindFile:Y.find((Z)=>Z.includes("tailwind.config.")),cssFile:Y.find((Z)=>Z.includes("globals.css")),layoutFile:Y.find((Z)=>Z.includes("layout")),appFile:Y.find((Z)=>Z.includes("_app")),mainFile:Y.find((Z)=>Z.includes("main")),packageJson:Y.find((Z)=>Z.includes("package.json")),tsConfig:z?.resultType==="success"?z?.configFileAbsolutePath:void 0};if(z.resultType==="failed")throw new Error(`Failed to load tsconfig.json. ${z.message??""}`.trim());return X}function o(Q,z,Y={},X=""){if(Q.includes("components")){if(Y?.componentsPrefix)return Q.replace(/@\/components\//,E0.posix.join(Y?.componentsPrefix,z?z.replace(/components\//,""):"","/"));if(z){let Z=Y?.srcPrefix?E0.posix.join(Y?.srcPrefix,z,"/"):X;return Q.replace(/@\/components\//,Z)}}if(Q.includes("app")&&Y?.appPrefix)return Q.replace(/^@\/app\//,Y?.appPrefix);if(Q.includes("utils")&&Y?.utilsPrefix)return Q.replace(/^@\/utils\//,Y?.utilsPrefix);if(Q.includes("styles")&&Y?.stylesPrefix)return Q.replace(/^@\/styles\//,Y?.stylesPrefix);if(Y?.srcPrefix)return Q.replace(/^@\//,Y?.srcPrefix);return Q}function x(){if("bun/1.2.15 npm/? node/v22.6.0 darwin arm64".startsWith("yarn"))return"yarn";if("bun/1.2.15 npm/? node/v22.6.0 darwin arm64".startsWith("pnpm"))return"pnpm";if("bun/1.2.15 npm/? node/v22.6.0 darwin arm64".startsWith("bun"))return"bun";return"npm"}function e(){switch(x()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function c0(){switch(x()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}function J0(Q){return Q.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}var v1=D.join(u1.homedir(),".untitledui"),c=D.join(v1,"config.json"),J={components:[],path:"",type:void 0,license:""};if(F.existsSync(c)){let Q=JSON.parse(F.readFileSync(c,"utf-8"));J.license=Q.license}var L0=(Q)=>{if(Q.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
3
+ `),process.exit(1)},a0=new V1().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.").addOption(new b1("-l, --license <license-key>","Add a license key for adding components.").hideHelp()).option("-t, --type <base|marketing|shared-assets|application|foundations>","The type of the component to add.").action(async(Q,z)=>{if(Q)J.components=Q;if(z)J.all=z.all,J.dir=z.dir,J.path=z.path,J.overwrite=z.overwrite,J.license=z.license||J.license;try{await I0(J)}catch(Y){console.error(_.red(Y))}});async function I0(Q){if(Q)J={...J,...Q};let z=W0().start(),Y=D.posix.join(process.cwd(),J.dir||"");if(!F.existsSync(D.resolve(Y,"package.json")))z.warn("This command should be run in a project directory."),process.exit(1);let Z=await p(Y);if(J.license){if(!await i(J.license))z.fail("Invalid license key"),process.exit(1);if(!F.existsSync(c)){let q=D.dirname(c);F.mkdirSync(q,{recursive:!0}),F.writeFileSync(c,JSON.stringify({license:J.license},null,2))}if(JSON.parse(F.readFileSync(c,"utf-8")).license!==J.license)F.writeFileSync(c,JSON.stringify({license:J.license},null,2),"utf-8")}z.stop();let B=[];if(J.components.length){let $=await A0(J.type,J.components,J.license);if($&&$.pro&&$.pro.length>0){if(console.log(),$.pro.length===1){let W=$.pro[0]?.split("/")[1]||$.pro[0];console.log(_.yellow(`\uD83D\uDD12 The ${_.cyan(W)} component requires PRO access.`))}else console.log(_.yellow("\uD83D\uDD12 The following components require PRO access:")),$.pro.forEach((W)=>{let q=W?.split("/")[1]||W;console.log(` • ${_.cyan(q)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${_.green("→")} If you've already purchased: ${_.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${_.green("→")} To purchase PRO components: ${_.cyan("https://www.untitledui.com/buy/react")}`),console.log()}if(!$?.components.length)console.log("No components found"),process.exit(1);B.push(...$.components)}if(!J?.type&&!J?.components.length){let $=await f0(J.license);if(!$)console.log("No component types found"),process.exit(1);let W=await Z0({type:"select",name:"type",onState:L0,message:`What type of ${_.cyan("component")} are you adding?`,choices:$?.types.map((q)=>({title:q,value:q}))});J.type=W.type}if(!J?.path){let $=await Z0({type:"text",name:"path",onState:L0,message:`Where would you like to add the ${_.cyan("components")}?`,initial:"components"});J.path=$.path}if(!J?.components.length){let $=await d0(J?.type,J.license);if(!$)console.log("No components found"),process.exit(1);let W=await Z0({type:"multiselect",name:"components",onState:L0,message:`Which ${_.cyan("components")} would you like to add?`,choices:$?.components?.map((L)=>({title:L?.name+(L?.count?` (${L?.count} variants)`:"")||"example",value:L||"example",selected:J.components.includes(L.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!W.components||!W.components.length)console.log("No option selected. Exiting..."),process.exit(1);let q=W.components.filter((L)=>L?.type==="file").map((L)=>L.name),K=W.components.filter((L)=>L?.type==="dir").map((L)=>L.name),S=[];if(K.length){let L=await h0(J?.type,J.license,K);if(L&&L.components.length)for(let C of L.components){let[R,g]=Object.entries(C)[0]||[],G=await Z0({type:"select",name:"component",onState:L0,message:`Which ${_.cyan("variant")} from ${_.cyan(R)} would you like to add?`,choices:g?.map((T)=>({title:T?.name||"example",value:T?.name||"example",selected:J.components.includes(T.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!G.component)console.log("No variant selected for "+_.cyan(R));S.push(R+"/"+G.component)}else console.log("No variants found")}J.components=[...S,...q]}if(!J.components?.length)z.warn("No components selected. Exiting."),process.exit(1);let b=t(Y),u=new Set,V=new Set,I=new Set,w=new M1({tsConfigFilePath:b?.tsConfig});if(J.type&&J.components.length){let $=await A0(J.type,J.components,J.license);if(!$?.components.length)console.log("No components found"),process.exit(1);B.push(...$.components)}if(B.forEach(($)=>{let W=W0(`Adding ${$.name}...`).start(),q=$.files;$.dependencies.forEach((K)=>V.add(K)),$.devDependencies.forEach((K)=>I.add(K));try{if(q?.forEach(async({path:K,code:S})=>{let L=D.posix.join(Y,`${Z?.isSrcDir&&"src"}`,K.replace(/components\//,J.path+"/")),C=Z?.framework==="vite"?S.replace(`"use client";
4
4
 
5
- `,""):S,u=K0(C),g=D.dirname(V);if(k.existsSync(V)&&!K.overwrite){if(k.readFileSync(V,"utf-8")!==u)M.add({code:u,path:V})}else{k.mkdirSync(g,{recursive:!0}),k.writeFileSync(V,u);let E=D.relative(D.resolve(Y,`${Z?.isSrcDir&&"src"}`,K.path),V).split("/").length,N=E===1?"./":"../".repeat(E-1),F=y.addSourceFileAtPath(D.resolve(V));F.getImportDeclarations().forEach((P)=>{let Q0=P.getModuleSpecifierValue();P.setModuleSpecifier(t(Q0,K.path,Z?.aliasPrefix,N))}),await F.save()}}),M.size)W.warn(`Some files of ${_.yellow($.name)} already exist`);else W.succeed(`${_.green($.name)} is added successfully`)}catch(L){W.fail(`
6
- Failed to add the component ${_.red($.name)}`),console.error(_.red(L)),process.exit(1)}}),M.size&&!K?.overwrite)if(console.log(`
7
- Following files already exist in the directory.`),M.forEach((W)=>{console.log(_.green(`- ${D.relative(Y,W.path)}`))}),(await Z0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let W=W0("Overwriting files").start();M.forEach((q)=>{let L=D.relative(D.resolve(Y,`${Z?.isSrcDir&&"src"}`,K.path),q.path).split("/").length,S=L===1?"./":"../".repeat(L-1),V=y.addSourceFileAtPath(D.resolve(q.path));V.replaceWithText(q.code),V.getImportDeclarations().forEach((C)=>{let u=C.getModuleSpecifierValue();C.setModuleSpecifier(t(u,K.path,Z?.aliasPrefix,S))}),V.saveSync()}),W.succeed("Files are overwritten")}else console.log(`Use ${_.cyan("--overwrite")} or ${_.cyan("-o")} to overwrite existing files, or refer to the documentation ${_.cyan("https://www.untitled.com/docs")} for manual installation. The rest of the files are added.`),process.exit(1);let A=x();if(J?.size){let $=W0("Installing component dependencies").start();await l0(()=>L0(A,[A==="npm"?"install":"add",...J],{cwd:Y}).catch(async(W)=>{if(W.message.includes("peer"))$.warn("Component dependencies conflict detected. Retrying with --legacy-peer-deps..."),$.start("Installing component dependencies with --legacy-peer-deps flag"),await L0(A,[A==="npm"?"install":"add",...J,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),$.succeed("Component dependencies are installed")}if(R?.size){let $=W0("Installing component devDependencies").start();await l0(()=>L0(A,[A==="npm"?"install":"add","-D",...R],{cwd:Y}).catch(async(W)=>{if(W.message.includes("peer"))$.warn("Component devDependencies conflict detected. Retrying with --legacy-peer-deps..."),$.start("Installing component devDependencies with --legacy-peer-deps flag"),await L0(A,[A==="npm"?"install":"add","-D",...R,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),$.succeed("Component devDependencies are installed")}if(K.message)console.log(K.message);process.exit(0)}import N0 from"chalk";import{Command as j1}from"commander";import*as f from"fs";import A1 from"http";import E1 from"open";import I1 from"ora";import R1 from"os";import*as D0 from"path";import{URL as u1}from"url";import*as s0 from"fs";import*as u0 from"path";var __dirname="/Users/deebov/Developer/untitledui/react/cli/utils",G1=u0.join(__dirname,"..","templates");function n0(){let Q=u0.join(G1,"auth-template.html");return s0.readFileSync(Q,"utf-8")}function r0(){return n0().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 J0(Q){return n0().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",Q).replace("{{AUTO_CLOSE_SCRIPT}}","")}var T0=D0.join(R1.homedir(),".untitledui"),_0=D0.join(T0,"config.json"),i0=new j1().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let Q=I1("Starting authentication...").start();try{await _1(Q),Q.succeed("Authentication completed successfully!"),console.log(N0.green(`
8
- ✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch(z){Q.fail(`Authentication failed: ${z instanceof Error?z.message:z}`),process.exit(1)}});async function _1(Q){return new Promise((z,Y)=>{let X=A1.createServer((Z,U)=>{let b=new u1(Z.url,"http://localhost");if(b.pathname==="/callback"){let M=b.searchParams.get("apiKey"),J=b.searchParams.get("error");if(J){U.writeHead(400,{"Content-Type":"text/html"}),U.end(J0(decodeURIComponent(J))),X.close(),Y(new Error(decodeURIComponent(J)));return}if(!M){U.writeHead(400,{"Content-Type":"text/html"}),U.end(J0("No Access Token received")),X.close(),Y(new Error("No Access Token received"));return}try{N1(M),U.writeHead(200,{"Content-Type":"text/html"}),U.end(r0()),X.close(),z()}catch(R){U.writeHead(500,{"Content-Type":"text/html"}),U.end(J0("Failed to save authentication data")),X.close(),Y(R)}}else U.writeHead(404),U.end("Not found")});X.listen(0,"localhost",()=>{let b=`https://www.untitledui.com/react/api/cli-auth?port=${X.address().port}`;Q.text="Opening browser for authentication...",E1(b).catch((M)=>{console.log(N0.yellow(`
9
- Failed to open browser automatically: ${M.message}`)),console.log(N0.cyan(`Please manually open: ${b}
10
- `))}),Q.text="Waiting for authentication in browser..."}),setTimeout(()=>{X.close(),Y(new Error("Authentication timeout. Please try again."))},300000)})}function N1(Q){if(!f.existsSync(T0))f.mkdirSync(T0,{recursive:!0});let z={};if(f.existsSync(_0))try{z=JSON.parse(f.readFileSync(_0,"utf-8"))}catch{z={}}z.license=Q,f.writeFileSync(_0,JSON.stringify(z,null,2),"utf-8")}import F0 from"async-retry";import H from"chalk";import{Command as c1,Option as l1}from"commander";import{execa as j0}from"execa";import*as w from"fs";import X0 from"ora";import a1 from"os";import*as G from"path";import s from"prompts";import{Project as s1}from"ts-morph";import T1 from"node-fetch";async function b0(Q,z){try{let X=await T1("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:Q,key:z})});if(!X.ok){if(X.status===401||X.status===403)return{type:"error",status:X.status,message:"PRO access required"};return console.error(`API error: ${X.status} - ${X.statusText}`),null}return await X.json()}catch(X){return console.error(X?.message||"Error fetching example data."),null}}import $0 from"async-retry";import I from"chalk";import{Command as k1}from"commander";import{execa as l}from"execa";import v0 from"fast-glob";import T from"fs";import Y0 from"ora";import F1 from"os";import*as j from"path";import G0 from"prompts";import{Project as P1}from"ts-morph";import{fileURLToPath as g1}from"url";import*as M0 from"fs";import*as p0 from"path";function w0(Q,z){let Y=p0.join(Q,"package.json");if(!M0.existsSync(Y))return z;let X=JSON.parse(M0.readFileSync(Y,"utf-8")),Z={...X.dependencies,...X.devDependencies},U=[];for(let b of z){let M=Z[b];if(!M){U.push(b);continue}if(b==="tailwindcss"){let J=M.match(/\d+/);if((J?parseInt(J[0],10):0)<4)U.push(b)}}return U}import D1 from"node-fetch";import{posix as t0,sep as w1}from"node:path";import{Readable as y1}from"node:stream";import{pipeline as S1}from"node:stream/promises";import{x as C1}from"tar";var o0=[".DS_Store",".git","node_modules","bun.lockb","yarn.lock","package-lock.json"];async function e0(Q,{username:z,repo:Y,branch:X,template:Z}){try{let U=`https://codeload.github.com/${z}/${Y}/tar.gz/${X}`,b=await x1(U);await S1(b,C1({cwd:Q,strip:1,filter:(M)=>{let J=M.split(t0.sep)?.pop()||"";if(o0.includes(J))return!1;if(Z)return M.split(w1).join(t0.sep).includes(Z);return!0}}))}catch(U){if(U instanceof Error)throw new Error(`Failed to download or extract repository: ${U.message}`);throw U}}async function x1(Q){let z=await D1(Q);if(!z.ok)throw new Error(`Failed to download: ${Q} - Status: ${z.status} ${z.statusText}`);if(!z.body)throw new Error(`Failed to download: ${Q} - No response body`);let Y=z.headers.get("content-type");if(Y&&!Y.includes("application/x-gzip")&&!Y.includes("application/octet-stream"))console.warn(`Warning: Unexpected content type: ${Y}. Expected application/x-gzip or application/octet-stream.`);return y1.from(z.body)}import y0 from"chalk";import*as m from"fs";import*as H0 from"path";function S0(Q){if(!m.existsSync(H0.resolve(Q)))console.log(y0.red(`Error: CSS file not found at ${Q}`)),process.exit(1);let z=m.readFileSync(H0.resolve(Q),"utf-8"),Y=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,X={},Z;while((Z=Y.exec(z))!==null)if(Z[1]&&Z[2])X[Z[1]]=Z[2];return X}function C0(Q,z,Y){let X=H0.resolve(Y);if(!m.existsSync(X)){console.log(y0.red(`Error: CSS file not found at ${X}`));return}let Z=m.readFileSync(X,"utf-8"),U=S0(Y),b={},M={};for(let[R,y]of Object.entries(U))if(R.startsWith(`--color-${Q}-`)){let A=R.replace(`--color-${Q}-`,"");b[A]=R}else if(R.startsWith(`--color-${z}-`)){let A=R.replace(`--color-${z}-`,"");M[A]=y}let J=!1;for(let[R,y]of Object.entries(b))if(M[R]){let A=M[R],$=new RegExp(`(${y}):\\s*rgb\\([^)]*\\);?`,"g");if($.test(Z))Z=Z.replace($,`$1: ${A};`),J=!0;else console.log(y0.yellow(`No match found for ${y}`))}if(J)m.writeFileSync(X,Z,"utf-8")}var O1=g1(import.meta.url),Y1=j.dirname(O1),d1=j.join(F1.homedir(),".untitledui"),a=j.join(d1,"config.json"),h1={"untitledui-nextjs-starter-temp":"Next.js","untitledui-vite-starter-temp":"Vite"},f1="untitledui-vite-starter-temp",m1="untitledui-nextjs-starter-temp",d="",v={color:"",template:"",framework:void 0};if(T.existsSync(a)){let Q=JSON.parse(T.readFileSync(a,"utf-8"));v.license=Q.license}var x0=(Q)=>{if(Q.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
11
- `),process.exit(1)},z1=new k1().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("--next","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.").option("-l, --license <license-key>","Add a license key to download the repository.").action(async(Q,z)=>{if(Q)d=Q;if(z){if(v.color=z.color,v.template=z.template,v.overwrite=z.overwrite,v.colorsList=z.colorsList,v.license=z.license||v.license,v.vite=z.vite,v.next=z.next,z.vite)v.framework=f1;if(z.next)v.framework=m1}try{await k0(z),process.exit(0)}catch(Y){console.error(I.red(Y)),process.exit(1)}});async function k0(Q,z=null){let Y=process.cwd(),X=T.existsSync(j.resolve(Y,"package.json")),Z=j.resolve(j.join(Y1,"../config/styles","theme.css")),U=S0(Z??""),b=Array.from(new Set(Object.keys(U).map(($)=>$?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),M=Y0().start(),J=await p(Y),R=X?v0.sync(["**/**/theme.css"],{cwd:Y,absolute:!0,onlyFiles:!0,ignore:h}):[],y=R?.[0]&&T.readFileSync(R[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0;if(v.license){if(!await r(v.license))M.fail("Invalid license key"),process.exit(1);if(!T.existsSync(a)){let q=j.dirname(a);T.mkdirSync(q,{recursive:!0}),T.writeFileSync(a,JSON.stringify({license:v.license},null,2))}if(JSON.parse(T.readFileSync(a,"utf-8")).license!==v.license)T.writeFileSync(a,JSON.stringify({license:v.license},null,2))}if(!X){if(M.stop(),!d){let $=await G0({onState:x0,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof $.path==="string")d=$.path.trim()}if(z)z.projectPath=d;if(T.existsSync(j.resolve(j.posix.join(Y,d))))M.fail(I.red("Directory already exists!")),process.exit(1);if(v.vite&&v.next||!v.framework){let $=await G0({type:"select",name:"framework",onState:x0,message:`Which ${I.cyan("framework")} would you like to use?`,choices:[{title:I.cyan("Next"),value:"nextjs-starter"},{title:I.yellow("Vite"),value:"vite-starter"}]});v.framework=$.framework}M.succeed("Framework is selected: "+I.green(h1[v.framework]))}else if(J?.framework==="other")M.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${I.cyan("https://www.untitled.com/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(J?.framework.startsWith("next")||J?.framework.startsWith("vite"))if(!z&&!y)M.succeed(I.yellow(`Detected ${m0[J.framework]} project, proceeding with the setup...`));else M.stop();if(v.colorsList||!v.color&&!y){let $=await G0({type:"select",name:"color",onState:x0,initial:Q.color??"",message:`Which ${I.cyan("color")} would you like to use as the ${I.cyanBright("brand")} color?`,choices:b.map((W)=>({title:W,value:W}))});v.color=$.color}let A=j.posix.join(Y,d||"");if(d&&!X){let $=j.resolve(d);console.log(`
12
- Creating a new project in ${I.blue(d)}`);let W=Y0("Downloading and extracting the repository...").start();try{T.mkdirSync($,{recursive:!0}),await $0(()=>e0($,{branch:"main",username:"untitleduico",repo:v.framework}),{retries:2}),W.succeed("Files are downloaded and extracted successfully!");let q=Y0({text:"Installing dependencies..."}).start(),L=v0.sync(["**/styles/theme.css"],{cwd:$,absolute:!0,onlyFiles:!0})[0];if(C0("brand",v.color||"",L??""),await $0(()=>l(x(),["install"],{cwd:A}).catch(async(S)=>{if(S.message.includes("peer"))q.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing dependencies with --legacy-peer-deps flag"),await l(x(),["install","--legacy-peer-deps"],{cwd:A})}),{retries:1}),await $0(()=>l("git",["init"],{cwd:A}),{retries:1}),q.succeed("Dependencies are installed"),!z)console.log(`
5
+ `,""):S,R=J0(C),g=D.dirname(L);if(F.existsSync(L)&&!J.overwrite){if(F.readFileSync(L,"utf-8")!==R)u.add({code:R,path:L})}else{F.mkdirSync(g,{recursive:!0}),F.writeFileSync(L,R);let G=D.relative(D.resolve(Y,`${Z?.isSrcDir&&"src"}`,J.path),L).split("/").length,T=G===1?"./":"../".repeat(G-1),k=w.addSourceFileAtPath(D.resolve(L));k.getImportDeclarations().forEach((P)=>{let Q0=P.getModuleSpecifierValue();P.setModuleSpecifier(o(Q0,J.path,Z?.aliasPrefix,T))}),await k.save()}}),u.size)W.warn(`Some files of ${_.yellow($.name)} already exist`);else W.succeed(`${_.green($.name)} is added successfully`)}catch(K){W.fail(`
6
+ Failed to add the component ${_.red($.name)}`),console.error(_.red(K)),process.exit(1)}}),u.size&&!J?.overwrite)if(console.log(`
7
+ Following files already exist in the directory.`),u.forEach((W)=>{console.log(_.green(`- ${D.relative(Y,W.path)}`))}),(await Z0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let W=W0("Overwriting files").start();u.forEach((q)=>{let K=D.relative(D.resolve(Y,`${Z?.isSrcDir&&"src"}`,J.path),q.path).split("/").length,S=K===1?"./":"../".repeat(K-1),L=w.addSourceFileAtPath(D.resolve(q.path));L.replaceWithText(q.code),L.getImportDeclarations().forEach((C)=>{let R=C.getModuleSpecifierValue();C.setModuleSpecifier(o(R,J.path,Z?.aliasPrefix,S))}),L.saveSync()}),W.succeed("Files are overwritten")}else console.log(`Use ${_.cyan("--overwrite")} or ${_.cyan("-o")} to overwrite existing files, or refer to the documentation ${_.cyan("https://www.untitled.com/docs")} for manual installation. The rest of the files are added.`),process.exit(1);let A=x();if(V?.size){let $=W0("Installing component dependencies").start();await l0(()=>K0(A,[A==="npm"?"install":"add",...V],{cwd:Y}).catch(async(W)=>{if(W.message.includes("peer"))$.warn("Component dependencies conflict detected. Retrying with --legacy-peer-deps..."),$.start("Installing component dependencies with --legacy-peer-deps flag"),await K0(A,[A==="npm"?"install":"add",...V,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),$.succeed("Component dependencies are installed")}if(I?.size){let $=W0("Installing component devDependencies").start();await l0(()=>K0(A,[A==="npm"?"install":"add","-D",...I],{cwd:Y}).catch(async(W)=>{if(W.message.includes("peer"))$.warn("Component devDependencies conflict detected. Retrying with --legacy-peer-deps..."),$.start("Installing component devDependencies with --legacy-peer-deps flag"),await K0(A,[A==="npm"?"install":"add","-D",...I,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),$.succeed("Component devDependencies are installed")}if(J.message)console.log(J.message);process.exit(0)}import T0 from"chalk";import{Command as j1}from"commander";import*as f from"fs";import A1 from"http";import G1 from"open";import E1 from"ora";import I1 from"os";import*as D0 from"path";import{URL as R1}from"url";import*as n0 from"fs";import*as R0 from"path";var __dirname="/Users/deebov/Developer/untitledui/react/cli/utils",H1=R0.join(__dirname,"..","templates");function s0(){let Q=R0.join(H1,"auth-template.html");return n0.readFileSync(Q,"utf-8")}function i0(){return s0().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 V0(Q){return s0().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",Q).replace("{{AUTO_CLOSE_SCRIPT}}","")}var N0=D0.join(I1.homedir(),".untitledui"),_0=D0.join(N0,"config.json"),r0=new j1().name("login").description("Authenticate with Untitled UI to access PRO components").action(async()=>{let Q=E1("Starting authentication...").start();try{await _1(Q),Q.succeed("Authentication completed successfully!"),console.log(T0.green(`
8
+ ✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch(z){Q.fail(`Authentication failed: ${z instanceof Error?z.message:z}`),process.exit(1)}});async function _1(Q){return new Promise((z,Y)=>{let X=A1.createServer((Z,B)=>{let b=new R1(Z.url,"http://localhost");if(b.pathname==="/callback"){let u=b.searchParams.get("apiKey"),V=b.searchParams.get("error");if(V){B.writeHead(400,{"Content-Type":"text/html"}),B.end(V0(decodeURIComponent(V))),X.close(),Y(new Error(decodeURIComponent(V)));return}if(!u){B.writeHead(400,{"Content-Type":"text/html"}),B.end(V0("No Access Token received")),X.close(),Y(new Error("No Access Token received"));return}try{T1(u),B.writeHead(200,{"Content-Type":"text/html"}),B.end(i0()),X.close(),z()}catch(I){B.writeHead(500,{"Content-Type":"text/html"}),B.end(V0("Failed to save authentication data")),X.close(),Y(I)}}else B.writeHead(404),B.end("Not found")});X.listen(0,"localhost",()=>{let b=`https://www.untitledui.com/react/api/cli-auth?port=${X.address().port}`;Q.text="Opening browser for authentication...",G1(b).catch((u)=>{console.log(T0.yellow(`
9
+ Failed to open browser automatically: ${u.message}`)),console.log(T0.cyan(`Please manually open: ${b}
10
+ `))}),Q.text="Waiting for authentication in browser..."}),setTimeout(()=>{X.close(),Y(new Error("Authentication timeout. Please try again."))},300000)})}function T1(Q){if(!f.existsSync(N0))f.mkdirSync(N0,{recursive:!0});let z={};if(f.existsSync(_0))try{z=JSON.parse(f.readFileSync(_0,"utf-8"))}catch{z={}}z.license=Q,f.writeFileSync(_0,JSON.stringify(z,null,2),"utf-8")}import k0 from"async-retry";import M from"chalk";import{Command as c1,Option as l1}from"commander";import{execa as j0}from"execa";import*as y from"fs";import X0 from"ora";import a1 from"os";import*as H from"path";import n from"prompts";import{Project as n1}from"ts-morph";import N1 from"node-fetch";async function b0(Q,z){try{let X=await N1("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:Q,key:z})});if(!X.ok){if(X.status===401||X.status===403)return{type:"error",status:X.status,message:"PRO access required"};return console.error(`API error: ${X.status} - ${X.statusText}`),null}return await X.json()}catch(X){return console.error(X?.message||"Error fetching example data."),null}}import $0 from"async-retry";import E from"chalk";import{Command as F1}from"commander";import{execa as l}from"execa";import v0 from"fast-glob";import N from"fs";import Y0 from"ora";import k1 from"os";import*as j from"path";import H0 from"prompts";import{Project as P1}from"ts-morph";import{fileURLToPath as g1}from"url";import*as u0 from"fs";import*as p0 from"path";function y0(Q,z){let Y=p0.join(Q,"package.json");if(!u0.existsSync(Y))return z;let X=JSON.parse(u0.readFileSync(Y,"utf-8")),Z={...X.dependencies,...X.devDependencies},B=[];for(let b of z){let u=Z[b];if(!u){B.push(b);continue}if(b==="tailwindcss"){let V=u.match(/\d+/);if((V?parseInt(V[0],10):0)<4)B.push(b)}}return B}import D1 from"node-fetch";import{posix as o0,sep as y1}from"node:path";import{Readable as w1}from"node:stream";import{pipeline as S1}from"node:stream/promises";import{x as C1}from"tar";var t0=[".DS_Store",".git","node_modules","bun.lockb","yarn.lock","package-lock.json"];async function e0(Q,{username:z,repo:Y,branch:X,template:Z}){try{let B=`https://codeload.github.com/${z}/${Y}/tar.gz/${X}`,b=await x1(B);await S1(b,C1({cwd:Q,strip:1,filter:(u)=>{let V=u.split(o0.sep)?.pop()||"";if(t0.includes(V))return!1;if(Z)return u.split(y1).join(o0.sep).includes(Z);return!0}}))}catch(B){if(B instanceof Error)throw new Error(`Failed to download or extract repository: ${B.message}`);throw B}}async function x1(Q){let z=await D1(Q);if(!z.ok)throw new Error(`Failed to download: ${Q} - Status: ${z.status} ${z.statusText}`);if(!z.body)throw new Error(`Failed to download: ${Q} - No response body`);let Y=z.headers.get("content-type");if(Y&&!Y.includes("application/x-gzip")&&!Y.includes("application/octet-stream"))console.warn(`Warning: Unexpected content type: ${Y}. Expected application/x-gzip or application/octet-stream.`);return w1.from(z.body)}import w0 from"chalk";import*as m from"fs";import*as M0 from"path";function S0(Q){if(!m.existsSync(M0.resolve(Q)))console.log(w0.red(`Error: CSS file not found at ${Q}`)),process.exit(1);let z=m.readFileSync(M0.resolve(Q),"utf-8"),Y=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,X={},Z;while((Z=Y.exec(z))!==null)if(Z[1]&&Z[2])X[Z[1]]=Z[2];return X}function C0(Q,z,Y){let X=M0.resolve(Y);if(!m.existsSync(X)){console.log(w0.red(`Error: CSS file not found at ${X}`));return}let Z=m.readFileSync(X,"utf-8"),B=S0(Y),b={},u={};for(let[I,w]of Object.entries(B))if(I.startsWith(`--color-${Q}-`)){let A=I.replace(`--color-${Q}-`,"");b[A]=I}else if(I.startsWith(`--color-${z}-`)){let A=I.replace(`--color-${z}-`,"");u[A]=w}let V=!1;for(let[I,w]of Object.entries(b))if(u[I]){let A=u[I],$=new RegExp(`(${w}):\\s*rgb\\([^)]*\\);?`,"g");if($.test(Z))Z=Z.replace($,`$1: ${A};`),V=!0;else console.log(w0.yellow(`No match found for ${w}`))}if(V)m.writeFileSync(X,Z,"utf-8")}var O1=g1(import.meta.url),Y1=j.dirname(O1),d1=j.join(k1.homedir(),".untitledui"),a=j.join(d1,"config.json"),h1={"untitledui-nextjs-starter-temp":"Next.js","untitledui-vite-starter-temp":"Vite"},f1="untitledui-vite-starter-temp",m1="untitledui-nextjs-starter-temp",d="",v={color:"",template:"",framework:void 0};if(N.existsSync(a)){let Q=JSON.parse(N.readFileSync(a,"utf-8"));v.license=Q.license}var x0=(Q)=>{if(Q.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
11
+ `),process.exit(1)},z1=new F1().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("--next","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.").option("-l, --license <license-key>","Add a license key to download the repository.").action(async(Q,z)=>{if(Q)d=Q;if(z){if(v.color=z.color,v.template=z.template,v.overwrite=z.overwrite,v.colorsList=z.colorsList,v.license=z.license||v.license,v.vite=z.vite,v.next=z.next,z.vite)v.framework=f1;if(z.next)v.framework=m1}try{await F0(z),process.exit(0)}catch(Y){console.error(E.red(Y)),process.exit(1)}});async function F0(Q,z=null){let Y=process.cwd(),X=N.existsSync(j.resolve(Y,"package.json")),Z=j.resolve(j.join(Y1,"../config/styles","theme.css")),B=S0(Z??""),b=Array.from(new Set(Object.keys(B).map(($)=>$?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),u=Y0().start(),V=await p(Y),I=X?v0.sync(["**/**/theme.css"],{cwd:Y,absolute:!0,onlyFiles:!0,ignore:h}):[],w=I?.[0]&&N.readFileSync(I[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0;if(v.license){if(!await i(v.license))u.fail("Invalid license key"),process.exit(1);if(!N.existsSync(a)){let q=j.dirname(a);N.mkdirSync(q,{recursive:!0}),N.writeFileSync(a,JSON.stringify({license:v.license},null,2))}if(JSON.parse(N.readFileSync(a,"utf-8")).license!==v.license)N.writeFileSync(a,JSON.stringify({license:v.license},null,2))}if(!X){if(u.stop(),!d){let $=await H0({onState:x0,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof $.path==="string")d=$.path.trim()}if(z)z.projectPath=d;if(N.existsSync(j.resolve(j.posix.join(Y,d))))u.fail(E.red("Directory already exists!")),process.exit(1);if(v.vite&&v.next||!v.framework){let $=await H0({type:"select",name:"framework",onState:x0,message:`Which ${E.cyan("framework")} would you like to use?`,choices:[{title:E.cyan("Next"),value:"nextjs-starter"},{title:E.yellow("Vite"),value:"vite-starter"}]});v.framework=$.framework}u.succeed("Framework is selected: "+E.green(h1[v.framework]))}else if(V?.framework==="other")u.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${E.cyan("https://www.untitled.com/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(V?.framework.startsWith("next")||V?.framework.startsWith("vite"))if(!z&&!w)u.succeed(E.yellow(`Detected ${m0[V.framework]} project, proceeding with the setup...`));else u.stop();if(v.colorsList||!v.color&&!w){let $=await H0({type:"select",name:"color",onState:x0,initial:Q.color??"",message:`Which ${E.cyan("color")} would you like to use as the ${E.cyanBright("brand")} color?`,choices:b.map((W)=>({title:W,value:W}))});v.color=$.color}let A=j.posix.join(Y,d||"");if(d&&!X){let $=j.resolve(d);console.log(`
12
+ Creating a new project in ${E.blue(d)}`);let W=Y0("Downloading and extracting the repository...").start();try{N.mkdirSync($,{recursive:!0}),await $0(()=>e0($,{branch:"main",username:"untitleduico",repo:v.framework}),{retries:2}),W.succeed("Files are downloaded and extracted successfully!");let q=Y0({text:"Installing dependencies..."}).start(),K=v0.sync(["**/styles/theme.css"],{cwd:$,absolute:!0,onlyFiles:!0})[0];if(C0("brand",v.color||"",K??""),await $0(()=>l(x(),["install"],{cwd:A}).catch(async(S)=>{if(S.message.includes("peer"))q.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing dependencies with --legacy-peer-deps flag"),await l(x(),["install","--legacy-peer-deps"],{cwd:A})}),{retries:1}),await $0(()=>l("git",["init"],{cwd:A}),{retries:1}),q.succeed("Dependencies are installed"),!z)console.log(`
13
13
  Your project is ready, to get started run the following commands:
14
14
 
15
- cd ${I.cyan(d)}
16
- ${I.cyan(c0())}`)}catch(q){if(W.fail(I.red(`
15
+ cd ${E.cyan(d)}
16
+ ${E.cyan(c0())}`)}catch(q){if(W.fail(E.red(`
17
17
  Failed to download and extract the repository`)),q instanceof Error)console.error(q.message);else console.error(`
18
- `);T.rmdirSync($,{recursive:!0}),process.exit(1)}}else{let $=Y0(),W=new Set,q=o(Y),L=j.resolve(j.join(Y1,"../config")),S=v0.sync(["**"],{cwd:L,onlyFiles:!0,ignore:h}),V=w0(Y,["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"]),C=w0(Y,["@tailwindcss/postcss","postcss"]);if(!z&&!y)$.start("Copying files to the project directory");if(S.forEach((E)=>{let N=E.includes("postcss.config"),F=j.resolve(j.posix.join(L),E),P=j.resolve(Y,N?E:`${J?.isSrcDir?"src":""}/${E}`);if(T.existsSync(P)){if(v?.overwrite)T.copyFileSync(F,P);else{let Q0=T.readFileSync(P,"utf-8"),O=T.readFileSync(F,"utf-8");if(Q0!==O){if(E.endsWith("theme.css")&&y)return;W.add({targetFile:P,sourceFile:F})}}return}T.mkdirSync(j.dirname(P),{recursive:!0}),T.writeFileSync(P,""),T.copyFileSync(F,P)}),$.stop(),W.size&&!v?.overwrite)if(console.log(`
19
- `),$.fail("Following files already exist in the directory."),W.forEach((N)=>{console.log(`- ${I.green(N.targetFile)}`)}),(await G0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let N=Y0("Overwriting files").start();W.forEach((F)=>{T.copyFileSync(F.sourceFile,F.targetFile)}),N.succeed("Files are overwritten")}else console.log(`Use ${I.cyan("--overwrite")} or ${I.cyan("-o")} to overwrite existing files, or refer to the documentation ${I.cyan("https://www.untitled.com/docs")} for manual installation. The rest of the files are added.`);if(q?.tailwindFile)console.log(`
18
+ `);N.rmdirSync($,{recursive:!0}),process.exit(1)}}else{let $=Y0(),W=new Set,q=t(Y),K=j.resolve(j.join(Y1,"../config")),S=v0.sync(["**"],{cwd:K,onlyFiles:!0,ignore:h}),L=y0(Y,["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"]),C=y0(Y,["@tailwindcss/postcss","postcss"]);if(!z&&!w)$.start("Copying files to the project directory");if(S.forEach((G)=>{let T=G.includes("postcss.config"),k=j.resolve(j.posix.join(K),G),P=j.resolve(Y,T?G:`${V?.isSrcDir?"src":""}/${G}`);if(N.existsSync(P)){if(v?.overwrite)N.copyFileSync(k,P);else{let Q0=N.readFileSync(P,"utf-8"),O=N.readFileSync(k,"utf-8");if(Q0!==O){if(G.endsWith("theme.css")&&w)return;W.add({targetFile:P,sourceFile:k})}}return}N.mkdirSync(j.dirname(P),{recursive:!0}),N.writeFileSync(P,""),N.copyFileSync(k,P)}),$.stop(),W.size&&!v?.overwrite)if(console.log(`
19
+ `),$.fail("Following files already exist in the directory."),W.forEach((T)=>{console.log(`- ${E.green(T.targetFile)}`)}),(await H0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let T=Y0("Overwriting files").start();W.forEach((k)=>{N.copyFileSync(k.sourceFile,k.targetFile)}),T.succeed("Files are overwritten")}else console.log(`Use ${E.cyan("--overwrite")} or ${E.cyan("-o")} to overwrite existing files, or refer to the documentation ${E.cyan("https://www.untitled.com/docs")} for manual installation. The rest of the files are added.`);if(q?.tailwindFile)console.log(`
20
20
  Tailwind config file exists in the project directory. You can add it to your globals.css as follows:`),console.log(`
21
- ${I.cyan(`@config "../${J?.isSrcDir&&"../"}${j.relative(Y,q.tailwindFile)}";`)}
22
- `);let u=q?.layoutFile||q?.appFile||J?.framework==="vite"&&q?.mainFile||"";if(!u)console.log(`Import following files to your main file:
23
- `),S.forEach((E)=>{console.log(I.cyan(E))});else{let N=new P1({tsConfigFilePath:j.resolve(q?.tsConfig||"")}).addSourceFileAtPath(j.resolve(u)),F="globals.css";N.getImportDeclarations().filter((O)=>O.getModuleSpecifierValue().includes("globals.css")).forEach((O)=>O.remove());let P=j.relative(j.resolve(Y,`${J?.isSrcDir&&"src"}`),u).split("/").length,Q0=J?.aliasPrefix?.stylesPrefix||J?.aliasPrefix?.srcPrefix||(P===1?"./":"../".repeat(P-1));N.addImportDeclarations(S.filter((O)=>O.includes("globals.css")).map((O)=>({moduleSpecifier:`${Q0}${J?.aliasPrefix?.stylesPrefix?O?.split("styles/")[1]:O}`}))),N.saveSync()}let g=v0.sync(["**/styles/theme.css"],{cwd:Y,absolute:!0,onlyFiles:!0,ignore:h});if(!g?.length)return $.fail(`Failed to copy ${I.cyan("theme.css")} file.
24
- Ensure that the ${I.cyan("theme.css")} file exists in the project directory under ${I.yellow("styles/")} folder.`);if((v.color||!y)&&C0("brand",v.color||"brand",g[0]??""),V.length||C.length){let E=Y0().start("Installing dependencies");V.length&&await $0(()=>l(x(),[x()==="npm"?"install":"add",...V],{cwd:A}).catch(async(N)=>{if(N.message.includes("peer"))E.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),E.start("Installing dependencies with --legacy-peer-deps flag"),await l(x(),[x()==="npm"?"install":"add",...V,"--legacy-peer-deps"],{cwd:A})}),{retries:1}),C.length&&await $0(()=>l(x(),[x()==="npm"?"install":"add","-D",...C],{cwd:A}).catch(async(N)=>{if(N.message.includes("peer"))E.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),E.start("Installing dependencies with --legacy-peer-deps flag"),await l(x(),[x()==="npm"?"install":"add","-D",...C,"--legacy-peer-deps"],{cwd:A})}),{retries:1}),E.succeed("Dependencies are installed")}if(!z&&!y)$.succeed(I.green("Project setup is completed!"));if(z&&X)return;else console.log(`
25
- Your project is ready, you can now start adding components.`)}}var n1=G.join(a1.homedir(),".untitledui"),n=G.join(n1,"config.json"),B={path:"",example:"",license:"",components:[]},P0={};if(w.existsSync(n)){let Q=JSON.parse(w.readFileSync(n,"utf-8"));B.license=Q.license}var z0=(Q)=>{if(Q.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
26
- `),process.exit(1)},Q1=new c1().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.").addOption(new l1("-l, --license <license-key>","Add a license key for adding components.").hideHelp()).action(async(Q,z)=>{if(Q)B.example=Q;if(z)B.path=z.path,B.overwrite=z.overwrite,B.examplePath=z.examplePath,B.license=z.license||B.license;try{await k0(z,P0),await r1(B)}catch(Y){console.error(H.red(Y))}});async function r1(Q){let z=X0().start(),Y=G.posix.join(process.cwd(),P0?.projectPath||"");if(!w.existsSync(G.posix.join(G.resolve(Y,"package.json"))))z.warn("This command should be run in a project directory."),process.exit(1);let Z=await p(Y);if(B.license){if(!await r(B.license))z.fail("Invalid license key"),process.exit(1);if(!w.existsSync(n)){let L=G.dirname(n);w.mkdirSync(L,{recursive:!0}),w.writeFileSync(n,JSON.stringify({license:B.license},null,2))}if(JSON.parse(w.readFileSync(n,"utf-8")).license!==B.license)w.writeFileSync(n,JSON.stringify({license:B.license},null,2),"utf-8")}if(z.stop(),!B.example){let W=await s({type:"select",name:"example",onState:z0,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});B.example=W.example}let U=null;if(B.example){let W=await b0(B.example,B.license);if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(H.yellow(`\uD83D\uDD12 The ${H.cyan(B.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${H.green("→")} If you've already purchased: ${H.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${H.green("→")} To purchase PRO examples: ${H.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(W?.type==="directory"){let q=await s({type:"select",name:"example",onState:z0,message:`Select a folder or file in "${B.example}"`,choices:W.results.map((L)=>({title:L,value:L}))});if(!q.example)return;if(B.example=q.example,W=await b0(q.example,B.license),W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(H.yellow(`\uD83D\uDD12 The ${H.cyan(q.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${H.green("→")} If you've already purchased: ${H.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${H.green("→")} To purchase PRO examples: ${H.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-files"){let q=await s({type:"select",name:"example",onState:z0,message:`Select which example you want to add from "${B.example}"`,choices:W.results.map((L)=>({title:L,value:`${B.example}/${L}`}))});if(!q.example)return;if(B.example=q.example,W=await b0(q.example,B.license),W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(H.yellow(`\uD83D\uDD12 The ${H.cyan(q.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${H.green("→")} If you've already purchased: ${H.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${H.green("→")} To purchase PRO examples: ${H.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-file")U=W.content}if(!U)z.fail("No example found"),process.exit(1);if(!B?.examplePath){let W=Z?.isUsingAppDir?"app":"pages",q=Z?.isSrcDir?G.posix.join("src",W):W,L=await s({type:"text",name:"examplePath",onState:z0,message:`Where would you like to add the ${H.cyan(B?.example)} example?`,initial:q});B.examplePath=L.examplePath}else if(!w.existsSync(G.posix.join(Y,B.examplePath)))w.mkdirSync(G.posix.join(Y,B.examplePath),{recursive:!0}),console.log(H.green(`Created directory ${B.examplePath}`));if(!B?.path){let W=await s({type:"text",name:"path",onState:z0,message:`Where would you like to add the ${H.cyan("components")}?`,initial:"components"});B.path=W.path}let b=U.components.filter((W)=>!w.existsSync(G.posix.join(Y,`${Z?.isSrcDir&&"src"}`,W?.path?.replace(/components\//,B.path+"/"))));if(b?.length){let W=await s({type:"multiselect",name:"components",onState:z0,message:`Select which components you want to add from ${H.cyan(U.name)} example`,choices:b.map((q)=>({title:q?.name,value:q?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(B.components=W.components,!b.length&&!W.components?.length)z.warn("No components selected")}let M=o(Y),J=new Set,R=new s1({tsConfigFilePath:M?.tsConfig}),y=X0(`Adding ${B?.example}...`).start(),A="";try{if(U.files?.forEach(async({path:W,code:q})=>{let L=G.posix.join(Y,`${Z?.isSrcDir&&"src"}`,W.replace(/components\//,B.path+"/")),S=Z?.framework==="vite"?q.replace(`"use client";
21
+ ${E.cyan(`@config "../${V?.isSrcDir&&"../"}${j.relative(Y,q.tailwindFile)}";`)}
22
+ `);let R=q?.layoutFile||q?.appFile||V?.framework==="vite"&&q?.mainFile||"";if(!R)console.log(`Import following files to your main file:
23
+ `),S.forEach((G)=>{console.log(E.cyan(G))});else{let T=new P1({tsConfigFilePath:j.resolve(q?.tsConfig||"")}).addSourceFileAtPath(j.resolve(R)),k="globals.css";T.getImportDeclarations().filter((O)=>O.getModuleSpecifierValue().includes("globals.css")).forEach((O)=>O.remove());let P=j.relative(j.resolve(Y,`${V?.isSrcDir&&"src"}`),R).split("/").length,Q0=V?.aliasPrefix?.stylesPrefix||V?.aliasPrefix?.srcPrefix||(P===1?"./":"../".repeat(P-1));T.addImportDeclarations(S.filter((O)=>O.includes("globals.css")).map((O)=>({moduleSpecifier:`${Q0}${V?.aliasPrefix?.stylesPrefix?O?.split("styles/")[1]:O}`}))),T.saveSync()}let g=v0.sync(["**/styles/theme.css"],{cwd:Y,absolute:!0,onlyFiles:!0,ignore:h});if(!g?.length)return $.fail(`Failed to copy ${E.cyan("theme.css")} file.
24
+ Ensure that the ${E.cyan("theme.css")} file exists in the project directory under ${E.yellow("styles/")} folder.`);if((v.color||!w)&&C0("brand",v.color||"brand",g[0]??""),L.length||C.length){let G=Y0().start("Installing dependencies");L.length&&await $0(()=>l(x(),[x()==="npm"?"install":"add",...L],{cwd:A}).catch(async(T)=>{if(T.message.includes("peer"))G.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),G.start("Installing dependencies with --legacy-peer-deps flag"),await l(x(),[x()==="npm"?"install":"add",...L,"--legacy-peer-deps"],{cwd:A})}),{retries:1}),C.length&&await $0(()=>l(x(),[x()==="npm"?"install":"add","-D",...C],{cwd:A}).catch(async(T)=>{if(T.message.includes("peer"))G.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),G.start("Installing dependencies with --legacy-peer-deps flag"),await l(x(),[x()==="npm"?"install":"add","-D",...C,"--legacy-peer-deps"],{cwd:A})}),{retries:1}),G.succeed("Dependencies are installed")}if(!z&&!w)$.succeed(E.green("Project setup is completed!"));if(z&&X)return;else console.log(`
25
+ Your project is ready, you can now start adding components.`)}}var s1=H.join(a1.homedir(),".untitledui"),s=H.join(s1,"config.json"),U={path:"",example:"",license:"",components:[]},P0={};if(y.existsSync(s)){let Q=JSON.parse(y.readFileSync(s,"utf-8"));U.license=Q.license}var z0=(Q)=>{if(Q.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
26
+ `),process.exit(1)},Q1=new c1().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.").addOption(new l1("-l, --license <license-key>","Add a license key for adding components.").hideHelp()).action(async(Q,z)=>{if(Q)U.example=Q;if(z)U.path=z.path,U.overwrite=z.overwrite,U.examplePath=z.examplePath,U.license=z.license||U.license;try{await F0(z,P0),await i1(U)}catch(Y){console.error(M.red(Y))}});async function i1(Q){let z=X0().start(),Y=H.posix.join(process.cwd(),P0?.projectPath||"");if(!y.existsSync(H.posix.join(H.resolve(Y,"package.json"))))z.warn("This command should be run in a project directory."),process.exit(1);let Z=await p(Y);if(U.license){if(!await i(U.license))z.fail("Invalid license key"),process.exit(1);if(!y.existsSync(s)){let K=H.dirname(s);y.mkdirSync(K,{recursive:!0}),y.writeFileSync(s,JSON.stringify({license:U.license},null,2))}if(JSON.parse(y.readFileSync(s,"utf-8")).license!==U.license)y.writeFileSync(s,JSON.stringify({license:U.license},null,2),"utf-8")}if(z.stop(),!U.example){let W=await n({type:"select",name:"example",onState:z0,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});U.example=W.example}let B=null;if(U.example){let W=await b0(U.example,U.license);if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(M.yellow(`\uD83D\uDD12 The ${M.cyan(U.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${M.green("→")} If you've already purchased: ${M.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${M.green("→")} To purchase PRO examples: ${M.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(W?.type==="directory"){let q=await n({type:"select",name:"example",onState:z0,message:`Select a folder or file in "${U.example}"`,choices:W.results.map((K)=>({title:K,value:K}))});if(!q.example)return;if(U.example=q.example,W=await b0(q.example,U.license),W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(M.yellow(`\uD83D\uDD12 The ${M.cyan(q.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${M.green("→")} If you've already purchased: ${M.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${M.green("→")} To purchase PRO examples: ${M.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-files"){let q=await n({type:"select",name:"example",onState:z0,message:`Select which example you want to add from "${U.example}"`,choices:W.results.map((K)=>({title:K,value:`${U.example}/${K}`}))});if(!q.example)return;if(U.example=q.example,W=await b0(q.example,U.license),W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(M.yellow(`\uD83D\uDD12 The ${M.cyan(q.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${M.green("→")} If you've already purchased: ${M.cyan(`${e()} untitledui@latest login`)}`),console.log(` ${M.green("→")} To purchase PRO examples: ${M.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-file")B=W.content}if(!B)z.fail("No example found"),process.exit(1);if(!U?.examplePath){let W=Z?.isUsingAppDir?"app":"pages",q=Z?.isSrcDir?H.posix.join("src",W):W,K=await n({type:"text",name:"examplePath",onState:z0,message:`Where would you like to add the ${M.cyan(U?.example)} example?`,initial:q});U.examplePath=K.examplePath}else if(!y.existsSync(H.posix.join(Y,U.examplePath)))y.mkdirSync(H.posix.join(Y,U.examplePath),{recursive:!0}),console.log(M.green(`Created directory ${U.examplePath}`));if(!U?.path){let W=await n({type:"text",name:"path",onState:z0,message:`Where would you like to add the ${M.cyan("components")}?`,initial:"components"});U.path=W.path}let b=B.components.filter((W)=>!y.existsSync(H.posix.join(Y,`${Z?.isSrcDir&&"src"}`,W?.path?.replace(/components\//,U.path+"/"))));if(b?.length){let W=await n({type:"multiselect",name:"components",onState:z0,message:`Select which components you want to add from ${M.cyan(B.name)} example`,choices:b.map((q)=>({title:q?.name,value:q?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(U.components=W.components,!b.length&&!W.components?.length)z.warn("No components selected")}let u=t(Y),V=new Set,I=new n1({tsConfigFilePath:u?.tsConfig}),w=X0(`Adding ${U?.example}...`).start(),A="";try{if(B.files?.forEach(async({path:W,code:q})=>{let K=H.posix.join(Y,`${Z?.isSrcDir&&"src"}`,W.replace(/components\//,U.path+"/")),S=Z?.framework==="vite"?q.replace(`"use client";
27
27
 
28
- `,""):q,V=K0(S);if(W.includes("examples")){let u=G.basename(W);L=G.posix.join(Y,B?.examplePath??"",u),A=G.posix.join(B?.examplePath??"",u)}let C=G.dirname(L);if(w.existsSync(L)&&!B.overwrite){if(w.readFileSync(L,"utf-8")!==V)J.add({code:V,path:L})}else{w.mkdirSync(C,{recursive:!0}),w.writeFileSync(L,V);let u=G.relative(G.resolve(Y,`${Z?.isSrcDir&&"src"}`,B.path),L).split("/").length,g=u===1?"./":"../".repeat(u-1),E=R.addSourceFileAtPath(G.resolve(L));E.getImportDeclarations().forEach((N)=>{let F=N.getModuleSpecifierValue();N.setModuleSpecifier(t(F,B.path,Z?.aliasPrefix,g))}),await E.save()}}),J.size)y.warn(`Some files of ${H.yellow(B?.example)} already exist`);else y.succeed(`${H.green(B?.example)} is added successfully`)}catch(W){y.fail(`
29
- Failed to add the component ${H.red(B?.example)}`),console.error(H.red(W)),process.exit(1)}if(J.size&&!B?.overwrite)if(console.log(`
30
- Following files already exist in the directory.`),J.forEach((q)=>{console.log(H.green(`- ${G.relative(Y,q.path)}`))}),(await s({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let q=X0("Overwriting files").start();J.forEach((L)=>{let S=G.relative(G.resolve(Y,`${Z?.isSrcDir&&"src"}`,B.path),L.path).split("/").length,V=S===1?"./":"../".repeat(S-1),C=R.addSourceFileAtPath(G.resolve(L.path));C.replaceWithText(L.code),C.getImportDeclarations().forEach((u)=>{let g=u.getModuleSpecifierValue();u.setModuleSpecifier(t(g,B.path,Z?.aliasPrefix,V))}),C.saveSync()}),q.succeed("Files are overwritten")}else console.log(`Use ${H.cyan("--overwrite")} or ${H.cyan("-o")} to overwrite existing files, or refer to the documentation ${H.cyan("https://www.untitled.com/docs")} for manual installation. The rest of the files are added.`),process.exit(1);let $=x();if(U?.dependencies?.length){let W=X0("Installing example dependencies").start();await F0(()=>j0($,[$==="npm"?"install":"add",...U.dependencies],{cwd:Y}).catch(async(q)=>{if(q.message.includes("peer"))W.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),W.start("Installing dependencies with --legacy-peer-deps flag"),await j0($,[$==="npm"?"install":"add",...U.dependencies,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),W.succeed("Example dependencies are installed")}if(U?.devDependencies?.length){let W=X0("Installing example devDependencies").start();await F0(()=>j0($,[$==="npm"?"install":"add","-D",...U.devDependencies],{cwd:Y}).catch(async(q)=>{if(q.message.includes("peer"))W.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),W.start("Installing devDependencies with --legacy-peer-deps flag"),await j0($,[$==="npm"?"install":"add","-D",...U.devDependencies,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),W.succeed("Example devDependencies are installed")}if(B?.components?.length)await F0(()=>R0({components:B.components,dir:P0?.projectPath||"",path:B.path,message:`
31
- \uD83C\uDF89 Example ${H.green(B.example)} has been added to ${H.green(A)}`}),{retries:1});console.log(`
32
- \uD83C\uDF89 Example ${H.green(B.example)} has been added to ${H.green(A)}`),process.exit(0)}var g0={name:"untitledui",version:"0.1.20",main:"dist/index.mjs",description:"Untitled UI CLI",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"},repository:{type:"git",url:"https://github.com/a-peak-works/untitledui-tailwind.git"},bugs:{url:"https://github.com/a-peak-works/untitledui-tailwind/issues"},homepage:"https://github.com/a-peak-works/untitledui-tailwind#readme",keywords:["untitled-ui","cli","tailwindcss","nextjs"],files:["dist","config"],author:"",license:"MIT",bin:{untitledui:"dist/index.mjs"},exports:"./dist/index.mjs",dependencies:{"async-retry":"^1.3.3",chalk:"^5.4.1",commander:"^13.1.0",execa:"^7.0.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",open:"^10.1.0",ora:"^8.2.0",prettier:"^3.5.3",prompts:"^2.4.2",tar:"^7.4.3","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.37.0",typescript:"^5.8.2"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function o1(){let Q=new p1().name(g0.name).version(g0.version);Q.addCommand(z1).addCommand(a0).addCommand(Q1).addCommand(i0),Q.parse()}o1();
28
+ `,""):q,L=J0(S);if(W.includes("examples")){let R=H.basename(W);K=H.posix.join(Y,U?.examplePath??"",R),A=H.posix.join(U?.examplePath??"",R)}let C=H.dirname(K);if(y.existsSync(K)&&!U.overwrite){if(y.readFileSync(K,"utf-8")!==L)V.add({code:L,path:K})}else{y.mkdirSync(C,{recursive:!0}),y.writeFileSync(K,L);let R=H.relative(H.resolve(Y,`${Z?.isSrcDir&&"src"}`,U.path),K).split("/").length,g=R===1?"./":"../".repeat(R-1),G=I.addSourceFileAtPath(H.resolve(K));G.getImportDeclarations().forEach((T)=>{let k=T.getModuleSpecifierValue();T.setModuleSpecifier(o(k,U.path,Z?.aliasPrefix,g))}),await G.save()}}),V.size)w.warn(`Some files of ${M.yellow(U?.example)} already exist`);else w.succeed(`${M.green(U?.example)} is added successfully`)}catch(W){w.fail(`
29
+ Failed to add the component ${M.red(U?.example)}`),console.error(M.red(W)),process.exit(1)}if(V.size&&!U?.overwrite)if(console.log(`
30
+ Following files already exist in the directory.`),V.forEach((q)=>{console.log(M.green(`- ${H.relative(Y,q.path)}`))}),(await n({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let q=X0("Overwriting files").start();V.forEach((K)=>{let S=H.relative(H.resolve(Y,`${Z?.isSrcDir&&"src"}`,U.path),K.path).split("/").length,L=S===1?"./":"../".repeat(S-1),C=I.addSourceFileAtPath(H.resolve(K.path));C.replaceWithText(K.code),C.getImportDeclarations().forEach((R)=>{let g=R.getModuleSpecifierValue();R.setModuleSpecifier(o(g,U.path,Z?.aliasPrefix,L))}),C.saveSync()}),q.succeed("Files are overwritten")}else console.log(`Use ${M.cyan("--overwrite")} or ${M.cyan("-o")} to overwrite existing files, or refer to the documentation ${M.cyan("https://www.untitled.com/docs")} for manual installation. The rest of the files are added.`),process.exit(1);let $=x();if(B?.dependencies?.length){let W=X0("Installing example dependencies").start();await k0(()=>j0($,[$==="npm"?"install":"add",...B.dependencies],{cwd:Y}).catch(async(q)=>{if(q.message.includes("peer"))W.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),W.start("Installing dependencies with --legacy-peer-deps flag"),await j0($,[$==="npm"?"install":"add",...B.dependencies,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),W.succeed("Example dependencies are installed")}if(B?.devDependencies?.length){let W=X0("Installing example devDependencies").start();await k0(()=>j0($,[$==="npm"?"install":"add","-D",...B.devDependencies],{cwd:Y}).catch(async(q)=>{if(q.message.includes("peer"))W.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),W.start("Installing devDependencies with --legacy-peer-deps flag"),await j0($,[$==="npm"?"install":"add","-D",...B.devDependencies,"--legacy-peer-deps"],{cwd:Y})}),{retries:1}),W.succeed("Example devDependencies are installed")}if(U?.components?.length)await k0(()=>I0({components:U.components,dir:P0?.projectPath||"",path:U.path,message:`
31
+ \uD83C\uDF89 Example ${M.green(U.example)} has been added to ${M.green(A)}`}),{retries:1});console.log(`
32
+ \uD83C\uDF89 Example ${M.green(U.example)} has been added to ${M.green(A)}`),process.exit(0)}var g0={name:"untitledui",version:"0.1.22",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"},repository:{type:"git",url:"https://github.com/untitledui/cli.git"},bugs:{url:"https://github.com/untitledui/cli/issues"},homepage:"https://github.com/untitledui/cli#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","README.md"],author:{name:"Untitled UI",url:"https://www.untitledui.com/react"},contributors:[{name:"Dilshod Turobov",email:"dilshod@untitledui.com",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.4.1",commander:"^13.1.0",execa:"^7.0.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",open:"^10.1.0",ora:"^8.2.0",prettier:"^3.5.3",prompts:"^2.4.2",tar:"^7.4.3","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.37.0",typescript:"^5.8.2"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function t1(){let Q=new p1().name(g0.name).version(g0.version);Q.addCommand(z1).addCommand(a0).addCommand(Q1).addCommand(r0),Q.parse()}t1();
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "untitledui",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "main": "dist/index.mjs",
5
- "description": "Untitled UI CLI",
5
+ "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.",
6
6
  "type": "module",
7
7
  "publishConfig": {
8
8
  "access": "public"
@@ -16,23 +16,50 @@
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "https://github.com/a-peak-works/untitledui-tailwind.git"
19
+ "url": "https://github.com/untitledui/cli.git"
20
20
  },
21
21
  "bugs": {
22
- "url": "https://github.com/a-peak-works/untitledui-tailwind/issues"
22
+ "url": "https://github.com/untitledui/cli/issues"
23
23
  },
24
- "homepage": "https://github.com/a-peak-works/untitledui-tailwind#readme",
24
+ "homepage": "https://github.com/untitledui/cli#readme",
25
25
  "keywords": [
26
+ "untitledui",
26
27
  "untitled-ui",
28
+ "untitledui",
29
+ "untitledui-cli",
30
+ "untitledui-react",
31
+ "untitledui-components",
32
+ "untitledui-examples",
33
+ "untitledui-vite",
34
+ "untitledui-nextjs",
27
35
  "cli",
28
36
  "tailwindcss",
29
- "nextjs"
37
+ "nextjs",
38
+ "react",
39
+ "components",
40
+ "examples",
41
+ "vite"
30
42
  ],
31
43
  "files": [
32
44
  "dist",
33
- "config"
45
+ "config",
46
+ "README.md"
47
+ ],
48
+ "author": {
49
+ "name": "Untitled UI",
50
+ "url": "https://www.untitledui.com/react"
51
+ },
52
+ "contributors": [
53
+ {
54
+ "name": "Dilshod Turobov",
55
+ "email": "dilshod@untitledui.com",
56
+ "url": "https://x.com/deebovv"
57
+ },
58
+ {
59
+ "name": "Jordan Hughes",
60
+ "url": "https://x.com/jordanphughes"
61
+ }
34
62
  ],
35
- "author": "",
36
63
  "license": "MIT",
37
64
  "bin": {
38
65
  "untitledui": "dist/index.mjs"