function stripFragment(url) {
  try {
    const u = new URL(url);
    u.hash = "";
    return u.toString();
  } catch {
    return url;
  }
}
function canonicalForCrawl(url) {
  try {
    const u = new URL(url);
    u.hash = "";
    let pathname = u.pathname;
    if (pathname.length > 1 && pathname.endsWith("/")) pathname = pathname.slice(0, -1);
    u.pathname = pathname;
    return u.toString();
  } catch {
    return url;
  }
}
function canonicalForOutput(url) {
  try {
    const u = new URL(url);
    let path = u.pathname;
    if (path === "/") {
      path = "";
    } else if (path.length > 1 && path.endsWith("/")) {
      path = path.slice(0, -1);
    }
    return `${u.origin}${path}${u.search}`;
  } catch {
    return url;
  }
}
function isPrivateUrl(url) {
  const parsed = new URL(url);
  const hostname = parsed.hostname.replace(/^\[|\]$/g, "");
  if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "0.0.0.0") {
    return true;
  }
  if (hostname.endsWith(".local")) {
    return true;
  }
  if (hostname.startsWith("10.")) {
    return true;
  }
  if (hostname.startsWith("192.168.")) {
    return true;
  }
  if (hostname.startsWith("172.")) {
    const parts = hostname.split(".");
    const second = parseInt(parts[1], 10);
    if (second >= 16 && second <= 31) {
      return true;
    }
  }
  return false;
}
function matchesPatterns(url, includePatterns, excludePatterns) {
  if (includePatterns && includePatterns.length > 0) {
    const matches = includePatterns.some((p) => new RegExp(p).test(url));
    if (!matches) return false;
  }
  if (excludePatterns && excludePatterns.length > 0) {
    const excluded = excludePatterns.some((p) => new RegExp(p).test(url));
    if (excluded) return false;
  }
  return true;
}
export {
  canonicalForCrawl,
  canonicalForOutput,
  isPrivateUrl,
  matchesPatterns,
  stripFragment
};
//# sourceMappingURL=url-utils.js.map