@dcl/http-server 1.0.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.
Files changed (59) hide show
  1. package/README.md +3 -0
  2. package/dist/benchmark.d.ts +1 -0
  3. package/dist/benchmark.js +94 -0
  4. package/dist/benchmark.js.map +1 -0
  5. package/dist/cors.d.ts +35 -0
  6. package/dist/cors.js +138 -0
  7. package/dist/cors.js.map +1 -0
  8. package/dist/helpers.d.ts +1 -0
  9. package/dist/helpers.js +3 -0
  10. package/dist/helpers.js.map +1 -0
  11. package/dist/index.d.ts +8 -0
  12. package/dist/index.js +25 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/injectors.d.ts +5 -0
  15. package/dist/injectors.js +22 -0
  16. package/dist/injectors.js.map +1 -0
  17. package/dist/layer.d.ts +58 -0
  18. package/dist/layer.js +102 -0
  19. package/dist/layer.js.map +1 -0
  20. package/dist/logic.d.ts +12 -0
  21. package/dist/logic.js +288 -0
  22. package/dist/logic.js.map +1 -0
  23. package/dist/methods.d.ts +6 -0
  24. package/dist/methods.js +16 -0
  25. package/dist/methods.js.map +1 -0
  26. package/dist/metrics.d.ts +36 -0
  27. package/dist/metrics.js +107 -0
  28. package/dist/metrics.js.map +1 -0
  29. package/dist/middleware.d.ts +9 -0
  30. package/dist/middleware.js +35 -0
  31. package/dist/middleware.js.map +1 -0
  32. package/dist/router.d.ts +190 -0
  33. package/dist/router.js +516 -0
  34. package/dist/router.js.map +1 -0
  35. package/dist/server-handler.d.ts +1 -0
  36. package/dist/server-handler.js +34 -0
  37. package/dist/server-handler.js.map +1 -0
  38. package/dist/server.d.ts +17 -0
  39. package/dist/server.js +176 -0
  40. package/dist/server.js.map +1 -0
  41. package/dist/status-checks.d.ts +33 -0
  42. package/dist/status-checks.js +154 -0
  43. package/dist/status-checks.js.map +1 -0
  44. package/dist/terminator.d.ts +18 -0
  45. package/dist/terminator.js +128 -0
  46. package/dist/terminator.js.map +1 -0
  47. package/dist/test-component.d.ts +22 -0
  48. package/dist/test-component.js +89 -0
  49. package/dist/test-component.js.map +1 -0
  50. package/dist/test-server.d.ts +21 -0
  51. package/dist/test-server.js +81 -0
  52. package/dist/test-server.js.map +1 -0
  53. package/dist/types.d.ts +32 -0
  54. package/dist/types.js +3 -0
  55. package/dist/types.js.map +1 -0
  56. package/dist/ws.d.ts +8 -0
  57. package/dist/ws.js +32 -0
  58. package/dist/ws.js.map +1 -0
  59. package/package.json +49 -0
@@ -0,0 +1,190 @@
1
+ import { Layer, LayerOptions } from './layer';
2
+ import type { IHttpServerComponent } from '@well-known-components/interfaces';
3
+ /** @public */
4
+ export type RouterOptions = Partial<{
5
+ methods: IHttpServerComponent.HTTPMethod[];
6
+ prefix: string;
7
+ routerPath: string;
8
+ sensitive: boolean;
9
+ strict: boolean;
10
+ }>;
11
+ /** @public */
12
+ export type AllowedMethodOptions = Partial<{
13
+ throw: boolean;
14
+ notImplemented: NewableFunction;
15
+ methodNotAllowed: NewableFunction;
16
+ }>;
17
+ /** @public */
18
+ export type RoutedContext<Context, Path extends string> = IHttpServerComponent.PathAwareContext<Context, Path> & {
19
+ captures: string[];
20
+ matched?: Layer<Context, Path>[];
21
+ routerPath?: string;
22
+ };
23
+ /** @public */
24
+ export type RoutePathSignature<Context extends {}> = <T extends string>(path: T, ...middlewares: Array<IHttpServerComponent.IRequestHandler<RoutedContext<Context, T>>>) => Router<Context>;
25
+ /**
26
+ * Create a new router.
27
+ *
28
+ * @example
29
+ *
30
+ * Basic usage:
31
+ *
32
+ * ```javascript
33
+ * const app = createTestServerComponent();
34
+ * const router = new Router();
35
+ *
36
+ * router.get('/', (ctx, next) => {
37
+ * // ctx.router available
38
+ * });
39
+ *
40
+ * app
41
+ * .use(router.routes())
42
+ * .use(router.allowedMethods());
43
+ * ```
44
+ * @public
45
+ */
46
+ export declare class Router<Context extends {}> implements IHttpServerComponent.MethodHandlers<Context> {
47
+ opts: RouterOptions;
48
+ methods: (IHttpServerComponent.HTTPMethod | string)[];
49
+ stack: Layer<Context, any>[];
50
+ constructor(opts?: RouterOptions);
51
+ connect: RoutePathSignature<Context>;
52
+ delete: RoutePathSignature<Context>;
53
+ get: RoutePathSignature<Context>;
54
+ head: RoutePathSignature<Context>;
55
+ options: RoutePathSignature<Context>;
56
+ patch: RoutePathSignature<Context>;
57
+ post: RoutePathSignature<Context>;
58
+ put: RoutePathSignature<Context>;
59
+ trace: RoutePathSignature<Context>;
60
+ /**
61
+ * Use given middleware.
62
+ *
63
+ * Middleware run in the order they are defined by `.use()`. They are invoked
64
+ * sequentially, requests start at the first middleware and work their way
65
+ * "down" the middleware stack.
66
+ *
67
+ * @example
68
+ *
69
+ * ```javascript
70
+ * // session middleware will run before authorize
71
+ * router
72
+ * .use(session())
73
+ * .use(authorize());
74
+ *
75
+ * // use middleware only with given path
76
+ * router.use('/users', userAuth());
77
+ *
78
+ * // or with an array of paths
79
+ * router.use(['/users', '/admin'], userAuth());
80
+ *
81
+ * app.use(router.routes());
82
+ * ```
83
+ *
84
+ * @param path -
85
+ * @param middleware -
86
+ */
87
+ use(...middlewares: IHttpServerComponent.IRequestHandler<RoutedContext<Context, string>>[]): this;
88
+ use<P extends string>(route: P, ...middlewares: IHttpServerComponent.IRequestHandler<RoutedContext<Context, P>>[]): this;
89
+ /**
90
+ * Set the path prefix for a Router instance that was already initialized.
91
+ *
92
+ * @example
93
+ *
94
+ * ```javascript
95
+ * router.prefix('/things/:thing_id')
96
+ * ```
97
+ *
98
+ * @param prefix -
99
+ */
100
+ prefix(prefix: string): this;
101
+ /**
102
+ * Returns router middleware which dispatches a route matching the request.
103
+ */
104
+ middleware(): IHttpServerComponent.IRequestHandler<Context>;
105
+ /**
106
+ * Returns separate middleware for responding to `OPTIONS` requests with
107
+ * an `Allow` header containing the allowed methods, as well as responding
108
+ * with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
109
+ *
110
+ * @example
111
+ *
112
+ * ```javascript
113
+ * const app = createTestServerComponent();
114
+ * const router = new Router();
115
+ *
116
+ * app.use(router.routes());
117
+ * app.use(router.allowedMethods());
118
+ * ```
119
+ *
120
+ * **Example with [Boom](https://github.com/hapijs/boom)**
121
+ *
122
+ * ```javascript
123
+ * const Boom = require('boom');
124
+ *
125
+ * const app = createTestServerComponent();
126
+ * const router = new Router();
127
+ *
128
+ * app.use(router.routes());
129
+ * app.use(router.allowedMethods({
130
+ * throw: true,
131
+ * notImplemented: () => new Boom.notImplemented(),
132
+ * methodNotAllowed: () => new Boom.methodNotAllowed()
133
+ * }));
134
+ * ```
135
+ *
136
+ * @param options -
137
+ */
138
+ allowedMethods(options?: AllowedMethodOptions): IHttpServerComponent.IRequestHandler<Context>;
139
+ /**
140
+ * Register route with all methods.
141
+ *
142
+ * @param name - Optional.
143
+ * @param path -
144
+ * @param middleware - You may also pass multiple middleware.
145
+ * @param callback -
146
+ */
147
+ all<T extends string>(path: T, middleware: IHttpServerComponent.IRequestHandler<RoutedContext<Context, T>>): this;
148
+ /**
149
+ * Redirect `source` to `destination` URL with optional 30x status `code`.
150
+ *
151
+ * Both `source` and `destination` can be route names.
152
+ *
153
+ * ```javascript
154
+ * router.redirect('/login', 'sign-in');
155
+ * ```
156
+ *
157
+ * This is equivalent to:
158
+ *
159
+ * ```javascript
160
+ * router.all('/login', ctx => {
161
+ * ctx.redirect('/sign-in');
162
+ * ctx.status = 301;
163
+ * });
164
+ * ```
165
+ *
166
+ * @param source - URL or route name.
167
+ * @param destination - URL or route name.
168
+ * @param code - HTTP status code (default: 301).
169
+ */
170
+ redirect(source: string, destination: string, code?: number): this;
171
+ /**
172
+ * Create and register a route.
173
+ *
174
+ * @param path - Path string.
175
+ * @param methods - Array of HTTP verbs.
176
+ * @param middleware - Multiple middleware also accepted.
177
+ */
178
+ register<Path extends string>(path: Path, methods: ReadonlyArray<IHttpServerComponent.HTTPMethod>, middleware: IHttpServerComponent.IRequestHandler<Context>, opts?: LayerOptions): Layer<Context, Path>;
179
+ /**
180
+ * Match given `path` and return corresponding routes.
181
+ *
182
+ * @param path -
183
+ * @param method -
184
+ */
185
+ match(path: string, method: string): {
186
+ path: Layer<Context, string>[];
187
+ pathAndMethod: Layer<Context, string>[];
188
+ route: boolean;
189
+ };
190
+ }
package/dist/router.js ADDED
@@ -0,0 +1,516 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Router = void 0;
7
+ const http_errors_1 = __importDefault(require("http-errors"));
8
+ const layer_1 = require("./layer");
9
+ const path_to_regexp_1 = require("path-to-regexp");
10
+ const middleware_1 = require("./middleware");
11
+ const methods_1 = require("./methods");
12
+ const injectedMiddlewareRouterSymbol = Symbol('injected-router');
13
+ /** @internal */
14
+ function getInjectedRouter(middleware) {
15
+ return middleware[injectedMiddlewareRouterSymbol] || null;
16
+ }
17
+ /** @internal */
18
+ function setInjectedRouter(middleware, router) {
19
+ ;
20
+ middleware[injectedMiddlewareRouterSymbol] = router;
21
+ }
22
+ function createMethodHandler(router, method) {
23
+ return function (path, ...middlewares) {
24
+ router.register(path, [method], (0, middleware_1.compose)(...middlewares), {});
25
+ return router;
26
+ };
27
+ }
28
+ /**
29
+ * Create a new router.
30
+ *
31
+ * @example
32
+ *
33
+ * Basic usage:
34
+ *
35
+ * ```javascript
36
+ * const app = createTestServerComponent();
37
+ * const router = new Router();
38
+ *
39
+ * router.get('/', (ctx, next) => {
40
+ * // ctx.router available
41
+ * });
42
+ *
43
+ * app
44
+ * .use(router.routes())
45
+ * .use(router.allowedMethods());
46
+ * ```
47
+ * @public
48
+ */
49
+ class Router {
50
+ constructor(opts) {
51
+ this.stack = [];
52
+ this.connect = createMethodHandler(this, 'CONNECT');
53
+ this.delete = createMethodHandler(this, 'DELETE');
54
+ this.get = createMethodHandler(this, 'GET');
55
+ this.head = createMethodHandler(this, 'HEAD');
56
+ this.options = createMethodHandler(this, 'OPTIONS');
57
+ this.patch = createMethodHandler(this, 'PATCH');
58
+ this.post = createMethodHandler(this, 'POST');
59
+ this.put = createMethodHandler(this, 'PUT');
60
+ this.trace = createMethodHandler(this, 'TRACE');
61
+ this.opts = opts || {};
62
+ this.methods = this.opts?.methods?.map(($) => $.toUpperCase()) || [
63
+ 'HEAD',
64
+ 'OPTIONS',
65
+ 'GET',
66
+ 'PUT',
67
+ 'PATCH',
68
+ 'POST',
69
+ 'DELETE'
70
+ ];
71
+ }
72
+ use() {
73
+ const middleware = Array.prototype.slice.call(arguments);
74
+ let path;
75
+ let router = this;
76
+ const hasPath = typeof middleware[0] === 'string';
77
+ if (hasPath)
78
+ path = middleware.shift();
79
+ for (let i = 0; i < middleware.length; i++) {
80
+ const m = middleware[i];
81
+ const injectedRouter = getInjectedRouter(m);
82
+ if (injectedRouter) {
83
+ const cloneRouter = Object.assign(Object.create(Router.prototype), injectedRouter, {
84
+ stack: injectedRouter.stack.slice(0)
85
+ });
86
+ for (let j = 0; j < cloneRouter.stack.length; j++) {
87
+ const nestedLayer = cloneRouter.stack[j];
88
+ const cloneLayer = Object.assign(Object.create(layer_1.Layer.prototype), nestedLayer);
89
+ if (path)
90
+ cloneLayer.setPrefix(path);
91
+ if (router.opts.prefix)
92
+ cloneLayer.setPrefix(router.opts.prefix);
93
+ router.stack.push(cloneLayer);
94
+ cloneRouter.stack[j] = cloneLayer;
95
+ }
96
+ }
97
+ else {
98
+ const keys = [];
99
+ (0, path_to_regexp_1.pathToRegexp)(router.opts.prefix || '', keys);
100
+ const routerPrefixHasParam = router.opts.prefix && keys.length;
101
+ router.register(path || '([^/]*)', [], m, { end: false, ignoreCaptures: !hasPath && !routerPrefixHasParam });
102
+ }
103
+ }
104
+ return this;
105
+ }
106
+ /**
107
+ * Set the path prefix for a Router instance that was already initialized.
108
+ *
109
+ * @example
110
+ *
111
+ * ```javascript
112
+ * router.prefix('/things/:thing_id')
113
+ * ```
114
+ *
115
+ * @param prefix -
116
+ */
117
+ prefix(prefix) {
118
+ prefix = prefix.replace(/\/$/, '');
119
+ this.opts.prefix = prefix;
120
+ for (let i = 0; i < this.stack.length; i++) {
121
+ const route = this.stack[i];
122
+ route.setPrefix(prefix);
123
+ }
124
+ return this;
125
+ }
126
+ /**
127
+ * Returns router middleware which dispatches a route matching the request.
128
+ */
129
+ middleware() {
130
+ const router = this;
131
+ const routerMiddleware = function routerMiddleware(ctx, next) {
132
+ const path = router.opts.routerPath || ctx.routerPath || ctx.url.pathname;
133
+ const matched = router.match(path, ctx.request.method);
134
+ let layerChain;
135
+ if (ctx.matched) {
136
+ ctx.matched.push.apply(ctx.matched, matched.path);
137
+ }
138
+ else {
139
+ ctx.matched = matched.path;
140
+ }
141
+ ctx.router = router;
142
+ if (!matched.route)
143
+ return next();
144
+ const matchedLayers = matched.pathAndMethod;
145
+ const mostSpecificLayer = matchedLayers[matchedLayers.length - 1];
146
+ ctx._matchedRoute = mostSpecificLayer.path;
147
+ if (mostSpecificLayer.name) {
148
+ ctx._matchedRouteName = mostSpecificLayer.name;
149
+ }
150
+ layerChain = matchedLayers.reduce(function (memo, layer) {
151
+ memo.push(async function (ctx, next) {
152
+ ctx.captures = layer.captures(path);
153
+ ctx.params = ctx.params = layer.params(ctx.captures, ctx.params);
154
+ ctx.routerPath = layer.path;
155
+ // ctx.routerName = layer.name || undefined
156
+ ctx._matchedRoute = layer.path;
157
+ if (layer.name) {
158
+ ctx._matchedRouteName = layer.name;
159
+ }
160
+ return await next();
161
+ });
162
+ return memo.concat(layer.stack);
163
+ }, []);
164
+ return (0, middleware_1.compose)(...layerChain)(ctx, next);
165
+ };
166
+ setInjectedRouter(routerMiddleware, this);
167
+ return routerMiddleware;
168
+ }
169
+ /**
170
+ * Returns separate middleware for responding to `OPTIONS` requests with
171
+ * an `Allow` header containing the allowed methods, as well as responding
172
+ * with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
173
+ *
174
+ * @example
175
+ *
176
+ * ```javascript
177
+ * const app = createTestServerComponent();
178
+ * const router = new Router();
179
+ *
180
+ * app.use(router.routes());
181
+ * app.use(router.allowedMethods());
182
+ * ```
183
+ *
184
+ * **Example with [Boom](https://github.com/hapijs/boom)**
185
+ *
186
+ * ```javascript
187
+ * const Boom = require('boom');
188
+ *
189
+ * const app = createTestServerComponent();
190
+ * const router = new Router();
191
+ *
192
+ * app.use(router.routes());
193
+ * app.use(router.allowedMethods({
194
+ * throw: true,
195
+ * notImplemented: () => new Boom.notImplemented(),
196
+ * methodNotAllowed: () => new Boom.methodNotAllowed()
197
+ * }));
198
+ * ```
199
+ *
200
+ * @param options -
201
+ */
202
+ allowedMethods(options = {}) {
203
+ options = options || {};
204
+ const implemented = this.methods;
205
+ const routerMiddleware = async function routerMiddleware(ctx, next) {
206
+ const response = await next();
207
+ const allowed = {};
208
+ if (!response.status || response.status === 404) {
209
+ if ('matched' in ctx && ctx.matched) {
210
+ for (let i = 0; i < ctx.matched.length; i++) {
211
+ const route = ctx.matched[i];
212
+ for (let j = 0; j < route.methods.length; j++) {
213
+ const method = route.methods[j];
214
+ allowed[method] = method;
215
+ }
216
+ }
217
+ }
218
+ const allowedArr = Object.keys(allowed);
219
+ const currentMethod = ctx.request.method.toUpperCase();
220
+ if (!~implemented.indexOf(currentMethod)) {
221
+ if (options.throw) {
222
+ let notImplementedThrowable = typeof options.notImplemented === 'function'
223
+ ? options.notImplemented() // set whatever the user returns from their function
224
+ : new http_errors_1.default.NotImplemented();
225
+ throw notImplementedThrowable;
226
+ }
227
+ else {
228
+ return {
229
+ status: 501,
230
+ headers: { Allow: allowedArr.join(', ') }
231
+ };
232
+ }
233
+ }
234
+ else if (allowedArr.length) {
235
+ if (currentMethod === 'OPTIONS') {
236
+ return {
237
+ status: 200,
238
+ headers: { Allow: allowedArr.join(', ') }
239
+ };
240
+ }
241
+ else if (!allowed[currentMethod]) {
242
+ if (options.throw) {
243
+ let notAllowedThrowable = typeof options.methodNotAllowed === 'function'
244
+ ? options.methodNotAllowed() // set whatever the user returns from their function
245
+ : new http_errors_1.default.MethodNotAllowed();
246
+ throw notAllowedThrowable;
247
+ }
248
+ else {
249
+ return {
250
+ status: 405,
251
+ headers: { Allow: allowedArr.join(', ') }
252
+ };
253
+ }
254
+ }
255
+ }
256
+ }
257
+ return response;
258
+ };
259
+ return routerMiddleware;
260
+ }
261
+ /**
262
+ * Register route with all methods.
263
+ *
264
+ * @param name - Optional.
265
+ * @param path -
266
+ * @param middleware - You may also pass multiple middleware.
267
+ * @param callback -
268
+ */
269
+ all(path, middleware) {
270
+ this.register(path, methods_1.methodsList, middleware, {});
271
+ return this;
272
+ }
273
+ /**
274
+ * Redirect `source` to `destination` URL with optional 30x status `code`.
275
+ *
276
+ * Both `source` and `destination` can be route names.
277
+ *
278
+ * ```javascript
279
+ * router.redirect('/login', 'sign-in');
280
+ * ```
281
+ *
282
+ * This is equivalent to:
283
+ *
284
+ * ```javascript
285
+ * router.all('/login', ctx => {
286
+ * ctx.redirect('/sign-in');
287
+ * ctx.status = 301;
288
+ * });
289
+ * ```
290
+ *
291
+ * @param source - URL or route name.
292
+ * @param destination - URL or route name.
293
+ * @param code - HTTP status code (default: 301).
294
+ */
295
+ redirect(source, destination, code = 301) {
296
+ // lookup source route by name
297
+ if (source[0] !== '/')
298
+ throw new Error(`Relative URL must start with / got ${JSON.stringify(source)} instead`);
299
+ // lookup destination route by name
300
+ if (destination[0] !== '/' && !destination.includes('://'))
301
+ throw new Error(`Can't resolve target URL, it is neither a relative or absolute URL. Got ${JSON.stringify(source)}`);
302
+ return this.all(source, async (ctx) => {
303
+ return { status: code, headers: { Location: destination } };
304
+ });
305
+ }
306
+ /**
307
+ * Create and register a route.
308
+ *
309
+ * @param path - Path string.
310
+ * @param methods - Array of HTTP verbs.
311
+ * @param middleware - Multiple middleware also accepted.
312
+ */
313
+ register(path, methods, middleware, opts) {
314
+ opts = opts || {};
315
+ const router = this;
316
+ const stack = this.stack;
317
+ // support array of paths
318
+ if (Array.isArray(path)) {
319
+ for (let i = 0; i < path.length; i++) {
320
+ const curPath = path[i];
321
+ router.register.call(router, curPath, methods, middleware, opts);
322
+ }
323
+ }
324
+ // create route
325
+ const route = new layer_1.Layer(path, methods, middleware, {
326
+ end: opts.end === false ? opts.end : true,
327
+ name: opts.name,
328
+ sensitive: opts.sensitive || this.opts.sensitive || false,
329
+ strict: opts.strict || this.opts.strict || false,
330
+ prefix: opts.prefix || this.opts.prefix || '',
331
+ ignoreCaptures: opts.ignoreCaptures
332
+ });
333
+ if (this.opts.prefix) {
334
+ route.setPrefix(this.opts.prefix);
335
+ }
336
+ stack.push(route);
337
+ // debug("defined route %s %s", route.methods, route.path)
338
+ return route;
339
+ }
340
+ /**
341
+ * Match given `path` and return corresponding routes.
342
+ *
343
+ * @param path -
344
+ * @param method -
345
+ */
346
+ match(path, method) {
347
+ const layers = this.stack;
348
+ let layer;
349
+ const matched = {
350
+ path: [],
351
+ pathAndMethod: [],
352
+ route: false
353
+ };
354
+ for (let len = layers.length, i = 0; i < len; i++) {
355
+ layer = layers[i];
356
+ // debug("test %s %s", layer.path, layer.regexp)
357
+ if (layer.match(path)) {
358
+ matched.path.push(layer);
359
+ if (layer.methods.length === 0 || ~layer.methods.indexOf(method)) {
360
+ matched.pathAndMethod.push(layer);
361
+ if (layer.methods.length)
362
+ matched.route = true;
363
+ }
364
+ }
365
+ }
366
+ return matched;
367
+ }
368
+ }
369
+ exports.Router = Router;
370
+ // /**
371
+ // * Generate URL from url pattern and given `params`.
372
+ // *
373
+ // * @example
374
+ // *
375
+ // * ```javascript
376
+ // * const url = Router.url('/users/:id', {id: 1});
377
+ // * // => "/users/1"
378
+ // * ```
379
+ // *
380
+ // * @param path - url pattern
381
+ // * @param params - url parameters
382
+ // */
383
+ // export function processUrl(path: string, ...rest: any[]): string {
384
+ // return Layer.prototype.url.apply({ path }, rest)
385
+ // }
386
+ // /**
387
+ // * Create `router.verb()` methods, where *verb* is one of the HTTP verbs such
388
+ // * as `router.get()` or `router.post()`.
389
+ // *
390
+ // * Match URL patterns to callback functions or controller actions using `router.verb()`,
391
+ // * where **verb** is one of the HTTP verbs such as `router.get()` or `router.post()`.
392
+ // *
393
+ // * Additionaly, `router.all()` can be used to match against all methods.
394
+ // *
395
+ // * ```javascript
396
+ // * router
397
+ // * .get('/', (ctx, next) => {
398
+ // * return ctx.body = 'Hello World!';
399
+ // * })
400
+ // * .post('/users', (ctx, next) => {
401
+ // * // ...
402
+ // * })
403
+ // * .put('/users/:id', (ctx, next) => {
404
+ // * // ...
405
+ // * })
406
+ // * .del('/users/:id', (ctx, next) => {
407
+ // * // ...
408
+ // * })
409
+ // * .all('/users/:id', (ctx, next) => {
410
+ // * // ...
411
+ // * });
412
+ // * ```
413
+ // *
414
+ // * When a route is matched, its path is available at `ctx._matchedRoute` and if named,
415
+ // * the name is available at `ctx._matchedRouteName`
416
+ // *
417
+ // * Route paths will be translated to regular expressions using
418
+ // * [path-to-regexp](https://github.com/pillarjs/path-to-regexp).
419
+ // *
420
+ // * Query strings will not be considered when matching requests.
421
+ // *
422
+ // * #### Named routes
423
+ // *
424
+ // * Routes can optionally have names. This allows generation of URLs and easy
425
+ // * renaming of URLs during development.
426
+ // *
427
+ // * ```javascript
428
+ // * router.get('user', '/users/:id', (ctx, next) => {
429
+ // * // ...
430
+ // * });
431
+ // *
432
+ // * router.url('user', 3);
433
+ // * // => "/users/3"
434
+ // * ```
435
+ // *
436
+ // * #### Multiple middleware
437
+ // *
438
+ // * Multiple middleware may be given:
439
+ // *
440
+ // * ```javascript
441
+ // * router.get(
442
+ // * '/users/:id',
443
+ // * (ctx, next) => {
444
+ // * return User.findOne(ctx.params.id).then(function(user) {
445
+ // * ctx.user = user;
446
+ // * next();
447
+ // * });
448
+ // * },
449
+ // * ctx => {
450
+ // * console.log(ctx.user);
451
+ // * // => { id: 17, name: "Alex" }
452
+ // * }
453
+ // * );
454
+ // * ```
455
+ // *
456
+ // * ### Nested routers
457
+ // *
458
+ // * Nesting routers is supported:
459
+ // *
460
+ // * ```javascript
461
+ // * const forums = new Router();
462
+ // * const posts = new Router();
463
+ // *
464
+ // * posts.get('/', (ctx, next) => {...});
465
+ // * posts.get('/:pid', (ctx, next) => {...});
466
+ // * forums.use('/forums/:fid/posts', posts.routes(), posts.allowedMethods());
467
+ // *
468
+ // * // responds to "/forums/123/posts" and "/forums/123/posts/123"
469
+ // * app.use(forums.routes());
470
+ // * ```
471
+ // *
472
+ // * #### Router prefixes
473
+ // *
474
+ // * Route paths can be prefixed at the router level:
475
+ // *
476
+ // * ```javascript
477
+ // * const router = new Router({
478
+ // * prefix: '/users'
479
+ // * });
480
+ // *
481
+ // * router.get('/', ...); // responds to "/users"
482
+ // * router.get('/:id', ...); // responds to "/users/:id"
483
+ // * ```
484
+ // *
485
+ // * #### URL parameters
486
+ // *
487
+ // * Named route parameters are captured and added to `ctx.params`.
488
+ // *
489
+ // * ```javascript
490
+ // * router.get('/:category/:title', (ctx, next) => {
491
+ // * console.log(ctx.params);
492
+ // * // => { category: 'programming', title: 'how-to-node' }
493
+ // * });
494
+ // * ```
495
+ // *
496
+ // * The [path-to-regexp](https://github.com/pillarjs/path-to-regexp) module is
497
+ // * used to convert paths to regular expressions.
498
+ // *
499
+ // * @name get|put|post|patch|delete|del
500
+ // * @memberof module:koa-router.prototype
501
+ // * @param path -
502
+ // * @param middleware - route middleware(s)
503
+ // * @param callback - route callback
504
+ // */
505
+ // for (let i = 0; i < methods.length; i++) {
506
+ // function setMethodVerb(method) {
507
+ // Router.prototype[method] = function (path, middleware: Middleware<any>) {
508
+ // this.register(path, [method], middleware, {})
509
+ // return this
510
+ // }
511
+ // }
512
+ // setMethodVerb(methods[i])
513
+ // }
514
+ // // Alias for `router.delete()` because delete is a reserved word
515
+ // Router.prototype.del = Router.prototype["delete"]
516
+ //# sourceMappingURL=router.js.map