@koa/router 14.0.0 → 15.1.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@koa/router",
3
3
  "description": "Router middleware for koa. Maintained by Forward Email and Lad.",
4
- "version": "14.0.0",
4
+ "version": "15.1.0",
5
5
  "author": "Alex Mingoia <talk@alexmingoia.com>",
6
6
  "bugs": {
7
7
  "url": "https://github.com/koajs/router/issues",
@@ -20,35 +20,69 @@
20
20
  "email": "imed-jaberi@outlook.com"
21
21
  }
22
22
  ],
23
+ "peerDependencies": {
24
+ "koa": "^2.0.0 || ^3.0.0"
25
+ },
26
+ "peerDependenciesMeta": {
27
+ "koa": {
28
+ "optional": false
29
+ }
30
+ },
23
31
  "dependencies": {
24
- "debug": "^4.4.1",
25
- "http-errors": "^2.0.0",
32
+ "debug": "^4.4.3",
33
+ "http-errors": "^2.0.1",
26
34
  "koa-compose": "^4.1.0",
27
- "path-to-regexp": "^8.2.0"
35
+ "path-to-regexp": "^8.3.0"
28
36
  },
29
37
  "devDependencies": {
30
- "@commitlint/cli": "^17.7.2",
31
- "@commitlint/config-conventional": "^17.7.0",
32
- "@ladjs/env": "^4.0.0",
38
+ "@commitlint/cli": "^20.2.0",
39
+ "@commitlint/config-conventional": "^20.2.0",
40
+ "@koa/bodyparser": "^6.0.0",
41
+ "@types/debug": "^4.1.12",
42
+ "@types/jsonwebtoken": "^9.0.7",
43
+ "@types/koa": "^3.0.1",
44
+ "@types/node": "^25.0.1",
45
+ "@types/supertest": "^6.0.3",
46
+ "@typescript-eslint/eslint-plugin": "^8.49.0",
47
+ "@typescript-eslint/parser": "^8.49.0",
48
+ "c8": "^10.1.3",
33
49
  "chalk": "^5.4.1",
34
- "eslint": "^9.32.0",
35
- "eslint-plugin-unicorn": "^60.0.0",
36
- "fixpack": "^4.0.0",
50
+ "eslint": "^9.39.1",
51
+ "eslint-plugin-unicorn": "^62.0.0",
37
52
  "husky": "^9.1.7",
38
- "jsdoc-to-markdown": "^8.0.0",
39
- "koa": "^3.0.1",
40
- "lint-staged": "^14.0.1",
41
- "mocha": "^11.7.1",
42
- "nyc": "^17.0.0",
43
- "remark-cli": "11",
44
- "remark-preset-github": "^4.0.4",
45
- "supertest": "^7.0.0"
53
+ "joi": "^18.0.2",
54
+ "jsonwebtoken": "^9.0.3",
55
+ "koa": "^3.1.1",
56
+ "lint-staged": "^16.2.7",
57
+ "prettier": "^3.7.4",
58
+ "rimraf": "^6.1.2",
59
+ "supertest": "^7.1.4",
60
+ "ts-node": "^10.9.2",
61
+ "tsup": "^8.5.1",
62
+ "typescript": "^5.9.3"
46
63
  },
47
64
  "engines": {
48
65
  "node": ">= 20"
49
66
  },
67
+ "main": "./dist/index.js",
68
+ "module": "./dist/index.mjs",
69
+ "types": "./dist/index.d.ts",
70
+ "exports": {
71
+ ".": {
72
+ "import": {
73
+ "types": "./dist/index.d.mts",
74
+ "import": "./dist/index.mjs"
75
+ },
76
+ "require": {
77
+ "types": "./dist/index.d.ts",
78
+ "require": "./dist/index.js"
79
+ }
80
+ }
81
+ },
50
82
  "files": [
51
- "lib"
83
+ "dist",
84
+ "LICENSE",
85
+ "README.md"
52
86
  ],
53
87
  "homepage": "https://github.com/koajs/router",
54
88
  "keywords": [
@@ -58,20 +92,29 @@
58
92
  "router"
59
93
  ],
60
94
  "license": "MIT",
61
- "main": "lib/router.js",
62
95
  "repository": {
63
96
  "type": "git",
64
97
  "url": "git+https://github.com/koajs/router.git"
65
98
  },
66
99
  "scripts": {
67
- "bench": "make -C bench",
68
- "benchmark": "node bench/run.js",
69
- "coverage": "nyc npm run test",
70
- "docs": "NODE_ENV=test jsdoc2md -t ./lib/API_tpl.hbs --src ./lib/*.js >| API.md",
71
- "lint": "eslint . --fix && remark . -qfo && fixpack",
100
+ "bench": "TS_NODE_PROJECT=tsconfig.bench.json node --require ts-node/register bench/run.ts",
101
+ "benchmark": "npm run bench",
102
+ "bench:all": "TS_NODE_PROJECT=tsconfig.bench.json node --require ts-node/register bench/make.ts",
103
+ "benchmark:all": "npm run bench:all",
72
104
  "prepare": "husky install",
73
- "pretest": "npm run lint",
74
- "test": "mocha test/**/*.js",
75
- "test:watch": "mocha test/**/*.js --watch"
105
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
106
+ "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
107
+ "lint:ts": "eslint src test --ext .ts,.tsx --fix",
108
+ "lint": "npm run lint:ts",
109
+ "test:core": "TS_NODE_PROJECT=tsconfig.ts-node.json node --require ts-node/register --test test/*.test.ts test/**/*.test.ts",
110
+ "test:recipes": "TS_NODE_PROJECT=tsconfig.recipes.json node --require ts-node/register --test recipes/**/*.test.ts",
111
+ "pretest:all": "npm run lint",
112
+ "test:all": "TS_NODE_PROJECT=tsconfig.ts-node.json node --require ts-node/register --test test/*.test.ts test/**/*.test.ts recipes/**/*.test.ts",
113
+ "test:coverage": "c8 npm run test:all",
114
+ "ts:check": "tsc --noEmit --project tsconfig.typecheck.json",
115
+ "ts:check:test": "tsc --noEmit --project tsconfig.test.json",
116
+ "prebuild": "rimraf dist",
117
+ "build": "tsup",
118
+ "prepublishOnly": "npm run build"
76
119
  }
77
120
  }
package/HISTORY.md DELETED
@@ -1,187 +0,0 @@
1
- # History
2
-
3
- **[History has moved to the Releases tab of GitHub](https://github.com/koajs/router/releases).**
4
-
5
-
6
- ## Log
7
-
8
-
9
- ## 9.0.0 / 2020-04-09
10
-
11
- * Update `path-to-regexp`. Migration path: change usage of `'*'` in routes to `(.*)` or `:splat*`.
12
- * Example: `router.get('*', ....)` becomes `router.get('(.*)') ....)`
13
-
14
-
15
- ## 8.0.0 / 2019-06-16
16
-
17
- **others**
18
-
19
- * [b5dd5e8](http://github.com/koajs/koa-router/commit/b5dd5e8f00e841b7061a62ab6228cbe96a999470)] - chore: rename to @koa/router (dead-horse)
20
-
21
- ---
22
-
23
- Changelogs inherit from koa-router.
24
-
25
-
26
- ## 7.4.0
27
-
28
- * Fix router.url() for multiple nested routers [#407](https://github.com/alexmingoia/koa-router/pull/407)
29
- * `layer.name` added to `ctx` at `ctx.routerName` during routing [#412](https://github.com/alexmingoia/koa-router/pull/412)
30
- * 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.
31
-
32
-
33
- ## 7.3.0
34
-
35
- * Router#url() now accepts query parameters to add to generated urls [#396](https://github.com/alexmingoia/koa-router/pull/396)
36
-
37
-
38
- ## 7.2.1
39
-
40
- * Respond to CORS preflights with 200, 0 length body [#359](https://github.com/alexmingoia/koa-router/issues/359)
41
-
42
-
43
- ## 7.2.0
44
-
45
- * Fix a bug in Router#url and append Router object to ctx. [#350](https://github.com/alexmingoia/koa-router/pull/350)
46
- * Adds `_matchedRouteName` to context [#337](https://github.com/alexmingoia/koa-router/pull/337)
47
- * Respond to CORS preflights with 200, 0 length body [#359](https://github.com/alexmingoia/koa-router/issues/359)
48
-
49
-
50
- ## 7.1.1
51
-
52
- * Fix bug where param handlers were run out of order [#282](https://github.com/alexmingoia/koa-router/pull/282)
53
-
54
-
55
- ## 7.1.0
56
-
57
- * Backports: merge 5.4 work into the 7.x upstream. See 5.4.0 updates for more details.
58
-
59
-
60
- ## 7.0.1
61
-
62
- * Fix: allowedMethods should be ctx.method not this.method [#215](https://github.com/alexmingoia/koa-router/pull/215)
63
-
64
-
65
- ## 7.0.0
66
-
67
- * The API has changed to match the new promise-based middleware
68
- signature of koa 2. See the
69
- [koa 2.x readme](https://github.com/koajs/koa/tree/2.0.0-alpha.3) for more
70
- information.
71
- * Middleware is now always run in the order declared by `.use()` (or `.get()`,
72
- etc.), which matches Express 4 API.
73
-
74
-
75
- ## 5.4.0
76
-
77
- * Expose matched route at `ctx._matchedRoute`.
78
-
79
-
80
- ## 5.3.0
81
-
82
- * Register multiple routes with array of paths [#203](https://github.com/alexmingoia/koa-router/issue/143).
83
- * Improved router.url() [#143](https://github.com/alexmingoia/koa-router/pull/143)
84
- * Adds support for named routes and regular expressions
85
- [#152](https://github.com/alexmingoia/koa-router/pull/152)
86
- * Add support for custom throw functions for 405 and 501 responses [#206](https://github.com/alexmingoia/koa-router/pull/206)
87
-
88
-
89
- ## 5.2.3
90
-
91
- * Fix for middleware running twice when nesting routes [#184](https://github.com/alexmingoia/koa-router/issues/184)
92
-
93
-
94
- ## 5.2.2
95
-
96
- * Register routes without params before those with params [#183](https://github.com/alexmingoia/koa-router/pull/183)
97
- * Fix for allowed methods [#182](https://github.com/alexmingoia/koa-router/issues/182)
98
-
99
-
100
- ## 5.2.0
101
-
102
- * Add support for async/await. Resolves [#130](https://github.com/alexmingoia/koa-router/issues/130).
103
- * Add support for array of paths by Router#use(). Resolves [#175](https://github.com/alexmingoia/koa-router/issues/175).
104
- * Inherit param middleware when nesting routers. Fixes [#170](https://github.com/alexmingoia/koa-router/issues/170).
105
- * 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).
106
- * Run nested router middleware after parent's. Fixes [#156](https://github.com/alexmingoia/koa-router/issues/156).
107
- * Remove dependency on koa-compose.
108
-
109
-
110
- ## 5.1.1
111
-
112
- * Match routes in order they were defined. Fixes #131.
113
-
114
-
115
- ## 5.1.0
116
-
117
- * Support mounting router middleware at a given path.
118
-
119
-
120
- ## 5.0.1
121
-
122
- * Fix bug with missing parameters when nesting routers.
123
-
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
-
134
- ## 4.3.2
135
-
136
- * Do not send 405 if route matched but status is 404. Fixes #112, closes #114.
137
-
138
-
139
- ## 4.3.1
140
-
141
- * Do not run middleware if not yielded to by previous middleware. Fixes #115.
142
-
143
-
144
- ## 4.3.0
145
-
146
- * Add support for router prefixes.
147
- * Add MIT license.
148
-
149
-
150
- ## 4.2.0
151
-
152
- * Fixed issue with router middleware being applied even if no route was
153
- matched.
154
- * Router.url - new static method to generate url from url pattern and data
155
-
156
-
157
- ## 4.1.0
158
-
159
- Private API changed to separate context parameter decoration from route
160
- matching. `Router#match` and `Route#match` are now pure functions that return
161
- an array of routes that match the URL path.
162
-
163
- For modules using this private API that need to determine if a method and path
164
- match a route, `route.methods` must be checked against the routes returned from
165
- `router.match()`:
166
-
167
- ```javascript
168
- var matchedRoute = router.match(path).filter(function (route) {
169
- return ~route.methods.indexOf(method);
170
- }).shift();
171
- ```
172
-
173
-
174
- ## 4.0.0
175
-
176
- 405, 501, and OPTIONS response handling was moved into separate middleware
177
- `router.allowedMethods()`. This resolves incorrect 501 or 405 responses when
178
- using multiple routers.
179
-
180
- ### Breaking changes
181
-
182
- 4.x is mostly backwards compatible with 3.x, except for the following:
183
-
184
- * Instantiating a router with `new` and `app` returns the router instance,
185
- whereas 3.x returns the router middleware. When creating a router in 4.x, the
186
- only time router middleware is returned is when creating using the
187
- `Router(app)` signature (with `app` and without `new`).
package/lib/API_tpl.hbs DELETED
@@ -1,7 +0,0 @@
1
-
2
- ## API Reference
3
- {{#module name="koa-router"~}}
4
- {{>body~}}
5
- {{>member-index~}}
6
- {{>members~}}
7
- {{/module~}}
package/lib/layer.js DELETED
@@ -1,262 +0,0 @@
1
- const { parse: parseUrl, format: formatUrl } = require('node:url');
2
-
3
- const { pathToRegexp, compile, parse } = require('path-to-regexp');
4
-
5
- module.exports = class Layer {
6
- /**
7
- * Initialize a new routing Layer with given `method`, `path`, and `middleware`.
8
- *
9
- * @param {String|RegExp} path Path string or regular expression.
10
- * @param {Array} methods Array of HTTP verbs.
11
- * @param {Array} middleware Layer callback/middleware or series of.
12
- * @param {Object=} opts
13
- * @param {String=} opts.name route name
14
- * @param {String=} opts.sensitive case sensitive (default: false)
15
- * @param {String=} opts.strict require the trailing slash (default: false)
16
- * @param {Boolean=} opts.pathAsRegExp if true, treat `path` as a regular expression
17
- * @returns {Layer}
18
- * @private
19
- */
20
- constructor(path, methods, middleware, opts = {}) {
21
- this.opts = opts;
22
- this.name = this.opts.name || null;
23
- this.methods = [];
24
- for (const method of methods) {
25
- const l = this.methods.push(method.toUpperCase());
26
- if (this.methods[l - 1] === 'GET') this.methods.unshift('HEAD');
27
- }
28
-
29
- this.stack = Array.isArray(middleware) ? middleware : [middleware];
30
- // ensure middleware is a function
31
- for (let i = 0; i < this.stack.length; i++) {
32
- const fn = this.stack[i];
33
- const type = typeof fn;
34
- if (type !== 'function')
35
- throw new Error(
36
- `${methods.toString()} \`${
37
- this.opts.name || path
38
- }\`: \`middleware\` must be a function, not \`${type}\``
39
- );
40
- }
41
-
42
- this.path = path;
43
- this.paramNames = [];
44
-
45
- if (this.opts.pathAsRegExp === true) {
46
- this.regexp = new RegExp(path);
47
- } else if (this.path) {
48
- if ('strict' in this.opts) {
49
- // path-to-regexp renamed strict to trailing in v8.1.0
50
- this.opts.trailing = this.opts.strict !== true;
51
- }
52
-
53
- const { regexp, keys } = pathToRegexp(this.path, this.opts);
54
- this.regexp = regexp;
55
- this.paramNames = keys;
56
- }
57
- }
58
-
59
- /**
60
- * Returns whether request `path` matches route.
61
- *
62
- * @param {String} path
63
- * @returns {Boolean}
64
- * @private
65
- */
66
- match(path) {
67
- return this.regexp.test(path);
68
- }
69
-
70
- /**
71
- * Returns map of URL parameters for given `path` and `paramNames`.
72
- *
73
- * @param {String} path
74
- * @param {Array.<String>} captures
75
- * @param {Object=} params
76
- * @returns {Object}
77
- * @private
78
- */
79
- params(path, captures, params = {}) {
80
- for (let len = captures.length, i = 0; i < len; i++) {
81
- if (this.paramNames[i]) {
82
- const c = captures[i];
83
- if (c && c.length > 0)
84
- params[this.paramNames[i].name] = c ? safeDecodeURIComponent(c) : c;
85
- }
86
- }
87
-
88
- return params;
89
- }
90
-
91
- /**
92
- * Returns array of regexp url path captures.
93
- *
94
- * @param {String} path
95
- * @returns {Array.<String>}
96
- * @private
97
- */
98
- captures(path) {
99
- return this.opts.ignoreCaptures ? [] : path.match(this.regexp).slice(1);
100
- }
101
-
102
- /**
103
- * Generate URL for route using given `params`.
104
- *
105
- * @example
106
- *
107
- * ```javascript
108
- * const route = new Layer('/users/:id', ['GET'], fn);
109
- *
110
- * route.url({ id: 123 }); // => "/users/123"
111
- * ```
112
- *
113
- * @param {Object} params url parameters
114
- * @returns {String}
115
- * @private
116
- */
117
- url(params, options) {
118
- let args = params;
119
- const url = this.path.replace(/\(\.\*\)/g, '');
120
-
121
- if (typeof params !== 'object') {
122
- args = Array.prototype.slice.call(arguments);
123
- if (typeof args[args.length - 1] === 'object') {
124
- options = args[args.length - 1];
125
- args = args.slice(0, -1);
126
- }
127
- }
128
-
129
- const toPath = compile(url, { encode: encodeURIComponent, ...options });
130
- let replaced;
131
- const { tokens } = parse(url);
132
- let replace = {};
133
-
134
- if (Array.isArray(args)) {
135
- for (let len = tokens.length, i = 0, j = 0; i < len; i++) {
136
- if (tokens[i].name) {
137
- replace[tokens[i].name] = args[j++];
138
- }
139
- }
140
- } else if (tokens.some((token) => token.name)) {
141
- replace = params;
142
- } else if (!options) {
143
- options = params;
144
- }
145
-
146
- for (const [key, value] of Object.entries(replace)) {
147
- replace[key] = String(value);
148
- }
149
-
150
- replaced = toPath(replace);
151
-
152
- if (options && options.query) {
153
- replaced = parseUrl(replaced);
154
- if (typeof options.query === 'string') {
155
- replaced.search = options.query;
156
- } else {
157
- replaced.search = undefined;
158
- replaced.query = options.query;
159
- }
160
-
161
- return formatUrl(replaced);
162
- }
163
-
164
- return replaced;
165
- }
166
-
167
- /**
168
- * Run validations on route named parameters.
169
- *
170
- * @example
171
- *
172
- * ```javascript
173
- * router
174
- * .param('user', function (id, ctx, next) {
175
- * ctx.user = users[id];
176
- * if (!ctx.user) return ctx.status = 404;
177
- * next();
178
- * })
179
- * .get('/users/:user', function (ctx, next) {
180
- * ctx.body = ctx.user;
181
- * });
182
- * ```
183
- *
184
- * @param {String} param
185
- * @param {Function} middleware
186
- * @returns {Layer}
187
- * @private
188
- */
189
- param(param, fn) {
190
- const { stack } = this;
191
- const params = this.paramNames;
192
- const middleware = function (ctx, next) {
193
- return fn.call(this, ctx.params[param], ctx, next);
194
- };
195
-
196
- middleware.param = param;
197
-
198
- const names = params.map(function (p) {
199
- return p.name;
200
- });
201
-
202
- const x = names.indexOf(param);
203
- if (x > -1) {
204
- // iterate through the stack, to figure out where to place the handler fn
205
- stack.some((fn, i) => {
206
- // param handlers are always first, so when we find an fn w/o a param property, stop here
207
- // if the param handler at this part of the stack comes after the one we are adding, stop here
208
- if (!fn.param || names.indexOf(fn.param) > x) {
209
- // inject this param handler right before the current item
210
- stack.splice(i, 0, middleware);
211
- return true; // then break the loop
212
- }
213
- });
214
- }
215
-
216
- return this;
217
- }
218
-
219
- /**
220
- * Prefix route path.
221
- *
222
- * @param {String} prefix
223
- * @returns {Layer}
224
- * @private
225
- */
226
- setPrefix(prefix) {
227
- if (this.path) {
228
- this.path =
229
- this.path !== '/' || this.opts.strict === true
230
- ? `${prefix}${this.path}`
231
- : prefix;
232
- if (this.opts.pathAsRegExp === true || prefix instanceof RegExp) {
233
- this.regexp = new RegExp(this.path);
234
- } else if (this.path) {
235
- const { regexp, keys } = pathToRegexp(this.path, this.opts);
236
- this.regexp = regexp;
237
- this.paramNames = keys;
238
- }
239
- }
240
-
241
- return this;
242
- }
243
- };
244
-
245
- /**
246
- * Safe decodeURIComponent, won't throw any error.
247
- * If `decodeURIComponent` error happen, just return the original value.
248
- *
249
- * @param {String} text
250
- * @returns {String} URL decode original string.
251
- * @private
252
- */
253
-
254
- function safeDecodeURIComponent(text) {
255
- try {
256
- // TODO: take a look on `safeDecodeURIComponent` if we use it only with route params let's remove the `replace` method otherwise make it flexible.
257
- // @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#decoding_query_parameters_from_a_url
258
- return decodeURIComponent(text.replace(/\+/g, ' '));
259
- } catch {
260
- return text;
261
- }
262
- }