@@ -143,16 +143,47 @@ class CodeInjector implements ICodeInjector {
143143
144144 }
145145
146- async runPnpmShell ( { command, cwd, envOverrides = { } } : {
146+
147+ async doesUserHasPnpmLockFile ( dir : string ) : Promise < boolean > {
148+ const usersPackagePath = path . join ( dir , 'package.json' ) ;
149+ let packageContent : { dependencies : any , devDependencies : any } = null ;
150+ try {
151+ packageContent = JSON . parse ( await fs . promises . readFile ( usersPackagePath , 'utf-8' ) ) ;
152+ } catch ( e ) {
153+ // user package.json does not exist, user does not have custom components
154+ }
155+ if ( packageContent ) {
156+ const lockPath = path . join ( dir , 'pnpm-lock.yaml' ) ;
157+ let lock : any = null ;
158+ try {
159+ lock = yaml . parse ( await fs . promises . readFile ( lockPath , 'utf-8' ) ) ;
160+ return true ;
161+ } catch ( e ) {
162+ return false ;
163+ }
164+ }
165+ return false ;
166+ }
167+
168+ async runPackageManagerShell ( { command, cwd, envOverrides = { } } : {
147169 command : string ,
148170 cwd : string ,
149171 envOverrides ?: { [ key : string ] : string }
150172 } ) {
151-
173+
152174 const nodeBinary = process . execPath ; // Path to the Node.js binary running this script
153- // On Windows, pnpm is pnpm.cmd, on Unix systems it's pnpm
154- const pnpmExecutable = process . platform === 'win32' ? 'pnpm.cmd' : 'pnpm' ;
155- const pnpmPath = path . join ( path . dirname ( nodeBinary ) , pnpmExecutable ) ; // Path to the pnpm executable
175+ const doesUserHavePnpmLock = await this . doesUserHasPnpmLockFile ( this . adminforth . config . customization . customComponentsDir ) ;
176+
177+ // On Windows, npm/pnpm is npm/pnpm.cmd, on Unix systems it's npm/pnpm
178+ let packageExecutable
179+ if ( doesUserHavePnpmLock ) {
180+ afLogger . trace ( `User has pnpm-lock.yaml, using pnpm for installing custom components` ) ;
181+ packageExecutable = process . platform === 'win32' ? 'pnpm.cmd' : 'pnpm' ;
182+ } else {
183+ afLogger . trace ( `User does not have pnpm-lock.yaml, falling back to npm for installing custom components` ) ;
184+ packageExecutable = process . platform === 'win32' ? 'npm.cmd' : 'npm' ;
185+ }
186+ const packagePath = path . join ( path . dirname ( nodeBinary ) , packageExecutable ) ; // Path to the package executable
156187
157188 const env = {
158189 VITE_ADMINFORTH_PUBLIC_PATH : this . adminforth . config . baseUrl ,
@@ -161,19 +192,19 @@ class CodeInjector implements ICodeInjector {
161192 ...envOverrides ,
162193 } ;
163194
164- afLogger . trace ( `⚙️ exec: pnpm ${ command } ` ) ;
165- afLogger . trace ( `🪲 pnpm ${ command } cwd: ${ cwd } ` ) ;
195+ afLogger . trace ( `⚙️ exec: ${ packageExecutable } ${ command } ` ) ;
196+ afLogger . trace ( `🪲 ${ packageExecutable } ${ command } cwd: ${ cwd } ` ) ;
166197
167198 let execCommand : string ;
168199 if ( process . platform === 'win32' ) {
169200 // Quote path if it contains spaces
170- const quotedPnpmPath = pnpmPath . includes ( ' ' ) ? `"${ pnpmPath } "` : pnpmPath ;
171- execCommand = `${ quotedPnpmPath } ${ command } ` ;
201+ const quotedPackagePath = packagePath . includes ( ' ' ) ? `"${ packagePath } "` : packagePath ;
202+ execCommand = `${ quotedPackagePath } ${ command } ` ;
172203 } else {
173204 // Quote paths that contain spaces (for Unix systems)
174205 const quotedNodeBinary = nodeBinary . includes ( ' ' ) ? `"${ nodeBinary } "` : nodeBinary ;
175- const quotedPnpmPath = pnpmPath . includes ( ' ' ) ? `"${ pnpmPath } "` : pnpmPath ;
176- execCommand = `${ quotedNodeBinary } ${ quotedPnpmPath } ${ command } ` ;
206+ const quotedPackagePath = packagePath . includes ( ' ' ) ? `"${ packagePath } "` : packagePath ;
207+ execCommand = `${ quotedNodeBinary } ${ quotedPackagePath } ${ command } ` ;
177208 }
178209
179210 const execOptions : any = {
@@ -186,10 +217,10 @@ class CodeInjector implements ICodeInjector {
186217 }
187218
188219 const { stderr : err } = await execAsync ( execCommand , execOptions ) ;
189- afLogger . trace ( `pnpm ${ command } done in` ) ;
220+ afLogger . trace ( `${ packageExecutable } ${ command } done in` ) ;
190221
191222 if ( err ) {
192- afLogger . trace ( `🪲pnpm ${ command } errors/warnings: ${ err } ` ) ;
223+ afLogger . trace ( `🪲${ packageExecutable } ${ command } errors/warnings: ${ err } ` ) ;
193224 }
194225 }
195226
@@ -745,7 +776,7 @@ class CodeInjector implements ICodeInjector {
745776 afLogger . trace ( `🪲Hash file does not exist, proceeding with pnpm install, ${ e } ` ) ;
746777 }
747778
748- await this . runPnpmShell ( { command : 'install --frozen-lockfile' , cwd : this . spaTmpPath ( ) , envOverrides : {
779+ await this . runPackageManagerShell ( { command : 'install --frozen-lockfile' , cwd : this . spaTmpPath ( ) , envOverrides : {
749780 NODE_ENV : 'development' // otherwise it will not install devDependencies which we still need, e.g for extract
750781 } } ) ;
751782
@@ -766,7 +797,7 @@ class CodeInjector implements ICodeInjector {
766797
767798 if ( allPacks . length ) {
768799 const pnpmInstallCommand = `install ${ allPacksUnique . join ( ' ' ) } ` ;
769- await this . runPnpmShell ( {
800+ await this . runPackageManagerShell ( {
770801 command : pnpmInstallCommand , cwd : this . spaTmpPath ( ) ,
771802 envOverrides : {
772803 NODE_ENV : 'development' // otherwise it will not install devDependencies which we still need, e.g for extract
@@ -977,7 +1008,7 @@ class CodeInjector implements ICodeInjector {
9771008 }
9781009
9791010 if ( ! skipExtract ) {
980- await this . runPnpmShell ( { command : 'run i18n:extract' , cwd} ) ;
1011+ await this . runPackageManagerShell ( { command : 'run i18n:extract' , cwd} ) ;
9811012
9821013 // create serveDir if not exists
9831014 await fs . promises . mkdir ( serveDir , { recursive : true } ) ;
@@ -995,7 +1026,7 @@ class CodeInjector implements ICodeInjector {
9951026 if ( ! skipBuild ) {
9961027
9971028 // TODO probably add option to build with tsh check (plain 'build')
998- await this . runPnpmShell ( { command : 'run build-only' , cwd} ) ;
1029+ await this . runPackageManagerShell ( { command : 'run build-only' , cwd} ) ;
9991030
10001031 // coy dist to serveDir
10011032 await fsExtra . copy ( path . join ( cwd , 'dist' ) , serveDir , { recursive : true } ) ;
0 commit comments