import { AttributeBuilder, Attribute } from './attribute';
import { Relation, RelationsBuilder } from './relation';
export interface Indexes<F> {
    unique: (keyof F)[][];
}
export declare type Records = {
    [alias: string]: SpecType;
};
export declare type Sets = {
    [alias: string]: SpecType;
};
export declare type SpecType<F = {}, R extends Records = Records, S extends Sets = Sets, N extends string = string> = {
    name: N;
    fields: F;
    records: R;
    sets: S;
};
export declare type EmptySpec = SpecType<{}, {}, {}, string>;
export declare type AnySpec = SpecType<any, any, any, string>;
export declare type Model<T extends SpecType> = T['fields'] & {
    [P in keyof T['records']]: Model<T['records'][P]>;
} & {
    [P in keyof T['sets']]: Model<T['sets'][P]>[];
};
export interface Spec<T extends SpecType = SpecType> {
    model: Model<T>;
    type: T;
    scope: string;
    name: T['name'];
    join: boolean;
    attributes: Attribute<T['fields']>[];
    indexes: Indexes<T['fields']>;
    relations: Relation<T>[];
    initialize: () => void;
}
export interface CreateSpecOptions<N extends string> {
    name: N;
    scope: string;
}
export interface SpecBuilder<T extends SpecType> {
    attribute: AttributeBuilder<T['fields']>;
    relation: RelationsBuilder<T>;
    multicolumnUniqueIndex(...fields: (keyof T['fields'])[]): void;
}
export declare function createSpec<T extends SpecType>(options: CreateSpecOptions<T['name']>, initializer?: (specBuilder: SpecBuilder<T>) => void): Spec<T>;
export interface SpecPool {
    [scope: string]: {
        [model: string]: Spec<any>;
    };
}
export declare function initializePool<S extends SpecPool>(pool: S): void;
