// src/lib/secure/collectDeclaredDependencies.ts
import { existsSync, readFileSync } from "node:fs";
import PATH from "node:path";
var DEP_FIELDS = ["dependencies", "devDependencies"];
var LOCAL_PROTOCOLS = ["workspace:", "file:", "link:", "portal:"];
function readPackageJson(filePath) {
  if (!existsSync(filePath)) return void 0;
  try {
    return JSON.parse(readFileSync(filePath, "utf8"));
  } catch {
    return void 0;
  }
}
function collectSecurePackageTargets(cwd, workspaces) {
  const targets = [];
  const seenLocations = /* @__PURE__ */ new Set();
  const root = readPackageJson(PATH.resolve(cwd, "package.json"));
  const rootName = root?.name;
  if (rootName !== void 0 && rootName.length > 0) {
    targets.push({ location: ".", name: rootName });
    seenLocations.add(".");
  }
  for (const workspace of workspaces) {
    const normalizedLocation = workspace.location || ".";
    if (seenLocations.has(normalizedLocation)) continue;
    targets.push({ location: normalizedLocation, name: workspace.name });
    seenLocations.add(normalizedLocation);
  }
  return targets.toSorted((a, b) => a.location.localeCompare(b.location));
}
function isLocalSecureDependency(name, range, localPackageNames) {
  return localPackageNames.has(name) || LOCAL_PROTOCOLS.some((protocol) => range.startsWith(protocol));
}
function collectExternalDeclaredDeps(deps, depType, target, localPackageNames, declared) {
  if (!deps) return;
  for (const [name, range] of Object.entries(deps)) {
    if (typeof range !== "string") continue;
    if (isLocalSecureDependency(name, range, localPackageNames)) continue;
    declared.push({
      depType,
      name,
      packageLocation: target.location,
      packageName: target.name,
      range
    });
  }
}
function collectSecureDeclaredDependencies(cwd, targets, localPackageNames) {
  const declared = [];
  for (const target of targets) {
    const pkgPath = PATH.resolve(cwd, target.location, "package.json");
    const pkg = readPackageJson(pkgPath);
    if (!pkg) continue;
    for (const depType of DEP_FIELDS) {
      collectExternalDeclaredDeps(pkg[depType], depType, target, localPackageNames, declared);
    }
  }
  return declared.toSorted((a, b) => {
    return a.name.localeCompare(b.name) || a.packageLocation.localeCompare(b.packageLocation) || a.depType.localeCompare(b.depType);
  });
}
export {
  collectSecureDeclaredDependencies,
  collectSecurePackageTargets,
  isLocalSecureDependency
};
//# sourceMappingURL=collectDeclaredDependencies.mjs.map
