// src/lib/updo/resolveVersions.ts
import semver from "semver";
function computeWanted(info, range) {
  return semver.maxSatisfying(info.versions, range) ?? void 0;
}
function isUnboundedAbove(range) {
  try {
    const parsed = new semver.Range(range);
    return parsed.set.some((comparators) => !comparators.some((c) => c.operator === "<" || c.operator === "<="));
  } catch {
    return false;
  }
}
function computePrerelease(info, latest) {
  if (!info) return void 0;
  let best;
  for (const tag of ["next", "rc", "beta"]) {
    const v = info.distTags[tag];
    if (!v) continue;
    if (!best || semver.gt(v, best)) best = v;
  }
  if (!best) return void 0;
  if (latest && !semver.gt(best, latest)) return void 0;
  return best;
}
function normalizeRange(prefix, version) {
  return version ? `${prefix}${version}` : void 0;
}
function maxVersion(versions) {
  let best;
  for (const version of versions) {
    if (!version) continue;
    if (!best || semver.gt(version, best)) {
      best = version;
    }
  }
  return best;
}
function wouldChange(targetRange, declaredRanges) {
  return !!targetRange && declaredRanges.some((range) => range !== targetRange);
}
function resolveVersions(deps, registry) {
  const resolved = [];
  const grouped = /* @__PURE__ */ new Map();
  for (const dep of deps) {
    const existing = grouped.get(dep.name);
    if (existing) {
      existing.push(dep);
    } else {
      grouped.set(dep.name, [dep]);
    }
  }
  for (const [name, group] of grouped) {
    const info = registry.get(name);
    const preferredRangePrefix = group.some((dep) => dep.range.startsWith("^")) ? "^" : "~";
    const declaredRanges = [...new Set(group.map((dep) => dep.range))];
    const workspaces = [...new Set(group.map((dep) => dep.workspaceName))];
    const current = declaredRanges.length === 1 ? declaredRanges[0] : "mixed";
    const boundedRanges = declaredRanges.filter((range) => !isUnboundedAbove(range));
    const rangesForWanted = boundedRanges.length > 0 ? boundedRanges : declaredRanges;
    const wanted = normalizeRange(
      preferredRangePrefix,
      info ? maxVersion(rangesForWanted.map((range) => computeWanted(info, range))) : void 0
    );
    const latest = normalizeRange(preferredRangePrefix, info?.distTags.latest);
    const next = normalizeRange(preferredRangePrefix, computePrerelease(info, info?.distTags.latest));
    const updateAvailable = wouldChange(wanted, declaredRanges) || wouldChange(latest, declaredRanges) || wouldChange(next, declaredRanges);
    resolved.push({
      current,
      declaredRanges,
      latest,
      name,
      next,
      preferredRangePrefix,
      updateAvailable,
      wanted: wanted && wanted !== current ? wanted : void 0,
      workspaces
    });
  }
  return resolved.toSorted((a, b) => {
    if (a.updateAvailable !== b.updateAvailable) return a.updateAvailable ? -1 : 1;
    return a.name.localeCompare(b.name);
  });
}
export {
  resolveVersions
};
//# sourceMappingURL=resolveVersions.mjs.map