// src/actions/deplint/getExtendsFromTsconfigs.ts
import fs from "node:fs";
import PATH from "node:path";
import { globSync } from "glob";

// src/actions/deplint/getBasePackageName.ts
function getBasePackageName(importName) {
  const importNameScrubbed = importName.replaceAll('"', "").trim();
  if (importNameScrubbed.startsWith("@")) {
    const parts = importNameScrubbed.split("/");
    return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : importNameScrubbed;
  }
  return importNameScrubbed.split("/", 1)[0];
}

// src/actions/deplint/getExtendsFromTsconfigs.ts
var isExternalReference = (ref) => !ref.startsWith(".") && !ref.startsWith("/");
function parseExtendsField(value) {
  if (typeof value === "string") return [value];
  if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
  return [];
}
function parseTypesField(value) {
  if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
  return [];
}
function parsePathsField(value) {
  if (typeof value !== "object" || value === null) return [];
  return Object.keys(value);
}
function collectTsconfigFiles(location) {
  const discovered = /* @__PURE__ */ new Set();
  const queue = globSync("./tsconfig*.json", { cwd: location, absolute: true });
  while (queue.length > 0) {
    const file = queue.pop();
    if (file === void 0 || discovered.has(file)) continue;
    discovered.add(file);
    try {
      const parsed = parseTsconfig(file);
      for (const ref of parseExtendsField(parsed.extends)) {
        if (!isExternalReference(ref)) {
          const resolved = PATH.resolve(PATH.dirname(file), ref);
          if (fs.existsSync(resolved) && !discovered.has(resolved)) {
            queue.push(resolved);
          }
        }
      }
    } catch {
    }
  }
  return [...discovered];
}
function isMatchingTsconfigPathPattern(pattern, importPath) {
  const patternParts = pattern.split("/");
  const importParts = importPath.split("/");
  let patternIndex = 0;
  let importIndex = 0;
  while (patternIndex < patternParts.length && importIndex < importParts.length) {
    const patternPart = patternParts[patternIndex];
    if (patternPart === "*") {
      if (patternIndex === patternParts.length - 1) return true;
      patternIndex++;
      importIndex++;
      continue;
    }
    const importPart = importParts[importIndex];
    if (patternPart !== importPart) return false;
    patternIndex++;
    importIndex++;
  }
  if (patternIndex === patternParts.length - 1 && patternParts[patternIndex] === "*") return true;
  return patternIndex === patternParts.length && importIndex === importParts.length;
}
function isTsconfigPathAlias(importPath, pathPatterns) {
  return pathPatterns.some((pattern) => isMatchingTsconfigPathPattern(pattern, importPath));
}
function parseTsconfig(file) {
  const content = fs.readFileSync(file, "utf8");
  const cleaned = content.replaceAll(/\/\/.*/g, "").replaceAll(/,\s*([}\]])/g, "$1");
  return JSON.parse(cleaned);
}
function getPathsFromTsconfigs(location) {
  const patterns = /* @__PURE__ */ new Set();
  for (const file of collectTsconfigFiles(location)) {
    try {
      const parsed = parseTsconfig(file);
      const compilerOptions = parsed.compilerOptions;
      const pathPatterns = parsePathsField(compilerOptions?.paths);
      for (const pattern of pathPatterns) {
        patterns.add(pattern);
      }
    } catch {
    }
  }
  return [...patterns];
}
function getExtendsFromTsconfigs(location) {
  const packages = /* @__PURE__ */ new Set();
  for (const file of collectTsconfigFiles(location)) {
    try {
      const parsed = parseTsconfig(file);
      const refs = parseExtendsField(parsed.extends);
      for (const ref of refs) {
        if (isExternalReference(ref)) {
          packages.add(getBasePackageName(ref));
        }
      }
    } catch {
    }
  }
  return [...packages];
}
function getTypesFromTsconfigs(location) {
  const packages = /* @__PURE__ */ new Set();
  for (const file of collectTsconfigFiles(location)) {
    try {
      const parsed = parseTsconfig(file);
      const compilerOptions = parsed.compilerOptions;
      const refs = parseTypesField(compilerOptions?.types);
      for (const ref of refs) {
        packages.add(getBasePackageName(ref));
      }
    } catch {
    }
  }
  return [...packages];
}
export {
  getExtendsFromTsconfigs,
  getPathsFromTsconfigs,
  getTypesFromTsconfigs,
  isMatchingTsconfigPathPattern,
  isTsconfigPathAlias
};
//# sourceMappingURL=getExtendsFromTsconfigs.mjs.map
