import { Select } from '@fewer/sq';
import { SchemaTable } from '../Schema';
import { SymbolProperties, ValidationError } from './createModel';
import { Pipe } from './pipe';
import { Association, AssociationType } from '../Association';
import { INTERNAL_TYPES, CommonQuery, Associations, WhereType, CreateSelectionSet, Subset, ResolveAssociations } from '../types';
export declare enum QueryTypes {
    SINGLE = 0,
    MULTIPLE = 1
}
declare type CheckUsedKeys<T, K> = T extends K ? 'This key is already in use.' : T;
export declare class Repository<SchemaType = any, RegisteredExtensions = any, SelectionSet = INTERNAL_TYPES.ALL_FIELDS, LoadAssociations extends Associations = {}, JoinAssociations extends Associations = {}, QueryType extends QueryTypes = any, ResolvedType = Subset<SchemaType & RegisteredExtensions & ResolveAssociations<LoadAssociations>, SelectionSet, keyof LoadAssociations>> implements CommonQuery<SchemaType & RegisteredExtensions, LoadAssociations & JoinAssociations> {
    readonly [INTERNAL_TYPES.SCHEMA_TYPE]: SchemaType;
    readonly [INTERNAL_TYPES.RESOLVED_TYPE]: ResolvedType;
    readonly [INTERNAL_TYPES.INTERNAL_TYPE]: SchemaType & RegisteredExtensions;
    /**
     * Contains symbols that are used to access metadata about the state of models.
     */
    readonly symbols: {
        readonly isModel: typeof import("./createModel").IsModel;
        readonly dirty: typeof import("./createModel").Dirty;
        readonly changed: typeof import("./createModel").Changed;
        readonly changes: typeof import("./createModel").Changes;
        readonly valid: typeof import("./createModel").Valid;
        readonly errors: typeof import("./createModel").Errors;
    };
    /**
     * The column that will be used as the primary key.
     */
    readonly primaryKey: keyof SchemaType;
    private schemaTable;
    private runningQuery?;
    private pipes;
    private queryType;
    constructor(schemaTable: SchemaTable<any, SchemaType>, runningQuery: Select | undefined, pipes: Pipe[], queryType: QueryTypes);
    private readonly db;
    [INTERNAL_TYPES.TO_SQ_SELECT](): Select;
    getTableName(): string;
    /**
     * TODO: Documentation.
     */
    pipe<Extensions>(pipe: Pipe<SchemaType & RegisteredExtensions, Extensions>): Repository<SchemaType, RegisteredExtensions & Extensions, SelectionSet, LoadAssociations, JoinAssociations, QueryType>;
    /**
     * Validates an object.
     */
    validate<T extends Partial<SchemaType & RegisteredExtensions> & SymbolProperties<SchemaType & RegisteredExtensions>>(model: T): boolean;
    /**
     * Converts a plain JavaScript object into a Fewer model.
     */
    from<T extends Partial<SchemaType & RegisteredExtensions>>(obj: T): import("./createModel").Model<SchemaType & RegisteredExtensions, T>;
    /**
     * TODO: Documentation.
     */
    create<T extends Partial<SchemaType & RegisteredExtensions>>(obj: T): Promise<any>;
    /**
     * Saves a model in the database.
     */
    save<T extends Partial<SchemaType & RegisteredExtensions> & SymbolProperties<SchemaType & RegisteredExtensions>>(model: T): Promise<any>;
    /**
     * Reloads the model in-place.
     */
    reload<T extends Partial<SchemaType & RegisteredExtensions> & SymbolProperties<SchemaType & RegisteredExtensions>>(model: T, inPlace?: boolean): Promise<any>;
    /**
     * TODO: Documentation.
     */
    where(wheres: WhereType<SchemaType & RegisteredExtensions, JoinAssociations>): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations, JoinAssociations, QueryTypes.MULTIPLE>;
    /**
     * TODO: Documentation.
     */
    find(id: string | number): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations, JoinAssociations, QueryTypes.SINGLE>;
    find(conditions: WhereType<SchemaType & RegisteredExtensions, JoinAssociations>): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations, JoinAssociations, QueryTypes.SINGLE>;
    /**
     * TODO: Documentation.
     */
    pluck<Key extends keyof SchemaType>(...columns: Key[]): Repository<SchemaType, RegisteredExtensions, CreateSelectionSet<SelectionSet, Key>, LoadAssociations, JoinAssociations, QueryType>;
    /**
     * TODO: Documentation
     */
    pluckAs<Key extends keyof SchemaType, Alias extends string>(name: Key, alias: Alias): Repository<SchemaType, RegisteredExtensions & {
        [P in Alias]: SchemaType[Key];
    }, CreateSelectionSet<SelectionSet, Alias>, LoadAssociations, JoinAssociations, QueryType>;
    /**
     * TODO: Documentation.
     */
    order(): void;
    /**
     * TODO: Documentation.
     */
    limit(amount: number): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations, JoinAssociations, QueryType>;
    /**
     * TODO: Documentation.
     */
    offset(amount: number): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations, JoinAssociations, QueryType>;
    /**
     * Loads an association.
     */
    load<Name extends string, LoadAssociation extends Association<AssociationType, Repository<SchemaType>, KeyConstraint>, KeyConstraint = LoadAssociation extends Association<AssociationType.BELONGS_TO> ? keyof SchemaType : any>(name: Name & CheckUsedKeys<Name, keyof LoadAssociations>, association: LoadAssociation): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations & {
        [P in Name]: LoadAssociation;
    }, JoinAssociations, QueryType>;
    /**
     * Resolves the association, but does not load the records.
     */
    join<Name extends string, JoinAssociation extends Association<AssociationType, Repository<SchemaType>, KeyConstraint, any, any, any, any, false>, KeyConstraint = JoinAssociation extends Association<AssociationType.BELONGS_TO> ? keyof SchemaType : any>(name: Name & CheckUsedKeys<Name, keyof JoinAssociations>, association: JoinAssociation): Repository<SchemaType, RegisteredExtensions, SelectionSet, LoadAssociations, JoinAssociations & {
        [P in Name]: JoinAssociation;
    }, QueryType>;
    /**
     * TODO: Documentation.
     */
    then(onFulfilled: (value: QueryType extends QueryTypes.SINGLE ? ResolvedType : ResolvedType[]) => void, onRejected?: (error: Error) => void): Promise<void>;
    private selectQuery;
}
export { ValidationError, Pipe };
/**
 * TODO: Documentation.
 */
export declare function createRepository<Type extends SchemaTable>(schemaTable: Type): Repository<Type[INTERNAL_TYPES.INTERNAL_TYPE], {}, INTERNAL_TYPES.ALL_FIELDS, {}, {}, QueryTypes.MULTIPLE>;
