import { IncomingMessage, OutgoingHttpHeader, OutgoingHttpHeaders, ServerResponse } from 'http'; import { UploadedFile } from './router.js'; import { Type, ValidationErrorItem } from '@deepkit/type'; import { TypeAnnotation } from '@deepkit/core'; export declare class HttpResponse extends ServerResponse { status(code: number): void; } /** * Reads the body of the request and returns it as a Buffer. * The result will be cached in the request object as `request.body`. * * Deepkit's router will automatically use `request.body` if available. */ export declare function readBody(request: IncomingMessage): Promise; export declare function createRequestWithCachedBody(request: Partial, body: Buffer): HttpRequest; export type HttpRequestQuery = { [name: string]: string; }; export type HttpRequestResolvedParameters = { [name: string]: any; }; export type HttpRequestPositionedParameters = { arguments: any[]; parameters: HttpRequestResolvedParameters; }; export declare class BodyValidationError { readonly errors: ValidationErrorItem[]; constructor(errors?: ValidationErrorItem[]); hasErrors(prefix?: string): boolean; getErrors(prefix?: string): ValidationErrorItem[]; getErrorsForPath(path: string): ValidationErrorItem[]; getErrorMessageForPath(path: string): string; } export declare class ValidatedBody { error: BodyValidationError; value?: T | undefined; constructor(error: BodyValidationError, value?: T | undefined); valid(): this is { value: T; }; } /** * Marks a parameter as HTTP body and reads the value from the request body. * * @example * ```typescript * class Controller { * @http.GET('/api') * route(body: HttpBody<{username: string}>) { * //body is {username: string} and required * //could also reference an interface or type alias via `HttpBody` * } * } * * // curl /api -d '{"username":"Peter"}' */ export type HttpBody = T & TypeAnnotation<'httpBody'>; export type HttpBodyValidation = ValidatedBody & TypeAnnotation<'httpBodyValidation'>; export interface HttpRequestParserOptions { withPath?: boolean; withBody?: boolean; withQuery?: boolean; withHeader?: boolean; } /** * 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. `{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}`. * * @example * ```typescript * async route(parser: HttpRequestParser<{authorization: string}>) { * const data = await parser(); * console.log(data.authorization); * } * ``` * * Note that the parsers is based on all defined parameters (e.g. `userId: HttpQuery` => {userId: string}), * and then starts from there applying header, body, and then query values. * This means you also get access to defined path parameters, like: * * ```typescript * @http.GET('teams/:teamId') * async route(teamId: string) { * //teamId is string * } * * httpWorkflow.onController.listen((event, parser: HttpRequestParser<{teamId: string}>) => { * const data = await parser(); * console.log(data.teamId); * }); * ``` * * HttpRequestParser is necessary in event listeners, since they are instantiated synchronously, * but body is parsed asynchronously. So use in event listeners HttpRequestParser instead of HttpBody. */ export type HttpRequestParser = ((options?: HttpRequestParserOptions) => Promise) & TypeAnnotation<'httpRequestParser', T>; /** * 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. * * @example * ```typescript * app.listen(httpWorkflow.onController, (event, request: HttpRequest, groupId: HttpPath) => { * console.log(groupId); //123 * }); * * class Controller { * @http.GET('/api/:groupId') * route(groupId: number) { * //groupId is number and required * //same as `groupId: HttpPath` * } * } * ``` */ export type HttpPath = T & TypeAnnotation<'httpPath', Options>; /** * Marks a parameter as HTTP header and reads the value from the request header. * * @example * ```typescript * class Controller { * @http.GET('/api') * route(authorization: HttpHeader) { * //authorization is string and required * //use `authorization?: HttpHeader` to make it optional * } * } * * // curl /api -H 'Authorization: 123' * ``` * * To change the header name, use `param: HttpHeader`. */ export type HttpHeader = T & TypeAnnotation<'httpHeader', Options>; /** * Marks a parameter as HTTP query and reads the value from the request query string. * * @example * ```typescript * class Controller { * @http.GET('/api') * route(limit: HttpQuery) { * //limit is number and required * //use `limit?: HttpQuery` to make it optional * } * } * * // curl /api?limit=10 * ``` */ export type HttpQuery = T & TypeAnnotation<'httpQuery', Options>; /** * Marks a parameter as HTTP query objects and reads multiple values from the request query string into an object. * * @example * ```typescript * interface Query { * limit?: number; * offset?: number; * sort?: 'asc' | 'desc'; * } * * class Controller { * @http.GET('/api') * route(query: HttpQueries) { * //query is an object containing limit, offset, and sort * } * * // curl /api?limit=10&offset=20&sort=asc */ export type HttpQueries = T & TypeAnnotation<'httpQueries', Options>; /** * For all parameters used in the URL path, a regular expression of /[^/]+/ is used. To change that, use getRegExp. * * @example * ```typescript * * class Controller { * @http.GET('/user/:username') * route(username: HttpRegExp) { * //username is string * } * } * ``` */ export type HttpRegExp = T & TypeAnnotation<'httpRegExp', Pattern>; export declare function getRegExp(type: Type): string | RegExp | undefined; export declare class RequestBuilder { protected path: string; protected method: string; protected contentBuffer: Buffer; protected _headers: { [name: string]: string; }; protected queryPath?: string; constructor(path: string, method?: string); getUrl(): string; 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 declare 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; readBody(): Promise; readBodyText(): Promise; 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 declare function incomingMessageToHttpRequest(request: IncomingMessage): HttpRequest; export declare function serverResponseToHttpResponse(response: ServerResponse): HttpResponse; export declare class MemoryHttpResponse extends HttpResponse { body: Buffer; headers: { [name: string]: number | string | string[] | undefined; }; setHeader(name: string, value: number | string | ReadonlyArray): this; removeHeader(name: string): void; getHeader(name: string): string | number | string[] | undefined; 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 declare type __ΩHttpRequestQuery = any[]; export declare type __ΩHttpRequestResolvedParameters = any[]; export declare type __ΩHttpRequestPositionedParameters = any[]; export declare type __ΩHttpBody = any[]; export declare type __ΩHttpBodyValidation = any[]; export declare type __ΩHttpRequestParserOptions = any[]; export declare type __ΩHttpRequestParser = any[]; export declare type __ΩHttpPath = any[]; export declare type __ΩHttpHeader = any[]; export declare type __ΩHttpQuery = any[]; export declare type __ΩHttpQueries = any[]; export declare type __ΩHttpRegExp = any[];