import type { VC } from "../VC";
import type { Rule, RuleResult } from "./Rule";
/**
 * This is a hearth of permissions checking, a machine which evaluates the rules
 * chain from top to bottom (one after another) and makes the decision based on
 * the following logic:
 * - ALLOW immediately allows the chain, the rest of the rules are not checked.
 *   It's an eager allowance.
 * - DENY immediately denies the chain, the rest of the rules are not checked.
 *   It's an eager denial.
 * - TOLERATE delegates the decision to the next rules; if it's the last
 *   decision in the chain, then allows the chain. I.e. it's like an allowance,
 *   but only if everyone else is tolerant.
 * - SKIP also delegates the decision to the next rules, but if it's the last
 *   rule in the chain (i.e. nothing to skip to anymore), denies the chain. I.e.
 *   it's "I don't vote here, please ask others".
 * - An empty chain is always denied.
 *
 * Having TOLERATE decision may sound superfluous, but unfortunately it's not.
 * The TOLERATE enables usage of the same machinery for both read-like checks
 * (where we typically want ANY of the rules to be okay with the row) and for
 * write-like checks (where we typically want ALL rules to be okay with the
 * row). Having the same logic for everything simplifies the code.
 *
 * If parallel argument is true, all the rules are run at once in concurrent
 * promises before the machine starts. This doesn't affect the final result,
 * just speeds up processing if we know that there is a high chance that most of
 * the rules will likely return TOLERATE and we'll anyway need to evaluate all
 * of them (e.g. most of the rules are Require, like in write operations). As
 * opposed, for read operation, there is a high chance for the first rule (which
 * is often AllowIf) to succeed, so we evaluate the rules sequentially, not in
 * parallel (to minimize the number of DB queries).
 *
 * Example of a chain (the order of rules always matters!):
 * - new Require(new OutgoingEdgePointsToVC("user_id"))
 * - new Require(new CanReadOutgoingEdge("post_id", EntPost))
 *
 * Example of a chain:
 * - new AllowIf(new OutgoingEdgePointsToVC("user_id"))
 * - new AllowIf(new CanReadOutgoingEdge("post_id", EntPost))
 *
 * Example of a chain:
 * - new DenyIf(new UserIsPendingApproval())
 * - new AllowIf(new OutgoingEdgePointsToVC("user_id"))
 */
export declare function evaluate<TInput extends object>(vc: VC, input: TInput, rules: Array<Rule<TInput>>, fashion: "parallel" | "sequential"): Promise<{
    allow: boolean;
    results: RuleResult[];
    cause: string;
}>;
//# sourceMappingURL=evaluate.d.ts.map