untitledui 0.1.57 → 0.1.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/v7/styles/globals.css +69 -0
- package/config/v7/styles/theme.css +1326 -0
- package/config/v7/styles/typography.css +430 -0
- package/dist/index.mjs +100 -100
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
2
|
+
import{Command as a1}from"commander";import u from"chalk";import{Command as s0}from"commander";import*as l from"fs";import Sy from"ora";import*as c from"path";import Gy from"prompts";import{Project as r0}from"ts-morph";import*as jy from"fs";import*as py from"path";import x0 from"os";var N$=py.join(x0.homedir(),".untitledui"),ny=py.join(N$,"config.json");function w$(y=ny){if(!jy.existsSync(y))return{};try{return JSON.parse(jy.readFileSync(y,"utf-8"))}catch{return{}}}function My(y=ny){return w$(y).license||""}function Oy(y,$=N$,j=ny){if(!jy.existsSync($))jy.mkdirSync($,{recursive:!0});let Q=w$(j);if(Q.license!==y)Q.license=y,jy.writeFileSync(j,JSON.stringify(Q,null,2),"utf-8")}import T0 from"node-fetch";var A$={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function ky(y,$,j,Q){let Y=$.map((Z)=>{if(Z.includes("modals/"))if(Z.includes("-modal"))return Z;else return Z+"-modal";return Z});try{let Z=await T0("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:y,components:Y,key:j,version:Q})});if(!Z.ok)console.log(A$?.[Z.statusText]||A$.no_components_found),process.exit(1);return await Z.json()}catch(Z){return null}}import ty from"node-fetch";var Ny={invalid_key:"Invalid key provided",no_components_found:"No components found",no_components_provided:"No components provided"};async function E$(y,$="",j){let Q=`https://www.untitledui.com/react/api/components/list?key=${$}&type=${y}${j?`&version=${j}`:""}`;try{let z=await ty(Q),Y=await z.json();if(!z.ok)console.log(Ny?.[z.statusText]||Ny.no_components_found),process.exit(1);if(!Y?.components?.length)return null;return Y}catch(z){return console.error(z),null}}async function I$(y,$="",j,Q){let z=`https://www.untitledui.com/react/api/components/list?key=${$}&type=${y}&subfolders=${j.join(",")}${Q?`&version=${Q}`:""}`;try{let Y=await ty(z);if(!Y.ok)console.log(Ny?.[Y.statusText]||Ny.no_components_found),process.exit(1);let Z=await Y.json();if(!Z?.components?.length)return null;return Z}catch(Y){return console.error(Y),null}}async function x$(y="",$){let j=`https://www.untitledui.com/react/api/components/list?key=${y}${$?`&version=${$}`:""}`;try{let Q=await ty(j);if(!Q.ok)console.log(Ny?.[Q.statusText]||Ny.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 y$ from"fast-glob";import*as dy from"fs";import*as Wy from"path";import{Project as O0}from"ts-morph";import{loadConfig as k$}from"tsconfig-paths";import S0 from"prettier";async function T$(y,$="typescript"){try{return await S0.format(y,{parser:$,printWidth:160,tabWidth:4})}catch(j){return console.error("Error formatting with Prettier:",j),y}}import zy from"chalk";import Hy from"fast-glob";import*as Qy from"fs";import*as Yy from"path";import{loadConfig as Py}from"tsconfig-paths";import S$ from"fs";import F0 from"path";function F$(y=""){let $=F0.join(y,"package.json");if(!S$.existsSync($))return null;else return JSON.parse(S$.readFileSync($,"utf-8"))}import ey from"fs";import v$ from"path";import{createMatchPath as R$}from"tsconfig-paths";function C$(y,$){let j=v$.posix.join(y,"index"),Q=(Y)=>{try{return ey.existsSync(Y)}catch{return!0}},z=R$($.absoluteBaseUrl,$.paths)(j,void 0,Q,[".ts",".tsx",".jsx",".js",".css"]);if(!z)z=R$($.absoluteBaseUrl,$.paths)(j,void 0,()=>!0,[".ts",".tsx",".jsx",".js",".css"]);if(z){let Y=z.split("/").slice(0,-1).join("/");try{if(ey.existsSync(Y)&&ey.statSync(Y).isFile())return v$.dirname(Y)}catch{}return Y}else return}var s=["**/node_modules/**",".next","public","dist","build"],gy=!1,u$={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function qy(y){let $=Qy.existsSync(Yy.resolve(y,"src")),j=Qy.existsSync(Yy.resolve(y,`${$?"src/":""}app`)),[Q,z,Y,Z,X]=await Promise.all([Hy.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:y,deep:2,ignore:s}),v0(y),C0(y),u0(y),F$(y)]),U=Qy.existsSync(Yy.resolve(y,"components.json")),M=null;if(U)M=JSON.parse(Qy.readFileSync(Yy.resolve(y,"components.json"),"utf-8"));let J=Hy.sync(["**/**/theme.css"],{cwd:y,absolute:!0,onlyFiles:!0,ignore:s}),D=J?.[0]&&Qy.readFileSync(J[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0,q={tailwind:{config:Y||void 0,brandColor:D?.replace(/--color-([^-]+(?:-[^-]+)?)-\d+:.*/,"$1")||void 0},examples:M?.examples||void 0,aliases:M?.aliases||Z||{},paths:await R0(M?.aliases||{})||{},isTsx:z,isSrcDir:$,isAppDir:j,isComponentsJson:!!U,framework:"other"};if(Q.find((_)=>_.startsWith("next.config."))?.length)return q.framework=j?"next-app":"next-pages",q;else if(Q.find((_)=>_.startsWith("vite.config."))?.length)return q.framework="vite",q;else if(Object.keys(X?.dependencies||{}).includes("react"))return q.framework="next-pages",q;else if(Q?.length||Qy.existsSync(Yy.resolve(y,"package.json")))return q.framework="other",q;return null}async function v0(y){return(await Hy.glob("tsconfig.*",{cwd:y,deep:2,ignore:s})).length>0}async function R0(y){let $={},j=[],Q=Object.entries(y).filter(([,U])=>U);if(Q.length===0)return null;let z=process.cwd(),Z=Py(z).resultType==="success",X=await O$(z);if(!X){if(!gy){if(gy=!0,process.stdout.write("\r\x1B[K"),Z)console.log(zy.yellow(`
|
|
3
3
|
⚠ Could not resolve path aliases from components.json - no paths configured in tsconfig.json.`));else console.log(zy.yellow(`
|
|
4
4
|
⚠ Could not resolve path aliases from components.json - tsconfig.json not found.`));console.log(zy.dim(` The following aliases will be used for imports but files will be placed in default locations:
|
|
5
|
-
`)),
|
|
5
|
+
`)),Q.forEach(([U,M])=>{console.log(zy.dim(` ${U}: ${M}`))}),console.log(zy.dim(`
|
|
6
6
|
To fix this, add matching paths to your tsconfig.json.
|
|
7
|
-
`))}return null}for(let[U,
|
|
7
|
+
`))}return null}for(let[U,M]of Object.entries(y))if(M){let J=await C$(M.replace(/\/\*$/,""),X);if(J)$[U]=Yy.relative(process.cwd(),J);else j.push(`${U}: ${M}`)}if(j.length>0&&!gy)gy=!0,process.stdout.write("\r\x1B[K"),console.log(zy.yellow(`
|
|
8
8
|
⚠ Could not resolve the following path aliases from tsconfig.json:`)),j.forEach((U)=>{console.log(zy.dim(` ${U}`))}),console.log(zy.dim(`
|
|
9
9
|
These aliases will be used for imports but files will be placed in default locations.`)),console.log(zy.dim(` To fix this, add matching paths to your tsconfig.json.
|
|
10
|
-
`));return $}async function O$(y){let[$,j]=await Promise.all([
|
|
11
|
-
"paths": ${JSON.stringify(
|
|
12
|
-
`),process.exit(1)};function fy(y){return y.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}import Xy from"path";function cy(y,$,j){let
|
|
13
|
-
|
|
14
|
-
`,""):
|
|
15
|
-
Please check your path aliases in components.json and tsconfig.json.`);
|
|
16
|
-
Failed to add the component ${
|
|
17
|
-
Following files already exist in the directory.`),
|
|
18
|
-
Use ${
|
|
10
|
+
`));return $}async function O$(y){let[$,j]=await Promise.all([Hy.glob("next.config.*",{cwd:y,deep:1,ignore:s}),Hy.glob("vite.config.*",{cwd:y,deep:1,ignore:s})]),Q=$.length>0,z=j.length>0,Y=null;if(Q)Y=Py(y);else if(z){if(Y=Py(y),Y?.resultType==="failed"||!Object.keys(Y.paths||{}).length){let Z=await Hy.glob(["tsconfig.app.*","*/tsconfig.app.*"],{cwd:y,deep:1,onlyFiles:!0,absolute:!0,ignore:s}),[X]=Z;if(X)try{let M=function(q){return q.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1")},U=Qy.readFileSync(X,"utf-8"),J=M(U),D=JSON.parse(J);if(D.compilerOptions?.paths)Y={resultType:"success",paths:D?.compilerOptions?.paths,baseUrl:D.compilerOptions.baseUrl||".",configFileAbsolutePath:X,absoluteBaseUrl:Yy.resolve(y,D.compilerOptions.baseUrl||".")}}catch{}}}else Y=Py(y);if(!Y||Y?.resultType==="failed"||!Object.keys(Y.paths).length)return null;return Y}async function C0(y){let $=await Hy.glob("tailwind.config.*",{cwd:y,deep:2,ignore:s});if(!$.length)return null;return $[0]}async function u0(y){let $=await O$(y);if(!$)return null;let j={},Q={app:/\/?app\/\*$/,components:/\/?components\/\*$/,utils:/\/?utils\/\*$/,styles:/\/?styles\/\*$/,hooks:/\/?hooks\/\*$/,src:/^(\.\/src\/\*|\.\/\*|\/src\/\*|src\/\*|\/\*|\*)$/};for(let[z,Y]of Object.entries($.paths)){let Z=z.replace(/\/\*$/,"/");for(let[X,U]of Object.entries(Q))if(Y.some((M)=>U.test(M))){j[X]=Z;break}}return j||null}function wy(y,$){let j=k$(y),Q=y$.sync(["tailwind.config.*","**/globals.css","package.json"],{cwd:y,deep:4,absolute:!0,onlyFiles:!0,ignore:s}),z=y$.sync("**/{layout,_app,main}.tsx",{cwd:$?Wy.posix.join(y,$):y,deep:4,absolute:!0,onlyFiles:!0,ignore:s});return{tailwindFile:Q.find((Z)=>Z.includes("tailwind.config.")),cssFile:Q.find((Z)=>Z.includes("globals.css")),packageJson:Q.find((Z)=>Z.includes("package.json")),tsConfig:j?.resultType==="success"?j?.configFileAbsolutePath:void 0,layoutFile:z.find((Z)=>Z.includes("layout")),appFile:z.find((Z)=>Z.includes("_app")),mainFile:z.find((Z)=>Z.includes("main"))}}function Ay(y,$,j={}){if(y.startsWith("@/components/")){if(j?.components)return y.replace(/^@\/components\//,Wy.posix.join(j.components,"/"));if($)return y.replace(/^@\/components\//,Wy.posix.join("@",$,"/"))}if(y.startsWith("@/app/")&&j?.app)return y.replace(/^@\/app\//,Wy.posix.join(j.app,"/"));if(y.startsWith("@/utils/")&&j?.utils)return y.replace(/^@\/utils\//,Wy.posix.join(j.utils,"/"));if(y.startsWith("@/hooks/")&&j?.hooks)return y.replace(/^@\/hooks\//,Wy.posix.join(j.hooks,"/"));if(y.startsWith("@/styles/")&&j?.styles)return y.replace(/^@\/styles\//,Wy.posix.join(j.styles,"/"));if(y.startsWith("@/")&&j?.src)return y.replace(/^@\//,Wy.posix.join(j.src,"/"));return y}async function g$(y,$,j="@/*"){let Q=await k$(y);if(Q?.resultType==="failed")return null;let z={};if(!Object.keys(Q.paths).length){Q.paths={[j]:[`./${$?"src/":""}*`]},z.src=j.replace(/\/\*$/,"");let Y=await dy.promises.readFile(Q.configFileAbsolutePath,"utf-8"),Z,X=/(?:\/\/\s*)?"paths":\s*\{(?:[^{}]|\{[^}]*\})*\}/;if(!X.test(Y))Z=Y.replace(/"compilerOptions":\s*{/,`"compilerOptions": {
|
|
11
|
+
"paths": ${JSON.stringify(Q.paths)},`);else Z=Y.replace(X,`"paths": ${JSON.stringify(Q.paths)}`);let M=new O0,J=await T$(Z,"json");return M.createSourceFile(Q.configFileAbsolutePath,J,{overwrite:!0}),await M.save(),z}return z||null}function P$(y){let $=y$.sync(["vite.config.*"],{cwd:y,absolute:!0,onlyFiles:!0,ignore:s})?.[0];if(!$)return!1;try{let j=dy.readFileSync($,"utf-8");return k0(j)}catch{return!1}}function k0(y){let $=y.replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"");if(!["tailwindcss","@tailwindcss/vite","tailwind("].some((Y)=>$.includes(Y)))return!1;return["plugins:","postcss:","css:"].some((Y)=>$.includes(Y))}var g0=["npm","config","user","agent"].join("_");function Vy(y){if(y===void 0)y=process.env[g0]||"";if(y.startsWith("yarn"))return"yarn";if(y.startsWith("pnpm"))return"pnpm";if(y.startsWith("bun"))return"bun";return"npm"}function Zy(){switch(Vy()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function d$(){switch(Vy()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}import P0 from"async-retry";import{execa as f$}from"execa";async function Uy(y,$){let j=Array.isArray(y)?y:Array.from(y);if(!j.length)return;let{cwd:Q,dev:z=!1,spinner:Y,label:Z=z?"devDependencies":"dependencies"}=$,X=Vy(),M=[X==="npm"?"install":"add",...z?["-D"]:[],...j];Y.start(`Installing ${Z}`),await P0(()=>f$(X,M,{cwd:Q}).catch(async(J)=>{if(J.message.includes("peer"))Y.warn(`${Z} conflict detected. Retrying with --legacy-peer-deps...`),Y.start(`Installing ${Z} with --legacy-peer-deps flag`),await f$(X,[...M,"--legacy-peer-deps"],{cwd:Q});else throw J}),{retries:1}),Y.succeed(`${Z} installed`)}var f=(y)=>{if(y.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
|
|
12
|
+
`),process.exit(1)};function fy(y){return y.replace(/^[ \t]*\/\/\s*(TODO:|collapse-(start|end)).*\r?\n?|[ \t]*{\s*\/\*\s*(TODO:|collapse-(start|end)).*?\*\/\s*}\r?\n?/gm,"")}import Xy from"path";function cy(y,$,j){let Q=y.replace(/^(components|utils|hooks|styles)\//,"");if(y.includes("components")&&$?.components)return Xy.relative(process.cwd(),Xy.posix.join($.components,Q));if(y.includes("utils")&&$?.utils)return Xy.relative(process.cwd(),Xy.posix.join($.utils,Q));if(y.includes("hooks")&&$?.hooks)return Xy.relative(process.cwd(),Xy.posix.join($.hooks,Q));if(y.includes("styles")&&$?.styles)return Xy.relative(process.cwd(),Xy.posix.join($.styles,Q));return Xy.posix.join(j?"src":"",y)}import c$ from"node-fetch";import{Readable as d0,pipeline as f0}from"stream";import{x as c0}from"tar";import{promisify as h0}from"util";var m0=h0(f0);async function h$(y,$){try{let j=await l0($);await m0(j,c0({cwd:y,strip:1}))}catch(j){throw Error(`Failed to download or extract repository from API: ${j instanceof Error?j.message:j}`)}}async function l0(y){let $=`https://www.untitledui.com/react/api/download-repo?template=${y.template}`;try{let j=await c$($,{method:"GET",headers:{"Content-Type":"application/json",Accept:"application/octet-stream"}});if(j.status===403||j.status===404)throw Error("Repository not found");if(!j.ok)throw Error(`Failed to download from API. Status: ${j.status} ${j.statusText}`);if(!j.body)throw Error("Response body is empty");return d0.from(j.body)}catch(j){throw Error(`Error downloading tarball: ${j instanceof Error?j.message:j}`)}}async function m$(y){let $=`https://www.untitledui.com/react/api/validate-key?key=${y}`;try{return(await c$($)).status===200}catch{return!1}}async function hy(y,$){if(!await m$(y))$.fail("Invalid license key"),process.exit(1);Oy(y)}var b={components:[],path:"",type:void 0,license:My()},l$=new s0().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.").option("--include-all-components","automatically include all base components without prompting.",!1).option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("--lib-version <version>","component library version (7 or 8)").action(async(y,$)=>{if(y)b.components=y;if($){if(b.all=$.all,b.dir=$.dir,b.path=$.path,b.overwrite=$.overwrite,b.includeAllComponents=$.includeAllComponents,b.license=$.license||b.license,b.version=$.libVersion,b.yes=$.yes,$.yes)b.includeAllComponents=!0,b.overwrite=!0}try{await $$(b)}catch(j){console.error(u.red(j))}});function i0(y,$){if($)return $;let j=c.resolve(y,"components.json");if(l.existsSync(j))try{return JSON.parse(l.readFileSync(j,"utf-8")).version??"8"}catch{}return"8"}async function $$(y){if(y)b={...b,...y};let $=Sy().start(),j=c.posix.join(process.cwd(),b.dir||"");if(!l.existsSync(c.resolve(j,"package.json")))$.warn("This command should be run in a project directory."),process.exit(1);let z=i0(j,b.version),Y=await qy(j);if(b.license)await hy(b.license,$);$.stop();let Z=[];if(b.components.length){let W=await ky(b.type,b.components,b.license,z);if(W&&W.pro&&W.pro.length>0){if(console.log(),W.pro.length===1){let K=W.pro[0]?.split("/")[1]||W.pro[0];console.log(u.yellow(`\uD83D\uDD12 The ${u.cyan(K)} component requires PRO access.`))}else console.log(u.yellow("\uD83D\uDD12 The following components require PRO access:")),W.pro.forEach((K)=>{let G=K?.split("/")[1]||K;console.log(` • ${u.cyan(G)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${u.green("→")} If you've already purchased: ${u.cyan(`${Zy()} untitledui@latest login`)}`),console.log(` ${u.green("→")} To purchase PRO components: ${u.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(!W?.components.length)console.log("No components found"),process.exit(1);Z.push(...W.components)}if(!b?.type&&!b?.components.length){if(b.yes)console.log(u.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let W=await x$(b.license,z);if(!W)console.log("No component types found"),process.exit(1);let K=await Gy({type:"select",name:"type",onState:f,message:`What type of ${u.cyan("component")} are you adding?`,choices:W?.types.map((G)=>({title:G,value:G}))});b.type=K.type}if(!b?.path&&!Y?.paths?.components)if(b.yes)b.path="components";else{let W=await Gy({type:"text",name:"path",onState:f,message:`Where would you like to add the ${u.cyan("components")}?`,initial:"components"});b.path=W.path}if(b?.path&&Y&&Y.paths)Y.paths.components=c.posix.join(Y?.isSrcDir?"src":"",b.path);if(Y&&!Object.keys(Y?.aliases).length){let W="@/*";if(!b.yes){let K=/^[^*"]+\/\*\s*$/;W=(await Gy({type:"text",name:"aliasPrefix",onState:f,initial:"@/*",message:`What is the ${u.cyan("import alias")} for your project?`,validate:(F)=>K.test(F)?!0:"Import alias must follow the pattern <prefix>/*"}))?.aliasPrefix}Y.aliases=await g$(j,Y?.isSrcDir,W)}if(!b?.components.length){if(b.yes)console.log(u.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let W=await E$(b?.type,b.license,z);if(!W)console.log("No components found"),process.exit(1);let K=await Gy({type:"multiselect",name:"components",onState:f,message:`Which ${u.cyan("components")} would you like to add?`,choices:W?.components?.map((E)=>({title:E?.name+(E?.count?` (${E?.count} variants)`:"")||"example",value:E||"example",selected:b.components.includes(E.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!K.components||!K.components.length)console.log("No option selected. Exiting..."),process.exit(1);let G=K.components.filter((E)=>E?.type==="file").map((E)=>E.name),F=K.components.filter((E)=>E?.type==="dir").map((E)=>E.name),x=[];if(F.length){let E=await I$(b?.type,b.license,F,z);if(E&&E.components.length)for(let I of E.components){let[C,T]=Object.entries(I)[0]||[],v=await Gy({type:"select",name:"component",onState:f,message:`Which ${u.cyan("variant")} from ${u.cyan(C)} would you like to add?`,choices:T?.map((H)=>({title:H?.name.replace(/-modal/g,"")||"example",value:H?.name||"example",selected:b.components.includes(H.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!v.component)console.log("No variant selected for "+u.cyan(C));x.push(C+"/"+v.component)}else console.log("No variants found")}b.components=[...x,...G]}if(!b.components?.length)$.warn("No components selected. Exiting."),process.exit(1);let X=wy(j),U=new Map,M=new Set,J=new Set,D=new r0({tsConfigFilePath:X?.tsConfig});if($.start(),b.type&&b.components.length){let W=await ky(b.type,b.components,b.license,z);if(!W?.components.length)console.log("No components found"),process.exit(1);Z.push(...W.components)}let q=new Set;if(Z.forEach((W)=>{W?.components?.forEach((K)=>{q.add({name:K.name,path:K.path})})}),$.stop(),q.size){let W=Array.from(q).filter((K)=>!l.existsSync(c.posix.join(j,`${Y?.isSrcDir?"src":""}`,K?.path?.replace(/components\//,b.path+"/"))));if(W?.length)if(b.includeAllComponents)b.baseComponents=W.map((K)=>K.name);else{let K=await Gy({type:"multiselect",name:"baseComponents",onState:f,message:"Select which base components you want to add",choices:W.map((G)=>({title:G?.name,value:G?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(b.baseComponents=K.baseComponents,!W.length&&!K.baseComponents?.length)$.warn("No components selected")}}if($.start(),b?.baseComponents?.length){let W=await ky("",b.baseComponents,b.license,z);if(!W||!W?.components.length)console.log("No base components found");else Z.push(...W.components)}$.stop();let _=new Set;for(let W of Z){let K=Sy(`Adding ${W.name}...`).start(),G=W.files;W?.dependencies?.forEach((x)=>M.add(x)),W?.devDependencies?.forEach((x)=>J.add(x));let F=!1;try{for(let{path:x,code:E}of G||[]){let I=c.posix.join(j,cy(x,Y?.paths,Y?.isSrcDir)),C=Y?.framework==="vite"?E.replace(`"use client";
|
|
13
|
+
|
|
14
|
+
`,""):E,T=fy(C),v=c.dirname(I);if(l.existsSync(I)&&!b.overwrite&&!_.has(I)){if(l.readFileSync(I,"utf-8")!==T)U.set(I,{code:T,path:I}),F=!0}else if(!_.has(I)){let H=v.split(c.sep),L="";for(let w of H)if(L=L?c.join(L,w):w,L&&l.existsSync(L)&&l.statSync(L).isFile())throw Error(`Cannot create directory '${v}' because '${L}' is an existing file.
|
|
15
|
+
Please check your path aliases in components.json and tsconfig.json.`);l.mkdirSync(v,{recursive:!0}),l.writeFileSync(I,T),_.add(I);let V=D.getSourceFile(c.resolve(I));if(V)V.replaceWithText(T);else V=D.addSourceFileAtPath(c.resolve(I));V.getImportDeclarations().forEach((w)=>{let R=w.getModuleSpecifierValue();w.setModuleSpecifier(Ay(R,b.path,Y?.aliases))}),await V.save()}}if(F)K.warn(`Some files of ${u.yellow(W.name)} already exist`);else K.succeed(`${u.green(W.name)} is added successfully`)}catch(x){K.fail(`
|
|
16
|
+
Failed to add the component ${u.red(W.name)}`),console.error(u.red(x)),process.exit(1)}}if(U.size&&!b?.overwrite){console.log(`
|
|
17
|
+
Following files already exist in the directory.`),U.forEach((K)=>{console.log(u.green(`- ${c.relative(j,K.path)}`))});let W=!1;if(b.yes)W=!0;else{let K=await Gy({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0});if(K.overwrite===void 0)console.log(`
|
|
18
|
+
Use ${u.cyan("--overwrite")} or ${u.cyan("-o")} flag to overwrite existing files, or run with ${u.cyan("node")} instead of ${u.cyan("bun")}.`),process.exit(1);W=K.overwrite}if(W){let K=Sy("Overwriting files").start();U.forEach((G)=>{let F=D.addSourceFileAtPath(c.resolve(G.path));F.replaceWithText(G.code),F.getImportDeclarations().forEach((x)=>{let E=x.getModuleSpecifierValue();x.setModuleSpecifier(Ay(E,b.path,Y?.aliases))}),F.saveSync()}),K.succeed("Files are overwritten")}}if(M.size){let W=Sy().start();await Uy(M,{cwd:j,spinner:W,label:"component dependencies"})}if(J.size){let W=Sy().start();await Uy(J,{cwd:j,dev:!0,spinner:W,label:"component devDependencies"})}if(b.message!==void 0){if(b.message)console.log(b.message);return}process.exit(0)}import Y$ from"chalk";import{Command as n0}from"commander";import*as Ly from"fs";import t0 from"http";import e0 from"open";import y1 from"ora";import $1 from"os";import*as W$ from"path";import{URL as j1}from"url";import*as my from"fs";import*as Jy from"path";import{fileURLToPath as a0}from"url";var o0=a0(import.meta.url),j$=Jy.dirname(o0);function p0(){let y=[Jy.join(j$,"..","templates","auth-template.html"),Jy.join(j$,"templates","auth-template.html"),Jy.join(process.cwd(),"node_modules","untitledui","templates","auth-template.html"),Jy.join(j$,"..","..","templates","auth-template.html")];for(let $ of y)if(my.existsSync($))return $;throw Error("Auth template file not found. Please ensure the CLI package is properly installed.")}function s$(){try{let y=p0();return my.readFileSync(y,"utf-8")}catch(y){return console.warn("Warning: Using fallback auth template. Some styling may be missing."),`<!doctype html>
|
|
19
19
|
<html lang="en">
|
|
20
20
|
<head>
|
|
21
21
|
<meta charset="UTF-8" />
|
|
@@ -61,120 +61,120 @@ Use ${C.cyan("--overwrite")} or ${C.cyan("-o")} flag to overwrite existing files
|
|
|
61
61
|
{{AUTO_CLOSE_SCRIPT}}
|
|
62
62
|
</div>
|
|
63
63
|
</body>
|
|
64
|
-
</html>`}}function r$(){return s$().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 ly(y){return s$().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",y).replace("{{AUTO_CLOSE_SCRIPT}}","")}var Q$=W$.join(
|
|
65
|
-
✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch($){y.fail(`Authentication failed: ${$ instanceof Error?$.message:$}`),process.exit(1)}});async function
|
|
64
|
+
</html>`}}function r$(){return s$().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 ly(y){return s$().replace("{{TITLE}}","Authentication failed").replace("{{HEADING}}","Authentication failed").replace("{{DESCRIPTION}}",y).replace("{{AUTO_CLOSE_SCRIPT}}","")}var Q$=W$.join($1.homedir(),".untitledui"),z$=W$.join(Q$,"config.json"),i$=new n0().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let y=y1("Starting authentication...").start();try{await z1(y),y.succeed("Authentication completed successfully!"),console.log(Y$.green(`
|
|
65
|
+
✨ You can now access PRO components with the CLI!`)),process.exit(0)}catch($){y.fail(`Authentication failed: ${$ instanceof Error?$.message:$}`),process.exit(1)}});async function z1(y){return new Promise(($,j)=>{let Q=t0.createServer((z,Y)=>{let Z=new j1(z.url,"http://localhost");if(Z.pathname==="/callback"){let X=Z.searchParams.get("apiKey"),U=Z.searchParams.get("error");if(U){Y.writeHead(400,{"Content-Type":"text/html"}),Y.end(ly(decodeURIComponent(U))),Q.close(),j(Error(decodeURIComponent(U)));return}if(!X){Y.writeHead(400,{"Content-Type":"text/html"}),Y.end(ly("No Access Token received")),Q.close(),j(Error("No Access Token received"));return}try{Y1(X),Y.writeHead(200,{"Content-Type":"text/html"}),Y.end(r$()),Q.close(),$()}catch(M){Y.writeHead(500,{"Content-Type":"text/html"}),Y.end(ly("Failed to save authentication data")),Q.close(),j(M)}}else Y.writeHead(404),Y.end("Not found")});Q.listen(0,"localhost",()=>{let Z=`https://www.untitledui.com/react/api/cli-auth?port=${Q.address().port}`;y.text="Opening browser for authentication...",e0(Z).catch((X)=>{console.log(Y$.yellow(`
|
|
66
66
|
Failed to open browser automatically: ${X.message}`)),console.log(Y$.cyan(`Please manually open: ${Z}
|
|
67
|
-
`))}),y.text="Waiting for authentication in browser..."}),setTimeout(()=>{
|
|
68
|
-
Creating a new project in ${
|
|
67
|
+
`))}),y.text="Waiting for authentication in browser..."}),setTimeout(()=>{Q.close(),j(Error("Authentication timeout. Please try again."))},300000)})}function Y1(y){if(!Ly.existsSync(Q$))Ly.mkdirSync(Q$,{recursive:!0});let $={};if(Ly.existsSync(z$))try{$=JSON.parse(Ly.readFileSync(z$,"utf-8"))}catch{$={}}$.license=y,Ly.writeFileSync(z$,JSON.stringify($,null,2),"utf-8")}import L1 from"async-retry";import A from"chalk";import{Command as M1}from"commander";import*as m from"fs";import Fy from"ora";import*as S from"path";import by from"prompts";import{Project as H1}from"ts-morph";import Q1 from"node-fetch";async function Ey(y,$,j){try{let z=await Q1("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:y,key:$,version:j})});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),null}}import M$ from"async-retry";import h from"chalk";import{Command as W1}from"commander";import{execa as H$}from"execa";import K$ from"fast-glob";import a from"fs";import Iy from"ora";import*as g from"path";import iy from"prompts";import{Project as Z1}from"ts-morph";import{fileURLToPath as U1}from"url";import*as sy from"fs";import*as a$ from"path";function Z$(y,$){let j=a$.join(y,"package.json");if(!sy.existsSync(j))return $;let Q=JSON.parse(sy.readFileSync(j,"utf-8")),z={...Q.dependencies,...Q.devDependencies},Y=[];for(let Z of $){let X=z[Z];if(!X){Y.push(Z);continue}if(Z==="tailwindcss"){let U=X.match(/\d+/);if((U?parseInt(U[0],10):0)<4)Y.push(Z)}}return Y}import U$ from"chalk";import*as Ky from"fs";import*as ry from"path";function X$(y){if(!Ky.existsSync(ry.resolve(y)))console.log(U$.red(`Error: CSS file not found at ${y}`)),process.exit(1);let $=Ky.readFileSync(ry.resolve(y),"utf-8"),j=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,Q={},z;while((z=j.exec($))!==null)if(z[1]&&z[2])Q[z[1]]=z[2];return Q}function L$(y,$,j){let Q=ry.resolve(j);if(!Ky.existsSync(Q)){console.log(U$.red(`Error: CSS file not found at ${Q}`));return}let z=Ky.readFileSync(Q,"utf-8"),Y=X$(j),Z={},X={};for(let[M,J]of Object.entries(Y))if(M.startsWith(`--color-${y}-`)){let D=M.replace(`--color-${y}-`,"");Z[D]=M}else if(M.startsWith(`--color-${$}-`)){let D=M.replace(`--color-${$}-`,"");X[D]=J}let U=!1;for(let[M,J]of Object.entries(Z))if(X[M]){let D=X[M],q=new RegExp(`(${J}):\\s*rgb\\([^)]*\\);?`,"g");if(q.test(z))z=z.replace(q,`$1: ${D};`),U=!0;else console.log(U$.yellow(`No match found for ${J}`))}if(U)Ky.writeFileSync(Q,z,"utf-8")}var X1=U1(import.meta.url),o$=g.dirname(X1),n$="vite",t$="nextjs",p$={[t$]:"Next.js",[n$]:"Vite"},n="",O={color:"",template:"",framework:void 0,license:My()},e$=new W1().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(y,$)=>{if(y)n=y;if($){if(O.color=$.color,O.template=$.template,O.overwrite=$.overwrite,O.colorsList=$.colorsList,O.license=$.license||O.license,O.vite=$.vite,O.nextjs=$.nextjs,$.vite)O.framework=n$;if($.nextjs)O.framework=t$}try{await B$($),process.exit(0)}catch(j){console.error(h.red(j)),process.exit(1)}});async function B$(y,$=null){let j=process.cwd(),Q=a.existsSync(g.resolve(j,"package.json")),z=g.resolve(g.join(o$,"../config/styles","theme.css")),Y=X$(z??""),Z=Array.from(new Set(Object.keys(Y).map((J)=>J?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),X=Iy().start(),U=await qy(j);if(O.license)Oy(O.license);if(!Q){if(X.stop(),!n){let D=await iy({onState:f,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof D.path==="string")n=D.path.trim()}if($)$.projectPath=n;let J=a.existsSync(g.resolve(g.posix.join(j,n,"package.json")));if(a.existsSync(g.resolve(g.posix.join(j,n)))&&J)X.fail(h.red("Directory already exists!")),process.exit(1);if(O.vite&&O.nextjs||!O.framework){let D=await iy({type:"select",name:"framework",onState:f,message:`Which ${h.cyan("framework")} would you like to use?`,choices:Object.entries(p$).map(([q,_])=>({title:_,value:q}))});O.framework=D.framework}X.succeed("Framework is selected: "+h.green(p$[O.framework]))}else if(U?.framework==="other")X.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${h.cyan("https://www.untitledui.com/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(U?.framework.startsWith("next")||U?.framework.startsWith("vite"))if(!$&&!U.tailwind.brandColor)X.succeed(h.yellow(`Detected ${u$[U.framework]} project, proceeding with the setup...`));else X.stop();if(O.colorsList||!O.color&&!U?.tailwind.brandColor){let J=await iy({type:"select",name:"color",onState:f,initial:y.color??"",message:`Which ${h.cyan("color")} would you like to use as the ${h.cyanBright("brand")} color?`,choices:Z.map((D)=>({title:D,value:D}))});if(O.color=J.color,O.colorsList&&U)U.tailwind.brandColor=J.color}let M=g.posix.join(j,n||"");if(n&&!Q){let J=g.resolve(n);console.log(`
|
|
68
|
+
Creating a new project in ${h.blue(n)}`);let D=Iy("Downloading and extracting the repository...").start();try{a.mkdirSync(J,{recursive:!0}),await M$(()=>h$(J,{template:O.framework}),{retries:2}),D.succeed("Files are downloaded and extracted successfully!");let q=Iy({text:"Installing dependencies..."}).start(),_=K$.sync(["**/styles/theme.css"],{cwd:J,absolute:!0,onlyFiles:!0})[0];if(L$("brand",O.color||"",_??""),await M$(()=>H$(Vy(),["install"],{cwd:M}).catch(async(W)=>{if(W.message.includes("peer"))q.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing dependencies with --legacy-peer-deps flag"),await H$(Vy(),["install","--legacy-peer-deps"],{cwd:M})}),{retries:1}),await M$(()=>H$("git",["init"],{cwd:M}),{retries:1}),q.succeed("Dependencies are installed"),!$)console.log(`
|
|
69
69
|
Your project is ready, to get started run the following commands:
|
|
70
70
|
|
|
71
|
-
cd ${
|
|
72
|
-
${
|
|
71
|
+
cd ${h.cyan(n)}
|
|
72
|
+
${h.cyan(d$())}`)}catch(q){if(D.fail(h.red(`
|
|
73
73
|
Failed to download and extract the repository`)),q instanceof Error)console.error(q.message);else console.error(`
|
|
74
|
-
`);
|
|
75
|
-
`),
|
|
74
|
+
`);a.rmdirSync(J,{recursive:!0}),process.exit(1)}}else{let J=Iy(),D=new Set,q=U?.examples||"",_=wy(j,q),W=g.resolve(g.join(o$,"../config")),K=K$.sync(["**"],{cwd:W,onlyFiles:!0,ignore:s}),G=Z$(j,["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"]),F=Z$(j,["@tailwindcss/postcss","postcss"]);if(!$&&!U?.tailwind.brandColor)J.start("Copying files to the project directory");if(K.forEach((I)=>{let C=I.includes("postcss.config"),T=g.posix.join(g.posix.join(W),I),v=g.posix.join(j,C?I:cy(I,U?.paths,U?.isSrcDir));if(a.existsSync(v)){if(O?.overwrite)a.copyFileSync(T,v);else{let H=a.readFileSync(v,"utf-8"),L=a.readFileSync(T,"utf-8");if(H!==L){if(I.endsWith("theme.css")&&U?.tailwind.brandColor)return;D.add({targetFile:v,sourceFile:T})}}return}a.mkdirSync(g.dirname(v),{recursive:!0}),a.writeFileSync(v,""),a.copyFileSync(T,v)}),J.stop(),D.size&&!O?.overwrite){if(console.log(`
|
|
75
|
+
`),J.fail("Following files already exist in the directory."),D.forEach((C)=>{console.log(`- ${h.green(C.targetFile)}`)}),(await iy({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let C=Iy("Overwriting files").start();D.forEach((T)=>{a.copyFileSync(T.sourceFile,T.targetFile)}),C.succeed("Files are overwritten")}}if(_?.tailwindFile)console.log(`
|
|
76
76
|
Tailwind config file exists in the project directory. You can add it to your globals.css as follows:`),console.log(`
|
|
77
|
-
${
|
|
78
|
-
`);if(U?.framework==="vite"){if(!
|
|
79
|
-
Tailwind CSS is not configured in your Vite project. Please refer to the documentation ${
|
|
80
|
-
`)}let x=
|
|
81
|
-
Ensure that the ${
|
|
82
|
-
Your project is ready, you can now start adding components.`)}}var
|
|
83
|
-
|
|
84
|
-
`,""):
|
|
85
|
-
Please check your path aliases in components.json and tsconfig.json.`);m.mkdirSync(
|
|
86
|
-
Failed to add the component ${
|
|
87
|
-
Following files already exist in the directory.`),
|
|
88
|
-
Use ${
|
|
89
|
-
\uD83C\uDF89 Example ${
|
|
90
|
-
`);for(let
|
|
77
|
+
${h.cyan(`@config "../${U?.isSrcDir?"../":""}${g.relative(j,_.tailwindFile)}";`)}
|
|
78
|
+
`);if(U?.framework==="vite"){if(!P$(j))console.log(`
|
|
79
|
+
Tailwind CSS is not configured in your Vite project. Please refer to the documentation ${h.cyan("https://www.untitledui.com/react/integrations/vite")} for manual installation.
|
|
80
|
+
`)}let x=_?.layoutFile||_?.appFile||U?.framework==="vite"&&_?.mainFile||"";if(x){let C=new Z1({tsConfigFilePath:g.resolve(_?.tsConfig||"")}).addSourceFileAtPath(g.resolve(x)),T="styles/globals.css";if(!C.getImportDeclarations().some((H)=>{let L=H.getModuleSpecifierValue();return/(?:styles\/)?globals\.css$/.test(L)})){let H=U?.aliases?.styles||U?.aliases?.src||"",L=U?.aliases?.styles?`${H}globals.css`:`${H}styles/globals.css`;C.addImportDeclaration({moduleSpecifier:L})}C.saveSync()}let E=K$.sync(["**/theme.css"],{cwd:j,absolute:!0,onlyFiles:!0,ignore:s});if(!E?.length)return J.fail(`Failed to copy ${h.cyan("theme.css")} file.
|
|
81
|
+
Ensure that the ${h.cyan("theme.css")} file exists in the project directory under your ${h.yellow("styles")} folder.`);if((O.color||!U?.tailwind.brandColor)&&L$("brand",O.color||"brand",E[0]??""),G.length||F.length){let I=Iy().start("Installing dependencies");if(G.length)await Uy(G,{cwd:M,spinner:I,label:"dependencies"});if(F.length)await Uy(F,{cwd:M,dev:!0,spinner:I,label:"devDependencies"});I.succeed("Dependencies are installed")}if(!$&&!U?.tailwind.brandColor)J.succeed(h.green("Project setup is completed!"));if($&&Q){X.stop(),J.stop();return}else console.log(`
|
|
82
|
+
Your project is ready, you can now start adding components.`)}}var B={path:"",example:"",license:My(),components:[]},q$={},y0=new M1().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 components to.").option("-e, --example-path <example-path>","the path to add the example file to.").option("--include-all-components","automatically include all components from the example without prompting.",!1).option("-y, --yes","non-interactive mode - use defaults for all prompts (for AI agents/CI).",!1).option("--lib-version <version>","component library version (7 or 8)").action(async(y,$)=>{if(y)B.example=y;if($){if(B.path=$.path,B.overwrite=$.overwrite,B.examplePath=$.examplePath,B.includeAllComponents=$.includeAllComponents,B.yes=$.yes,B.license=$.license||B.license,B.version=$.libVersion,$.yes)B.includeAllComponents=!0,B.overwrite=!0}try{await B$($,q$),await B1()}catch(j){console.error(A.red(j))}});function K1(y,$){if($)return $;let j=S.resolve(y,"components.json");if(m.existsSync(j))try{return JSON.parse(m.readFileSync(j,"utf-8")).version??"8"}catch{}return"8"}async function B1(){let y=Fy().start(),$=S.posix.join(process.cwd(),q$?.projectPath||"");if(!m.existsSync(S.posix.join(S.resolve($,"package.json"))))y.warn("This command should be run in a project directory."),process.exit(1);let Q=K1($,B.version),z=await qy($);if(B.license)await hy(B.license,y);if(y.stop(),!B.example){if(B.yes)console.error(A.red("Error: Example name is required in non-interactive mode.")),console.log(`Usage: ${A.cyan("npx untitledui example <example-name> --yes")}`),console.log(`Example: ${A.cyan("npx untitledui example dashboards-01/01 --yes")}`),process.exit(1);let W=await by({type:"select",name:"example",onState:f,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});B.example=W.example}let Y=null;if(B.example){let W=await Ey(B.example,B.license,Q);if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(A.yellow(`\uD83D\uDD12 The ${A.cyan(B.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${A.green("→")} If you've already purchased: ${A.cyan(`${Zy()} untitledui@latest login`)}`),console.log(` ${A.green("→")} To purchase PRO examples: ${A.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(W?.type==="directory"){if(B.yes)if(W.results.length>0)B.example=W.results[0]||"",console.log(A.yellow(`Auto-selecting: ${B.example}`)),W=await Ey(B.example,B.license,Q);else console.error(A.red("Error: No examples found in directory.")),process.exit(1);else{let K=await by({type:"select",name:"example",onState:f,message:`Select a folder or file in "${B.example}"`,choices:W.results.map((G)=>({title:G,value:G}))});if(!K.example)return;B.example=K.example,W=await Ey(K.example,B.license,Q)}if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(A.yellow(`\uD83D\uDD12 The ${A.cyan(B.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${A.green("→")} If you've already purchased: ${A.cyan(`${Zy()} untitledui@latest login`)}`),console.log(` ${A.green("→")} To purchase PRO examples: ${A.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-files"){if(B.yes)if(W.results.length>0)B.example=`${B.example}/${W.results[0]}`,console.log(A.yellow(`Auto-selecting: ${B.example}`)),W=await Ey(B.example,B.license,Q);else console.error(A.red("Error: No example files found.")),process.exit(1);else{let K=await by({type:"select",name:"example",onState:f,message:`Select which example you want to add from "${B.example}"`,choices:W.results.map((G)=>({title:G,value:`${B.example}/${G}`}))});if(!K.example)return;B.example=K.example,W=await Ey(K.example,B.license,Q)}if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(A.yellow(`\uD83D\uDD12 The ${A.cyan(B.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${A.green("→")} If you've already purchased: ${A.cyan(`${Zy()} untitledui@latest login`)}`),console.log(` ${A.green("→")} To purchase PRO examples: ${A.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-file")Y=W.content}if(!Y)y.fail("No example found"),process.exit(1);let Z=z?.examples||"";if(Z){let W=await qy(S.posix.join($,Z));if(W)z={...W,aliases:z?.aliases||{}};B.examplePath=Z}if(!B?.examplePath){let W=z?.isAppDir?"app":"pages",K=z?.isSrcDir?S.posix.join("src",W):W;if(B.yes)B.examplePath=K,console.log(A.yellow(`Using default example path: ${K}`));else{let G=await by({type:"text",name:"examplePath",onState:f,message:`Where would you like to add the ${A.cyan(B?.example)} example?`,initial:K});B.examplePath=G.examplePath}}if(B.examplePath&&!m.existsSync(S.posix.join($,B.examplePath)))m.mkdirSync(S.posix.join($,B.examplePath),{recursive:!0}),console.log(A.green(`Created directory ${B.examplePath}`));if(!B?.path&&!z?.paths?.components)if(B.yes)B.path="components",console.log(A.yellow("Using default components path: components"));else{let W=await by({type:"text",name:"path",onState:f,message:`Where would you like to add the ${A.cyan("components")}?`,initial:"components"});B.path=W.path}if(B?.path&&z?.paths&&!z.paths.components)z.paths.components=S.posix.join(z?.isSrcDir?"src":"",B.path);if(!B?.path&&z?.paths?.components)B.path=z.paths.components.replace(/^src\//,"");let X=Y.components.filter((W)=>!m.existsSync(S.posix.join($,`${z?.isSrcDir?"src":""}`,W?.path?.replace(/components\//,B.path+"/"))));if(X?.length)if(B.includeAllComponents)B.components=X.map((W)=>W.name);else{let W=await by({type:"multiselect",name:"components",onState:f,message:`Select which components you want to add from ${A.cyan(Y.name)} example`,choices:X.map((K)=>({title:K?.name,value:K?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(B.components=W.components,!X.length&&!W.components?.length)y.warn("No components selected")}let U=wy($),M=new Set,J=new H1({tsConfigFilePath:U?.tsConfig}),D=Fy(`Adding ${B?.example}...`).start(),q="",_=new Set(Y.components.filter((W)=>B.components?.includes(W.name)).map((W)=>S.dirname(W.path)));try{for(let{path:W,code:K}of Y.files||[]){let G=S.dirname(W);if(Array.from(_).some((T)=>G===T||G.startsWith(T+"/")))continue;let x=S.posix.join($,`${z?.isSrcDir?"src":""}`,W.replace(/components\//,B.path+"/")),E=z?.framework==="vite"?K.replace(`"use client";
|
|
83
|
+
|
|
84
|
+
`,""):K,I=fy(E);if(W.includes("examples")){let T=S.basename(W);x=S.posix.join($,B?.examplePath??"",T),q=S.posix.join(B?.examplePath??"",T)}let C=S.dirname(x);if(m.existsSync(x)&&!B.overwrite){if(m.readFileSync(x,"utf-8")!==I)M.add({code:I,path:x})}else{let T=C.split(S.sep),v="";for(let L of T)if(v=v?S.join(v,L):L,v&&m.existsSync(v)&&m.statSync(v).isFile())throw Error(`Cannot create directory '${C}' because '${v}' is an existing file.
|
|
85
|
+
Please check your path aliases in components.json and tsconfig.json.`);m.mkdirSync(C,{recursive:!0}),m.writeFileSync(x,I);let H=J.getSourceFile(S.resolve(x));if(H)H.replaceWithText(I);else H=J.addSourceFileAtPath(S.resolve(x));H.getImportDeclarations().forEach((L)=>{let V=L.getModuleSpecifierValue();L.setModuleSpecifier(Ay(V,B.path,z?.aliases))}),await H.save()}}if(M.size)D.warn(`Some files of ${A.yellow(B?.example)} already exist`);else D.succeed(`${A.green(B?.example)} is added successfully`)}catch(W){D.fail(`
|
|
86
|
+
Failed to add the component ${A.red(B?.example)}`),console.error(A.red(W)),process.exit(1)}if(M.size&&!B?.overwrite){console.log(`
|
|
87
|
+
Following files already exist in the directory.`),M.forEach((K)=>{console.log(A.green(`- ${S.relative($,K.path)}`))});let W=!1;if(B.yes)W=!0,console.log(A.yellow("Auto-overwriting existing files (--yes mode)"));else{let K=await by({type:"confirm",name:"overwrite",onState:f,message:"Do you want to overwrite the existing files?",initial:!0});if(K.overwrite===void 0)console.log(`
|
|
88
|
+
Use ${A.cyan("--overwrite")} or ${A.cyan("-o")} flag to overwrite existing files, or run with ${A.cyan("node")} instead of ${A.cyan("bun")}.`),process.exit(1);W=K.overwrite}if(W){let K=Fy("Overwriting files").start();M.forEach((G)=>{let F=J.addSourceFileAtPath(S.resolve(G.path));F.replaceWithText(G.code),F.getImportDeclarations().forEach((x)=>{let E=x.getModuleSpecifierValue();x.setModuleSpecifier(Ay(E,B.path,z?.aliases))}),F.saveSync()}),K.succeed("Files are overwritten")}}if(Y?.dependencies?.length){let W=Fy().start();await Uy(Y.dependencies,{cwd:$,spinner:W,label:"example dependencies"})}if(Y?.devDependencies?.length){let W=Fy().start();await Uy(Y.devDependencies,{cwd:$,dev:!0,spinner:W,label:"example devDependencies"})}if(B?.components?.length)await L1(()=>$$({components:B.components,dir:q$?.projectPath||"",path:B.path,message:""}),{retries:1});console.log(`
|
|
89
|
+
\uD83C\uDF89 Example ${A.green(B.example)} has been added to ${A.green(q)}`),process.exit(0)}import P from"chalk";import{Command as q1}from"commander";import z0 from"fast-glob";import Dy from"fs";import $0 from"ora";import vy from"path";import V1 from"prompts";var G1={ArrowRight:"ArrowNext",ArrowLeft:"ArrowPrevious",ChevronRight:"ChevronNext",ChevronLeft:"ChevronPrevious",ChevronRightDouble:"ChevronNextDouble",ChevronLeftDouble:"ChevronPreviousDouble"},J1=[{pattern:/\bml-/g,replace:"ms-",description:"ml- → ms-"},{pattern:/\bmr-/g,replace:"me-",description:"mr- → me-"},{pattern:/\bpl-/g,replace:"ps-",description:"pl- → ps-"},{pattern:/\bpr-/g,replace:"pe-",description:"pr- → pe-"},{pattern:/(?<!from-|to-|placement-)(?<!\bin-placement-)\bleft-/g,replace:"start-",description:"left- → start-"},{pattern:/(?<!from-|to-|placement-)(?<!\bin-placement-)\bright-/g,replace:"end-",description:"right- → end-"},{pattern:/\brounded-l-/g,replace:"rounded-s-",description:"rounded-l- → rounded-s-"},{pattern:/\brounded-r-/g,replace:"rounded-e-",description:"rounded-r- → rounded-e-"},{pattern:/\brounded-tl-/g,replace:"rounded-ss-",description:"rounded-tl- → rounded-ss-"},{pattern:/\brounded-tr-/g,replace:"rounded-se-",description:"rounded-tr- → rounded-se-"},{pattern:/\brounded-bl-/g,replace:"rounded-es-",description:"rounded-bl- → rounded-es-"},{pattern:/\brounded-br-/g,replace:"rounded-ee-",description:"rounded-br- → rounded-ee-"},{pattern:/\bborder-l-/g,replace:"border-s-",description:"border-l- → border-s-"},{pattern:/\bborder-r-/g,replace:"border-e-",description:"border-r- → border-e-"},{pattern:/\bborder-l\b/g,replace:"border-s",description:"border-l → border-s"},{pattern:/\bborder-r\b/g,replace:"border-e",description:"border-r → border-e"},{pattern:/\btext-left\b/g,replace:"text-start",description:"text-left → text-start"},{pattern:/\btext-right\b/g,replace:"text-end",description:"text-right → text-end"},{pattern:/\bfloat-left\b/g,replace:"float-start",description:"float-left → float-start"},{pattern:/\bfloat-right\b/g,replace:"float-end",description:"float-right → float-end"},{pattern:/\bclear-left\b/g,replace:"clear-start",description:"clear-left → clear-start"},{pattern:/\bclear-right\b/g,replace:"clear-end",description:"clear-right → clear-end"},{pattern:/\bscroll-ml-/g,replace:"scroll-ms-",description:"scroll-ml- → scroll-ms-"},{pattern:/\bscroll-mr-/g,replace:"scroll-me-",description:"scroll-mr- → scroll-me-"},{pattern:/\bscroll-pl-/g,replace:"scroll-ps-",description:"scroll-pl- → scroll-ps-"},{pattern:/\bscroll-pr-/g,replace:"scroll-pe-",description:"scroll-pr- → scroll-pe-"}],By="(?:(sm|md|lg|xl|2xl):)?";function _y(y,$){let j=y.match(/^(sm|md|lg|xl|2xl):/);return j?`${y} ${j[1]}:rtl:${$}`:`${y} rtl:${$}`}var b1=[{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-in-from-right(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-in-from-left)/g,replace:(y)=>`${y} rtl:slide-in-from-left${y.replace("slide-in-from-right","")}`,description:"slide-in-from-right + rtl:slide-in-from-left",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-in-from-left(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-in-from-right)/g,replace:(y)=>`${y} rtl:slide-in-from-right${y.replace("slide-in-from-left","")}`,description:"slide-in-from-left + rtl:slide-in-from-right",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-out-to-right(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-out-to-left)/g,replace:(y)=>`${y} rtl:slide-out-to-left${y.replace("slide-out-to-right","")}`,description:"slide-out-to-right + rtl:slide-out-to-left",needsReview:!0},{pattern:/(?<!placement-\w+:|in-placement-\w+:|rtl:)\bslide-out-to-left(?:-([\d.]+|\[\S+\]))?\b(?!\s+rtl:slide-out-to-right)/g,replace:(y)=>`${y} rtl:slide-out-to-right${y.replace("slide-out-to-left","")}`,description:"slide-out-to-left + rtl:slide-out-to-right",needsReview:!0},{pattern:new RegExp(`(?<![-:])${By}translate-x-([\\d./]+(?=\\s|$|")|full|px|\\[\\S+\\])(?!\\s+rtl:)`,"g"),replace:(y)=>_y(y,`-${y.replace(/^(sm|md|lg|xl|2xl):/,"")}`),description:"translate-x + rtl:-translate-x",needsReview:!0},{pattern:new RegExp(`(?<=^|\\s|")${By}-translate-x-([\\d./]+(?=\\s|$|")|full|px|\\[\\S+\\])(?!\\s+rtl:)`,"g"),replace:(y)=>{let $=y.match(/^(sm|md|lg|xl|2xl):/),j=y.slice(y.indexOf("-translate-x-")+13);return $?`${y} ${$[1]}:rtl:translate-x-${j}`:`${y} rtl:translate-x-${j}`},description:"-translate-x + rtl:translate-x",needsReview:!0},{pattern:new RegExp(`\\b${By}space-x-(\\d+(?:\\.\\d+)?|\\[\\S+\\])(?!\\s+(?:sm:|md:|lg:|xl:|2xl:)?rtl:space-x-reverse)`,"g"),replace:(y)=>_y(y,"space-x-reverse"),description:"space-x + rtl:space-x-reverse",needsReview:!0},{pattern:new RegExp(`\\b${By}divide-x(?:-(\\d+(?:\\.\\d+)?|\\[\\S+\\]))?(?!\\s+(?:sm:|md:|lg:|xl:|2xl:)?rtl:divide-x-reverse)`,"g"),replace:(y)=>_y(y,"divide-x-reverse"),description:"divide-x + rtl:divide-x-reverse",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${By}bg-linear-to-r\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-linear-to-l)`,"g"),replace:(y)=>_y(y,"bg-linear-to-l"),description:"bg-linear-to-r + rtl:bg-linear-to-l",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${By}bg-linear-to-l\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-linear-to-r)`,"g"),replace:(y)=>_y(y,"bg-linear-to-r"),description:"bg-linear-to-l + rtl:bg-linear-to-r",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${By}bg-gradient-to-r\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-gradient-to-l)`,"g"),replace:(y)=>_y(y,"bg-gradient-to-l"),description:"bg-gradient-to-r + rtl:bg-gradient-to-l",needsReview:!0},{pattern:new RegExp(`(?<!rtl:)\\b${By}bg-gradient-to-l\\b(?! (?:sm:|md:|lg:|xl:|2xl:)?rtl:bg-gradient-to-r)`,"g"),replace:(y)=>_y(y,"bg-gradient-to-r"),description:"bg-gradient-to-l + rtl:bg-gradient-to-r",needsReview:!0}],_1=/\bleft-1\/2\b.*-translate-x-1\/2|-translate-x-1\/2.*\bleft-1\/2\b/,Y0=/\b(ml-|mr-|pl-|pr-|left-|right-|rounded-[lr]-|rounded-t[lr]-|rounded-b[lr]-|border-[lr]|text-left|text-right|float-left|float-right|scroll-m[lr]-|scroll-p[lr]-|translate-x-|space-x-|divide-x|bg-linear-to-[lr]|bg-gradient-to-[lr]|slide-in-from-(?:left|right)|slide-out-to-(?:left|right))/;function Q0(y,$){let j=y;for(let Q of $)j=j.replace(Q.pattern,Q.replace);return j}function D1(y,$,j){let Q={file:y,changes:[]},z=$.split(`
|
|
90
|
+
`);for(let Y=0;Y<z.length;Y++){let Z=z[Y];if(/^\s*(import\b|export\b.*from\b)/.test(Z)||/\brequire\s*\(/.test(Z))continue;if(_1.test(Z))continue;let X=Z,U=!1;if(X=X.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(M,J,D,q,_)=>{let W=J??D??q??_;if(W==null||!Y0.test(W))return M;let K=Q0(W,j);if(K!==W)return U=!0,M.replace(W,K);return M}),U&&X!==Z)z[Y]=X,Q.changes.push({line:Y+1,before:Z.trim(),after:X.trim()})}return Q}function N1(y){let $=0,j=y;for(let[Q,z]of Object.entries(G1)){let Y=new RegExp(`\\b${Q}\\b`,"g"),Z=j;if(j=j.replace(Y,z),j!==Z)$+=(Z.match(Y)||[]).length}return{content:j,swaps:$}}async function w1(y){let $=vy.resolve(y);return z0(["**/*.tsx","**/*.ts"],{cwd:$,absolute:!0,ignore:["**/node_modules/**","**/*.story.tsx","**/*.demo.tsx","**/*.test.tsx"]})}var W0="[data-rtl-flip]:dir(rtl) { transform: scaleX(-1); }";function j0(y){let $=["global.css","globals.css","styles/global.css","styles/globals.css","src/global.css","src/globals.css","src/styles/global.css","src/styles/globals.css","app/global.css","app/globals.css"];for(let Q of $){let z=vy.resolve(y,Q);if(Dy.existsSync(z))return z}let j=z0.sync(["**/*.css"],{cwd:y,absolute:!0,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/.next/**"]});for(let Q of j){let z=Dy.readFileSync(Q,"utf-8");if(z.includes("@import")&&z.includes("tailwindcss"))return Q}return j[0]||null}function A1(y,$){let j=Dy.readFileSync(y,"utf-8");if(j.includes("data-rtl-flip"))return!1;let Q=j.trimEnd()+`
|
|
91
91
|
|
|
92
92
|
`+W0+`
|
|
93
|
-
`;if(!$)Dy.writeFileSync(y,
|
|
93
|
+
`;if(!$)Dy.writeFileSync(y,Q);return!0}var Z0=new q1().name("migrate").description("migrate components for RTL support").argument("[path]","path to migrate (defaults to current directory)").option("--dry-run","preview changes without writing files",!1).option("--skip-icons","skip directional icon swapping",!1).option("-y, --yes","skip prompts and use defaults",!1).action(async(y,$)=>{console.log(P.bold(`
|
|
94
94
|
Migrate to RTL
|
|
95
|
-
`));let j=
|
|
95
|
+
`));let j=vy.resolve(y||".");if(!Dy.existsSync(j))console.log(P.red(` Path not found: ${j}`)),process.exit(1);let Q=!$.skipIcons,z=!0,Y=!1;if(!$.yes){let G=await V1([{type:$.skipIcons?null:"confirm",name:"swapIcons",message:"Swap directional icons for RTL-aware versions? (e.g. ArrowRight → ArrowNext)",initial:!0},{type:"confirm",name:"includeVariants",message:"Add rtl: variants for animations, gradients, translate, and space-x?",initial:!0},{type:$.dryRun?null:"confirm",name:"confirm",message:`Apply changes to ${P.cyan(j)}?`,initial:!0}]);if(G.confirm===!1){console.log(P.yellow(`
|
|
96
96
|
Cancelled.
|
|
97
|
-
`));return}
|
|
98
|
-
`).map((
|
|
99
|
-
`)[
|
|
100
|
-
`);let T=
|
|
101
|
-
`),
|
|
102
|
-
`);for(let
|
|
103
|
-
`),
|
|
97
|
+
`));return}Q=!$.skipIcons&&G.swapIcons!==!1,z=G.includeVariants!==!1,Y=Q}else Y=Q;let Z=$0(" Scanning files...").start(),X=await w1(j);Z.succeed(` Found ${P.bold(X.length)} files`);let U=[...J1,...z?b1:[]],M=0,J=0,D=0,q=[],_=$0(" Transforming...").start();for(let G of X){let F=Dy.readFileSync(G,"utf-8"),x=vy.relative(j,G),E=F,I=!1,C=D1(x,E,U);if(C.changes.length>0){E=F.split(`
|
|
98
|
+
`).map((H,L)=>{return C.changes.find((w)=>w.line===L+1)?E.split(`
|
|
99
|
+
`)[L]:H}).join(`
|
|
100
|
+
`);let T=E.split(`
|
|
101
|
+
`),v=F.split(`
|
|
102
|
+
`);for(let H of C.changes){let L=H.line-1,V=v[L];V=V.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(w,R,k,p,e)=>{let yy=R??k??p??e;if(yy==null||!Y0.test(yy))return w;let t=Q0(yy,U);return t!==yy?w.replace(yy,t):w}),T[L]=V}E=T.join(`
|
|
103
|
+
`),M+=C.changes.length,I=!0,q.push(C)}if(Q){let T=N1(E);if(T.swaps>0)E=T.content,J+=T.swaps,I=!0}if(I){if(D++,!$.dryRun)Dy.writeFileSync(G,E)}}_.succeed(` Processed ${P.bold(X.length)} files`);let W=!1,K="";if(Y&&J>0){let G=j0(j);if(G)K=vy.relative(j,G),W=A1(G,$.dryRun)}if(console.log(P.bold(`
|
|
104
104
|
Summary
|
|
105
|
-
`)),console.log(` Files modified: ${
|
|
106
|
-
Could not find a global CSS file to inject the RTL flip rule.`)),console.log(
|
|
107
|
-
`)),console.log(
|
|
108
|
-
`));else console.log(` RTL flip rule: ${
|
|
109
|
-
Dry run — no files were modified.`)),q.length>0){console.log(
|
|
105
|
+
`)),console.log(` Files modified: ${P.cyan(D)}`),console.log(` Class changes: ${P.cyan(M)}`),Q)console.log(` Icon swaps: ${P.cyan(J)}`);if(W)console.log(` RTL flip rule: ${P.cyan("added")} → ${P.dim(K)}`);else if(Y&&J>0&&!W)if(!j0(j))console.log(P.yellow(`
|
|
106
|
+
Could not find a global CSS file to inject the RTL flip rule.`)),console.log(P.yellow(` Add this manually to your global stylesheet:
|
|
107
|
+
`)),console.log(P.dim(` ${W0}
|
|
108
|
+
`));else console.log(` RTL flip rule: ${P.dim("already present")}`);if($.dryRun){if(console.log(P.yellow(`
|
|
109
|
+
Dry run — no files were modified.`)),q.length>0){console.log(P.bold(`
|
|
110
110
|
Changes preview:
|
|
111
|
-
`));for(let
|
|
112
|
-
... and ${q.length-10} more files`))}}else console.log(
|
|
113
|
-
Done! ${
|
|
111
|
+
`));for(let G of q.slice(0,10)){console.log(P.dim(` ${G.file}`));for(let F of G.changes.slice(0,3))console.log(P.red(` - ${F.before.substring(0,100)}`)),console.log(P.green(` + ${F.after.substring(0,100)}`));if(G.changes.length>3)console.log(P.dim(` ... and ${G.changes.length-3} more`))}if(q.length>10)console.log(P.dim(`
|
|
112
|
+
... and ${q.length-10} more files`))}}else console.log(P.green(`
|
|
113
|
+
Done! ${D} files updated.`));console.log()});import d from"chalk";import{Command as E1}from"commander";import V$ from"node-fetch";import I1 from"ora";var G$="https://www.untitledui.com/react/api/mcp/tools";async function x1(y,$,j=10,Q){return(await(await V$(`${G$}/search-components`,{method:"POST",headers:{"Content-Type":"application/json",...$&&{Authorization:`Bearer ${$}`}},body:JSON.stringify({query:y,limit:j,version:Q})})).json()).results||[]}async function T1(y,$,j=10,Q){return(await(await V$(`${G$}/get-page-templates`,{method:"POST",headers:{"Content-Type":"application/json",...$&&{Authorization:`Bearer ${$}`}},body:JSON.stringify({query:y,limit:j,version:Q})})).json()).templates||[]}async function S1(y,$=10){return(await(await V$(`${G$}/search-icons`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:y,limit:$})})).json()).results||[]}function F1(y,$){let j=y.access==="pro"?d.magenta(" PRO"):d.green(" FREE");if(console.log(` ${d.bold(`${$+1}. ${y.name}`)}${j} ${d.dim(`(${y.category})`)}`),console.log(` ${d.dim(y.description)}`),y.key_features?.length)console.log(` ${y.key_features.map((Q)=>d.cyan(Q)).join(" ")}`);console.log()}function v1(y,$){if(console.log(` ${d.bold(`${$+1}. ${y.name}`)} ${d.dim(`(${y.type} · ${y.layout})`)}`),console.log(` ${d.dim(y.description)}`),y.sections?.length)console.log(` ${d.dim("Sections:")} ${y.sections.map((j)=>d.cyan(j)).join(" ")}`);if(y.hero_style)console.log(` ${d.dim("Hero:")} ${d.yellow(y.hero_style)}`);console.log()}function R1(y,$){if(console.log(` ${d.bold(`${$+1}. ${y.importName}`)} ${d.dim(`(${y.category})`)}`),console.log(` ${d.dim(`import { ${y.importName} } from "@untitledui/icons"`)}`),y.tags?.length)console.log(` ${y.tags.slice(0,6).map((j)=>d.dim(j)).join(" ")}`);console.log()}var U0=new E1().name("search").description("search for components, templates, and icons using natural language").argument("<query...>","search query (e.g., 'login with reviews', 'dark pricing table')").option("-t, --type <type>","filter by type: components, templates, icons, all","all").option("-l, --limit <number>","max results per category","5").option("-k, --key <key>","API key for PRO access").option("--lib-version <version>","component library version (7 or 8)").action(async(y,$)=>{let j=y.join(" "),Q=parseInt($.limit,10),z=$.key||My()||void 0,Y=$.type.toLowerCase(),Z=$.libVersion,X=I1(`Searching for "${j}"...`).start();try{let U=Y==="all"||Y==="components",M=Y==="all"||Y==="templates",J=Y==="all"||Y==="icons",[D,q,_]=await Promise.all([U?x1(j,z,Q,Z):Promise.resolve([]),M?T1(j,z,Q,Z):Promise.resolve([]),J?S1(j,Q):Promise.resolve([])]);if(X.stop(),D.length+q.length+_.length===0){console.log(d.yellow(`
|
|
114
114
|
No results found for "${j}"
|
|
115
|
-
`));return}if(
|
|
116
|
-
Components (${
|
|
117
|
-
`)),
|
|
118
|
-
`))}}if(
|
|
119
|
-
Templates (${
|
|
120
|
-
`)),
|
|
121
|
-
`))}}if(
|
|
122
|
-
Icons (${
|
|
123
|
-
`)),
|
|
124
|
-
`,"utf-8");return{updated:
|
|
125
|
-
`);for(let
|
|
126
|
-
`),
|
|
127
|
-
`),changes:j}}function
|
|
128
|
-
`);for(let
|
|
129
|
-
`),changes:j}}function
|
|
130
|
-
`);for(let{pattern:
|
|
131
|
-
`);for(let
|
|
132
|
-
`,"utf-8")}async function _0(y){let $=
|
|
115
|
+
`));return}if(D.length>0){if(console.log(d.bold.underline(`
|
|
116
|
+
Components (${D.length})
|
|
117
|
+
`)),D.forEach(F1),D.length>0){let K=D[0].name;console.log(d.dim(` Install: npx untitledui@latest add ${K} --yes
|
|
118
|
+
`))}}if(q.length>0){if(console.log(d.bold.underline(`
|
|
119
|
+
Templates (${q.length})
|
|
120
|
+
`)),q.forEach(v1),q.length>0){let K=q[0].name;console.log(d.dim(` Install: npx untitledui@latest example ${K} --yes
|
|
121
|
+
`))}}if(_.length>0)console.log(d.bold.underline(`
|
|
122
|
+
Icons (${_.length})
|
|
123
|
+
`)),_.forEach(R1)}catch(U){X.fail("Search failed"),console.error(d.red(U instanceof Error?U.message:"Unknown error")),process.exit(1)}});import N from"chalk";import{Command as d1}from"commander";import{execa as b$}from"execa";import _$ from"fast-glob";import r from"fs";import o from"ora";import i from"path";import b0 from"prompts";var X0={fromVersion:"7",toVersion:"8",classTransforms:[{pattern:/\bshadow-xs-skeumorphic\b/g,replace:"shadow-xs-skeuomorphic",description:"shadow-xs-skeumorphic → shadow-xs-skeuomorphic (typo fix)"},{pattern:/\bshadow-skeumorphic\b/g,replace:"shadow-skeuomorphic",description:"shadow-skeumorphic → shadow-skeuomorphic (typo fix)"},{pattern:/\butility-gray-blue-/g,replace:"utility-slate-",description:"utility-gray-blue- → utility-slate-"},{pattern:/\butility-blue-light-/g,replace:"utility-sky-",description:"utility-blue-light- → utility-sky-"},{pattern:/\butility-gray-/g,replace:"utility-neutral-",description:"utility-gray- → utility-neutral-"},{pattern:/\butility-error-/g,replace:"utility-red-",description:"utility-error- → utility-red-"},{pattern:/\butility-warning-/g,replace:"utility-yellow-",description:"utility-warning- → utility-yellow-"},{pattern:/\butility-success-/g,replace:"utility-green-",description:"utility-success- → utility-green-"},{pattern:/\boutline-none\b/g,replace:"outline-hidden",description:"outline-none → outline-hidden"},{pattern:/\bbg-disabled_subtle\b/g,replace:"opacity-50",description:"bg-disabled_subtle → opacity-50",needsReview:!0},{pattern:/\bbg-disabled\b/g,replace:"opacity-50",description:"bg-disabled → opacity-50",needsReview:!0},{pattern:/\btext-disabled\b/g,replace:"",description:"text-disabled → removed",needsReview:!0},{pattern:/\bring-disabled_subtle\b/g,replace:"",description:"ring-disabled_subtle → removed",needsReview:!0},{pattern:/\bring-disabled\b/g,replace:"",description:"ring-disabled → removed",needsReview:!0},{pattern:/\bborder-disabled_subtle\b/g,replace:"",description:"border-disabled_subtle → removed",needsReview:!0},{pattern:/\bborder-disabled\b/g,replace:"",description:"border-disabled → removed",needsReview:!0},{pattern:/\btext-fg-disabled_subtle\b/g,replace:"",description:"text-fg-disabled_subtle → removed",needsReview:!0},{pattern:/\btext-fg-disabled\b/g,replace:"",description:"text-fg-disabled → removed",needsReview:!0},{pattern:/\btext-placeholder_subtle\b/g,replace:"",description:"text-placeholder_subtle → removed",needsReview:!0},{pattern:/\btext-button-primary-icon_hover\b/g,replace:"text-white/70",description:"text-button-primary-icon_hover → text-white/70"},{pattern:/\btext-button-primary-icon\b/g,replace:"text-white/60",description:"text-button-primary-icon → text-white/60"},{pattern:/\btext-button-destructive-primary-icon_hover\b/g,replace:"text-white/70",description:"text-button-destructive-primary-icon_hover → text-white/70"},{pattern:/\btext-button-destructive-primary-icon\b/g,replace:"text-white/60",description:"text-button-destructive-primary-icon → text-white/60"},{pattern:/\bbg-avatar-bg\b/g,replace:"bg-tertiary",description:"bg-avatar-bg → bg-tertiary"},{pattern:/\bring-bg-brand-solid\b/g,replace:"ring-brand-solid",description:"ring-bg-brand-solid → ring-brand-solid"},{pattern:/\bbg-active\b/g,replace:"bg-primary_hover",description:"bg-active → bg-primary_hover",needsReview:!0},{pattern:/\bbg-toggle-button-fg_disabled\b/g,replace:"",description:"bg-toggle-button-fg_disabled → removed",needsReview:!0}],importTransforms:[{from:"pin-input/pin-input",to:"input/pin-input",description:"pin-input moved into input directory"},{from:"nav-item-button",to:"nav-button",description:"nav-item-button renamed to nav-button"},{from:"select/multi-select",to:"select/tag-select",description:"multi-select renamed to tag-select (new multi-select is a different component)",symbolRenames:[{from:"MultiSelect",to:"TagSelect"}]}],propTransforms:[{from:'color="gray-blue"',to:'color="slate"',description:'color="gray-blue" renamed to color="slate"'},{from:'color="blue-light"',to:'color="sky"',description:'color="blue-light" renamed to color="sky"'}],structuralPatterns:[],orphanedTokens:["bg-disabled_subtle","text-disabled","ring-disabled","border-disabled","text-fg-disabled","bg-avatar-bg","text-button-primary-icon","text-button-destructive-primary-icon","bg-toggle-button-fg_disabled","utility-gray-","utility-error-","utility-warning-","utility-success-","utility-gray-blue-","utility-blue-light-","skeumorphic"],dependencyChanges:{update:{next:"16.2.0",react:"^19.2.4","react-dom":"^19.2.4","react-aria-components":"^1.16.0","react-aria":"^3.47.0",tailwindcss:"^4.2.2",motion:"^12.38.0",recharts:"^3.8.0"},add:{},devUpdate:{storybook:"^10.3.0",vite:"^8.0.0","@vitejs/plugin-react":"^6.0.1",eslint:"^10.0.3",typescript:"^5.9.3"},devAdd:{"@storybook/test-runner":"^0.24.3"},remove:[]},configChanges:{tsconfig:[{description:"Update JSX transform to react-jsx",find:'"jsx": "preserve"',replace:'"jsx": "react-jsx"'}]},notes:["The v7 MultiSelect (tag-chip style) has been renamed to TagSelect. The new MultiSelect is a different component with autocomplete. Update your imports accordingly.","Default size for Select, ComboBox, and Input changed from 'sm' to 'md'. Review component usage.","Avatar size 'xxs' removed. Use 'xs' instead.","Dropdown no longer defaults to selectionMode='single'. Set explicitly if needed."]};import*as xy from"fs";import*as J$ from"path";function L0(y){let{tsconfigPath:$,changes:j,dryRun:Q}=y,z=J$.resolve($),Y=[],Z=[],X;try{X=xy.readFileSync(z,"utf-8")}catch{return{applied:Y,skipped:j.map((M)=>M.description)}}let U=X;for(let M of j)if(U.includes(M.find))U=U.replace(M.find,M.replace),Y.push(M.description);else Z.push(M.description);if(!Q&&Y.length>0)xy.writeFileSync(z,U,"utf-8");return{applied:Y,skipped:Z}}function M0(y){let{packageJsonPath:$,update:j,add:Q,devUpdate:z,devAdd:Y,remove:Z,dryRun:X}=y,U=J$.resolve($),M=[],J=[],D=[],q;try{let _=xy.readFileSync(U,"utf-8");q=JSON.parse(_)}catch{return{updated:M,added:J,removed:D}}if(!q.dependencies)q.dependencies={};if(!q.devDependencies)q.devDependencies={};for(let[_,W]of Object.entries(j))if(q.dependencies[_])q.dependencies[_]=W,M.push(_);for(let[_,W]of Object.entries(Q))if(!q.dependencies[_])q.dependencies[_]=W,J.push(_);for(let[_,W]of Object.entries(z))if(q.devDependencies[_])q.devDependencies[_]=W,M.push(_);for(let[_,W]of Object.entries(Y))if(!q.devDependencies[_])q.devDependencies[_]=W,J.push(_);for(let _ of Z){if(q.dependencies[_])delete q.dependencies[_],D.push(_);if(q.devDependencies[_]){if(delete q.devDependencies[_],!D.includes(_))D.push(_)}}if(!X&&(M.length>0||J.length>0||D.length>0))xy.writeFileSync(U,JSON.stringify(q,null,2)+`
|
|
124
|
+
`,"utf-8");return{updated:M,added:J,removed:D}}import*as Ty from"fs";import*as H0 from"path";function C1(y){let $=/--color-brand-(\d+):\s*([^;]+);/g,j={},Q;while((Q=$.exec(y))!==null)if(Q[1]&&Q[2])j[`--color-brand-${Q[1]}`]=Q[2].trim();return j}function u1(y,$){let j=y;for(let[Q,z]of Object.entries($)){let Y=new RegExp(`(${Q.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}):\\s*[^;]+;`,"g");j=j.replace(Y,`${Q}: ${z};`)}return j}async function K0(y){let{themePath:$,newThemeContent:j,dryRun:Q}=y,z=H0.resolve($),Y;try{Y=Ty.readFileSync(z,"utf-8")}catch{return{brandColors:{},success:!1,message:`Theme file not found at ${z}`}}let Z=C1(Y);if(Q)return{brandColors:Z,success:!0,message:`Dry run: found ${Object.keys(Z).length} brand color variables`};try{if(Ty.writeFileSync(z,j,"utf-8"),Object.keys(Z).length>0){let X=Ty.readFileSync(z,"utf-8"),U=u1(X,Z);Ty.writeFileSync(z,U,"utf-8")}return{brandColors:Z,success:!0,message:`Theme upgraded successfully. Preserved ${Object.keys(Z).length} brand color variables.`}}catch(X){let U=X instanceof Error?X.message:String(X);return{brandColors:Z,success:!1,message:`Failed to write theme file: ${U}`}}}var O1=/\bleft-1\/2\b.*-translate-x-1\/2|-translate-x-1\/2.*\bleft-1\/2\b/;function k1(y,$){return $.some((j)=>j.pattern.test(y))}function g1(y,$){let j=y;for(let Q of $)Q.pattern.lastIndex=0,j=j.replace(Q.pattern,Q.replace);return j}function P1(y,$,j){let Q=[];for(let z of j){if(z.pattern.lastIndex=0,z.pattern.test(y))Q.push(z.description);z.pattern.lastIndex=0}return Q.join("; ")}function B0(y,$,j){let Q={file:y,changes:[]},z=$.split(`
|
|
125
|
+
`);for(let Y=0;Y<z.length;Y++){let Z=z[Y];if(/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(Z))continue;if(O1.test(Z))continue;let X=Z,U=!1;if(X=X.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(M,J,D,q,_)=>{let W=J??D??q??_;if(W==null)return M;for(let G of j)G.pattern.lastIndex=0;if(!k1(W,j))return M;for(let G of j)G.pattern.lastIndex=0;let K=g1(W,j);if(K!==W)return U=!0,M.replace(W,K);return M}),U&&X!==Z){let M=P1(Z,X,j);z[Y]=X,Q.changes.push({line:Y+1,before:Z.trim(),after:X.trim(),description:M})}}return Q}function q0(y,$){let j=[],Q=y.split(`
|
|
126
|
+
`),z=[];for(let Y=0;Y<Q.length;Y++){let Z=Q[Y];if(!/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(Z))continue;let X=Z;for(let U of $)if(X.includes(U.from)){if(X=X.replace(U.from,U.to),U.symbolRenames)z.push(...U.symbolRenames)}if(X!==Z){Q[Y]=X;let U=$.find((M)=>Z.includes(M.from));j.push({line:Y+1,before:Z.trim(),after:X.trim(),description:U?.description??"Import path update"})}}if(z.length>0)for(let Y=0;Y<Q.length;Y++){let Z=Q[Y],X=Z;for(let U of z){let M=new RegExp(`\\b${U.from}\\b`,"g");X=X.replace(M,U.to)}if(X!==Z){if(Q[Y]=X,!j.some((M)=>M.line===Y+1))j.push({line:Y+1,before:Z.trim(),after:X.trim(),description:`Renamed ${z.map((M)=>`${M.from} → ${M.to}`).join(", ")}`})}}return{content:Q.join(`
|
|
127
|
+
`),changes:j}}function V0(y,$){let j=[],Q=y.split(`
|
|
128
|
+
`);for(let z=0;z<Q.length;z++){let Y=Q[z];if(/^\s*(import\b|require\s*\(|export\b.*from\b)/.test(Y))continue;let Z=Y;for(let X of $)if(Z.includes(X.from))Z=Z.split(X.from).join(X.to);if(Z!==Y){Q[z]=Z;let X=$.find((U)=>Y.includes(U.from));j.push({line:z+1,before:Y.trim(),after:Z.trim(),description:X?.description??"Prop update"})}}return{content:Q.join(`
|
|
129
|
+
`),changes:j}}function G0(y,$,j){let Q=[],z=$.split(`
|
|
130
|
+
`);for(let{pattern:Y,instruction:Z}of j)for(let X=0;X<z.length;X++){if(/^\s*(import\b|export\b.*from\b)/.test(z[X])||/\brequire\s*\(/.test(z[X]))continue;if(z[X].includes(Y))Q.push({file:y,line:X+1,pattern:Y,instruction:Z})}return Q}function J0(y,$,j){let Q=[],z=$.split(`
|
|
131
|
+
`);for(let Y=0;Y<z.length;Y++)for(let Z of j)if(z[Y].includes(Z))Q.push({file:y,line:Y+1,token:Z});return Q}function f1(y){return{fromVersion:y.fromVersion,toVersion:y.toVersion,classTransforms:y.classRenames.map(($)=>({pattern:new RegExp(`\\b${D0($.from)}\\b`,"g"),replace:$.to,description:$.description,needsReview:$.needsReview})),importTransforms:y.importRenames,propTransforms:y.propRenames,structuralPatterns:y.structuralPatterns,orphanedTokens:y.orphanedTokens,dependencyChanges:y.dependencyChanges,configChanges:y.configChanges,notes:y.notes}}function D0(y){return y.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function c1(y){let $=i.join(y,"components.json");try{return JSON.parse(r.readFileSync($,"utf-8"))}catch{return null}}function h1(y,$){let j=i.join(y,"components.json");r.writeFileSync(j,JSON.stringify($,null,2)+`
|
|
132
|
+
`,"utf-8")}async function _0(y){let $=i.resolve(y);return _$(["**/*.{tsx,ts}"],{cwd:$,absolute:!0,ignore:["**/node_modules/**","**/*.story.tsx","**/*.demo.tsx","**/.next/**","**/dist/**","**/build/**"]})}async function m1(y){return(await _$(["**/theme.css"],{cwd:y,absolute:!0,deep:5,ignore:["**/node_modules/**","**/.next/**","**/dist/**"]}))[0]}function l1(y){let $=i.join(y,"package.json");return r.existsSync($)?$:void 0}function s1(y){let $=i.join(y,"tsconfig.json");return r.existsSync($)?$:void 0}function r1(y){let $=0;for(let j=0;j<y.length;j++){let Q=y.charCodeAt(j);$=($<<5)-$+Q|0}return $.toString(36)}var N0=new d1().name("upgrade").description("upgrade your project to the latest version of Untitled UI").option("--dry-run","preview changes without writing files",!1).option("--skip-theme","skip theme.css replacement",!1).option("--skip-deps","skip dependency updates",!1).option("--skip-config","skip config file updates",!1).option("--path <dir>","directory to scan for source files").option("-y, --yes","skip prompts and use defaults",!1).action(async(y)=>{console.log(N.bold(`
|
|
133
133
|
Upgrade Untitled UI
|
|
134
|
-
`));let $=
|
|
134
|
+
`));let $=i.resolve(y.path||".");try{let{stdout:H}=await b$("git",["status","--porcelain"],{cwd:$});if(H.trim().length>0){if(console.log(N.yellow(" You have uncommitted changes. We recommend committing first so you can\n revert with `git checkout .` if needed.")),!y.yes){let{proceed:L}=await b0({type:"confirm",name:"proceed",message:"Continue with uncommitted changes?",initial:!0});if(!L){console.log(N.yellow(`
|
|
135
135
|
Cancelled.
|
|
136
|
-
`));return}}console.log()}}catch{}let j=
|
|
137
|
-
`),
|
|
138
|
-
`));return}let Y,
|
|
139
|
-
`);for(let t of k.changes){let Ry=t.line-1,$y=yy[Ry];$y=$y.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(
|
|
140
|
-
`),
|
|
141
|
-
`).filter((
|
|
142
|
-
`,"utf-8")}catch{}if(
|
|
136
|
+
`));return}}console.log()}}catch{}let j=c1($),Q=j?.version??"7";if(console.log(` Detected version: ${N.cyan(Q)}
|
|
137
|
+
`),Q==="8"){console.log(N.green(` Already on version 8. Nothing to upgrade.
|
|
138
|
+
`));return}let z,Y,Z=o(" Fetching migration rules...").start();try{let H=await fetch("https://www.untitledui.com/react/api/upgrade",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fromVersion:Q,toVersion:"8"})});if(!H.ok)throw Error(`Server returned ${H.status}`);let L=await H.json();z=f1(L),Y="server",Z.succeed(" Migration rules fetched from server")}catch{z=X0,Y="built-in",Z.warn(" Could not reach server. Using built-in migration rules")}let X=o(" Scanning files...").start(),U=await _0($);X.succeed(` Found ${N.bold(U.length)} source files`);let M=0,J=0,D=0,q=0,_=[],W=[],K=[],G=[];if(!y.skipTheme){let H=o(" Upgrading theme.css...").start(),L=await m1($);if(L)try{let V=i.resolve(import.meta.dirname,"../config/styles/theme.css"),w=r.readFileSync(V,"utf-8"),R=await K0({themePath:L,newThemeContent:w,dryRun:y.dryRun});if(R.success){let k=Object.keys(R.brandColors);if(k.length>0)H.succeed(` Theme upgraded. Brand colors preserved: ${N.cyan(k.join(", "))}`);else H.succeed(" Theme upgraded (no custom brand colors found)")}else H.warn(` Theme upgrade issue: ${R.message}`)}catch(V){let w=V instanceof Error?V.message:String(V);H.warn(` Theme upgrade skipped: ${w}`)}else H.warn(" No theme.css found — skipping theme upgrade")}if(!y.skipConfig){let H=o(" Updating config files...").start(),L=s1($);if(L&&z.configChanges.tsconfig.length>0){let{applied:V,skipped:w}=L0({tsconfigPath:L,changes:z.configChanges.tsconfig,dryRun:y.dryRun});if(V.length>0)H.succeed(` Config updated: ${V.map((R)=>N.cyan(R)).join(", ")}`);else H.info(" No config changes needed");if(w.length>0)for(let R of w)console.log(N.dim(` Skipped: ${R}`))}else H.info(" No config changes to apply")}if(!y.skipDeps){let H=o(" Updating dependencies...").start(),L=l1($);if(L){let V=M0({packageJsonPath:L,update:z.dependencyChanges.update,add:z.dependencyChanges.add,devUpdate:z.dependencyChanges.devUpdate,devAdd:z.dependencyChanges.devAdd,remove:z.dependencyChanges.remove,dryRun:y.dryRun});if(V.updated.length+V.added.length+V.removed.length>0){if(H.succeed(" Dependencies updated in package.json"),V.updated.length>0)console.log(N.dim(` Updated: ${V.updated.join(", ")}`));if(V.added.length>0)console.log(N.dim(` Added: ${V.added.join(", ")}`));if(V.removed.length>0)console.log(N.dim(` Removed: ${V.removed.join(", ")}`));if(!y.dryRun){let R=o(" Installing dependencies...").start();try{let k=Zy();await b$(k==="bunx"?"bun":k==="pnpx"?"pnpm":k==="yarn"?"yarn":"npm",["install"],{cwd:$}),R.succeed(" Dependencies installed")}catch(k){let p=k instanceof Error?k.message:String(k);R.warn(` Could not auto-install dependencies: ${p.substring(0,100)}`),console.log(N.dim(" Run your package manager's install command manually."))}}}else H.info(" No dependency changes needed")}else H.warn(" No package.json found — skipping dependency updates")}let F=o(" Renaming files...").start(),x=new Set;for(let H of z.importTransforms){let L=H.from.split("/").pop(),V=H.to.split("/").pop();if(L===V)continue;let w=_$.sync([`**/${L}.tsx`,`**/${L}.ts`],{cwd:$,absolute:!0,ignore:["**/node_modules/**"]});for(let R of w){let k=R.replace(new RegExp(`${D0(L)}(\\.tsx?)$`),`${V}$1`);if(!y.dryRun)try{r.renameSync(R,k),x.add(H.from)}catch{}else x.add(H.from)}}let E=z.importTransforms.filter((H)=>{let L=H.from.split("/").pop(),V=H.to.split("/").pop();if(L===V)return!0;return x.has(H.from)});if(x.size>0)F.succeed(` Renamed ${N.bold(x.size)} files`),U.length=0,U.push(...await _0($));else F.info(" No file renames needed");let I=o(" Applying source transforms...").start();for(let H of U){let L;try{L=r.readFileSync(H,"utf-8")}catch{continue}let V=i.relative($,H),w=L,R=!1,k=B0(V,w,z.classTransforms);if(k.changes.length>0){let yy=w.split(`
|
|
139
|
+
`);for(let t of k.changes){let Ry=t.line-1,$y=yy[Ry];$y=$y.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(ay,w0,A0,E0,I0)=>{let Cy=w0??A0??E0??I0;if(Cy==null)return ay;let uy=Cy;for(let oy of z.classTransforms)oy.pattern.lastIndex=0,uy=uy.replace(oy.pattern,oy.replace);return uy!==Cy?ay.replace(Cy,uy):ay}),yy[Ry]=$y}w=yy.join(`
|
|
140
|
+
`),M+=k.changes.length,R=!0,_.push(k);for(let t of k.changes){let Ry=z.classTransforms.find(($y)=>{return $y.pattern.lastIndex=0,$y.needsReview&&$y.pattern.test(t.before)});for(let $y of z.classTransforms)$y.pattern.lastIndex=0;if(Ry)W.push({file:V,line:t.line,description:t.description,before:t.before,after:t.after})}}let p=V0(w,z.propTransforms);if(p.changes.length>0)w=p.content,J+=p.changes.length,R=!0;let e=q0(w,E);if(e.changes.length>0)w=e.content,D+=e.changes.length,R=!0;if(R){if(q++,!y.dryRun)r.writeFileSync(H,w)}}I.succeed(` Processed ${N.bold(U.length)} files`);let C=o(" Detecting structural patterns...").start();for(let H of U){let L;try{L=r.readFileSync(H,"utf-8")}catch{continue}let V=i.relative($,H),w=G0(V,L,z.structuralPatterns);G.push(...w)}if(G.length>0)C.warn(` Found ${N.bold(G.length)} structural patterns requiring manual review`);else C.succeed(" No structural patterns found");if(j?.components&&Array.isArray(j.components)&&j.components.some((H)=>H.contentHash)){let H=o(" Checking stock components...").start(),L=[];for(let V of j.components){if(!V.contentHash||!V.filePath)continue;let w=i.resolve($,V.filePath);try{let R=r.readFileSync(w,"utf-8");if(r1(R)===V.contentHash)L.push({name:V.name,path:V.filePath})}catch{}}if(L.length>0){H.info(` ${N.bold(L.length)} stock components can be auto-refreshed`);let V=y.yes;if(!V){let{confirm:w}=await b0({type:"confirm",name:"confirm",message:`Refresh ${L.length} unmodified stock components to v8.0?`,initial:!0});V=w}if(V&&!y.dryRun){let w=o(" Fetching v8.0 components...").start();try{let R=await fetch("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({components:L.map((k)=>k.name),version:"8"})});if(R.ok){let k=await R.json(),p=0;for(let e of L)if(k[e.name])r.writeFileSync(i.resolve($,e.path),k[e.name]),p++;w.succeed(` Refreshed ${N.bold(p)} stock components`)}else w.warn(" Could not fetch v8.0 components from server")}catch{w.warn(" Could not reach server for component refresh")}}}else H.info(" No unmodified stock components to refresh")}let T=o(" Scanning for orphaned tokens...").start();for(let H of U){let L;try{L=r.readFileSync(H,"utf-8")}catch{continue}let V=i.relative($,H),w=J0(V,L,z.orphanedTokens);K.push(...w)}if(K.length>0)T.warn(` Found ${N.bold(K.length)} orphaned v7.0 tokens remaining`);else T.succeed(" No orphaned tokens found");let v=[];if(!y.dryRun){let H=o(" Running type check...").start();try{let L=Zy();await b$(L,["tsc","--noEmit"],{cwd:$}),H.succeed(" Type check passed")}catch(L){let w=(L?.stderr||L?.stdout||"").split(`
|
|
141
|
+
`).filter((R)=>R.includes("error TS")).slice(0,20);v.push(...w),H.warn(` Type check found ${N.bold(w.length)} error(s)`)}}if(!y.dryRun){let H={version:"8",status:W.length>0||K.length>0?"partial":"success",filesScanned:U.length,filesModified:q,classChanges:M,propChanges:J,importChanges:D,manualReview:W,orphanedTokens:K,typeErrors:v,structuralPatterns:G,notes:z.notes};try{r.writeFileSync(i.join($,"upgrade-report.json"),JSON.stringify(H,null,2)+`
|
|
142
|
+
`,"utf-8")}catch{}if(W.length>0||G.length>0)try{let L=`# Untitled UI v7.0 to v8.0 Upgrade Instructions
|
|
143
143
|
|
|
144
|
-
`;if(
|
|
144
|
+
`;if(L+="This file was generated by `untitledui upgrade`. It is meant to guide\n",L+=`manual review of changes that could not be fully automated.
|
|
145
145
|
|
|
146
|
-
`,
|
|
147
|
-
`,
|
|
146
|
+
`,L+=`**Important**: Ignore pre-existing type errors and linting issues.
|
|
147
|
+
`,L+=`Focus only on migration-related changes listed below.
|
|
148
148
|
|
|
149
|
-
`,
|
|
149
|
+
`,L+=`Delete this file after review is complete.
|
|
150
150
|
|
|
151
|
-
`,
|
|
151
|
+
`,G.length>0){L+=`## Structural changes
|
|
152
152
|
|
|
153
|
-
`,
|
|
153
|
+
`,L+=`These patterns require manual refactoring:
|
|
154
154
|
|
|
155
|
-
`;for(let
|
|
156
|
-
`,
|
|
155
|
+
`;for(let V of G)L+=`- **${V.file}:${V.line}** — \`${V.pattern}\`
|
|
156
|
+
`,L+=` ${V.instruction}
|
|
157
157
|
|
|
158
|
-
`}if(
|
|
158
|
+
`}if(W.length>0){L+=`## Manual review items
|
|
159
159
|
|
|
160
|
-
`,
|
|
160
|
+
`,L+=`These class replacements may need manual verification:
|
|
161
161
|
|
|
162
|
-
`;for(let
|
|
162
|
+
`;for(let V of W)L+=`### ${V.file}:${V.line}
|
|
163
163
|
|
|
164
|
-
`,
|
|
164
|
+
`,L+=`${V.description}
|
|
165
165
|
|
|
166
|
-
`,
|
|
167
|
-
`,
|
|
168
|
-
`,
|
|
166
|
+
`,L+="```diff\n",L+=`- ${V.before}
|
|
167
|
+
`,L+=`+ ${V.after}
|
|
168
|
+
`,L+="```\n\n"}if(z.notes.length>0){L+=`## Additional notes
|
|
169
169
|
|
|
170
|
-
`;for(let
|
|
171
|
-
`;
|
|
172
|
-
`}
|
|
170
|
+
`;for(let V of z.notes)L+=`- ${V}
|
|
171
|
+
`;L+=`
|
|
172
|
+
`}r.writeFileSync(i.join($,"UPGRADE-INSTRUCTIONS.md"),L,"utf-8")}catch{}}if(!y.dryRun&&j)j.version="8",h1($,j);if(console.log(N.bold(`
|
|
173
173
|
Summary
|
|
174
|
-
`)),console.log(` Migration source: ${N.cyan(
|
|
175
|
-
Dry run — no files were modified.`)),
|
|
174
|
+
`)),console.log(` Migration source: ${N.cyan(Y)}`),console.log(` Files scanned: ${N.cyan(U.length)}`),console.log(` Files modified: ${N.cyan(q)}`),console.log(` Class changes: ${N.cyan(M)}`),console.log(` Prop changes: ${N.cyan(J)}`),console.log(` Import changes: ${N.cyan(D)}`),G.length>0){console.log(` Structural patterns: ${N.yellow(G.length)}`);for(let H of G.slice(0,5))console.log(N.dim(` ${H.file}:${H.line} — ${H.pattern}`));if(G.length>5)console.log(N.dim(` ... and ${G.length-5} more (see UPGRADE-INSTRUCTIONS.md)`))}if(W.length>0){console.log(` Manual review items: ${N.yellow(W.length)}`);for(let H of W.slice(0,5))console.log(N.dim(` ${H.file}:${H.line} — ${H.description}`));if(W.length>5)console.log(N.dim(` ... and ${W.length-5} more (see UPGRADE-INSTRUCTIONS.md)`))}if(K.length>0){console.log(` Orphaned tokens: ${N.yellow(K.length)}`);let H=[...new Set(K.map((L)=>L.token))];for(let L of H.slice(0,5))console.log(N.dim(` ${L}`));if(H.length>5)console.log(N.dim(` ... and ${H.length-5} more`))}if(v.length>0)console.log(` Type errors: ${N.yellow(v.length)}`);if(y.dryRun){if(console.log(N.yellow(`
|
|
175
|
+
Dry run — no files were modified.`)),_.length>0){console.log(N.bold(`
|
|
176
176
|
Changes preview:
|
|
177
|
-
`));for(let
|
|
178
|
-
... and ${
|
|
177
|
+
`));for(let H of _.slice(0,10)){console.log(N.dim(` ${H.file}`));for(let L of H.changes.slice(0,3))console.log(N.red(` - ${L.before.substring(0,100)}`)),console.log(N.green(` + ${L.after.substring(0,100)}`));if(H.changes.length>3)console.log(N.dim(` ... and ${H.changes.length-3} more`))}if(_.length>10)console.log(N.dim(`
|
|
178
|
+
... and ${_.length-10} more files`))}console.log(N.dim(`
|
|
179
179
|
Run without --dry-run to apply changes.
|
|
180
|
-
`))}else console.log(N.green("\n Done! Run `bun run build` to verify.")),console.log(N.dim(" If something went wrong, run `git checkout .` to revert.\n"))});var D$={name:"untitledui",version:"0.1.
|
|
180
|
+
`))}else console.log(N.green("\n Done! Run `bun run build` to verify.")),console.log(N.dim(" If something went wrong, run `git checkout .` to revert.\n"))});var D$={name:"untitledui",version:"0.1.59",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:"bun test __tests__/",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",repository:{type:"git",url:"https://github.com/untitleduico/react.git",directory:"cli"},engines:{node:">=18"},keywords:["untitledui","untitled-ui","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/bun":"^1.3.10","@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 o1(){let y=new a1().name(D$.name).version(D$.version);y.addCommand(e$).addCommand(l$).addCommand(y0).addCommand(U0).addCommand(i$).addCommand(Z0).addCommand(N0),y.parse()}o1();
|