@koa/router 13.1.1 → 15.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/LICENSE +1 -1
- package/README.md +1136 -41
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1378 -0
- package/dist/index.mjs +1341 -0
- package/dist/layer.d.mts +761 -0
- package/dist/layer.d.ts +761 -0
- package/dist/layer.js +457 -0
- package/dist/layer.mjs +436 -0
- package/dist/router.d.mts +3 -0
- package/dist/router.d.ts +3 -0
- package/dist/router.js +1371 -0
- package/dist/router.mjs +1340 -0
- package/dist/types.d.mts +3 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +18 -0
- package/dist/types.mjs +0 -0
- package/package.json +58 -30
- package/lib/API_tpl.hbs +0 -7
- package/lib/layer.js +0 -240
- package/lib/router.js +0 -824
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import 'koa';
|
|
2
|
+
export { A as AllowedMethodsOptions, H as HttpMethod, default as Layer, L as LayerOptions, M as MatchResult, d as RouterContext, e as RouterMiddleware, a as RouterOptions, b as RouterParameterContext, c as RouterParameterMiddleware, U as UrlOptions } from './layer.mjs';
|
|
3
|
+
import 'path-to-regexp';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import 'koa';
|
|
2
|
+
export { A as AllowedMethodsOptions, H as HttpMethod, default as Layer, L as LayerOptions, M as MatchResult, d as RouterContext, e as RouterMiddleware, a as RouterOptions, b as RouterParameterContext, c as RouterParameterMiddleware, U as UrlOptions } from './layer.js';
|
|
3
|
+
import 'path-to-regexp';
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/types.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
package/dist/types.mjs
ADDED
|
File without changes
|
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": "
|
|
4
|
+
"version": "15.0.0",
|
|
5
5
|
"author": "Alex Mingoia <talk@alexmingoia.com>",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/koajs/router/issues",
|
|
@@ -21,34 +21,53 @@
|
|
|
21
21
|
}
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"debug": "^4.4.
|
|
25
|
-
"http-errors": "^2.0.
|
|
24
|
+
"debug": "^4.4.3",
|
|
25
|
+
"http-errors": "^2.0.1",
|
|
26
26
|
"koa-compose": "^4.1.0",
|
|
27
|
-
"path-to-regexp": "^
|
|
27
|
+
"path-to-regexp": "^8.3.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@commitlint/cli": "^
|
|
31
|
-
"@commitlint/config-conventional": "^
|
|
32
|
-
"@
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
30
|
+
"@commitlint/cli": "^20.1.0",
|
|
31
|
+
"@commitlint/config-conventional": "^20.0.0",
|
|
32
|
+
"@types/debug": "^4.1.12",
|
|
33
|
+
"@types/jsonwebtoken": "^9.0.7",
|
|
34
|
+
"@types/koa": "^3.0.1",
|
|
35
|
+
"@types/node": "^24.10.1",
|
|
36
|
+
"@types/supertest": "^6.0.3",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
38
|
+
"@typescript-eslint/parser": "^8.48.0",
|
|
39
|
+
"c8": "^10.1.3",
|
|
40
|
+
"chalk": "^5.4.1",
|
|
41
|
+
"eslint": "^9.39.1",
|
|
42
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
43
|
+
"husky": "^9.1.7",
|
|
44
|
+
"joi": "^18.0.2",
|
|
45
|
+
"jsonwebtoken": "^9.0.2",
|
|
46
|
+
"koa": "^3.1.1",
|
|
47
|
+
"lint-staged": "^16.2.7",
|
|
48
|
+
"prettier": "^3.7.1",
|
|
49
|
+
"rimraf": "^6.1.2",
|
|
50
|
+
"supertest": "^7.1.4",
|
|
51
|
+
"ts-node": "^10.9.2",
|
|
52
|
+
"tsup": "^8.5.1",
|
|
53
|
+
"typescript": "^5.9.3"
|
|
46
54
|
},
|
|
47
55
|
"engines": {
|
|
48
|
-
"node": ">=
|
|
56
|
+
"node": ">= 20"
|
|
57
|
+
},
|
|
58
|
+
"main": "./dist/index.js",
|
|
59
|
+
"module": "./dist/index.mjs",
|
|
60
|
+
"types": "./dist/index.d.ts",
|
|
61
|
+
"exports": {
|
|
62
|
+
".": {
|
|
63
|
+
"require": "./dist/index.js",
|
|
64
|
+
"import": "./dist/index.mjs"
|
|
65
|
+
}
|
|
49
66
|
},
|
|
50
67
|
"files": [
|
|
51
|
-
"
|
|
68
|
+
"dist",
|
|
69
|
+
"LICENSE",
|
|
70
|
+
"README.md"
|
|
52
71
|
],
|
|
53
72
|
"homepage": "https://github.com/koajs/router",
|
|
54
73
|
"keywords": [
|
|
@@ -58,19 +77,28 @@
|
|
|
58
77
|
"router"
|
|
59
78
|
],
|
|
60
79
|
"license": "MIT",
|
|
61
|
-
"main": "lib/router.js",
|
|
62
80
|
"repository": {
|
|
63
81
|
"type": "git",
|
|
64
82
|
"url": "git+https://github.com/koajs/router.git"
|
|
65
83
|
},
|
|
66
84
|
"scripts": {
|
|
67
|
-
"bench": "
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
85
|
+
"bench": "TS_NODE_PROJECT=tsconfig.bench.json node --require ts-node/register bench/run.ts",
|
|
86
|
+
"benchmark": "npm run bench",
|
|
87
|
+
"bench:all": "TS_NODE_PROJECT=tsconfig.bench.json node --require ts-node/register bench/make.ts",
|
|
88
|
+
"benchmark:all": "npm run bench:all",
|
|
71
89
|
"prepare": "husky install",
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
90
|
+
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
|
|
91
|
+
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
|
|
92
|
+
"lint:ts": "eslint src test --ext .ts,.tsx --fix",
|
|
93
|
+
"lint": "npm run lint:ts",
|
|
94
|
+
"test:core": "TS_NODE_PROJECT=tsconfig.ts-node.json node --require ts-node/register --test test/*.test.ts test/**/*.test.ts",
|
|
95
|
+
"test:recipes": "TS_NODE_PROJECT=tsconfig.recipes.json node --require ts-node/register --test recipes/**/*.test.ts",
|
|
96
|
+
"pretest:all": "npm run lint",
|
|
97
|
+
"test:all": "TS_NODE_PROJECT=tsconfig.ts-node.json node --require ts-node/register --test test/*.test.ts test/**/*.test.ts recipes/**/*.test.ts",
|
|
98
|
+
"test:coverage": "c8 npm run test:all",
|
|
99
|
+
"ts:check": "tsc --noEmit --project tsconfig.typecheck.json",
|
|
100
|
+
"prebuild": "rimraf dist",
|
|
101
|
+
"build": "tsup",
|
|
102
|
+
"prepublishOnly": "npm run build"
|
|
75
103
|
}
|
|
76
104
|
}
|
package/lib/API_tpl.hbs
DELETED
package/lib/layer.js
DELETED
|
@@ -1,240 +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
|
-
* @returns {Layer}
|
|
17
|
-
* @private
|
|
18
|
-
*/
|
|
19
|
-
constructor(path, methods, middleware, opts = {}) {
|
|
20
|
-
this.opts = opts;
|
|
21
|
-
this.name = this.opts.name || null;
|
|
22
|
-
this.methods = [];
|
|
23
|
-
this.paramNames = [];
|
|
24
|
-
this.stack = Array.isArray(middleware) ? middleware : [middleware];
|
|
25
|
-
|
|
26
|
-
for (const method of methods) {
|
|
27
|
-
const l = this.methods.push(method.toUpperCase());
|
|
28
|
-
if (this.methods[l - 1] === 'GET') this.methods.unshift('HEAD');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// ensure middleware is a function
|
|
32
|
-
for (let i = 0; i < this.stack.length; i++) {
|
|
33
|
-
const fn = this.stack[i];
|
|
34
|
-
const type = typeof fn;
|
|
35
|
-
if (type !== 'function')
|
|
36
|
-
throw new Error(
|
|
37
|
-
`${methods.toString()} \`${
|
|
38
|
-
this.opts.name || path
|
|
39
|
-
}\`: \`middleware\` must be a function, not \`${type}\``
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this.path = path;
|
|
44
|
-
this.regexp = pathToRegexp(path, this.paramNames, this.opts);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Returns whether request `path` matches route.
|
|
49
|
-
*
|
|
50
|
-
* @param {String} path
|
|
51
|
-
* @returns {Boolean}
|
|
52
|
-
* @private
|
|
53
|
-
*/
|
|
54
|
-
match(path) {
|
|
55
|
-
return this.regexp.test(path);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Returns map of URL parameters for given `path` and `paramNames`.
|
|
60
|
-
*
|
|
61
|
-
* @param {String} path
|
|
62
|
-
* @param {Array.<String>} captures
|
|
63
|
-
* @param {Object=} params
|
|
64
|
-
* @returns {Object}
|
|
65
|
-
* @private
|
|
66
|
-
*/
|
|
67
|
-
params(path, captures, params = {}) {
|
|
68
|
-
for (let len = captures.length, i = 0; i < len; i++) {
|
|
69
|
-
if (this.paramNames[i]) {
|
|
70
|
-
const c = captures[i];
|
|
71
|
-
if (c && c.length > 0)
|
|
72
|
-
params[this.paramNames[i].name] = c ? safeDecodeURIComponent(c) : c;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return params;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Returns array of regexp url path captures.
|
|
81
|
-
*
|
|
82
|
-
* @param {String} path
|
|
83
|
-
* @returns {Array.<String>}
|
|
84
|
-
* @private
|
|
85
|
-
*/
|
|
86
|
-
captures(path) {
|
|
87
|
-
return this.opts.ignoreCaptures ? [] : path.match(this.regexp).slice(1);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Generate URL for route using given `params`.
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
*
|
|
95
|
-
* ```javascript
|
|
96
|
-
* const route = new Layer('/users/:id', ['GET'], fn);
|
|
97
|
-
*
|
|
98
|
-
* route.url({ id: 123 }); // => "/users/123"
|
|
99
|
-
* ```
|
|
100
|
-
*
|
|
101
|
-
* @param {Object} params url parameters
|
|
102
|
-
* @returns {String}
|
|
103
|
-
* @private
|
|
104
|
-
*/
|
|
105
|
-
url(params, options) {
|
|
106
|
-
let args = params;
|
|
107
|
-
const url = this.path.replace(/\(\.\*\)/g, '');
|
|
108
|
-
|
|
109
|
-
if (typeof params !== 'object') {
|
|
110
|
-
args = Array.prototype.slice.call(arguments);
|
|
111
|
-
if (typeof args[args.length - 1] === 'object') {
|
|
112
|
-
options = args[args.length - 1];
|
|
113
|
-
args = args.slice(0, -1);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const toPath = compile(url, { encode: encodeURIComponent, ...options });
|
|
118
|
-
let replaced;
|
|
119
|
-
|
|
120
|
-
const tokens = parse(url);
|
|
121
|
-
let replace = {};
|
|
122
|
-
|
|
123
|
-
if (Array.isArray(args)) {
|
|
124
|
-
for (let len = tokens.length, i = 0, j = 0; i < len; i++) {
|
|
125
|
-
if (tokens[i].name) replace[tokens[i].name] = args[j++];
|
|
126
|
-
}
|
|
127
|
-
} else if (tokens.some((token) => token.name)) {
|
|
128
|
-
replace = params;
|
|
129
|
-
} else if (!options) {
|
|
130
|
-
options = params;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
replaced = toPath(replace);
|
|
134
|
-
|
|
135
|
-
if (options && options.query) {
|
|
136
|
-
replaced = parseUrl(replaced);
|
|
137
|
-
if (typeof options.query === 'string') {
|
|
138
|
-
replaced.search = options.query;
|
|
139
|
-
} else {
|
|
140
|
-
replaced.search = undefined;
|
|
141
|
-
replaced.query = options.query;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return formatUrl(replaced);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return replaced;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Run validations on route named parameters.
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
*
|
|
155
|
-
* ```javascript
|
|
156
|
-
* router
|
|
157
|
-
* .param('user', function (id, ctx, next) {
|
|
158
|
-
* ctx.user = users[id];
|
|
159
|
-
* if (!ctx.user) return ctx.status = 404;
|
|
160
|
-
* next();
|
|
161
|
-
* })
|
|
162
|
-
* .get('/users/:user', function (ctx, next) {
|
|
163
|
-
* ctx.body = ctx.user;
|
|
164
|
-
* });
|
|
165
|
-
* ```
|
|
166
|
-
*
|
|
167
|
-
* @param {String} param
|
|
168
|
-
* @param {Function} middleware
|
|
169
|
-
* @returns {Layer}
|
|
170
|
-
* @private
|
|
171
|
-
*/
|
|
172
|
-
param(param, fn) {
|
|
173
|
-
const { stack } = this;
|
|
174
|
-
const params = this.paramNames;
|
|
175
|
-
const middleware = function (ctx, next) {
|
|
176
|
-
return fn.call(this, ctx.params[param], ctx, next);
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
middleware.param = param;
|
|
180
|
-
|
|
181
|
-
const names = params.map(function (p) {
|
|
182
|
-
return p.name;
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
const x = names.indexOf(param);
|
|
186
|
-
if (x > -1) {
|
|
187
|
-
// iterate through the stack, to figure out where to place the handler fn
|
|
188
|
-
stack.some((fn, i) => {
|
|
189
|
-
// param handlers are always first, so when we find an fn w/o a param property, stop here
|
|
190
|
-
// if the param handler at this part of the stack comes after the one we are adding, stop here
|
|
191
|
-
if (!fn.param || names.indexOf(fn.param) > x) {
|
|
192
|
-
// inject this param handler right before the current item
|
|
193
|
-
stack.splice(i, 0, middleware);
|
|
194
|
-
return true; // then break the loop
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
return this;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Prefix route path.
|
|
204
|
-
*
|
|
205
|
-
* @param {String} prefix
|
|
206
|
-
* @returns {Layer}
|
|
207
|
-
* @private
|
|
208
|
-
*/
|
|
209
|
-
setPrefix(prefix) {
|
|
210
|
-
if (this.path) {
|
|
211
|
-
this.path =
|
|
212
|
-
this.path !== '/' || this.opts.strict === true
|
|
213
|
-
? `${prefix}${this.path}`
|
|
214
|
-
: prefix;
|
|
215
|
-
this.paramNames = [];
|
|
216
|
-
this.regexp = pathToRegexp(this.path, this.paramNames, this.opts);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return this;
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Safe decodeURIComponent, won't throw any error.
|
|
225
|
-
* If `decodeURIComponent` error happen, just return the original value.
|
|
226
|
-
*
|
|
227
|
-
* @param {String} text
|
|
228
|
-
* @returns {String} URL decode original string.
|
|
229
|
-
* @private
|
|
230
|
-
*/
|
|
231
|
-
|
|
232
|
-
function safeDecodeURIComponent(text) {
|
|
233
|
-
try {
|
|
234
|
-
// TODO: take a look on `safeDecodeURIComponent` if we use it only with route params let's remove the `replace` method otherwise make it flexible.
|
|
235
|
-
// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#decoding_query_parameters_from_a_url
|
|
236
|
-
return decodeURIComponent(text.replace(/\+/g, ' '));
|
|
237
|
-
} catch {
|
|
238
|
-
return text;
|
|
239
|
-
}
|
|
240
|
-
}
|