@socketsecurity/lib
Version:
Core utilities and infrastructure for Socket.dev security tools
426 lines (425 loc) • 15.2 kB
JavaScript
;
/* Socket Lib - Built with esbuild */
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var bin_exports = {};
__export(bin_exports, {
execBin: () => execBin,
findRealBin: () => findRealBin,
findRealNpm: () => findRealNpm,
findRealPnpm: () => findRealPnpm,
findRealYarn: () => findRealYarn,
isShadowBinPath: () => isShadowBinPath,
resolveBinPathSync: () => resolveBinPathSync,
which: () => which,
whichBin: () => whichBin,
whichBinSync: () => whichBinSync,
whichSync: () => whichSync
});
module.exports = __toCommonJS(bin_exports);
var import_home = require("#env/home");
var import_windows = require("#env/windows");
var import_xdg = require("#env/xdg");
var import_platform = require("#constants/platform");
var import_fs = require("./fs");
var import_path = require("./path");
var import_spawn = require("./spawn");
let _fs;
// @__NO_SIDE_EFFECTS__
function getFs() {
if (_fs === void 0) {
_fs = require("node:fs");
}
return _fs;
}
let _path;
// @__NO_SIDE_EFFECTS__
function getPath() {
if (_path === void 0) {
_path = require("node:path");
}
return _path;
}
let _which;
// @__NO_SIDE_EFFECTS__
function getWhich() {
if (_which === void 0) {
_which = require("./external/which");
}
return _which;
}
// @__NO_SIDE_EFFECTS__
async function execBin(binPath, args, options) {
const resolvedPath = (0, import_path.isPath)(binPath) ? /* @__PURE__ */ resolveBinPathSync(binPath) : await whichBin(binPath);
if (!resolvedPath) {
const error = new Error(
`Binary not found: ${binPath}
Possible causes:
- Binary "${binPath}" is not installed or not in PATH
- Binary name is incorrect or misspelled
- Installation directory is not in system PATH
To resolve:
1. Verify "${binPath}" is installed: which ${binPath} (Unix) or where ${binPath} (Windows)
2. Install the binary if missing, ex: npm install -g ${binPath}
3. Check PATH environment variable includes the binary location`
);
error.code = "ENOENT";
throw error;
}
const binCommand = Array.isArray(resolvedPath) ? resolvedPath[0] : resolvedPath;
return await (0, import_spawn.spawn)(binCommand, args ?? [], {
shell: import_platform.WIN32,
...options
});
}
async function which(binName, options) {
return await (/* @__PURE__ */ getWhich())(binName, options);
}
function whichSync(binName, options) {
return (/* @__PURE__ */ getWhich()).sync(binName, options);
}
async function whichBin(binName, options) {
const which2 = /* @__PURE__ */ getWhich();
const opts = { nothrow: true, ...options };
const result = await which2(binName, opts);
if (opts?.all) {
const paths = Array.isArray(result) ? result : typeof result === "string" ? [result] : void 0;
return paths?.length ? paths.map((p) => /* @__PURE__ */ resolveBinPathSync(p)) : paths;
}
if (!result) {
return void 0;
}
return /* @__PURE__ */ resolveBinPathSync(result);
}
function whichBinSync(binName, options) {
const opts = { nothrow: true, ...options };
const result = whichSync(binName, opts);
if (opts.all) {
const paths = Array.isArray(result) ? result : typeof result === "string" ? [result] : void 0;
return paths?.length ? paths.map((p) => /* @__PURE__ */ resolveBinPathSync(p)) : paths;
}
if (!result) {
return void 0;
}
return /* @__PURE__ */ resolveBinPathSync(result);
}
function isShadowBinPath(dirPath) {
if (!dirPath) {
return false;
}
const normalized = dirPath.replace(/\\/g, "/");
return normalized.includes("node_modules/.bin");
}
function findRealBin(binName, commonPaths = []) {
const fs = /* @__PURE__ */ getFs();
const path = /* @__PURE__ */ getPath();
const which2 = /* @__PURE__ */ getWhich();
for (const binPath2 of commonPaths) {
if (fs?.existsSync(binPath2)) {
return binPath2;
}
}
const binPath = which2?.sync(binName, { nothrow: true });
if (binPath) {
const binDir = path?.dirname(binPath);
if (isShadowBinPath(binDir)) {
const allPaths = which2?.sync(binName, { all: true, nothrow: true }) || [];
const pathsArray = Array.isArray(allPaths) ? allPaths : typeof allPaths === "string" ? [allPaths] : [];
for (const altPath of pathsArray) {
const altDir = path?.dirname(altPath);
if (!isShadowBinPath(altDir)) {
return altPath;
}
}
}
return binPath;
}
return void 0;
}
function findRealNpm() {
const fs = /* @__PURE__ */ getFs();
const path = /* @__PURE__ */ getPath();
const nodeDir = path?.dirname(process.execPath);
const npmInNodeDir = path?.join(nodeDir, "npm");
if (fs?.existsSync(npmInNodeDir)) {
return npmInNodeDir;
}
const commonPaths = ["/usr/local/bin/npm", "/usr/bin/npm"];
const result = findRealBin("npm", commonPaths);
if (result && fs?.existsSync(result)) {
return result;
}
const npmPath = whichBinSync("npm", { nothrow: true });
if (npmPath && typeof npmPath === "string" && fs?.existsSync(npmPath)) {
return npmPath;
}
return "npm";
}
function findRealPnpm() {
const path = /* @__PURE__ */ getPath();
const commonPaths = import_platform.WIN32 ? [
// Windows common paths.
path?.join((0, import_windows.getAppdata)(), "npm", "pnpm.cmd"),
path?.join((0, import_windows.getAppdata)(), "npm", "pnpm"),
path?.join((0, import_windows.getLocalappdata)(), "pnpm", "pnpm.cmd"),
path?.join((0, import_windows.getLocalappdata)(), "pnpm", "pnpm"),
"C:\\Program Files\\nodejs\\pnpm.cmd",
"C:\\Program Files\\nodejs\\pnpm"
].filter(Boolean) : [
// Unix common paths.
"/usr/local/bin/pnpm",
"/usr/bin/pnpm",
path?.join(
(0, import_xdg.getXdgDataHome)() || `${(0, import_home.getHome)()}/.local/share`,
"pnpm/pnpm"
),
path?.join((0, import_home.getHome)(), ".pnpm/pnpm")
].filter(Boolean);
return findRealBin("pnpm", commonPaths) ?? "";
}
function findRealYarn() {
const path = /* @__PURE__ */ getPath();
const commonPaths = [
"/usr/local/bin/yarn",
"/usr/bin/yarn",
path?.join((0, import_home.getHome)(), ".yarn/bin/yarn"),
path?.join(
(0, import_home.getHome)(),
".config/yarn/global/node_modules/.bin/yarn"
)
].filter(Boolean);
return findRealBin("yarn", commonPaths) ?? "";
}
// @__NO_SIDE_EFFECTS__
function resolveBinPathSync(binPath) {
const fs = /* @__PURE__ */ getFs();
const path = /* @__PURE__ */ getPath();
if (!path?.isAbsolute(binPath)) {
try {
const resolved = whichBinSync(binPath);
if (resolved) {
binPath = resolved;
}
} catch {
}
}
binPath = (0, import_path.normalizePath)(binPath);
if (binPath === ".") {
return binPath;
}
const ext = path?.extname(binPath);
const extLowered = ext.toLowerCase();
const basename = path?.basename(binPath, ext);
const voltaIndex = basename === "node" ? -1 : /(?<=\/)\.volta\//i.exec(binPath)?.index ?? -1;
if (voltaIndex !== -1) {
const voltaPath = binPath.slice(0, voltaIndex);
const voltaToolsPath = path?.join(voltaPath, "tools");
const voltaImagePath = path?.join(voltaToolsPath, "image");
const voltaUserPath = path?.join(voltaToolsPath, "user");
const voltaPlatform = (0, import_fs.readJsonSync)(
path?.join(voltaUserPath, "platform.json"),
{ throws: false }
);
const voltaNodeVersion = voltaPlatform?.node?.runtime;
const voltaNpmVersion = voltaPlatform?.node?.npm;
let voltaBinPath = "";
if (basename === "npm" || basename === "npx") {
if (voltaNpmVersion) {
const relCliPath = `bin/${basename}-cli.js`;
voltaBinPath = path?.join(
voltaImagePath,
`npm/${voltaNpmVersion}/${relCliPath}`
);
if (voltaNodeVersion && !fs?.existsSync(voltaBinPath)) {
voltaBinPath = path?.join(
voltaImagePath,
`node/${voltaNodeVersion}/lib/node_modules/npm/${relCliPath}`
);
if (!fs?.existsSync(voltaBinPath)) {
voltaBinPath = "";
}
}
}
} else {
const voltaUserBinPath = path?.join(voltaUserPath, "bin");
const binInfo = (0, import_fs.readJsonSync)(
path?.join(voltaUserBinPath, `${basename}.json`),
{ throws: false }
);
const binPackage = binInfo?.package;
if (binPackage) {
voltaBinPath = path?.join(
voltaImagePath,
`packages/${binPackage}/bin/${basename}`
);
if (!fs?.existsSync(voltaBinPath)) {
voltaBinPath = `${voltaBinPath}.cmd`;
if (!fs?.existsSync(voltaBinPath)) {
voltaBinPath = "";
}
}
}
}
if (voltaBinPath) {
try {
return (0, import_path.normalizePath)(fs?.realpathSync.native(voltaBinPath));
} catch {
}
return voltaBinPath;
}
}
if (import_platform.WIN32) {
const hasKnownExt = extLowered === "" || extLowered === ".cmd" || extLowered === ".exe" || extLowered === ".ps1";
const isNpmOrNpx = basename === "npm" || basename === "npx";
const isPnpmOrYarn = basename === "pnpm" || basename === "yarn";
if (hasKnownExt && isNpmOrNpx) {
const quickPath = path?.join(
path?.dirname(binPath),
`node_modules/npm/bin/${basename}-cli.js`
);
if (fs?.existsSync(quickPath)) {
try {
return fs?.realpathSync.native(quickPath);
} catch {
}
return quickPath;
}
}
let relPath = "";
if (hasKnownExt && // Only parse shell scripts and batch files, not actual executables.
// .exe files are already executables and don't need path resolution from wrapper scripts.
extLowered !== ".exe" && // Check if file exists before attempting to read it to avoid ENOENT errors.
fs?.existsSync(binPath)) {
const source = fs?.readFileSync(binPath, "utf8");
if (isNpmOrNpx) {
if (extLowered === ".cmd") {
relPath = basename === "npm" ? /(?<="NPM_CLI_JS=%~dp0\\).*(?=")/.exec(source)?.[0] || "" : /(?<="NPX_CLI_JS=%~dp0\\).*(?=")/.exec(source)?.[0] || "";
} else if (extLowered === "") {
relPath = basename === "npm" ? /(?<=NPM_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0] || "" : /(?<=NPX_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0] || "";
} else if (extLowered === ".ps1") {
relPath = basename === "npm" ? /(?<=\$NPM_CLI_JS="\$PSScriptRoot\/).*(?=")/.exec(
source
)?.[0] || "" : /(?<=\$NPX_CLI_JS="\$PSScriptRoot\/).*(?=")/.exec(
source
)?.[0] || "";
}
} else if (isPnpmOrYarn) {
if (extLowered === ".cmd") {
relPath = /(?<=node\s+")%~dp0\\([^"]+)(?="\s+%\*)/.exec(source)?.[1] || "";
if (!relPath) {
relPath = /(?<="%~dp0\\[^"]*node[^"]*"\s+")%~dp0\\([^"]+)(?="\s+%\*)/.exec(
source
)?.[1] || "";
}
if (!relPath) {
relPath = /(?<="%dp0%\\).*(?=" %\*\r\n)/.exec(source)?.[0] || "";
}
} else if (extLowered === "") {
relPath = /(?<="\$basedir\/)\.tools\/pnpm\/[^"]+(?="\s+"\$@")/.exec(
source
)?.[0] || "";
if (!relPath) {
relPath = /(?<=exec\s+node\s+"\$basedir\/)\.tools\/pnpm\/[^"]+(?="\s+"\$@")/.exec(
source
)?.[0] || "";
}
if (!relPath) {
relPath = /(?<="\$basedir\/).*(?=" "\$@"\n)/.exec(source)?.[0] || "";
}
} else if (extLowered === ".ps1") {
relPath = /(?<="\$basedir\/).*(?=" $args\n)/.exec(source)?.[0] || "";
}
} else if (extLowered === ".cmd") {
relPath = /(?<="%dp0%\\).*(?=" %\*\r\n)/.exec(source)?.[0] || "";
} else if (extLowered === "") {
relPath = /(?<="$basedir\/).*(?=" "\$@"\n)/.exec(source)?.[0] || "";
} else if (extLowered === ".ps1") {
relPath = /(?<="\$basedir\/).*(?=" $args\n)/.exec(source)?.[0] || "";
}
if (relPath) {
binPath = (0, import_path.normalizePath)(path?.resolve(path?.dirname(binPath), relPath));
}
}
} else {
let hasNoExt = extLowered === "";
const isPnpmOrYarn = basename === "pnpm" || basename === "yarn";
const isNpmOrNpx = basename === "npm" || basename === "npx";
if (isPnpmOrYarn && binPath.includes("/.bin/pnpm/bin/")) {
const binIndex = binPath.indexOf("/.bin/pnpm");
if (binIndex !== -1) {
const baseBinPath = binPath.slice(0, binIndex + "/.bin/pnpm".length);
try {
const stats = fs?.statSync(baseBinPath);
if (stats.isFile()) {
binPath = (0, import_path.normalizePath)(baseBinPath);
hasNoExt = !path?.extname(binPath);
}
} catch {
}
}
}
if (hasNoExt && (isPnpmOrYarn || isNpmOrNpx) && // For extensionless files (Unix shell scripts), verify existence before reading.
// This prevents ENOENT errors when the bin path doesn't exist.
fs?.existsSync(binPath)) {
const source = fs?.readFileSync(binPath, "utf8");
let relPath = "";
if (isPnpmOrYarn) {
relPath = /(?<="\$basedir\/)\.tools\/[^"]+(?="\s+"\$@")/.exec(source)?.[0] || "";
if (!relPath) {
relPath = /(?<="\$basedir\/)[^"]+(?="\s+"\$@")/.exec(source)?.[0] || "";
}
if (!relPath) {
const match = /exec\s+node\s+"?\$basedir\/([^"]+)"?\s+"\$@"/.exec(
source
);
if (match) {
relPath = match[1] || "";
}
}
if (relPath && basename === "pnpm" && relPath.startsWith("pnpm/")) {
relPath = `../${relPath}`;
}
} else if (isNpmOrNpx) {
relPath = basename === "npm" ? /(?<=NPM_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0] || "" : /(?<=NPX_CLI_JS="\$CLI_BASEDIR\/).*(?=")/.exec(source)?.[0] || "";
}
if (relPath) {
binPath = (0, import_path.normalizePath)(path?.resolve(path?.dirname(binPath), relPath));
}
}
}
try {
const realPath = fs?.realpathSync.native(binPath);
return (0, import_path.normalizePath)(realPath);
} catch {
}
return (0, import_path.normalizePath)(binPath);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
execBin,
findRealBin,
findRealNpm,
findRealPnpm,
findRealYarn,
isShadowBinPath,
resolveBinPathSync,
which,
whichBin,
whichBinSync,
whichSync
});