@eggjs/router 2.1.0 → 2.2.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/README.md CHANGED
@@ -28,16 +28,18 @@ Router core component for [Egg.js](https://github.com/eggjs).
28
28
  - [Router.url(path, params \[, options\]) ⇒ String](#routerurlpath-params--options--string)
29
29
  - [Tests](#tests)
30
30
  - [License](#license)
31
+ - [Contributors](#contributors)
31
32
 
32
33
  <a name="exp_module_egg-router--Router"></a>
33
34
 
34
35
  ### Router ⏏
36
+
35
37
  **Kind**: Exported class
36
38
  <a name="new_module_egg-router--Router_new"></a>
37
39
 
38
40
  #### new Router([opts])
39
- Create a new router.
40
41
 
42
+ Create a new router.
41
43
 
42
44
  | Param | Type | Description |
43
45
  | --- | --- | --- |
@@ -62,9 +64,11 @@ app
62
64
  .use(router.routes())
63
65
  .use(router.allowedMethods());
64
66
  ```
67
+
65
68
  <a name="module_egg-router--Router+get|put|post|patch|delete|del"></a>
66
69
 
67
70
  #### router.get|put|post|patch|delete|del ⇒ <code>Router</code>
71
+
68
72
  Create `router.verb()` methods, where *verb* is one of the HTTP verbs such
69
73
  as `router.get()` or `router.post()`.
70
74
 
@@ -188,12 +192,14 @@ used to convert paths to regular expressions.
188
192
  <a name="module_egg-router--Router+routes"></a>
189
193
 
190
194
  #### router.routes ⇒ <code>function</code>
195
+
191
196
  Returns router middleware which dispatches a route matching the request.
192
197
 
193
198
  **Kind**: instance property of <code>[Router](#exp_module_egg-router--Router)</code>
194
199
  <a name="module_egg-router--Router+use"></a>
195
200
 
196
201
  #### router.use([path], middleware) ⇒ <code>Router</code>
202
+
197
203
  Use given middleware.
198
204
 
199
205
  Middleware run in the order they are defined by `.use()`. They are invoked
@@ -209,6 +215,7 @@ sequentially, requests start at the first middleware and work their way
209
215
  | [...] | <code>function</code> |
210
216
 
211
217
  **Example**
218
+
212
219
  ```javascript
213
220
  // session middleware will run before authorize
214
221
  router
@@ -223,9 +230,11 @@ router.use(['/users', '/admin'], userAuth());
223
230
 
224
231
  app.use(router.routes());
225
232
  ```
233
+
226
234
  <a name="module_egg-router--Router+prefix"></a>
227
235
 
228
236
  #### router.prefix(prefix) ⇒ <code>Router</code>
237
+
229
238
  Set the path prefix for a Router instance that was already initialized.
230
239
 
231
240
  **Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
@@ -235,12 +244,15 @@ Set the path prefix for a Router instance that was already initialized.
235
244
  | prefix | <code>String</code> |
236
245
 
237
246
  **Example**
247
+
238
248
  ```javascript
239
249
  router.prefix('/things/:thing_id')
240
250
  ```
251
+
241
252
  <a name="module_egg-router--Router+allowedMethods"></a>
242
253
 
243
254
  #### router.allowedMethods([options]) ⇒ <code>function</code>
255
+
244
256
  Returns separate middleware for responding to `OPTIONS` requests with
245
257
  an `Allow` header containing the allowed methods, as well as responding
246
258
  with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
@@ -255,6 +267,7 @@ with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
255
267
  | [options.methodNotAllowed] | <code>function</code> | throw the returned value in place of the default MethodNotAllowed error |
256
268
 
257
269
  **Example**
270
+
258
271
  ```javascript
259
272
  var Koa = require('koa');
260
273
  var Router = require('egg-router');
@@ -283,9 +296,11 @@ app.use(router.allowedMethods({
283
296
  methodNotAllowed: () => new Boom.methodNotAllowed()
284
297
  }));
285
298
  ```
299
+
286
300
  <a name="module_egg-router--Router+redirect"></a>
287
301
 
288
302
  #### router.redirect(source, destination, [code]) ⇒ <code>Router</code>
303
+
289
304
  Redirect `source` to `destination` URL with optional 30x status `code`.
290
305
 
291
306
  Both `source` and `destination` can be route names.
@@ -314,6 +329,7 @@ router.all('/login', ctx => {
314
329
  <a name="module_egg-router--Router+route"></a>
315
330
 
316
331
  #### router.route(name) ⇒ <code>Layer</code> &#124; <code>false</code>
332
+
317
333
  Lookup route with given `name`.
318
334
 
319
335
  **Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
@@ -325,6 +341,7 @@ Lookup route with given `name`.
325
341
  <a name="module_egg-router--Router+url"></a>
326
342
 
327
343
  #### router.url(name, params, [options]) ⇒ <code>String</code> &#124; <code>Error</code>
344
+
328
345
  Generate URL for route. Takes a route name and map of named `params`.
329
346
 
330
347
  **Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
@@ -337,6 +354,7 @@ Generate URL for route. Takes a route name and map of named `params`.
337
354
  | [options.query] | <code>Object</code> &#124; <code>String</code> | query options |
338
355
 
339
356
  **Example**
357
+
340
358
  ```javascript
341
359
  router.get('user', '/users/:id', (ctx, next) => {
342
360
  // ...
@@ -359,9 +377,11 @@ router.url('user', { id: 3 }, { query: { limit: 1 } });
359
377
  router.url('user', { id: 3 }, { query: "limit=1" });
360
378
  // => "/users/3?limit=1"
361
379
  ```
380
+
362
381
  <a name="module_egg-router--Router+param"></a>
363
382
 
364
383
  #### router.param(param, middleware) ⇒ <code>Router</code>
384
+
365
385
  Run middleware for named route parameters. Useful for auto-loading or
366
386
  validation.
367
387
 
@@ -373,6 +393,7 @@ validation.
373
393
  | middleware | <code>function</code> |
374
394
 
375
395
  **Example**
396
+
376
397
  ```javascript
377
398
  router
378
399
  .param('user', (id, ctx, next) => {
@@ -391,9 +412,11 @@ router
391
412
  // /users/3 => {"id": 3, "name": "Alex"}
392
413
  // /users/3/friends => [{"id": 4, "name": "TJ"}]
393
414
  ```
415
+
394
416
  <a name="module_egg-router--Router.url"></a>
395
417
 
396
418
  #### Router.url(path, params [, options]) ⇒ <code>String</code>
419
+
397
420
  Generate URL from url pattern and given `params`.
398
421
 
399
422
  **Kind**: static method of <code>[Router](#exp_module_egg-router--Router)</code>
@@ -406,6 +429,7 @@ Generate URL from url pattern and given `params`.
406
429
  | [options.query] | <code>Object</code> &#124; <code>String</code> | query options |
407
430
 
408
431
  **Example**
432
+
409
433
  ```javascript
410
434
  var url = Router.url('/users/:id', {id: 1});
411
435
  // => "/users/1"
@@ -421,3 +445,9 @@ Run tests using `npm test`.
421
445
  ## License
422
446
 
423
447
  [MIT](LICENSE)
448
+
449
+ ## Contributors
450
+
451
+ [![Contributors](https://contrib.rocks/image?repo=eggjs/router)](https://github.com/eggjs/router/graphs/contributors)
452
+
453
+ Made with [contributors-img](https://contrib.rocks).
package/lib/layer.js CHANGED
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const debug = require('util').debuglog('egg-router:layer');
4
- const pathToRegExp = require('path-to-regexp');
4
+ const assert = require('assert');
5
+ const pathToRegexpModule = require('path-to-regexp');
5
6
  const uri = require('urijs');
6
7
  const utility = require('utility');
7
8
 
@@ -16,10 +17,15 @@ module.exports = class Layer {
16
17
  * @param {String=} opts.name route name
17
18
  * @param {String=} opts.sensitive case sensitive (default: false)
18
19
  * @param {String=} opts.strict require the trailing slash (default: false)
20
+ * @param {Object=} opts.pathToRegexpModule custom path-to-regexp module
19
21
  * @private
20
22
  */
21
23
  constructor(path, methods, middleware, opts) {
22
24
  this.opts = opts || {};
25
+ this._pathToRegexpModule = this.opts.pathToRegexpModule || pathToRegexpModule;
26
+ // support path-to-regexp@8 and path-to-regexp@1
27
+ this._pathToRegexp = this._pathToRegexpModule.pathToRegexp || this._pathToRegexpModule;
28
+ assert(typeof this._pathToRegexp === 'function', 'opts.pathToRegexpModule.pathToRegexp must be a function');
23
29
  this.name = this.opts.name || null;
24
30
  this.methods = [];
25
31
  this.paramNames = [];
@@ -44,11 +50,22 @@ module.exports = class Layer {
44
50
  }, this);
45
51
 
46
52
  this.path = path;
47
- this.regexp = pathToRegExp(path, this.paramNames, this.opts);
48
-
53
+ const { regexp, keys } = this._convertPathToRegexp(path, this.opts);
54
+ this.regexp = regexp;
55
+ this.paramNames = keys;
49
56
  debug('defined route %s %s', this.methods, this.opts.prefix + this.path);
50
57
  }
51
58
 
59
+ _convertPathToRegexp(path, options) {
60
+ let regexp = this._pathToRegexp(path, [], options);
61
+ const keys = regexp.keys;
62
+ if (regexp.regexp) {
63
+ // support path-to-regexp@8
64
+ regexp = regexp.regexp;
65
+ }
66
+ return { regexp, keys };
67
+ }
68
+
52
69
  /**
53
70
  * Returns whether request `path` matches route.
54
71
  *
@@ -112,7 +129,7 @@ module.exports = class Layer {
112
129
  url(params, options) {
113
130
  let args = params;
114
131
  const url = this.path.replace(/\(\.\*\)/g, '');
115
- const toPath = pathToRegExp.compile(url);
132
+ const toPath = this._pathToRegexpModule.compile(url);
116
133
 
117
134
  if (typeof params !== 'object') {
118
135
  args = Array.prototype.slice.call(arguments);
@@ -122,7 +139,7 @@ module.exports = class Layer {
122
139
  }
123
140
  }
124
141
 
125
- const tokens = pathToRegExp.parse(url);
142
+ const tokens = this._pathToRegexpModule.parse(url);
126
143
  let replace = {};
127
144
 
128
145
  if (args instanceof Array) {
@@ -209,7 +226,9 @@ module.exports = class Layer {
209
226
  if (this.path) {
210
227
  this.path = prefix + this.path;
211
228
  this.paramNames = [];
212
- this.regexp = pathToRegExp(this.path, this.paramNames, this.opts);
229
+ const { regexp, keys } = this._convertPathToRegexp(this.path, this.opts);
230
+ this.regexp = regexp;
231
+ this.paramNames = keys;
213
232
  }
214
233
 
215
234
  return this;
package/lib/router.js CHANGED
@@ -8,6 +8,7 @@ const debug = require('util').debuglog('egg-router');
8
8
  const compose = require('koa-compose');
9
9
  const HttpError = require('http-errors');
10
10
  const methods = require('methods');
11
+ const pathToRegexpModule = require('path-to-regexp');
11
12
  const Layer = require('./layer');
12
13
 
13
14
  /**
@@ -86,6 +87,7 @@ class Router {
86
87
  * @param {Function} middleware middleware function
87
88
  * @return {Router} router instance
88
89
  */
90
+
89
91
  use(/* path, middleware */) {
90
92
  const router = this;
91
93
  const middleware = Array.prototype.slice.call(arguments);
@@ -172,7 +174,9 @@ class Router {
172
174
 
173
175
  ctx.router = router;
174
176
 
175
- if (!matched.route) return next();
177
+ if (!matched.route) {
178
+ return next();
179
+ }
176
180
 
177
181
  const matchedLayers = matched.pathAndMethod;
178
182
  const layerChain = matchedLayers.reduce(function(memo, layer) {
@@ -303,6 +307,7 @@ class Router {
303
307
  * @return {Router} router instance
304
308
  * @private
305
309
  */
310
+
306
311
  all(name, path/* , middleware */) {
307
312
  let middleware;
308
313
 
@@ -394,6 +399,7 @@ class Router {
394
399
  strict: opts.strict || this.opts.strict || false,
395
400
  prefix: opts.prefix || this.opts.prefix || '',
396
401
  ignoreCaptures: opts.ignoreCaptures,
402
+ pathToRegexpModule: this.opts.pathToRegexpModule,
397
403
  });
398
404
 
399
405
  if (this.opts.prefix) {
@@ -462,6 +468,7 @@ class Router {
462
468
  * @param {Object|String} [options.query] query options
463
469
  * @return {String|Error} string or error instance
464
470
  */
471
+
465
472
  url(name/* , params */) {
466
473
  const route = this.route(name);
467
474
 
@@ -497,14 +504,16 @@ class Router {
497
504
  for (let len = layers.length, i = 0; i < len; i++) {
498
505
  layer = layers[i];
499
506
 
500
- debug('test %s %s', layer.path, layer.regexp);
507
+ debug('test %s %o', layer.path, layer.regexp);
501
508
 
502
509
  if (layer.match(path)) {
503
510
  matched.path.push(layer);
504
511
 
505
512
  if (layer.methods.length === 0 || layer.methods.includes(method)) {
506
513
  matched.pathAndMethod.push(layer);
507
- if (layer.methods.length) matched.route = true;
514
+ if (layer.methods.length) {
515
+ matched.route = true;
516
+ }
508
517
  }
509
518
  // if (layer.methods.length === 0) {
510
519
  // matched.pathAndMethod.push(layer);
@@ -563,7 +572,7 @@ class Router {
563
572
  * Match URL patterns to callback functions or controller actions using `router.verb()`,
564
573
  * where **verb** is one of the HTTP verbs such as `router.get()` or `router.post()`.
565
574
  *
566
- * Additionaly, `router.all()` can be used to match against all methods.
575
+ * Additionally, `router.all()` can be used to match against all methods.
567
576
  *
568
577
  * ```javascript
569
578
  * router
@@ -706,7 +715,7 @@ Router.prototype.del = Router.prototype.delete;
706
715
  * @example
707
716
  *
708
717
  * ```javascript
709
- * var url = Router.url('/users/:id', {id: 1});
718
+ * var url = Router.url('/users/:id', { id: 1 });
710
719
  * // => "/users/1"
711
720
  * ```
712
721
  *
@@ -714,9 +723,10 @@ Router.prototype.del = Router.prototype.delete;
714
723
  * @param {Object} params url parameters
715
724
  * @return {String} url string
716
725
  */
726
+
717
727
  Router.url = function(path/* , params */) {
718
728
  const args = Array.prototype.slice.call(arguments, 1);
719
- return Layer.prototype.url.apply({ path }, args);
729
+ return Layer.prototype.url.apply({ path, _pathToRegexpModule: pathToRegexpModule }, args);
720
730
  };
721
731
 
722
732
  Router.prototype.middleware = Router.prototype.routes;
package/package.json CHANGED
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "@eggjs/router",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "engines": {
5
5
  "node": ">= 8.5.0"
6
6
  },
7
7
  "publishConfig": {
8
- "access": "public",
9
- "tag": "latest-2"
8
+ "access": "public"
10
9
  },
11
10
  "description": "Router middleware for egg/koa. Provides RESTful resource routing.",
12
11
  "repository": {
13
12
  "type": "git",
14
- "url": "https://github.com/eggjs/egg-router.git"
13
+ "url": "git@github.com:eggjs/router.git"
15
14
  },
16
15
  "bugs": {
17
16
  "url": "https://github.com/eggjs/egg/issues"
@@ -46,7 +45,8 @@
46
45
  "koa": "^2.7.0",
47
46
  "mocha": "^2.0.1",
48
47
  "should": "^6.0.3",
49
- "supertest": "^1.0.1"
48
+ "supertest": "^1.0.1",
49
+ "path-to-regexp-v8": "npm:path-to-regexp@8"
50
50
  },
51
51
  "scripts": {
52
52
  "test-local": "egg-bin test",