@@ -2,7 +2,7 @@ import fs from 'node:fs'
2
2
import os from "node:os" ;
3
3
import path from 'node:path'
4
4
5
- import { getCustomPath , invokeCommand , toPurl , toPurlFromString } from "../tools.js" ;
5
+ import { getCustom , getCustomPath , invokeCommand , toPurl , toPurlFromString } from "../tools.js" ;
6
6
import Sbom from '../sbom.js'
7
7
import Manifest from './manifest.js' ;
8
8
@@ -314,10 +314,56 @@ export default class Base_javascript {
314
314
if ( ! opts . cwd ) {
315
315
opts . cwd = path . dirname ( this . #manifest. manifestPath ) ;
316
316
}
317
- return invokeCommand ( this . #cmd, args , opts ) ;
317
+
318
+ // Add version manager paths for JavaScript package managers
319
+ if ( process . platform !== 'win32' ) {
320
+ const versionManagerPaths = [ ] ;
321
+
322
+ // Add fnm path if available
323
+ const fnmDir = getCustom ( 'FNM_DIR' , null , opts ) ;
324
+ if ( fnmDir ) {
325
+ versionManagerPaths . push ( `${ fnmDir } /current/bin` ) ;
326
+ }
327
+
328
+ // Add nvm path if available
329
+ const nvmDir = getCustom ( 'NVM_DIR' , null , opts ) ;
330
+ if ( nvmDir ) {
331
+ versionManagerPaths . push ( `${ nvmDir } /current/bin` ) ;
332
+ }
333
+
334
+ // Add local node_modules/.bin path
335
+ const localBinPath = path . join ( opts . cwd , 'node_modules' , '.bin' ) ;
336
+ if ( fs . existsSync ( localBinPath ) ) {
337
+ versionManagerPaths . push ( localBinPath ) ;
338
+ }
339
+
340
+ if ( versionManagerPaths . length > 0 ) {
341
+ opts = {
342
+ ...opts ,
343
+ env : {
344
+ ...opts . env ,
345
+ PATH : `${ versionManagerPaths . join ( ':' ) } :${ process . env . PATH } `
346
+ }
347
+ } ;
348
+ }
349
+ }
350
+
351
+ // Try to find the command in the following order:
352
+ // 1. Custom path from environment/opts (via getCustomPath)
353
+ // 2. Local node_modules/.bin
354
+ // 3. Global installation
355
+ let cmd = this . #cmd;
356
+ if ( ! fs . existsSync ( cmd ) ) {
357
+ const localCmd = path . join ( opts . cwd , 'node_modules' , '.bin' , this . _cmdName ( ) ) ;
358
+ if ( fs . existsSync ( localCmd ) ) {
359
+ cmd = localCmd ;
360
+ }
361
+ }
362
+
363
+ return invokeCommand ( cmd , args , opts ) ;
318
364
} catch ( error ) {
319
365
if ( error . code === 'ENOENT' ) {
320
- throw new Error ( `${ this . #cmd} is not accessible.` ) ;
366
+ throw new Error ( `${ this . #cmd} is not accessible. Please ensure it is installed via npm, corepack, or your version manager. ` ) ;
321
367
}
322
368
if ( error . code === 'EACCES' ) {
323
369
throw new Error ( `Permission denied when executing ${ this . #cmd} . Please check file permissions.` ) ;
0 commit comments