"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_paths_predicates = require('../paths/predicates.js');
const require_primordials_array = require('../primordials/array.js');
const require_node_fs = require('../node/fs.js');
const require_bin__internal = require('./_internal.js');
const require_bin_resolve = require('./resolve.js');
let src_external_which = require("../external/which");
src_external_which = require_runtime.__toESM(src_external_which);

//#region src/bin/which.ts
/**
* @file Look up binaries on PATH. Two pairs of public functions: `which` /
*   `whichSync` — wrap the upstream `which` package, returning the first
*   matching path (or array with `{ all: true }`). Path-like inputs (absolute
*   paths, `./relative`, `../relative`) bypass PATH resolution and pass through
*   unchanged. Both are tolerant — they return `null` for not-found instead of
*   throwing. `whichReal` / `whichRealSync` — same but resolve the result
*   through `resolveRealBinSync` so the caller gets the underlying script path
*   (e.g., `npm-cli.js`) rather than the wrapper. Default `nothrow: true` so a
*   missing binary returns `undefined` instead of bubbling a `which` package
*   error. Caching matches `_internal.binPathCache` and `binPathAllCache`. Both
*   caches validate hits with `existsSync` so a tool reinstall mid-session
*   doesn't return a stale path.
*/
/**
* Find an executable in the system PATH asynchronously.
*
* This function resolves binary names to their full paths by searching the
* system PATH. It should only be used for binary names (not paths). If the
* input is already a path (absolute or relative), it will be returned as-is
* without PATH resolution.
*
* Binary name vs. path detection:
*
* - Binary names: 'npm', 'git', 'node' - will be resolved via PATH
* - Absolute paths: '/usr/bin/node', 'C:\Program Files\nodejs\node.exe' -
*   returned as-is
* - Relative paths: './node', '../bin/npm' - returned as-is
*
* @example
*   ;```typescript
*   // Resolve binary names
*   await which('node') // '/usr/local/bin/node'
*   await which('npm') // '/usr/local/bin/npm'
*   await which('nonexistent') // null
*
*   // Paths are returned as-is
*   await which('/usr/bin/node') // '/usr/bin/node'
*   await which('./local-script') // './local-script'
*   ```
*
* @param {string} binName - The binary name to resolve (e.g., 'npm', 'git')
* @param {WhichOptions | undefined} options - Options for resolution.
*
* @returns {Promise<string | string[] | null>} Promise resolving to the full
*   path, the original path, or null if not found.
*/
async function which(binName, options) {
	if (/* @__PURE__ */ require_paths_predicates.isPath(binName)) return binName;
	try {
		return await (0, src_external_which.default)(binName, options);
	} catch {
		return null;
	}
}
/**
* Find a binary in the system PATH and resolve to the real underlying script
* asynchronously. Resolves wrapper scripts (.cmd, .ps1, shell scripts) to the
* actual .js files they execute.
*
* @example
*   ;```typescript
*   const npmPath = await whichReal('npm')
*   // e.g. '/usr/local/lib/node_modules/npm/bin/npm-cli.js'
*   ```
*
* @throws {Error} If the binary is not found and nothrow is false.
*/
async function whichReal(binName, options) {
	const fs = /* @__PURE__ */ require_node_fs.getNodeFs();
	const opts = {
		__proto__: null,
		nothrow: true,
		...options
	};
	/* c8 ignore start */
	if (opts.all) {
		const cachedAll = require_bin__internal.binPathAllCache.get(binName);
		if (cachedAll && cachedAll.length > 0) {
			if (fs.existsSync(cachedAll[0])) return cachedAll;
			require_bin__internal.binPathAllCache.delete(binName);
		}
	} else {
		const cached = require_bin__internal.binPathCache.get(binName);
		if (cached) {
			if (fs.existsSync(cached)) return cached;
			require_bin__internal.binPathCache.delete(binName);
		}
	}
	/* c8 ignore stop */
	/* c8 ignore next - External which call */
	const result = await (0, src_external_which.default)(binName, opts);
	/* c8 ignore start */
	if (opts?.all) {
		const paths = require_primordials_array.ArrayIsArray(result) ? result : typeof result === "string" ? [result] : void 0;
		if (paths?.length) {
			const resolved = require_primordials_array.ArrayPrototypeMap(paths, (p) => /* @__PURE__ */ require_bin_resolve.resolveRealBinSync(p));
			require_bin__internal.binPathAllCache.set(binName, resolved);
			return resolved;
		}
		return paths;
	}
	if (!result) return;
	/* c8 ignore stop */
	const resolved = /* @__PURE__ */ require_bin_resolve.resolveRealBinSync(result);
	require_bin__internal.binPathCache.set(binName, resolved);
	return resolved;
}
/**
* Find a binary in the system PATH and resolve to the real underlying script
* synchronously. Resolves wrapper scripts (.cmd, .ps1, shell scripts) to the
* actual .js files they execute.
*
* @example
*   ;```typescript
*   const npmPath = whichRealSync('npm')
*   // e.g. '/usr/local/lib/node_modules/npm/bin/npm-cli.js'
*   ```
*
* @throws {Error} If the binary is not found and nothrow is false.
*/
function whichRealSync(binName, options) {
	const fs = /* @__PURE__ */ require_node_fs.getNodeFs();
	const opts = {
		__proto__: null,
		nothrow: true,
		...options
	};
	/* c8 ignore start */
	if (opts.all) {
		const cachedAll = require_bin__internal.binPathAllCache.get(binName);
		if (cachedAll && cachedAll.length > 0) {
			if (fs.existsSync(cachedAll[0])) return cachedAll;
			require_bin__internal.binPathAllCache.delete(binName);
		}
	} else {
		const cached = require_bin__internal.binPathCache.get(binName);
		if (cached) {
			if (fs.existsSync(cached)) return cached;
			require_bin__internal.binPathCache.delete(binName);
		}
	}
	/* c8 ignore stop */
	const result = whichSync(binName, opts);
	/* c8 ignore start */
	if (opts.all) {
		const paths = require_primordials_array.ArrayIsArray(result) ? result : typeof result === "string" ? [result] : void 0;
		if (paths?.length) {
			const resolved = require_primordials_array.ArrayPrototypeMap(paths, (p) => /* @__PURE__ */ require_bin_resolve.resolveRealBinSync(p));
			require_bin__internal.binPathAllCache.set(binName, resolved);
			return resolved;
		}
		return paths;
	}
	if (!result) return;
	/* c8 ignore stop */
	const resolved = /* @__PURE__ */ require_bin_resolve.resolveRealBinSync(result);
	require_bin__internal.binPathCache.set(binName, resolved);
	return resolved;
}
/**
* Find an executable in the system PATH synchronously.
*
* This function resolves binary names to their full paths by searching the
* system PATH. It should only be used for binary names (not paths). If the
* input is already a path (absolute or relative), it will be returned as-is
* without PATH resolution.
*
* Binary name vs. path detection:
*
* - Binary names: 'npm', 'git', 'node' - will be resolved via PATH
* - Absolute paths: '/usr/bin/node', 'C:\Program Files\nodejs\node.exe' -
*   returned as-is
* - Relative paths: './node', '../bin/npm' - returned as-is
*
* @example
*   ;```typescript
*   // Resolve binary names
*   whichSync('node') // '/usr/local/bin/node'
*   whichSync('npm') // '/usr/local/bin/npm'
*   whichSync('nonexistent') // null
*
*   // Paths are returned as-is
*   whichSync('/usr/bin/node') // '/usr/bin/node'
*   whichSync('./local-script') // './local-script'
*   ```
*
* @param {string} binName - The binary name to resolve (e.g., 'npm', 'git')
* @param {WhichOptions | undefined} options - Options for resolution.
*
* @returns {string | string[] | null} The full path to the binary, the original
*   path if input is a path, or null if not found.
*/
function whichSync(binName, options) {
	if (/* @__PURE__ */ require_paths_predicates.isPath(binName)) return binName;
	try {
		return src_external_which.default.sync(binName, options);
	} catch {
		return null;
	}
}

//#endregion
exports.which = which;
exports.whichReal = whichReal;
exports.whichRealSync = whichRealSync;
exports.whichSync = whichSync;