import { APIStructure, Structure } from './Document';
import { Layout } from './Layout';
export type ContainerStructure<Model extends Structure = Structure> = Builder<Model, ContainerStructure<Model>>;
export type Extraction<TModel extends Structure, TLayout extends Layout<TModel, true | false>> = {
    [K in keyof Omit<TModel, 'createdAt' | 'updatedAt'>]: (TLayout[K]['optional']) extends true ? (undefined | TModel[K]) : TModel[K];
} & {
    createdAt: string;
    updatedAt: string;
};
export declare abstract class Builder<TModel extends Structure, TBuilder extends Builder<TModel, TBuilder>> {
    protected _id?: string;
    protected object?: Required<TModel>;
    abstract layout: Layout<TModel, true | false>;
    protected abstract foreign: {
        key: keyof TModel;
        model: string;
        isArray?: boolean;
    }[];
    protected abstract many: {
        key: string;
        model: string;
        reference: boolean;
    }[];
    createLayout<T extends Layout<TModel, B>, B extends true | false>(optional: Omit<T, 'createdAt' | 'updatedAt'>): T;
    hookId(id: string): TBuilder;
    hookObject(object: Extraction<TModel, TBuilder['layout']>): TBuilder;
    abstract instantiate(_id: string, _object: Extraction<TModel, TBuilder['layout']>): TBuilder;
    build(object: [string, Extraction<TModel, TBuilder['layout']>]): TBuilder;
    create(object: Extraction<TModel, TBuilder['layout']>, id: string): TBuilder;
    mutate(new_model: Partial<TModel>): TBuilder;
    prune(key: keyof TModel): TBuilder;
    update(new_model: Partial<TModel>, updater: ((old_object: Extraction<TModel, TBuilder['layout']>, new_object: TBuilder) => void) | undefined): TBuilder;
    list(object: Record<string, TModel>): Map<string, TBuilder>;
    generate(): TModel;
    private handleMissing;
    private handleMismatch;
    private processKeyValidate;
    private handleExtra;
    private processValidation;
    validateObject(object: Extraction<TModel, TBuilder['layout']>, updating?: boolean, silent?: boolean): TModel;
    validate(updating?: boolean, silent?: boolean): TBuilder;
    fixateExtra(obj: TModel): {
        fixed: TModel;
        fix: {
            data: APIStructure | undefined;
            type: string;
        }[];
    };
    extractExtra(obj: TModel): {
        extracted: TModel;
        extra: {
            data: APIStructure[];
            type: string;
        }[];
    };
    abstract get extract(): Extraction<TModel, TBuilder['layout']>;
    get extra(): string[] | undefined;
    get safeExtract(): never;
    get generateDefault(): TModel;
    get id(): string;
    get getObj(): Required<TModel>;
    toString(): string;
}
