diff --git a/README.md b/README.md index eba8724..c2390ad 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,11 @@ The middleware is processed as a stack, where each middleware function can control the flow of the response. When the middleware is called, it is passed a context and reference to the "next" method in the stack. +Middleware can also be an object as long as it has a `handleRequest` method. +Middleware objects can optionally have an `init` function which will be called +when the application starts listening. This makes middleware objects ideal for +encapsulation or delayed initialization. + A more complex example: ```ts @@ -197,6 +202,25 @@ app.use(async (ctx, next) => { ctx.response.headers.set("X-Response-Time", `${ms}ms`); }); +// Counter +class CountingMiddleware implements MiddlewareObject { + #id = 0; + #counter = 0; + + init() { + const array = new Uint32Array(1); + crypto.getRandomValues(array); + this.#id = array[0]; + } + + handleRequest(ctx: Context, next: Next) { + ctx.response.headers.set("X-Response-Count", String(this.#counter++)); + ctx.response.headers.set("X-Response-Counter-ID", String(this.#id)); + return next(); + } +} +app.use(new CountingMiddleware()); + // Hello World! app.use((ctx) => { ctx.response.body = "Hello World!"; @@ -758,6 +782,9 @@ await app.listen({ port: 80 }); The `Router` class produces middleware which can be used with an `Application` to enable routing based on the pathname of the request. +Like regular `Middleware`, router middleware can be an object as long as the +`handleRequest` method is implemented. + ### Basic usage The following example serves up a _RESTful_ service of a map of books, where diff --git a/examples/routingServer.ts b/examples/routingServer.ts index afac56a..66b9db0 100644 --- a/examples/routingServer.ts +++ b/examples/routingServer.ts @@ -34,6 +34,32 @@ function notFound(context: Context) { `

404 - Not Found

Path ${context.request.url} not found.`; } +class OrdersObject { + #orders = new Set(); + + handleRequest(context: RouterContext<"/orders">) { + if (context.params["order"]) { + if (this.#orders.has(context.params["order"])) { + context.response.body = `${ + context.params["order"] + } is already ordered.`; + } else { + this.#orders.add(context.params["order"]); + context.response.body = `Ordered ${context.params["order"]}.`; + } + } else { + const orders = Array.from(this.#orders.values()); + if (orders.length > 0) { + context.response.body = `Orders: ${orders.join(", ")}`; + } else { + context.response.body = "No orders so far."; + } + } + } +} + +const orders = new OrdersObject(); + const router = new Router(); router .get("/", (context) => { @@ -78,7 +104,9 @@ router } else { return notFound(context); } - }); + }) + .get("/orders", orders) + .get("/orders/:order", orders); const app = new Application(); diff --git a/mod.ts b/mod.ts index 4c22e07..6089521 100644 --- a/mod.ts +++ b/mod.ts @@ -123,15 +123,17 @@ export { } from "./middleware.ts"; export { Request } from "./request.ts"; export { REDIRECT_BACK, Response } from "./response.ts"; -export { - type Route, - type RouteParams, - Router, - type RouterAllowedMethodsOptions, - type RouterContext, - type RouterMiddleware, - type RouterOptions, - type RouterParamMiddleware, +export { Router } from "./router.ts"; +export type { + Route, + RouteParams, + RouterAllowedMethodsOptions, + RouterContext, + RouterMiddleware, + RouterMiddlewareObject, + RouterMiddlewareOrMiddlewareObject, + RouterOptions, + RouterParamMiddleware, } from "./router.ts"; export { send, type SendOptions } from "./send.ts"; /** Utilities for making testing oak servers easier. */ diff --git a/router.ts b/router.ts index db338fd..c79e3da 100644 --- a/router.ts +++ b/router.ts @@ -66,7 +66,7 @@ import { Status, type TokensToRegexpOptions, } from "./deps.ts"; -import { compose, type Middleware } from "./middleware.ts"; +import { compose, type Middleware, type Next } from "./middleware.ts"; import { decodeComponent } from "./utils/decode_component.ts"; interface Matches { @@ -105,7 +105,7 @@ export interface Route< methods: HTTPMethods[]; /** The middleware that will be applied to this route. */ - middleware: RouterMiddleware[]; + middleware: RouterMiddlewareOrMiddlewareObject[]; /** An optional name for the route. */ name?: string; @@ -161,7 +161,7 @@ export interface RouterMiddleware< // deno-lint-ignore no-explicit-any S extends State = Record, > { - (context: RouterContext, next: () => Promise): + (context: RouterContext, next: Next): | Promise | unknown; /** For route parameter middleware, the `param` key for this parameter will @@ -171,6 +171,29 @@ export interface RouterMiddleware< router?: Router; } +export interface RouterMiddlewareObject< + R extends string, + P extends RouteParams = RouteParams, + // deno-lint-ignore no-explicit-any + S extends State = Record, +> { + init?: () => Promise | unknown; + handleRequest( + context: RouterContext, + next: Next, + ): Promise | unknown; + param?: keyof P; + // deno-lint-ignore no-explicit-any + router?: Router; +} + +export type RouterMiddlewareOrMiddlewareObject< + R extends string, + P extends RouteParams = RouteParams, + // deno-lint-ignore no-explicit-any + S extends State = Record, +> = RouterMiddleware | RouterMiddlewareObject; + /** Options which can be specified when creating a new instance of a * {@linkcode Router}. */ export interface RouterOptions { @@ -303,12 +326,14 @@ export class Layer< methods: HTTPMethods[]; name?: string; path: string; - stack: RouterMiddleware[]; + stack: RouterMiddlewareOrMiddlewareObject[]; constructor( path: string, methods: HTTPMethods[], - middleware: RouterMiddleware | RouterMiddleware[], + middleware: + | RouterMiddlewareOrMiddlewareObject + | RouterMiddlewareOrMiddlewareObject[], { name, ...opts }: LayerOptions = {}, ) { this.#opts = opts; @@ -378,7 +403,7 @@ export class Layer< ): Promise | unknown { const p = ctx.params[param]; assert(p); - return fn.call(this, p, ctx, next); + return fn.call(this, p!, ctx, next); }; middleware.param = param; @@ -525,7 +550,7 @@ export class Router< #register( path: string | string[], - middlewares: RouterMiddleware[], + middlewares: RouterMiddlewareOrMiddlewareObject[], methods: HTTPMethods[], options: RegisterOptions = {}, ): void { @@ -536,7 +561,7 @@ export class Router< return; } - let layerMiddlewares: RouterMiddleware[] = []; + let layerMiddlewares: RouterMiddlewareOrMiddlewareObject[] = []; for (const middleware of middlewares) { if (!middleware.router) { layerMiddlewares.push(middleware); @@ -572,7 +597,7 @@ export class Router< #addLayer( path: string, - middlewares: RouterMiddleware[], + middlewares: RouterMiddlewareOrMiddlewareObject[], methods: HTTPMethods[], options: LayerOptions = {}, ) { @@ -612,8 +637,8 @@ export class Router< #useVerb( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - middleware: RouterMiddleware[], + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + middleware: RouterMiddlewareOrMiddlewareObject[], methods: HTTPMethods[], ): void { let name: string | undefined = undefined; @@ -660,8 +685,8 @@ export class Router< methods: HTTPMethods[] | HTTPMethods, name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the specified methods is * requested. */ @@ -672,8 +697,8 @@ export class Router< >( methods: HTTPMethods[] | HTTPMethods, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the specified methods * are requested with explicit path parameters. */ @@ -683,8 +708,8 @@ export class Router< >( methods: HTTPMethods[] | HTTPMethods, nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; add< P extends RouteParams = RouteParams, @@ -692,13 +717,13 @@ export class Router< >( methods: HTTPMethods[] | HTTPMethods, nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], typeof methods === "string" ? [methods] : methods, ); return this; @@ -713,8 +738,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `DELETE`, * `GET`, `POST`, or `PUT` method is requested. */ @@ -724,8 +749,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `DELETE`, * `GET`, `POST`, or `PUT` method is requested with explicit path parameters. @@ -735,21 +760,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; all< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], this.#methods.filter((method) => method !== "OPTIONS"), ); return this; @@ -782,7 +807,7 @@ export class Router< if (!ctx.response.status || ctx.response.status === Status.NotFound) { assert(ctx.matched); const allowed = new Set(); - for (const route of ctx.matched) { + for (const route of ctx.matched!) { for (const method of route.methods) { allowed.add(method); } @@ -828,8 +853,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `DELETE`, * method is requested. */ @@ -839,8 +864,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `DELETE`, * method is requested with explicit path parameters. */ @@ -849,21 +874,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; delete< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["DELETE"], ); return this; @@ -905,8 +930,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `GET`, * method is requested. */ @@ -916,8 +941,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `GET`, * method is requested with explicit path parameters. */ @@ -926,21 +951,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; get< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["GET"], ); return this; @@ -955,8 +980,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `HEAD`, * method is requested. */ @@ -966,8 +991,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `HEAD`, * method is requested with explicit path parameters. */ @@ -976,21 +1001,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; head< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["HEAD"], ); return this; @@ -1013,8 +1038,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `OPTIONS`, * method is requested. */ @@ -1024,8 +1049,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `OPTIONS`, * method is requested with explicit path parameters. */ @@ -1034,21 +1059,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; options< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["OPTIONS"], ); return this; @@ -1076,8 +1101,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `PATCH`, * method is requested. */ @@ -1087,8 +1112,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `PATCH`, * method is requested with explicit path parameters. */ @@ -1097,21 +1122,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; patch< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["PATCH"], ); return this; @@ -1126,8 +1151,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `POST`, * method is requested. */ @@ -1137,8 +1162,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `POST`, * method is requested with explicit path parameters. */ @@ -1147,21 +1172,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; post< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["POST"], ); return this; @@ -1186,8 +1211,8 @@ export class Router< >( name: string, path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `PUT` * method is requested. */ @@ -1197,8 +1222,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware for the specified routes when the `PUT` * method is requested with explicit path parameters. */ @@ -1207,21 +1232,21 @@ export class Router< S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router; put< P extends RouteParams = RouteParams, S extends State = RS, >( nameOrPath: string, - pathOrMiddleware: string | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: string | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { this.#useVerb( nameOrPath, - pathOrMiddleware as (string | RouterMiddleware), - middleware as RouterMiddleware[], + pathOrMiddleware as (string | RouterMiddlewareOrMiddlewareObject), + middleware as RouterMiddlewareOrMiddlewareObject[], ["PUT"], ); return this; @@ -1328,7 +1353,7 @@ export class Router< }, ...route.stack, ], - [] as RouterMiddleware[], + [] as RouterMiddlewareOrMiddlewareObject[], ); return compose(chain)(ctx, next); }; @@ -1355,8 +1380,8 @@ export class Router< P extends RouteParams = RouteParams, S extends State = RS, >( - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware to be used on every route that matches the supplied * `path`. */ @@ -1366,8 +1391,8 @@ export class Router< S extends State = RS, >( path: R, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; /** Register middleware to be used on every route that matches the supplied * `path` with explicit path parameters. */ @@ -1376,23 +1401,26 @@ export class Router< S extends State = RS, >( path: string, - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; use< P extends RouteParams = RouteParams, S extends State = RS, >( path: string[], - middleware: RouterMiddleware, - ...middlewares: RouterMiddleware[] + middleware: RouterMiddlewareOrMiddlewareObject, + ...middlewares: RouterMiddlewareOrMiddlewareObject[] ): Router; use< P extends RouteParams = RouteParams, S extends State = RS, >( - pathOrMiddleware: string | string[] | RouterMiddleware, - ...middleware: RouterMiddleware[] + pathOrMiddleware: + | string + | string[] + | RouterMiddlewareOrMiddlewareObject, + ...middleware: RouterMiddlewareOrMiddlewareObject[] ): Router { let path: string | string[] | undefined; if ( @@ -1405,7 +1433,7 @@ export class Router< this.#register( path ?? "(.*)", - middleware as RouterMiddleware[], + middleware as RouterMiddlewareOrMiddlewareObject[], [], { end: false, ignoreCaptures: !path, ignorePrefix: !path }, );