@eggjs/router 3.0.5 → 4.0.0-beta.16
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 +69 -81
- package/dist/EggRouter.d.ts +108 -0
- package/dist/EggRouter.js +208 -0
- package/dist/Layer.d.ts +118 -0
- package/dist/Layer.js +201 -0
- package/dist/Router.d.ts +496 -0
- package/dist/Router.js +676 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.js +1 -0
- package/package.json +37 -56
- package/dist/commonjs/EggRouter.d.ts +0 -102
- package/dist/commonjs/EggRouter.js +0 -244
- package/dist/commonjs/Layer.d.ts +0 -114
- package/dist/commonjs/Layer.js +0 -237
- package/dist/commonjs/Router.d.ts +0 -494
- package/dist/commonjs/Router.js +0 -790
- package/dist/commonjs/index.d.ts +0 -7
- package/dist/commonjs/index.js +0 -24
- package/dist/commonjs/package.json +0 -3
- package/dist/commonjs/types.d.ts +0 -18
- package/dist/commonjs/types.js +0 -3
- package/dist/esm/EggRouter.d.ts +0 -102
- package/dist/esm/EggRouter.js +0 -237
- package/dist/esm/Layer.d.ts +0 -114
- package/dist/esm/Layer.js +0 -230
- package/dist/esm/Router.d.ts +0 -494
- package/dist/esm/Router.js +0 -783
- package/dist/esm/index.d.ts +0 -7
- package/dist/esm/index.js +0 -7
- package/dist/esm/package.json +0 -3
- package/dist/esm/types.d.ts +0 -18
- package/dist/esm/types.js +0 -2
- package/src/EggRouter.ts +0 -349
- package/src/Layer.ts +0 -274
- package/src/Router.ts +0 -1087
- package/src/index.ts +0 -9
- package/src/types.ts +0 -15
package/README.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://npmjs.org/package/@eggjs/router)
|
|
4
4
|
[](https://npmjs.org/package/@eggjs/router)
|
|
5
|
-
[](https://github.com/eggjs/egg-router/actions/workflows/nodejs.yml)
|
|
6
|
-
[](https://codecov.io/gh/eggjs/egg-router)
|
|
7
5
|
[](https://snyk.io/test/npm/@eggjs/router)
|
|
6
|
+
[](https://nodejs.org/en/download/)
|
|
7
|
+
[](https://makeapullrequest.com)
|
|
8
|
+

|
|
8
9
|
|
|
9
10
|
Router core component for [Egg.js](https://github.com/eggjs).
|
|
10
11
|
|
|
@@ -48,9 +49,9 @@ Router core component for [Egg.js](https://github.com/eggjs).
|
|
|
48
49
|
|
|
49
50
|
Create a new router.
|
|
50
51
|
|
|
51
|
-
| Param
|
|
52
|
-
|
|
|
53
|
-
| [opts]
|
|
52
|
+
| Param | Type | Description |
|
|
53
|
+
| ------------- | ------------------- | ------------------- |
|
|
54
|
+
| [opts] | <code>Object</code> | |
|
|
54
55
|
| [opts.prefix] | <code>String</code> | prefix router paths |
|
|
55
56
|
|
|
56
57
|
**Example**
|
|
@@ -67,16 +68,14 @@ router.get('/', async (ctx, next) => {
|
|
|
67
68
|
// ctx.router available
|
|
68
69
|
});
|
|
69
70
|
|
|
70
|
-
app
|
|
71
|
-
.use(router.routes())
|
|
72
|
-
.use(router.allowedMethods());
|
|
71
|
+
app.use(router.routes()).use(router.allowedMethods());
|
|
73
72
|
```
|
|
74
73
|
|
|
75
74
|
<a name="module_egg-router--Router+get|put|post|patch|delete|del"></a>
|
|
76
75
|
|
|
77
76
|
#### router.get|put|post|patch|delete|del ⇒ <code>Router</code>
|
|
78
77
|
|
|
79
|
-
Create `router.verb()` methods, where
|
|
78
|
+
Create `router.verb()` methods, where _verb_ is one of the HTTP verbs such
|
|
80
79
|
as `router.get()` or `router.post()`.
|
|
81
80
|
|
|
82
81
|
Match URL patterns to callback functions or controller actions using `router.verb()`,
|
|
@@ -118,7 +117,7 @@ renaming of URLs during development.
|
|
|
118
117
|
|
|
119
118
|
```ts
|
|
120
119
|
router.get('user', '/users/:id', (ctx, next) => {
|
|
121
|
-
|
|
120
|
+
// ...
|
|
122
121
|
});
|
|
123
122
|
|
|
124
123
|
router.url('user', 3);
|
|
@@ -133,7 +132,7 @@ Multiple middleware may be given:
|
|
|
133
132
|
router.get(
|
|
134
133
|
'/users/:id',
|
|
135
134
|
(ctx, next) => {
|
|
136
|
-
return User.findOne(ctx.params.id).then(function(user) {
|
|
135
|
+
return User.findOne(ctx.params.id).then(function (user) {
|
|
137
136
|
ctx.user = user;
|
|
138
137
|
next();
|
|
139
138
|
});
|
|
@@ -190,15 +189,16 @@ used to convert paths to regular expressions.
|
|
|
190
189
|
|
|
191
190
|
**Kind**: instance property of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
192
191
|
|
|
193
|
-
| Param
|
|
194
|
-
|
|
|
195
|
-
| path
|
|
192
|
+
| Param | Type | Description |
|
|
193
|
+
| ------------ | --------------------- | ------------------- |
|
|
194
|
+
| path | <code>String</code> | |
|
|
196
195
|
| [middleware] | <code>function</code> | route middleware(s) |
|
|
197
|
-
| callback
|
|
196
|
+
| callback | <code>function</code> | route callback |
|
|
198
197
|
|
|
199
198
|
<a name="module_egg-router--Router+routes"></a>
|
|
200
199
|
|
|
201
200
|
#### router.routes ⇒ <code>function</code>
|
|
201
|
+
|
|
202
202
|
Returns router middleware which dispatches a route matching the request.
|
|
203
203
|
|
|
204
204
|
**Kind**: instance property of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
@@ -214,19 +214,17 @@ sequentially, requests start at the first middleware and work their way
|
|
|
214
214
|
|
|
215
215
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
216
216
|
|
|
217
|
-
| Param
|
|
218
|
-
|
|
|
219
|
-
| [path]
|
|
217
|
+
| Param | Type |
|
|
218
|
+
| ---------- | --------------------- |
|
|
219
|
+
| [path] | <code>String</code> |
|
|
220
220
|
| middleware | <code>function</code> |
|
|
221
|
-
| [...]
|
|
221
|
+
| [...] | <code>function</code> |
|
|
222
222
|
|
|
223
223
|
**Example**
|
|
224
224
|
|
|
225
225
|
```ts
|
|
226
226
|
// session middleware will run before authorize
|
|
227
|
-
router
|
|
228
|
-
.use(session())
|
|
229
|
-
.use(authorize());
|
|
227
|
+
router.use(session()).use(authorize());
|
|
230
228
|
|
|
231
229
|
// use middleware only with given path
|
|
232
230
|
router.use('/users', userAuth());
|
|
@@ -245,14 +243,14 @@ Set the path prefix for a Router instance that was already initialized.
|
|
|
245
243
|
|
|
246
244
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
247
245
|
|
|
248
|
-
| Param
|
|
249
|
-
|
|
|
246
|
+
| Param | Type |
|
|
247
|
+
| ------ | ------------------- |
|
|
250
248
|
| prefix | <code>String</code> |
|
|
251
249
|
|
|
252
250
|
**Example**
|
|
253
251
|
|
|
254
252
|
```ts
|
|
255
|
-
router.prefix('/things/:thing_id')
|
|
253
|
+
router.prefix('/things/:thing_id');
|
|
256
254
|
```
|
|
257
255
|
|
|
258
256
|
<a name="module_egg-router--Router+allowedMethods"></a>
|
|
@@ -265,11 +263,11 @@ with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
|
|
|
265
263
|
|
|
266
264
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
267
265
|
|
|
268
|
-
| Param
|
|
269
|
-
|
|
|
270
|
-
| [options]
|
|
271
|
-
| [options.throw]
|
|
272
|
-
| [options.notImplemented]
|
|
266
|
+
| Param | Type | Description |
|
|
267
|
+
| -------------------------- | --------------------- | ----------------------------------------------------------------------- |
|
|
268
|
+
| [options] | <code>Object</code> | |
|
|
269
|
+
| [options.throw] | <code>Boolean</code> | throw error instead of setting status and header |
|
|
270
|
+
| [options.notImplemented] | <code>function</code> | throw the returned value in place of the default NotImplemented error |
|
|
273
271
|
| [options.methodNotAllowed] | <code>function</code> | throw the returned value in place of the default MethodNotAllowed error |
|
|
274
272
|
|
|
275
273
|
**Example**
|
|
@@ -296,11 +294,13 @@ const app = new Koa();
|
|
|
296
294
|
const router = new Router();
|
|
297
295
|
|
|
298
296
|
app.use(router.routes());
|
|
299
|
-
app.use(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
297
|
+
app.use(
|
|
298
|
+
router.allowedMethods({
|
|
299
|
+
throw: true,
|
|
300
|
+
notImplemented: () => new Boom.notImplemented(),
|
|
301
|
+
methodNotAllowed: () => new Boom.methodNotAllowed(),
|
|
302
|
+
})
|
|
303
|
+
);
|
|
304
304
|
```
|
|
305
305
|
|
|
306
306
|
<a name="module_egg-router--Router+redirect"></a>
|
|
@@ -326,11 +326,11 @@ router.all('/login', ctx => {
|
|
|
326
326
|
|
|
327
327
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
328
328
|
|
|
329
|
-
| Param
|
|
330
|
-
|
|
|
331
|
-
| source
|
|
332
|
-
| destination | <code>String</code> | URL or route name.
|
|
333
|
-
| [code]
|
|
329
|
+
| Param | Type | Description |
|
|
330
|
+
| ----------- | ------------------- | -------------------------------- |
|
|
331
|
+
| source | <code>String</code> | URL or route name. |
|
|
332
|
+
| destination | <code>String</code> | URL or route name. |
|
|
333
|
+
| [code] | <code>Number</code> | HTTP status code (default: 301). |
|
|
334
334
|
|
|
335
335
|
<a name="module_egg-router--Router+route"></a>
|
|
336
336
|
|
|
@@ -340,9 +340,9 @@ Lookup route with given `name`.
|
|
|
340
340
|
|
|
341
341
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
342
342
|
|
|
343
|
-
| Param | Type
|
|
344
|
-
|
|
|
345
|
-
| name
|
|
343
|
+
| Param | Type |
|
|
344
|
+
| ----- | ------------------- |
|
|
345
|
+
| name | <code>String</code> |
|
|
346
346
|
|
|
347
347
|
<a name="module_egg-router--Router+url"></a>
|
|
348
348
|
|
|
@@ -352,12 +352,12 @@ Generate URL for route. Takes a route name and map of named `params`.
|
|
|
352
352
|
|
|
353
353
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
354
354
|
|
|
355
|
-
| Param
|
|
356
|
-
|
|
|
357
|
-
| name
|
|
358
|
-
| params
|
|
359
|
-
| [options]
|
|
360
|
-
| [options.query] | <code>Object</code> | <code>String</code> | query options
|
|
355
|
+
| Param | Type | Description |
|
|
356
|
+
| --------------- | ---------------------------------------------- | ----------------- |
|
|
357
|
+
| name | <code>String</code> | route name |
|
|
358
|
+
| params | <code>Object</code> | url parameters |
|
|
359
|
+
| [options] | <code>Object</code> | options parameter |
|
|
360
|
+
| [options.query] | <code>Object</code> | <code>String</code> | query options |
|
|
361
361
|
|
|
362
362
|
**Example**
|
|
363
363
|
|
|
@@ -375,12 +375,12 @@ router.url('user', { id: 3 });
|
|
|
375
375
|
router.use((ctx, next) => {
|
|
376
376
|
// redirect to named route
|
|
377
377
|
ctx.redirect(ctx.router.url('sign-in'));
|
|
378
|
-
})
|
|
378
|
+
});
|
|
379
379
|
|
|
380
380
|
router.url('user', { id: 3 }, { query: { limit: 1 } });
|
|
381
381
|
// => "/users/3?limit=1"
|
|
382
382
|
|
|
383
|
-
router.url('user', { id: 3 }, { query:
|
|
383
|
+
router.url('user', { id: 3 }, { query: 'limit=1' });
|
|
384
384
|
// => "/users/3?limit=1"
|
|
385
385
|
```
|
|
386
386
|
|
|
@@ -393,9 +393,9 @@ validation.
|
|
|
393
393
|
|
|
394
394
|
**Kind**: instance method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
395
395
|
|
|
396
|
-
| Param
|
|
397
|
-
|
|
|
398
|
-
| param
|
|
396
|
+
| Param | Type |
|
|
397
|
+
| ---------- | --------------------- |
|
|
398
|
+
| param | <code>String</code> |
|
|
399
399
|
| middleware | <code>function</code> |
|
|
400
400
|
|
|
401
401
|
**Example**
|
|
@@ -404,19 +404,19 @@ validation.
|
|
|
404
404
|
router
|
|
405
405
|
.param('user', (id, ctx, next) => {
|
|
406
406
|
ctx.user = users[id];
|
|
407
|
-
if (!ctx.user) return ctx.status = 404;
|
|
407
|
+
if (!ctx.user) return (ctx.status = 404);
|
|
408
408
|
return next();
|
|
409
409
|
})
|
|
410
410
|
.get('/users/:user', ctx => {
|
|
411
411
|
ctx.body = ctx.user;
|
|
412
412
|
})
|
|
413
413
|
.get('/users/:user/friends', ctx => {
|
|
414
|
-
return ctx.user.getFriends().then(function(friends) {
|
|
414
|
+
return ctx.user.getFriends().then(function (friends) {
|
|
415
415
|
ctx.body = friends;
|
|
416
416
|
});
|
|
417
|
-
})
|
|
418
|
-
|
|
419
|
-
|
|
417
|
+
});
|
|
418
|
+
// /users/3 => {"id": 3, "name": "Alex"}
|
|
419
|
+
// /users/3/friends => [{"id": 4, "name": "TJ"}]
|
|
420
420
|
```
|
|
421
421
|
|
|
422
422
|
<a name="module_egg-router--Router.url"></a>
|
|
@@ -427,20 +427,20 @@ Generate URL from url pattern and given `params`.
|
|
|
427
427
|
|
|
428
428
|
**Kind**: static method of <code>[Router](#exp_module_egg-router--Router)</code>
|
|
429
429
|
|
|
430
|
-
| Param
|
|
431
|
-
|
|
|
432
|
-
| path
|
|
433
|
-
| params
|
|
434
|
-
| [options]
|
|
435
|
-
| [options.query] | <code>Object</code> | <code>String</code> | query options
|
|
430
|
+
| Param | Type | Description |
|
|
431
|
+
| --------------- | ---------------------------------------------- | ----------------- |
|
|
432
|
+
| path | <code>String</code> | url pattern |
|
|
433
|
+
| params | <code>Object</code> | url parameters |
|
|
434
|
+
| [options] | <code>Object</code> | options parameter |
|
|
435
|
+
| [options.query] | <code>Object</code> | <code>String</code> | query options |
|
|
436
436
|
|
|
437
437
|
**Example**
|
|
438
438
|
|
|
439
439
|
```ts
|
|
440
|
-
const url = Router.url('/users/:id', {id: 1});
|
|
440
|
+
const url = Router.url('/users/:id', { id: 1 });
|
|
441
441
|
// => "/users/1"
|
|
442
442
|
|
|
443
|
-
const url = Router.url('/users/:id', {id: 1}, {query: { active: true }});
|
|
443
|
+
const url = Router.url('/users/:id', { id: 1 }, { query: { active: true } });
|
|
444
444
|
// => "/users/1?active=true"
|
|
445
445
|
```
|
|
446
446
|
|
|
@@ -457,20 +457,8 @@ Run tests using `npm test`.
|
|
|
457
457
|
|
|
458
458
|
[MIT](LICENSE)
|
|
459
459
|
|
|
460
|
-
<!-- GITCONTRIBUTOR_START -->
|
|
461
|
-
|
|
462
460
|
## Contributors
|
|
463
461
|
|
|
464
|
-
|
|
465
|
-
| :---: | :---: | :---: | :---: | :---: | :---: |
|
|
466
|
-
|[<img src="https://avatars.githubusercontent.com/u/25254?v=4" width="100px;"/><br/><sub><b>tj</b></sub>](https://github.com/tj)<br/>|[<img src="https://avatars.githubusercontent.com/u/166834?v=4" width="100px;"/><br/><sub><b>aheckmann</b></sub>](https://github.com/aheckmann)<br/>|[<img src="https://avatars.githubusercontent.com/u/385716?v=4" width="100px;"/><br/><sub><b>kilianc</b></sub>](https://github.com/kilianc)<br/>|[<img src="https://avatars.githubusercontent.com/u/98955?v=4" width="100px;"/><br/><sub><b>secretfader</b></sub>](https://github.com/secretfader)<br/>|[<img src="https://avatars.githubusercontent.com/u/474587?v=4" width="100px;"/><br/><sub><b>ilkkao</b></sub>](https://github.com/ilkkao)<br/>|[<img src="https://avatars.githubusercontent.com/u/6873217?v=4" width="100px;"/><br/><sub><b>HeavenDuke</b></sub>](https://github.com/HeavenDuke)<br/>|
|
|
467
|
-
|[<img src="https://avatars.githubusercontent.com/u/2842176?v=4" width="100px;"/><br/><sub><b>XadillaX</b></sub>](https://github.com/XadillaX)<br/>|[<img src="https://avatars.githubusercontent.com/u/200876?v=4" width="100px;"/><br/><sub><b>yiminghe</b></sub>](https://github.com/yiminghe)<br/>|[<img src="https://avatars.githubusercontent.com/u/32174276?v=4" width="100px;"/><br/><sub><b>semantic-release-bot</b></sub>](https://github.com/semantic-release-bot)<br/>|[<img src="https://avatars.githubusercontent.com/u/6794386?v=4" width="100px;"/><br/><sub><b>vkhv</b></sub>](https://github.com/vkhv)<br/>|[<img src="https://avatars.githubusercontent.com/u/7627362?v=4" width="100px;"/><br/><sub><b>vikramdurai</b></sub>](https://github.com/vikramdurai)<br/>|[<img src="https://avatars.githubusercontent.com/u/9271565?v=4" width="100px;"/><br/><sub><b>Tankenstein</b></sub>](https://github.com/Tankenstein)<br/>|
|
|
468
|
-
|[<img src="https://avatars.githubusercontent.com/u/2822996?v=4" width="100px;"/><br/><sub><b>richardprior</b></sub>](https://github.com/richardprior)<br/>|[<img src="https://avatars.githubusercontent.com/u/1635441?v=4" width="100px;"/><br/><sub><b>joesonw</b></sub>](https://github.com/joesonw)<br/>|[<img src="https://avatars.githubusercontent.com/u/875091?v=4" width="100px;"/><br/><sub><b>ifroz</b></sub>](https://github.com/ifroz)<br/>|[<img src="https://avatars.githubusercontent.com/u/13130706?v=4" width="100px;"/><br/><sub><b>jeynish</b></sub>](https://github.com/jeynish)<br/>|[<img src="https://avatars.githubusercontent.com/u/72027?v=4" width="100px;"/><br/><sub><b>jergason</b></sub>](https://github.com/jergason)<br/>|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|
|
|
469
|
-
|[<img src="https://avatars.githubusercontent.com/u/130963?v=4" width="100px;"/><br/><sub><b>lagden</b></sub>](https://github.com/lagden)<br/>|[<img src="https://avatars.githubusercontent.com/u/484559?v=4" width="100px;"/><br/><sub><b>fixe</b></sub>](https://github.com/fixe)<br/>|[<img src="https://avatars.githubusercontent.com/u/2671328?v=4" width="100px;"/><br/><sub><b>viliam-jobko</b></sub>](https://github.com/viliam-jobko)<br/>|[<img src="https://avatars.githubusercontent.com/u/2971112?v=4" width="100px;"/><br/><sub><b>mzyy94</b></sub>](https://github.com/mzyy94)<br/>|[<img src="https://avatars.githubusercontent.com/u/687842?v=4" width="100px;"/><br/><sub><b>jeromew</b></sub>](https://github.com/jeromew)<br/>|[<img src="https://avatars.githubusercontent.com/u/6897780?v=4" width="100px;"/><br/><sub><b>killagu</b></sub>](https://github.com/killagu)<br/>|
|
|
470
|
-
|[<img src="https://avatars.githubusercontent.com/u/8069753?v=4" width="100px;"/><br/><sub><b>RobertHerhold</b></sub>](https://github.com/RobertHerhold)<br/>|[<img src="https://avatars.githubusercontent.com/u/4619802?v=4" width="100px;"/><br/><sub><b>yudppp</b></sub>](https://github.com/yudppp)<br/>|[<img src="https://avatars.githubusercontent.com/u/3173170?v=4" width="100px;"/><br/><sub><b>thedark1337</b></sub>](https://github.com/thedark1337)<br/>|[<img src="https://avatars.githubusercontent.com/u/6903313?v=4" width="100px;"/><br/><sub><b>x-cold</b></sub>](https://github.com/x-cold)<br/>|[<img src="https://avatars.githubusercontent.com/u/6713367?v=4" width="100px;"/><br/><sub><b>zzuieliyaoli</b></sub>](https://github.com/zzuieliyaoli)<br/>|[<img src="https://avatars.githubusercontent.com/u/81891?v=4" width="100px;"/><br/><sub><b>ryankask</b></sub>](https://github.com/ryankask)<br/>|
|
|
471
|
-
|[<img src="https://avatars.githubusercontent.com/u/4810916?v=4" width="100px;"/><br/><sub><b>pschwyter</b></sub>](https://github.com/pschwyter)<br/>|[<img src="https://avatars.githubusercontent.com/u/62940?v=4" width="100px;"/><br/><sub><b>mikefrey</b></sub>](https://github.com/mikefrey)<br/>|[<img src="https://avatars.githubusercontent.com/u/300104?v=4" width="100px;"/><br/><sub><b>dizlexik</b></sub>](https://github.com/dizlexik)<br/>|[<img src="https://avatars.githubusercontent.com/u/2505474?v=4" width="100px;"/><br/><sub><b>jeffijoe</b></sub>](https://github.com/jeffijoe)<br/>|[<img src="https://avatars.githubusercontent.com/u/349336?v=4" width="100px;"/><br/><sub><b>iliakan</b></sub>](https://github.com/iliakan)<br/>|[<img src="https://avatars.githubusercontent.com/u/615334?v=4" width="100px;"/><br/><sub><b>frederickfogerty</b></sub>](https://github.com/frederickfogerty)<br/>|
|
|
472
|
-
[<img src="https://avatars.githubusercontent.com/u/2552790?v=4" width="100px;"/><br/><sub><b>t3chnoboy</b></sub>](https://github.com/t3chnoboy)<br/>|[<img src="https://avatars.githubusercontent.com/u/1484279?v=4" width="100px;"/><br/><sub><b>bitinn</b></sub>](https://github.com/bitinn)<br/>|[<img src="https://avatars.githubusercontent.com/u/1441230?v=4" width="100px;"/><br/><sub><b>drGrove</b></sub>](https://github.com/drGrove)<br/>|[<img src="https://avatars.githubusercontent.com/u/12624092?v=4" width="100px;"/><br/><sub><b>CreativeCactus</b></sub>](https://github.com/CreativeCactus)<br/>|[<img src="https://avatars.githubusercontent.com/u/1773785?v=4" width="100px;"/><br/><sub><b>bguiz</b></sub>](https://github.com/bguiz)<br/>
|
|
473
|
-
|
|
474
|
-
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sun Jun 16 2024 12:28:11 GMT+0800`.
|
|
462
|
+
[](https://github.com/eggjs/egg/graphs/contributors)
|
|
475
463
|
|
|
476
|
-
|
|
464
|
+
Made with [contributors-img](https://contrib.rocks).
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { MiddlewareFunc, ResourcesController } from "./types.js";
|
|
2
|
+
import { Layer } from "./Layer.js";
|
|
3
|
+
import { RegisterOptions, Router, RouterMethod, RouterOptions } from "./Router.js";
|
|
4
|
+
|
|
5
|
+
//#region src/EggRouter.d.ts
|
|
6
|
+
interface Application {
|
|
7
|
+
controller: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* FIXME: move these patch into @eggjs/router
|
|
11
|
+
*/
|
|
12
|
+
declare class EggRouter extends Router {
|
|
13
|
+
readonly app: Application;
|
|
14
|
+
/**
|
|
15
|
+
* @class
|
|
16
|
+
* @param {Object} opts - Router options.
|
|
17
|
+
* @param {Application} app - Application object.
|
|
18
|
+
*/
|
|
19
|
+
constructor(opts: RouterOptions, app: Application);
|
|
20
|
+
verb(method: RouterMethod | RouterMethod[], nameOrPath: string | RegExp | (string | RegExp)[], pathOrMiddleware: string | RegExp | (string | RegExp)[] | MiddlewareFunc, ...middleware: (MiddlewareFunc | string)[]): this;
|
|
21
|
+
head(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
22
|
+
head(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
23
|
+
options(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
24
|
+
options(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
25
|
+
get(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
26
|
+
get(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
27
|
+
put(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
28
|
+
put(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
29
|
+
patch(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
30
|
+
patch(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
31
|
+
post(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
32
|
+
post(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
33
|
+
delete(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
34
|
+
delete(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
35
|
+
all(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
36
|
+
all(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router;
|
|
37
|
+
register(path: string | RegExp | (string | RegExp)[], methods: string[], middleware: MiddlewareFunc | string | (MiddlewareFunc | string | ResourcesController)[], opts?: RegisterOptions): Layer | Layer[];
|
|
38
|
+
/**
|
|
39
|
+
* restful router api
|
|
40
|
+
* @param {String} name - Router name
|
|
41
|
+
* @param {String} prefix - url prefix
|
|
42
|
+
* @param {Function} middleware - middleware or controller
|
|
43
|
+
* @example
|
|
44
|
+
* ```js
|
|
45
|
+
* app.resources('/posts', 'posts')
|
|
46
|
+
* app.resources('posts', '/posts', 'posts')
|
|
47
|
+
* app.resources('posts', '/posts', app.role.can('user'), app.controller.posts)
|
|
48
|
+
* app.resources('posts', '/posts', middleware1, middleware2, app.controller.posts)
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* Examples:
|
|
52
|
+
*
|
|
53
|
+
* ```js
|
|
54
|
+
* app.resources('/posts', 'posts')
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* yield router mapping
|
|
58
|
+
*
|
|
59
|
+
* Method | Path | Route Name | Controller.Action
|
|
60
|
+
* -------|-----------------|----------------|-----------------------------
|
|
61
|
+
* GET | /posts | posts | app.controller.posts.index
|
|
62
|
+
* GET | /posts/new | new_post | app.controller.posts.new
|
|
63
|
+
* GET | /posts/:id | post | app.controller.posts.show
|
|
64
|
+
* GET | /posts/:id/edit | edit_post | app.controller.posts.edit
|
|
65
|
+
* POST | /posts | posts | app.controller.posts.create
|
|
66
|
+
* PATCH | /posts/:id | post | app.controller.posts.update
|
|
67
|
+
* DELETE | /posts/:id | post | app.controller.posts.destroy
|
|
68
|
+
*
|
|
69
|
+
* app.router.url can generate url based on arguments
|
|
70
|
+
* ```js
|
|
71
|
+
* app.router.url('posts')
|
|
72
|
+
* => /posts
|
|
73
|
+
* app.router.url('post', { id: 1 })
|
|
74
|
+
* => /posts/1
|
|
75
|
+
* app.router.url('new_post')
|
|
76
|
+
* => /posts/new
|
|
77
|
+
* app.router.url('edit_post', { id: 1 })
|
|
78
|
+
* => /posts/1/edit
|
|
79
|
+
* ```
|
|
80
|
+
* @return {Router} return route object.
|
|
81
|
+
* @since 1.0.0
|
|
82
|
+
*/
|
|
83
|
+
resources(prefix: string, controller: string | ResourcesController): Router;
|
|
84
|
+
resources(prefix: string, middleware: MiddlewareFunc, controller: string | ResourcesController): Router;
|
|
85
|
+
resources(name: string, prefix: string, controller: string | ResourcesController): Router;
|
|
86
|
+
resources(name: string, prefix: string, middleware: MiddlewareFunc, controller: string | ResourcesController): Router;
|
|
87
|
+
resources(nameOrPath: string | RegExp, ...middleware: (MiddlewareFunc | string | ResourcesController)[]): Router;
|
|
88
|
+
/**
|
|
89
|
+
* @param {String} name - Router name
|
|
90
|
+
* @param {Object} params - more parameters
|
|
91
|
+
* @example
|
|
92
|
+
* ```js
|
|
93
|
+
* router.url('edit_post', { id: 1, name: 'foo', page: 2 })
|
|
94
|
+
* => /posts/1/edit?name=foo&page=2
|
|
95
|
+
* router.url('posts', { name: 'foo&1', page: 2 })
|
|
96
|
+
* => /posts?name=foo%261&page=2
|
|
97
|
+
* ```
|
|
98
|
+
* @return {String} url by path name and query params.
|
|
99
|
+
* @since 1.0.0
|
|
100
|
+
*/
|
|
101
|
+
url(name: string, params?: Record<string, string | number | (string | number)[]>): string;
|
|
102
|
+
/**
|
|
103
|
+
* @alias to url()
|
|
104
|
+
*/
|
|
105
|
+
pathFor(name: string, params?: Record<string, string | number | (string | number)[]>): string;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { EggRouter };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { Router } from "./Router.js";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { encodeURIComponent } from "utility";
|
|
4
|
+
import inflection from "inflection";
|
|
5
|
+
import methods from "methods";
|
|
6
|
+
import { isGeneratorFunction } from "is-type-of";
|
|
7
|
+
|
|
8
|
+
//#region src/EggRouter.ts
|
|
9
|
+
const REST_MAP = {
|
|
10
|
+
index: {
|
|
11
|
+
suffix: "",
|
|
12
|
+
method: "GET"
|
|
13
|
+
},
|
|
14
|
+
new: {
|
|
15
|
+
namePrefix: "new_",
|
|
16
|
+
member: true,
|
|
17
|
+
suffix: "new",
|
|
18
|
+
method: "GET"
|
|
19
|
+
},
|
|
20
|
+
create: {
|
|
21
|
+
suffix: "",
|
|
22
|
+
method: "POST"
|
|
23
|
+
},
|
|
24
|
+
show: {
|
|
25
|
+
member: true,
|
|
26
|
+
suffix: ":id",
|
|
27
|
+
method: "GET"
|
|
28
|
+
},
|
|
29
|
+
edit: {
|
|
30
|
+
member: true,
|
|
31
|
+
namePrefix: "edit_",
|
|
32
|
+
suffix: ":id/edit",
|
|
33
|
+
method: "GET"
|
|
34
|
+
},
|
|
35
|
+
update: {
|
|
36
|
+
member: true,
|
|
37
|
+
namePrefix: "",
|
|
38
|
+
suffix: ":id",
|
|
39
|
+
method: ["PATCH", "PUT"]
|
|
40
|
+
},
|
|
41
|
+
destroy: {
|
|
42
|
+
member: true,
|
|
43
|
+
namePrefix: "destroy_",
|
|
44
|
+
suffix: ":id",
|
|
45
|
+
method: "DELETE"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* FIXME: move these patch into @eggjs/router
|
|
50
|
+
*/
|
|
51
|
+
var EggRouter = class extends Router {
|
|
52
|
+
app;
|
|
53
|
+
/**
|
|
54
|
+
* @class
|
|
55
|
+
* @param {Object} opts - Router options.
|
|
56
|
+
* @param {Application} app - Application object.
|
|
57
|
+
*/
|
|
58
|
+
constructor(opts, app) {
|
|
59
|
+
super(opts);
|
|
60
|
+
this.app = app;
|
|
61
|
+
}
|
|
62
|
+
verb(method, nameOrPath, pathOrMiddleware, ...middleware) {
|
|
63
|
+
const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware);
|
|
64
|
+
if (typeof method === "string") method = [method];
|
|
65
|
+
this.register(path, method, middlewares, options);
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
head(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
69
|
+
return this.verb("head", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
70
|
+
}
|
|
71
|
+
options(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
72
|
+
return this.verb("options", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
73
|
+
}
|
|
74
|
+
get(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
75
|
+
return this.verb("get", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
76
|
+
}
|
|
77
|
+
put(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
78
|
+
return this.verb("put", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
79
|
+
}
|
|
80
|
+
patch(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
81
|
+
return this.verb("patch", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
82
|
+
}
|
|
83
|
+
post(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
84
|
+
return this.verb("post", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
85
|
+
}
|
|
86
|
+
delete(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
87
|
+
return this.verb("delete", nameOrPath, pathOrMiddleware, ...middlewares);
|
|
88
|
+
}
|
|
89
|
+
all(nameOrPath, pathOrMiddleware, ...middlewares) {
|
|
90
|
+
return this.verb(methods, nameOrPath, pathOrMiddleware, ...middlewares);
|
|
91
|
+
}
|
|
92
|
+
register(path, methods$1, middleware, opts) {
|
|
93
|
+
middleware = Array.isArray(middleware) ? middleware : [middleware];
|
|
94
|
+
for (const mw of middleware) if (isGeneratorFunction(mw)) throw new TypeError(methods$1.toString() + " `" + path + "`: Please use async function instead of generator function");
|
|
95
|
+
const middlewares = convertMiddlewares(middleware, this.app);
|
|
96
|
+
return super.register(path, methods$1, middlewares, opts);
|
|
97
|
+
}
|
|
98
|
+
resources(nameOrPath, pathOrMiddleware, ...middleware) {
|
|
99
|
+
const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware);
|
|
100
|
+
const controller = resolveController(middlewares.pop(), this.app);
|
|
101
|
+
for (const key in REST_MAP) {
|
|
102
|
+
const action = controller[key];
|
|
103
|
+
if (!action) continue;
|
|
104
|
+
const opts = REST_MAP[key];
|
|
105
|
+
let routeName;
|
|
106
|
+
if (opts.member) routeName = inflection.singularize(options.name ?? "");
|
|
107
|
+
else routeName = inflection.pluralize(options.name ?? "");
|
|
108
|
+
if (opts.namePrefix) routeName = opts.namePrefix + routeName;
|
|
109
|
+
const prefix = path.replace(/\/$/, "");
|
|
110
|
+
const urlPath = opts.suffix ? `${prefix}/${opts.suffix}` : prefix;
|
|
111
|
+
const method = Array.isArray(opts.method) ? opts.method : [opts.method];
|
|
112
|
+
this.register(urlPath, method, middlewares.concat(action), { name: routeName });
|
|
113
|
+
}
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* @param {String} name - Router name
|
|
118
|
+
* @param {Object} params - more parameters
|
|
119
|
+
* @example
|
|
120
|
+
* ```js
|
|
121
|
+
* router.url('edit_post', { id: 1, name: 'foo', page: 2 })
|
|
122
|
+
* => /posts/1/edit?name=foo&page=2
|
|
123
|
+
* router.url('posts', { name: 'foo&1', page: 2 })
|
|
124
|
+
* => /posts?name=foo%261&page=2
|
|
125
|
+
* ```
|
|
126
|
+
* @return {String} url by path name and query params.
|
|
127
|
+
* @since 1.0.0
|
|
128
|
+
*/
|
|
129
|
+
url(name, params) {
|
|
130
|
+
const route = this.route(name);
|
|
131
|
+
if (!route) return "";
|
|
132
|
+
const args = params;
|
|
133
|
+
let url = route.path;
|
|
134
|
+
assert(!(url instanceof RegExp), `Can't get the url for regExp ${url} for by name '${name}'`);
|
|
135
|
+
const queries = [];
|
|
136
|
+
if (typeof args === "object" && args !== null) {
|
|
137
|
+
const replacedParams = [];
|
|
138
|
+
url = url.replace(/:([a-zA-Z_]\w*)/g, ($0, key) => {
|
|
139
|
+
if (key in args) {
|
|
140
|
+
const values = args[key];
|
|
141
|
+
replacedParams.push(key);
|
|
142
|
+
return encodeURIComponent(Array.isArray(values) ? String(values[0]) : String(values));
|
|
143
|
+
}
|
|
144
|
+
return $0;
|
|
145
|
+
});
|
|
146
|
+
for (const key in args) {
|
|
147
|
+
if (replacedParams.includes(key)) continue;
|
|
148
|
+
const values = args[key];
|
|
149
|
+
const encodedKey = encodeURIComponent(key);
|
|
150
|
+
if (Array.isArray(values)) for (const val of values) queries.push(`${encodedKey}=${encodeURIComponent(String(val))}`);
|
|
151
|
+
else queries.push(`${encodedKey}=${encodeURIComponent(String(values))}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (queries.length > 0) {
|
|
155
|
+
const queryStr = queries.join("&");
|
|
156
|
+
if (!url.includes("?")) url = `${url}?${queryStr}`;
|
|
157
|
+
else url = `${url}&${queryStr}`;
|
|
158
|
+
}
|
|
159
|
+
return url;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* @alias to url()
|
|
163
|
+
*/
|
|
164
|
+
pathFor(name, params) {
|
|
165
|
+
return this.url(name, params);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* resolve controller from string to function
|
|
170
|
+
* @param {String|Function} controller input controller
|
|
171
|
+
* @param {Application} app egg application instance
|
|
172
|
+
*/
|
|
173
|
+
function resolveController(controller, app) {
|
|
174
|
+
if (typeof controller === "string") {
|
|
175
|
+
const actions = controller.split(".");
|
|
176
|
+
let obj = app.controller;
|
|
177
|
+
actions.forEach((key) => {
|
|
178
|
+
obj = obj[key];
|
|
179
|
+
if (!obj) throw new Error(`app.controller.${controller} not exists`);
|
|
180
|
+
});
|
|
181
|
+
controller = obj;
|
|
182
|
+
}
|
|
183
|
+
if (!controller) throw new Error("controller not exists");
|
|
184
|
+
return controller;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 1. ensure controller(last argument) support string
|
|
188
|
+
* - [url, controller]: app.get('/home', 'home');
|
|
189
|
+
* - [name, url, controller(string)]: app.get('posts', '/posts', 'posts.list');
|
|
190
|
+
* - [name, url, controller]: app.get('posts', '/posts', app.controller.posts.list);
|
|
191
|
+
* - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index');
|
|
192
|
+
* - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');`
|
|
193
|
+
*
|
|
194
|
+
* 2. bind ctx to controller `this`
|
|
195
|
+
*
|
|
196
|
+
* @param {Array} middlewares middlewares and controller(last middleware)
|
|
197
|
+
* @param {Application} app egg application instance
|
|
198
|
+
*/
|
|
199
|
+
function convertMiddlewares(middlewares, app) {
|
|
200
|
+
const controller = resolveController(middlewares.pop(), app);
|
|
201
|
+
function wrappedController(ctx, next) {
|
|
202
|
+
return controller.apply(ctx, [ctx, next]);
|
|
203
|
+
}
|
|
204
|
+
return [...middlewares, wrappedController];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//#endregion
|
|
208
|
+
export { EggRouter };
|