import * as defuss_runtime from 'defuss-runtime';
import { PathAccessor, ValidationStep } from 'defuss-runtime';
export * from 'defuss-runtime';

type ValidationChain<ET = {}> = ValidationChainApi<ET> & ET;
interface FieldValidationMessage<T = string> {
    message: T;
    path: string;
}
interface ValidationChainApi<ET = {}> {
    fieldPath: string | PathAccessor<any>;
    validationCalls: Call[];
    lastValidationResult: AllValidationResult;
    transformedData: any;
    options: ValidationChainOptions;
    not: ValidationChainApi<ET> & ET;
    isSafeNumber(message?: string): ValidationChain<ET>;
    isString(message?: string): ValidationChain<ET>;
    isArray(message?: string): ValidationChain<ET>;
    isObject(message?: string): ValidationChain<ET>;
    isDate(message?: string): ValidationChain<ET>;
    isSafeNumeric(message?: string): ValidationChain<ET>;
    isBoolean(message?: string): ValidationChain<ET>;
    isInteger(message?: string): ValidationChain<ET>;
    isNull(message?: string): ValidationChain<ET>;
    isRequired(message?: string): ValidationChain<ET>;
    isUndefined(message?: string): ValidationChain<ET>;
    isDefined(message?: string): ValidationChain<ET>;
    isEmpty(message?: string): ValidationChain<ET>;
    isInstanceOf<T extends new (...args: any[]) => any>(someConstructorFunction: T, message?: string): ValidationChain<ET>;
    isTypeOf(type: string, message?: string): ValidationChain<ET>;
    isNull(message?: string): ValidationChain<ET>;
    isEmail(message?: string): ValidationChain<ET>;
    isUrl(message?: string): ValidationChain<ET>;
    isUrlPath(message?: string): ValidationChain<ET>;
    isSlug(message?: string): ValidationChain<ET>;
    isPhoneNumber(message?: string): ValidationChain<ET>;
    hasDateFormat(format: string, message?: string): ValidationChain<ET>;
    hasPattern(pattern: RegExp, message?: string): ValidationChain<ET>;
    is(v: any, message?: string): ValidationChain<ET>;
    isEqual<T>(value: T, message?: string): ValidationChain<ET>;
    isInstanceOf<T>(c: new (...args: any[]) => T, message?: string): ValidationChain<ET>;
    isTypeOf(type: string, message?: string): ValidationChain<ET>;
    isOneOf<T extends readonly (string | number)[]>(options: T, message?: string): ValidationChain<ET>;
    isTrue(message?: string): ValidationChain<ET>;
    isFalse(message?: string): ValidationChain<ET>;
    isTruthy(message?: string): ValidationChain<ET>;
    isFalsy(message?: string): ValidationChain<ET>;
    isLongerThan(minLength: number, inclusive?: boolean, message?: string): ValidationChain<ET>;
    isShorterThan(maxLength: number, inclusive?: boolean, message?: string): ValidationChain<ET>;
    isGreaterThan(minValue: number, inclusive?: boolean, message?: string): ValidationChain<ET>;
    isLessThan(maxValue: number, inclusive?: boolean, message?: string): ValidationChain<ET>;
    isAfter(minDate: Date, inclusive?: boolean, message?: string): ValidationChain<ET>;
    isBefore(maxDate: Date, inclusive?: boolean, message?: string): ValidationChain<ET>;
    asString(): ValidationChain<ET>;
    asNumber(): ValidationChain<ET>;
    asBoolean(): ValidationChain<ET>;
    asDate(): ValidationChain<ET>;
    asArray(transformerFn: (value: any) => any): ValidationChain<ET>;
    asInteger(): ValidationChain<ET>;
    useFormatter(messageFn: (messages: FieldValidationMessage[], format: (msgs: FieldValidationMessage[]) => string) => string): ValidationChain<ET>;
    isValid<T = unknown>(formData: T): Promise<boolean>;
    getMessages(): FieldValidationMessage[];
    getData(): any;
    getField(path: string | PathAccessor<any>): any;
}
interface ValidationChainOptions {
    timeout?: number;
    onValidationError?: <T extends unknown[] = unknown[]>(error: Error, step: ValidationStep<T>) => void;
}
interface AllValidationResult {
    isValid: boolean;
    messages: FieldValidationMessage[];
    error?: Error;
}

declare class Call<VT = boolean> {
    name: string;
    fn: (...args: any[]) => Promise<VT>;
    args: any[];
    type: "validator" | "transformer";
    constructor(name: string, fn: (...args: any[]) => Promise<VT>, args: any[], type?: "validator" | "transformer");
}
declare class Rules<ET = ValidationChainApi> implements ValidationChainApi<ET> {
    fieldPath: string | PathAccessor<any>;
    validationCalls: Call[];
    lastValidationResult: AllValidationResult;
    transformedData: any;
    options: ValidationChainOptions;
    messageFormatter?: (messages: FieldValidationMessage[], format: (msgs: FieldValidationMessage[]) => string) => string;
    _state: {
        isNegated: boolean;
        hasValidators: boolean;
    };
    constructor(fieldPath: string | PathAccessor<any>, options?: ValidationChainOptions);
    get not(): ValidationChainApi<ET> & ET;
    protected _handleValidationError(error: Error, callback?: (isValid: boolean, error?: Error) => void): boolean;
    isValid<T = any>(formData: T, callback?: (isValid: boolean, error?: Error) => void): Promise<boolean>;
    private _triggerValidation;
    private _executeValidation;
    private _buildValidationResult;
    private _buildErrorResult;
    private _getFieldValue;
    useFormatter(messageFn?: (messages: FieldValidationMessage[], format: (msgs: FieldValidationMessage[]) => string) => string): ValidationChainApi<ET> & ET;
    getMessages(): FieldValidationMessage[];
    getData(): any;
    getField(path: string | PathAccessor<any>): any;
    then<TResult1 = boolean, TResult2 = never>(onfulfilled?: ((value: Rules<ET>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
}
declare function rule(fieldPath: string | PathAccessor<any>, options?: ValidationChainOptions): ValidationChainApi<Rules>;
declare namespace rule {
    var extend: <ET extends new (...args: any[]) => any>(ExtensionClass: ET) => {
        (fieldPath: string | PathAccessor<any>, options?: ValidationChainOptions): ValidationChainApi<InstanceType<ET>> & InstanceType<ET>;
        extend: /*elided*/ any;
    };
}
declare function transval(...args: (Rules | Rules[])[]): {
    isValid: <T = any>(formData: T, callback?: (isValid: boolean, error?: Error) => void) => Promise<boolean>;
    getMessages: <T = FieldValidationMessage[]>(path?: string | PathAccessor<any>, customFormatterFn?: (messages: FieldValidationMessage[]) => T) => T;
    getData: () => any;
    getField: (path: string | PathAccessor<any>) => any;
};
type ExtendedValidationChain<T> = Rules & T;

declare const transformers: {
    asArray: (...args: any[]) => any;
    asBoolean: (...args: any[]) => any;
    asDate: (...args: any[]) => any;
    asInteger: (...args: any[]) => any;
    asNumber: (...args: any[]) => any;
    asString: (...args: any[]) => any;
};

declare const validators: {
    isAfter: defuss_runtime.ValidatorFn<any[]>;
    isArray: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isBefore: defuss_runtime.ValidatorFn<any[]>;
    isBoolean: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isDate: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isDefined: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isEmail: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isEmpty: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    is: defuss_runtime.ValidatorFn<any[]>;
    isEqual: defuss_runtime.ValidatorFn<any[]>;
    isGreaterThan: defuss_runtime.ValidatorFn<any[]>;
    isInteger: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isLongerThan: defuss_runtime.ValidatorFn<any[]>;
    isLessThan: defuss_runtime.ValidatorFn<any[]>;
    isSafeNumber: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isSafeNumeric: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isObject: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isOneOf: defuss_runtime.ValidatorFn<any[]>;
    isPhoneNumber: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isRequired: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isShorterThan: defuss_runtime.ValidatorFn<any[]>;
    isSlug: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isString: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isUrl: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    isUrlPath: defuss_runtime.ValidatorPrimitiveFn<unknown>;
    hasPattern: defuss_runtime.ValidatorFn<any[]>;
    isTrue: defuss_runtime.ValidatorFn<any[]>;
    isFalse: defuss_runtime.ValidatorFn<any[]>;
    isTruthy: defuss_runtime.ValidatorFn<any[]>;
    isFalsy: defuss_runtime.ValidatorFn<any[]>;
    hasDateFormat: defuss_runtime.ValidatorFn<any[]>;
    isInstanceOf: defuss_runtime.ValidatorFn<any[]>;
    isTypeOf: defuss_runtime.ValidatorFn<any[]>;
    isNull: defuss_runtime.ValidatorPrimitiveFn<unknown>;
};

export { type AllValidationResult, Call, type ExtendedValidationChain, type FieldValidationMessage, Rules, type ValidationChainApi, type ValidationChainOptions, rule, transformers, transval, validators };
