UNPKG

hyper-express

Version:

High performance Node.js webserver with a simple-to-use API powered by uWebsockets.js under the hood.

285 lines (250 loc) 10.5 kB
import { Readable, Writable } from 'stream'; import * as uWebsockets from 'uWebSockets.js'; import { LiveFile } from '../plugins/LiveFile'; import { Server } from '../Server'; import { SSEventStream } from '../plugins/SSEventStream'; export type SendableData = string | Buffer | ArrayBuffer; export type FileCachePool = { [key: string]: LiveFile; }; export interface CookieOptions { domain?: string; path?: string; maxAge?: number; secure?: boolean; httpOnly?: boolean; sameSite?: boolean | 'none' | 'lax' | 'strict'; secret?: string; } type DefaultResponseLocals = { [key: string]: any; }; export class Response<Locals = DefaultResponseLocals> extends Writable { /** * Underlying raw lazy initialized writable stream. */ _writable: null | Writable; /** * Alias of aborted property as they both represent the same request state in terms of inaccessibility. */ completed: boolean; /* HyperExpress Methods */ /** * Alias of `uWS.HttpResponse.cork()` which allows for manual corking of the response. * This is required by `uWebsockets.js` to maximize network performance with batched writes. * * @param {Function} handler * @returns {Response} Response (Chainable) */ atomic(handler: () => void): Response; /** * This method is used to set a custom response code. * * @param {Number} code Example: response.status(403) * @param {String=} message Example: response.status(403, 'Forbidden') * @returns {Response} Response (Chainable) */ status(code: number, message?: string): Response; /** * This method is used to set the response content type header * based on the provided mime type. Example: type('json') * * @param {String} mime_type Mime type * @returns {Response} Response (Chainable) */ type(mime_type: string): Response; /** * This method can be used to write a response header and supports chaining. * * @param {String} name Header Name * @param {String|Array<String>} value Header Value * @param {Boolean=} overwrite If true, overwrites existing header value with same name * @returns {Response} Response (Chainable) */ header(name: string, value: string | Array<string>, overwrite?: boolean): Response; /** * This method is used to write a cookie to incoming request. * To delete a cookie, set the value to null. * * @param {String} name Cookie Name * @param {String|null} value Cookie Value * @param {Number=} expiry In milliseconds * @param {CookieOptions=} options Cookie Options * @param {Boolean=} sign_cookie Enables/Disables Cookie Signing * @returns {Response} Response (Chainable) */ cookie( name: string, value: string | null, expiry?: number, options?: CookieOptions, sign_cookie?: boolean ): Response; /** * This method is used to upgrade an incoming upgrade HTTP request to a Websocket connection. * @param {Object=} context Store information about the websocket connection */ upgrade(context?: Object): void; /** * Binds a drain handler which gets called with a byte offset that can be used to try a failed chunk write. * You MUST perform a write call inside the handler for uWS chunking to work properly. * You MUST return a boolean value indicating if the write was successful or not. * * @param {function(number):boolean} handler Synchronous callback only */ drain(handler: (offset: number) => boolean): void; /** * This method is used to end the current request and send response with specified body and headers. * * @param {String|Buffer|ArrayBuffer} body Optional * @returns {Boolean} 'false' signifies that the result was not sent due to built up backpressure. */ send(body?: SendableData, close_connection?: boolean): Response; /** * This method is used to pipe a readable stream as response body and send response. * By default, this method will use chunked encoding transfer to stream data. * If your use-case requires a content-length header, you must specify the total payload size. * * @param {Readable} readable A Readable stream which will be piped as response body * @param {Number=} total_size Total size of the Readable stream source in bytes (Optional) */ stream(readable: Readable, total_size?: number): Promise<void>; /** * Instantly aborts/closes current request without writing a status response code. * Use this only in extreme situations to abort a request where a proper response is not neccessary. */ close(): void; /** * This method is used to redirect an incoming request to a different url. * * @param {String} url Redirect URL * @returns {Boolean} */ redirect(url: string): boolean; /** * This method is an alias of send() method except it accepts an object and automatically stringifies the passed payload object. * * @param {Object} body JSON body * @returns {Boolean} Boolean */ json(body: any): boolean; /** * This method is an alias of send() method except it accepts an object * and automatically stringifies the passed payload object with a callback name. * Note! This method uses 'callback' query parameter by default but you can specify 'name' to use something else. * * @param {Object} body * @param {String=} name * @returns {Boolean} Boolean */ jsonp(body: any, name?: string): boolean; /** * This method is an alias of send() method except it automatically sets * html as the response content type and sends provided html response body. * * @param {String} body * @returns {Boolean} Boolean */ html(body: string): boolean; /** * This method is an alias of send() method except it sends the file at specified path. * This method automatically writes the appropriate content-type header if one has not been specified yet. * This method also maintains its own cache pool in memory allowing for fast performance. * Avoid using this method to a send a large file as it will be kept in memory. * * @param {String} path * @param {function(Object):void=} callback Executed after file has been served with the parameter being the cache pool. */ file(path: string, callback?: (pool: FileCachePool) => void): void; /** * Writes approriate headers to signify that file at path has been attached. * * @param {String} path * @param {String=} name * @returns {Response} Chainable */ attachment(path: string, name?: string): Response; /** * Writes appropriate attachment headers and sends file content for download on user browser. * This method combined Response.attachment() and Response.file() under the hood, so be sure to follow the same guidelines for usage. * * @param {String} path * @param {String=} filename */ download(path: string, filename?: string): void; /** * This method allows you to throw an error which will be caught by the global error handler (If one was setup with the Server instance). * * @param {Error} error */ throw(error: Error): Response; /* HyperExpress Properties */ /** * Returns the underlying raw uWS.Response object. * @returns {uWebsockets.Response} */ get raw(): uWebsockets.HttpResponse; /** * Returns the HyperExpress.Server instance this Response object originated from. * * @returns {Server} */ get app(): Server; /** * Returns whether response has been initiated by writing the HTTP status code and headers. * Note! No changes can be made to the HTTP status code or headers after a response has been initiated. * @returns {Boolean} */ get initiated(): boolean; /** * Returns current state of request in regards to whether the source is still connected. * @returns {Boolean} */ get aborted(): boolean; /** * Returns the current response body content write offset in bytes. * Use in conjunction with the drain() offset handler to retry writing failed chunks. * @returns {Number} */ get write_offset(): number; /** * Upgrade socket context for upgrade requests. * @returns {uWebsockets.ux_socket_context} */ get upgrade_socket(): uWebsockets.us_socket_context_t; /** * Returns a "Server-Sent Events" connection object to allow for SSE functionality. * This property will only be available for GET requests as per the SSE specification. * * @returns {SSEventStream=} */ get sse(): SSEventStream | undefined /* ExpressJS Methods */ append(name: string, values: string | Array<string>): Response; writeHead(name: string, values: string | Array<string>): Response; setHeader(name: string, values: string | Array<string>): Response; writeHeaders(headers: Object): void; setHeaders(headers: Object): void; writeHeaderValues(name: string, values: Array<string>): void; getHeader(name: string): string | Array<string> | void; getHeaders(): { [key: string]: Array<string> }; removeHeader(name: string): void; setCookie(name: string, value: string, options?: CookieOptions): Response; hasCookie(name: string): Boolean; removeCookie(name: string): Response; clearCookie(name: string): Response; get(name: string): string | Array<string>; links(links: Object): string; location(path: string): Response; sendFile(path: string): void; sendStatus(status_code: number): Response; set(field: string | object, value?: string | Array<string>): Response | void; vary(name: string): Response; /* ExpressJS Properties */ get headersSent(): boolean; get statusCode(): number | undefined; set statusCode(value: number | undefined); get statusMessage(): string | undefined; set statusMessage(value: string | undefined); locals: Locals; }