// src/actions/deplint/packageJsonEditor.ts
import fs2 from "fs";
import chalk from "chalk";
import semver from "semver";
import sortPackageJson from "sort-package-json";

// src/actions/deplint/getRequiredPeerDependencies.ts
import fs from "fs";
import path from "path";
function findDepPackageJson(location, dep) {
  let dir = location;
  while (true) {
    const candidate = path.join(dir, "node_modules", dep, "package.json");
    if (fs.existsSync(candidate)) return candidate;
    const parent = path.dirname(dir);
    if (parent === dir) return void 0;
    dir = parent;
  }
}

// src/actions/deplint/packageJsonEditor.ts
function formatPeerRange(version, boundType = "major") {
  const parsed = semver.parse(version);
  if (!parsed) return `~${version}`;
  if (boundType === "minor") return `>=${parsed.version} <${parsed.major}.${parsed.minor + 1}`;
  return `>=${parsed.version} <${parsed.major + 1}`;
}
function inferPeerBoundType(devRange) {
  return devRange?.startsWith("~") ? "minor" : "major";
}
function readInstalledVersion(location, dep) {
  const depPkgPath = findDepPackageJson(location, dep);
  if (!depPkgPath) return void 0;
  try {
    const depPkg = JSON.parse(fs2.readFileSync(depPkgPath, "utf8"));
    return depPkg.version;
  } catch {
    return void 0;
  }
}
function resolvePeerLowerBound(location, dep, devRange) {
  if (devRange && devRange !== "*" && !devRange.startsWith("workspace:") && !devRange.startsWith("catalog:") && !devRange.startsWith("npm:")) {
    try {
      const min = semver.minVersion(devRange);
      if (min) return min.version;
    } catch {
    }
  }
  return readInstalledVersion(location, dep);
}
function resolveExpectedPeerVersion(location, dep, devRange) {
  const lower = resolvePeerLowerBound(location, dep, devRange);
  return lower ? formatPeerRange(lower, inferPeerBoundType(devRange)) : "*";
}
function resolveExpectedDevVersion(location, dep) {
  const version = readInstalledVersion(location, dep);
  if (!version) return "*";
  const match = /^(\d+)\.(\d+)/.exec(version);
  return match ? `~${match[1]}.${match[2]}` : `~${version}`;
}

// src/actions/deplint/versionMismatchFixes.ts
function sectionLookupsFor(context) {
  const {
    dependencies,
    devDependencies,
    peerDependencies,
    dependencyVersions,
    devDependencyVersions,
    peerDependencyVersions
  } = context.packageParams;
  return [
    ["dependencies", dependencies, dependencyVersions],
    ["devDependencies", devDependencies, devDependencyVersions],
    ["peerDependencies", peerDependencies, peerDependencyVersions]
  ];
}
function addSourceBumpFixes(context, finding, fixes) {
  if (!finding.installedVersion || !finding.mismatchedSources) return;
  const sectionLookups = sectionLookupsFor(context);
  const seen = /* @__PURE__ */ new Set();
  for (const source of finding.mismatchedSources) {
    const dep = source.requiredBy;
    if (seen.has(dep) || dep === context.workspace.name) continue;
    seen.add(dep);
    for (const [section, names, versions] of sectionLookups) {
      if (!names.includes(dep)) continue;
      const current = versions[dep];
      if (!current || current.startsWith("workspace:")) continue;
      fixes.push({
        action: "resolve-peer-bump",
        currentRange: current,
        dependency: dep,
        detail: `bump ${section} range so a newer version of ${dep} is installed that accepts peer ${finding.peer}@${finding.installedVersion}`,
        installedPeerVersion: finding.installedVersion,
        peer: finding.peer,
        section
      });
    }
  }
}
function generateVersionMismatchFixes(context, finding) {
  const fixes = [];
  const devRange = context.packageParams.devDependencyVersions[finding.peer];
  const expectedPeerVersion = resolveExpectedPeerVersion(context.workspace.location, finding.peer, devRange);
  const expectedDevVersion = resolveExpectedDevVersion(context.workspace.location, finding.peer);
  if (expectedPeerVersion !== "*" && context.packageParams.peerDependencies.includes(finding.peer)) {
    const peerVersion = context.packageParams.peerDependencyVersions[finding.peer];
    if (!peerVersion?.startsWith("workspace:")) {
      fixes.push({
        action: "set-version",
        dependency: finding.peer,
        detail: `updated peerDependency version to match installed (${finding.installedVersion})`,
        section: "peerDependencies",
        version: expectedPeerVersion
      });
    }
  }
  if (expectedDevVersion !== "*" && context.packageParams.devDependencies.includes(finding.peer)) {
    const devVersion = context.packageParams.devDependencyVersions[finding.peer];
    if (devVersion && !devVersion.startsWith("workspace:")) {
      fixes.push({
        action: "set-version",
        dependency: finding.peer,
        detail: `updated devDependency version to match installed (${finding.installedVersion})`,
        section: "devDependencies",
        version: expectedDevVersion
      });
    }
  }
  addSourceBumpFixes(context, finding, fixes);
  return fixes;
}
export {
  generateVersionMismatchFixes
};
//# sourceMappingURL=versionMismatchFixes.mjs.map