import { type InsertFieldsRequired, type InsertInput, type Row, type Table, type UpdateInput } from "../types";
import type { AbstractIs } from "./predicates/AbstractIs";
import type { AllowIf } from "./rules/AllowIf";
import type { DenyIf } from "./rules/DenyIf";
import { Require } from "./rules/Require";
import type { VC } from "./VC";
export type LoadRule<TInput extends object> = AllowIf<TInput> | DenyIf<TInput>;
/**
 * For safety, we enforce all Require rules to be in the end of the
 * insert/update/delete privacy list, and have at least one of them. In
 * TypeScript, it's not possible to create [...L[], R, ...R[]] type
 * (double-variadic) when both L[] and R[] are open-ended (i.e. tuples with
 * unknown length), so we have to brute-force.
 */
export type WriteRules<TInput extends object> = [] | [Require<TInput>, ...Array<Require<TInput>>] | [LoadRule<TInput>, Require<TInput>, ...Array<Require<TInput>>] | [
    LoadRule<TInput>,
    LoadRule<TInput>,
    Require<TInput>,
    ...Array<Require<TInput>>
] | [
    LoadRule<TInput>,
    LoadRule<TInput>,
    LoadRule<TInput>,
    Require<TInput>,
    ...Array<Require<TInput>>
] | [
    LoadRule<TInput>,
    LoadRule<TInput>,
    LoadRule<TInput>,
    LoadRule<TInput>,
    Require<TInput>,
    ...Array<Require<TInput>>
];
export type ValidationRules<TTable extends Table> = {
    readonly tenantPrincipalField?: InsertFieldsRequired<TTable> & string;
    readonly inferPrincipal: (vc: VC, row: Row<TTable>) => Promise<VC>;
    readonly load: Validation<TTable>["load"];
    readonly insert: Validation<TTable>["insert"];
    readonly update?: Validation<TTable>["update"];
    readonly delete?: Validation<TTable>["delete"];
    readonly validate?: Array<AbstractIs<InsertInput<TTable>>>;
};
export declare class Validation<TTable extends Table> {
    private entName;
    readonly tenantPrincipalField?: ValidationRules<TTable>["tenantPrincipalField"];
    readonly inferPrincipal: ValidationRules<TTable>["inferPrincipal"];
    readonly load: Array<LoadRule<Row<TTable>>>;
    readonly insert: WriteRules<InsertInput<TTable>>;
    readonly update: WriteRules<Row<TTable>>;
    readonly delete: WriteRules<Row<TTable>>;
    readonly validate: Array<Require<InsertInput<TTable>>>;
    constructor(entName: string, rules: ValidationRules<TTable>);
    validateLoad(vc: VC, row: Row<TTable>): Promise<void>;
    validateInsert(vc: VC, input: InsertInput<TTable>): Promise<void>;
    validateUpdate(vc: VC, old: Row<TTable>, input: UpdateInput<TTable>, privacyOnly?: boolean): Promise<void>;
    validateDelete(vc: VC, row: Row<TTable>): Promise<void>;
    private validatePrivacyImpl;
    private validateTenantUserIDImpl;
    private validateUserInputImpl;
}
//# sourceMappingURL=Validation.d.ts.map