import fs from "node:fs";
import fsp from "node:fs/promises";
import path from "pathe";
import { exists } from "./exists.js";
export async function findWorkspaceRoot(directory = process.cwd()) {
    const checks = await Promise.all(Object.entries(predicates).map(async ([file, predicate]) => {
        return await check(path.join(directory, file), predicate);
    }));
    if (checks.includes(true)) {
        return directory;
    }
    const parent = path.resolve(directory, "..");
    if (parent === directory) {
        // Bail if we've reached the filesystem root to avoid infinite recursion
        return directory;
    }
    return await findWorkspaceRoot(parent);
}
export function findWorkspaceRootSync(directory = process.cwd()) {
    for (const [file, predicate] of Object.entries(predicates)) {
        const filePath = path.join(directory, file);
        if (checkSync(filePath, predicate)) {
            return directory;
        }
    }
    const parent = path.resolve(directory, "..");
    if (parent === directory) {
        // Bail if we've reached the filesystem root to avoid infinite recursion
        return directory;
    }
    return findWorkspaceRootSync(parent);
}
async function check(filePath, predicate) {
    if (!(await exists(filePath))) {
        return false;
    }
    if (typeof predicate === "function") {
        try {
            const value = await fsp.readFile(filePath, "utf-8");
            const json = JSON.parse(value);
            return predicate(json);
        }
        catch {
            return false;
        }
    }
    else {
        return true;
    }
}
function checkSync(filePath, predicate) {
    if (!fs.existsSync(filePath)) {
        return false;
    }
    if (typeof predicate === "function") {
        try {
            const value = fs.readFileSync(filePath, "utf-8");
            const json = JSON.parse(value);
            return predicate(json);
        }
        catch {
            return false;
        }
    }
    else {
        return predicate;
    }
}
const predicates = {
    // bun
    "bun.lock": true,
    "bun.lockb": true,
    // git
    ".git": true,
    // lerna
    "lerna.json": true,
    // npm
    "package.json": (value) => "workspaces" in value,
    "package-lock.json": true,
    // nx
    "nx.json": true,
    // pnpm
    "pnpm-lock.yaml": true,
    "pnpm-workspace.yaml": true,
    "pnpm-workspace.yml": true,
    // rush
    "rush.json": true,
    // turbo
    // (a monorepo can contain more than one turbo.json, but unless it's the root, it must contain the `extends` property)
    "turbo.json": (value) => !("extends" in value),
    // yarn
    "yarn.lock": true,
};
//# sourceMappingURL=find-workspace-root.js.map