untitledui 0.1.56 → 0.1.57
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/styles/theme.css +1 -1
- package/dist/index.mjs +8 -8
- package/package.json +1 -1
package/config/styles/theme.css
CHANGED
|
@@ -719,7 +719,7 @@
|
|
|
719
719
|
--color-bg-warning-solid: var(--color-yellow-600);
|
|
720
720
|
--color-bg-success-solid: var(--color-green-600);
|
|
721
721
|
--color-bg-secondary_hover: var(--color-neutral-800);
|
|
722
|
-
--color-bg-primary_hover: var(--color-neutral-
|
|
722
|
+
--color-bg-primary_hover: var(--color-neutral-900);
|
|
723
723
|
--color-bg-active: var(--color-neutral-800);
|
|
724
724
|
--color-bg-brand-solid_hover: var(--color-brand-500);
|
|
725
725
|
--color-bg-error-primary: var(--color-red-950);
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as r1}from"commander";import C from"chalk";import{Command as s0}from"commander";import*as i from"fs";import vy from"ora";import*as h from"path";import Jy from"prompts";import{Project as r0}from"ts-morph";import*as jy from"fs";import*as py from"path";import I0 from"os";var N$=py.join(I0.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 z=w$(j);if(z.license!==y)z.license=y,jy.writeFileSync(j,JSON.stringify(z,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){let Y=$.map((W)=>{if(W.includes("modals/"))if(W.includes("-modal"))return W;else return W+"-modal";return W});try{let W=await T0("
|
|
2
|
+
import{Command as r1}from"commander";import C from"chalk";import{Command as s0}from"commander";import*as i from"fs";import vy from"ora";import*as h from"path";import Jy from"prompts";import{Project as r0}from"ts-morph";import*as jy from"fs";import*as py from"path";import I0 from"os";var N$=py.join(I0.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 z=w$(j);if(z.license!==y)z.license=y,jy.writeFileSync(j,JSON.stringify(z,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){let Y=$.map((W)=>{if(W.includes("modals/"))if(W.includes("-modal"))return W;else return W+"-modal";return W});try{let W=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})});if(!W.ok)console.log(A$?.[W.statusText]||A$.no_components_found),process.exit(1);return await W.json()}catch(W){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,$=""){let j=`https://www.untitledui.com/react/api/components/list?key=${$}&type=${y}`;try{let z=await ty(j),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 x$(y,$="",j){let z=`https://www.untitledui.com/react/api/components/list?key=${$}&type=${y}&subfolders=${j.join(",")}`;try{let Y=await ty(z);if(!Y.ok)console.log(Ny?.[Y.statusText]||Ny.no_components_found),process.exit(1);let W=await Y.json();if(!W?.components?.length)return null;return W}catch(Y){return console.error(Y),null}}async function I$(y=""){let $=`https://www.untitledui.com/react/api/components/list?key=${y}`;try{let j=await ty($);if(!j.ok)console.log(Ny?.[j.statusText]||Ny.no_components_found),process.exit(1);let z=await j.json();if(!z?.types?.length)return null;return z}catch(j){return console.error(j),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 v0 from"prettier";async function T$(y,$="typescript"){try{return await v0.format(y,{parser:$,printWidth:160,tabWidth:4})}catch(j){return console.error("Error formatting with Prettier:",j),y}}import zy from"chalk";import Vy from"fast-glob";import*as Qy from"fs";import*as Yy from"path";import{loadConfig as gy}from"tsconfig-paths";import v$ from"fs";import S0 from"path";function S$(y=""){let $=S0.join(y,"package.json");if(!v$.existsSync($))return null;else return JSON.parse(v$.readFileSync($,"utf-8"))}import ey from"fs";import F$ from"path";import{createMatchPath as R$}from"tsconfig-paths";function C$(y,$){let j=F$.posix.join(y,"index"),z=(W)=>{try{return ey.existsSync(W)}catch{return!0}},Y=R$($.absoluteBaseUrl,$.paths)(j,void 0,z,[".ts",".tsx",".jsx",".js",".css"]);if(!Y)Y=R$($.absoluteBaseUrl,$.paths)(j,void 0,()=>!0,[".ts",".tsx",".jsx",".js",".css"]);if(Y){let W=Y.split("/").slice(0,-1).join("/");try{if(ey.existsSync(W)&&ey.statSync(W).isFile())return F$.dirname(W)}catch{}return W}else return}var l=["**/node_modules/**",".next","public","dist","build"],Py=!1,u$={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function By(y){let $=Qy.existsSync(Yy.resolve(y,"src")),j=Qy.existsSync(Yy.resolve(y,`${$?"src/":""}app`)),[z,Y,W,Z,X]=await Promise.all([Vy.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:y,deep:2,ignore:l}),F0(y),C0(y),u0(y),S$(y)]),U=Qy.existsSync(Yy.resolve(y,"components.json")),V=null;if(U)V=JSON.parse(Qy.readFileSync(Yy.resolve(y,"components.json"),"utf-8"));let B=Vy.sync(["**/**/theme.css"],{cwd:y,absolute:!0,onlyFiles:!0,ignore:l}),b=B?.[0]&&Qy.readFileSync(B[0],"utf-8").match(/(--color-brand+-\d{1,3}):\s*(rgb\([^)]+\))/g)?.[1]||void 0,q={tailwind:{config:W||void 0,brandColor:b?.replace(/--color-([^-]+(?:-[^-]+)?)-\d+:.*/,"$1")||void 0},examples:V?.examples||void 0,aliases:V?.aliases||Z||{},paths:await R0(V?.aliases||{})||{},isTsx:Y,isSrcDir:$,isAppDir:j,isComponentsJson:!!U,framework:"other"};if(z.find((Q)=>Q.startsWith("next.config."))?.length)return q.framework=j?"next-app":"next-pages",q;else if(z.find((Q)=>Q.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(z?.length||Qy.existsSync(Yy.resolve(y,"package.json")))return q.framework="other",q;return null}async function F0(y){return(await Vy.glob("tsconfig.*",{cwd:y,deep:2,ignore:l})).length>0}async function R0(y){let $={},j=[],z=Object.entries(y).filter(([,U])=>U);if(z.length===0)return null;let Y=process.cwd(),Z=gy(Y).resultType==="success",X=await O$(Y);if(!X){if(!Py){if(Py=!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
|
`)),z.forEach(([U,V])=>{console.log(zy.dim(` ${U}: ${V}`))}),console.log(zy.dim(`
|
|
@@ -9,7 +9,7 @@ import{Command as r1}from"commander";import C from"chalk";import{Command as s0}f
|
|
|
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
10
|
`));return $}async function O$(y){let[$,j]=await Promise.all([Vy.glob("next.config.*",{cwd:y,deep:1,ignore:l}),Vy.glob("vite.config.*",{cwd:y,deep:1,ignore:l})]),z=$.length>0,Y=j.length>0,W=null;if(z)W=gy(y);else if(Y){if(W=gy(y),W?.resultType==="failed"||!Object.keys(W.paths||{}).length){let Z=await Vy.glob(["tsconfig.app.*","*/tsconfig.app.*"],{cwd:y,deep:1,onlyFiles:!0,absolute:!0,ignore:l}),[X]=Z;if(X)try{let V=function(q){return q.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1")},U=Qy.readFileSync(X,"utf-8"),B=V(U),b=JSON.parse(B);if(b.compilerOptions?.paths)W={resultType:"success",paths:b?.compilerOptions?.paths,baseUrl:b.compilerOptions.baseUrl||".",configFileAbsolutePath:X,absoluteBaseUrl:Yy.resolve(y,b.compilerOptions.baseUrl||".")}}catch{}}}else W=gy(y);if(!W||W?.resultType==="failed"||!Object.keys(W.paths).length)return null;return W}async function C0(y){let $=await Vy.glob("tailwind.config.*",{cwd:y,deep:2,ignore:l});if(!$.length)return null;return $[0]}async function u0(y){let $=await O$(y);if(!$)return null;let j={},z={app:/\/?app\/\*$/,components:/\/?components\/\*$/,utils:/\/?utils\/\*$/,styles:/\/?styles\/\*$/,hooks:/\/?hooks\/\*$/,src:/^(\.\/src\/\*|\.\/\*|\/src\/\*|src\/\*|\/\*|\*)$/};for(let[Y,W]of Object.entries($.paths)){let Z=Y.replace(/\/\*$/,"/");for(let[X,U]of Object.entries(z))if(W.some((V)=>U.test(V))){j[X]=Z;break}}return j||null}function wy(y,$){let j=k$(y),z=y$.sync(["tailwind.config.*","**/globals.css","package.json"],{cwd:y,deep:4,absolute:!0,onlyFiles:!0,ignore:l}),Y=y$.sync("**/{layout,_app,main}.tsx",{cwd:$?Wy.posix.join(y,$):y,deep:4,absolute:!0,onlyFiles:!0,ignore:l});return{tailwindFile:z.find((Z)=>Z.includes("tailwind.config.")),cssFile:z.find((Z)=>Z.includes("globals.css")),packageJson:z.find((Z)=>Z.includes("package.json")),tsConfig:j?.resultType==="success"?j?.configFileAbsolutePath:void 0,layoutFile:Y.find((Z)=>Z.includes("layout")),appFile:Y.find((Z)=>Z.includes("_app")),mainFile:Y.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 P$(y,$,j="@/*"){let z=await k$(y);if(z?.resultType==="failed")return null;let Y={};if(!Object.keys(z.paths).length){z.paths={[j]:[`./${$?"src/":""}*`]},Y.src=j.replace(/\/\*$/,"");let W=await dy.promises.readFile(z.configFileAbsolutePath,"utf-8"),Z,X=/(?:\/\/\s*)?"paths":\s*\{(?:[^{}]|\{[^}]*\})*\}/;if(!X.test(W))Z=W.replace(/"compilerOptions":\s*{/,`"compilerOptions": {
|
|
11
11
|
"paths": ${JSON.stringify(z.paths)},`);else Z=W.replace(X,`"paths": ${JSON.stringify(z.paths)}`);let V=new O0,B=await T$(Z,"json");return V.createSourceFile(z.configFileAbsolutePath,B,{overwrite:!0}),await V.save(),Y}return Y||null}function g$(y){let $=y$.sync(["vite.config.*"],{cwd:y,absolute:!0,onlyFiles:!0,ignore:l})?.[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((W)=>$.includes(W)))return!1;return["plugins:","postcss:","css:"].some((W)=>$.includes(W))}var P0=["npm","config","user","agent"].join("_");function qy(y){if(y===void 0)y=process.env[P0]||"";if(y.startsWith("yarn"))return"yarn";if(y.startsWith("pnpm"))return"pnpm";if(y.startsWith("bun"))return"bun";return"npm"}function Zy(){switch(qy()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bunx";default:return"npx"}}function d$(){switch(qy()){case"yarn":return"yarn dev";case"pnpm":return"pnpm dev";case"bun":return"bun dev";default:return"npm run dev"}}import g0 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:z,dev:Y=!1,spinner:W,label:Z=Y?"devDependencies":"dependencies"}=$,X=qy(),V=[X==="npm"?"install":"add",...Y?["-D"]:[],...j];W.start(`Installing ${Z}`),await g0(()=>f$(X,V,{cwd:z}).catch(async(B)=>{if(B.message.includes("peer"))W.warn(`${Z} conflict detected. Retrying with --legacy-peer-deps...`),W.start(`Installing ${Z} with --legacy-peer-deps flag`),await f$(X,[...V,"--legacy-peer-deps"],{cwd:z});else throw B}),{retries:1}),W.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 z=y.replace(/^(components|utils|hooks|styles)\//,"");if(y.includes("components")&&$?.components)return Xy.relative(process.cwd(),Xy.posix.join($.components,z));if(y.includes("utils")&&$?.utils)return Xy.relative(process.cwd(),Xy.posix.join($.utils,z));if(y.includes("hooks")&&$?.hooks)return Xy.relative(process.cwd(),Xy.posix.join($.hooks,z));if(y.includes("styles")&&$?.styles)return Xy.relative(process.cwd(),Xy.posix.join($.styles,z));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 $=`
|
|
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 z=y.replace(/^(components|utils|hooks|styles)\//,"");if(y.includes("components")&&$?.components)return Xy.relative(process.cwd(),Xy.posix.join($.components,z));if(y.includes("utils")&&$?.utils)return Xy.relative(process.cwd(),Xy.posix.join($.utils,z));if(y.includes("hooks")&&$?.hooks)return Xy.relative(process.cwd(),Xy.posix.join($.hooks,z));if(y.includes("styles")&&$?.styles)return Xy.relative(process.cwd(),Xy.posix.join($.styles,z));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 G={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).action(async(y,$)=>{if(y)G.components=y;if($){if(G.all=$.all,G.dir=$.dir,G.path=$.path,G.overwrite=$.overwrite,G.includeAllComponents=$.includeAllComponents,G.license=$.license||G.license,G.yes=$.yes,$.yes)G.includeAllComponents=!0,G.overwrite=!0}try{await $$(G)}catch(j){console.error(C.red(j))}});async function $$(y){if(y)G={...G,...y};let $=vy().start(),j=h.posix.join(process.cwd(),G.dir||"");if(!i.existsSync(h.resolve(j,"package.json")))$.warn("This command should be run in a project directory."),process.exit(1);let Y=await By(j);if(G.license)await hy(G.license,$);$.stop();let W=[];if(G.components.length){let Q=await ky(G.type,G.components,G.license);if(Q&&Q.pro&&Q.pro.length>0){if(console.log(),Q.pro.length===1){let L=Q.pro[0]?.split("/")[1]||Q.pro[0];console.log(C.yellow(`\uD83D\uDD12 The ${C.cyan(L)} component requires PRO access.`))}else console.log(C.yellow("\uD83D\uDD12 The following components require PRO access:")),Q.pro.forEach((L)=>{let D=L?.split("/")[1]||L;console.log(` • ${C.cyan(D)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${C.green("→")} If you've already purchased: ${C.cyan(`${Zy()} untitledui@latest login`)}`),console.log(` ${C.green("→")} To purchase PRO components: ${C.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(!Q?.components.length)console.log("No components found"),process.exit(1);W.push(...Q.components)}if(!G?.type&&!G?.components.length){if(G.yes)console.log(C.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let Q=await I$(G.license);if(!Q)console.log("No component types found"),process.exit(1);let L=await Jy({type:"select",name:"type",onState:f,message:`What type of ${C.cyan("component")} are you adding?`,choices:Q?.types.map((D)=>({title:D,value:D}))});G.type=L.type}if(!G?.path&&!Y?.paths?.components)if(G.yes)G.path="components";else{let Q=await Jy({type:"text",name:"path",onState:f,message:`Where would you like to add the ${C.cyan("components")}?`,initial:"components"});G.path=Q.path}if(G?.path&&Y&&Y.paths)Y.paths.components=h.posix.join(Y?.isSrcDir?"src":"",G.path);if(Y&&!Object.keys(Y?.aliases).length){let Q="@/*";if(!G.yes){let L=/^[^*"]+\/\*\s*$/;Q=(await Jy({type:"text",name:"aliasPrefix",onState:f,initial:"@/*",message:`What is the ${C.cyan("import alias")} for your project?`,validate:(_)=>L.test(_)?!0:"Import alias must follow the pattern <prefix>/*"}))?.aliasPrefix}Y.aliases=await P$(j,Y?.isSrcDir,Q)}if(!G?.components.length){if(G.yes)console.log(C.red("Error: In non-interactive mode (--yes), you must specify components as arguments.")),process.exit(1);let Q=await E$(G?.type,G.license);if(!Q)console.log("No components found"),process.exit(1);let L=await Jy({type:"multiselect",name:"components",onState:f,message:`Which ${C.cyan("components")} would you like to add?`,choices:Q?.components?.map((x)=>({title:x?.name+(x?.count?` (${x?.count} variants)`:"")||"example",value:x||"example",selected:G.components.includes(x.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!L.components||!L.components.length)console.log("No option selected. Exiting..."),process.exit(1);let D=L.components.filter((x)=>x?.type==="file").map((x)=>x.name),_=L.components.filter((x)=>x?.type==="dir").map((x)=>x.name),E=[];if(_.length){let x=await x$(G?.type,G.license,_);if(x&&x.components.length)for(let v of x.components){let[F,I]=Object.entries(v)[0]||[],T=await Jy({type:"select",name:"component",onState:f,message:`Which ${C.cyan("variant")} from ${C.cyan(F)} would you like to add?`,choices:I?.map((R)=>({title:R?.name.replace(/-modal/g,"")||"example",value:R?.name||"example",selected:G.components.includes(R.name)})),instructions:!1,hint:"- Space to select. Return to submit"});if(!T.component)console.log("No variant selected for "+C.cyan(F));E.push(F+"/"+T.component)}else console.log("No variants found")}G.components=[...E,...D]}if(!G.components?.length)$.warn("No components selected. Exiting."),process.exit(1);let Z=wy(j),X=new Set,U=new Set,V=new Set,B=new r0({tsConfigFilePath:Z?.tsConfig});if($.start(),G.type&&G.components.length){let Q=await ky(G.type,G.components,G.license);if(!Q?.components.length)console.log("No components found"),process.exit(1);W.push(...Q.components)}let b=new Set;if(W.forEach((Q)=>{Q?.components?.forEach((L)=>{b.add({name:L.name,path:L.path})})}),$.stop(),b.size){let Q=Array.from(b).filter((L)=>!i.existsSync(h.posix.join(j,`${Y?.isSrcDir?"src":""}`,L?.path?.replace(/components\//,G.path+"/"))));if(Q?.length)if(G.includeAllComponents)G.baseComponents=Q.map((L)=>L.name);else{let L=await Jy({type:"multiselect",name:"baseComponents",onState:f,message:"Select which base components you want to add",choices:Q.map((D)=>({title:D?.name,value:D?.name,selected:!0})),instructions:!1,hint:"- Space to select. Return to submit"});if(G.baseComponents=L.baseComponents,!Q.length&&!L.baseComponents?.length)$.warn("No components selected")}}if($.start(),G?.baseComponents?.length){let Q=await ky("",G.baseComponents,G.license);if(!Q||!Q?.components.length)console.log("No base components found");else W.push(...Q.components)}$.stop();let q=new Set;for(let Q of W){let L=vy(`Adding ${Q.name}...`).start(),D=Q.files;Q?.dependencies?.forEach((E)=>U.add(E)),Q?.devDependencies?.forEach((E)=>V.add(E));let _=!1;try{for(let{path:E,code:x}of D||[]){let v=h.posix.join(j,cy(E,Y?.paths,Y?.isSrcDir)),F=Y?.framework==="vite"?x.replace(`"use client";
|
|
13
13
|
|
|
14
14
|
`,""):x,I=fy(F),T=h.dirname(v);if(i.existsSync(v)&&!G.overwrite&&!q.has(v)){if(i.readFileSync(v,"utf-8")!==I)X.add({code:I,path:v}),_=!0}else if(!q.has(v)){let R=T.split(h.sep),M="";for(let J of R)if(M=M?h.join(M,J):J,M&&i.existsSync(M)&&i.statSync(M).isFile())throw Error(`Cannot create directory '${T}' because '${M}' is an existing file.
|
|
15
15
|
Please check your path aliases in components.json and tsconfig.json.`);i.mkdirSync(T,{recursive:!0}),i.writeFileSync(v,I),q.add(v);let H=B.getSourceFile(h.resolve(v));if(H)H.replaceWithText(I);else H=B.addSourceFileAtPath(h.resolve(v));H.getImportDeclarations().forEach((J)=>{let A=J.getModuleSpecifierValue();J.setModuleSpecifier(Ay(A,G.path,Y?.aliases))}),await H.save()}}if(_)L.warn(`Some files of ${C.yellow(Q.name)} already exist`);else L.succeed(`${C.green(Q.name)} is added successfully`)}catch(E){L.fail(`
|
|
@@ -62,9 +62,9 @@ Use ${C.cyan("--overwrite")} or ${C.cyan("-o")} flag to overwrite existing files
|
|
|
62
62
|
</div>
|
|
63
63
|
</body>
|
|
64
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(y1.homedir(),".untitledui"),z$=W$.join(Q$,"config.json"),i$=new p0().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let y=e0("Starting authentication...").start();try{await j1(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 j1(y){return new Promise(($,j)=>{let z=n0.createServer((Y,W)=>{let Z=new $1(Y.url,"http://localhost");if(Z.pathname==="/callback"){let X=Z.searchParams.get("apiKey"),U=Z.searchParams.get("error");if(U){W.writeHead(400,{"Content-Type":"text/html"}),W.end(ly(decodeURIComponent(U))),z.close(),j(Error(decodeURIComponent(U)));return}if(!X){W.writeHead(400,{"Content-Type":"text/html"}),W.end(ly("No Access Token received")),z.close(),j(Error("No Access Token received"));return}try{z1(X),W.writeHead(200,{"Content-Type":"text/html"}),W.end(r$()),z.close(),$()}catch(V){W.writeHead(500,{"Content-Type":"text/html"}),W.end(ly("Failed to save authentication data")),z.close(),j(V)}}else W.writeHead(404),W.end("Not found")});z.listen(0,"localhost",()=>{let Z=`
|
|
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 j1(y){return new Promise(($,j)=>{let z=n0.createServer((Y,W)=>{let Z=new $1(Y.url,"http://localhost");if(Z.pathname==="/callback"){let X=Z.searchParams.get("apiKey"),U=Z.searchParams.get("error");if(U){W.writeHead(400,{"Content-Type":"text/html"}),W.end(ly(decodeURIComponent(U))),z.close(),j(Error(decodeURIComponent(U)));return}if(!X){W.writeHead(400,{"Content-Type":"text/html"}),W.end(ly("No Access Token received")),z.close(),j(Error("No Access Token received"));return}try{z1(X),W.writeHead(200,{"Content-Type":"text/html"}),W.end(r$()),z.close(),$()}catch(V){W.writeHead(500,{"Content-Type":"text/html"}),W.end(ly("Failed to save authentication data")),z.close(),j(V)}}else W.writeHead(404),W.end("Not found")});z.listen(0,"localhost",()=>{let Z=`https://www.untitledui.com/react/api/cli-auth?port=${z.address().port}`;y.text="Opening browser for authentication...",t0(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(()=>{z.close(),j(Error("Authentication timeout. Please try again."))},300000)})}function z1(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 X1 from"async-retry";import w from"chalk";import{Command as L1}from"commander";import*as m from"fs";import Sy from"ora";import*as S from"path";import by from"prompts";import{Project as M1}from"ts-morph";import Y1 from"node-fetch";async function Ey(y,$){try{let z=await Y1("
|
|
67
|
+
`))}),y.text="Waiting for authentication in browser..."}),setTimeout(()=>{z.close(),j(Error("Authentication timeout. Please try again."))},300000)})}function z1(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 X1 from"async-retry";import w from"chalk";import{Command as L1}from"commander";import*as m from"fs";import Sy from"ora";import*as S from"path";import by from"prompts";import{Project as M1}from"ts-morph";import Y1 from"node-fetch";async function Ey(y,$){try{let z=await Y1("https://www.untitledui.com/react/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:y,key:$})});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 c from"chalk";import{Command as Q1}from"commander";import{execa as V$}from"execa";import H$ from"fast-glob";import o from"fs";import xy from"ora";import*as P from"path";import iy from"prompts";import{Project as W1}from"ts-morph";import{fileURLToPath as Z1}from"url";import*as sy from"fs";import*as o$ from"path";function Z$(y,$){let j=o$.join(y,"package.json");if(!sy.existsSync(j))return $;let z=JSON.parse(sy.readFileSync(j,"utf-8")),Y={...z.dependencies,...z.devDependencies},W=[];for(let Z of $){let X=Y[Z];if(!X){W.push(Z);continue}if(Z==="tailwindcss"){let U=X.match(/\d+/);if((U?parseInt(U[0],10):0)<4)W.push(Z)}}return W}import U$ from"chalk";import*as Hy from"fs";import*as ry from"path";function X$(y){if(!Hy.existsSync(ry.resolve(y)))console.log(U$.red(`Error: CSS file not found at ${y}`)),process.exit(1);let $=Hy.readFileSync(ry.resolve(y),"utf-8"),j=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,z={},Y;while((Y=j.exec($))!==null)if(Y[1]&&Y[2])z[Y[1]]=Y[2];return z}function L$(y,$,j){let z=ry.resolve(j);if(!Hy.existsSync(z)){console.log(U$.red(`Error: CSS file not found at ${z}`));return}let Y=Hy.readFileSync(z,"utf-8"),W=X$(j),Z={},X={};for(let[V,B]of Object.entries(W))if(V.startsWith(`--color-${y}-`)){let b=V.replace(`--color-${y}-`,"");Z[b]=V}else if(V.startsWith(`--color-${$}-`)){let b=V.replace(`--color-${$}-`,"");X[b]=B}let U=!1;for(let[V,B]of Object.entries(Z))if(X[V]){let b=X[V],q=new RegExp(`(${B}):\\s*rgb\\([^)]*\\);?`,"g");if(q.test(Y))Y=Y.replace(q,`$1: ${b};`),U=!0;else console.log(U$.yellow(`No match found for ${B}`))}if(U)Hy.writeFileSync(z,Y,"utf-8")}var U1=Z1(import.meta.url),a$=P.dirname(U1),n$="vite",t$="nextjs",p$={[t$]:"Next.js",[n$]:"Vite"},n="",O={color:"",template:"",framework:void 0,license:My()},e$=new Q1().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 K$($),process.exit(0)}catch(j){console.error(c.red(j)),process.exit(1)}});async function K$(y,$=null){let j=process.cwd(),z=o.existsSync(P.resolve(j,"package.json")),Y=P.resolve(P.join(a$,"../config/styles","theme.css")),W=X$(Y??""),Z=Array.from(new Set(Object.keys(W).map((B)=>B?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),X=xy().start(),U=await By(j);if(O.license)Oy(O.license);if(!z){if(X.stop(),!n){let b=await iy({onState:f,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof b.path==="string")n=b.path.trim()}if($)$.projectPath=n;let B=o.existsSync(P.resolve(P.posix.join(j,n,"package.json")));if(o.existsSync(P.resolve(P.posix.join(j,n)))&&B)X.fail(c.red("Directory already exists!")),process.exit(1);if(O.vite&&O.nextjs||!O.framework){let b=await iy({type:"select",name:"framework",onState:f,message:`Which ${c.cyan("framework")} would you like to use?`,choices:Object.entries(p$).map(([q,Q])=>({title:Q,value:q}))});O.framework=b.framework}X.succeed("Framework is selected: "+c.green(p$[O.framework]))}else if(U?.framework==="other")X.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${c.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(c.yellow(`Detected ${u$[U.framework]} project, proceeding with the setup...`));else X.stop();if(O.colorsList||!O.color&&!U?.tailwind.brandColor){let B=await iy({type:"select",name:"color",onState:f,initial:y.color??"",message:`Which ${c.cyan("color")} would you like to use as the ${c.cyanBright("brand")} color?`,choices:Z.map((b)=>({title:b,value:b}))});if(O.color=B.color,O.colorsList&&U)U.tailwind.brandColor=B.color}let V=P.posix.join(j,n||"");if(n&&!z){let B=P.resolve(n);console.log(`
|
|
68
68
|
Creating a new project in ${c.blue(n)}`);let b=xy("Downloading and extracting the repository...").start();try{o.mkdirSync(B,{recursive:!0}),await M$(()=>h$(B,{template:O.framework}),{retries:2}),b.succeed("Files are downloaded and extracted successfully!");let q=xy({text:"Installing dependencies..."}).start(),Q=H$.sync(["**/styles/theme.css"],{cwd:B,absolute:!0,onlyFiles:!0})[0];if(L$("brand",O.color||"",Q??""),await M$(()=>V$(qy(),["install"],{cwd:V}).catch(async(L)=>{if(L.message.includes("peer"))q.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing dependencies with --legacy-peer-deps flag"),await V$(qy(),["install","--legacy-peer-deps"],{cwd:V})}),{retries:1}),await M$(()=>V$("git",["init"],{cwd:V}),{retries:1}),q.succeed("Dependencies are installed"),!$)console.log(`
|
|
69
69
|
Your project is ready, to get started run the following commands:
|
|
70
70
|
|
|
@@ -110,7 +110,7 @@ Use ${w.cyan("--overwrite")} or ${w.cyan("-o")} flag to overwrite existing files
|
|
|
110
110
|
Changes preview:
|
|
111
111
|
`));for(let _ of q.slice(0,10)){console.log(g.dim(` ${_.file}`));for(let E of _.changes.slice(0,3))console.log(g.red(` - ${E.before.substring(0,100)}`)),console.log(g.green(` + ${E.after.substring(0,100)}`));if(_.changes.length>3)console.log(g.dim(` ... and ${_.changes.length-3} more`))}if(q.length>10)console.log(g.dim(`
|
|
112
112
|
... and ${q.length-10} more files`))}}else console.log(g.green(`
|
|
113
|
-
Done! ${b} files updated.`));console.log()});import d from"chalk";import{Command as w1}from"commander";import q$ from"node-fetch";import A1 from"ora";var J$="
|
|
113
|
+
Done! ${b} files updated.`));console.log()});import d from"chalk";import{Command as w1}from"commander";import q$ from"node-fetch";import A1 from"ora";var J$="https://www.untitledui.com/react/api/mcp/tools";async function E1(y,$,j=10){return(await(await q$(`${J$}/search-components`,{method:"POST",headers:{"Content-Type":"application/json",...$&&{Authorization:`Bearer ${$}`}},body:JSON.stringify({query:y,limit:j})})).json()).results||[]}async function x1(y,$,j=10){return(await(await q$(`${J$}/get-page-templates`,{method:"POST",headers:{"Content-Type":"application/json",...$&&{Authorization:`Bearer ${$}`}},body:JSON.stringify({query:y,limit:j})})).json()).templates||[]}async function I1(y,$=10){return(await(await q$(`${J$}/search-icons`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:y,limit:$})})).json()).results||[]}function T1(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((z)=>d.cyan(z)).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 S1(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 w1().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").action(async(y,$)=>{let j=y.join(" "),z=parseInt($.limit,10),Y=$.key||My()||void 0,W=$.type.toLowerCase(),Z=A1(`Searching for "${j}"...`).start();try{let X=W==="all"||W==="components",U=W==="all"||W==="templates",V=W==="all"||W==="icons",[B,b,q]=await Promise.all([X?E1(j,Y,z):Promise.resolve([]),U?x1(j,Y,z):Promise.resolve([]),V?I1(j,z):Promise.resolve([])]);if(Z.stop(),B.length+b.length+q.length===0){console.log(d.yellow(`
|
|
114
114
|
No results found for "${j}"
|
|
115
115
|
`));return}if(B.length>0){if(console.log(d.bold.underline(`
|
|
116
116
|
Components (${B.length})
|
|
@@ -135,9 +135,9 @@ Use ${w.cyan("--overwrite")} or ${w.cyan("-o")} flag to overwrite existing files
|
|
|
135
135
|
Cancelled.
|
|
136
136
|
`));return}}console.log()}}catch{}let j=d1($),z=j?.version??"7";if(console.log(` Detected version: ${N.cyan(z)}
|
|
137
137
|
`),z==="8"){console.log(N.green(` Already on version 8. Nothing to upgrade.
|
|
138
|
-
`));return}let Y,W,Z=a(" Fetching migration rules...").start();try{let M=await fetch("
|
|
138
|
+
`));return}let Y,W,Z=a(" Fetching migration rules...").start();try{let M=await fetch("https://www.untitledui.com/react/api/upgrade",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fromVersion:z,toVersion:"8"})});if(!M.ok)throw Error(`Server returned ${M.status}`);let H=await M.json();Y=g1(H),W="server",Z.succeed(" Migration rules fetched from server")}catch{Y=X0,W="built-in",Z.warn(" Could not reach server. Using built-in migration rules")}let X=a(" Scanning files...").start(),U=await _0($);X.succeed(` Found ${N.bold(U.length)} source files`);let V=0,B=0,b=0,q=0,Q=[],L=[],D=[],_=[];if(!y.skipTheme){let M=a(" Upgrading theme.css...").start(),H=await c1($);if(H)try{let J=r.resolve(import.meta.dirname,"../config/styles/theme.css"),A=s.readFileSync(J,"utf-8"),u=await H0({themePath:H,newThemeContent:A,dryRun:y.dryRun});if(u.success){let k=Object.keys(u.brandColors);if(k.length>0)M.succeed(` Theme upgraded. Brand colors preserved: ${N.cyan(k.join(", "))}`);else M.succeed(" Theme upgraded (no custom brand colors found)")}else M.warn(` Theme upgrade issue: ${u.message}`)}catch(J){let A=J instanceof Error?J.message:String(J);M.warn(` Theme upgrade skipped: ${A}`)}else M.warn(" No theme.css found — skipping theme upgrade")}if(!y.skipConfig){let M=a(" Updating config files...").start(),H=m1($);if(H&&Y.configChanges.tsconfig.length>0){let{applied:J,skipped:A}=L0({tsconfigPath:H,changes:Y.configChanges.tsconfig,dryRun:y.dryRun});if(J.length>0)M.succeed(` Config updated: ${J.map((u)=>N.cyan(u)).join(", ")}`);else M.info(" No config changes needed");if(A.length>0)for(let u of A)console.log(N.dim(` Skipped: ${u}`))}else M.info(" No config changes to apply")}if(!y.skipDeps){let M=a(" Updating dependencies...").start(),H=h1($);if(H){let J=M0({packageJsonPath:H,update:Y.dependencyChanges.update,add:Y.dependencyChanges.add,devUpdate:Y.dependencyChanges.devUpdate,devAdd:Y.dependencyChanges.devAdd,remove:Y.dependencyChanges.remove,dryRun:y.dryRun});if(J.updated.length+J.added.length+J.removed.length>0){if(M.succeed(" Dependencies updated in package.json"),J.updated.length>0)console.log(N.dim(` Updated: ${J.updated.join(", ")}`));if(J.added.length>0)console.log(N.dim(` Added: ${J.added.join(", ")}`));if(J.removed.length>0)console.log(N.dim(` Removed: ${J.removed.join(", ")}`));if(!y.dryRun){let u=a(" Installing dependencies...").start();try{let k=Zy();await b$(k==="bunx"?"bun":k==="pnpx"?"pnpm":k==="yarn"?"yarn":"npm",["install"],{cwd:$}),u.succeed(" Dependencies installed")}catch(k){let p=k instanceof Error?k.message:String(k);u.warn(` Could not auto-install dependencies: ${p.substring(0,100)}`),console.log(N.dim(" Run your package manager's install command manually."))}}}else M.info(" No dependency changes needed")}else M.warn(" No package.json found — skipping dependency updates")}let E=a(" Renaming files...").start(),x=new Set;for(let M of Y.importTransforms){let H=M.from.split("/").pop(),J=M.to.split("/").pop();if(H===J)continue;let A=_$.sync([`**/${H}.tsx`,`**/${H}.ts`],{cwd:$,absolute:!0,ignore:["**/node_modules/**"]});for(let u of A){let k=u.replace(new RegExp(`${D0(H)}(\\.tsx?)$`),`${J}$1`);if(!y.dryRun)try{s.renameSync(u,k),x.add(M.from)}catch{}else x.add(M.from)}}let v=Y.importTransforms.filter((M)=>{let H=M.from.split("/").pop(),J=M.to.split("/").pop();if(H===J)return!0;return x.has(M.from)});if(x.size>0)E.succeed(` Renamed ${N.bold(x.size)} files`),U.length=0,U.push(...await _0($));else E.info(" No file renames needed");let F=a(" Applying source transforms...").start();for(let M of U){let H;try{H=s.readFileSync(M,"utf-8")}catch{continue}let J=r.relative($,M),A=H,u=!1,k=K0(J,A,Y.classTransforms);if(k.changes.length>0){let yy=A.split(`
|
|
139
139
|
`);for(let t of k.changes){let Ry=t.line-1,$y=yy[Ry];$y=$y.replace(/"([^"]*)"|'([^']*)'|`([^`$]*)`|`([^`$]*)\$\{/g,(oy,w0,A0,E0,x0)=>{let Cy=w0??A0??E0??x0;if(Cy==null)return oy;let uy=Cy;for(let ay of Y.classTransforms)ay.pattern.lastIndex=0,uy=uy.replace(ay.pattern,ay.replace);return uy!==Cy?oy.replace(Cy,uy):oy}),yy[Ry]=$y}A=yy.join(`
|
|
140
|
-
`),V+=k.changes.length,u=!0,Q.push(k);for(let t of k.changes){let Ry=Y.classTransforms.find(($y)=>{return $y.pattern.lastIndex=0,$y.needsReview&&$y.pattern.test(t.before)});for(let $y of Y.classTransforms)$y.pattern.lastIndex=0;if(Ry)L.push({file:J,line:t.line,description:t.description,before:t.before,after:t.after})}}let p=q0(A,Y.propTransforms);if(p.changes.length>0)A=p.content,B+=p.changes.length,u=!0;let e=B0(A,v);if(e.changes.length>0)A=e.content,b+=e.changes.length,u=!0;if(u){if(q++,!y.dryRun)s.writeFileSync(M,A)}}F.succeed(` Processed ${N.bold(U.length)} files`);let I=a(" Detecting structural patterns...").start();for(let M of U){let H;try{H=s.readFileSync(M,"utf-8")}catch{continue}let J=r.relative($,M),A=J0(J,H,Y.structuralPatterns);_.push(...A)}if(_.length>0)I.warn(` Found ${N.bold(_.length)} structural patterns requiring manual review`);else I.succeed(" No structural patterns found");if(j?.components&&Array.isArray(j.components)&&j.components.some((M)=>M.contentHash)){let M=a(" Checking stock components...").start(),H=[];for(let J of j.components){if(!J.contentHash||!J.filePath)continue;let A=r.resolve($,J.filePath);try{let u=s.readFileSync(A,"utf-8");if(l1(u)===J.contentHash)H.push({name:J.name,path:J.filePath})}catch{}}if(H.length>0){M.info(` ${N.bold(H.length)} stock components can be auto-refreshed`);let J=y.yes;if(!J){let{confirm:A}=await b0({type:"confirm",name:"confirm",message:`Refresh ${H.length} unmodified stock components to v8.0?`,initial:!0});J=A}if(J&&!y.dryRun){let A=a(" Fetching v8.0 components...").start();try{let u=await fetch("
|
|
140
|
+
`),V+=k.changes.length,u=!0,Q.push(k);for(let t of k.changes){let Ry=Y.classTransforms.find(($y)=>{return $y.pattern.lastIndex=0,$y.needsReview&&$y.pattern.test(t.before)});for(let $y of Y.classTransforms)$y.pattern.lastIndex=0;if(Ry)L.push({file:J,line:t.line,description:t.description,before:t.before,after:t.after})}}let p=q0(A,Y.propTransforms);if(p.changes.length>0)A=p.content,B+=p.changes.length,u=!0;let e=B0(A,v);if(e.changes.length>0)A=e.content,b+=e.changes.length,u=!0;if(u){if(q++,!y.dryRun)s.writeFileSync(M,A)}}F.succeed(` Processed ${N.bold(U.length)} files`);let I=a(" Detecting structural patterns...").start();for(let M of U){let H;try{H=s.readFileSync(M,"utf-8")}catch{continue}let J=r.relative($,M),A=J0(J,H,Y.structuralPatterns);_.push(...A)}if(_.length>0)I.warn(` Found ${N.bold(_.length)} structural patterns requiring manual review`);else I.succeed(" No structural patterns found");if(j?.components&&Array.isArray(j.components)&&j.components.some((M)=>M.contentHash)){let M=a(" Checking stock components...").start(),H=[];for(let J of j.components){if(!J.contentHash||!J.filePath)continue;let A=r.resolve($,J.filePath);try{let u=s.readFileSync(A,"utf-8");if(l1(u)===J.contentHash)H.push({name:J.name,path:J.filePath})}catch{}}if(H.length>0){M.info(` ${N.bold(H.length)} stock components can be auto-refreshed`);let J=y.yes;if(!J){let{confirm:A}=await b0({type:"confirm",name:"confirm",message:`Refresh ${H.length} unmodified stock components to v8.0?`,initial:!0});J=A}if(J&&!y.dryRun){let A=a(" Fetching v8.0 components...").start();try{let u=await fetch("https://www.untitledui.com/react/api/components",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({components:H.map((k)=>k.name),version:"8"})});if(u.ok){let k=await u.json(),p=0;for(let e of H)if(k[e.name])s.writeFileSync(r.resolve($,e.path),k[e.name]),p++;A.succeed(` Refreshed ${N.bold(p)} stock components`)}else A.warn(" Could not fetch v8.0 components from server")}catch{A.warn(" Could not reach server for component refresh")}}}else M.info(" No unmodified stock components to refresh")}let T=a(" Scanning for orphaned tokens...").start();for(let M of U){let H;try{H=s.readFileSync(M,"utf-8")}catch{continue}let J=r.relative($,M),A=G0(J,H,Y.orphanedTokens);D.push(...A)}if(D.length>0)T.warn(` Found ${N.bold(D.length)} orphaned v7.0 tokens remaining`);else T.succeed(" No orphaned tokens found");let R=[];if(!y.dryRun){let M=a(" Running type check...").start();try{let H=Zy();await b$(H,["tsc","--noEmit"],{cwd:$}),M.succeed(" Type check passed")}catch(H){let A=(H?.stderr||H?.stdout||"").split(`
|
|
141
141
|
`).filter((u)=>u.includes("error TS")).slice(0,20);R.push(...A),M.warn(` Type check found ${N.bold(A.length)} error(s)`)}}if(!y.dryRun){let M={version:"8",status:L.length>0||D.length>0?"partial":"success",filesScanned:U.length,filesModified:q,classChanges:V,propChanges:B,importChanges:b,manualReview:L,orphanedTokens:D,typeErrors:R,structuralPatterns:_,notes:Y.notes};try{s.writeFileSync(r.join($,"upgrade-report.json"),JSON.stringify(M,null,2)+`
|
|
142
142
|
`,"utf-8")}catch{}if(L.length>0||_.length>0)try{let H=`# Untitled UI v7.0 to v8.0 Upgrade Instructions
|
|
143
143
|
|
|
@@ -177,4 +177,4 @@ Use ${w.cyan("--overwrite")} or ${w.cyan("-o")} flag to overwrite existing files
|
|
|
177
177
|
`));for(let M of Q.slice(0,10)){console.log(N.dim(` ${M.file}`));for(let H of M.changes.slice(0,3))console.log(N.red(` - ${H.before.substring(0,100)}`)),console.log(N.green(` + ${H.after.substring(0,100)}`));if(M.changes.length>3)console.log(N.dim(` ... and ${M.changes.length-3} more`))}if(Q.length>10)console.log(N.dim(`
|
|
178
178
|
... and ${Q.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.57",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 i1(){let y=new r1().name(D$.name).version(D$.version);y.addCommand(e$).addCommand(l$).addCommand(y0).addCommand(U0).addCommand(i$).addCommand(Z0).addCommand(N0),y.parse()}i1();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "untitledui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.57",
|
|
4
4
|
"main": "dist/index.mjs",
|
|
5
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",
|