"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_primordials_string = require('../primordials/string.js');
const require_paths__internal = require('../paths/_internal.js');
const require_primordials_array = require('../primordials/array.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_primordials_globals = require('../primordials/globals.js');
const require_arrays_predicates = require('../arrays/predicates.js');
const require_objects_mutate = require('../objects/mutate.js');
const require_promises_retry = require('../promises/retry.js');
const require_fs__internal = require('./_internal.js');

//#region src/fs/safe.ts
/**
* @file Safe deletion + idempotent directory creation. The delete helpers gate
*   destructive operations behind an "allowed directories" allow-list (temp
*   dir, cacache dir, ~/.socket); paths outside those need an explicit `force:
*   true`. The mkdir helpers default to `recursive: true` and swallow `EEXIST`
*   so concurrent callers don't race-condition each other.
*/
const defaultRemoveOptions = require_objects_mutate.objectFreeze({
	__proto__: null,
	force: true,
	maxRetries: 3,
	recursive: true,
	retryDelay: 200
});
let _del;
/*@__NO_SIDE_EFFECTS__*/
function getDel() {
	if (_del === void 0) _del = /*@__PURE__*/ require("../external/del");
	return _del;
}
/**
* Safely delete a file or directory asynchronously with built-in protections.
*
* Uses [`del`](https://socket.dev/npm/package/del/overview/8.0.1) for safer
* deletion with these safety features:
*
* - By default, prevents deleting the current working directory (cwd) and above
* - Allows deleting within cwd (descendant paths) without force option
* - Automatically uses force: true for temp directory, cacache, and ~/.socket
*   subdirectories
* - Protects against accidental deletion of parent directories via `../` paths
*
* @example
*   ;```ts
*   // Delete files within cwd (safe by default)
*   await safeDelete('./build')
*   await safeDelete('./dist')
*
*   // Delete with glob patterns
*   await safeDelete(['./temp/**', '!./temp/keep.txt'])
*
*   // Delete with custom retry settings
*   await safeDelete('./flaky-dir', { maxRetries: 5, retryDelay: 500 })
*
*   // Force delete cwd or above (requires explicit force: true)
*   await safeDelete('../parent-dir', { force: true })
*   ```
*
* @param filepath - Path or array of paths to delete (supports glob patterns)
* @param options - Deletion options including force, retries, and recursion.
* @param options.force - Set to true to allow deleting cwd and above (use with
*   caution)
*
* @throws {Error} When attempting to delete protected paths without force
*   option.
*/
async function safeDelete(filepath, options) {
	const opts = {
		__proto__: null,
		...options
	};
	const patterns = require_arrays_predicates.isArray(filepath) ? filepath.map(require_paths__internal.pathLikeToString) : [/* @__PURE__ */ require_paths__internal.pathLikeToString(filepath)];
	/* c8 ignore start */
	let shouldForce = opts.force !== false;
	if (!shouldForce && patterns.length > 0) {
		const path = /* @__PURE__ */ require_node_path.getNodePath();
		const allowedDirs = require_fs__internal.getAllowedDirectories();
		if (patterns.every((pattern) => {
			const resolvedPath = path.resolve(pattern);
			for (const allowedDir of allowedDirs) {
				const isInAllowedDir = require_primordials_string.StringPrototypeStartsWith(resolvedPath, allowedDir + path.sep) || resolvedPath === allowedDir;
				const isGoingBackward = require_primordials_string.StringPrototypeStartsWith(path.relative(allowedDir, resolvedPath), "..");
				if (isInAllowedDir && !isGoingBackward) return true;
			}
			return false;
		})) shouldForce = true;
	}
	/* c8 ignore stop */
	const maxRetries = opts.maxRetries ?? defaultRemoveOptions.maxRetries;
	const retryDelay = opts.retryDelay ?? defaultRemoveOptions.retryDelay;
	/* c8 ignore start - External del call */
	const del = /* @__PURE__ */ getDel();
	await /* @__PURE__ */ require_promises_retry.pRetry(async () => {
		await del.deleteAsync(patterns, {
			dryRun: false,
			force: shouldForce,
			onlyFiles: false
		});
	}, {
		retries: maxRetries,
		baseDelayMs: retryDelay,
		backoffFactor: 2,
		signal: opts.signal
	});
	/* c8 ignore stop */
}
/**
* Safely delete a file or directory synchronously with built-in protections.
*
* Uses [`del`](https://socket.dev/npm/package/del/overview/8.0.1) for safer
* deletion with these safety features:
*
* - By default, prevents deleting the current working directory (cwd) and above
* - Allows deleting within cwd (descendant paths) without force option
* - Automatically uses force: true for temp directory, cacache, and ~/.socket
*   subdirectories
* - Protects against accidental deletion of parent directories via `../` paths
*
* @example
*   ;```ts
*   // Delete files within cwd (safe by default)
*   safeDeleteSync('./build')
*   safeDeleteSync('./dist')
*
*   // Delete with glob patterns
*   safeDeleteSync(['./temp/**', '!./temp/keep.txt'])
*
*   // Delete multiple paths
*   safeDeleteSync(['./coverage', './reports'])
*
*   // Force delete cwd or above (requires explicit force: true)
*   safeDeleteSync('../parent-dir', { force: true })
*   ```
*
* @param filepath - Path or array of paths to delete (supports glob patterns)
* @param options - Deletion options including force, retries, and recursion.
* @param options.force - Set to true to allow deleting cwd and above (use with
*   caution)
*
* @throws {Error} When attempting to delete protected paths without force
*   option.
*/
function safeDeleteSync(filepath, options) {
	const opts = {
		__proto__: null,
		...options
	};
	const patterns = require_arrays_predicates.isArray(filepath) ? filepath.map(require_paths__internal.pathLikeToString) : [/* @__PURE__ */ require_paths__internal.pathLikeToString(filepath)];
	/* c8 ignore start */
	let shouldForce = opts.force !== false;
	if (!shouldForce && patterns.length > 0) {
		const path = /* @__PURE__ */ require_node_path.getNodePath();
		const allowedDirs = require_fs__internal.getAllowedDirectories();
		if (patterns.every((pattern) => {
			const resolvedPath = path.resolve(pattern);
			for (const allowedDir of allowedDirs) {
				const isInAllowedDir = require_primordials_string.StringPrototypeStartsWith(resolvedPath, allowedDir + path.sep) || resolvedPath === allowedDir;
				const isGoingBackward = require_primordials_string.StringPrototypeStartsWith(path.relative(allowedDir, resolvedPath), "..");
				if (isInAllowedDir && !isGoingBackward) return true;
			}
			return false;
		})) shouldForce = true;
	}
	/* c8 ignore stop */
	const maxRetries = opts.maxRetries ?? defaultRemoveOptions.maxRetries;
	const retryDelay = opts.retryDelay ?? defaultRemoveOptions.retryDelay;
	/* c8 ignore start - External del call */
	const del = /* @__PURE__ */ getDel();
	let lastError;
	let delay = retryDelay;
	for (let attempt = 0; attempt <= maxRetries; attempt++) try {
		del.deleteSync(patterns, {
			dryRun: false,
			force: shouldForce,
			onlyFiles: false
		});
		return;
	} catch (e) {
		lastError = e;
		if (attempt < maxRetries) {
			const waitMs = delay;
			require_primordials_array.AtomicsWait(new require_primordials_array.Int32ArrayCtor(new require_primordials_globals.SharedArrayBufferCtor(4)), 0, 0, waitMs);
			delay *= 2;
		}
	}
	if (lastError) throw lastError;
	/* c8 ignore stop */
}
/**
* Safely create a directory asynchronously, ignoring EEXIST errors. This
* function wraps fs.promises.mkdir and handles the race condition where the
* directory might already exist, which is common in concurrent code.
*
* Unlike fs.promises.mkdir with recursive:true, this function: - Silently
* ignores EEXIST errors (directory already exists) - Re-throws all other errors
* (permissions, invalid path, etc.) - Works reliably in
* multi-process/concurrent scenarios - Defaults to recursive: true for
* convenient nested directory creation.
*
* @example
*   ;```ts
*   // Create a directory recursively by default, no error if it exists
*   await safeMkdir('./config')
*
*   // Create nested directories (recursive: true is the default)
*   await safeMkdir('./data/cache/temp')
*
*   // Create with specific permissions
*   await safeMkdir('./secure', { mode: 0o700 })
*
*   // Explicitly disable recursive behavior
*   await safeMkdir('./single-level', { recursive: false })
*   ```
*
* @param path - Directory path to create.
* @param options - Options including recursive (default: true) and mode
*   settings.
*
* @returns Promise that resolves when directory is created or already exists
*/
async function safeMkdir(path, options) {
	const fs = /* @__PURE__ */ require_node_fs.getNodeFs();
	const opts = {
		__proto__: null,
		recursive: true,
		...options
	};
	try {
		await fs.promises.mkdir(path, opts);
	} catch (e) {
		if (!require_errors_predicates.isErrnoException(e) || e.code !== "EEXIST") throw e;
	}
	/* c8 ignore stop */
}
/**
* Safely create a directory synchronously, ignoring EEXIST errors. This
* function wraps fs.mkdirSync and handles the race condition where the
* directory might already exist, which is common in concurrent code.
*
* Unlike fs.mkdirSync with recursive:true, this function: - Silently ignores
* EEXIST errors (directory already exists) - Re-throws all other errors
* (permissions, invalid path, etc.) - Works reliably in
* multi-process/concurrent scenarios - Defaults to recursive: true for
* convenient nested directory creation.
*
* @example
*   ;```ts
*   // Create a directory recursively by default, no error if it exists
*   safeMkdirSync('./config')
*
*   // Create nested directories (recursive: true is the default)
*   safeMkdirSync('./data/cache/temp')
*
*   // Create with specific permissions
*   safeMkdirSync('./secure', { mode: 0o700 })
*
*   // Explicitly disable recursive behavior
*   safeMkdirSync('./single-level', { recursive: false })
*   ```
*
* @param path - Directory path to create.
* @param options - Options including recursive (default: true) and mode
*   settings.
*/
function safeMkdirSync(path, options) {
	const fs = /* @__PURE__ */ require_node_fs.getNodeFs();
	const opts = {
		__proto__: null,
		recursive: true,
		...options
	};
	try {
		fs.mkdirSync(path, opts);
	} catch (e) {
		if (!require_errors_predicates.isErrnoException(e) || e.code !== "EEXIST") throw e;
	}
	/* c8 ignore stop */
}

//#endregion
exports.getDel = getDel;
exports.safeDelete = safeDelete;
exports.safeDeleteSync = safeDeleteSync;
exports.safeMkdir = safeMkdir;
exports.safeMkdirSync = safeMkdirSync;