@@ -2,7 +2,7 @@ import fs from 'node:fs'
22import os from "node:os" ;
33import path from 'node:path'
44
5- import { getCustomPath , invokeCommand , toPurl , toPurlFromString } from "../tools.js" ;
5+ import { getCustom , getCustomPath , invokeCommand , toPurl , toPurlFromString } from "../tools.js" ;
66import Sbom from '../sbom.js'
77import Manifest from './manifest.js' ;
88
@@ -314,10 +314,56 @@ export default class Base_javascript {
314314 if ( ! opts . cwd ) {
315315 opts . cwd = path . dirname ( this . #manifest. manifestPath ) ;
316316 }
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 ( path . delimiter ) } ${ path . delimiter } ${ 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 ) ;
318364 } catch ( error ) {
319365 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. ` ) ;
321367 }
322368 if ( error . code === 'EACCES' ) {
323369 throw new Error ( `Permission denied when executing ${ this . #cmd} . Please check file permissions.` ) ;
0 commit comments