import OmitCallSignature from "omit-call-signature";
/**
 * @tested_by tests/index.test.ts
 */
export declare namespace ApiErrors {
    type ErrorType = {
        error: string;
    };
    class Error {
        errorCode: number;
        description: string;
        route: string | undefined;
        constructor(res: ApiResponse<ErrorType>, errorCode?: number, description?: string);
        toString(): string;
    }
    class NotFoundError extends Error {
        constructor(res: ApiResponse<ErrorType>, routeName: string);
    }
    class InvalidRequestError extends Error {
        constructor(res: ApiResponse<ErrorType>);
    }
    class UnauthorizedError extends Error {
        constructor(res: ApiResponse<ErrorType>);
    }
    class InternalServerError extends Error {
        constructor(res: ApiResponse<ErrorType>);
    }
}
export interface HttpRequest {
    url?: string;
    body: any;
}
export interface ApiResponse<TSend> {
    send(data: TSend | ApiErrors.ErrorType): ApiResponse<TSend>;
    status(code: number): ApiResponse<TSend>;
    error(code: number, message: string): ApiResponse<TSend>;
}
export type Route<TArgs extends Array<any>, TReturn, TDependencies, TDataFetchedDuringAuth, TRequest extends HttpRequest = HttpRequest, TResponse extends ApiResponse<TReturn> = ApiResponse<TReturn>, TLocalDependencies extends object = {}> = {
    subUrl: string;
    (...args: TArgs): Promise<TReturn>;
    beforeCall?: (deps: TLocalDependencies, args: TArgs) => Promise<TArgs>;
    afterResponse?: (deps: TLocalDependencies, res: TReturn, ranFallback: boolean) => Promise<void>;
    fallback?: (deps: TLocalDependencies, args: TArgs) => Promise<TReturn>;
    isAuthorized: (req: TRequest, res: TResponse, deps: TDependencies, args: TArgs) => Promise<{
        authorized: boolean;
        authData: TDataFetchedDuringAuth | undefined;
    }>;
    handler: (req: TRequest, res: TResponse, deps: TDependencies, authData: TDataFetchedDuringAuth, args: TArgs) => Promise<any> | any;
};
export declare enum RequestMethod {
    POST = "POST",
    GET = "GET"
}
export declare class RequestHelper<TLocalDependencies extends object = {}> {
    baseUrl: string;
    private onError;
    constructor(baseUrl: string, onError: (url: string, error: any) => void, logPrefix?: boolean);
    request<TArgs extends Array<any>, TReturn, TDependencies, TDataFetchedDuringAuth, TRequest extends HttpRequest = HttpRequest>(route: string | Route<TArgs, TReturn, TDependencies, TDataFetchedDuringAuth, TRequest, any, TLocalDependencies>, body: any, method?: RequestMethod): Promise<any>;
    getLocalDependencies(): Promise<TLocalDependencies>;
}
/**
 * There's no easy one-liner to create a function with properties while maintaining typing, so I made this shortcut
 */
export declare function createRoute<TArgs extends Array<any>, TReturn, TDependencies, TFetchedDuringAuth, TRequest extends HttpRequest = HttpRequest, TResponse extends ApiResponse<TReturn> = ApiResponse<TReturn>>(config: Omit<OmitCallSignature<Route<TArgs, TReturn, TDependencies, TFetchedDuringAuth, TRequest, TResponse>>, "subUrl">, clientHandler?: (...args: any) => Promise<any>): Route<TArgs, TReturn, TDependencies, TFetchedDuringAuth, TRequest, TResponse>;
export type Segment<TDependencies> = {
    [route: string]: Segment<TDependencies> | Route<any, any, TDependencies, any>;
};
export declare abstract class ApiTemplate<TDependencies, TRequest extends HttpRequest = HttpRequest> {
    requestHelper: RequestHelper;
    /**
     * You need to pass false in subclasses and then call this.init()
     * @param init Whether to call init() on construction. Pass false if calling super()
     */
    constructor(requestHelper: RequestHelper, init?: boolean);
    private initSegment;
    protected init(): void;
}
export declare enum ErrorLogMode {
    Throw = 0,
    Log = 1,
    None = 2
}
export declare abstract class ServerApi<TDependencies, TRequest extends HttpRequest = HttpRequest, TResponse extends ApiResponse<any> = ApiResponse<any>> {
    private api;
    private errorLogMode;
    private urlPrefix;
    constructor(api: ApiTemplate<TDependencies>, errorLogMode?: ErrorLogMode, logPrefix?: boolean);
    handle(req: TRequest, rawRes: any): Promise<void>;
    protected parseRawResponse(rawRes: any): TResponse;
    abstract getDependencies(req: TRequest, res: TResponse): TDependencies;
}
