"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_node_fs = require('../node/fs.js');
const require_node_path = require('../node/path.js');
const require_primordials_date = require('../primordials/date.js');
const require_primordials_object = require('../primordials/object.js');
const require_primordials_json = require('../primordials/json.js');
const require_errors_message = require('../errors/message.js');
const require_logger_default = require('../logger/default.js');
const require_paths_socket = require('../paths/socket.js');
const require_fs_safe = require('../fs/safe.js');
const require_process_lock_instance = require('../process/lock-instance.js');
const require_fs_read_file = require('../fs/read-file.js');

//#region src/dlx/manifest.ts
/**
* @file DLX manifest storage utilities. Manages persistent caching of DLX
*   package and binary metadata with TTL support and atomic file operations.
*   Primary API (on {@link DlxManifest}):
*
*   - `getManifestEntry(spec)` — retrieve a manifest entry by spec
*   - `setPackageEntry(spec, key, details)` — store npm package metadata
*   - `setBinaryEntry(spec, key, details)` — store binary download metadata
*   - `getAllPackages()` — enumerate cached package names
*   - `clear(name)` / `clearAll()` — eviction
*   - `isFresh(record, ttlMs)` — TTL check The bare `get(name)` / `set(name,
*     record)` methods are deprecated legacy shims kept for backward
*     compatibility with pre-5.x callers. Features:
*   - TTL-based cache expiration
*   - Atomic file operations with locking
*   - JSON-based persistent storage
*   - Error-resistant implementation Storage Format:
*   - Stores in ~/.socket/_dlx/.dlx-manifest.json
*   - Per-spec manifest entries with timestamps
*   - Thread-safe operations using process lock utility Usage:
*   - Update check caching
*   - Binary metadata tracking
*   - Rate limiting registry requests
*/
const fs = /* @__PURE__ */ require_node_fs.getNodeFs();
const path = /* @__PURE__ */ require_node_path.getNodePath();
const logger = require_logger_default.getDefaultLogger();
/**
* Manifest file name.
*/
const MANIFEST_FILE_NAME = ".dlx-manifest.json";
/**
* Type guard for binary entries.
*
* @example
*   ;```typescript
*   const entry = manifest.getManifestEntry('https://example.com/tool')
*   if (entry && isBinaryEntry(entry)) {
*     console.log(entry.details.integrity)
*   }
*   ```
*/
function isBinaryEntry(entry) {
	return entry.type === "binary";
}
/**
* Type guard for package entries.
*
* @example
*   ;```typescript
*   const entry = manifest.getManifestEntry('@socketsecurity/cli@^2.0.0')
*   if (entry && isPackageEntry(entry)) {
*     console.log(entry.details.installed_version)
*   }
*   ```
*/
function isPackageEntry(entry) {
	return entry.type === "package";
}
/**
* DLX manifest storage manager with atomic operations. Supports both legacy
* format (package name keys) and new unified manifest format (spec keys).
*/
var DlxManifest = class {
	manifestPath;
	lockPath;
	constructor(options = {}) {
		this.manifestPath = options.manifestPath ?? path.join(require_paths_socket.getSocketDlxDir(), MANIFEST_FILE_NAME);
		this.lockPath = `${this.manifestPath}.lock`;
	}
	/**
	* Read the entire manifest file.
	*
	* @private
	*/
	readManifest() {
		try {
			if (!fs.existsSync(this.manifestPath)) return { __proto__: null };
			const rawContent = /* @__PURE__ */ require_fs_read_file.readFileUtf8Sync(this.manifestPath);
			const content = (typeof rawContent === "string" ? rawContent : rawContent.toString("utf8")).trim();
			if (!content) return { __proto__: null };
			return require_primordials_json.JSONParse(content);
		} catch (e) {
			logger.warn(`Failed to read manifest: ${require_errors_message.errorMessage(e)}`);
			return { __proto__: null };
		}
	}
	/**
	* Write the manifest file atomically.
	*
	* @private
	*/
	async writeManifest(data) {
		const manifestDir = path.dirname(this.manifestPath);
		try {
			require_fs_safe.safeMkdirSync(manifestDir, { recursive: true });
		} catch (e) {
			logger.warn(`Failed to create manifest directory: ${require_errors_message.errorMessage(e)}`);
		}
		/* c8 ignore stop */
		const content = require_primordials_json.JSONStringify(data, void 0, 2);
		const tempPath = `${this.manifestPath}.tmp`;
		try {
			fs.writeFileSync(tempPath, content, "utf8");
			fs.renameSync(tempPath, this.manifestPath);
		} catch (e) {
			try {
				if (fs.existsSync(tempPath)) require_fs_safe.safeDeleteSync(tempPath);
			} catch {}
			throw e;
		}
		/* c8 ignore stop */
	}
	/**
	* Clear cached data for a specific entry.
	*/
	async clear(name) {
		await require_process_lock_instance.processLock.withLock(this.lockPath, async () => {
			try {
				if (!fs.existsSync(this.manifestPath)) return;
				const content = fs.readFileSync(this.manifestPath, "utf8");
				if (!content.trim()) return;
				const data = require_primordials_json.JSONParse(content);
				delete data[name];
				await this.writeManifest(data);
			} catch (e) {
				logger.warn(`Failed to clear cache for ${name}: ${require_errors_message.errorMessage(e)}`);
			}
			/* c8 ignore stop */
		});
	}
	/**
	* Clear all cached data.
	*/
	async clearAll() {
		await require_process_lock_instance.processLock.withLock(this.lockPath, async () => {
			try {
				if (fs.existsSync(this.manifestPath)) require_fs_safe.safeDeleteSync(this.manifestPath);
			} catch (e) {
				logger.warn(`Failed to clear all cache: ${require_errors_message.errorMessage(e)}`);
			}
		});
	}
	/**
	* Get cached update information for a package (legacy format).
	*
	* @deprecated Use getManifestEntry() for new code.
	*/
	get(name) {
		const entry = this.readManifest()[name];
		if (entry && !("type" in entry)) return entry;
	}
	/**
	* Get all cached package names.
	*/
	getAllPackages() {
		try {
			if (!fs.existsSync(this.manifestPath)) return [];
			const rawContent = /* @__PURE__ */ require_fs_read_file.readFileUtf8Sync(this.manifestPath);
			const content = (typeof rawContent === "string" ? rawContent : rawContent.toString("utf8")).trim();
			if (!content) return [];
			return require_primordials_object.ObjectKeys(require_primordials_json.JSONParse(content));
		} catch (e) {
			logger.warn(`Failed to get package list: ${require_errors_message.errorMessage(e)}`);
			return [];
		}
	}
	/**
	* Get a manifest entry by spec (e.g., "@socketsecurity/cli@^2.0.11").
	*/
	getManifestEntry(spec) {
		const entry = this.readManifest()[spec];
		if (entry && "type" in entry) return entry;
	}
	/**
	* Check if cached data is fresh based on TTL.
	*/
	isFresh(record, ttlMs) {
		if (!record) return false;
		return require_primordials_date.DateNow() - record.timestampFetch < ttlMs;
	}
	/**
	* Store update information for a package (legacy format).
	*
	* @deprecated Use setPackageEntry() for new code.
	*/
	async set(name, record) {
		await require_process_lock_instance.processLock.withLock(this.lockPath, async () => {
			let data = { __proto__: null };
			try {
				if (fs.existsSync(this.manifestPath)) {
					const content = fs.readFileSync(this.manifestPath, "utf8");
					if (content.trim()) data = require_primordials_json.JSONParse(content);
				}
			} catch (e) {
				logger.warn(`Failed to read existing manifest: ${require_errors_message.errorMessage(e)}`);
			}
			data[name] = record;
			const manifestDir = path.dirname(this.manifestPath);
			try {
				require_fs_safe.safeMkdirSync(manifestDir, { recursive: true });
			} catch (e) {
				logger.warn(`Failed to create manifest directory: ${require_errors_message.errorMessage(e)}`);
			}
			const content = require_primordials_json.JSONStringify(data, null, 2);
			const tempPath = `${this.manifestPath}.tmp`;
			try {
				fs.writeFileSync(tempPath, content, "utf8");
				fs.renameSync(tempPath, this.manifestPath);
			} catch (e) {
				try {
					if (fs.existsSync(tempPath)) require_fs_safe.safeDeleteSync(tempPath);
				} catch {}
				throw e;
			}
		});
	}
	/**
	* Set a binary manifest entry.
	*/
	async setBinaryEntry(spec, cacheKey, details) {
		await require_process_lock_instance.processLock.withLock(this.lockPath, async () => {
			const data = this.readManifest();
			data[spec] = {
				type: "binary",
				cache_key: cacheKey,
				timestamp: Date.now(),
				details
			};
			await this.writeManifest(data);
		});
	}
	/**
	* Set a package manifest entry.
	*/
	async setPackageEntry(spec, cacheKey, details) {
		await require_process_lock_instance.processLock.withLock(this.lockPath, async () => {
			const data = this.readManifest();
			data[spec] = {
				type: "package",
				cache_key: cacheKey,
				timestamp: Date.now(),
				details
			};
			await this.writeManifest(data);
		});
	}
};
const dlxManifest = new DlxManifest();

//#endregion
exports.DlxManifest = DlxManifest;
exports.dlxManifest = dlxManifest;
exports.isBinaryEntry = isBinaryEntry;
exports.isPackageEntry = isPackageEntry;