"use strict";
/* Socket Lib - Built with esbuild */
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var dlx_package_exports = {};
__export(dlx_package_exports, {
  dlxPackage: () => dlxPackage,
  downloadPackage: () => downloadPackage,
  executePackage: () => executePackage
});
module.exports = __toCommonJS(dlx_package_exports);
var import_node_fs = __toESM(require("node:fs"));
var import_path = __toESM(require("path"));
var import_platform = require("./constants/platform");
var import_packages = require("./constants/packages");
var import_dlx = require("./dlx");
var import_arborist = __toESM(require("./external/@npmcli/arborist"));
var import_libnpmexec = __toESM(require("./external/libnpmexec"));
var import_npm_package_arg = __toESM(require("./external/npm-package-arg"));
var import_pacote = __toESM(require("./external/pacote"));
var import_fs = require("./fs");
var import_normalize = require("./paths/normalize");
var import_socket = require("./paths/socket");
var import_process_lock = require("./process-lock");
var import_spawn = require("./spawn");
const rangeOperatorsRegExp = /[~^><=xX* ]|\|\|/;
function parsePackageSpec(spec) {
  try {
    const parsed = (0, import_npm_package_arg.default)(spec);
    const version = parsed.type === "tag" ? parsed.fetchSpec : parsed.type === "version" || parsed.type === "range" ? parsed.fetchSpec : void 0;
    return {
      name: parsed.name || spec,
      version
    };
  } catch {
    const atIndex = spec.lastIndexOf("@");
    if (atIndex === -1 || spec.startsWith("@")) {
      return { name: spec, version: void 0 };
    }
    return {
      name: spec.slice(0, atIndex),
      version: spec.slice(atIndex + 1)
    };
  }
}
async function ensurePackageInstalled(packageName, packageSpec, force) {
  const cacheKey = (0, import_dlx.generateCacheKey)(packageSpec);
  const packageDir = (0, import_normalize.normalizePath)(import_path.default.join((0, import_socket.getSocketDlxDir)(), cacheKey));
  const installedDir = (0, import_normalize.normalizePath)(
    import_path.default.join(packageDir, "node_modules", packageName)
  );
  try {
    await (0, import_fs.safeMkdir)(packageDir);
  } catch (e) {
    const code = e.code;
    if (code === "EACCES" || code === "EPERM") {
      throw new Error(
        `Permission denied creating package directory: ${packageDir}
Please check directory permissions or run with appropriate access.`,
        { cause: e }
      );
    }
    if (code === "EROFS") {
      throw new Error(
        `Cannot create package directory on read-only filesystem: ${packageDir}
Ensure the filesystem is writable or set SOCKET_DLX_DIR to a writable location.`,
        { cause: e }
      );
    }
    throw new Error(`Failed to create package directory: ${packageDir}`, {
      cause: e
    });
  }
  const lockPath = import_path.default.join(packageDir, "concurrency.lock");
  return await import_process_lock.processLock.withLock(
    lockPath,
    async () => {
      if (!force && import_node_fs.default.existsSync(installedDir)) {
        const pkgJsonPath = import_path.default.join(installedDir, "package.json");
        if (import_node_fs.default.existsSync(pkgJsonPath)) {
          return { installed: false, packageDir };
        }
      }
      const pacoteCachePath = (0, import_packages.getPacoteCachePath)();
      try {
        await import_pacote.default.extract(packageSpec, installedDir, {
          // Use consistent pacote cache path (respects npm cache locations when available).
          cache: pacoteCachePath || import_path.default.join(packageDir, ".cache")
        });
        const arb = new import_arborist.default({
          path: installedDir,
          cache: pacoteCachePath || import_path.default.join(packageDir, ".cache"),
          // Skip devDependencies (production-only like npx).
          omit: ["dev"],
          // Security: Skip install/preinstall/postinstall scripts to prevent arbitrary code execution.
          ignoreScripts: true,
          // Security: Enable binary links (needed for dlx to execute the package binary).
          binLinks: true,
          // Suppress funding messages (unneeded for ephemeral dlx installs).
          fund: false,
          // Skip audit (unneeded for ephemeral dlx installs).
          audit: false,
          // Suppress output (unneeded for ephemeral dlx installs).
          silent: true
        });
        await arb.buildIdealTree();
        await arb.reify({ save: false });
      } catch (e) {
        const code = e.code;
        if (code === "E404" || code === "ETARGET") {
          throw new Error(
            `Package not found: ${packageSpec}
Verify the package exists on npm registry and check the version.
Visit https://www.npmjs.com/package/${packageName} to see available versions.`,
            { cause: e }
          );
        }
        if (code === "ENOTFOUND" || code === "ETIMEDOUT" || code === "EAI_AGAIN") {
          throw new Error(
            `Network error installing ${packageSpec}
Check your internet connection and try again.`,
            { cause: e }
          );
        }
        throw new Error(
          `Failed to install package: ${packageSpec}
Destination: ${installedDir}
Check npm registry connectivity or package name.`,
          { cause: e }
        );
      }
      return { installed: true, packageDir };
    },
    {
      // Align with npm npx locking strategy.
      staleMs: 5e3,
      touchIntervalMs: 2e3
    }
  );
}
function resolveBinaryPath(basePath) {
  if (!import_platform.WIN32) {
    return basePath;
  }
  const extensions = [".cmd", ".bat", ".ps1", ".exe", ""];
  for (const ext of extensions) {
    const testPath = basePath + ext;
    if (import_node_fs.default.existsSync(testPath)) {
      return testPath;
    }
  }
  return basePath;
}
function findBinaryPath(packageDir, packageName, binaryName) {
  const installedDir = (0, import_normalize.normalizePath)(
    import_path.default.join(packageDir, "node_modules", packageName)
  );
  const pkgJsonPath = import_path.default.join(installedDir, "package.json");
  const pkgJson = (0, import_fs.readJsonSync)(pkgJsonPath);
  const bin = pkgJson["bin"];
  let binName;
  let binPath;
  if (typeof bin === "string") {
    binPath = bin;
  } else if (typeof bin === "object" && bin !== null) {
    const binObj = bin;
    const binKeys = Object.keys(binObj);
    if (binKeys.length === 1) {
      binName = binKeys[0];
      binPath = binObj[binName];
    } else {
      try {
        const { getBinFromManifest } = import_libnpmexec.default;
        binName = getBinFromManifest({
          name: packageName,
          bin: binObj,
          _id: `${packageName}@${pkgJson.version || "unknown"}`
        });
        binPath = binObj[binName];
      } catch {
        const lastSegment = packageName.split("/").pop();
        const candidates = [
          binaryName,
          lastSegment,
          packageName.replace(/^@[^/]+\//, "")
        ].filter(Boolean);
        for (const candidate of candidates) {
          if (candidate && binObj[candidate]) {
            binName = candidate;
            binPath = binObj[candidate];
            break;
          }
        }
        if (!binPath && binKeys.length > 0) {
          binName = binKeys[0];
          binPath = binObj[binName];
        }
      }
    }
  }
  if (!binPath) {
    throw new Error(`No binary found for package "${packageName}"`);
  }
  const rawPath = (0, import_normalize.normalizePath)(import_path.default.join(installedDir, binPath));
  return resolveBinaryPath(rawPath);
}
async function dlxPackage(args, options, spawnExtra) {
  const downloadResult = await downloadPackage(options);
  const spawnPromise = executePackage(
    downloadResult.binaryPath,
    args,
    options?.spawnOptions,
    spawnExtra
  );
  return {
    ...downloadResult,
    spawnPromise
  };
}
function makePackageBinsExecutable(packageDir, packageName) {
  if (import_platform.WIN32) {
    return;
  }
  const installedDir = (0, import_normalize.normalizePath)(
    import_path.default.join(packageDir, "node_modules", packageName)
  );
  const pkgJsonPath = import_path.default.join(installedDir, "package.json");
  try {
    const pkgJson = (0, import_fs.readJsonSync)(pkgJsonPath);
    const bin = pkgJson["bin"];
    if (!bin) {
      return;
    }
    const binPaths = [];
    if (typeof bin === "string") {
      binPaths.push(bin);
    } else if (typeof bin === "object" && bin !== null) {
      const binObj = bin;
      binPaths.push(...Object.values(binObj));
    }
    for (const binPath of binPaths) {
      const fullPath = (0, import_normalize.normalizePath)(import_path.default.join(installedDir, binPath));
      if (import_node_fs.default.existsSync(fullPath)) {
        try {
          import_node_fs.default.chmodSync(fullPath, 493);
        } catch {
        }
      }
    }
  } catch {
  }
}
async function downloadPackage(options) {
  const {
    binaryName,
    force: userForce,
    package: packageSpec,
    yes
  } = {
    __proto__: null,
    ...options
  };
  const { name: packageName, version: packageVersion } = parsePackageSpec(packageSpec);
  const isVersionRange = packageVersion !== void 0 && rangeOperatorsRegExp.test(packageVersion);
  const force = userForce !== void 0 ? userForce : yes === true ? true : isVersionRange;
  const fullPackageSpec = packageVersion ? `${packageName}@${packageVersion}` : packageName;
  const { installed, packageDir } = await ensurePackageInstalled(
    packageName,
    fullPackageSpec,
    force
  );
  const binaryPath = findBinaryPath(packageDir, packageName, binaryName);
  makePackageBinsExecutable(packageDir, packageName);
  return {
    binaryPath,
    installed,
    packageDir
  };
}
function executePackage(binaryPath, args, spawnOptions, spawnExtra) {
  const needsShell = import_platform.WIN32 && /\.(?:bat|cmd|ps1)$/i.test(binaryPath);
  const finalOptions = needsShell ? {
    ...spawnOptions,
    shell: true
  } : spawnOptions;
  return (0, import_spawn.spawn)(binaryPath, args, finalOptions, spawnExtra);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  dlxPackage,
  downloadPackage,
  executePackage
});
