"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_primordials_regexp = require('../primordials/regexp.js');
const require_paths_normalize = require('../paths/normalize.js');
const require_primordials_map_set = require('../primordials/map-set.js');
const require_node_path = require('../node/path.js');
const require_constants_sentinels = require('../constants/sentinels.js');
const require_objects_predicates = require('../objects/predicates.js');
const require_constants_licenses = require('../constants/licenses.js');
let src_external_spdx_correct = require("../external/spdx-correct");
src_external_spdx_correct = require_runtime.__toESM(src_external_spdx_correct);
let src_external_spdx_expression_parse = require("../external/spdx-expression-parse");
src_external_spdx_expression_parse = require_runtime.__toESM(src_external_spdx_expression_parse);

//#region src/packages/licenses.ts
/**
* @file SPDX license parsing and analysis utilities.
*/
const copyLeftLicenses = require_constants_licenses.getCopyLeftLicenses();
const BINARY_OPERATION_NODE_TYPE = "BinaryOperation";
const LICENSE_NODE_TYPE = "License";
const fileReferenceRegExp = /^SEE LICEN[CS]E IN (.+)$/;
/**
* Collect licenses that are incompatible (copyleft).
*
* @example
*   ;```typescript
*   const nodes = [{ license: 'MIT' }, { license: 'GPL-3.0' }]
*   const incompatible = collectIncompatibleLicenses(nodes)
*   // incompatible contains only the GPL-3.0 node
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function collectIncompatibleLicenses(licenseNodes) {
	const result = [];
	for (let i = 0, { length } = licenseNodes; i < length; i += 1) {
		const node = licenseNodes[i];
		if (node && copyLeftLicenses.has(node.license)) result.push(node);
	}
	return result;
}
/**
* Collect warnings from license nodes.
*
* @example
*   ;```typescript
*   const nodes = [{ license: 'UNLICENSED' }]
*   collectLicenseWarnings(nodes) // ['Package is unlicensed']
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function collectLicenseWarnings(licenseNodes) {
	const warnings = new require_primordials_map_set.MapCtor();
	for (let i = 0, { length } = licenseNodes; i < length; i += 1) {
		const node = licenseNodes[i];
		if (!node) continue;
		const { license } = node;
		if (license === "UNLICENSED") warnings.set("UNLICENSED", "Package is unlicensed");
		else if (node.inFile !== void 0) warnings.set("IN_FILE", `License terms specified in ${node.inFile}`);
	}
	return [...warnings.values()];
}
/**
* Create an AST node from a raw node.
*
* @example
*   ;```typescript
*   const raw = { license: 'MIT' }
*   const node = createAstNode(raw)
*   // node.type === 'License'
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function createAstNode(rawNode) {
	return /* @__PURE__ */ require_objects_predicates.hasOwn(rawNode, "license") ? /* @__PURE__ */ createLicenseNode(rawNode) : /* @__PURE__ */ createBinaryOperationNode(rawNode);
}
/**
* Create a binary operation AST node.
*
* @example
*   ;```typescript
*   const raw = {
*     left: { license: 'MIT' },
*     conjunction: 'OR' as const,
*     right: { license: 'Apache-2.0' },
*   }
*   const node = createBinaryOperationNode(raw)
*   // node.type === 'BinaryOperation'
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function createBinaryOperationNode(rawNodeParam) {
	let left;
	let right;
	let rawLeft = rawNodeParam.left;
	let rawRight = rawNodeParam.right;
	const { conjunction } = rawNodeParam;
	return {
		__proto__: null,
		type: BINARY_OPERATION_NODE_TYPE,
		get left() {
			if (left === void 0) {
				left = /* @__PURE__ */ createAstNode(rawLeft);
				rawLeft = void 0;
			}
			return left;
		},
		conjunction,
		get right() {
			if (right === void 0) {
				right = /* @__PURE__ */ createAstNode(rawRight);
				rawRight = void 0;
			}
			return right;
		}
	};
}
/**
* Create a license AST node.
*
* @example
*   ;```typescript
*   const node = createLicenseNode({ license: 'MIT' })
*   // node.type === 'License' && node.license === 'MIT'
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function createLicenseNode(rawNode) {
	return {
		__proto__: null,
		...rawNode,
		type: LICENSE_NODE_TYPE
	};
}
/**
* Parse an SPDX license expression into an AST.
*
* @example
*   ;```typescript
*   const ast = parseSpdxExp('MIT OR Apache-2.0')
*   // ast is a BinaryOperation node with MIT and Apache-2.0 leaves
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function parseSpdxExp(spdxExp) {
	try {
		return (0, src_external_spdx_expression_parse.default)(spdxExp);
	} catch {}
	const corrected = (0, src_external_spdx_correct.default)(spdxExp);
	return corrected ? (0, src_external_spdx_expression_parse.default)(corrected) : void 0;
}
/**
* Parse package license field into structured license nodes.
*
* @example
*   ;```typescript
*   const nodes = resolvePackageLicenses('MIT', '/tmp/my-project')
*   // [{ license: 'MIT' }]
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function resolvePackageLicenses(licenseFieldValue, where) {
	if (licenseFieldValue === "UNLICENSED" || licenseFieldValue === "UNLICENCED") return [{ license: "UNLICENSED" }];
	const match = require_primordials_regexp.RegExpPrototypeExec(fileReferenceRegExp, licenseFieldValue);
	if (match) return [{
		license: licenseFieldValue,
		inFile: /* @__PURE__ */ require_paths_normalize.normalizePath((/* @__PURE__ */ require_node_path.getNodePath()).relative(where, match[1] || ""))
	}];
	const licenseNodes = [];
	if (/* @__PURE__ */ parseSpdxExp(licenseFieldValue)) {}
	return licenseNodes;
}
/**
* Traverse SPDX license AST and invoke visitor callbacks for each node.
*
* @example
*   ;```typescript
*   const ast = parseSpdxExp('MIT OR Apache-2.0')
*   const licenses: string[] = []
*   if (ast) {
*     visitLicenses(ast, {
*       License(node) {
*         licenses.push(node.license)
*       },
*     })
*   }
*   // licenses === ['MIT', 'Apache-2.0']
*   ```
*/
/*@__NO_SIDE_EFFECTS__*/
function visitLicenses(ast, visitor) {
	const queue = [[/* @__PURE__ */ createAstNode(ast), void 0]];
	let pos = 0;
	let { length: queueLength } = queue;
	while (pos < queueLength) {
		if (pos === 1e6) throw new require_primordials_error.ErrorCtor("Detected infinite loop in ast crawl of visitLicenses");
		const { 0: node, 1: parent } = queue[pos++];
		const { type } = node;
		const visitorRecord = visitor;
		if (typeof visitorRecord[type] === "function" && /* @__PURE__ */ require_objects_predicates.hasOwn(visitor, type)) {
			if (type === LICENSE_NODE_TYPE) {
				const licenseVisitor = visitorRecord["License"];
				if (typeof licenseVisitor === "function" && licenseVisitor(node, parent) === false) break;
			} else if (type === BINARY_OPERATION_NODE_TYPE) {
				const binaryOpVisitor = visitorRecord["BinaryOperation"];
				if (typeof binaryOpVisitor === "function" && binaryOpVisitor(node, parent) === false) break;
			}
		}
		if (type === BINARY_OPERATION_NODE_TYPE) {
			queue[queueLength++] = [node.left, node];
			queue[queueLength++] = [node.right, node];
		}
	}
}

//#endregion
exports.collectIncompatibleLicenses = collectIncompatibleLicenses;
exports.collectLicenseWarnings = collectLicenseWarnings;
exports.createAstNode = createAstNode;
exports.createBinaryOperationNode = createBinaryOperationNode;
exports.createLicenseNode = createLicenseNode;
exports.parseSpdxExp = parseSpdxExp;
exports.resolvePackageLicenses = resolvePackageLicenses;
exports.visitLicenses = visitLicenses;