import { HotTestDriver } from "./HotTestDriver";
import { HotRoute } from "./HotRoute";
import express from "express";
import { HotWebSocketServerClient } from "./HotWebSocketServerClient";
import { HotRouteMethodParameterMap, IHotValidReturn } from "./HotStaq";
import { ValidationOptions } from "./HotProcessInput";
/**
 * The available event methods.
 */
export declare enum HotEventMethod {
    /**
     * A HTTP GET request.
     */
    GET = "get",
    /**
     * A HTTP POST request.
     */
    POST = "post",
    /**
     * This will upload a file, then post the json request afterwards.
     */
    FILE_UPLOAD = "file_upload_then_post_json",
    /**
     * A SSE sub event. This will close the event whenever
     */
    SSE_SUB_EVENT = "sse_sub_event",
    /**
     * A websocket event.
     */
    WEBSOCKET_CLIENT_PUB_EVENT = "websocket_client_pub_event",
    /**
     * Handles both a HTTP POST websocket event requests.
     */
    POST_AND_WEBSOCKET_CLIENT_PUB_EVENT = "post_and_websocket_client_pub_event"
}
/**
 * The request that came from a client.
 */
export interface IServerRequest {
    /**
     * The express request received from the client. Will be set to null if using worker
     * threads or if this request was received from a websocket connection.
     */
    req?: express.Request;
    /**
     * The express response to send to the client. Will be set to null if using worker
     * threads or if this request was received from a websocket connection.
     */
    res?: express.Response;
    /**
     * The bearer token being presented from the client requesting access.
     */
    bearerToken?: string;
    /**
     * The client websocket that was used to send the message. Will be set to null if using worker
     * threads or if this request was received from a HTTP connection.
     */
    wsSocket?: HotWebSocketServerClient;
    /**
     * The response received from sucessfully authorizing a client. Can be a JWT token, api key, etc.
     * Will be null if this request was received from a websocket connection.
     * DO NOT STORE SENSITIVE INFORMATION HERE SUCH AS PASSWORDS.
     */
    authorizedValue?: any;
    /**
     * The JSON received from the client.
     */
    jsonObj?: any;
    /**
     * Any query variables received from the client. Will be null if this request was
     * received from a websocket connection.
     */
    queryObj?: any;
    /**
     * Any files received from the client. Will be null if no files were sent.
     * Once a file is uploaded, you can access it at the temporary path found in:
     * files[uploadId].path
     */
    files?: {
        [key: string]: {
            name: string;
            size: number;
            path: string;
        };
    };
    /**
     * Called when the client's connection has closed for any reason.
     */
    onClose?: () => void;
}
/**
 * How data should be passed through the server execute process.
 */
export declare enum PassType {
    /**
     * Any data set in jsonObj will immediately be passed to the client when
     * this function returns.
     */
    ReturnToClient = 0,
    /**
     * Any data being set in jsonObj will be passed to the next step after
     * this function returns.
     */
    Update = 1,
    /**
     * Ignore any data set in jsonObj.
     */
    Ignore = 2
}
/**
 * The request that came from a client.
 */
export declare class ServerRequest implements IServerRequest {
    /**
     * The express request received from the client. Will be set to null if using worker
     * threads or if this request was received from a websocket connection.
     */
    req: express.Request;
    /**
     * The express response to send to the client. Will be set to null if using worker
     * threads or if this request was received from a websocket connection.
     */
    res: express.Response;
    /**
     * The bearer token being presented from the client requesting access.
     */
    bearerToken: string;
    /**
     * The client websocket that was used to send the message. Will be set to null if using worker
     * threads or if this request was received from a HTTP connection.
     */
    wsSocket: HotWebSocketServerClient;
    /**
     * The response received from sucessfully authorizing a client. Can be a JWT token, api key, etc.
     * Will be null if this request was received from a websocket connection.
     * DO NOT STORE SENSITIVE INFORMATION HERE SUCH AS PASSWORDS.
     */
    authorizedValue: any;
    /**
     * The JSON object received from either onServerPreExecute or onServerExecute. If
     * returnToClient is set to true, onServerExecute will not be called and the data
     * returned from onServerPreExecute will be sent to the client instead. If returnToClient
     * is set to either false or undefined, onServerExecute will be called and the data
     * will be passed to onServerExecute in passObject.jsonObj.
     */
    passObject: {
        passType: PassType;
        jsonObj: any;
    };
    /**
     * The JSON received from the client.
     */
    jsonObj: any;
    /**
     * Any query variables received from the client. The object will be in key/value pair.
     *
     * **HTTP Example**
     *
     * In the web browser, the client sends the following query:
     * ```js
     * fetch ("http://localhost:3000?name=John&age=30");
     * ```
     *
     * In the server, the query will be received as:
     * ```json
     * {
     * 		"name": "John",
     * 		"age": 30
     * }
     * ```
     *
     * **WebSocket Example**
     *
     * In the web browser, the client initiates a socket.io connection and
     * sends the following query:
     * ```js
     * let client = io ("http://localhost:3000", {
     * 			query: {
     * 				name: "John",
     * 				age: 30
     * 			}
     * 		});
     * ```
     *
     * In the server, the query will be received as:
     * ```json
     * {
     * 		"name": "John",
     * 		"age": 30
     * }
     * ```
     */
    queryObj: any;
    /**
     * Any files received from the client. Will be null if no files were sent.
     * Once a file is uploaded, you can access it at the temporary path found in:
     * files[uploadId].path
     */
    files: {
        [key: string]: {
            name: string;
            size: number;
            path: string;
        };
    };
    /**
     * Called when the client's connection has closed for any reason.
     */
    onClose: () => void;
    constructor(obj?: IServerRequest);
    /**
     * Write to the HTTP response. This is mostly intended to be used
     * when using SSE. This requires JSON to be sent.
     */
    httpWrite(event: string, jsonObj: any): Promise<void>;
    /**
     * Write to the HTTP response. This is mostly intended to be used
     * when using SSE.
     */
    httpWriteRaw(data: any): Promise<void>;
    /**
     * Close the HTTP response. This is mostly intended to be used when
     * using SSE.
     */
    httpClose(): void;
}
/**
 * A function that will be executed by the server when first registering with Express.
 * If this returns false, this route method will not be registered.
 */
export type ServerRegistrationFunction = () => Promise<boolean>;
/**
 * A function that will be executed by the server.
 */
export type ServerExecutionFunction = (request: ServerRequest) => Promise<any>;
/**
 * A function that will be executed by the client.
 */
export type ClientExecutionFunction = (...args: any[]) => Promise<any>;
/**
 * A function that will be executed by the server for authorization. Any value
 * returned from this function will be passed to the ServerExecutionFunction.
 * If an undefined value is returned, this indicates the server was not able
 * to authenticate the user, so the ServerExecutionFunction will not be
 * executed.
 */
export type ServerAuthorizationFunction = (request: ServerRequest) => Promise<any>;
/**
 * The test case function to execute.
 */
export type TestCaseFunction = ((driver: HotTestDriver) => Promise<any>) | ((driver: HotTestDriver) => any);
/**
 * The test case object to pass.
 */
export interface TestCaseObject {
    /**
     * The name of the test case.
     */
    name: string;
    /**
     * The function to execute.
     */
    func: TestCaseFunction;
}
/**
 * Backwards-compat alias for the validator-name string. Re-introduced
 * after 725eab8 removed it — `@hotstaq/userroute` and `@hotstaq/dataroute`
 * still ship .d.ts files that import this name, so removing it breaks
 * the TS build of every downstream package even when only the type
 * surface changed and the runtime kept working.
 *
 * The enum values mirror the keys registered in HotStaq.valids[…]; any
 * additional validator type can also be passed as a plain string.
 */
export declare enum HotValidationType {
    UUID = "UUID",
    Boolean = "boolean",
    Number = "number",
    Integer = "Integer",
    Float = "Float",
    Text = "Text",
    Email = "Email",
    Phone = "Phone",
    URL = "URL",
    IPv4 = "IPv4",
    IP = "IP",
    IPv6 = "IPv6",
    Date = "Date",
    Object = "Object",
    Array = "Array",
    Map = "Map",
    Enum = "Enum",
    JSON = "JSON",
    JS = "JS",
    Undefined = "undefined",
    Null = "null"
}
/**
 * Is chained together to create a validation chain.
 */
export interface HotValidation {
    /**
     * The type of validation to perform.
     * @default Text
     */
    type?: string | HotValidationType;
    /**
     * The default value to set if the incoming input is null or undefined.
     */
    defaultValue?: any;
    /**
     * The associated validations for this current validation. This is mostly to be used for the Array or
     * Map types when trying to validate each item of an array.
     * @default Text
     */
    associatedValids?: HotValidation[];
    /**
     * The possible properties to check against. Works only with the Object type.
     */
    properties?: HotValidation[];
    /**
     * The possible values to check against. Works best using the Enum type.
     */
    values?: any[];
    /**
     * The function to use to validate if the input is valid.
     */
    func?: (options: ValidationOptions, key: string, input: any) => Promise<IHotValidReturn>;
    /**
     * The regex to use to validate with.
     */
    regex?: string | RegExp;
    /**
     * The min text or array length. This can also be the minimum number if the type is number.
     */
    min?: number;
    /**
     * The max text or array length. This can also be the maximum number if the type is number.
     */
    max?: number;
    /**
     * Ensures that the string or array is not empty or null.
     */
    notEmptyOrNull?: boolean;
    /**
     * The value to check against.
     */
    comparison?: {
        /**
         * The value to check if greater than.
         */
        greaterThan?: any;
        /**
         * The value to check if less than.
         */
        lessThan?: any;
        /**
         * The value to check equal to.
         */
        eq?: any;
        /**
         * The value to check if its not equal to.
         */
        not?: any;
    };
    /**
     * The next type of validation to perform.
     */
    next?: HotValidation;
}
/**
 * A method parameter.
 */
export interface HotRouteMethodParameter {
    /**
     * The type of parameter. Default: string
     * Can be:
     * * string
     * * integer
     * * number
     * * boolean
     * * array
     * * object
     */
    type?: string;
    /**
     * The item type of each element in the array.
     *
     * @todo This cannot generate objects or nested objects yet :/
     */
    items?: HotRouteMethodParameter;
    /**
     * The description of the parameter. Default: ""
     */
    description?: string;
    /**
     * Additional OpenAPI information. Anything added here will be automerged in.
     */
    openAPI?: any;
    /**
     * Is this parameter required? Default: false
     */
    required?: boolean;
    /**
     * Is this parameter read only? Default: false
     */
    readOnly?: boolean;
    /**
     * The validation chain to perform on this parameter.
     */
    validations?: HotValidation[];
    /**
     * The parameters in the object. If using the function, the function
     * will only execute if the application's connection type is set to generation.
     */
    parameters?: {
        [name: string]: (string | HotRouteMethodParameter | (() => Promise<HotRouteMethodParameter>));
    };
}
/**
 * An API method to make.
 */
export interface IHotRouteMethod {
    /**
     * The parent route.
     */
    route?: HotRoute;
    /**
     * The api call name.
     */
    name: string;
    /**
     * The description of the api method.
     */
    description?: string;
    /**
     * Additional OpenAPI information. Anything added here will be automerged in.
     */
    openAPI?: any;
    /**
     * The tags for the api method.
     */
    tags?: string[];
    /**
     * The description of what returns from the api method.
     */
    returns?: string | HotRouteMethodParameter | (() => Promise<HotRouteMethodParameter>);
    /**
     * If set, this will validate the query input before executing the method.
     */
    validateQueryInput?: ValidationOptions;
    /**
     * If set, this will validate the JSON input before executing the method.
     */
    validateJSONInput?: ValidationOptions;
    /**
     * The reference name for the parameters when generating documentation.
     * This is so the generated components all use the same parameters.
     */
    parametersRefName?: string;
    /**
     * The parameters in the api method.
     */
    parameters?: {
        [name: string]: string | HotRouteMethodParameter | (() => Promise<HotRouteMethodParameter>);
    };
    /**
     * The query parameters used in the api method.
     */
    queryParameters?: HotRouteMethodParameterMap;
    /**
     * The api call name.
     */
    type?: HotEventMethod;
    /**
     * The test case objects to execute during tests.
     */
    testCases?: {
        [name: string]: TestCaseObject;
    } | (string | TestCaseFunction)[] | TestCaseFunction[] | TestCaseObject[];
    /**
     * Executes before all routes have been registered.
     */
    onPreRegister?: () => Promise<void>;
    /**
     * Executes when first registering this method with Express. If
     * this returns false, the method will not be registered.
     */
    onRegister?: ServerRegistrationFunction;
    /**
     * Executes after all routes have been registered.
     */
    onPostRegister?: () => Promise<void>;
    /**
     * Executes when authorizing a called method. If this method
     * is set, this will not call onAuthorize for the parent HotRoute.
     * The value returned from here will be passed to onExecute.
     * Undefined returning from here will mean the authorization failed.
     * If any exceptions are thrown from this function, they will be sent
     * to the server as an { error: string; } object with the exception
     * message as the error.
     *
     * Currently this has no effect when using websockets.
     */
    onServerAuthorize?: ServerAuthorizationFunction;
    /**
     * Executes when executing a called method from the server side.
     * This will stringify any JSON object and send it as a JSON response.
     * If undefined is returned no response will be sent to the server.
     * So the developer would have to send a response using "res".
     * If any exceptions are thrown from this function, they will be sent
     * to the server as an { error: string; } object with the exception
     * message as the error.
     */
    onServerExecute?: ServerExecutionFunction;
    /**
     * Executes when executing a called method from the client side.
     * @fixme Is this necessary?
     */
    onClientExecute?: ClientExecutionFunction;
    /**
     * Executes when validating incoming data.
     */
    onValidateQueryInput?: ClientExecutionFunction;
    /**
     * Executes when validating incoming json data.
     */
    onValidateJSONInput?: ClientExecutionFunction;
}
/**
 * An API method to make.
 */
export declare class HotRouteMethod implements IHotRouteMethod {
    /**
     * The parent route.
     */
    route: HotRoute;
    /**
     * The api call name.
     */
    name: string;
    /**
     * The description of the api method.
     */
    description: string;
    /**
     * Additional OpenAPI information. Anything added here will be automerged in.
     */
    openAPI: any;
    /**
     * The tags for the api method.
     */
    tags: string[];
    /**
     * The description of what returns from the api method.
     */
    returns: HotRouteMethodParameter | (() => Promise<HotRouteMethodParameter>);
    /**
     * If set to true, this will validate the query input before executing the method.
     */
    validateQueryInput: ValidationOptions;
    /**
     * If set to true, this will validate the JSON input before executing the method.
     */
    validateJSONInput: ValidationOptions;
    /**
     * The reference name for the parameters when generating documentation.
     * This is so the generated components all use the same parameters.
     */
    parametersRefName: string;
    /**
     * The parameters in the api method.
     */
    parameters: HotRouteMethodParameterMap;
    /**
     * The query parameters used in the api method.
     */
    queryParameters: HotRouteMethodParameterMap;
    /**
     * The api call name.
     */
    type: HotEventMethod;
    /**
     * Has this method been registered with the server? This
     * prevents the method from being reregistered.
     */
    isRegistered: boolean;
    /**
     * Has this method been registered with the server? This
     * prevents the method from being reregistered.
     */
    executeSetup: boolean;
    /**
     * The test case objects to execute during tests.
     */
    testCases: {
        [name: string]: TestCaseObject;
    };
    /**
     * Executes before all routes have been registered.
     */
    onPreRegister?: () => Promise<void>;
    /**
     * Executes when first registering this method with Express. If
     * this returns false, the method will not be registered.
     */
    onRegister?: ServerRegistrationFunction;
    /**
     * Executes after all routes have been registered.
     */
    onPostRegister?: () => Promise<void>;
    /**
     * Executes when authorizing a called method. If this method
     * is set, this will not call onAuthorize for the parent HotRoute.
     * The value returned from here will be passed to onServerExecute.
     * Undefined returning from here will mean the authorization failed.
     * If any exceptions are thrown from this function, they will be sent
     * to the client as an { error: string; } object with the exception
     * message as the error.
     */
    onServerAuthorize?: ServerAuthorizationFunction;
    /**
     * Executes before executing onServerExecute. Anything that returns
     * from this will be passed onto onServerExecute via request.previousJsonObj.
     * Any exceptions thrown from this function will be sent to the client in
     * the form of an error message object.
     */
    onServerPreExecute?: ServerExecutionFunction;
    /**
     * Executes when executing a called method from the server side.
     * This will stringify any JSON object and send it as a JSON response.
     * If undefined is returned no response will be sent to the server.
     * So the developer would have to send a response using "res".
     * If any exceptions are thrown from this function, they will be sent
     * to the server as an { error: string; } object with the exception
     * message as the error.
     */
    onServerExecute?: ServerExecutionFunction;
    /**
     * Executes after executing onServerExecute. If this returns anything
     * other than undefined, the response will be sent to the client.
     */
    onServerPostExecute?: ServerExecutionFunction;
    /**
     * Executes when executing a called method from the client side.
     * @fixme Is this necessary?
     */
    onClientExecute?: ClientExecutionFunction;
    /**
     * Executes when validating incoming query data.
     */
    onValidateQueryInput?: ClientExecutionFunction;
    /**
     * Executes when validating incoming json data.
     */
    onValidateJSONInput?: ClientExecutionFunction;
    private constructor();
    /**
     * Create a new route method.
     */
    static create(route: HotRoute | IHotRouteMethod, name?: string, onExecute?: ServerExecutionFunction | ClientExecutionFunction, type?: HotEventMethod, onServerAuthorize?: ServerAuthorizationFunction, onRegister?: ServerRegistrationFunction, testCases?: {
        [name: string]: TestCaseObject;
    } | (string | TestCaseFunction)[] | TestCaseFunction[] | TestCaseObject[]): HotRouteMethod;
    /**
     * Add a new test case.
     */
    addTestCase(newTestCase: TestCaseObject | string | TestCaseFunction, testCaseFunction?: TestCaseFunction): void;
    /**
     * Get the relative url from this method and its route.
     */
    getRouteUrl(): string;
}
//# sourceMappingURL=HotRouteMethod.d.ts.map