UNPKG

@socketsecurity/lib

Version:

Core utilities and infrastructure for Socket.dev security tools

426 lines (425 loc) 15.2 kB
"use strict"; /* 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 });