"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_primordials_string = require('../../../primordials/string.js');
const require_primordials_regexp = require('../../../primordials/regexp.js');
const require_primordials_array = require('../../../primordials/array.js');
const require_primordials_object = require('../../../primordials/object.js');
const require_smol_manifest = require('../../../smol/manifest.js');
const require_eco_npm_pnpm_detect_pnpm_version = require('./detect-pnpm-version.js');
const require_eco_npm_pnpm_parse_pnpm_package_id_v5 = require('./parse-pnpm-package-id-v5.js');
const require_eco_npm_pnpm_parse_pnpm_package_id_v6_v9 = require('./parse-pnpm-package-id-v6-v9.js');

//#region src/eco/npm/pnpm/parse-lockfile.ts
/**
* @file `parsePnpmLock(content)` — parses a `pnpm-lock.yaml` (v5, v6, or v9)
*   into a `ParsedLockfile`. On socket-btm's smol Node binary this routes to
*   `node:smol-manifest`'s native `parseLockfile(content, 'npm', 'pnpm')`; on
*   stock Node it runs the line-scanning JS impl below. The parser supports
*   three top-level sections:
*
*   - `packages:` — pnpm v5/v6 main package entries
*   - `snapshots:` — pnpm v9 main package entries
*   - `importers:` — workspace/monorepo dependency declarations (extracted as
*     ad-hoc package entries so SBOM tooling sees the workspace's own deps even
*     when no `packages:` block lists them) Forgiving by design — unknown keys
*     ignored, missing versions default to `0.0.0`. Never throws. Source
*     material (in lock-step order, newest → oldest):
*
*   1. **C++ native parser** in socket-btm/node-smol-builder:
*      additions/source-patched/src/socketsecurity/manifest/parser_pnpm.cc Same
*      algorithm, same fixes — keep the two in lock-step.
*   2. **socket-sdxgen** — algorithm oracle:
*      socket-sdxgen/src/parsers/pnpm/pnpm-lock-v5.mts
*      socket-sdxgen/src/parsers/pnpm/pnpm-lock-v6.mts
*      socket-sdxgen/src/parsers/pnpm/pnpm-lock-v9.mts
*   3. **cdxgen** (pinned v11.11.0):
*      https://github.com/CycloneDX/cdxgen/blob/v11.11.0/lib/parsers/js.js
*      (parsePnpmLock)
*   4. **pnpm lockfile spec** + reference implementation:
*      https://github.com/pnpm/spec/blob/master/lockfile/9.0.md
*      https://github.com/pnpm/pnpm/blob/main/packages/lockfile-file/ Bug fixes
*      implemented here (and in the native parser):
*
*   - Fix 3a Empty-version guard in importer block-shape walk — v9
*     nested-property entries (`pkg:` parent + indented `version:` child) no
*     longer emit a phantom parent PackageRef with `version: ''`.
*   - Fix 3b workspace/file/link protocol filter — importer deps with
*     `workspace:` / `file:` / `link:` values are workspace-local refs, not
*     shippable registry artifacts.
*   - Fix 5 pnpm v9 isDev derivation from importer prod/devOnly sets, post-pass
*     classified. The v9 format dropped per- snapshot `dev: true` markers, so
*     isDev must be derived from importers. Prior impls left every v9 snapshot
*     as `depType: 'prod'`. Regression fixtures live under socket-btm's
*     test/fixtures/ sdxgen-bug-regressions/ — every shipped fix has a matching
*     fixture directory there.
*/
const RE_INTEGRITY = /integrity:\s*([a-zA-Z0-9+/=-]+)/;
const RE_TARBALL = /tarball:\s*['"]?([^'"}\s]+)['"]?/;
function addToPnpmIndex(packageIndex, name, idx) {
	const existing = packageIndex[name];
	if (existing === void 0) packageIndex[name] = idx;
	else if (typeof existing === "number") packageIndex[name] = [existing, idx];
	else require_primordials_array.ArrayPrototypePush(existing, idx);
}
function freezeEntry(entry) {
	const { _inDeps, ...rest } = entry;
	return require_primordials_object.ObjectFreeze({
		__proto__: null,
		...rest
	});
}
function indentOf(line) {
	let indent = 0;
	while (indent < line.length && (line[indent] === " " || line[indent] === "	")) indent++;
	return indent;
}
function jsParsePnpmLock(content) {
	const packages = [];
	const packageIndex = { __proto__: null };
	const lockVersion = require_eco_npm_pnpm_detect_pnpm_version.detectPnpmVersion(content);
	let inPackages = false;
	let inSnapshots = false;
	let inImporters = false;
	let currentPkg;
	let currentIndent = 0;
	let currentImporter;
	let importerIndent = 0;
	let pos = 0;
	while (pos < content.length) {
		const eol = require_primordials_string.StringPrototypeIndexOf(content, "\n", pos);
		const end = eol === -1 ? content.length : eol;
		const line = require_primordials_string.StringPrototypeSlice(content, pos, end);
		pos = end + 1;
		const trimmed = require_primordials_string.StringPrototypeTrim(line);
		if (trimmed === "packages:") {
			inPackages = true;
			inSnapshots = false;
			inImporters = false;
			continue;
		}
		if (trimmed === "snapshots:") {
			inSnapshots = true;
			inPackages = false;
			inImporters = false;
			continue;
		}
		if (trimmed === "importers:") {
			inImporters = true;
			inPackages = false;
			inSnapshots = false;
			continue;
		}
		if (line[0] !== " " && line[0] !== "	" && trimmed.length > 0 && trimmed !== "packages:" && trimmed !== "snapshots:" && trimmed !== "importers:") {
			inPackages = false;
			inSnapshots = false;
			inImporters = false;
			continue;
		}
		if (inImporters) {
			const indent = indentOf(line);
			if (indent === 2 && require_primordials_string.StringPrototypeEndsWith(trimmed, ":")) {
				currentImporter = { section: void 0 };
				importerIndent = indent;
				continue;
			}
			if (currentImporter && indent > importerIndent) {
				if (require_primordials_string.StringPrototypeIndexOf(trimmed, "devDependencies:") === 0) currentImporter.section = "dev";
				else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "optionalDependencies:") === 0) currentImporter.section = "optional";
				else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "dependencies:") === 0) currentImporter.section = "prod";
				else if (indent > importerIndent + 2) {
					if (require_primordials_string.StringPrototypeIndexOf(trimmed, "specifier:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "version:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "resolution:") === 0) continue;
					const colonIdx = require_primordials_string.StringPrototypeIndexOf(trimmed, ":");
					if (colonIdx > 0) {
						const depName = require_primordials_string.StringPrototypeSlice(trimmed, 0, colonIdx);
						const depVersion = require_primordials_string.StringPrototypeTrim(require_primordials_string.StringPrototypeSlice(trimmed, colonIdx + 1));
						if (depVersion.length === 0 || require_primordials_string.StringPrototypeIndexOf(depVersion, "link:") === 0 || require_primordials_string.StringPrototypeIndexOf(depVersion, "workspace:") === 0 || require_primordials_string.StringPrototypeIndexOf(depVersion, "file:") === 0) continue;
						const versionWithoutPeer = stripPeerSuffix(depVersion);
						if (packageIndex[depName] === void 0) {
							const section = currentImporter.section;
							require_primordials_array.ArrayPrototypePush(packages, require_primordials_object.ObjectFreeze({
								__proto__: null,
								name: depName,
								version: versionWithoutPeer,
								resolved: void 0,
								integrity: void 0,
								ecosystem: "npm",
								depType: section === "dev" ? "dev" : section === "optional" ? "optional" : "prod",
								isDev: section === "dev",
								isOptional: section === "optional",
								isPeer: false,
								isBundled: false,
								vcsUrl: void 0,
								vcsCommit: void 0,
								dependencies: []
							}));
							packageIndex[depName] = packages.length - 1;
						}
					}
				}
			}
			continue;
		}
		if (!inPackages && !inSnapshots) continue;
		const indent = indentOf(line);
		if (indent >= 2 && indent <= 4 && require_primordials_string.StringPrototypeEndsWith(trimmed, ":") && trimmed.length > 1 && (currentPkg === void 0 || indent <= currentIndent)) {
			if (currentPkg && currentPkg.name) {
				require_primordials_array.ArrayPrototypePush(packages, freezeEntry(currentPkg));
				addToPnpmIndex(packageIndex, currentPkg.name, packages.length - 1);
			}
			const key = require_primordials_string.StringPrototypeSlice(trimmed, 0, -1);
			const parsed = key[0] === "/" ? require_eco_npm_pnpm_parse_pnpm_package_id_v5.parsePnpmPackageIdV5(key) : require_eco_npm_pnpm_parse_pnpm_package_id_v6_v9.parsePnpmPackageIdV6V9(key);
			currentPkg = newPnpmEntry(parsed.name, parsed.version);
			currentIndent = indent;
			continue;
		}
		if (currentPkg && indent > currentIndent) {
			if (require_primordials_string.StringPrototypeIndexOf(trimmed, "dev:") === 0) {
				if (require_primordials_string.StringPrototypeIndexOf(trimmed, "true") !== -1) {
					currentPkg.depType = "dev";
					currentPkg.isDev = true;
				}
			} else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "optional:") === 0) {
				if (require_primordials_string.StringPrototypeIndexOf(trimmed, "true") !== -1) {
					currentPkg.depType = "optional";
					currentPkg.isOptional = true;
				}
			} else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "integrity:") === 0) currentPkg.integrity = require_primordials_string.StringPrototypeTrim(require_primordials_string.StringPrototypeSlice(trimmed, 10));
			else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "resolution:") === 0) {
				const intMatch = require_primordials_regexp.RegExpPrototypeExec(RE_INTEGRITY, trimmed);
				if (intMatch) currentPkg.integrity = intMatch[1];
				const tarballMatch = require_primordials_regexp.RegExpPrototypeExec(RE_TARBALL, trimmed);
				if (tarballMatch) currentPkg.resolved = tarballMatch[1];
			} else if (require_primordials_string.StringPrototypeIndexOf(trimmed, "dependencies:") === 0) {
				currentPkg.dependencies = [];
				currentPkg._inDeps = true;
			} else if (currentPkg._inDeps && (require_primordials_string.StringPrototypeIndexOf(trimmed, "peerDependencies:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "optionalDependencies:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "engines:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "os:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "cpu:") === 0 || require_primordials_string.StringPrototypeIndexOf(trimmed, "bin:") === 0)) currentPkg._inDeps = false;
			else if (currentPkg._inDeps && indent > currentIndent + 2) {
				const colonIdx = require_primordials_string.StringPrototypeIndexOf(trimmed, ":");
				if (colonIdx > 0) require_primordials_array.ArrayPrototypePush(currentPkg.dependencies, require_primordials_string.StringPrototypeSlice(trimmed, 0, colonIdx));
			}
		}
	}
	if (currentPkg && currentPkg.name) {
		require_primordials_array.ArrayPrototypePush(packages, freezeEntry(currentPkg));
		addToPnpmIndex(packageIndex, currentPkg.name, packages.length - 1);
	}
	return require_primordials_object.ObjectFreeze({
		__proto__: null,
		type: "lockfile",
		lockVersion: String(lockVersion),
		ecosystem: "npm",
		packages: require_primordials_object.ObjectFreeze(packages),
		_index: packageIndex
	});
}
function newPnpmEntry(name, version) {
	return {
		name,
		version,
		resolved: void 0,
		integrity: void 0,
		ecosystem: "npm",
		depType: "prod",
		isDev: false,
		isOptional: false,
		isPeer: false,
		isBundled: false,
		vcsUrl: void 0,
		vcsCommit: void 0,
		dependencies: [],
		_inDeps: false
	};
}
function stripPeerSuffix(version) {
	const underIdx = require_primordials_string.StringPrototypeIndexOf(version, "_");
	const noUnderscore = underIdx !== -1 ? require_primordials_string.StringPrototypeSlice(version, 0, underIdx) : version;
	const parenIdx = require_primordials_string.StringPrototypeIndexOf(noUnderscore, "(");
	return parenIdx !== -1 ? require_primordials_string.StringPrototypeSlice(noUnderscore, 0, parenIdx) : noUnderscore;
}
const _smol = /* @__PURE__ */ require_smol_manifest.getSmolManifest();
const parsePnpmLock = _smol ? (content) => _smol.parseLockfile(content, "npm", "pnpm") : jsParsePnpmLock;

//#endregion
exports.addToPnpmIndex = addToPnpmIndex;
exports.freezeEntry = freezeEntry;
exports.indentOf = indentOf;
exports.jsParsePnpmLock = jsParsePnpmLock;
exports.newPnpmEntry = newPnpmEntry;
exports.parsePnpmLock = parsePnpmLock;
exports.stripPeerSuffix = stripPeerSuffix;