/// <reference types="node" />
import { EntityManager, QueryRunner, Connection } from 'typeorm';
import { IsolationLevel } from 'typeorm/driver/types/IsolationLevel';
import { EventEmitter } from 'events';
import { Namespace } from 'cls-hooked';
export declare function createTransactionsNamespace(): Namespace;
export declare function getTransactionsNamespace(): Namespace;
export declare function bindTransactionsNamespace(req: EventEmitter, res: EventEmitter, next: AnyFunction): void;
export declare function execInTransactionsNamespace<R extends AnyFunction>(cb: R): Promise<ReturnType<R>>;
export declare class Transaction<T extends Repositories = Repositories> implements ITransaction<T> {
    protected readonly _options: ITransactionOptions<T>;
    protected _repositories: RepositoriesInstances<T>;
    protected _connection: Connection;
    protected readonly _queryRunner: QueryRunner;
    protected readonly _shouldUseNs: boolean;
    protected readonly _hasParentTransaction: boolean;
    protected readonly _transactionId?: string;
    protected readonly _parentTransaction?: ITransaction<T>;
    constructor(_options: ITransactionOptions<T>);
    get repositories(): RepositoriesInstances<T>;
    get manager(): EntityManager;
    get id(): string | number | boolean;
    begin(): Promise<void>;
    commit(): Promise<void>;
    rollback(error?: string | Error): Promise<void>;
    protected _validateNsAvailability(): void;
}
export declare class UnitOfWork<T extends Repositories = Repositories> implements IUnitOfWork<T> {
    protected readonly _options: IUnitOfWorkOptions<T>;
    protected _repositories: RepositoriesInstances<T>;
    protected _connection: Connection;
    constructor(_options?: IUnitOfWorkOptions<T>);
    exec<R>(cb: UnitOfWorkExecutor<T, R>): Promise<R>;
    protected _getRepositories(manager: EntityManager): RepositoriesInstances<T>;
}
export declare class TransactionManager<T extends Repositories = Repositories> implements ITransactionManager<T> {
    protected readonly _options: ITransactionManagerOptions<T>;
    protected _repositories: RepositoriesInstances<T>;
    protected _connection: Connection;
    constructor(_options?: ITransactionManagerOptions<T>);
    unitOfWork<R>(cb: UnitOfWorkExecutor<T, R>, options?: UnitOfWorkExecutorOptions<T>): Promise<R>;
    createUnitOfWork<C extends Repositories = T>(options?: UnitOfWorkExecutorOptions<C>): UnitOfWork<C>;
    transaction<C extends Repositories = T>(options?: TransactionExecutorOptions<C>): Promise<ITransaction<C>>;
    transaction<C extends Repositories = T, R = unknown>(cb: TransactionExecutor<C, R>, options?: TransactionExecutorOptions<C>): Promise<R>;
    createTransaction<C extends Repositories = T>(options?: TransactionExecutorOptions<C>): ITransaction<C>;
    get connection(): Connection;
    get repositories(): RepositoriesInstances<T>;
    protected _getDefaults<O extends TransactionExecutorOptions>(options?: O): O;
    protected _validateOptions(options: TransactionExecutorOptions): void;
}
export declare type AnyFunction<T = any> = (...args: any) => T;
export declare type Repository<T = any> = new (manager: EntityManager, ...args: any[]) => T;
export declare type Repositories = Record<string, Repository>;
export declare type RepositoriesInstances<T extends Repositories = Repositories> = {
    [K in keyof T]: InstanceType<T[K]>;
};
export declare type RepositoryConstructorParams = (() => any[]) | any[];
export interface ITransactionManager<T extends Repositories = Repositories> {
    connection: Connection;
    repositories: RepositoriesInstances<T>;
    unitOfWork<R>(cb: UnitOfWorkExecutor<T, R>, options?: UnitOfWorkExecutorOptions<T>): Promise<R>;
    createUnitOfWork<C extends Repositories = T>(options?: UnitOfWorkExecutorOptions<C>): UnitOfWork<C>;
    transaction<C extends Repositories = T>(options?: TransactionExecutorOptions<C>): Promise<ITransaction<C>>;
    transaction<C extends Repositories = T, R = unknown>(cb: TransactionExecutor<C, R>, options?: TransactionExecutorOptions<C>): Promise<R>;
    createTransaction<C extends Repositories = T>(options?: TransactionExecutorOptions<C>): ITransaction<C>;
}
export interface ITransactionManagerOptions<T extends Repositories = Repositories> extends ITransactionOptions<T> {
    defaultTransactionId?: string | number | boolean;
}
export interface ITransaction<T extends Repositories = Repositories> {
    manager: EntityManager;
    repositories: RepositoriesInstances<T>;
    id?: string | number | boolean;
    begin(): Promise<void>;
    commit(): Promise<void>;
    rollback(error?: string | Error): Promise<void>;
}
export interface ITransactionOptions<T extends Repositories = Repositories> extends IUnitOfWorkOptions<T> {
    id?: string | number | false;
    transaction?: ITransaction<T>;
}
export declare type TransactionExecutor<T extends Repositories = Repositories, R = unknown> = (transaction: ITransaction<T>) => Promise<R>;
export declare type TransactionExecutorOptions<T extends Repositories = Repositories> = Omit<ITransactionOptions<T>, 'connection' | 'connectionName'>;
export interface IUnitOfWork<T extends Repositories = Repositories> {
    exec<R>(cb: UnitOfWorkExecutor<T, R>): Promise<R>;
}
export interface IUnitOfWorkOptions<T extends Repositories = Repositories> {
    connection?: Connection | AnyFunction<Connection>;
    connectionName?: string | AnyFunction<string>;
    manager?: EntityManager;
    repositories?: T;
    repositoryConstructorParams?: RepositoryConstructorParams;
    isolationLevel?: IsolationLevel;
}
export declare type UnitOfWorkExecutor<T extends Repositories = Repositories, R = unknown> = (unitOfWork: UnitOfWorkExecutorPayload<T>) => Promise<R>;
export declare type UnitOfWorkExecutorPayload<T extends Repositories = Repositories> = {
    manager: EntityManager;
    repositories: RepositoriesInstances<T>;
};
export declare type UnitOfWorkExecutorOptions<T extends Repositories = Repositories> = Omit<IUnitOfWorkOptions<T>, 'connection' | 'connectionName'>;
export declare type Transactionable<T extends Repositories = Repositories> = {
    transaction?: ITransaction<T>;
};
