@eggjs/router 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { Router } from './Router.js';
2
+
3
+ export * from './Router.js';
4
+ export * from './EggRouter.js';
5
+
6
+ export const KoaRouter = Router;
7
+ export default Router;
package/src/types.ts ADDED
@@ -0,0 +1,15 @@
1
+ export type Next = () => Promise<void>;
2
+ export type MiddlewareFunc = (ctx: any, next: Next) => Promise<void> | void;
3
+ export type MiddlewareFuncWithParamProperty = MiddlewareFunc & { param?: string };
4
+ export type ParamMiddlewareFunc = (param: string, ctx: any, next: Next) => Promise<void> | void;
5
+ export type MiddlewareFuncWithRouter<T> = MiddlewareFunc & { router: T };
6
+
7
+ export interface ResourcesController {
8
+ index?: MiddlewareFunc;
9
+ new?: MiddlewareFunc;
10
+ create?: MiddlewareFunc;
11
+ show?: MiddlewareFunc;
12
+ edit?: MiddlewareFunc;
13
+ update?: MiddlewareFunc;
14
+ destroy?: MiddlewareFunc;
15
+ }
package/History.md DELETED
@@ -1,181 +0,0 @@
1
-
2
- 2.0.0 / 2019-02-14
3
- ==================
4
-
5
- **features**
6
- * [[`f0b29ec`](https://github.com/eggjs/egg-router/commit/f0b29ec34df32ba9d872f6318f4febd2b4ef9359)] - refactor: use class instead prototype (#4) (fengmk2 <<fengmk2@gmail.com>>)
7
-
8
- 1.2.0 / 2019-02-13
9
- ==================
10
-
11
- **features**
12
- * [[`1a0036a`](http://github.com/eggjs/egg-router/commit/1a0036a64a023b6b7993fecffe8062d5d0150971)] - feat: add routerPath to respond to routerName (#2) (Khaidi Chu <<i@2333.moe>>)
13
-
14
- **others**
15
- * [[`ff723fd`](http://github.com/eggjs/egg-router/commit/ff723fd03630ec49d5fe861abf129a583d214d22)] - chore: add koa-router license (#3) (fengmk2 <<fengmk2@gmail.com>>)
16
-
17
- 1.1.0 / 2019-01-30
18
- ==================
19
-
20
- **features**
21
- * [[`b318dd5`](http://github.com/eggjs/egg-router/commit/b318dd5ff2eea60013ed62b2a435f803c12bf20f)] - feat: add egg-router (dead-horse <<dead_horse@qq.com>>)
22
-
23
- **fixes**
24
- * [[`b3db7b4`](http://github.com/eggjs/egg-router/commit/b3db7b41988d3bf1b4e885ed76b3a8165c1d3b1d)] - fix: add missing dependencies koa-convert (dead-horse <<dead_horse@qq.com>>)
25
- * [[`c280336`](http://github.com/eggjs/egg-router/commit/c2803368a8256bc9504ae3c821eefeb9d1fcbc4d)] - fix: only support node@8 (dead-horse <<dead_horse@qq.com>>)
26
- * [[`7a887a2`](http://github.com/eggjs/egg-router/commit/7a887a252445e602c2ea7e1c6f4cde52a433644d)] - fix: update license (dead-horse <<dead_horse@qq.com>>)
27
-
28
- **others**
29
- * [[`ae40168`](http://github.com/eggjs/egg-router/commit/ae4016862fb8bdaf30e730a9278fbb1455d8b75d)] - docs: clean doc (dead-horse <<dead_horse@qq.com>>)
30
- * [[`e4f21a8`](http://github.com/eggjs/egg-router/commit/e4f21a8ed6dfd72c4d6f4a13bbda9a4e90b0401c)] - chore: fix history (dead-horse <<dead_horse@qq.com>>)
31
-
32
- 1.0.0 / 2019-01-30
33
- ==================
34
-
35
- **others**
36
- * [[`d6496e0`](http://github.com/eggjs/egg-router/commit/d6496e09be6b0f91dcb96611f31ec5ab6ad8ac78)] - refactor: rename to @eggjs/router (dead-horse <<dead_horse@qq.com>>)
37
-
38
- -------------------------------
39
-
40
- # Release History from koa-router
41
-
42
- ## 7.4.0
43
-
44
- - Fix router.url() for multiple nested routers [#407](https://github.com/alexmingoia/koa-router/pull/407)
45
- - `layer.name` added to `ctx` at `ctx.routerName` during routing [#412](https://github.com/alexmingoia/koa-router/pull/412)
46
- - Router.use() was erroneously settings `(.*)` as a prefix to all routers nested with .use that did not pass an explicit prefix string as the first argument. This resulted in routes being matched that should not have been, included the running of multiple route handlers in error. [#369](https://github.com/alexmingoia/koa-router/issues/369) and [#410](https://github.com/alexmingoia/koa-router/issues/410) include information on this issue.
47
-
48
- ## 7.3.0
49
-
50
- - Router#url() now accepts query parameters to add to generated urls [#396](https://github.com/alexmingoia/koa-router/pull/396)
51
-
52
- ## 7.2.1
53
-
54
- - Respond to CORS preflights with 200, 0 length body [#359](https://github.com/alexmingoia/koa-router/issues/359)
55
-
56
- ## 7.2.0
57
-
58
- - Fix a bug in Router#url and append Router object to ctx. [#350](https://github.com/alexmingoia/koa-router/pull/350)
59
- - Adds `_matchedRouteName` to context [#337](https://github.com/alexmingoia/koa-router/pull/337)
60
- - Respond to CORS preflights with 200, 0 length body [#359](https://github.com/alexmingoia/koa-router/issues/359)
61
-
62
- ## 7.1.1
63
-
64
- - Fix bug where param handlers were run out of order [#282](https://github.com/alexmingoia/koa-router/pull/282)
65
-
66
- ## 7.1.0
67
-
68
- - Backports: merge 5.4 work into the 7.x upstream. See 5.4.0 updates for more details.
69
-
70
- ## 7.0.1
71
-
72
- - Fix: allowedMethods should be ctx.method not this.method [#215](https://github.com/alexmingoia/koa-router/pull/215)
73
-
74
- ## 7.0.0
75
-
76
- - The API has changed to match the new promise-based middleware
77
- signature of koa 2. See the
78
- [koa 2.x readme](https://github.com/koajs/koa/tree/2.0.0-alpha.3) for more
79
- information.
80
- - Middleware is now always run in the order declared by `.use()` (or `.get()`,
81
- etc.), which matches Express 4 API.
82
-
83
- ## 5.4.0
84
-
85
- - Expose matched route at `ctx._matchedRoute`.
86
-
87
- ## 5.3.0
88
-
89
- - Register multiple routes with array of paths [#203](https://github.com/alexmingoia/koa-router/issue/143).
90
- - Improved router.url() [#143](https://github.com/alexmingoia/koa-router/pull/143)
91
- - Adds support for named routes and regular expressions
92
- [#152](https://github.com/alexmingoia/koa-router/pull/152)
93
- - Add support for custom throw functions for 405 and 501 responses [#206](https://github.com/alexmingoia/koa-router/pull/206)
94
-
95
- ## 5.2.3
96
-
97
- - Fix for middleware running twice when nesting routes [#184](https://github.com/alexmingoia/koa-router/issues/184)
98
-
99
- ## 5.2.2
100
-
101
- - Register routes without params before those with params [#183](https://github.com/alexmingoia/koa-router/pull/183)
102
- - Fix for allowed methods [#182](https://github.com/alexmingoia/koa-router/issues/182)
103
-
104
- ## 5.2.0
105
-
106
- - Add support for async/await. Resolves [#130](https://github.com/alexmingoia/koa-router/issues/130).
107
- - Add support for array of paths by Router#use(). Resolves [#175](https://github.com/alexmingoia/koa-router/issues/175).
108
- - Inherit param middleware when nesting routers. Fixes [#170](https://github.com/alexmingoia/koa-router/issues/170).
109
- - Default router middleware without path to root. Fixes [#161](https://github.com/alexmingoia/koa-router/issues/161), [#155](https://github.com/alexmingoia/koa-router/issues/155), [#156](https://github.com/alexmingoia/koa-router/issues/156).
110
- - Run nested router middleware after parent's. Fixes [#156](https://github.com/alexmingoia/koa-router/issues/156).
111
- - Remove dependency on koa-compose.
112
-
113
- ## 5.1.1
114
-
115
- - Match routes in order they were defined. Fixes #131.
116
-
117
- ## 5.1.0
118
-
119
- - Support mounting router middleware at a given path.
120
-
121
- ## 5.0.1
122
-
123
- - Fix bug with missing parameters when nesting routers.
124
-
125
- ## 5.0.0
126
-
127
- - Remove confusing API for extending koa app with router methods. Router#use()
128
- does not have the same behavior as app#use().
129
- - Add support for nesting routes.
130
- - Remove support for regular expression routes to achieve nestable routers and
131
- enable future trie-based routing optimizations.
132
-
133
- ## 4.3.2
134
-
135
- - Do not send 405 if route matched but status is 404. Fixes #112, closes #114.
136
-
137
- ## 4.3.1
138
-
139
- - Do not run middleware if not yielded to by previous middleware. Fixes #115.
140
-
141
- ## 4.3.0
142
-
143
- - Add support for router prefixes.
144
- - Add MIT license.
145
-
146
- ## 4.2.0
147
-
148
- - Fixed issue with router middleware being applied even if no route was
149
- matched.
150
- - Router.url - new static method to generate url from url pattern and data
151
-
152
- ## 4.1.0
153
-
154
- Private API changed to separate context parameter decoration from route
155
- matching. `Router#match` and `Route#match` are now pure functions that return
156
- an array of routes that match the URL path.
157
-
158
- For modules using this private API that need to determine if a method and path
159
- match a route, `route.methods` must be checked against the routes returned from
160
- `router.match()`:
161
-
162
- ```javascript
163
- var matchedRoute = router.match(path).filter(function (route) {
164
- return ~route.methods.indexOf(method);
165
- }).shift();
166
- ```
167
-
168
- ## 4.0.0
169
-
170
- 405, 501, and OPTIONS response handling was moved into separate middleware
171
- `router.allowedMethods()`. This resolves incorrect 501 or 405 responses when
172
- using multiple routers.
173
-
174
- ### Breaking changes
175
-
176
- 4.x is mostly backwards compatible with 3.x, except for the following:
177
-
178
- - Instantiating a router with `new` and `app` returns the router instance,
179
- whereas 3.x returns the router middleware. When creating a router in 4.x, the
180
- only time router middleware is returned is when creating using the
181
- `Router(app)` signature (with `app` and without `new`).
package/index.js DELETED
@@ -1,10 +0,0 @@
1
- 'use strict';
2
-
3
- const KoaRouter = require('./lib/router');
4
- const EggRouter = require('./lib/egg_router');
5
-
6
- // for compact
7
- module.exports = KoaRouter;
8
- module.exports.KoaRouter = KoaRouter;
9
- module.exports.EggRouter = EggRouter;
10
-
package/lib/egg_router.js DELETED
@@ -1,327 +0,0 @@
1
- 'use strict';
2
-
3
- const is = require('is-type-of');
4
- const Router = require('./router');
5
- const utility = require('utility');
6
- const inflection = require('inflection');
7
- const assert = require('assert');
8
- const utils = require('./utils');
9
-
10
- const METHODS = [ 'head', 'options', 'get', 'put', 'patch', 'post', 'delete' ];
11
-
12
- const REST_MAP = {
13
- index: {
14
- suffix: '',
15
- method: 'GET',
16
- },
17
- new: {
18
- namePrefix: 'new_',
19
- member: true,
20
- suffix: 'new',
21
- method: 'GET',
22
- },
23
- create: {
24
- suffix: '',
25
- method: 'POST',
26
- },
27
- show: {
28
- member: true,
29
- suffix: ':id',
30
- method: 'GET',
31
- },
32
- edit: {
33
- member: true,
34
- namePrefix: 'edit_',
35
- suffix: ':id/edit',
36
- method: 'GET',
37
- },
38
- update: {
39
- member: true,
40
- namePrefix: '',
41
- suffix: ':id',
42
- method: [ 'PATCH', 'PUT' ],
43
- },
44
- destroy: {
45
- member: true,
46
- namePrefix: 'destroy_',
47
- suffix: ':id',
48
- method: 'DELETE',
49
- },
50
- };
51
-
52
- /**
53
- * FIXME: move these patch into @eggjs/router
54
- */
55
- class EggRouter extends Router {
56
-
57
- /**
58
- * @constructor
59
- * @param {Object} opts - Router options.
60
- * @param {Application} app - Application object.
61
- */
62
- constructor(opts, app) {
63
- super(opts);
64
- this.app = app;
65
- this.patchRouterMethod();
66
- }
67
-
68
- patchRouterMethod() {
69
- // patch router methods to support generator function middleware and string controller
70
- METHODS.concat([ 'all' ]).forEach(method => {
71
- this[method] = (...args) => {
72
- const splited = spliteAndResolveRouterParams({ args, app: this.app });
73
- // format and rebuild params
74
- args = splited.prefix.concat(splited.middlewares);
75
- return super[method](...args);
76
- };
77
- });
78
- }
79
-
80
- /**
81
- * Create and register a route.
82
- * @param {String} path - url path
83
- * @param {Array} methods - Array of HTTP verbs
84
- * @param {Array} middlewares -
85
- * @param {Object} opts -
86
- * @return {Route} this
87
- */
88
- register(path, methods, middlewares, opts) {
89
- // patch register to support generator function middleware and string controller
90
- middlewares = Array.isArray(middlewares) ? middlewares : [ middlewares ];
91
- middlewares = convertMiddlewares(middlewares, this.app);
92
- path = Array.isArray(path) ? path : [ path ];
93
- path.forEach(p => super.register(p, methods, middlewares, opts));
94
- return this;
95
- }
96
-
97
- /**
98
- * restful router api
99
- * @param {String} name - Router name
100
- * @param {String} prefix - url prefix
101
- * @param {Function} middleware - middleware or controller
102
- * @example
103
- * ```js
104
- * app.resources('/posts', 'posts')
105
- * app.resources('posts', '/posts', 'posts')
106
- * app.resources('posts', '/posts', app.role.can('user'), app.controller.posts)
107
- * ```
108
- *
109
- * Examples:
110
- *
111
- * ```js
112
- * app.resources('/posts', 'posts')
113
- * ```
114
- *
115
- * yield router mapping
116
- *
117
- * Method | Path | Route Name | Controller.Action
118
- * -------|-----------------|----------------|-----------------------------
119
- * GET | /posts | posts | app.controller.posts.index
120
- * GET | /posts/new | new_post | app.controller.posts.new
121
- * GET | /posts/:id | post | app.controller.posts.show
122
- * GET | /posts/:id/edit | edit_post | app.controller.posts.edit
123
- * POST | /posts | posts | app.controller.posts.create
124
- * PATCH | /posts/:id | post | app.controller.posts.update
125
- * DELETE | /posts/:id | post | app.controller.posts.destroy
126
- *
127
- * app.router.url can generate url based on arguments
128
- * ```js
129
- * app.router.url('posts')
130
- * => /posts
131
- * app.router.url('post', { id: 1 })
132
- * => /posts/1
133
- * app.router.url('new_post')
134
- * => /posts/new
135
- * app.router.url('edit_post', { id: 1 })
136
- * => /posts/1/edit
137
- * ```
138
- * @return {Router} return route object.
139
- * @since 1.0.0
140
- */
141
- resources(...args) {
142
- const splited = spliteAndResolveRouterParams({ args, app: this.app });
143
- const middlewares = splited.middlewares;
144
- // last argument is Controller object
145
- const controller = splited.middlewares.pop();
146
-
147
- let name = '';
148
- let prefix = '';
149
- if (splited.prefix.length === 2) {
150
- // router.get('users', '/users')
151
- name = splited.prefix[0];
152
- prefix = splited.prefix[1];
153
- } else {
154
- // router.get('/users')
155
- prefix = splited.prefix[0];
156
- }
157
-
158
- for (const key in REST_MAP) {
159
- const action = controller[key];
160
- if (!action) continue;
161
-
162
- const opts = REST_MAP[key];
163
- let formatedName;
164
- if (opts.member) {
165
- formatedName = inflection.singularize(name);
166
- } else {
167
- formatedName = inflection.pluralize(name);
168
- }
169
- if (opts.namePrefix) {
170
- formatedName = opts.namePrefix + formatedName;
171
- }
172
- prefix = prefix.replace(/\/$/, '');
173
- const path = opts.suffix ? `${prefix}/${opts.suffix}` : prefix;
174
- const method = Array.isArray(opts.method) ? opts.method : [ opts.method ];
175
- this.register(path, method, middlewares.concat(action), { name: formatedName });
176
- }
177
-
178
- return this;
179
- }
180
-
181
- /**
182
- * @param {String} name - Router name
183
- * @param {Object} params - more parameters
184
- * @example
185
- * ```js
186
- * router.url('edit_post', { id: 1, name: 'foo', page: 2 })
187
- * => /posts/1/edit?name=foo&page=2
188
- * router.url('posts', { name: 'foo&1', page: 2 })
189
- * => /posts?name=foo%261&page=2
190
- * ```
191
- * @return {String} url by path name and query params.
192
- * @since 1.0.0
193
- */
194
- url(name, params) {
195
- const route = this.route(name);
196
- if (!route) return '';
197
-
198
- const args = params;
199
- let url = route.path;
200
-
201
- assert(!is.regExp(url), `Can't get the url for regExp ${url} for by name '${name}'`);
202
-
203
- const queries = [];
204
- if (typeof args === 'object' && args !== null) {
205
- const replacedParams = [];
206
- url = url.replace(/:([a-zA-Z_]\w*)/g, function($0, key) {
207
- if (utility.has(args, key)) {
208
- const values = args[key];
209
- replacedParams.push(key);
210
- return utility.encodeURIComponent(Array.isArray(values) ? values[0] : values);
211
- }
212
- return $0;
213
- });
214
-
215
- for (const key in args) {
216
- if (replacedParams.includes(key)) {
217
- continue;
218
- }
219
-
220
- const values = args[key];
221
- const encodedKey = utility.encodeURIComponent(key);
222
- if (Array.isArray(values)) {
223
- for (const val of values) {
224
- queries.push(`${encodedKey}=${utility.encodeURIComponent(val)}`);
225
- }
226
- } else {
227
- queries.push(`${encodedKey}=${utility.encodeURIComponent(values)}`);
228
- }
229
- }
230
- }
231
-
232
- if (queries.length > 0) {
233
- const queryStr = queries.join('&');
234
- if (!url.includes('?')) {
235
- url = `${url}?${queryStr}`;
236
- } else {
237
- url = `${url}&${queryStr}`;
238
- }
239
- }
240
-
241
- return url;
242
- }
243
-
244
- pathFor(name, params) {
245
- return this.url(name, params);
246
- }
247
- }
248
-
249
- /**
250
- * 1. split (name, url, ...middleware, controller) to
251
- * {
252
- * prefix: [name, url]
253
- * middlewares [...middleware, controller]
254
- * }
255
- *
256
- * 2. resolve controller from string to function
257
- *
258
- * @param {Object} options inputs
259
- * @param {Object} options.args router params
260
- * @param {Object} options.app egg application instance
261
- * @return {Object} prefix and middlewares
262
- */
263
- function spliteAndResolveRouterParams({ args, app }) {
264
- let prefix;
265
- let middlewares;
266
- if (args.length >= 3 && (is.string(args[1]) || is.regExp(args[1]))) {
267
- // app.get(name, url, [...middleware], controller)
268
- prefix = args.slice(0, 2);
269
- middlewares = args.slice(2);
270
- } else {
271
- // app.get(url, [...middleware], controller)
272
- prefix = args.slice(0, 1);
273
- middlewares = args.slice(1);
274
- }
275
- // resolve controller
276
- const controller = middlewares.pop();
277
- middlewares.push(resolveController(controller, app));
278
- return { prefix, middlewares };
279
- }
280
-
281
- /**
282
- * resolve controller from string to function
283
- * @param {String|Function} controller input controller
284
- * @param {Application} app egg application instance
285
- * @return {Function} controller function
286
- */
287
- function resolveController(controller, app) {
288
- if (is.string(controller)) {
289
- const actions = controller.split('.');
290
- let obj = app.controller;
291
- actions.forEach(key => {
292
- obj = obj[key];
293
- if (!obj) throw new Error(`controller '${controller}' not exists`);
294
- });
295
- controller = obj;
296
- }
297
- // ensure controller is exists
298
- if (!controller) throw new Error('controller not exists');
299
- return controller;
300
- }
301
-
302
- /**
303
- * 1. ensure controller(last argument) support string
304
- * - [url, controller]: app.get('/home', 'home');
305
- * - [name, url, controller(string)]: app.get('posts', '/posts', 'posts.list');
306
- * - [name, url, controller]: app.get('posts', '/posts', app.controller.posts.list);
307
- * - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index');
308
- * - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');`
309
- *
310
- * 2. make middleware support generator function
311
- *
312
- * @param {Array} middlewares middlewares and controller(last middleware)
313
- * @param {Application} app egg application instance
314
- * @return {Array} middlewares
315
- */
316
- function convertMiddlewares(middlewares, app) {
317
- // ensure controller is resolved
318
- const controller = resolveController(middlewares.pop(), app);
319
- // make middleware support generator function
320
- middlewares = middlewares.map(utils.middleware);
321
- const wrappedController = (ctx, next) => {
322
- return utils.callFn(controller, [ ctx, next ], ctx);
323
- };
324
- return middlewares.concat([ wrappedController ]);
325
- }
326
-
327
- module.exports = EggRouter;