// src/actions/statics.ts
import chalk3 from "chalk";

// src/lib/dependencies/detectDuplicateDependencies.ts
import { execSync } from "node:child_process";

// src/pm/workspaces.ts
import { existsSync, readFileSync } from "node:fs";
import PATH from "node:path";
import { globSync } from "glob";
function readJsonFile(path) {
  if (!existsSync(path)) return void 0;
  try {
    return JSON.parse(readFileSync(path, "utf8"));
  } catch {
    return void 0;
  }
}
function readRootPackageJson(cwd = process.cwd()) {
  return readJsonFile(PATH.resolve(cwd, "package.json"));
}
function detectPackageManagerFromPackageJson(cwd = process.cwd()) {
  const packageManager = readRootPackageJson(cwd)?.packageManager;
  if (!packageManager) return void 0;
  return packageManager.split("@")[0];
}

// src/pm/detectPackageManager.ts
import { existsSync as existsSync2 } from "node:fs";
var knownPackageManagers = /* @__PURE__ */ new Set(["bun", "npm", "pnpm", "yarn"]);
function detectPackageManager() {
  const packageManager = detectPackageManagerFromPackageJson();
  if (packageManager && knownPackageManagers.has(packageManager)) {
    return packageManager;
  }
  if (existsSync2("pnpm-lock.yaml") || existsSync2("pnpm-workspace.yaml")) return "pnpm";
  if (existsSync2("bun.lock") || existsSync2("bun.lockb")) return "bun";
  if (existsSync2("yarn.lock") || existsSync2(".yarnrc.yml")) return "yarn";
  if (existsSync2("package-lock.json") || existsSync2("npm-shrinkwrap.json")) return "npm";
  return "yarn";
}

// src/pm/registry.ts
var implementations = /* @__PURE__ */ new Map();
function getPackageManager(name) {
  const pmName = name ?? detectPackageManager();
  const pm = implementations.get(pmName);
  if (!pm) {
    throw new Error(
      `No package manager implementation registered for "${pmName}". Ensure registerPackageManager() has been called before getPackageManager().`
    );
  }
  return pm;
}

// src/lib/processEx.ts
import chalk from "chalk";

// src/lib/withError.ts
var withError = (ex, closure, predicate = (ex2) => !!ex2.name && !!ex2.message) => {
  return predicate(ex) ? closure(ex) : void 0;
};

// src/lib/withErrnoException.ts
var withErrnoException = (ex, closure) => {
  return withError(ex, closure, (ex2) => ex2.errno !== void 0);
};

// src/lib/processEx.ts
var processEx = (ex) => {
  const error = typeof ex === "string" ? new Error(ex) : ex;
  const exitCode = withErrnoException(error, (error2) => {
    if (error2.code === "ENOENT") {
      console.error(chalk.red(`'${error2.path}' not found.`));
    } else {
      console.error(chalk.red(`Errno: ${error2.code}`));
    }
    return error2.errno ?? -1;
  }) ?? withError(error, (error2) => {
    console.error(chalk.red(`${error2.name}: ${error2.message}`));
    return -1;
  }) ?? (() => {
    console.error(chalk.red(`Unexpected Error: ${JSON.stringify(ex, null, 2)}`));
    return -1;
  })();
  process.exit(process.exitCode ?? exitCode);
};

// src/lib/safeExit.ts
var safeExit = (func, exitOnFail = true) => {
  try {
    const result = func();
    if (result && exitOnFail) {
      process.exit(result);
    }
    return result;
  } catch (ex) {
    return processEx(ex);
  }
};

// src/lib/dependencies/DuplicateDetector.ts
import { EOL } from "node:os";
import chalk2 from "chalk";

// src/lib/jsonFormatters.ts
var multiLineToJSONArray = (output) => {
  const withCommas = output.replaceAll("\r\n", "").replaceAll("\n", ",");
  const cleanCollection = withCommas.slice(0, Math.max(0, withCommas.length - 1));
  const collection = `[${cleanCollection}]`;
  return JSON.parse(collection);
};

// src/lib/dependencies/DuplicateDetector.ts
var trimVirtualMeta = (value) => {
  const virtualParts = value.split("virtual:");
  if (virtualParts.length > 1) {
    const hashParts = virtualParts[1].split("#");
    return virtualParts[0] + hashParts[1];
  } else {
    return value;
  }
};
var trimObjectDependencyVirtualMeta = (obj) => {
  const resultObj = {};
  for (const [key, value] of Object.entries(obj)) {
    resultObj[trimVirtualMeta(key)] = {
      descriptor: trimVirtualMeta(value.descriptor),
      locator: trimVirtualMeta(value.locator)
    };
  }
  return resultObj;
};
var trimDependencyVirtualMeta = (dependencies) => {
  return dependencies.map((dependency) => {
    return { children: trimObjectDependencyVirtualMeta(dependency.children), value: trimVirtualMeta(dependency.value) };
  });
};
function extractPnpmVersions(data, depName) {
  const versions = /* @__PURE__ */ new Set();
  function walk(obj) {
    if (Array.isArray(obj)) {
      for (const item of obj) walk(item);
    } else if (obj && typeof obj === "object") {
      const record = obj;
      if (typeof record.version === "string" && typeof record.from === "string" && record.from === depName) {
        versions.add(record.version);
      }
      for (const val of Object.values(record)) walk(val);
    }
  }
  walk(data);
  return [...versions];
}
var DuplicateDetector = class {
  dependency;
  duplicateVersions;
  constructor(output, dependency) {
    this.dependency = dependency;
    this.duplicateVersions = this.parseVersions(output, dependency);
  }
  detect() {
    if (this.duplicateVersions.length > 1) {
      console.log(chalk2.yellow(`${EOL}Duplicates found for: ${this.dependency}`));
      const duplicateVersions = this.duplicateVersions.join(`${EOL}  `);
      console.log(chalk2.grey(`  ${duplicateVersions}`, EOL));
      return 1;
    } else {
      console.log(`${this.dependency} - OK`);
      return 0;
    }
  }
  parseVersions(output, dependency) {
    try {
      const parsed = JSON.parse(output);
      if (Array.isArray(parsed)) {
        return extractPnpmVersions(parsed, dependency);
      }
    } catch {
    }
    try {
      const entries = trimDependencyVirtualMeta(multiLineToJSONArray(output));
      const versions = /* @__PURE__ */ new Set();
      for (const entry of entries) {
        for (const key of Object.keys(entry.children)) {
          const version = key.includes("@virtual:") ? void 0 : key;
          if (version) versions.add(version);
        }
      }
      return [...versions];
    } catch {
      console.warn(chalk2.yellow(`Could not parse dependency output for ${dependency}`));
      return [];
    }
  }
};

// src/lib/dependencies/detectDuplicateDependencies.ts
var detectDuplicateDependencies = (depsFromPackageJSON, DefaultDependencies2, exitOnFail = true) => {
  let exitCode = 0;
  const dependencies = depsFromPackageJSON?.length ? depsFromPackageJSON : DefaultDependencies2;
  return safeExit(() => {
    if (dependencies) {
      for (const dependency of dependencies) {
        let output;
        try {
          const pm = getPackageManager();
          const cmd = `${pm.command} why ${dependency} --json`;
          output = execSync(cmd, { maxBuffer: 64 * 1024 * 1024 }).toString();
        } catch (e) {
          console.error(`Error running dependency check: ${String(e)}`);
          exitCode = 1;
          continue;
        }
        if (output) {
          exitCode = new DuplicateDetector(output, dependency).detect();
        } else {
          console.log(`${dependency} - N/A`);
          if (depsFromPackageJSON) {
            exitCode = 1;
            console.log(`\u{1F6A8} Library ${dependency} was requested in package.json but not found`);
          }
        }
      }
      return exitCode;
    } else {
      console.log("\u{1F6A8} No dependencies where passed");
      return exitCode;
    }
  }, exitOnFail);
};

// src/lib/parsedPackageJSON.ts
import { readFileSync as readFileSync2 } from "node:fs";
var parsedPackageJSON = (path) => {
  const pathToPackageJSON = path ?? process.env.npm_package_json ?? "";
  const packageJSON = readFileSync2(pathToPackageJSON).toString();
  return JSON.parse(packageJSON);
};

// src/lib/reporting/xyReporter.ts
var strictMode = false;
function isStrictMode() {
  return strictMode || process.env.XY_STRICT === "1";
}

// src/actions/statics.ts
var DefaultDependencies = ["axios", "@xylabs/pixel", "react", "graphql", "react-router", "@mui/material", "@mui/system"];
var statics = () => {
  console.log(chalk3.green("Check Required Static Dependencies"));
  const pkg = parsedPackageJSON();
  const xy = pkg?.xy;
  const deps = xy?.deps;
  const staticsValue = deps?.statics;
  const result = detectDuplicateDependencies(staticsValue, DefaultDependencies, false);
  return isStrictMode() ? result : 0;
};
export {
  statics
};
//# sourceMappingURL=statics.mjs.map
