bun-route
Version:
A fast, Express-like router for the high-performance bun.serve() HTTP server.
453 lines (448 loc) • 17.4 kB
TypeScript
// Generated by dts-bundle-generator v9.5.1
import { Server, SocketAddress } from 'bun';
import { BodyInit as BodyInit$1 } from 'undici-types';
export type HttpMethodString = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE" | "PATCH";
export declare enum HttpMethod {
ALL = 1,
GET = 2,
PUT = 3,
POST = 4,
PATCH = 5,
DELETE = 6,
HEAD = 7,
OPTIONS = 8,
TRACE = 9,
CONNECT = 10,
UNKNOWN = 11
}
export declare function parseHttpMethods(method: string): HttpMethod;
export declare function stringifyHttpMethods(method: HttpMethod | undefined): string;
export type BunRequest = Request;
export declare const notFoundResponse: Response;
export declare class ResponseBuilder {
submit: boolean;
statusCode: number;
statusText?: string;
bodyInit: BodyInit$1;
headers: [
string,
string
][];
beforeSentHooks: ((res: ResponseBuilder) => Awaitable<void>)[] | undefined;
/**
* Adds a hook that will be called before the response is build for sending
* @param hook The hook to add
* @returns The ResponseBuilder instance
*/
beforeSent(hook: (res: ResponseBuilder) => Awaitable<void>): ResponseBuilder;
/**
* Starts the before sent hooks in order and waits for them all to finish
* @param p The promise to wait for before starting the hooks
*/
private startBeforeSentHookAsync;
/**
* Starts the before sent hooks in order and waits for them all to finish
* @returns A promise that resolves when all the hooks have finished
*/
startBeforeSentHook(): Awaitable<void>;
/**
* Builds the bun response object
* @returns The final response object
*/
build(): Response;
/**
* Resets the response builder to its default state, clearing all options and properties.
* @returns The response builder instance
*/
reset(): ResponseBuilder;
/**
* Sets the status code and optional status text of the response.
* @param statusCode The status code
* @param statusText The status text, if provided
* @returns The response builder instance
*/
status(statusCode: number, statusText?: string): ResponseBuilder;
/**
* Removes the given header from the response.
* @param name The name of the header to remove
* @returns The response builder instance
*/
unsetHeader(name: string): ResponseBuilder;
/**
* Sets a header on the response.
* @param name The name of the header to set
* @param value The value of the header
* @param overwrite Whether to overwrite any existing header with the same name. Default is true.
* @returns The response builder instance
*/
setHeader(name: string, value: string, overwrite?: boolean): ResponseBuilder;
/**
* Sets a cookie on the response.
* @param name The name of the cookie
* @param value The value of the cookie
* @param options The options for the cookie
* @returns The response builder instance
*/
setCookie(name: string, value: string, options?: CookieOptions): ResponseBuilder;
/**
* Unsets a cookie on the response.
* @param name The name of the cookie to unset
* @returns The response builder instance
*/
unsetCookie(name: string): ResponseBuilder;
/**
* Sets the body of the response.
* @param bodyInit The body of the response
* @returns The response builder instance
*/
body(bodyInit?: BodyInit$1): ResponseBuilder;
/**
* Submits the response to the client, with an optional body.
* @param bodyInit The body of the response, if any
*/
send(bodyInit?: BodyInit$1): void;
/**
* Redirects to a given url. If perma is true, this is a 308 redirect, otherwise it is a 307.
* @param url The url to redirect to
* @param perma Whether this is a permanent redirect
* @returns void because it is submitted to the client
*/
sendRedirect(url: string, perma?: boolean): void;
/**
* Redirects to a given url with a custom status code.
* @param url The url to redirect to
* @param status The status code to use for the redirect
* @returns void because it is submitted to the client
*/
sendRedirectCustom(url: string, status: number): void;
/**
* Sets the status code to 401 and adds a basic auth `WWW-Authenticate` header.
* @param realm The realm to use for the header. Default is "User Visible Realm".
* @param charset The character set to use for the realm. Default is "UTF-8".
* @returns void because it is submitted to the client
*/
sendBasicAuth(bodyInit?: BodyInit$1, realm?: string, charset?: string): void;
}
export type SplitPath = [
string,
...string[]
] | undefined;
/**
* ## Simple Router
* ### About
* A simple express-like router written for bun serve.
*
* ### Author
* By [NobleMajo](https://github.com/NobleMajo)
* @see https://github.com/NobleMajo
*
* ### Usage:
* You can use the bun.serve function and use router.handle as fetch parameter of the settings:
* ```ts
* export const server = Bun.serve({
* fetch: router.handle,
* })
* ```
*
* But you can also use the convenient router.listen function:
* ```ts
* const server = router.listen()
* ```
*/
export declare class Router {
routes: EndpointRoute[];
mergeHandlers: boolean;
/**
* Parses the cookie header of the request and sets the cookies property of the request.
* @param req The request to parse the cookies for
*/
static parseCookies(req: Request$1, forceReload?: boolean): void;
/**
* Stores the cookies in the request object into the response.
*
* If the value of a cookie is changed, it will be set in the response.
* If a cookie is deleted, it will be unset in the response.
* @param req The request that contains the cookies.
* @param res The response that will be modified.
*/
static storeCookies(req: Request$1, res: ResponseBuilder): void;
/**
* @hidden
*
* Creates a string tuple that contains the method, path and name of the middleware
* @param route The route to generate the string for
* @param handler The handler of the route
* @param mergedToTop Whether the handler is merged to the top
* @returns A string with 3 parts: method, path and name
*/
private static getDefinitionString;
/**
* Prints a table of all endpoints defined in this router.
*
* If a server is given as a parameter, a running message with the url of the server is printed too.
* @param server The server to print the url of
* @returns A string representing the table of endpoints
*/
dump(...servers: Server[]): string;
/**
* This function can be used as fetch handler for bun.serve.
* It will route a request to the correct handler based on the request's method and path.
* @param request A bun request object
* @param server A bun server object
* @returns Bun response, void or a promise of response or void
*/
handle: BunRequestHandler;
/**
* @hidden
*
* Handles a request.
* This function creates the ResponseBuilder and modifies the base bun request.
* @param req A request to handle
* @param server A server to handle it on
* @returns Bun response, void or a promise of response or void
*/
innerHandle(request: BunRequest, server: Server): Awaitable<Response>;
/**
* This function will route a request to the correct handler based on the request's method and path.
* Recursively calls middlewares until a handler sets `res.submit` to true or `req.upgraded` to true.
*
* First handles the request synchronously until a async middleware is hit.
* Then its uses the private routeAsync function to handle it in a promise.
*
* If no async middleware is hit the request is handled fully synchronously.
* @param req A modified bun request to handle
* @param res A response builder
* @returns Bun response, void or a promise of response or void
*/
route(req: Request$1, res: ResponseBuilder): Awaitable<void>;
/**
* @hidden
*
* Is a followup of the route function. Is used if the route function hits a async middleware.
* The route function will provide the initialDefIndex when routeAsync is called.
* The initialDefIndex is the index of the first found async middleware in the route function.
*
* If route dont hits a async middleware, routeAsync dont get called
* @param initialDefIndex The index of the first found async middleware in the route function
* @param promise The promise returned by the first async middleware found by the route function
* @param req A modified bun request to handle
* @param res A response builder
* @returns Bun response, void or a promise of response or void
*/
private routeAsync;
/**
* Register a handler to run for all incoming requests.
* @param method The HTTP method to run the handler on (undefined = all)
* @param path The path to run the handler on (undefined = all)
* @param handlers The handler(s) to run
* @returns The router
*/
use(method: "*" | HttpMethodString, path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Registers a route for the `GET` HTTP method.
* @param path The route path.
* @param handler The handler function for the route.
* @param handlers Additional middleware functions to apply to the route.
* @returns The router instance.
*/
get(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Register a handler to run on incoming POST requests.
* @param path The path to run the handler on
* @param handler The handler(s) to run
* @returns The router
*/
post(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Register a PUT route.
* @param path The path to match.
* @param handler The handler for the route.
* @param handlers Additional handlers to run before the main handler.
* @returns The Router instance.
*/
put(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Register a middleware function to handle DELETE requests to `path`.
* @param path The path to register the handler for.
* @param handler The middleware function to call.
* @param handlers Additional middleware functions to call.
* @returns this
*/
delete(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Register a middleware function to handle PATCH requests to `path`.
* @param path The path to register the handler for.
* @param handler The middleware function to call.
* @param handlers Additional middleware functions to call.
* @returns this
*/
patch(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Add a route for the HTTP TRACE method.
* The TRACE method is used to invoke a remote, application-layer loop-back
* of the request message.
* @param path The path this route will match.
* @param handler The handler to invoke when this route is matched.
* @param handlers Additional handlers to run when this route is matched.
* @returns This router, for chaining.
*/
trace(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Registers a route for the `HEAD` HTTP method.
* @param path The route path.
* @param handler The handler function for the route.
* @param handlers Additional middleware functions to apply to the route.
* @returns The router instance.
*/
head(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Register a handler to run for CONNECT requests on the given path.
* @param path The path to run the handler on
* @param handler The handler to run
*/
connect(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Register a handler to run on OPTIONS requests.
* @param path The path to run the handler on (undefined = all)
* @param handler The handler(s) to run
* @returns The router
*/
options(path: string, handler: RequestMiddleware, ...handlers: RequestMiddleware[]): Router;
/**
* Upgrade a request to a websocket connection.
* @param path The path to use for the websocket connection.
* @returns The router, for chaining.
*/
ws(path: string): Router;
redirect(method: "*" | HttpMethodString, path: string, redirectTarget: string, perma?: boolean): Router;
static(path: string, targetDir: string, indexFile?: string, deepestLevel?: number): Router;
basicAuth(method: "*" | HttpMethodString, path: string, validator: ((username: string, password: string) => boolean), realm?: string, charset?: string): Router;
cookies(method: "*" | HttpMethodString, path: string, autoResponseHeaders?: boolean): Router;
}
/**
* Trims leading and trailing whitespace characters from a string.
* @param {string} value - The input string to be trimmed.
* @return {string} The trimmed string.
*/
export declare function trimSpaces(value: string): string;
/**
* Splits a path into its components.
* @param path The path to split.
* @returns An array of strings representing the path components.
* undefined if the path is empty.
*/
export declare function splitPath(path: string | undefined): SplitPath;
export declare function splitRoutePath(path: string | undefined): SplitPath;
/**
* Checks if a requested splitpath matches the routes splitpath.
* Also resolves single (*) and double (**) wildcards.
* `true` or wildcarded path parts are returned if found and match.
* `false` is returned if not.
* @param requestPath the path to check
* @param routeSelector the route selector to check against
*/
export declare function requestPathMatchesRouteDefinition(requestPath: SplitPath, routeSelector: SplitPath): string[] | boolean;
export type Awaitable<T> = T | Promise<T>;
type Request$1 = BunRequest & {
/**
* `req.pathParams` is the path parameters of the request.
* If a wildcard is used in the endpoint route,
* then it is available in a `Router` handled request.
*/
pathParams?: string[];
/**
* `req.httpMethod` is the HttpMethod enum value of the reuqest method used for routing.
* It is always available in a `Router` handled request.
*/
httpMethod: HttpMethod;
/**
* `req.path` is the path of the request.
* It is always available in a `Router` handled request.
*/
path: string;
/**
* `req.splitPath` is the splitted path of the request used for routing.
* It is always available in a `Router` handled request.
*/
splitPath: SplitPath;
/**
* `req.server` is the server that is handling the request.
* It is always available in a `Router` handled request.
*/
server: Server;
/**
* `req.sock` is the socket address of the request.
* It is always available in a `Router` handled request.
*/
sock: SocketAddress;
/**
* `req.originCookies` is not to use in your code.
* It holds the origin cookies state of the request.
*/
originCookies: unknown;
/**
* `req.cookies` is a key value map of all the cookies in the request if parsed earlier.
* Gets loaded via the `Router.storeCookies(req, res)` function.
*/
cookies: {
[key: string]: string | undefined;
};
/**
* `req.rid` is set to true if the request has been upgraded to a websocket.
*/
upgraded?: true;
};
export type BunRequestHandler = (request: Request$1, server: Server) => Awaitable<Response>;
export type RequestMiddleware = (req: Request$1, res: ResponseBuilder) => Awaitable<void>;
export type MergedRequestMiddleware = RequestMiddleware & {
base: RequestMiddleware[];
};
export interface EndpointRoute {
handler: RequestMiddleware;
method: HttpMethod;
splitPath: SplitPath;
}
export interface CookieOptions {
MaxAge?: number;
Path?: string;
HttpOnly?: boolean;
Secure?: boolean;
SameSite?: "Strict" | "Lax" | "None";
}
/**
* Unmerge multiple request middlewares into individual ones.
* @param middlewares The middlewares to unmerge.
* @returns An array of individual request middlewares.
*/
export declare function unmergeRequestMiddleware(...middlewares: RequestMiddleware[]): RequestMiddleware[];
/**
* Merge multiple request middlewares into a single one.
* @param middlewares The middlewares to merge.
* @returns A single middleware that calls all the given middlewares in order.
* If any of the middlewares returns a promise, its handles the rest middlewars async.
*/
export declare function mergeRequestMiddlewares(...middlewares: RequestMiddleware[]): MergedRequestMiddleware | RequestMiddleware;
/**
* Checks if the given middleware is a merged middleware.
* Merged middlewares are created by {@link mergeRequestMiddlewares}.
* They contain an array of middlewares in the `base` property.
* This function checks if the `base` property is an array and
* returns true if it is, false otherwise.
* @param middleware The middleware to check.
* @returns True if the middleware is a merged middleware, false otherwise.
*/
export declare function isMergedRequestMiddleware(middleware: RequestMiddleware): middleware is MergedRequestMiddleware;
/**
* Checks if two endpoint routes are mergeable.
* The routes are mergeable if they have the same method and path.
* The path is considered the same if the splitPath property is undefined for both routes or
* if the splitPath property is defined for both routes and the joined string is the same.
* @param route - The first route to check.
* @param route2 - The second route to check.
* @returns true if the routes are mergeable, false otherwise.
*/
export declare function isMergeableEndpointRoute(route: EndpointRoute, route2: EndpointRoute): boolean;
export {
Request$1 as Request,
};
export {};