"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_string = require('../primordials/string.js');
const require_fs_read_json = require('../fs/read-json.js');
const require_process_abort = require('../process/abort.js');
const require_objects_predicates = require('../objects/predicates.js');
const require_objects_mutate = require('../objects/mutate.js');
const require_constants_socket = require('../constants/socket.js');
const require_constants_packages = require('../constants/packages.js');
const require_smol_purl = require('../smol/purl.js');
const require_packages_normalize = require('./normalize.js');
const require_paths_packages = require('../paths/packages.js');
const require_packages_specs = require('./specs.js');
const require_packages_edit = require('./edit.js');
let src_external_cacache = require("../external/cacache");
src_external_cacache = require_runtime.__toESM(src_external_cacache);
let src_external_semver = require("../external/semver");
src_external_semver = require_runtime.__toESM(src_external_semver);
let src_external_pacote = require("../external/pacote");
src_external_pacote = require_runtime.__toESM(src_external_pacote);
let src_external_libnpmpack = require("../external/libnpmpack");
src_external_libnpmpack = require_runtime.__toESM(src_external_libnpmpack);
let src_external_make_fetch_happen = require("../external/make-fetch-happen");
src_external_make_fetch_happen = require_runtime.__toESM(src_external_make_fetch_happen);
let src_external_npm_package_arg = require("../external/npm-package-arg");
src_external_npm_package_arg = require_runtime.__toESM(src_external_npm_package_arg);
let src_external__socketregistry_packageurl_js = require("../external/@socketregistry/packageurl-js");

//#region src/packages/operations.ts
/**
* @file Package operations including extraction, packing, and I/O.
*/
const abortSignal = require_process_abort.getAbortSignal();
const packageExtensions = /* @__PURE__ */ require_constants_packages.getPackageExtensions();
const packumentCache = /* @__PURE__ */ require_constants_packages.getPackumentCache();
const pacoteCachePath = /* @__PURE__ */ require_constants_packages.getPacoteCachePath();
let _fetcher;
/**
* Extract a package to a destination directory.
*
* @example
*   ;```typescript
*   await extractPackage('lodash@4.17.21', { dest: '/tmp/lodash' })
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
async function extractPackage(pkgNameOrId, options, callback) {
	let actualCallback = callback;
	let actualOptions = options;
	if (arguments.length === 2 && typeof options === "function") {
		actualCallback = options;
		actualOptions = void 0;
	}
	const { dest, tmpPrefix, ...extractOptions_ } = {
		__proto__: null,
		...actualOptions
	};
	const extractOptions = {
		packumentCache,
		preferOffline: true,
		...extractOptions_
	};
	/* c8 ignore start - External package registry extraction */
	if (typeof dest === "string") {
		await src_external_pacote.default.extract(pkgNameOrId, dest, extractOptions);
		if (typeof actualCallback === "function") await actualCallback(dest);
	} else await src_external_cacache.default.tmp.withTmp(pacoteCachePath, { tmpPrefix }, async (tmpDirPath) => {
		await src_external_pacote.default.extract(pkgNameOrId, tmpDirPath, extractOptions);
		if (typeof actualCallback === "function") await actualCallback(tmpDirPath);
	});
	/* c8 ignore stop */
}
/**
* Find package extensions for a given package.
*
* @example
*   ;```typescript
*   const extensions = findPackageExtensions('my-pkg', '1.0.0')
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function findPackageExtensions(pkgName, pkgVer) {
	let result;
	for (const entry of packageExtensions) {
		const selector = String(entry[0]);
		const ext = entry[1];
		const lastAtSignIndex = selector.lastIndexOf("@");
		if (pkgName === selector.slice(0, lastAtSignIndex)) {
			const range = selector.slice(lastAtSignIndex + 1);
			if (src_external_semver.satisfies(pkgVer, range)) {
				if (result === void 0) result = {};
				if (typeof ext === "object" && ext !== null) /* @__PURE__ */ require_objects_mutate.merge(result, ext);
			}
		}
	}
	return result;
}
function getFetcher() {
	if (_fetcher === void 0) _fetcher = src_external_make_fetch_happen.default.defaults({
		cachePath: pacoteCachePath,
		cache: "force-cache"
	});
	return _fetcher;
}
/**
* Get the release tag for a version.
*
* @example
*   ;```typescript
*   getReleaseTag('lodash@latest') // 'latest'
*   getReleaseTag('@scope/pkg@beta') // 'beta'
*   getReleaseTag('lodash') // ''
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function getReleaseTag(spec) {
	if (!spec) return "";
	let atIndex = -1;
	if (require_primordials_string.StringPrototypeStartsWith(spec, "@")) atIndex = require_primordials_string.StringPrototypeIndexOf(spec, "@", 1);
	else atIndex = require_primordials_string.StringPrototypeIndexOf(spec, "@");
	if (atIndex !== -1) return require_primordials_string.StringPrototypeSlice(spec, atIndex + 1);
	return "";
}
/**
* Pack a package tarball using pacote.
*
* @example
*   ;```typescript
*   const tarball = await packPackage('lodash@4.17.21')
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
async function packPackage(spec, options) {
	/* c8 ignore start - External package registry packing */
	return await (0, src_external_libnpmpack.default)(spec, {
		__proto__: null,
		signal: abortSignal,
		...options,
		packumentCache,
		preferOffline: true
	});
	/* c8 ignore stop */
}
/**
* Slugify an npm package name into a hyphenated identifier suitable for
* User-Agent tokens, log namespaces, file paths, and other contexts where `@`
* and `/` are not welcome.
*
* @example
*   ;```typescript
*   pkgNameToSlug('@socketsecurity/lib') // 'socketsecurity-lib'
*   pkgNameToSlug('@cyclonedx/cdxgen') // 'cyclonedx-cdxgen'
*   pkgNameToSlug('lodash') // 'lodash'
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function pkgNameToSlug(pkgName) {
	return require_primordials_string.StringPrototypeCharCodeAt(pkgName, 0) === 64 ? `${pkgName.slice(1).replace("/", "-")}` : pkgName;
}
/**
* Read and parse a package.json file asynchronously.
*
* @example
*   ;```typescript
*   const pkgJson = await readPackageJson('/tmp/my-project')
*   console.log(pkgJson?.name)
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
async function readPackageJson(filepath, options) {
	const { editable, normalize, throws, ...normalizeOptions } = {
		__proto__: null,
		...options
	};
	const pkgJson = await /* @__PURE__ */ require_fs_read_json.readJson(/* @__PURE__ */ require_paths_packages.resolvePackageJsonPath(filepath), { throws });
	if (pkgJson) {
		if (editable) return await /* @__PURE__ */ require_packages_edit.toEditablePackageJson(pkgJson, {
			path: filepath,
			normalize,
			...normalizeOptions
		});
		return normalize ? /* @__PURE__ */ require_packages_normalize.normalizePackageJson(pkgJson, normalizeOptions) : pkgJson;
	}
}
/**
* Read and parse package.json from a file path synchronously.
*
* @example
*   ;```typescript
*   const pkgJson = readPackageJsonSync('/tmp/my-project')
*   console.log(pkgJson?.name)
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function readPackageJsonSync(filepath, options) {
	const { editable, normalize, throws, ...normalizeOptions } = {
		__proto__: null,
		...options
	};
	const pkgJson = /* @__PURE__ */ require_fs_read_json.readJsonSync(/* @__PURE__ */ require_paths_packages.resolvePackageJsonPath(filepath), { throws });
	if (pkgJson) {
		if (editable) return /* @__PURE__ */ require_packages_edit.toEditablePackageJsonSync(pkgJson, {
			path: filepath,
			normalize,
			...normalizeOptions
		});
		return normalize ? /* @__PURE__ */ require_packages_normalize.normalizePackageJson(pkgJson, normalizeOptions) : pkgJson;
	}
}
/**
* Resolve GitHub tarball URL for a package specifier.
*
* @example
*   ;```typescript
*   const url = await resolveGitHubTgzUrl('my-pkg@1.0.0', '/tmp/my-project')
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
async function resolveGitHubTgzUrl(pkgNameOrId, where) {
	const whereIsPkgJson = /* @__PURE__ */ require_objects_predicates.isPlainObject(where);
	const pkgJson = whereIsPkgJson ? where : await /* @__PURE__ */ readPackageJson(where, { normalize: true });
	if (!pkgJson) return "";
	const { version } = pkgJson;
	const parsedSpec = (0, src_external_npm_package_arg.default)(pkgNameOrId, whereIsPkgJson ? void 0 : where);
	if (/* @__PURE__ */ require_packages_specs.isGitHubTgzSpec(parsedSpec)) return parsedSpec.saveSpec || "";
	const isGitHubUrl = /* @__PURE__ */ require_packages_specs.isGitHubUrlSpec(parsedSpec);
	const repository = pkgJson.repository;
	const { project, user } = (isGitHubUrl ? parsedSpec.hosted : /* @__PURE__ */ require_packages_specs.getRepoUrlDetails(repository?.url)) || {
		project: "",
		user: ""
	};
	/* c8 ignore start - External GitHub API calls */
	if (user && project) {
		const fetcher = getFetcher();
		let apiUrl = "";
		if (isGitHubUrl) apiUrl = /* @__PURE__ */ require_packages_specs.gitHubTagRefUrl(user, project, parsedSpec.gitCommittish || "");
		else {
			const versionStr = version;
			apiUrl = /* @__PURE__ */ require_packages_specs.gitHubTagRefUrl(user, project, `v${versionStr}`);
			if (!(await fetcher(apiUrl, { method: "head" })).ok) {
				apiUrl = /* @__PURE__ */ require_packages_specs.gitHubTagRefUrl(user, project, versionStr);
				if (!(await fetcher(apiUrl, { method: "head" })).ok) apiUrl = "";
			}
		}
		if (apiUrl) {
			const resp = await fetcher(apiUrl);
			let json;
			try {
				json = await resp.json();
			} catch {
				json = void 0;
			}
			const sha = json?.object?.sha;
			if (sha) return /* @__PURE__ */ require_packages_specs.gitHubTgzUrl(user, project, sha);
		}
	}
	/* c8 ignore stop */
	return "";
}
/**
* Resolve full package name from a PURL object with custom delimiter.
*
* @example
*   ;```typescript
*   resolvePackageName({ name: 'core', namespace: '@babel' }) // '@babel/core'
*   resolvePackageName({ name: 'lodash' }) // 'lodash'
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function resolvePackageName(purlObj, delimiter = "/") {
	const { name, namespace } = purlObj;
	return `${namespace ? `${namespace}${delimiter}` : ""}${name}`;
}
/**
* Convert npm package name to Socket registry format with delimiter.
*
* @example
*   ;```typescript
*   resolveRegistryPackageName('@babel/core') // 'babel__core'
*   resolveRegistryPackageName('lodash') // 'lodash'
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function resolveRegistryPackageName(pkgName) {
	const input = `pkg:npm/${pkgName}`;
	const smolPurl = /* @__PURE__ */ require_smol_purl.getSmolPurl();
	const purlObj = smolPurl ? smolPurl.parse(input) : src_external__socketregistry_packageurl_js.PackageURL.fromString(input);
	return purlObj.namespace ? `${purlObj.namespace.slice(1)}${"__"}${purlObj.name}` : pkgName;
}

//#endregion
exports.extractPackage = extractPackage;
exports.findPackageExtensions = findPackageExtensions;
exports.getFetcher = getFetcher;
exports.getReleaseTag = getReleaseTag;
exports.packPackage = packPackage;
exports.pkgNameToSlug = pkgNameToSlug;
exports.readPackageJson = readPackageJson;
exports.readPackageJsonSync = readPackageJsonSync;
exports.resolveGitHubTgzUrl = resolveGitHubTgzUrl;
exports.resolvePackageName = resolvePackageName;
exports.resolveRegistryPackageName = resolveRegistryPackageName;