@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 CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  [![NPM version](https://img.shields.io/npm/v/@eggjs/router.svg?style=flat-square)](https://npmjs.org/package/@eggjs/router)
4
4
  [![NPM download](https://img.shields.io/npm/dm/@eggjs/router.svg?style=flat-square)](https://npmjs.org/package/@eggjs/router)
5
- [![Node.js CI](https://github.com/eggjs/egg-router/actions/workflows/nodejs.yml/badge.svg?branch=master)](https://github.com/eggjs/egg-router/actions/workflows/nodejs.yml)
6
- [![Test coverage](https://img.shields.io/codecov/c/github/eggjs/egg-router.svg?style=flat-square)](https://codecov.io/gh/eggjs/egg-router)
7
5
  [![Known Vulnerabilities](https://snyk.io/test/npm/@eggjs/router/badge.svg?style=flat-square)](https://snyk.io/test/npm/@eggjs/router)
6
+ [![Node.js Version](https://img.shields.io/node/v/@eggjs/router.svg?style=flat)](https://nodejs.org/en/download/)
7
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com)
8
+ ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/eggjs/router)
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 | Type | Description |
52
- | --- | --- | --- |
53
- | [opts] | <code>Object</code> | |
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 *verb* is one of the HTTP verbs such
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 | Type | Description |
194
- | --- | --- | --- |
195
- | path | <code>String</code> | |
192
+ | Param | Type | Description |
193
+ | ------------ | --------------------- | ------------------- |
194
+ | path | <code>String</code> | |
196
195
  | [middleware] | <code>function</code> | route middleware(s) |
197
- | callback | <code>function</code> | route 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 | Type |
218
- | --- | --- |
219
- | [path] | <code>String</code> |
217
+ | Param | Type |
218
+ | ---------- | --------------------- |
219
+ | [path] | <code>String</code> |
220
220
  | middleware | <code>function</code> |
221
- | [...] | <code>function</code> |
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 | Type |
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 | Type | Description |
269
- | --- | --- | --- |
270
- | [options] | <code>Object</code> | |
271
- | [options.throw] | <code>Boolean</code> | throw error instead of setting status and header |
272
- | [options.notImplemented] | <code>function</code> | throw the returned value in place of the default NotImplemented error |
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(router.allowedMethods({
300
- throw: true,
301
- notImplemented: () => new Boom.notImplemented(),
302
- methodNotAllowed: () => new Boom.methodNotAllowed()
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 | 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). |
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 | <code>String</code> |
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 | 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> &#124; <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> &#124; <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: "limit=1" });
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 | Type |
397
- | --- | --- |
398
- | param | <code>String</code> |
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
- // /users/3 => {"id": 3, "name": "Alex"}
419
- // /users/3/friends => [{"id": 4, "name": "TJ"}]
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 | 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> &#124; <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> &#124; <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
- |[<img src="https://avatars.githubusercontent.com/u/1112718?v=4" width="100px;"/><br/><sub><b>alexmingoia</b></sub>](https://github.com/alexmingoia)<br/>|[<img src="https://avatars.githubusercontent.com/u/1413330?v=4" width="100px;"/><br/><sub><b>jbielick</b></sub>](https://github.com/jbielick)<br/>|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/1024246?v=4" width="100px;"/><br/><sub><b>wachunei</b></sub>](https://github.com/wachunei)<br/>|[<img src="https://avatars.githubusercontent.com/u/160197?v=4" width="100px;"/><br/><sub><b>dominicbarnes</b></sub>](https://github.com/dominicbarnes)<br/>|
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
+ [![Contributors](https://contrib.rocks/image?repo=eggjs/egg)](https://github.com/eggjs/egg/graphs/contributors)
475
463
 
476
- <!-- GITCONTRIBUTOR_END -->
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 };