You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.4 KiB
55 lines
1.4 KiB
import process from 'node:process'; |
|
import path from 'node:path'; |
|
import pathKey from 'path-key'; |
|
import {toPath, traversePathUp} from 'unicorn-magic'; |
|
|
|
export const npmRunPath = ({ |
|
cwd = process.cwd(), |
|
path: pathOption = process.env[pathKey()], |
|
preferLocal = true, |
|
execPath = process.execPath, |
|
addExecPath = true, |
|
} = {}) => { |
|
const cwdPath = path.resolve(toPath(cwd)); |
|
const result = []; |
|
const pathParts = pathOption.split(path.delimiter); |
|
|
|
if (preferLocal) { |
|
applyPreferLocal(result, pathParts, cwdPath); |
|
} |
|
|
|
if (addExecPath) { |
|
applyExecPath(result, pathParts, execPath, cwdPath); |
|
} |
|
|
|
return pathOption === '' || pathOption === path.delimiter |
|
? `${result.join(path.delimiter)}${pathOption}` |
|
: [...result, pathOption].join(path.delimiter); |
|
}; |
|
|
|
const applyPreferLocal = (result, pathParts, cwdPath) => { |
|
for (const directory of traversePathUp(cwdPath)) { |
|
const pathPart = path.join(directory, 'node_modules/.bin'); |
|
if (!pathParts.includes(pathPart)) { |
|
result.push(pathPart); |
|
} |
|
} |
|
}; |
|
|
|
// Ensure the running `node` binary is used |
|
const applyExecPath = (result, pathParts, execPath, cwdPath) => { |
|
const pathPart = path.resolve(cwdPath, toPath(execPath), '..'); |
|
if (!pathParts.includes(pathPart)) { |
|
result.push(pathPart); |
|
} |
|
}; |
|
|
|
export const npmRunPathEnv = ({env = process.env, ...options} = {}) => { |
|
env = {...env}; |
|
|
|
const pathName = pathKey({env}); |
|
options.path = env[pathName]; |
|
env[pathName] = npmRunPath(options); |
|
|
|
return env; |
|
};
|
|
|