"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_primordials_error = require('../primordials/error.js');
const require_constants_platform = require('../constants/platform.js');
const require_primordials_regexp = require('../primordials/regexp.js');
const require_paths_normalize = require('../paths/normalize.js');
const require_node_fs = require('../node/fs.js');
const require_node_path = require('../node/path.js');
const require_errors_predicates = require('../errors/predicates.js');
const require_process_spawn_child = require('../process/spawn/child.js');
const require_paths_socket = require('../paths/socket.js');
const require_fs_safe = require('../fs/safe.js');
const require_dlx__internal = require('./_internal.js');
const require_process_lock_instance = require('../process/lock-instance.js');
const require_dlx_cache = require('./cache.js');
const require_dlx_binary_resolution = require('./binary-resolution.js');
const require_dlx_firewall = require('./firewall.js');
const require_dlx_spec = require('./spec.js');
let src_external__npmcli_arborist = require("../external/@npmcli/arborist");
src_external__npmcli_arborist = require_runtime.__toESM(src_external__npmcli_arborist);

//#region src/dlx/package.ts
/**
* @file DLX package execution — install and execute npm packages. This module
*   provides functionality to install and execute npm packages in the
*   ~/.socket/_dlx directory, similar to npx but with Socket's own cache. Uses
*   content-addressed storage like npm's _npx:
*
*   - Hash is generated from package spec (name@version)
*   - Each unique spec gets its own directory: ~/.socket/_dlx/<hash>/
*   - Allows caching multiple versions of the same package Concurrency
*     protection:
*   - Uses process-lock to prevent concurrent installation corruption
*   - Lock file created at ~/.socket/_dlx/<hash>/concurrency.lock
*   - Uses npm npx's concurrency.lock naming convention (5s stale, 2s touching)
*   - Prevents multiple processes from corrupting the same package installation
*     Version range handling:
*   - Exact versions (1.0.0) use cache if available
*   - Range versions (^1.0.0, ~1.0.0) auto-force to get latest within range
*   - User can override with explicit force: false Key difference from
*     dlx/binary.ts:
*   - dlx/binary.ts: Downloads standalone binaries from URLs
*   - dlx/package.ts: Installs npm packages from registries Implementation:
*   - Uses Arborist for package installation (like npx, no npm CLI required)
*   - Split into downloadPackage() and executePackage() for flexibility
*   - dlxPackage() combines both for convenience Module shape: this file holds
*     the three async orchestrators (`dlxPackage`, `downloadPackage`,
*     `ensurePackageInstalled`) and the synchronous `executePackage`. The
*     supporting surface lives in sibling leaves and is re-exported here so
*     existing `dlx/package` importers keep working unchanged:
*   - types — `./types`
*   - PURL + firewall — `./firewall`
*   - spec parsing — `./spec`
*   - binary resolution — `./binary-resolution`
*   - lazy `node:fs` / `node:path` + LRU cache — `./_internal`
*/
/**
* Regex to check if a version string contains range operators. Matches any
* version with range operators: ~, ^, >, <, =, x, X, *, spaces, or ||.
*/
const rangeOperatorsRegExp = /[~^><=xX* ]|\|\|/;
/**
* Execute a package via DLX - install if needed and run its binary.
*
* This is the Socket equivalent of npx/pnpm dlx/yarn dlx, but using our own
* cache directory (~/.socket/_dlx) and installation logic.
*
* Auto-forces reinstall for version ranges to get latest within range.
*
* @example
*   ;```typescript
*   // Download and execute cdxgen
*   const result = await dlxPackage(['--version'], {
*     package: '@cyclonedx/cdxgen@10.0.0',
*   })
*   await result.spawnPromise
*   ```
*/
async function dlxPackage(args, options, spawnExtra) {
	const downloadResult = await downloadPackage(options);
	const spawnPromise = executePackage(downloadResult.binaryPath, args, options.spawnOptions, spawnExtra);
	return {
		...downloadResult,
		spawnPromise
	};
}
/**
* Download and install a package without executing it. This is useful for
* self-update or when you need the package files but don't want to run the
* binary immediately.
*
* @example
*   ;```typescript
*   // Install @socketsecurity/cli without running it
*   const result = await downloadPackage({
*     package: '@socketsecurity/cli@1.2.0',
*     force: true,
*   })
*   console.log('Installed to:', result.packageDir)
*   console.log('Binary at:', result.binaryPath)
*   ```
*/
async function downloadPackage(options) {
	const { binaryName, force: userForce, hash, installRoot, lockfile, package: packageSpec, yes } = {
		__proto__: null,
		...options
	};
	const { name: packageName, version: packageVersion } = require_dlx_spec.parsePackageSpec(packageSpec);
	const isVersionRange = packageVersion !== void 0 && require_primordials_regexp.RegExpPrototypeTest(rangeOperatorsRegExp, packageVersion);
	const force = userForce !== void 0 ? userForce : yes === true ? true : isVersionRange;
	const { installed, packageDir } = await ensurePackageInstalled(packageName, packageVersion ? `${packageName}@${packageVersion}` : packageName, force, {
		hash,
		installRoot,
		lockfile
	});
	const binaryPath = require_dlx_binary_resolution.findBinaryPath(packageDir, packageName, binaryName);
	require_dlx_binary_resolution.makePackageBinsExecutable(packageDir, packageName);
	return {
		binaryPath,
		installed,
		packageDir
	};
}
/**
* Install package to ~/.socket/_dlx/<hash>/ if not already installed. Uses
* pacote for installation (no npm CLI required). Protected by process lock to
* prevent concurrent installation corruption.
*
* @example
*   ```typescript
*   const { installed, packageDir } = await ensurePackageInstalled(
*   'prettier',
*   'prettier@3.0.0',
*   false,
*   )
*   console.log(`Installed: ${installed}, dir: ${packageDir}`)
*   ```
*/
async function ensurePackageInstalled(packageName, packageSpec, force, install) {
	const fs = /* @__PURE__ */ require_node_fs.getNodeFs();
	const path = /* @__PURE__ */ require_node_path.getNodePath();
	const packageDir = /* @__PURE__ */ require_paths_normalize.normalizePath(install?.installRoot ?? path.join(require_paths_socket.getSocketDlxDir(), require_dlx_cache.generateCacheKey(packageSpec)));
	const installedDir = /* @__PURE__ */ require_paths_normalize.normalizePath(path.join(packageDir, "node_modules", packageName));
	try {
		await require_fs_safe.safeMkdir(packageDir);
	} catch (e) {
		const code = e.code;
		if (code === "EACCES" || code === "EPERM") throw new require_primordials_error.ErrorCtor(`Permission denied creating package directory: ${packageDir}\nPlease check directory permissions or run with appropriate access.`, { cause: e });
		if (code === "EROFS") throw new require_primordials_error.ErrorCtor(`Cannot create package directory on read-only filesystem: ${packageDir}\nEnsure the filesystem is writable or set SOCKET_DLX_DIR to a writable location.`, { cause: e });
		throw new require_primordials_error.ErrorCtor(`Failed to create package directory: ${packageDir}`, { cause: e });
	}
	const lockPath = path.join(packageDir, "concurrency.lock");
	return await require_process_lock_instance.processLock.withLock(lockPath, async () => {
		if (!force && fs.existsSync(installedDir)) {
			const pkgJsonPath = path.join(installedDir, "package.json");
			if (fs.existsSync(pkgJsonPath)) return {
				installed: false,
				packageDir
			};
		}
		if (install?.lockfile !== void 0) {
			const spec = install.lockfile;
			const lockDest = path.join(packageDir, "package-lock.json");
			let isContent;
			let value;
			if (typeof spec === "string") {
				isContent = spec.trimStart().startsWith("{");
				value = spec;
			} else {
				isContent = spec.type === "content";
				value = spec.value;
			}
			if (isContent) fs.writeFileSync(lockDest, value, "utf8");
			else fs.copyFileSync(value, lockDest);
			fs.writeFileSync(path.join(packageDir, ".npmrc"), "ignore-scripts=true\naudit=false\nfund=false\nsave=false\n", "utf8");
		}
		try {
			/* c8 ignore start */
			const arb = new src_external__npmcli_arborist.default({
				path: packageDir,
				/* c8 ignore stop */
				cache: require_paths_socket.getSocketCacacheDir(),
				omit: ["dev"],
				ignoreScripts: true,
				binLinks: true,
				fund: false,
				audit: false,
				silent: true
			});
			/* c8 ignore next - External Arborist call */
			await arb.buildIdealTree({ add: [packageSpec] });
			/* c8 ignore next - External API call */
			await require_dlx_firewall.checkFirewallPurls(arb, packageName);
			/* c8 ignore next - External Arborist call */
			await arb.reify({ save: true });
		} catch (e) {
			if (require_errors_predicates.isError(e) && e.message.startsWith("Socket Firewall blocked")) throw e;
			const code = e?.code;
			if (code === "E404" || code === "ETARGET") throw new require_primordials_error.ErrorCtor(`Package not found: ${packageSpec}\nVerify the package exists on npm registry and check the version.
Visit https://www.npmjs.com/package/${packageName} to see available versions.`, { cause: e });
			if (code === "ENOTFOUND" || code === "ETIMEDOUT" || code === "EAI_AGAIN") throw new require_primordials_error.ErrorCtor(`Network error installing ${packageSpec}\nCheck your internet connection and try again.`, { cause: e });
			throw new require_primordials_error.ErrorCtor(`Failed to install package: ${packageSpec}\nDestination: ${installedDir}\nCheck npm registry connectivity or package name.`, { cause: e });
		}
		return {
			installed: true,
			packageDir
		};
	}, {
		staleMs: 5e3,
		touchIntervalMs: 2e3
	});
}
/**
* Execute a package's binary with cross-platform shell handling. The package
* must already be installed (use downloadPackage first).
*
* On Windows, script files (.bat, .cmd, .ps1) require shell: true. Matches
* npm/npx execution behavior.
*
* @example
*   ;```typescript
*   // Execute an already-installed package
*   const downloaded = await downloadPackage({ package: 'cowsay@1.5.0' })
*   const result = await executePackage(
*     downloaded.binaryPath,
*     ['Hello World'],
*     { stdio: 'inherit' },
*   )
*   ```
*/
function executePackage(binaryPath, args, spawnOptions, spawnExtra) {
	return require_process_spawn_child.spawn(binaryPath, args, require_constants_platform.WIN32 && /\.(?:bat|cmd|ps1)$/i.test(binaryPath) ? {
		...spawnOptions,
		shell: true
	} : spawnOptions, spawnExtra);
}

//#endregion
exports.binaryPathCacheSet = require_dlx__internal.binaryPathCacheSet;
exports.checkFirewallPurls = require_dlx_firewall.checkFirewallPurls;
exports.dlxPackage = dlxPackage;
exports.downloadPackage = downloadPackage;
exports.ensurePackageInstalled = ensurePackageInstalled;
exports.executePackage = executePackage;
exports.findBinaryPath = require_dlx_binary_resolution.findBinaryPath;
exports.makePackageBinsExecutable = require_dlx_binary_resolution.makePackageBinsExecutable;
exports.npmPurl = require_dlx_firewall.npmPurl;
exports.parsePackageSpec = require_dlx_spec.parsePackageSpec;
exports.resolveBinaryPath = require_dlx_binary_resolution.resolveBinaryPath;