#!/usr/bin/env node

// src/utils/repo-root.ts
import { existsSync } from "fs";
import path from "path";
import { fileURLToPath } from "url";
function isRepoRoot(candidate) {
  return existsSync(path.join(candidate, "pnpm-workspace.yaml")) && existsSync(path.join(candidate, "apps", "dreamboard-cli", "package.json"));
}
function resolveCliRepoRoot(importMetaUrl = import.meta.url) {
  let current = path.dirname(fileURLToPath(importMetaUrl));
  while (true) {
    if (isRepoRoot(current)) {
      return current;
    }
    const parent = path.dirname(current);
    if (parent === current) {
      break;
    }
    current = parent;
  }
  throw new Error(
    `Could not resolve Dreamboard CLI repo root from ${importMetaUrl}.`
  );
}

// src/utils/repo-local-package-resolution.ts
import { existsSync as existsSync2, readdirSync, readFileSync } from "fs";
import { createRequire } from "module";
import path2 from "path";
var PACKAGE_INFO_CACHE = /* @__PURE__ */ new Map();
function normalizeRepoRoot(options) {
  return options?.repoRoot ?? resolveCliRepoRoot(import.meta.url);
}
function readPackageInfos(repoRoot) {
  const cached = PACKAGE_INFO_CACHE.get(repoRoot);
  if (cached) {
    return cached;
  }
  const packageInfos = /* @__PURE__ */ new Map();
  const addPackageInfo = (packageRoot) => {
    const packageJsonPath = path2.join(packageRoot, "package.json");
    if (!existsSync2(packageJsonPath)) {
      return;
    }
    const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
    if (!parsed.name || !parsed.name.startsWith("@dreamboard/") && !parsed.name.startsWith("@dreamboard-games/") || parsed.exports === void 0) {
      return;
    }
    packageInfos.set(parsed.name, {
      rootDir: packageRoot,
      exports: parsed.exports
    });
  };
  for (const workspaceDirName of ["packages", "apps"]) {
    const workspaceRoot = path2.join(repoRoot, workspaceDirName);
    if (!existsSync2(workspaceRoot)) {
      continue;
    }
    for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {
      if (!entry.isDirectory()) {
        continue;
      }
      addPackageInfo(path2.join(workspaceRoot, entry.name));
    }
  }
  for (const nodeModulesRoot of [
    path2.join(repoRoot, "node_modules"),
    path2.join(repoRoot, "apps", "dreamboard-cli", "node_modules")
  ]) {
    for (const scopeName of ["@dreamboard", "@dreamboard-games"]) {
      const scopeRoot = path2.join(nodeModulesRoot, scopeName);
      if (!existsSync2(scopeRoot)) {
        continue;
      }
      for (const entry of readdirSync(scopeRoot, { withFileTypes: true })) {
        if (!entry.isDirectory() && !entry.isSymbolicLink()) {
          continue;
        }
        addPackageInfo(path2.join(scopeRoot, entry.name));
      }
    }
  }
  PACKAGE_INFO_CACHE.set(repoRoot, packageInfos);
  return packageInfos;
}
function parseDreamboardPackageSpecifier(specifier) {
  if (!specifier.startsWith("@dreamboard/") && !specifier.startsWith("@dreamboard-games/")) {
    return null;
  }
  const segments = specifier.split("/");
  if (segments.length < 2) {
    return null;
  }
  const packageName = `${segments[0]}/${segments[1]}`;
  const subpath = segments.length === 2 ? "." : `./${segments.slice(2).join("/")}`;
  return { packageName, subpath };
}
function resolveSourceTarget(exportEntry) {
  if (typeof exportEntry === "string") {
    return exportEntry;
  }
  if (typeof exportEntry === "object" && exportEntry !== null && "dreamboard-source" in exportEntry && typeof exportEntry["dreamboard-source"] === "string") {
    return exportEntry["dreamboard-source"];
  }
  if (typeof exportEntry === "object" && exportEntry !== null && "bun" in exportEntry && typeof exportEntry.bun === "string") {
    return exportEntry.bun;
  }
  if (typeof exportEntry === "object" && exportEntry !== null && "import" in exportEntry && typeof exportEntry.import === "string") {
    return exportEntry.import;
  }
  return null;
}
function resolveSourceTargetForSubpath(options) {
  if (typeof options.exportsField !== "object" || options.exportsField === null || Array.isArray(options.exportsField)) {
    return options.subpath === "." ? resolveSourceTarget(options.exportsField) : null;
  }
  const exportsMap = options.exportsField;
  if (options.subpath === ".") {
    return resolveSourceTarget(exportsMap["."]) ?? resolveSourceTarget(exportsMap);
  }
  const exactTarget = resolveSourceTarget(exportsMap[options.subpath]);
  if (exactTarget) {
    return exactTarget;
  }
  const wildcardEntries = Object.entries(exportsMap).filter(([key]) => key.includes("*")).sort(([left], [right]) => right.length - left.length);
  for (const [pattern, exportEntry] of wildcardEntries) {
    const starIndex = pattern.indexOf("*");
    const prefix = pattern.slice(0, starIndex);
    const suffix = pattern.slice(starIndex + 1);
    if (!options.subpath.startsWith(prefix) || !options.subpath.endsWith(suffix)) {
      continue;
    }
    const wildcardValue = options.subpath.slice(
      prefix.length,
      options.subpath.length - suffix.length
    );
    const targetPattern = resolveSourceTarget(exportEntry);
    if (!targetPattern) {
      continue;
    }
    return targetPattern.replace("*", wildcardValue);
  }
  return null;
}
function resolveRepoLocalPackageSource(specifier, options) {
  const parsedSpecifier = parseDreamboardPackageSpecifier(specifier);
  if (!parsedSpecifier) {
    return null;
  }
  let repoRoot;
  try {
    repoRoot = normalizeRepoRoot(options);
  } catch {
    return null;
  }
  const packageInfo = readPackageInfos(repoRoot).get(
    parsedSpecifier.packageName
  );
  if (!packageInfo) {
    return null;
  }
  const sourceTarget = resolveSourceTargetForSubpath({
    exportsField: packageInfo.exports,
    subpath: parsedSpecifier.subpath
  });
  if (!sourceTarget) {
    return null;
  }
  return path2.join(packageInfo.rootDir, sourceTarget);
}
var cliPackageRequire = createRequire(import.meta.url);
function resolvableFromDirectory(specifier, directory) {
  try {
    createRequire(path2.join(directory, "noop.js")).resolve(specifier);
    return true;
  } catch {
    return false;
  }
}
function resolveCliBundledPackage(specifier) {
  try {
    return cliPackageRequire.resolve(specifier);
  } catch {
    return null;
  }
}
function createRepoLocalPackageResolutionPlugin(options) {
  return {
    name: "dreamboard-repo-local-package-resolution",
    setup(build) {
      build.onResolve({ filter: /^@dreamboard(?:-games)?\// }, (args) => {
        const resolvedPath = resolveRepoLocalPackageSource(args.path, options);
        if (resolvedPath) {
          return { path: resolvedPath };
        }
        if (resolvableFromDirectory(args.path, args.resolveDir)) {
          return null;
        }
        const bundledPath = resolveCliBundledPackage(args.path);
        if (bundledPath) {
          return { path: bundledPath };
        }
        return null;
      });
    }
  };
}

export {
  resolveCliRepoRoot,
  createRepoLocalPackageResolutionPlugin
};
//# sourceMappingURL=chunk-QBAF7EYR.mjs.map