import { ErrorChain } from "../error";
import { Field } from "./field";
/** Schema error codes. */
export declare enum ESchemaError {
    Field = "SchemaError.Field",
    Value = "SchemaError.Value"
}
/** Schema error class. */
export declare class SchemaError extends ErrorChain {
    protected readonly isSchemaError = true;
    constructor(code: ESchemaError, cause?: Error, context?: object);
}
/** Schema array type, recursive type. */
export interface ISchemaArray {
    [key: number]: ISchemaFields;
}
/** Schema map type, recursive type. */
export interface ISchemaMap {
    [key: string]: ISchemaFields;
}
/** Schema mask type, recursive type. */
export interface ISchemaMask {
    [key: string]: ISchemaMask | boolean;
}
/** Schema arrays or maps may contain field instances or internal arrays/maps. */
export declare type ISchemaFields = ISchema | Field<any>;
/** Schema root definition must be an array or map. */
export declare type ISchema = ISchemaArray | ISchemaMap;
/** Schema map handlers. */
export interface ISchemaMapHandlers {
    isSchemaArray: (i: any, o: any, schema: Schema<any>, array: ISchemaArray, k: number | string, m?: ISchemaMask, pk?: string) => void;
    isSchemaMap: (i: any, o: any, schema: Schema<any>, map: ISchemaMap, k: number | string, m?: ISchemaMask, pk?: string) => void;
    isField: (i: any, o: any, field: Field<any>, k: number | string, m?: ISchemaMask, pk?: string) => void;
}
export declare class Schema<T = object> {
    readonly schema: ISchema;
    static mapValidateHandlers: ISchemaMapHandlers;
    static mapFormatHandlers: ISchemaMapHandlers;
    /** Returns true if input instance of Schema. */
    static isSchema<X>(schema: any): schema is Schema<X>;
    /** Returns true if input instance of SchemaError. */
    static isSchemaError(error: any): error is SchemaError;
    /**
     * Construct new schema by merging existing schemas.
     * Accepts schema definition objects or existing Schema class instances.
     */
    static extend<E>(...schemas: (Schema<any> | ISchema)[]): Schema<E>;
    /** Used for isSchema static method. */
    protected readonly isSchema = true;
    constructor(schema: ISchema);
    /**
     * Construct new schema using this as a base.
     * Accepts schema definition objects or existing Schema class instances.
     */
    extend<K extends T>(...schemas: (Schema<any> | ISchema)[]): Schema<K>;
    /** Validate input data, transform strings to typed values. */
    validate(data: object, mask?: ISchemaMask, parentKey?: string, schema?: ISchema): T;
    /** Format input data, transform typed values to object of strings for serialisation. */
    format(data: T, mask?: ISchemaMask, parentKey?: string, schema?: ISchema): object;
    /** Helper for iterating over schema fields. */
    map(input: any, output: any, schema: ISchema, handlers: ISchemaMapHandlers, mask?: ISchemaMask, parentKey?: string): void;
    protected mapHandler(input: any, output: any, mask: ISchemaMask | undefined, parentKey: string, handlers: ISchemaMapHandlers, value: any, key: number | string): void;
}
export interface ISchemaFieldContext {
    mask?: ISchemaMask;
    parentKey?: string;
}
export declare class SchemaField<T = object> extends Field<T> {
    protected readonly schema: Schema<T>;
    constructor(instanceOrSchema: Schema<T> | ISchema);
    validate(value: object, context?: ISchemaFieldContext): T;
    format(value: T, context: ISchemaFieldContext): object;
}
