@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 +31 -1
- package/lib/layer.js +25 -6
- package/lib/router.js +16 -6
- package/package.json +5 -5
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> | <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> | <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> | <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> | <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
|
+
[](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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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)
|
|
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 %
|
|
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)
|
|
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
|
-
*
|
|
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.
|
|
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": "
|
|
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",
|