11import { Args , Command , Options } from "@effect/cli"
2+ import * as FileSystem from "@effect/platform/FileSystem"
3+
4+ import * as Path from "node:path"
25import {
36 HttpClient ,
47 HttpClientRequest ,
@@ -8,6 +11,14 @@ import {
811import chalk from "chalk"
912import { Console , Effect , Schema , pipe } from "effect"
1013import { REGISTRY_URL } from "~/consts"
14+ import { applyUserAliases } from "~/lib/apply-user-aliases"
15+ import {
16+ isLaravel ,
17+ isNextWithSrc ,
18+ isNextWithoutSrc ,
19+ isRemix ,
20+ } from "~/lib/check-current-user-project"
21+ import { walkFiles } from "~/lib/walk-files"
1122import { Component } from "~/schema/component"
1223
1324export const componentNames = Args . text ( { name : "componentNames" } ) . pipe ( Args . repeated )
@@ -78,13 +89,61 @@ export const addCommand = Command.make(
7889 }
7990 args . push ( ...componentPaths )
8091
81- return yield * pipe (
92+ const exitCode = yield * pipe (
8293 RawCommand . make ( "shadcnClone" , ...args ) . pipe (
8394 RawCommand . stdin ( "inherit" ) ,
8495 RawCommand . stdout ( "inherit" ) ,
8596 RawCommand . stderr ( "inherit" ) ,
8697 RawCommand . exitCode ,
8798 ) ,
8899 )
100+
101+ if ( exitCode === 0 ) {
102+ const fileSystem = yield * FileSystem . FileSystem
103+
104+ const userConfigPath = Path . resolve ( process . cwd ( ) , "components.json" )
105+ const userConfigRaw = yield * fileSystem . readFileString ( userConfigPath )
106+ const userConfig = JSON . parse ( userConfigRaw )
107+
108+ const cwd = process . cwd ( )
109+
110+ const hasSrc = yield * Effect . promise ( ( ) => isNextWithSrc ( cwd ) )
111+ const noSrc = yield * Effect . promise ( ( ) => isNextWithoutSrc ( cwd ) )
112+ const isRemixApp = yield * Effect . promise ( ( ) => isRemix ( cwd ) )
113+ const isLaravelApp = yield * Effect . promise ( ( ) => isLaravel ( cwd ) )
114+
115+ function resolveAliasPath ( aliasPath : string ) : string {
116+ const base =
117+ isLaravelApp || noSrc ? cwd : hasSrc || isRemixApp ? Path . join ( cwd , "src" ) : cwd
118+
119+ return Path . resolve ( aliasPath . replace ( / ^ @ \/ / , `${ base } /` ) )
120+ }
121+
122+ const foldersToPatch = Object . values ( userConfig . aliases as Record < string , string > )
123+ . filter ( ( dir ) => typeof dir === "string" && dir . startsWith ( "@/" ) )
124+ . map ( ( aliasPath ) => resolveAliasPath ( aliasPath ) )
125+
126+ for ( const folder of foldersToPatch ) {
127+ const exists = yield * fileSystem . exists ( folder )
128+ if ( ! exists ) continue
129+
130+ const allFiles = yield * walkFiles ( fileSystem , folder )
131+
132+ for ( const file of allFiles ) {
133+ const fullPath = Path . join ( folder , file )
134+ if ( ! fullPath . endsWith ( ".tsx" ) ) continue
135+
136+ const raw = yield * fileSystem . readFileString ( fullPath )
137+ const updated = applyUserAliases ( raw , userConfig . aliases )
138+
139+ if ( updated !== raw ) {
140+ yield * fileSystem . writeFile ( fullPath , Buffer . from ( updated ) )
141+ }
142+ }
143+ }
144+
145+ }
146+
147+ return exitCode
89148 } ) ,
90149) . pipe ( Command . withDescription ( "Adds UI components or blocks to your project." ) )
0 commit comments