/** * Type definitions for @koa/router */ import type { ParameterizedContext, DefaultContext, DefaultState, Middleware } from 'koa'; import type { RouterInstance as Router } from './router'; import type Layer from './layer'; /** * Re-export Koa types for convenience * This makes types.ts the single source of truth for all type imports */ export type { Middleware, ParameterizedContext, DefaultContext, DefaultState } from 'koa'; export type RouterOptions = { /** * Only run last matched route's controller when there are multiple matches */ exclusive?: boolean; /** * Prefix for all routes */ prefix?: string; /** * Host for router match (string, array of strings, or RegExp) * - string: exact match * - string[]: matches if input equals any string in the array * - RegExp: pattern match */ host?: string | string[] | RegExp; /** * HTTP methods this router should respond to */ methods?: string[]; /** * Path to use for routing (internal) */ routerPath?: string; /** * Whether to use case-sensitive routing */ sensitive?: boolean; /** * Whether trailing slashes are significant */ strict?: boolean; /** * Additional options passed through */ [key: string]: unknown; }; export type LayerOptions = { /** * Route name for URL generation */ name?: string | null; /** * Case sensitive routing */ sensitive?: boolean; /** * Require trailing slash */ strict?: boolean; /** * Whether trailing slashes matter (path-to-regexp v8) */ trailing?: boolean; /** * Route path ends at this path */ end?: boolean; /** * Prefix for the route */ prefix?: string; /** * Ignore captures in route matching */ ignoreCaptures?: boolean; /** * Treat path as a regular expression */ pathAsRegExp?: boolean; /** * Additional options passed through to path-to-regexp */ [key: string]: unknown; }; export type UrlOptions = { /** * Query string parameters */ query?: Record | string; [key: string]: unknown; }; export type RouterParameterContext< StateT = DefaultState, ContextT = DefaultContext > = { /** * URL parameters */ params: Record; /** * Router instance */ router: Router; /** * Matched route path (internal) */ _matchedRoute?: string | RegExp; /** * Matched route name (internal) */ _matchedRouteName?: string; }; export type RouterParameterMiddleware< StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown > = ( parameterValue: string, context: RouterContext, next: () => Promise ) => unknown | Promise; export type MatchResult< StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown > = { /** * Layers that matched the path */ path: Layer[]; /** * Layers that matched both path and HTTP method */ pathAndMethod: Layer[]; /** * Whether a route (not just middleware) was matched */ route: boolean; }; export type AllowedMethodsOptions = { /** * Throw error instead of setting status and header */ throw?: boolean; /** * Throw the returned value in place of the default NotImplemented error */ notImplemented?: () => Error; /** * Throw the returned value in place of the default MethodNotAllowed error */ methodNotAllowed?: () => Error; }; /** * Extended Koa context with router-specific properties * Matches the structure from @types/koa-router */ export type RouterContext< StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown > = ParameterizedContext< StateT, ContextT & RouterParameterContext, BodyT > & { /** * Request with params (set by router during routing) */ request: { params: Record; }; /** * Path of matched route */ routerPath?: string; /** * Name of matched route */ routerName?: string; /** * Array of matched layers */ matched?: Layer[]; /** * Whether a route (with HTTP methods) was matched for this request. * Set by the router before any handlers run. * * Use this in app-level middleware after `router.routes()` to detect * requests that the router did not handle. * * @example * ```javascript * app.use(router.routes()); * app.use((ctx) => { * if (!ctx.routeMatched) { * ctx.status = 404; * ctx.body = { error: 'Not Found' }; * } * }); * ``` */ routeMatched?: boolean; /** * Captured values from path */ captures?: string[]; /** * New router path (for nested routers) */ newRouterPath?: string; /** * Track param middleware execution (internal) */ _matchedParams?: WeakMap; }; /** * Router middleware function type */ export type RouterMiddleware< StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown > = Middleware, BodyT>; /** * HTTP method names in lowercase */ export type HttpMethod = | 'get' | 'post' | 'put' | 'patch' | 'delete' | 'del' | 'head' | 'options' | 'connect' | 'trace' | string; /** * Router options with generic methods array for type inference */ export type RouterOptionsWithMethods = Omit< RouterOptions, 'methods' > & { methods?: readonly M[]; }; /** * Type for a dynamic HTTP method function on Router */ export type RouterMethodFunction< StateT = DefaultState, ContextT = DefaultContext > = { ( name: string, path: string | RegExp, ...middleware: Array> ): Router; ( path: string | RegExp | Array, ...middleware: Array> ): Router; }; /** * Router with additional HTTP methods based on the methods option. * Use createRouter() factory function for automatic type inference. */ export type RouterWithMethods< M extends string, StateT = DefaultState, ContextT = DefaultContext > = Router & Record, RouterMethodFunction>; export type { RouterEvent, RouterEventSelector } from './utils/router-events'; export { type default as Layer } from './layer';