import { Logger, ObjectTS, ValidatorTypeResolver } from "@intuitionrobotics/ts-common";
import { Stream } from "stream";
import { ServerApi_Middleware } from "./HttpServer";
import { IncomingHttpHeaders } from "http";
import { ApiTypeBinder, ApiWithBody, ApiWithQuery, HttpMethod, QueryParams } from "../../../shared/types";
import { ApiException } from "../../exceptions";
import { ExpressRequest, ExpressResponse, ExpressRouter } from "../../utils/types";
export type HttpRequestData = {
    originalUrl: string;
    headers: IncomingHttpHeaders;
    url: string;
    query: any;
    body: any;
    method: HttpMethod;
};
export declare abstract class ServerApi<Binder extends ApiTypeBinder<string, R, B, P>, R = Binder["response"], B = Binder["body"], P extends QueryParams = Binder["queryParams"]> extends Logger {
    static isDebug: boolean;
    private printResponse;
    readonly headersToLog: string[];
    readonly method: HttpMethod;
    private url;
    readonly relativePath: string;
    private middlewares?;
    private bodyValidator?;
    private queryValidator?;
    private sideEffects;
    protected baseUrl?: string;
    private scopes;
    protected constructor(method: HttpMethod, relativePath: string, tag?: string);
    shouldPrintResponse(): boolean;
    addSideEffect(sideEffect: () => Promise<any>): this;
    setMiddlewares(...middlewares: ServerApi_Middleware[]): this;
    addMiddlewares(...middlewares: ServerApi_Middleware[]): this;
    setScopes(...scopes: string[]): this;
    getScopes(): string[];
    addHeaderToLog(...headersToLog: string[]): void;
    setBodyValidator(bodyValidator: ValidatorTypeResolver<B>): void;
    setQueryValidator(queryValidator: ValidatorTypeResolver<P>): void;
    asProxy(): ServerApi<Binder>;
    getUrl(): string;
    dontPrintResponse(): void;
    setMaxResponsePrintSize(printResponseMaxSizeBytes: number): void;
    route(router: ExpressRouter, prefixUrl: string, baseUrl: string): void;
    assertProperty: <T extends object, K extends keyof T = keyof T>(instance: T, key: K | K[], statusCode?: number, check?: string | ((propValue: T[K]) => void)) => void;
    callWrapper: (req: ExpressRequest, res: ExpressResponse) => Promise<void>;
    private releaseSideEffects;
    call: (req: ExpressRequest, res: ExpressResponse) => Promise<void>;
    private applyMiddlewares;
    protected abstract process(request: ExpressRequest, response: ApiResponse, queryParams: P, body: B, context: ObjectTS): Promise<R>;
}
export declare abstract class ServerApi_Get<Binder extends ApiWithQuery<U, R, P>, U extends string = Binder["url"], R = Binder["response"], P extends QueryParams | {} = Binder["queryParams"]> extends ServerApi<Binder> {
    protected constructor(apiName: string);
}
export declare abstract class ServerApi_Post<Binder extends ApiWithBody<U, B, R>, U extends string = Binder["url"], R = Binder["response"], B = Binder["body"]> extends ServerApi<Binder> {
    protected constructor(apiName: string);
}
export declare class ServerApi_Proxy<Binder extends ApiTypeBinder<string, R, B, P>, R = Binder["response"], B = Binder["body"], P extends QueryParams = Binder["queryParams"]> extends ServerApi<Binder> {
    private readonly api;
    constructor(api: ServerApi<any>);
    protected process(request: ExpressRequest, response: ApiResponse, queryParams: P, body: B, context: ObjectTS): Promise<R>;
}
export declare class ServerApi_Redirect extends ServerApi<any> {
    private readonly responseCode;
    private readonly redirectUrl;
    constructor(apiName: string, responseCode: number, redirectUrl: string);
    protected process(request: ExpressRequest, response: ApiResponse, queryParams: QueryParams, body: any): Promise<void>;
}
export declare class ApiResponse {
    private api;
    private readonly res;
    private consumed;
    constructor(api: ServerApi<any>, res: ExpressResponse);
    isConsumed(): boolean;
    private consume;
    stream(responseCode: number, stream: Stream, headers?: any): void;
    private printHeaders;
    private printResponse;
    code(responseCode: number, headers?: any): void;
    text(responseCode: number, response?: string, _headers?: any): void;
    html(responseCode: number, response?: string, _headers?: any): void;
    json(responseCode: number, response?: object | string, _headers?: any): void;
    private _json;
    end(responseCode: number, response?: object | string, headers?: any): void;
    setHeaders(headers: any): void;
    setHeader(headerKey: string, value: string | string[]): void;
    getHeader(headerKey: string): string | undefined;
    redirect(responseCode: number, url: string): void;
    exception(exception: ApiException, headers?: any): void;
    serverError(error: Error & {
        cause?: Error;
    }, headers?: any): void;
}
