API @deepkit/http
npm install @deepkit/http
Same as App, but with easily accessible router to make the most common use case easier. A class to describe a filter for routes. Reads the body of the request and returns it as a Buffer.
The result will be cached in the request object as Deepkit's router will automatically use Serves an index file and allows to load asset files from the same folder. Can be used to serve an angular application All paths like Marks a parameter as HTTP body and reads the value from the request body. Delays the parsing of the path/body/query/header to the very last moment, when the parameter is actually used. If no options are provided, the parser will receive data from path, header, body, and query, in this order.
This basically allows to fetch data from all possible HTTP sources in one go. You can disable various sources by providing the options, e.g. Marks a parameter as HTTP path and reads the value from the request path.
This is normally not requires since the parameter name automatically maps to the path parameter,
but in case of requesting the path parameter in for example listeners, this is required.
The name option can be used to change the parameter name. Marks a parameter as HTTP header and reads the value from the request header. Marks a parameter as HTTP query and reads the value from the request query string. Marks a parameter as HTTP query objects and reads multiple values from the request query string into an object. For all parameters used in the URL path, a regular expression of /[^/]+/ is used. To change that, use getRegExp.Classes
export class HttpController {
baseUrl: string;
actions;
groups: string[];
middlewares: (() => HttpMiddlewareConfig)[];
resolverForToken: Map<any, ClassType>;
resolverForParameterName: Map<string, ClassType>;
getUrl(action: HttpAction): string;
addAction(action: HttpAction);
getActions(): Set<HttpAction>;
removeAction(methodName: string): void;
getAction(methodName: string): HttpAction;
}
export class HttpActionParameter {
name: string;
type?: | | ;
/**
* undefined = propertyName, '' === root, else given path
*/
typePath?: string;
optional: boolean;
}
export class HttpAction {
name: string;
description: string;
category: string;
path: string;
httpMethods: string[];
methodName: string;
groups: string[];
serializer?: Serializer;
middlewares: (() => HttpMiddlewareConfig)[];
serializationOptions?: SerializationOptions;
resolverForToken: Map<any, ClassType>;
resolverForParameterName: Map<string, ClassType>;
/**
* An arbitrary data container the user can use to store app specific settings/values.
*/
data;
responses: {
statusCode: number;
description: string;
type?: Type;
}[];
}
export class HttpControllerDecorator {
t;
controller(baseUrl: string = );
group(...group: string[]);
middleware(...middlewares: HttpActionMiddleware[]);
/**
* Adds a parameter resolver for parameters based on the class type. Use .resolveParameterByName() for name-based resolving.
*
* ```typescript
*
* class UserResolver {
* resolve(context: RouteParameterResolverContext): any | Promise<any> {
* return new User();
* }
* }
*
* @http.resolveParameter(User, UserResolver)
* class MyController {
*
* @http.GET()
* myAction(user: User) {
* }
* }
*
* new App({providers: [UserResolver]}).run();
* ```
*/
resolveParameter(classType: ClassType | string | any, resolver: ClassType<RouteParameterResolver>);
/**
* Adds a parameter resolver for parameters based on its name. Use .resolveParameter() for class-based resolving.
*
* ```typescript
*
* class UserResolver {
* resolve(context: RouteParameterResolverContext): any | Promise<any> {
* return new User();
* }
* }
*
* @http.resolveParameterByName('user', UserResolver)
* class MyController {
*
* @http.GET()
* myAction(user: User) {
* }
* }
*
* new App({providers: [UserResolver]}).run();
* ```
*/
resolveParameterByName(name: string, resolver: ClassType<RouteParameterResolver>);
setAction(action: HttpAction);
}
export class HttpActionDecorator {
t;
onDecorator(target: ClassType, property: string | undefined, parameterIndexOrDescriptor?: any);
name(name: string);
description(description: string);
serialization(options: SerializationOptions);
serializer(serializer: Serializer);
middleware(...middlewares: HttpActionMiddleware[]);
/**
* Allows to change the HttpAction object and composite multiple properties into one function.
*
* @example
* ```typescript
* const authGroup = Symbol('authGroup');
*
* function authGroup(group: 'admin' | 'user') {
* return (action: HttpAction) => {
* action.data.set(authGroup, group);
* };
* }
*
* class My Controller {
* @http.GET('/assets').use(authGroup('admin'))
* assets() {}
* }
* ```
*/
use(use: (action: HttpAction) => void);
/**
* Arbitrary value container that can be read in RouterParameterResolver and all
* HTTP workflow events (like authentication).
*
* @example
* ```typescript
* class My Controller {
* @http.GET('/assets').data('authGroup', 'admin')
* assets() {}
* }
* ```
*/
data(name: string, value: any);
category(category: string);
group(...group: string[]);
GET(path: string = );
HEAD(path: string = );
POST(path: string = );
PUT(path: string = );
DELETE(path: string = );
OPTIONS(path: string = );
TRACE(path: string = );
PATCH(path: string = );
ANY(path: string = );
/**
* Adds additional information about what HTTP status codes are available in this route.
* You can add additionally a description and a response body type.
*
* The type is used for serialization for responses with the given statusCode.
*
* This information is available in Deepkit API console.
*
* ```typescript
*
* http.GET().response<boolean>(200, 'All ok')
*
* interface User {
* username: string;
* }
* http.GET().response<User>(200, 'User object')
*
* interface HttpErrorMessage {
* error: string;
* }
* http.GET().response<HttpErrorMessage>(500, 'Error')
* ```
*/
response<T>(statusCode: number, description: string = , type?: ReceiveType<T>);
/**
* Adds a parameter resolver for parameters based on the class type. Use .resolveParameterByName() for name-based resolving.
*
* ```typescript
*
* class UserResolver {
* resolve(context: RouteParameterResolverContext): any | Promise<any> {
* return new User();
* }
* }
*
* class MyController {
* @http.GET()
* @http.resolveParameter(User, UserResolver)
* myAction(user: User) {
* }
* }
*
* new App({providers: [UserResolver]}).run();
* ```
*/
resolveParameter(classType: ClassType | string | any, resolver: ClassType<RouteParameterResolver>);
/**
* Adds a parameter resolver for parameters based on its name. Use .resolveParameter() for class-based resolving.
*
* ```typescript
*
* class UserResolver {
* resolve(context: RouteParameterResolverContext): any | Promise<any> {
* return new User();
* }
* }
*
* class MyController {
* @http.GET()
* @http.resolveParameterByName('user', UserResolver)
* myAction(user: User) {
* }
* }
*
* new App({providers: [UserResolver]}).run();
* ```
*/
resolveParameterByName(name: string, resolver: ClassType<RouteParameterResolver>);
}
export class Redirect {
routeName?: string;
routeParameters?: {
[name: string]: any;
};
url?: string;
constructor(public statusCode: number = );
static toRoute(routeName: string, parameters: {
[name: string]: any;
} = {}, statusCode: number = ): Redirect;
static toUrl(url: string, statusCode: number = ): Redirect;
}
export class HttpWorkflowEvent extends BaseEvent {
nextState?: any;
nextStateEvent?: any;
clearNext();
/**
* @see WorkflowNextEvent.next
*/
next(nextState: string, event?: any);
/**
* Whether already a next workflow state has been scheduled.
*/
hasNext(): boolean;
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse);
get url();
/**
* Whether a response has already been sent.
*/
get sent();
send(response: any);
}
export class HttpWorkflowEventWithRoute extends HttpWorkflowEvent {
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public route: RouteConfig);
send(response: any);
accessDenied(error?: Error);
}
export class HttpRouteEvent extends HttpWorkflowEvent {
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public parameterResolver?: RouteParameterResolverForInjector, public route?: RouteConfig);
routeFound(route: RouteConfig, parameterResolver: RouteParameterResolverForInjector);
routeFoundCallback<T extends any[]>(callback: (...args: T) => void, args: T);
notFound();
}
export class HttpAuthEvent extends HttpWorkflowEventWithRoute {
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public route: RouteConfig, public parameterResolver: RouteParameterResolverForInjector);
success();
}
export class HttpAccessDeniedEvent extends HttpWorkflowEvent {
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public route: RouteConfig, public error?: Error);
}
export class HttpResolveParametersEvent extends HttpWorkflowEventWithRoute {
parameters: HttpRequestPositionedParameters;
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public parameterResolver: RouteParameterResolverForInjector, public route: RouteConfig);
accessDenied();
}
export class HttpControllerEvent extends HttpWorkflowEventWithRoute {
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public parameters: HttpRequestPositionedParameters = { arguments: [], parameters: {} }, public route: RouteConfig);
}
export class HttpResponseEvent extends WorkflowEvent {
/**
* The time it took to call the controller action in milliseconds.
*/
controllerActionTime: number;
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public result: any, public route?: RouteConfig);
}
export class HttpControllerErrorEvent extends HttpWorkflowEventWithRoute {
/**
* The time it took to call the controller action in milliseconds.
*/
controllerActionTime: number;
constructor(public injectorContext: InjectorContext, public request: HttpRequest, public response: HttpResponse, public route: RouteConfig, public error: Error);
}
export class BaseResponse {
autoSerializing: boolean;
constructor(public _statusCode?: number, public _headers: OutgoingHttpHeaders = {});
status(code: number): this;
/**
* Per default a JSONResponse is serialized using the return type specified at the route.
* This disables that behaviour so that JSON.stringify is run on the result directly.
*/
disableAutoSerializing();
header(name: string, value: string | number): this;
headers(headers: OutgoingHttpHeaders): this;
contentType(type: string): this;
}
export class Response extends BaseResponse {
constructor(public content: string | Uint8Array, contentType: string, statusCode?: number);
}
export class HtmlResponse extends BaseResponse {
constructor(public html: string, statusCode?: number);
}
export class JSONResponse extends BaseResponse {
constructor(public json: any, statusCode?: number);
}
export class HttpResultFormatter {
constructor(protected router: HttpRouter);
handleError(error: Error, context: HttpResultFormatterContext): void;
handleUndefined(result: undefined | null, context: HttpResultFormatterContext): void;
handleRedirect(result: Redirect, context: HttpResultFormatterContext): void;
handleUnknown(result: any, context: HttpResultFormatterContext): void;
handleHtmlResponse(result: HtmlResponse, context: HttpResultFormatterContext): void;
handleGenericResponse(result: Response, context: HttpResultFormatterContext): void;
handleJSONResponse(result: JSONResponse, context: HttpResultFormatterContext): void;
handleTypeEntity<T>(classType: ClassType<T>, instance: T, context: HttpResultFormatterContext, route?: RouteConfig): void;
handleType<T>(type: Type, instance: T, context: HttpResultFormatterContext, route?: RouteConfig): void;
handleStream(stream: stream.Readable, context: HttpResultFormatterContext): void;
handleBinary(result: Uint8Array, context: HttpResultFormatterContext): void;
handleResponse(context: HttpResultFormatterContext);
handle(result: SupportedHttpResult, context: HttpResultFormatterContext): void;
}
export class HttpListener {
constructor(protected router: HttpRouter, protected logger: LoggerInterface, protected resultFormatter: HttpResultFormatter, protected injector: Injector, protected stopwatch?: Stopwatch);
onRequest(event: typeof httpWorkflow.onRequest.event): void;
async onRoute(event: typeof httpWorkflow.onRoute.event);
onRouteForward(event: typeof httpWorkflow.onRoute.event);
async routeNotFound(event: typeof httpWorkflow.onRouteNotFound.event): Promise<void>;
onAuth(event: typeof httpWorkflow.onAuth.event): void;
async onResolveParameters(event: typeof httpWorkflow.onResolveParameters.event);
onAccessDenied(event: typeof httpWorkflow.onAccessDenied.event): void;
async onController(event: typeof httpWorkflow.onController.event);
onParametersFailed(event: typeof httpWorkflow.onParametersFailed.event): void;
onControllerError(event: typeof httpWorkflow.onControllerError.event): void;
/**
* This happens before the result is sent.
*/
async onResultSerialization(event: typeof httpWorkflow.onResponse.event);
async onResponse(event: typeof httpWorkflow.onResponse.event);
}
export class HttpApp<T extends RootModuleDefinition> extends App<T> {
get router(): HttpRouterRegistry;
}
export class HttpResponse extends ServerResponse {
status(code: number);
}
export class BodyValidationError {
constructor(public readonly errors: ValidationErrorItem[] = []);
hasErrors(prefix?: string): boolean;
getErrors(prefix?: string): ValidationErrorItem[];
getErrorsForPath(path: string): ValidationErrorItem[];
getErrorMessageForPath(path: string): string;
}
export class ValidatedBody<T> {
constructor(public error: BodyValidationError, public value?: T);
valid(): this is {
value: T;
};
}
export class RequestBuilder {
constructor(protected path: string, protected method: string = );
getUrl();
build(): HttpRequest;
headers(headers: {
[name: string]: string;
}): this;
header(name: string, value: string | number): this;
json(body: object): this;
multiPart(items: ({
name: string;
} & ({
file: Uint8Array;
fileName?: string;
contentType?: string;
} | {
json: any;
} | {
value: any;
}))[]): this;
body(body: string | Buffer): this;
query(query: any | string): this;
}
export class HttpRequest extends IncomingMessage {
/**
* A store that can be used to transport data from guards/listeners to ParameterResolvers/controllers.
*/
store: {
[name: string]: any;
};
uploadedFiles: {
[name: string]: UploadedFile;
};
throwErrorOnNotFound: boolean;
/**
* The router sets the body when it was read.
*/
body?: Buffer;
async readBody(): Promise<Buffer>;
async readBodyText(): Promise<string>;
static GET(path: string): RequestBuilder;
static POST(path: string): RequestBuilder;
static OPTIONS(path: string): RequestBuilder;
static TRACE(path: string): RequestBuilder;
static HEAD(path: string): RequestBuilder;
static PATCH(path: string): RequestBuilder;
static PUT(path: string): RequestBuilder;
static DELETE(path: string): RequestBuilder;
getUrl(): string;
getMethod(): string;
getRemoteAddress(): string;
}
export class MemoryHttpResponse extends HttpResponse {
body: Buffer;
headers: {
[name: string]: number | string | string[] | undefined;
};
setHeader(name: string, value: number | string | ReadonlyArray<string>): this;
removeHeader(name: string);
getHeader(name: string);
getHeaders(): OutgoingHttpHeaders;
writeHead(statusCode: number, headersOrReasonPhrase?: string | OutgoingHttpHeaders | OutgoingHttpHeader[], headers?: OutgoingHttpHeaders | OutgoingHttpHeader[]): this;
get json(): any;
get text(): string;
get bodyString(): string;
write(chunk: any, encoding: any, callback?: any): any;
end(chunk: any, encoding?: any, callback?: any): any;
}
export class HttpLogger {
constructor(private logger: LoggerInterface);
onHttpRequest(event: typeof httpWorkflow.onResponse.event);
}
@entity.name()
export class UploadedFile {
/**
* Validator to ensure the file was provided by the framework, and not the user spoofing it.
*/
validator: typeof UploadedFileSymbol | null;
/**
* The size of the uploaded file in bytes.
*/
size: number;
/**
* The local path this file is being written to. Will be deleted when request is handled.
*/
path: string;
/**
* The name this file had according to the uploading client.
*/
name: string | null;
/**
* The mime type of this file, according to the uploading client.
*/
type: string | null;
/**
* A Date object (or `null`) containing the time this file was last written to.
* Mostly here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/).
*/
lastModifiedDate: Date | null;
}
export class RouteConfig {
baseUrl: string;
responses: {
statusCode: number;
description: string;
type?: Type;
}[];
description: string;
groups: string[];
category: string;
returnType?: Type;
serializationOptions?: SerializationOptions;
serializer?: Serializer;
/**
* When assigned defines where this route came from.
*/
module?: InjectorModule<any>;
resolverForToken: Map<any, ClassType>;
middlewares: {
config: HttpMiddlewareConfig;
module?: InjectorModule<any>;
}[];
resolverForParameterName: Map<string, ClassType>;
/**
* An arbitrary data container the user can use to store app specific settings/values.
*/
data;
constructor(public readonly name: string, public readonly httpMethods: string[], public readonly path: string, public readonly action: RouteClassControllerAction | RouteFunctionControllerAction, public internal: boolean = false);
getReflectionFunction(): ReflectionFunction;
getSchemaForResponse(statusCode: number): Type | undefined;
getFullPath(): string;
}
export class ParsedRoute {
regex?: string;
pathParameterNames: {
[name: string]: number;
};
constructor(public routeConfig: RouteConfig);
addParameter(property: ReflectionParameter): ParameterForRequestParser;
getParameters(): ParameterForRequestParser[];
getParameter(name: string): ParameterForRequestParser;
}
export abstract class HttpRouterRegistryFunctionRegistrar {
abstract addRoute(routeConfig: RouteConfig): void;
/**
* Returns a new registrar object with default options that apply to each registered route through this registrar.
*
* ```typescript
* const registry: HttpRouterRegistry = ...;
*
* const secretRegistry = registry.forOptions({groups: ['secret']});
*
* secretRegistry.get('/admin/groups', () => {
* });
*
* secretRegistry.get('/admin/users', () => {
* });
* ```
*/
forOptions(options: Partial<HttpRouterFunctionOptions>): HttpRouterRegistryFunctionRegistrar;
any(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
add(decorator: HttpDecorator, callback: (...args: any[]) => any);
get(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
post(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
put(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
patch(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
delete(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
options(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
trace(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
head(pathOrOptions: string | HttpRouterFunctionOptions, callback: (...args: any[]) => any);
}
export class HttpRouterRegistry extends HttpRouterRegistryFunctionRegistrar {
getBuildId(): number;
getRoutes(): RouteConfig[];
addRouteForController(controller: ClassType, module: InjectorModule<any>);
addRoute(routeConfig: RouteConfig);
}
export class HttpRouter {
constructor(controllers: HttpControllers, private logger: LoggerInterface, private config: HttpConfig, private middlewareRegistry: MiddlewareRegistry = new MiddlewareRegistry, private registry: HttpRouterRegistry = new HttpRouterRegistry);
getRoutes(): RouteConfig[];
static forControllers(controllers: (ClassType | {
module: InjectorModule<any>;
controller: ClassType;
})[], middlewareRegistry: MiddlewareRegistry = new MiddlewareRegistry(), module: InjectorModule<any> = new InjectorModule(), config: HttpConfig = new HttpConfig()): HttpRouter;
addRoute(routeConfig: RouteConfig);
addRouteForController(controller: ClassType, module: InjectorModule<any>);
resolveUrl(routeName: string, parameters: {
[name: string]: any;
} = {}): string;
resolveRequest(request: HttpRequest): ResolvedController | undefined;
resolve(method: string, url: string): ResolvedController | undefined;
}
export class HttpKernel {
constructor(protected router: HttpRouter, protected eventDispatcher: EventDispatcher, protected injectorContext: InjectorContext, protected logger: LoggerInterface, protected stopwatch?: Stopwatch);
/**
* Creates a request handler function that can be used with http.createServer
* or any other http server library based on the node.js http module.
*
* When `fallThroughOnNotFound` is set to true, the handler will call `next()`
* when the route is not found, allowing the request to fall through to the next
* middleware in the chain.
*
* @example
* ```typescript
* import { createServer } from 'http';
*
* const app = new App({
* imports: [new HttpModule({})],
* });
*
* const handler = app.get(HttpKernel).createMiddleware({ fallThroughOnNotFound: true });
* const server = createServer(handler);
*
* server.listen(3000);
* ```
*/
createMiddleware(options: HttpKernelMiddlewareOptions = {});
async request(requestBuilder: RequestBuilder, options: HttpKernelHandleOptions = {}): Promise<MemoryHttpResponse>;
async handleRequest(_req: IncomingMessage, _res: ServerResponse, options: HttpKernelHandleOptions = {}): Promise<void>;
}
export class HttpModule extends createModuleClass({
config: HttpConfig, providers: [
HttpRouter, HttpKernel, HttpResultFormatter, HttpRouterRegistry, HttpRouterFilterResolver, { provide: HttpResponse, scope: }, { provide: HttpRequest, scope: }, { provide: RouteConfig, useValue: undefined, scope: }, { provide: Logger, useValue: new Logger([new ConsoleTransport()]) },
], listeners: [
HttpListener,
], workflows: [
httpWorkflow
], exports: [
HttpRouter, HttpRouterRegistry, HttpKernel, HttpResultFormatter, HttpRouterFilterResolver, HttpResponse, HttpRequest, HttpControllers, RouteConfig, Logger,
]
}) {
process();
processListener(module: AppModule<any>, listener: AddedListener);
processController(module: AppModule<any>, config: ControllerConfig);
}
export class HttpConfig {
debug: boolean;
parser: HttpParserOptions;
/**
* Limits maximum incoming headers count. If set to 0, no limit will be applied.
*/
maxHeadersCount?: number;
/**
* The maximum number of requests socket can handle
* before closing keep alive connection.
*
* A value of `0` will disable the limit.
*
* When the limit is reached it will set the `Connection` header value to `close`,
* but will not actually close the connection, subsequent requests sent
* after the limit is reached will get `503 Service Unavailable` as a response.
*/
maxRequestsPerSocket?: number;
/**
* The number of milliseconds of inactivity before a socket is presumed
* to have timed out.
*
* A value of `0` will disable the timeout behavior on incoming connections.
*
* The socket timeout logic is set up on connection, so changing this
* value only affects new connections to the server, not any existing connections.
*/
timeout?: number;
/**
* Limit the amount of time the parser will wait to receive the complete HTTP
* headers.
*
* If the timeout expires, the server responds with status 408 without
* forwarding the request to the request listener and then closes the connection.
*
* It must be set to a non-zero value (e.g. 120 seconds) to protect against
* potential Denial-of-Service attacks in case the server is deployed without a
* reverse proxy in front.
*/
headersTimeout?: number;
/**
* The number of milliseconds of inactivity a server needs to wait for additional
* incoming data, after it has finished writing the last response, before a socket
* will be destroyed. If the server receives new data before the keep-alive
* timeout has fired, it will reset the regular inactivity timeout, i.e., `server.timeout`.
*
* A value of `0` will disable the keep-alive timeout behavior on incoming
* connections.
* A value of `0` makes the http server behave similarly to Node.js versions prior
* to 8.0.0, which did not have a keep-alive timeout.
*
* The socket timeout logic is set up on connection, so changing this value only
* affects new connections to the server, not any existing connections.
*/
keepAliveTimeout?: number;
/**
* Sets the timeout value in milliseconds for receiving the entire request from
* the client.
*
* If the timeout expires, the server responds with status 408 without
* forwarding the request to the request listener and then closes the connection.
*
* It must be set to a non-zero value (e.g. 120 seconds) to protect against
* potential Denial-of-Service attacks in case the server is deployed without a
* reverse proxy in front.
*
* Default is 5 minutes.
*/
requestTimeout?: number;
}
export class HttpControllers {
constructor(public readonly controllers: {
controller: ClassType;
module: InjectorModule<any>;
}[] = []);
add(controller: ClassType, module: InjectorModule<any>);
}
export class HttpMiddlewareConfig {
name?: string;
middlewares: (HttpMiddlewareFn | ClassType<HttpMiddleware>)[];
routes: HttpMiddlewareRoute[];
excludeRoutes: HttpMiddlewareRoute[];
order: number;
controllers: ClassType[];
excludeControllers: ClassType[];
routeNames: string[];
excludeRouteNames: string[];
timeout?: number;
modules: InjectorModule<any>[];
selfModule: boolean;
getClassTypes(): ClassType[];
}
export class HttpMiddlewareApi {
t;
name(name: string);
for(...middlewares: (HttpMiddlewareFn | ClassType<HttpMiddleware>)[]);
forRoutes(...routes: HttpMiddlewareRoute[]);
excludeRoutes(...routes: HttpMiddlewareRoute[]);
forRouteNames(...names: string[]);
excludeRouteNames(...names: string[]);
/**
* When the middleware does not respond (either calling next() or sending headers) withing <timeout> milliseconds,
* automatically the next is executed and warning printed.
*/
timeout(timeout: number);
forControllers(...controllers: ClassType[]);
excludeControllers(...controllers: ClassType[]);
/**
* Per default middlewares are executed in the order they were registered. The default order is 0. A lower order means the middleware is executed earlier.
*/
order(order: number);
forModules(...modules: AppModule<any>[]);
/**
* Limit the middleware to the module where this middleware is defined.
*/
forSelfModules();
}
export class HttpRouteFilterModel {
controllers: ClassType[];
excludeControllers: ClassType[];
routes: HttpRouteFilterRoute[];
excludeRoutes: HttpRouteFilterRoute[];
routeNames: string[];
excludeRouteNames: string[];
modules: AppModule<any>[];
excludeModules: AppModule<any>[];
moduleClasses: ClassType<AppModule<any>>[];
excludeModuleClasses: ClassType<AppModule<any>>[];
reset();
}
export class HttpRouterFilterResolver {
constructor(protected router: HttpRouter);
/**
* Resolves
*/
resolve(filter: HttpRouteFilterModel): RouteConfig[];
}
export class HttpRouteFilter {
model;
reset(): this;
forControllers(...controllers: ClassType[]): this;
excludeControllers(...controllers: ClassType[]): this;
forRoutes(...routes: HttpRouteFilterRoute[]): this;
excludeRoutes(...routes: HttpRouteFilterRoute[]): this;
forRouteNames(...names: string[]): this;
excludeRouteNames(...names: string[]): this;
forModules(...modules: AppModule<any>[]): this;
excludeModules(...modules: AppModule<any>[]): this;
forModuleClasses(...moduleClasses: ClassType<AppModule<any>>[]): this;
excludeModuleClasses(...moduleClasses: ClassType<AppModule<any>>[]): this;
}
Errors
export class HttpError<T extends number> extends CustomError {
constructor(public message: string, public httpCode: T);
}
export class HttpBadRequestError extends createHttpError(, ) {
}
export class HttpUnauthorizedError extends createHttpError(, ) {
}
export class HttpAccessDeniedError extends createHttpError(, ) {
}
export class HttpNotFoundError extends createHttpError(, ) {
}
export class HttpMethodNotAllowedError extends createHttpError(, ) {
}
export class HttpNotAcceptableError extends createHttpError(, ) {
}
export class HttpTimeoutError extends createHttpError(, ) {
}
export class HttpConflictError extends createHttpError(, ) {
}
export class HttpGoneError extends createHttpError(, ) {
}
export class HttpTooManyRequestsError extends createHttpError(, ) {
}
export class HttpInternalServerError extends createHttpError(, ) {
}
export class HttpNotImplementedError extends createHttpError(, ) {
}
Const
HttpMerge<Omit<FluidDecorator<HttpControllerDecorator, ClassDecoratorFn> & ClassDecoratorFn & { _fetch: (classType: AbstractClassType, property?: string, parameterIndexOrDescriptor?: any) => HttpController; } & HttpActionFluidDecorator<...> & PropertyDecoratorFn & { ...; }, "t" | "_fetch">>
typeof HttpWorkflowEvent
typeof HttpWorkflowEvent
WorkflowDefinition<{ start: typeof WorkflowEvent; request: typeof HttpWorkflowEvent; route: typeof HttpRouteEvent; routeNotFound: typeof HttpWorkflowEvent; ... 6 more ...; response: typeof HttpResponseEvent; }> & WorkflowDefinitionEvents<...>
unique symbol
Functions
(target: ClassType): HttpAction[]
ClassDecoratorResult<typeof HttpControllerDecorator>
HttpActionPropertyDecoratorResult
(v: any): v is ElementStruct
<T extends number>(code: T, defaultMessage?: string): ClassType<HttpError<T>>
(request: IncomingMessage): Promise<Buffer>
request.body
.request.body
if available.(request: Partial<IncomingMessage>, body: Buffer): HttpRequest
(type: Type): string | RegExp | undefined
(request: IncomingMessage): HttpRequest
(response: ServerResponse): HttpResponse
(action: RouteClassControllerAction | RouteFunctionControllerAction): string
(routeConfig: RouteConfig): ParsedRoute
(dotPath: string): string
(localPath: string, path: string, request: HttpRequest, response: HttpResponse): Promise<unknown>
(event: typeof httpWorkflow.onRoute.event, path: string, localPath: string): Promise<unknown>
(module: AppModule<any>, path: string, localPath?: string): ClassType
(module: AppModule<any>, options: StaticHttpOptions): void
FreeDecoratorResult<typeof HttpMiddlewareApi>
(path: string): string
Types
type HttpDecorator = PropertyDecoratorFn & HttpActionFluidDecorator<HttpActionDecorator, PropertyDecoratorFn>;
type SupportedHttpResult =
undefined
| null
| number
| string
| Response
| JSONResponse
| HtmlResponse
| HttpResponse
| ServerResponse
| stream.Readable
| Redirect
| Uint8Array
| Error;
interface HttpResultFormatterContext {
request: HttpRequest;
response: HttpResponse;
route?: RouteConfig;
}
type HttpRequestQuery = { [name: string]: string };
type HttpRequestResolvedParameters = { [name: string]: any };
type HttpRequestPositionedParameters = { arguments: any[], parameters: HttpRequestResolvedParameters };
type HttpBody<T> = T & TypeAnnotation<'httpBody'>;
type HttpBodyValidation<T> = ValidatedBody<T> & TypeAnnotation<'httpBodyValidation'>;
interface HttpRequestParserOptions {
withPath?: boolean;
withBody?: boolean;
withQuery?: boolean;
withHeader?: boolean;
}
type HttpRequestParser<T> = ((options?: HttpRequestParserOptions) => Promise<T>) & TypeAnnotation<'httpRequestParser', T>;
{withBody: false}
to disable body parsing.
Or {withQuery: false}
to disable query parsing. Or {withHeader: false}
to disable header parsing.
To only parse the body, use {withQuery: false, withHeader: false}
.type HttpPath<T, Options extends { name?: string } = {}> = T & TypeAnnotation<'httpPath', Options>;
type HttpHeader<T, Options extends { name?: string } = {}> = T & TypeAnnotation<'httpHeader', Options>;
type HttpQuery<T, Options extends { name?: string } = {}> = T & TypeAnnotation<'httpQuery', Options>;
type HttpQueries<T, Options extends { name?: string } = {}> = T & TypeAnnotation<'httpQueries', Options>;
type HttpRegExp<T, Pattern extends string | RegExp> = T & TypeAnnotation<'httpRegExp', Pattern>;
type RouteParameterResolverForInjector = ((injector: InjectorContext) => HttpRequestPositionedParameters | Promise<HttpRequestPositionedParameters>);
interface RouteFunctionControllerAction {
type: 'function';
//if not set, the root module is used
module?: InjectorModule<any>;
fn: (...args: any[]) => any;
}
interface RouteClassControllerAction {
type: 'controller';
//if not set, the root module is used
module?: InjectorModule<any>;
controller: ClassType;
methodName: string;
}
interface RouteParameterResolver {
resolve(context: RouteParameterResolverContext): any | Promise<any>;
}
interface RouteParameterResolverContext {
token: ClassType | string | symbol | any;
route: RouteConfig;
request: HttpRequest;
/**
* The parameter name (variable name).
*/
name: any;
/**
* The raw parameter value from the path, if the parameter is defined in the path (e.g. /user/:name).
* If not in the path, you have to use `parameters.<name>` instead.
*/
value: any;
query: HttpRequestQuery;
parameters: HttpRequestResolvedParameters;
type: ReflectionParameter;
}
interface HttpRouterFunctionOptions {
path: string;
name?: string;
methods?: string[];
description?: string;
category?: string;
groups?: string[];
/**
* An arbitrary data container the user can use to store app specific settings/values.
*/
data?: Record<any, any>;
baseUrl?: string;
middlewares?: (() => HttpMiddlewareConfig)[];
serializer?: Serializer;
serializationOptions?: SerializationOptions;
resolverForToken?: Map<any, ClassType>;
resolverForParameterName?: Map<string, ClassType>;
responses?: { statusCode: number, description: string, type?: Type }[];
}
interface StaticHttpOptions {
/**
* The public URL path.
*/
path: string;
/**
* The local path from the file system. Either relative or absolute.
*/
localPath: string;
groups?: string[];
/**
* The controller name of the registered controller class. Is per default `StaticController`.
*/
controllerName?: string;
/**
* Replaces strings in the served index.html file.
*/
indexReplace?: { [name: string]: string };
}
interface FormidableOptions {
/**
* sets encoding for incoming form fields
*
* @default 'utf-8'
*/
encoding?: string | undefined;
/**
* the directory for placing file uploads in. You can move them later by using fs.rename()
*
* @default os.tmpdir()
*/
uploadDir?: string | undefined;
/**
* to include the extensions of the original files or not
*
* @default false
*/
keepExtensions?: boolean | undefined;
/**
* allow upload empty files
*
* @default true
*/
allowEmptyFiles?: boolean | undefined;
/**
* the minium size of uploaded file
*
* @default 0
*/
minFileSize?: number | undefined;
/**
* limit the amount of uploaded files, set Infinity for unlimited
*
* @default Infinity
*/
maxFiles?: number | undefined;
/**
* limit the size of uploaded file
*
* @default 200 * 1024 * 1024
*/
maxFileSize?: number | undefined;
/**
* limit the size of the batch of uploaded files
*
* @default options.maxFileSize
*/
maxTotalFileSize?: number | undefined;
/**
* limit the number of fields, set 0 for unlimited
*
* @default 1000
*/
maxFields?: number | undefined;
/**
* limit the amount of memory all fields together (except files) can allocate in bytes
*
* @default 20 * 1024 * 1024
*/
maxFieldsSize?: number | undefined;
/**
* include checksums calculated for incoming files, set this to some hash algorithm, see
* crypto.createHash for available algorithms
*
* @default false
*/
hashAlgorithm?: string | false | undefined;
/**
* plugin imports from formidable package
*/
enabledPlugins?: any[] | undefined;
}
interface HttpParserOptions extends FormidableOptions {
/**
* allow extracting JSON from a multipart/form-data request
*/
multipartJsonKey?: string | undefined;
}
type HttpMiddlewareFn = (req: HttpRequest, res: HttpResponse, next: (err?: any) => void) => void | Promise<void>;
interface HttpMiddleware {
execute: HttpMiddlewareFn;
}
interface HttpMiddlewareRoute {
path?: string;
pathRegExp?: RegExp;
httpMethod?: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'OPTIONS' | 'TRACE';
category?: string;
excludeCategory?: string;
group?: string;
excludeGroup?: string;
}
interface HttpRouteFilterRoute {
path?: string;
pathRegExp?: RegExp;
httpMethod?: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'OPTIONS' | 'TRACE';
category?: string;
group?: string;
}