@koa/router 15.0.0 → 15.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,843 @@
1
- export { A as AllowedMethodsOptions, H as HttpMethod, default as Layer, L as LayerOptions, M as MatchResult, R as Router, d as RouterContext, e as RouterMiddleware, a as RouterOptions, c as RouterParameterMiddleware, U as UrlOptions, R as default } from './layer.js';
2
- import 'koa';
3
- import 'path-to-regexp';
1
+ import * as koa from 'koa';
2
+ import { DefaultState, DefaultContext, Middleware, ParameterizedContext } from 'koa';
3
+ import { Key } from 'path-to-regexp';
4
+
5
+ /**
6
+ * Extended middleware with param metadata
7
+ * @internal
8
+ */
9
+ type ParameterMiddleware<StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown> = RouterMiddleware<StateT, ContextT, BodyT> & {
10
+ param?: string;
11
+ _originalFn?: RouterParameterMiddleware<StateT, ContextT, BodyT>;
12
+ };
13
+ /**
14
+ * Layer class represents a single route or middleware layer.
15
+ * It handles path matching, parameter extraction, and middleware execution.
16
+ *
17
+ * @typeParam StateT - Custom state type extending Koa's DefaultState
18
+ * @typeParam ContextT - Custom context type extending Koa's DefaultContext
19
+ * @typeParam BodyT - Response body type
20
+ */
21
+ declare class Layer<StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown> {
22
+ opts: LayerOptions;
23
+ name: string | undefined;
24
+ methods: string[];
25
+ paramNames: Key[];
26
+ stack: Array<RouterMiddleware<StateT, ContextT, BodyT> | ParameterMiddleware<StateT, ContextT, BodyT>>;
27
+ path: string | RegExp;
28
+ regexp: RegExp;
29
+ /**
30
+ * Initialize a new routing Layer with given `method`, `path`, and `middleware`.
31
+ *
32
+ * @param path - Path string or regular expression
33
+ * @param methods - Array of HTTP verbs
34
+ * @param middleware - Layer callback/middleware or series of
35
+ * @param opts - Layer options
36
+ * @private
37
+ */
38
+ constructor(path: string | RegExp, methods: string[], middleware: RouterMiddleware<StateT, ContextT, BodyT> | Array<RouterMiddleware<StateT, ContextT, BodyT>>, options?: LayerOptions);
39
+ /**
40
+ * Normalize HTTP methods and add automatic HEAD support for GET
41
+ * @private
42
+ */
43
+ private _normalizeHttpMethods;
44
+ /**
45
+ * Normalize middleware to array and validate all are functions
46
+ * @private
47
+ */
48
+ private _normalizeAndValidateMiddleware;
49
+ /**
50
+ * Configure path matching regexp and parameters
51
+ * @private
52
+ */
53
+ private _configurePathMatching;
54
+ /**
55
+ * Configure path-to-regexp for string paths
56
+ * @private
57
+ */
58
+ private _configurePathToRegexp;
59
+ /**
60
+ * Returns whether request `path` matches route.
61
+ *
62
+ * @param path - Request path
63
+ * @returns Whether path matches
64
+ * @private
65
+ */
66
+ match(path: string): boolean;
67
+ /**
68
+ * Returns map of URL parameters for given `path` and `paramNames`.
69
+ *
70
+ * @param _path - Request path (not used, kept for API compatibility)
71
+ * @param captures - Captured values from regexp
72
+ * @param existingParams - Existing params to merge with
73
+ * @returns Parameter map
74
+ * @private
75
+ */
76
+ params(_path: string, captures: string[], existingParameters?: Record<string, string>): Record<string, string>;
77
+ /**
78
+ * Returns array of regexp url path captures.
79
+ *
80
+ * @param path - Request path
81
+ * @returns Array of captured values
82
+ * @private
83
+ */
84
+ captures(path: string): string[];
85
+ /**
86
+ * Generate URL for route using given `params`.
87
+ *
88
+ * @example
89
+ *
90
+ * ```javascript
91
+ * const route = new Layer('/users/:id', ['GET'], fn);
92
+ *
93
+ * route.url({ id: 123 }); // => "/users/123"
94
+ * ```
95
+ *
96
+ * @param args - URL parameters (various formats supported)
97
+ * @returns Generated URL
98
+ * @throws Error if route path is a RegExp (cannot generate URL from RegExp)
99
+ * @private
100
+ */
101
+ url(...arguments_: unknown[]): string;
102
+ /**
103
+ * Parse url() arguments into params and options
104
+ * Supports multiple call signatures:
105
+ * - url({ id: 1 })
106
+ * - url(1, 2, 3)
107
+ * - url({ query: {...} })
108
+ * - url({ id: 1 }, { query: {...} })
109
+ * @private
110
+ */
111
+ private _parseUrlArguments;
112
+ /**
113
+ * Build parameter replacements for URL generation
114
+ * @private
115
+ */
116
+ private _buildParamReplacements;
117
+ /**
118
+ * Add query string to URL
119
+ * @private
120
+ */
121
+ private _addQueryString;
122
+ /**
123
+ * Run validations on route named parameters.
124
+ *
125
+ * @example
126
+ *
127
+ * ```javascript
128
+ * router
129
+ * .param('user', function (id, ctx, next) {
130
+ * ctx.user = users[id];
131
+ * if (!ctx.user) return ctx.status = 404;
132
+ * next();
133
+ * })
134
+ * .get('/users/:user', function (ctx, next) {
135
+ * ctx.body = ctx.user;
136
+ * });
137
+ * ```
138
+ *
139
+ * @param paramName - Parameter name
140
+ * @param paramHandler - Middleware function
141
+ * @returns This layer instance
142
+ * @private
143
+ */
144
+ param(parameterName: string, parameterHandler: RouterParameterMiddleware<StateT, ContextT, BodyT>): Layer<StateT, ContextT, BodyT>;
145
+ /**
146
+ * Create param middleware with deduplication tracking
147
+ * @private
148
+ */
149
+ private _createParamMiddleware;
150
+ /**
151
+ * Insert param middleware at the correct position in the stack
152
+ * @private
153
+ */
154
+ private _insertParamMiddleware;
155
+ /**
156
+ * Prefix route path.
157
+ *
158
+ * @param prefixPath - Prefix to prepend
159
+ * @returns This layer instance
160
+ * @private
161
+ */
162
+ setPrefix(prefixPath: string): Layer<StateT, ContextT, BodyT>;
163
+ /**
164
+ * Apply prefix to the current path
165
+ * @private
166
+ */
167
+ private _applyPrefix;
168
+ /**
169
+ * Reconfigure path matching after prefix is applied
170
+ * @private
171
+ */
172
+ private _reconfigurePathMatching;
173
+ }
174
+
175
+ /**
176
+ * Middleware with router property
177
+ */
178
+ type RouterComposedMiddleware<StateT = koa.DefaultState, ContextT = koa.DefaultContext> = Middleware<StateT, ContextT & RouterParameterContext<StateT, ContextT>> & {
179
+ router?: Router<StateT, ContextT>;
180
+ };
181
+ /**
182
+ * @module koa-router
183
+ */
184
+ declare class Router<StateT = koa.DefaultState, ContextT = koa.DefaultContext> {
185
+ opts: RouterOptions;
186
+ methods: string[];
187
+ exclusive: boolean;
188
+ params: Record<string, RouterParameterMiddleware<StateT, ContextT> | RouterParameterMiddleware<StateT, ContextT>[]>;
189
+ stack: Layer<StateT, ContextT>[];
190
+ host?: string | string[] | RegExp;
191
+ /**
192
+ * Create a new router.
193
+ *
194
+ * @example
195
+ *
196
+ * Basic usage:
197
+ *
198
+ * ```javascript
199
+ * const Koa = require('koa');
200
+ * const Router = require('@koa/router');
201
+ *
202
+ * const app = new Koa();
203
+ * const router = new Router();
204
+ *
205
+ * router.get('/', (ctx, next) => {
206
+ * // ctx.router available
207
+ * });
208
+ *
209
+ * app
210
+ * .use(router.routes())
211
+ * .use(router.allowedMethods());
212
+ * ```
213
+ *
214
+ * @alias module:koa-router
215
+ * @param opts - Router options
216
+ * @constructor
217
+ */
218
+ constructor(options?: RouterOptions);
219
+ /**
220
+ * Generate URL from url pattern and given `params`.
221
+ *
222
+ * @example
223
+ *
224
+ * ```javascript
225
+ * const url = Router.url('/users/:id', {id: 1});
226
+ * // => "/users/1"
227
+ * ```
228
+ *
229
+ * @param path - URL pattern
230
+ * @param args - URL parameters
231
+ * @returns Generated URL
232
+ */
233
+ static url(path: string | RegExp, ...arguments_: unknown[]): string;
234
+ /**
235
+ * Use given middleware.
236
+ *
237
+ * Middleware run in the order they are defined by `.use()`. They are invoked
238
+ * sequentially, requests start at the first middleware and work their way
239
+ * "down" the middleware stack.
240
+ *
241
+ * @example
242
+ *
243
+ * ```javascript
244
+ * // session middleware will run before authorize
245
+ * router
246
+ * .use(session())
247
+ * .use(authorize());
248
+ *
249
+ * // use middleware only with given path
250
+ * router.use('/users', userAuth());
251
+ *
252
+ * // or with an array of paths
253
+ * router.use(['/users', '/admin'], userAuth());
254
+ *
255
+ * app.use(router.routes());
256
+ * ```
257
+ *
258
+ * @param middleware - Middleware functions
259
+ * @returns This router instance
260
+ */
261
+ use<T = {}, U = {}, B = unknown>(middleware: RouterMiddleware<StateT & T, ContextT & U, B>): Router<StateT, ContextT>;
262
+ use<T = {}, U = {}>(middleware: RouterComposedMiddleware<StateT & T, ContextT & U>): Router<StateT, ContextT>;
263
+ use<T = {}, U = {}, B = unknown>(path: string | RegExp | string[], middleware: RouterMiddleware<StateT & T, ContextT & U, B>): Router<StateT, ContextT>;
264
+ use<T = {}, U = {}>(path: string | RegExp | string[], middleware: RouterComposedMiddleware<StateT & T, ContextT & U>): Router<StateT, ContextT>;
265
+ use<T = {}, U = {}, B = unknown>(path: string | RegExp | string[], m1: RouterMiddleware<StateT & T, ContextT & U, B>, m2: RouterMiddleware<StateT & T, ContextT & U, B> | RouterComposedMiddleware<StateT & T, ContextT & U>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B> | RouterComposedMiddleware<StateT & T, ContextT & U>>): Router<StateT, ContextT>;
266
+ use<T = {}, U = {}, B = unknown>(m1: RouterMiddleware<StateT & T, ContextT & U, B>, m2: RouterMiddleware<StateT & T, ContextT & U, B> | RouterComposedMiddleware<StateT & T, ContextT & U>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B> | RouterComposedMiddleware<StateT & T, ContextT & U>>): Router<StateT, ContextT>;
267
+ /**
268
+ * Check if first argument is an array of paths (all elements must be strings)
269
+ * @private
270
+ */
271
+ private _isPathArray;
272
+ /**
273
+ * Check if first argument is an explicit path (string or RegExp)
274
+ * Empty string counts as explicit path to enable param capture
275
+ * @private
276
+ */
277
+ private _hasExplicitPath;
278
+ /**
279
+ * Check if middleware contains a nested router
280
+ * @private
281
+ */
282
+ private _isNestedRouter;
283
+ /**
284
+ * Apply middleware to multiple paths
285
+ * @private
286
+ */
287
+ private _useWithPathArray;
288
+ /**
289
+ * Mount a nested router
290
+ * @private
291
+ */
292
+ private _mountNestedRouter;
293
+ /**
294
+ * Clone a router instance
295
+ * @private
296
+ */
297
+ private _cloneRouter;
298
+ /**
299
+ * Clone a layer instance (deep clone to avoid shared references)
300
+ * @private
301
+ */
302
+ private _cloneLayer;
303
+ /**
304
+ * Apply this router's param middleware to a nested router
305
+ * @private
306
+ */
307
+ private _applyParamMiddlewareToRouter;
308
+ /**
309
+ * Register regular middleware (not nested router)
310
+ * @private
311
+ */
312
+ private _registerMiddleware;
313
+ /**
314
+ * Set the path prefix for a Router instance that was already initialized.
315
+ * Note: Calling this method multiple times will replace the prefix, not stack them.
316
+ *
317
+ * @example
318
+ *
319
+ * ```javascript
320
+ * router.prefix('/things/:thing_id')
321
+ * ```
322
+ *
323
+ * @param prefixPath - Prefix string
324
+ * @returns This router instance
325
+ */
326
+ prefix(prefixPath: string): Router<StateT, ContextT>;
327
+ /**
328
+ * Returns router middleware which dispatches a route matching the request.
329
+ *
330
+ * @returns Router middleware
331
+ */
332
+ middleware(): RouterComposedMiddleware<StateT, ContextT>;
333
+ /**
334
+ * Get the request path to use for routing
335
+ * @private
336
+ */
337
+ private _getRequestPath;
338
+ /**
339
+ * Store matched routes on context
340
+ * @private
341
+ */
342
+ private _storeMatchedRoutes;
343
+ /**
344
+ * Set matched route information on context
345
+ * @private
346
+ */
347
+ private _setMatchedRouteInfo;
348
+ /**
349
+ * Build middleware chain from matched layers
350
+ * @private
351
+ */
352
+ private _buildMiddlewareChain;
353
+ routes(): RouterComposedMiddleware<StateT, ContextT>;
354
+ /**
355
+ * Returns separate middleware for responding to `OPTIONS` requests with
356
+ * an `Allow` header containing the allowed methods, as well as responding
357
+ * with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
358
+ *
359
+ * @example
360
+ *
361
+ * ```javascript
362
+ * const Koa = require('koa');
363
+ * const Router = require('@koa/router');
364
+ *
365
+ * const app = new Koa();
366
+ * const router = new Router();
367
+ *
368
+ * app.use(router.routes());
369
+ * app.use(router.allowedMethods());
370
+ * ```
371
+ *
372
+ * **Example with [Boom](https://github.com/hapijs/boom)**
373
+ *
374
+ * ```javascript
375
+ * const Koa = require('koa');
376
+ * const Router = require('@koa/router');
377
+ * const Boom = require('boom');
378
+ *
379
+ * const app = new Koa();
380
+ * const router = new Router();
381
+ *
382
+ * app.use(router.routes());
383
+ * app.use(router.allowedMethods({
384
+ * throw: true,
385
+ * notImplemented: () => new Boom.notImplemented(),
386
+ * methodNotAllowed: () => new Boom.methodNotAllowed()
387
+ * }));
388
+ * ```
389
+ *
390
+ * @param options - Options object
391
+ * @returns Middleware function
392
+ */
393
+ allowedMethods(options?: AllowedMethodsOptions): RouterMiddleware<StateT, ContextT>;
394
+ /**
395
+ * Check if we should process allowed methods
396
+ * @private
397
+ */
398
+ private _shouldProcessAllowedMethods;
399
+ /**
400
+ * Collect all allowed methods from matched routes
401
+ * @private
402
+ */
403
+ private _collectAllowedMethods;
404
+ /**
405
+ * Handle 501 Not Implemented response
406
+ * @private
407
+ */
408
+ private _handleNotImplemented;
409
+ /**
410
+ * Handle OPTIONS request
411
+ * @private
412
+ */
413
+ private _handleOptionsRequest;
414
+ /**
415
+ * Handle 405 Method Not Allowed response
416
+ * @private
417
+ */
418
+ private _handleMethodNotAllowed;
419
+ /**
420
+ * Register route with all methods.
421
+ *
422
+ * @param args - Route arguments (name, path, middleware)
423
+ * @returns This router instance
424
+ */
425
+ all<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
426
+ all<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
427
+ /**
428
+ * Redirect `source` to `destination` URL with optional 30x status `code`.
429
+ *
430
+ * Both `source` and `destination` can be route names.
431
+ *
432
+ * ```javascript
433
+ * router.redirect('/login', 'sign-in');
434
+ * ```
435
+ *
436
+ * This is equivalent to:
437
+ *
438
+ * ```javascript
439
+ * router.all('/login', ctx => {
440
+ * ctx.redirect('/sign-in');
441
+ * ctx.status = 301;
442
+ * });
443
+ * ```
444
+ *
445
+ * @param source - URL or route name
446
+ * @param destination - URL or route name
447
+ * @param code - HTTP status code (default: 301)
448
+ * @returns This router instance
449
+ */
450
+ redirect(source: string | symbol, destination: string | symbol, code?: number): Router<StateT, ContextT>;
451
+ /**
452
+ * Create and register a route.
453
+ *
454
+ * @param path - Path string
455
+ * @param methods - Array of HTTP verbs
456
+ * @param middleware - Middleware functions
457
+ * @param additionalOptions - Additional options
458
+ * @returns Created layer
459
+ * @private
460
+ */
461
+ register(path: string | RegExp | string[], methods: string[], middleware: RouterMiddleware<StateT, ContextT> | RouterMiddleware<StateT, ContextT>[], additionalOptions?: LayerOptions): Layer<StateT, ContextT> | Router<StateT, ContextT>;
462
+ /**
463
+ * Register multiple paths with the same configuration
464
+ * @private
465
+ */
466
+ private _registerMultiplePaths;
467
+ /**
468
+ * Create a route layer with given configuration
469
+ * @private
470
+ */
471
+ private _createRouteLayer;
472
+ /**
473
+ * Lookup route with given `name`.
474
+ *
475
+ * @param name - Route name
476
+ * @returns Matched layer or false
477
+ */
478
+ route(name: string): Layer<StateT, ContextT> | false;
479
+ /**
480
+ * Generate URL for route. Takes a route name and map of named `params`.
481
+ *
482
+ * @example
483
+ *
484
+ * ```javascript
485
+ * router.get('user', '/users/:id', (ctx, next) => {
486
+ * // ...
487
+ * });
488
+ *
489
+ * router.url('user', 3);
490
+ * // => "/users/3"
491
+ *
492
+ * router.url('user', { id: 3 });
493
+ * // => "/users/3"
494
+ *
495
+ * router.use((ctx, next) => {
496
+ * // redirect to named route
497
+ * ctx.redirect(ctx.router.url('sign-in'));
498
+ * })
499
+ *
500
+ * router.url('user', { id: 3 }, { query: { limit: 1 } });
501
+ * // => "/users/3?limit=1"
502
+ *
503
+ * router.url('user', { id: 3 }, { query: "limit=1" });
504
+ * // => "/users/3?limit=1"
505
+ * ```
506
+ *
507
+ * @param name - Route name
508
+ * @param args - URL parameters
509
+ * @returns Generated URL or Error
510
+ */
511
+ url(name: string, ...arguments_: unknown[]): string | Error;
512
+ /**
513
+ * Match given `path` and return corresponding routes.
514
+ *
515
+ * @param path - Request path
516
+ * @param method - HTTP method
517
+ * @returns Match result with matched layers
518
+ * @private
519
+ */
520
+ match(path: string, method: string): MatchResult<StateT, ContextT>;
521
+ /**
522
+ * Match given `input` to allowed host
523
+ * @param input - Host to check
524
+ * @returns Whether host matches
525
+ */
526
+ matchHost(input?: string): boolean;
527
+ /**
528
+ * Run middleware for named route parameters. Useful for auto-loading or
529
+ * validation.
530
+ *
531
+ * @example
532
+ *
533
+ * ```javascript
534
+ * router
535
+ * .param('user', (id, ctx, next) => {
536
+ * ctx.user = users[id];
537
+ * if (!ctx.user) return ctx.status = 404;
538
+ * return next();
539
+ * })
540
+ * .get('/users/:user', ctx => {
541
+ * ctx.body = ctx.user;
542
+ * })
543
+ * .get('/users/:user/friends', ctx => {
544
+ * return ctx.user.getFriends().then(function(friends) {
545
+ * ctx.body = friends;
546
+ * });
547
+ * })
548
+ * // /users/3 => {"id": 3, "name": "Alex"}
549
+ * // /users/3/friends => [{"id": 4, "name": "TJ"}]
550
+ * ```
551
+ *
552
+ * @param param - Parameter name
553
+ * @param middleware - Parameter middleware
554
+ * @returns This router instance
555
+ */
556
+ param(parameter: string, middleware: RouterParameterMiddleware<StateT, ContextT>): Router<StateT, ContextT>;
557
+ /**
558
+ * Helper method for registering HTTP verb routes
559
+ * @internal - Used by dynamically added HTTP methods
560
+ */
561
+ _registerMethod(method: string, ...arguments_: unknown[]): Router<StateT, ContextT>;
562
+ /**
563
+ * HTTP GET method
564
+ */
565
+ get<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
566
+ get<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
567
+ /**
568
+ * HTTP POST method
569
+ */
570
+ post<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
571
+ post<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
572
+ /**
573
+ * HTTP PUT method
574
+ */
575
+ put<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
576
+ put<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
577
+ /**
578
+ * HTTP PATCH method
579
+ */
580
+ patch<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
581
+ patch<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
582
+ /**
583
+ * HTTP DELETE method
584
+ */
585
+ delete<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
586
+ delete<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
587
+ /**
588
+ * HTTP DELETE method alias (del)
589
+ */
590
+ del<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
591
+ del<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
592
+ /**
593
+ * HTTP HEAD method
594
+ */
595
+ head<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
596
+ head<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
597
+ /**
598
+ * HTTP OPTIONS method
599
+ */
600
+ options<T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
601
+ options<T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
602
+ /**
603
+ * Dynamic HTTP method handler for any method from http.METHODS.
604
+ * Use this index signature to access methods like PURGE, COPY, CONNECT, TRACE, etc.
605
+ * These are dynamically added at runtime from Node's http.METHODS.
606
+ *
607
+ * @example
608
+ * ```typescript
609
+ * // Type-safe way to use dynamic methods
610
+ * const router = new Router();
611
+ * router.register('/cache/:key', ['PURGE'], middleware);
612
+ *
613
+ * // Or cast to access dynamic method directly
614
+ * (router as any).purge('/cache/:key', middleware);
615
+ * ```
616
+ */
617
+ [method: string]: unknown;
618
+ }
619
+ /**
620
+ * Router constructor interface with automatic type inference for custom HTTP methods.
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * // Methods are automatically typed based on what you pass
625
+ * const router = new Router({
626
+ * methods: ['GET', 'POST', 'PURGE', 'CUSTOM'] as const
627
+ * });
628
+ *
629
+ * // TypeScript knows these methods exist
630
+ * router.get('/users', handler);
631
+ * router.purge('/cache/:key', handler);
632
+ * router.custom('/special', handler);
633
+ * ```
634
+ */
635
+ interface RouterConstructor {
636
+ new <M extends string, StateT = koa.DefaultState, ContextT = koa.DefaultContext>(options: RouterOptionsWithMethods<M>): RouterWithMethods<M, StateT, ContextT>;
637
+ new <StateT = koa.DefaultState, ContextT = koa.DefaultContext>(options?: RouterOptions): Router<StateT, ContextT>;
638
+ /**
639
+ * Generate URL from url pattern and given `params`.
640
+ */
641
+ url(path: string, parameters?: Record<string, unknown>): string;
642
+ url(path: string, ...parameters: unknown[]): string;
643
+ readonly prototype: Router;
644
+ }
645
+ declare const RouterExport: RouterConstructor;
646
+
647
+ /**
648
+ * Type definitions for @koa/router
649
+ */
650
+
651
+ type RouterOptions = {
652
+ /**
653
+ * Only run last matched route's controller when there are multiple matches
654
+ */
655
+ exclusive?: boolean;
656
+ /**
657
+ * Prefix for all routes
658
+ */
659
+ prefix?: string;
660
+ /**
661
+ * Host for router match (string, array of strings, or RegExp)
662
+ * - string: exact match
663
+ * - string[]: matches if input equals any string in the array
664
+ * - RegExp: pattern match
665
+ */
666
+ host?: string | string[] | RegExp;
667
+ /**
668
+ * HTTP methods this router should respond to
669
+ */
670
+ methods?: string[];
671
+ /**
672
+ * Path to use for routing (internal)
673
+ */
674
+ routerPath?: string;
675
+ /**
676
+ * Whether to use case-sensitive routing
677
+ */
678
+ sensitive?: boolean;
679
+ /**
680
+ * Whether trailing slashes are significant
681
+ */
682
+ strict?: boolean;
683
+ /**
684
+ * Additional options passed through
685
+ */
686
+ [key: string]: unknown;
687
+ };
688
+ type LayerOptions = {
689
+ /**
690
+ * Route name for URL generation
691
+ */
692
+ name?: string | null;
693
+ /**
694
+ * Case sensitive routing
695
+ */
696
+ sensitive?: boolean;
697
+ /**
698
+ * Require trailing slash
699
+ */
700
+ strict?: boolean;
701
+ /**
702
+ * Whether trailing slashes matter (path-to-regexp v8)
703
+ */
704
+ trailing?: boolean;
705
+ /**
706
+ * Route path ends at this path
707
+ */
708
+ end?: boolean;
709
+ /**
710
+ * Prefix for the route
711
+ */
712
+ prefix?: string;
713
+ /**
714
+ * Ignore captures in route matching
715
+ */
716
+ ignoreCaptures?: boolean;
717
+ /**
718
+ * Treat path as a regular expression
719
+ */
720
+ pathAsRegExp?: boolean;
721
+ /**
722
+ * Additional options passed through to path-to-regexp
723
+ */
724
+ [key: string]: unknown;
725
+ };
726
+ type UrlOptions = {
727
+ /**
728
+ * Query string parameters
729
+ */
730
+ query?: Record<string, unknown> | string;
731
+ [key: string]: unknown;
732
+ };
733
+ type RouterParameterContext<StateT = DefaultState, ContextT = DefaultContext> = {
734
+ /**
735
+ * URL parameters
736
+ */
737
+ params: Record<string, string>;
738
+ /**
739
+ * Router instance
740
+ */
741
+ router: Router<StateT, ContextT>;
742
+ /**
743
+ * Matched route path (internal)
744
+ */
745
+ _matchedRoute?: string | RegExp;
746
+ /**
747
+ * Matched route name (internal)
748
+ */
749
+ _matchedRouteName?: string;
750
+ };
751
+ type RouterParameterMiddleware<StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown> = (parameterValue: string, context: RouterContext<StateT, ContextT, BodyT>, next: () => Promise<unknown>) => unknown | Promise<unknown>;
752
+ type MatchResult<StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown> = {
753
+ /**
754
+ * Layers that matched the path
755
+ */
756
+ path: Layer<StateT, ContextT, BodyT>[];
757
+ /**
758
+ * Layers that matched both path and HTTP method
759
+ */
760
+ pathAndMethod: Layer<StateT, ContextT, BodyT>[];
761
+ /**
762
+ * Whether a route (not just middleware) was matched
763
+ */
764
+ route: boolean;
765
+ };
766
+ type AllowedMethodsOptions = {
767
+ /**
768
+ * Throw error instead of setting status and header
769
+ */
770
+ throw?: boolean;
771
+ /**
772
+ * Throw the returned value in place of the default NotImplemented error
773
+ */
774
+ notImplemented?: () => Error;
775
+ /**
776
+ * Throw the returned value in place of the default MethodNotAllowed error
777
+ */
778
+ methodNotAllowed?: () => Error;
779
+ };
780
+ /**
781
+ * Extended Koa context with router-specific properties
782
+ * Matches the structure from @types/koa-router
783
+ */
784
+ type RouterContext<StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown> = ParameterizedContext<StateT, ContextT & RouterParameterContext<StateT, ContextT>, BodyT> & {
785
+ /**
786
+ * Request with params (set by router during routing)
787
+ */
788
+ request: {
789
+ params: Record<string, string>;
790
+ };
791
+ /**
792
+ * Path of matched route
793
+ */
794
+ routerPath?: string;
795
+ /**
796
+ * Name of matched route
797
+ */
798
+ routerName?: string;
799
+ /**
800
+ * Array of matched layers
801
+ */
802
+ matched?: Layer<StateT, ContextT, BodyT>[];
803
+ /**
804
+ * Captured values from path
805
+ */
806
+ captures?: string[];
807
+ /**
808
+ * New router path (for nested routers)
809
+ */
810
+ newRouterPath?: string;
811
+ /**
812
+ * Track param middleware execution (internal)
813
+ */
814
+ _matchedParams?: WeakMap<Function, boolean>;
815
+ };
816
+ /**
817
+ * Router middleware function type
818
+ */
819
+ type RouterMiddleware<StateT = DefaultState, ContextT = DefaultContext, BodyT = unknown> = (context: RouterContext<StateT, ContextT, BodyT>, next: () => Promise<unknown>) => unknown | Promise<unknown>;
820
+ /**
821
+ * HTTP method names in lowercase
822
+ */
823
+ type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'del' | 'head' | 'options' | 'connect' | 'trace' | string;
824
+ /**
825
+ * Router options with generic methods array for type inference
826
+ */
827
+ type RouterOptionsWithMethods<M extends string = string> = Omit<RouterOptions, 'methods'> & {
828
+ methods?: readonly M[];
829
+ };
830
+ /**
831
+ * Type for a dynamic HTTP method function on Router
832
+ */
833
+ type RouterMethodFunction<StateT = DefaultState, ContextT = DefaultContext> = {
834
+ <T = {}, U = {}, B = unknown>(name: string, path: string | RegExp, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
835
+ <T = {}, U = {}, B = unknown>(path: string | RegExp | Array<string | RegExp>, ...middleware: Array<RouterMiddleware<StateT & T, ContextT & U, B>>): Router<StateT, ContextT>;
836
+ };
837
+ /**
838
+ * Router with additional HTTP methods based on the methods option.
839
+ * Use createRouter() factory function for automatic type inference.
840
+ */
841
+ type RouterWithMethods<M extends string, StateT = DefaultState, ContextT = DefaultContext> = Router<StateT, ContextT> & Record<Lowercase<M>, RouterMethodFunction<StateT, ContextT>>;
842
+
843
+ export { type AllowedMethodsOptions, type HttpMethod, Layer, type LayerOptions, type MatchResult, RouterExport as Router, type RouterContext, Router as RouterInstance, type RouterMethodFunction, type RouterMiddleware, type RouterOptions, type RouterOptionsWithMethods, type RouterParameterMiddleware, type RouterWithMethods, type UrlOptions, RouterExport as default };