///
import * as http from 'http';
import * as net from 'net';
import * as oas3 from 'openapi3-ts';
import { Context as KoaContext } from 'koa';
import { Callback, ParametersByLocation, ParametersMap, HttpIncomingMessage } from './basicTypes';
import { Readable } from 'stream';
import { ParameterLocations, ParameterLocation, ExegesisOptions } from '.';
import { BodyParser } from './bodyParser';
import { IValidationError, ValidatorFunction, ResponseValidationResult } from './validation';
export interface HttpHeaders {
[header: string]: number | string | string[];
}
export interface ExegesisResponse {
statusCode: number;
statusMessage: string | undefined;
headers: HttpHeaders;
body: Buffer | string | Readable | any;
connection: net.Socket;
ended: boolean;
setStatus(status: number): this;
status(status: number): this;
setBody(body: any): this;
/**
* Set the value of a header.
* @param header - the header to set.
* @param value - the value to set the header to.
*/
header(header: string, value: number | string | string[] | undefined): this;
set(header: string, value: number | string | string[] | undefined): this;
json(json: any): this;
end(): void;
setHeader(name: string, value: number | string | string[] | undefined): void;
getHeader(name: string): number | string | string[] | undefined;
getHeaderNames(): string[];
getHeaders(): HttpHeaders;
hasHeader(name: string): boolean;
removeHeader(name: string): void;
writeHead(statusCode: number, headers?: HttpHeaders): void;
writeHead(statusCode: number, statusMessage?: string, headers?: HttpHeaders): void;
}
export interface ExegesisContextBase {
readonly req: HttpIncomingMessage;
readonly origRes: http.ServerResponse;
readonly res: ExegesisResponse;
api: any;
security?: {
[scheme: string]: AuthenticationSuccess;
};
user?: any;
parameterLocations?: ParameterLocations;
makeError(statusCode: number, message: string): Error;
makeValidationError(message: string, parameterLocation: ParameterLocation): Error;
/**
* Returns true if the response has already been sent.
*/
isResponseFinished(): boolean;
}
export interface ExegesisContext extends ExegesisContextBase {
parameterLocations: ParameterLocations;
params: ParametersByLocation>;
requestBody: any;
options: ExegesisOptions;
}
export interface ExegesisPluginContext extends ExegesisContextBase {
getParams(): Promise>>;
getParams(done: Callback>>): void;
getRequestBody(): Promise;
getRequestBody(done: Callback): void;
}
export interface OAS3ApiInfo {
openApiDoc: oas3.OpenAPIObject;
serverPtr: string | undefined;
serverObject: oas3.ServerObject | undefined;
pathItemPtr: string;
pathItemObject: oas3.PathItemObject;
operationPtr: string | undefined;
operationObject: oas3.OperationObject | undefined;
requestBodyMediaTypePtr: string | undefined;
requestBodyMediaTypeObject: oas3.MediaTypeObject | undefined;
}
export declare type PromiseController = (context: ExegesisContext) => any;
export declare type CallbackController = (context: ExegesisContext, done: Callback) => void;
export declare type Controller = PromiseController | CallbackController;
export interface ControllerModule {
[operationId: string]: Controller;
}
export interface Controllers {
[controllerName: string]: ControllerModule;
}
export interface AuthenticationFailure {
type: "invalid" | "missing";
status?: number;
message?: string;
challenge?: string;
}
export interface AuthenticationSuccess {
type: "success";
user?: any;
roles?: string[] | undefined;
scopes?: string[] | undefined;
[name: string]: any;
}
export declare type AuthenticationResult = AuthenticationSuccess | AuthenticationFailure;
export interface AuthenticatorInfo {
in?: "query" | "header" | "cookie";
name?: string;
scheme?: string;
}
export declare type PromiseAuthenticator = (context: ExegesisPluginContext, info: AuthenticatorInfo) => AuthenticationResult | undefined | Promise;
export declare type CallbackAuthenticator = (context: ExegesisPluginContext, info: AuthenticatorInfo, done: Callback) => void;
export declare type Authenticator = PromiseAuthenticator | CallbackAuthenticator;
export interface Authenticators {
[scheme: string]: Authenticator;
}
/**
* Result returned by the exegesisRunner.
*/
export interface HttpResult {
headers: HttpHeaders;
status: number;
body: NodeJS.ReadableStream | undefined;
}
/**
* A function which takes in a request and response, and returns an HttpResult.
*
* @throws {ValidationError} - If a validation error occurs in the parameters or the body.
* @throws {HttpError} - If a non-validation error occurs, and an HTTP error code is suggested.
* @throws {Error} - If any other error occurs.
*/
export declare type ExegesisRunner = (req: http.IncomingMessage, res: http.ServerResponse, ctx: KoaContext) => Promise;
export declare type ParsedParameterValidator = (parameterValues: ParametersByLocation>) => IValidationError[] | null;
export interface ResolvedOperation {
parseParameters: (() => ParametersByLocation>);
validateParameters: ParsedParameterValidator;
parameterLocations: ParameterLocations;
bodyParser: BodyParser | undefined;
validateBody: ValidatorFunction | undefined;
exegesisControllerName: string | undefined;
operationId: string | undefined;
controllerModule: ControllerModule | undefined;
controller: Controller | undefined;
validateResponse(response: ExegesisResponse, validateDefaultResponses: boolean): ResponseValidationResult;
authenticate(context: ExegesisContext): Promise<{
[scheme: string]: AuthenticationSuccess;
} | undefined>;
}
export interface ResolvedPath {
operation: ResolvedOperation | undefined;
api: T;
}
export interface ApiInterface {
/**
* Resolve an incoming request.
*
* @param method - The HTTP method used (e.g. 'GET').
* @param url - The URL used to retrieve this request.
* @param headers - Any headers sent along with the request.
* @throws {ValidationError} if some parameters cannot be parsed.
*/
resolve(method: string, url: string, headers: http.IncomingHttpHeaders): ResolvedPath | undefined;
}
export interface ExegesisPluginInstance {
/**
* Called exactly once, before Exegesis "compiles" the API document.
* Plugins must not modify apiDoc here.
*
* @param data.apiDoc - the API document.
*/
preCompile?: ((data: {
apiDoc: any;
}) => void | Promise) | ((data: {
apiDoc: any;
}, done: Callback) => void);
/**
* Called immediately after the routing phase. Note that this is
* called before Exegesis verifies routing was valid - the
* `pluginContext.api` object will have information about the
* matched route, but will this information may be incomplete.
* For example, for OAS3 we may have matched a route, but not
* matched an operation within the route. Or we may have matched
* an operation but that operation may have no controller defined.
* (If we failed to match a route at all, this will not be called.)
*
* If your API added a route to the API document, this function is a
* good place to write a reply.
*
* @param pluginContext - the plugin context.
*/
postRouting?: ((pluginContext: ExegesisPluginContext) => void | Promise) | ((pluginContext: ExegesisPluginContext, done: Callback) => void);
/**
* Called for each request, after security phase and before input
* is parsed and the controller is run. This is a good place to
* do extra security checks. The `exegesis-plugin-roles` plugin,
* for example, generates a 403 response here if the authenticated
* user has insufficient privliedges to access this path.
*
* Note that this function will not be called if a previous pluing
* has already written a response.
*
* @param pluginContext - the plugin context.
*/
postSecurity?: ((pluginContext: ExegesisPluginContext) => void | Promise) | ((pluginContext: ExegesisPluginContext, done: Callback) => void);
/**
* Called immediately after the controller has been run, but before
* any response validation. This is a good place to do custom
* response validation. If you have to deal with something weird
* like XML, this is where you'd handle it.
*
* This function can modify the contents of the response.
*
* @param context - The exegesis plugin context.
*/
postController?: ((pluginContext: ExegesisContext) => void | Promise) | ((pluginContext: ExegesisContext, done: Callback) => void);
}
export interface ExegesisPlugin {
info: {
name: string;
};
makeExegesisPlugin(data: {
apiDoc: any;
}): ExegesisPluginInstance;
}