cus-base-ui 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/README.md +55 -0
  2. package/README_CLI.md +51 -0
  3. package/dist/assets/abap-BZhW0Cx0.js +1 -0
  4. package/dist/assets/actionscript-3-LeBFK6Bh.js +1 -0
  5. package/dist/assets/ada-NqWpZflS.js +1 -0
  6. package/dist/assets/andromeeda-Bz6Fhh1J.js +1 -0
  7. package/dist/assets/angular-html-BTaiG3kK.js +1 -0
  8. package/dist/assets/angular-ts-BTxRTU6v.js +1 -0
  9. package/dist/assets/apache-CUjmQNca.js +1 -0
  10. package/dist/assets/apex-Lnt0wCMk.js +1 -0
  11. package/dist/assets/apl-BMP17s5Y.js +1 -0
  12. package/dist/assets/applescript-DqDANhM3.js +1 -0
  13. package/dist/assets/ara-B57Nv7hO.js +1 -0
  14. package/dist/assets/asciidoc-BJu0_1of.js +1 -0
  15. package/dist/assets/asm-CuWCE7za.js +1 -0
  16. package/dist/assets/astro-BFlLe0Jt.js +1 -0
  17. package/dist/assets/aurora-x-C-FyNReN.js +1 -0
  18. package/dist/assets/awk-CcQf-hTf.js +1 -0
  19. package/dist/assets/ayu-dark-DTz3rt1D.js +1 -0
  20. package/dist/assets/ayu-light-4_lDvMFX.js +1 -0
  21. package/dist/assets/ayu-mirage-DEK31dHd.js +1 -0
  22. package/dist/assets/ballerina-CMoGdttB.js +1 -0
  23. package/dist/assets/base-80a1f760-CWBUL8Qn.js +1 -0
  24. package/dist/assets/bat-Du2vR4-z.js +1 -0
  25. package/dist/assets/beancount-Bi9B10Ux.js +1 -0
  26. package/dist/assets/berry-DGTfJRqr.js +1 -0
  27. package/dist/assets/bibtex-DcCCuWNc.js +1 -0
  28. package/dist/assets/bicep-DLKVW3S6.js +1 -0
  29. package/dist/assets/bird2-F7TUYfu4.js +1 -0
  30. package/dist/assets/blade-kxW2wQoS.js +1 -0
  31. package/dist/assets/bsl-DoLiY7vL.js +1 -0
  32. package/dist/assets/c-CjOo_kFY.js +1 -0
  33. package/dist/assets/c3-Sv48Lcih.js +1 -0
  34. package/dist/assets/cadence-DISWvDw3.js +1 -0
  35. package/dist/assets/cairo-D_2aS-5Z.js +1 -0
  36. package/dist/assets/catppuccin-frappe-B21liG2_.js +1 -0
  37. package/dist/assets/catppuccin-latte-CNvibSqZ.js +1 -0
  38. package/dist/assets/catppuccin-macchiato-Cx6PrsL1.js +1 -0
  39. package/dist/assets/catppuccin-mocha-BIm4AS9Y.js +1 -0
  40. package/dist/assets/clarity-BV8oI-Co.js +1 -0
  41. package/dist/assets/clojure-DImyyA30.js +1 -0
  42. package/dist/assets/cmake-COi4JEwX.js +1 -0
  43. package/dist/assets/cobol-DPcHQ5ld.js +1 -0
  44. package/dist/assets/codeowners-CIUzB3xZ.js +1 -0
  45. package/dist/assets/codeql-DpjoiHFk.js +1 -0
  46. package/dist/assets/coffee-B6eTlRtE.js +1 -0
  47. package/dist/assets/common-lisp-D9vmlDeK.js +1 -0
  48. package/dist/assets/consoleHook-59e792cb-CZnef-bR.js +2 -0
  49. package/dist/assets/coq-DZ8BF_1-.js +1 -0
  50. package/dist/assets/cpp-KQ_I6Shn.js +1 -0
  51. package/dist/assets/crystal-BZeo3Lqr.js +1 -0
  52. package/dist/assets/csharp-dHPIw-bc.js +1 -0
  53. package/dist/assets/css-CZs88HIP.js +1 -0
  54. package/dist/assets/csv-BGa2_mHk.js +1 -0
  55. package/dist/assets/cue-DR2zNE_H.js +1 -0
  56. package/dist/assets/cypher-Dg5YFlvT.js +1 -0
  57. package/dist/assets/d-DrZsIShC.js +1 -0
  58. package/dist/assets/dark-plus-B-5tgoOG.js +1 -0
  59. package/dist/assets/dart-DsQLQS9X.js +1 -0
  60. package/dist/assets/dax-CXg_sVxN.js +1 -0
  61. package/dist/assets/desktop-N0lvQBra.js +1 -0
  62. package/dist/assets/diff-D7s5hVgG.js +1 -0
  63. package/dist/assets/docker-BA8qRwzp.js +1 -0
  64. package/dist/assets/dotenv-BFGjaxJy.js +1 -0
  65. package/dist/assets/dracula-DRURUhCs.js +1 -0
  66. package/dist/assets/dracula-soft-Dp6xOjRx.js +1 -0
  67. package/dist/assets/dream-maker-2XBfktlT.js +1 -0
  68. package/dist/assets/edge-BGjX0NsG.js +1 -0
  69. package/dist/assets/elixir-ZT3zz1k7.js +1 -0
  70. package/dist/assets/elm-BcCDQdX7.js +1 -0
  71. package/dist/assets/emacs-lisp-D5CEN_ek.js +1 -0
  72. package/dist/assets/erb-B0Ylddxe.js +1 -0
  73. package/dist/assets/erlang-CQ_9b5Q0.js +1 -0
  74. package/dist/assets/everforest-dark-D0e45-qh.js +1 -0
  75. package/dist/assets/everforest-light-CV-9cMo-.js +1 -0
  76. package/dist/assets/fennel-CCh9rfhR.js +1 -0
  77. package/dist/assets/fish-juOF7Euk.js +1 -0
  78. package/dist/assets/fluent-DDP2E4tD.js +1 -0
  79. package/dist/assets/fortran-fixed-form-DNAmXaue.js +1 -0
  80. package/dist/assets/fortran-free-form-hUjoeXWd.js +1 -0
  81. package/dist/assets/fsharp-BQjqeKnO.js +1 -0
  82. package/dist/assets/gdresource-DVnnD8v8.js +1 -0
  83. package/dist/assets/gdscript-BzPcVPC8.js +1 -0
  84. package/dist/assets/gdshader-BdDwKR67.js +1 -0
  85. package/dist/assets/genie-qbJIkXcC.js +1 -0
  86. package/dist/assets/gherkin-Ch-BbHus.js +1 -0
  87. package/dist/assets/git-commit-BnOb2edR.js +1 -0
  88. package/dist/assets/git-rebase-CvpwEJrg.js +1 -0
  89. package/dist/assets/github-dark-B230dITH.js +1 -0
  90. package/dist/assets/github-dark-default-2TLSR-Px.js +1 -0
  91. package/dist/assets/github-dark-dimmed-DCC8Z3wE.js +1 -0
  92. package/dist/assets/github-dark-high-contrast-4CxjYhxn.js +1 -0
  93. package/dist/assets/github-light-ChJgJtUx.js +1 -0
  94. package/dist/assets/github-light-default-BebDo5t1.js +1 -0
  95. package/dist/assets/github-light-high-contrast-DufJ-VDq.js +1 -0
  96. package/dist/assets/gleam-Cyq4dQUt.js +1 -0
  97. package/dist/assets/glimmer-js-DH-fBOCR.js +1 -0
  98. package/dist/assets/glimmer-ts-kW54HLwU.js +1 -0
  99. package/dist/assets/glsl-Bmytusq6.js +1 -0
  100. package/dist/assets/gn-DgWw1A6X.js +1 -0
  101. package/dist/assets/gnuplot-BLSnNDQw.js +1 -0
  102. package/dist/assets/go-D753U82n.js +1 -0
  103. package/dist/assets/graphql-DeBU-cLI.js +1 -0
  104. package/dist/assets/groovy-C-Ecqvz2.js +1 -0
  105. package/dist/assets/gruvbox-dark-hard-Dx2sCn0Q.js +1 -0
  106. package/dist/assets/gruvbox-dark-medium-CXgyPHB1.js +1 -0
  107. package/dist/assets/gruvbox-dark-soft-DLfc9u0w.js +1 -0
  108. package/dist/assets/gruvbox-light-hard-D631YK5U.js +1 -0
  109. package/dist/assets/gruvbox-light-medium-CotNhrrp.js +1 -0
  110. package/dist/assets/gruvbox-light-soft-jFOOHYkF.js +1 -0
  111. package/dist/assets/hack-Dp6PdyaY.js +1 -0
  112. package/dist/assets/haml-Bb83gMJl.js +1 -0
  113. package/dist/assets/handlebars-4R2ucKwU.js +1 -0
  114. package/dist/assets/haskell-rmPPOegz.js +1 -0
  115. package/dist/assets/haxe-CKu_saXU.js +1 -0
  116. package/dist/assets/hcl-faVI7vm2.js +1 -0
  117. package/dist/assets/hjson-CO1T3zWN.js +1 -0
  118. package/dist/assets/hlsl-BhAWAfzJ.js +1 -0
  119. package/dist/assets/horizon-53_LdpdV.js +1 -0
  120. package/dist/assets/horizon-bright-CSJE0fg2.js +1 -0
  121. package/dist/assets/houston-BpRFjtYR.js +1 -0
  122. package/dist/assets/html-Ci7bSu-j.js +1 -0
  123. package/dist/assets/html-derivative-Bgjrt2Le.js +1 -0
  124. package/dist/assets/http-CzcxElj_.js +1 -0
  125. package/dist/assets/hurl-DU4lsuIz.js +1 -0
  126. package/dist/assets/hxml-BBMS41CJ.js +1 -0
  127. package/dist/assets/hy-BmdhWrf-.js +1 -0
  128. package/dist/assets/imba-CtNjQhN8.js +1 -0
  129. package/dist/assets/index-2HLs_nFj.css +1 -0
  130. package/dist/assets/index-599aeaf7-C4r7tddb.js +16 -0
  131. package/dist/assets/index-BOcAhqxV.js +1128 -0
  132. package/dist/assets/ini-v8Z5jhL_.js +1 -0
  133. package/dist/assets/java-CRTRlqfh.js +1 -0
  134. package/dist/assets/javascript-CNlkeRu4.js +1 -0
  135. package/dist/assets/jinja-Cmw44Rm8.js +1 -0
  136. package/dist/assets/jison-y7C7OqGi.js +1 -0
  137. package/dist/assets/json-TEdWkzyG.js +1 -0
  138. package/dist/assets/json5-Ay2rxHe-.js +1 -0
  139. package/dist/assets/jsonc-B5g7Bvk3.js +1 -0
  140. package/dist/assets/jsonl-D29jLPlx.js +1 -0
  141. package/dist/assets/jsonnet-et6t4-No.js +1 -0
  142. package/dist/assets/jssm-CfWVn5PB.js +1 -0
  143. package/dist/assets/jsx-CvVKWB9w.js +1 -0
  144. package/dist/assets/julia-CwCdIlc9.js +1 -0
  145. package/dist/assets/just-DsYr7DtD.js +1 -0
  146. package/dist/assets/kanagawa-dragon-BUEG3Nzw.js +1 -0
  147. package/dist/assets/kanagawa-lotus-BxmByTxd.js +1 -0
  148. package/dist/assets/kanagawa-wave-DiV3svz9.js +1 -0
  149. package/dist/assets/kdl-J3ti3M73.js +1 -0
  150. package/dist/assets/kotlin-DL7L1F2M.js +1 -0
  151. package/dist/assets/kusto-qibBLLok.js +1 -0
  152. package/dist/assets/laserwave-twIHjrzg.js +1 -0
  153. package/dist/assets/latex-BpmOboQG.js +1 -0
  154. package/dist/assets/lean-nIys3EXb.js +1 -0
  155. package/dist/assets/less-D3-GPjgt.js +1 -0
  156. package/dist/assets/light-plus-BLaDUeKu.js +1 -0
  157. package/dist/assets/liquid-De7rf4NV.js +1 -0
  158. package/dist/assets/llvm-DLvitYDc.js +1 -0
  159. package/dist/assets/log-CpfCrxX8.js +1 -0
  160. package/dist/assets/logo-BtGdk1-r.js +1 -0
  161. package/dist/assets/lua-BLofQ8Om.js +1 -0
  162. package/dist/assets/luau-BtzxLu36.js +1 -0
  163. package/dist/assets/make-7ApKNKSo.js +1 -0
  164. package/dist/assets/markdown-593J-HHD.js +1 -0
  165. package/dist/assets/marko-_ASnk5VL.js +1 -0
  166. package/dist/assets/material-theme-CfBPWgR2.js +1 -0
  167. package/dist/assets/material-theme-darker-CA8_s_rR.js +1 -0
  168. package/dist/assets/material-theme-lighter-CYlfxoXo.js +1 -0
  169. package/dist/assets/material-theme-ocean-BUi3vxXM.js +1 -0
  170. package/dist/assets/material-theme-palenight-DBwe4FQz.js +1 -0
  171. package/dist/assets/matlab-BW8IAV77.js +1 -0
  172. package/dist/assets/mdc-DvEA27F9.js +1 -0
  173. package/dist/assets/mdx-CThNn1AJ.js +1 -0
  174. package/dist/assets/mermaid-B1orlPdl.js +1 -0
  175. package/dist/assets/min-dark-CM4QSiY-.js +1 -0
  176. package/dist/assets/min-light-lnYMk6TN.js +1 -0
  177. package/dist/assets/mipsasm-BoF7lD-G.js +1 -0
  178. package/dist/assets/mojo-I8mrPp2q.js +1 -0
  179. package/dist/assets/monokai-CkHtS8AE.js +1 -0
  180. package/dist/assets/moonbit-7gV_EAWj.js +1 -0
  181. package/dist/assets/move-BC3qjKgo.js +1 -0
  182. package/dist/assets/narrat-CreRK8Of.js +1 -0
  183. package/dist/assets/nextflow-groovy-COkUU9Xo.js +1 -0
  184. package/dist/assets/nextflow-zEreFSl1.js +1 -0
  185. package/dist/assets/nginx-CV7Ml0NF.js +1 -0
  186. package/dist/assets/night-owl-DWPUUao2.js +1 -0
  187. package/dist/assets/night-owl-light-UWsCFnvo.js +1 -0
  188. package/dist/assets/nim-Bw6JkhsE.js +1 -0
  189. package/dist/assets/nix-vTa-TrnA.js +1 -0
  190. package/dist/assets/node-BaZpsMhE.js +4 -0
  191. package/dist/assets/nord-aoF20Emb.js +1 -0
  192. package/dist/assets/nushell-CBKIN0Df.js +1 -0
  193. package/dist/assets/objective-c-3fxkmuDp.js +1 -0
  194. package/dist/assets/objective-cpp-CEA4HtQL.js +1 -0
  195. package/dist/assets/ocaml-CQvEBP80.js +1 -0
  196. package/dist/assets/odin-CNF3G1pa.js +1 -0
  197. package/dist/assets/one-dark-pro-hYb6hiJM.js +1 -0
  198. package/dist/assets/one-light-CykW5KzK.js +1 -0
  199. package/dist/assets/openscad-CnqDNPox.js +1 -0
  200. package/dist/assets/pascal-Ds_J5C10.js +1 -0
  201. package/dist/assets/perl-Cghem8JI.js +1 -0
  202. package/dist/assets/php-Bv_uiLgZ.js +1 -0
  203. package/dist/assets/pkl-BHfXVEv0.js +1 -0
  204. package/dist/assets/plastic-gYsT69zC.js +1 -0
  205. package/dist/assets/plsql-BVshfseW.js +1 -0
  206. package/dist/assets/po-DGQTg6O8.js +1 -0
  207. package/dist/assets/poimandres-TB_8oCZj.js +1 -0
  208. package/dist/assets/polar-BDONHBaM.js +1 -0
  209. package/dist/assets/postcss-DTdSrw8q.js +1 -0
  210. package/dist/assets/powerquery-Bj3teieW.js +1 -0
  211. package/dist/assets/powershell-DzQXIeRD.js +1 -0
  212. package/dist/assets/prisma-e-tuwUHK.js +1 -0
  213. package/dist/assets/prolog-szw3pCXI.js +1 -0
  214. package/dist/assets/proto-BDxsyPZj.js +1 -0
  215. package/dist/assets/pug-Ctl01sr_.js +1 -0
  216. package/dist/assets/puppet-DIkUL05Q.js +1 -0
  217. package/dist/assets/purescript-6mbXpT_X.js +1 -0
  218. package/dist/assets/python-C72FlIEV.js +1 -0
  219. package/dist/assets/qml-DVeXuuO9.js +1 -0
  220. package/dist/assets/qmldir-jT2JFKaC.js +1 -0
  221. package/dist/assets/qss-CaOY579a.js +1 -0
  222. package/dist/assets/r-Hn-yDixW.js +1 -0
  223. package/dist/assets/racket-CL23vpaj.js +1 -0
  224. package/dist/assets/raku-D--0OsK6.js +1 -0
  225. package/dist/assets/razor-J_vDYOlw.js +1 -0
  226. package/dist/assets/red-DZRYD6K0.js +1 -0
  227. package/dist/assets/reg-CMx5SBwW.js +1 -0
  228. package/dist/assets/regexp-ClVttry8.js +1 -0
  229. package/dist/assets/rel-DYeuMJNs.js +1 -0
  230. package/dist/assets/riscv-DPgt2IM1.js +1 -0
  231. package/dist/assets/ron-CNUpRTUS.js +1 -0
  232. package/dist/assets/rose-pine-_Vxn4ntM.js +1 -0
  233. package/dist/assets/rose-pine-dawn-sY7FPYh0.js +1 -0
  234. package/dist/assets/rose-pine-moon-BIHtMi2S.js +1 -0
  235. package/dist/assets/rosmsg-efi2xErU.js +1 -0
  236. package/dist/assets/rst-nlfGseIM.js +1 -0
  237. package/dist/assets/ruby-DoVDlCwl.js +1 -0
  238. package/dist/assets/runtime-CQA7fIpc.js +1 -0
  239. package/dist/assets/rust-DnEBzrVL.js +1 -0
  240. package/dist/assets/sas-BcDSpQtn.js +1 -0
  241. package/dist/assets/sass-DP1OjaPs.js +1 -0
  242. package/dist/assets/scala-Bhuo3V1q.js +1 -0
  243. package/dist/assets/scheme-T2JZTR-5.js +1 -0
  244. package/dist/assets/scss-T4kOXV2Q.js +1 -0
  245. package/dist/assets/sdbl-DCrj75ur.js +1 -0
  246. package/dist/assets/shaderlab-C3scLHTE.js +1 -0
  247. package/dist/assets/shellscript-BunGOPZl.js +1 -0
  248. package/dist/assets/shellsession-C0IDaiU6.js +1 -0
  249. package/dist/assets/slack-dark-CVSkF4Cu.js +1 -0
  250. package/dist/assets/slack-ochin-CSE3d4AO.js +1 -0
  251. package/dist/assets/smalltalk-BAm-PEke.js +1 -0
  252. package/dist/assets/snazzy-light-lluQUjam.js +1 -0
  253. package/dist/assets/solarized-dark-ftCwpP34.js +1 -0
  254. package/dist/assets/solarized-light-44akI74N.js +1 -0
  255. package/dist/assets/solidity-CHjqn_02.js +1 -0
  256. package/dist/assets/soy-DroYVJzh.js +1 -0
  257. package/dist/assets/sparql-Ce4K2mvS.js +1 -0
  258. package/dist/assets/splunk-MwRh86cy.js +1 -0
  259. package/dist/assets/sql-glVt9tXx.js +1 -0
  260. package/dist/assets/ssh-config-d1rEeQrl.js +1 -0
  261. package/dist/assets/stata-C450JpKP.js +1 -0
  262. package/dist/assets/stylus-rQkaPWdf.js +1 -0
  263. package/dist/assets/surrealql-DadcZCP3.js +1 -0
  264. package/dist/assets/svelte-BT5ewu7M.js +1 -0
  265. package/dist/assets/swift-tyNOsy40.js +1 -0
  266. package/dist/assets/synthwave-84-BNJQQOX0.js +1 -0
  267. package/dist/assets/system-verilog-Bi8d1SdY.js +1 -0
  268. package/dist/assets/systemd-Cbw3HuPR.js +1 -0
  269. package/dist/assets/talonscript-RJjG5DH-.js +1 -0
  270. package/dist/assets/tasl-XZffQMVP.js +1 -0
  271. package/dist/assets/tcl-DDxomfuG.js +1 -0
  272. package/dist/assets/templ-Bs-UR7bT.js +1 -0
  273. package/dist/assets/terraform-C-a_z6EL.js +1 -0
  274. package/dist/assets/tex-0SQU_25t.js +1 -0
  275. package/dist/assets/tokyo-night-C5m3Iu1u.js +1 -0
  276. package/dist/assets/toml-Cpr_hoc4.js +1 -0
  277. package/dist/assets/ts-tags-DrI5ZCYg.js +1 -0
  278. package/dist/assets/tsv-0Nk6Vx0M.js +1 -0
  279. package/dist/assets/tsx-Cb1mPjps.js +1 -0
  280. package/dist/assets/turtle-Dm1TESdq.js +1 -0
  281. package/dist/assets/twig-DGOb00Fn.js +1 -0
  282. package/dist/assets/typescript-DfGIBSes.js +1 -0
  283. package/dist/assets/typespec-LRbCWivn.js +1 -0
  284. package/dist/assets/typst-C1_ki4iq.js +1 -0
  285. package/dist/assets/v-BxICDpo_.js +1 -0
  286. package/dist/assets/vala-BCAVMbt1.js +1 -0
  287. package/dist/assets/vb-C74Oc43Q.js +1 -0
  288. package/dist/assets/verilog-c8krZF_X.js +1 -0
  289. package/dist/assets/vesper-DVU53IPV.js +1 -0
  290. package/dist/assets/vhdl-C7FYgf5r.js +1 -0
  291. package/dist/assets/viml-1MXIIzly.js +1 -0
  292. package/dist/assets/vitesse-black-Ca3I6Jeb.js +1 -0
  293. package/dist/assets/vitesse-dark-CGGsP_ry.js +1 -0
  294. package/dist/assets/vitesse-light-BzG99g10.js +1 -0
  295. package/dist/assets/vue-DqFNHlvr.js +1 -0
  296. package/dist/assets/vue-html-CkrO3fEY.js +1 -0
  297. package/dist/assets/vue-vine-BYYhuvKb.js +1 -0
  298. package/dist/assets/vyper-Dkgft_3R.js +1 -0
  299. package/dist/assets/wasm-CE7OjoBR.js +1 -0
  300. package/dist/assets/wasm-D_MQmneJ.js +1 -0
  301. package/dist/assets/wenyan-CxlvaCGE.js +1 -0
  302. package/dist/assets/wgsl-BAe_9Dgb.js +1 -0
  303. package/dist/assets/wikitext-DxZ8uM9m.js +1 -0
  304. package/dist/assets/wit-BKLwvvdc.js +1 -0
  305. package/dist/assets/wolfram-DnaeypqR.js +1 -0
  306. package/dist/assets/xml-DdarD9Fy.js +1 -0
  307. package/dist/assets/xsl-l8oVQM8u.js +1 -0
  308. package/dist/assets/yaml-BM_YwV-H.js +1 -0
  309. package/dist/assets/zenscript-spOPJke_.js +1 -0
  310. package/dist/assets/zig-Dr5aj8gQ.js +1 -0
  311. package/dist/favicon.svg +1 -0
  312. package/dist/icons.svg +24 -0
  313. package/dist/index.html +29 -0
  314. package/package.json +86 -0
  315. package/registry.json +593 -0
  316. package/scripts/build-registry.ts +209 -0
  317. package/scripts/ui-cli.ts +259 -0
@@ -0,0 +1,209 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const COMPONENTS_DIR = './src/components/ui';
5
+ const OUTPUT_FILE = './registry.json';
6
+
7
+ // Directories to exclude from registry (not reusable components)
8
+ const EXCLUDE_DIRS = new Set(['icons', 'layout', 'vs-code', 'pretty-code', 'Showcase.tsx']);
9
+
10
+ interface RegistryFile {
11
+ path: string;
12
+ content: string;
13
+ }
14
+
15
+ interface RegistryComponent {
16
+ name: string;
17
+ dependencies: string[];
18
+ internalDependencies: string[];
19
+ files: RegistryFile[];
20
+ }
21
+
22
+ interface Registry {
23
+ core: {
24
+ dependencies: string[];
25
+ files: RegistryFile[];
26
+ };
27
+ components: Record<string, RegistryComponent>;
28
+ }
29
+
30
+ const getFiles = (dir: string): string[] => {
31
+ const files: string[] = [];
32
+ let entries: string[];
33
+ try {
34
+ entries = fs.readdirSync(dir);
35
+ } catch (err) {
36
+ console.warn(`Cannot read directory ${dir}: ${err}`);
37
+ return files;
38
+ }
39
+ for (const file of entries) {
40
+ const fullPath = path.join(dir, file);
41
+ try {
42
+ const stat = fs.statSync(fullPath);
43
+ if (stat.isDirectory()) {
44
+ files.push(...getFiles(fullPath));
45
+ } else if (file.endsWith('.tsx') || file.endsWith('.ts')) {
46
+ if (!file.includes('.test.') && !file.includes('.stories.')) {
47
+ files.push(fullPath);
48
+ }
49
+ }
50
+ } catch (err) {
51
+ console.warn(`Skipping ${fullPath}: ${err}`);
52
+ }
53
+ }
54
+ return files;
55
+ };
56
+
57
+ const INTERNAL_ALIAS_PREFIXES = ['@/', '@lib/', '@components/', '@app/'];
58
+
59
+ const parseDependencies = (content: string): string[] => {
60
+ const dependencies = new Set<string>();
61
+ const importRegex = /(?:from|import)\s+['"]([^'"]+)['"]/g;
62
+ let match;
63
+
64
+ while ((match = importRegex.exec(content)) !== null) {
65
+ const pkg = match[1];
66
+
67
+ // Skip relative imports
68
+ if (pkg.startsWith('.')) continue;
69
+ // Skip internal aliases
70
+ if (INTERNAL_ALIAS_PREFIXES.some(prefix => pkg.startsWith(prefix))) continue;
71
+
72
+ // Extract package name
73
+ const parts = pkg.split('/');
74
+ if (pkg.startsWith('@') && parts.length >= 2) {
75
+ dependencies.add(`${parts[0]}/${parts[1]}`);
76
+ } else {
77
+ dependencies.add(parts[0]);
78
+ }
79
+ }
80
+
81
+ // Remove React (always a peer dependency)
82
+ dependencies.delete('react');
83
+ dependencies.delete('react-dom');
84
+
85
+ return [...dependencies];
86
+ };
87
+
88
+ const getInternalDeps = (content: string, currentDirName: string): string[] => {
89
+ const internalDeps = new Set<string>();
90
+
91
+ // 1. Alias imports: @/components/ui/xxx or @components/ui/xxx
92
+ const aliasRegex = /from\s+['"](?:@\/?components\/ui)\/([^'"]+)['"]/g;
93
+ let match;
94
+ while ((match = aliasRegex.exec(content)) !== null) {
95
+ const depPath = match[1].split('/')[0];
96
+ if (depPath !== currentDirName && depPath !== 'icons') {
97
+ internalDeps.add(depPath);
98
+ }
99
+ }
100
+
101
+ // 2. Relative imports: ../spinner/Spinner
102
+ const relativeRegex = /from\s+['"]\.\.\/([^'"]+)['"]/g;
103
+ while ((match = relativeRegex.exec(content)) !== null) {
104
+ const depPath = match[1].split('/')[0];
105
+ if (depPath !== currentDirName) {
106
+ internalDeps.add(depPath);
107
+ }
108
+ }
109
+
110
+ return [...internalDeps];
111
+ };
112
+
113
+ const buildRegistry = () => {
114
+ console.log('Building component registry...');
115
+
116
+ const registry: Registry = {
117
+ core: {
118
+ dependencies: [
119
+ '@base-ui/react',
120
+ 'clsx',
121
+ 'tailwind-merge',
122
+ 'tailwind-variants',
123
+ 'tailwindcss-animate',
124
+ '@tailwindcss/vite',
125
+ 'autoprefixer',
126
+ 'tailwindcss',
127
+ 'postcss',
128
+ ],
129
+ files: [
130
+ {
131
+ path: 'src/lib/utils/cn.ts',
132
+ content: fs.readFileSync('./src/lib/utils/cn.ts', 'utf-8'),
133
+ },
134
+ {
135
+ path: 'src/styles/index.css',
136
+ content: fs.readFileSync('./src/styles/index.css', 'utf-8'),
137
+ },
138
+ ],
139
+ },
140
+ components: {},
141
+ };
142
+
143
+ const componentDirs = fs.readdirSync(COMPONENTS_DIR);
144
+
145
+ for (const dirName of componentDirs) {
146
+ if (EXCLUDE_DIRS.has(dirName)) continue;
147
+
148
+ const dirPath = path.join(COMPONENTS_DIR, dirName);
149
+ if (!fs.statSync(dirPath).isDirectory()) continue;
150
+
151
+ const files = getFiles(dirPath);
152
+ if (files.length === 0) continue;
153
+
154
+ // Find main file: prefer <DirName>.tsx, then any .tsx
155
+ const mainFile =
156
+ files.find(
157
+ (f) =>
158
+ f.toLowerCase().includes(dirName.toLowerCase()) &&
159
+ f.endsWith('.tsx')
160
+ ) || files.find((f) => f.endsWith('.tsx'));
161
+
162
+ if (!mainFile) continue;
163
+
164
+ // Parse all files in the component directory for dependencies
165
+ const allDependencies = new Set<string>();
166
+ const allInternalDeps = new Set<string>();
167
+
168
+ for (const file of files) {
169
+ try {
170
+ const content = fs.readFileSync(file, 'utf-8');
171
+ for (const dep of parseDependencies(content)) allDependencies.add(dep);
172
+ for (const dep of getInternalDeps(content, dirName)) allInternalDeps.add(dep);
173
+ } catch (err) {
174
+ console.warn(`Failed to read ${file}: ${err}`);
175
+ }
176
+ }
177
+
178
+ registry.components[dirName] = {
179
+ name: dirName,
180
+ dependencies: [...allDependencies],
181
+ internalDependencies: [...allInternalDeps],
182
+ files: files.map((f) => {
183
+ try {
184
+ return {
185
+ path: f.replace(/\\/g, '/').replace(/^\.\//, ''),
186
+ content: fs.readFileSync(f, 'utf-8'),
187
+ };
188
+ } catch (err) {
189
+ console.warn(`Failed to read ${f}: ${err}`);
190
+ return { path: f.replace(/\\/g, '/').replace(/^\.\//, ''), content: '' };
191
+ }
192
+ }).filter(f => f.content !== ''),
193
+ };
194
+ }
195
+
196
+ const componentCount = Object.keys(registry.components).length;
197
+ if (componentCount === 0) {
198
+ console.warn('Warning: No components found in registry');
199
+ }
200
+ try {
201
+ fs.writeFileSync(OUTPUT_FILE, JSON.stringify(registry, null, 2));
202
+ } catch (err) {
203
+ console.error(`Failed to write registry: ${err}`);
204
+ process.exit(1);
205
+ }
206
+ console.log(`Registry built: ${componentCount} components → ${OUTPUT_FILE}`);
207
+ };
208
+
209
+ buildRegistry();
@@ -0,0 +1,259 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { execSync } from 'child_process';
5
+
6
+ const REGISTRY_LOCAL = './registry.json';
7
+ const REGISTRY_REMOTE = 'https://raw.githubusercontent.com/huy14032003/ui-component/main/registry.json';
8
+
9
+ const log = (msg: string) => console.log(`[CUS-BASE-UI] ${msg}`);
10
+ const warn = (msg: string) => console.warn(`[CUS-BASE-UI] WARN: ${msg}`);
11
+ const error = (msg: string) => console.error(`[CUS-BASE-UI] ERROR: ${msg}`);
12
+
13
+ const getTargetProjectDir = () => process.cwd();
14
+
15
+ interface Registry {
16
+ core?: { dependencies: string[]; files: { path: string; content: string }[] };
17
+ components: Record<string, { dependencies: string[]; internalDependencies?: string[]; files: { path: string; content: string }[] }>;
18
+ }
19
+
20
+ const validateRegistry = (data: unknown): data is Registry => {
21
+ if (!data || typeof data !== 'object') return false;
22
+ const reg = data as Record<string, unknown>;
23
+ return 'components' in reg && typeof reg.components === 'object' && reg.components !== null;
24
+ };
25
+
26
+ const getRegistry = async (isLocal: boolean): Promise<Registry> => {
27
+ if (isLocal && fs.existsSync(REGISTRY_LOCAL)) {
28
+ log('Using local registry...');
29
+ try {
30
+ const data = JSON.parse(fs.readFileSync(REGISTRY_LOCAL, 'utf-8'));
31
+ if (!validateRegistry(data)) {
32
+ error('Invalid local registry format — missing "components" field.');
33
+ process.exit(1);
34
+ }
35
+ return data;
36
+ } catch (err) {
37
+ error(`Failed to parse local registry: ${err instanceof Error ? err.message : err}`);
38
+ process.exit(1);
39
+ }
40
+ }
41
+
42
+ log('Fetching registry from remote...');
43
+ try {
44
+ const response = await fetch(REGISTRY_REMOTE);
45
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
46
+ const data = await response.json();
47
+ if (!validateRegistry(data)) {
48
+ error('Invalid remote registry format — missing "components" field.');
49
+ process.exit(1);
50
+ }
51
+ return data;
52
+ } catch (err: unknown) {
53
+ const message = err instanceof Error ? err.message : String(err);
54
+ error(`Cannot fetch registry: ${message}`);
55
+ process.exit(1);
56
+ }
57
+ };
58
+
59
+ const installNpmPackages = (packages: string[], cwd: string) => {
60
+ if (packages.length === 0) return;
61
+
62
+ const pkgJsonPath = path.join(cwd, 'package.json');
63
+ let toInstall = packages;
64
+
65
+ if (fs.existsSync(pkgJsonPath)) {
66
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
67
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
68
+ toInstall = packages.filter((p) => !allDeps[p]);
69
+ }
70
+
71
+ if (toInstall.length === 0) return;
72
+
73
+ log(`Installing: ${toInstall.join(', ')}...`);
74
+ try {
75
+ execSync(`npm install ${toInstall.join(' ')} --save`, { stdio: 'inherit', cwd });
76
+ } catch (err) {
77
+ error(`Failed to install packages: ${toInstall.join(', ')}. ${err instanceof Error ? err.message : ''}`);
78
+ }
79
+ };
80
+
81
+ const ensureCore = (registry: { core?: { dependencies: string[]; files: { path: string; content: string }[] } }, cwd: string) => {
82
+ const core = registry.core;
83
+ if (!core) return;
84
+
85
+ installNpmPackages(core.dependencies, cwd);
86
+
87
+ for (const file of core.files) {
88
+ const targetPath = path.join(cwd, file.path);
89
+ const targetDir = path.dirname(targetPath);
90
+
91
+ if (!fs.existsSync(targetDir)) {
92
+ fs.mkdirSync(targetDir, { recursive: true });
93
+ }
94
+
95
+ if (!fs.existsSync(targetPath)) {
96
+ fs.writeFileSync(targetPath, file.content);
97
+ log(`Created core file: ${file.path}`);
98
+ }
99
+ }
100
+ };
101
+
102
+ const addComponent = (
103
+ name: string,
104
+ registry: { core?: unknown; components: Record<string, { dependencies: string[]; internalDependencies?: string[]; files: { path: string; content: string }[] }> },
105
+ cwd: string,
106
+ options: { force: boolean },
107
+ added: Set<string> = new Set()
108
+ ) => {
109
+ if (added.has(name)) return;
110
+ added.add(name);
111
+
112
+ const component = registry.components[name];
113
+ if (!component) {
114
+ error(`Component "${name}" not found. Run 'list' to see available components.`);
115
+ return;
116
+ }
117
+
118
+ log(`Adding: ${name}...`);
119
+
120
+ ensureCore(registry as Parameters<typeof ensureCore>[0], cwd);
121
+ installNpmPackages(component.dependencies, cwd);
122
+
123
+ // Resolve internal dependencies first
124
+ if (component.internalDependencies) {
125
+ for (const dep of component.internalDependencies) {
126
+ if (registry.components[dep]) {
127
+ addComponent(dep, registry, cwd, options, added);
128
+ }
129
+ }
130
+ }
131
+
132
+ for (const file of component.files) {
133
+ const targetPath = path.join(cwd, file.path);
134
+ const targetDir = path.dirname(targetPath);
135
+
136
+ if (!fs.existsSync(targetDir)) {
137
+ fs.mkdirSync(targetDir, { recursive: true });
138
+ }
139
+
140
+ if (fs.existsSync(targetPath) && !options.force) {
141
+ warn(`Skipped (exists): ${file.path} — use --force to overwrite`);
142
+ continue;
143
+ }
144
+
145
+ fs.writeFileSync(targetPath, file.content);
146
+ log(`Created: ${file.path}`);
147
+ }
148
+ };
149
+
150
+ const removeComponent = (name: string, registry: { components: Record<string, { files: { path: string }[] }> }, cwd: string) => {
151
+ const component = registry.components[name];
152
+ if (!component) {
153
+ error(`Component "${name}" not found.`);
154
+ return;
155
+ }
156
+
157
+ log(`Removing: ${name}...`);
158
+
159
+ for (const file of component.files) {
160
+ const targetPath = path.join(cwd, file.path);
161
+ if (fs.existsSync(targetPath)) {
162
+ fs.unlinkSync(targetPath);
163
+ log(`Deleted: ${file.path}`);
164
+ }
165
+ }
166
+
167
+ // Clean up empty directories
168
+ for (const file of component.files) {
169
+ const targetDir = path.dirname(path.join(cwd, file.path));
170
+ try {
171
+ if (fs.existsSync(targetDir) && fs.readdirSync(targetDir).length === 0) {
172
+ fs.rmdirSync(targetDir);
173
+ log(`Removed empty dir: ${path.relative(cwd, targetDir)}`);
174
+ }
175
+ } catch (err) {
176
+ warn(`Could not remove directory: ${err instanceof Error ? err.message : err}`);
177
+ }
178
+ }
179
+ };
180
+
181
+ const main = async () => {
182
+ const args = process.argv.slice(2);
183
+ const isLocal = args.includes('--local');
184
+ const isForce = args.includes('--force');
185
+ const filteredArgs = args.filter((a) => !a.startsWith('--'));
186
+ const command = filteredArgs[0];
187
+ const componentNames = filteredArgs.slice(1);
188
+
189
+ const cwd = getTargetProjectDir();
190
+ const registry = await getRegistry(isLocal);
191
+
192
+ switch (command) {
193
+ case 'add': {
194
+ if (componentNames.length === 0) {
195
+ error('Usage: npx cus-base-ui add <component-name> [--force]');
196
+ return;
197
+ }
198
+ for (const name of componentNames) {
199
+ addComponent(name, registry, cwd, { force: isForce });
200
+ }
201
+ log('Done!');
202
+ break;
203
+ }
204
+
205
+ case 'remove': {
206
+ if (componentNames.length === 0) {
207
+ error('Usage: npx cus-base-ui remove <component-name>');
208
+ return;
209
+ }
210
+ for (const name of componentNames) {
211
+ removeComponent(name, registry, cwd);
212
+ }
213
+ log('Done!');
214
+ break;
215
+ }
216
+
217
+ case 'list': {
218
+ const components = Object.keys(registry.components).sort();
219
+ log(`Available components (${components.length}):`);
220
+ for (const k of components) {
221
+ const deps = registry.components[k].internalDependencies;
222
+ const depStr = deps?.length ? ` (requires: ${deps.join(', ')})` : '';
223
+ console.log(` - ${k}${depStr}`);
224
+ }
225
+ break;
226
+ }
227
+
228
+ case 'init': {
229
+ ensureCore(registry, cwd);
230
+ log('Initialization complete.');
231
+ break;
232
+ }
233
+
234
+ case 'tailwind': {
235
+ console.log('\n--- Copy to tailwind.config.ts / tailwind.config.js ---\n');
236
+ console.log('// See README_CLI.md for full theme config');
237
+ break;
238
+ }
239
+
240
+ default: {
241
+ console.log(`
242
+ cus-base-ui — UI Component CLI
243
+
244
+ Commands:
245
+ init Initialize project (install core deps + files)
246
+ add <name> [--force] Add component(s) to your project
247
+ remove <name> Remove component(s) from your project
248
+ list List all available components
249
+ tailwind Show Tailwind config instructions
250
+
251
+ Options:
252
+ --local Use local registry.json instead of remote
253
+ --force Overwrite existing files when adding
254
+ `);
255
+ }
256
+ }
257
+ };
258
+
259
+ main();