@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.
@@ -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';
@@ -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": "13.1.1",
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.1",
25
- "http-errors": "^2.0.0",
24
+ "debug": "^4.4.3",
25
+ "http-errors": "^2.0.1",
26
26
  "koa-compose": "^4.1.0",
27
- "path-to-regexp": "^6.3.0"
27
+ "path-to-regexp": "^8.3.0"
28
28
  },
29
29
  "devDependencies": {
30
- "@commitlint/cli": "^17.7.2",
31
- "@commitlint/config-conventional": "^17.7.0",
32
- "@ladjs/env": "^4.0.0",
33
- "eslint": "^8.39.0",
34
- "eslint-config-xo-lass": "^2.0.1",
35
- "fixpack": "^4.0.0",
36
- "husky": "^8.0.3",
37
- "jsdoc-to-markdown": "^8.0.0",
38
- "koa": "^2.15.3",
39
- "lint-staged": "^14.0.1",
40
- "mocha": "^10.7.3",
41
- "nyc": "^17.0.0",
42
- "remark-cli": "11",
43
- "remark-preset-github": "^4.0.4",
44
- "supertest": "^7.0.0",
45
- "xo": "0.53.1"
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": ">= 18"
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
- "lib"
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": "make -C bench",
68
- "coverage": "nyc npm run test",
69
- "docs": "NODE_ENV=test jsdoc2md -t ./lib/API_tpl.hbs --src ./lib/*.js >| API.md",
70
- "lint": "xo --fix && remark . -qfo && fixpack",
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
- "pretest": "npm run lint",
73
- "test": "mocha test/**/*.js",
74
- "test:watch": "mocha test/**/*.js --watch"
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
@@ -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,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
- }