@koa/router 15.4.0 → 15.5.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/README.md +8 -8
- package/dist/index.d.mts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +21 -5
- package/dist/index.mjs +21 -5
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -266,14 +266,14 @@ Create a new router instance.
|
|
|
266
266
|
|
|
267
267
|
**Options:**
|
|
268
268
|
|
|
269
|
-
| Option | Type | Description
|
|
270
|
-
| ----------- | ------------------------------ |
|
|
271
|
-
| `prefix` | `string` | Prefix all routes with this path
|
|
272
|
-
| `exclusive` | `boolean`
|
|
273
|
-
| `host` | `string \| string[] \| RegExp` | Match routes only for this hostname(s)
|
|
274
|
-
| `methods` | `string[]` | Custom HTTP methods to support
|
|
275
|
-
| `sensitive` | `boolean` | Enable case-sensitive routing
|
|
276
|
-
| `strict` | `boolean` | Require trailing slashes
|
|
269
|
+
| Option | Type | Description |
|
|
270
|
+
| ----------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
271
|
+
| `prefix` | `string` | Prefix all routes with this path |
|
|
272
|
+
| `exclusive` | `boolean \| 'specificity'` | `true`: only run the last-registered matching route. `'specificity'`: only run the route with the fewest path parameters (OpenAPI-compliant). Omit to run all matching routes. |
|
|
273
|
+
| `host` | `string \| string[] \| RegExp` | Match routes only for this hostname(s) |
|
|
274
|
+
| `methods` | `string[]` | Custom HTTP methods to support |
|
|
275
|
+
| `sensitive` | `boolean` | Enable case-sensitive routing |
|
|
276
|
+
| `strict` | `boolean` | Require trailing slashes |
|
|
277
277
|
|
|
278
278
|
**Example:**
|
|
279
279
|
|
package/dist/index.d.mts
CHANGED
|
@@ -748,9 +748,18 @@ declare const Router: RouterConstructor;
|
|
|
748
748
|
|
|
749
749
|
type RouterOptions = {
|
|
750
750
|
/**
|
|
751
|
-
*
|
|
752
|
-
|
|
753
|
-
|
|
751
|
+
* Control which route is executed when multiple routes match a request.
|
|
752
|
+
*
|
|
753
|
+
* - `true` — run only the last registered matching route (legacy behaviour)
|
|
754
|
+
* - `'specificity'` — run only the most specific matching route, defined as
|
|
755
|
+
* the one with the fewest path parameters. This is OpenAPI-compliant
|
|
756
|
+
* (see https://spec.openapis.org/oas/v3.0.3#path-templating-matching) and
|
|
757
|
+
* is the recommended mode for code generated from OpenAPI specifications.
|
|
758
|
+
* When two routes have an equal number of parameters the last registered
|
|
759
|
+
* one wins, preserving deterministic behaviour.
|
|
760
|
+
* - `false` / omitted — all matching routes run in registration order
|
|
761
|
+
*/
|
|
762
|
+
exclusive?: boolean | 'specificity';
|
|
754
763
|
/**
|
|
755
764
|
* Prefix for all routes
|
|
756
765
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -748,9 +748,18 @@ declare const Router: RouterConstructor;
|
|
|
748
748
|
|
|
749
749
|
type RouterOptions = {
|
|
750
750
|
/**
|
|
751
|
-
*
|
|
752
|
-
|
|
753
|
-
|
|
751
|
+
* Control which route is executed when multiple routes match a request.
|
|
752
|
+
*
|
|
753
|
+
* - `true` — run only the last registered matching route (legacy behaviour)
|
|
754
|
+
* - `'specificity'` — run only the most specific matching route, defined as
|
|
755
|
+
* the one with the fewest path parameters. This is OpenAPI-compliant
|
|
756
|
+
* (see https://spec.openapis.org/oas/v3.0.3#path-templating-matching) and
|
|
757
|
+
* is the recommended mode for code generated from OpenAPI specifications.
|
|
758
|
+
* When two routes have an equal number of parameters the last registered
|
|
759
|
+
* one wins, preserving deterministic behaviour.
|
|
760
|
+
* - `false` / omitted — all matching routes run in registration order
|
|
761
|
+
*/
|
|
762
|
+
exclusive?: boolean | 'specificity';
|
|
754
763
|
/**
|
|
755
764
|
* Prefix for all routes
|
|
756
765
|
*/
|
package/dist/index.js
CHANGED
|
@@ -966,8 +966,11 @@ var RouterImplementation = class {
|
|
|
966
966
|
const previousPrefix = this.opts.prefix || "";
|
|
967
967
|
this.opts.prefix = normalizedPrefix;
|
|
968
968
|
for (const route of this.stack) {
|
|
969
|
-
if (
|
|
970
|
-
|
|
969
|
+
if (typeof route.path === "string" && previousPrefix) {
|
|
970
|
+
const stripBoundary = previousPrefix + "/";
|
|
971
|
+
if (route.path === previousPrefix || route.path.startsWith(stripBoundary)) {
|
|
972
|
+
route.path = route.path.slice(previousPrefix.length) || "/";
|
|
973
|
+
}
|
|
971
974
|
}
|
|
972
975
|
route.setPrefix(normalizedPrefix);
|
|
973
976
|
}
|
|
@@ -1049,9 +1052,22 @@ var RouterImplementation = class {
|
|
|
1049
1052
|
* @private
|
|
1050
1053
|
*/
|
|
1051
1054
|
_buildMiddlewareChain(matchedLayers, requestPath) {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
+
let layersToExecute;
|
|
1056
|
+
if (this.exclusive) {
|
|
1057
|
+
let chosenLayer;
|
|
1058
|
+
if (this.opts.exclusive === "specificity") {
|
|
1059
|
+
for (const layer of matchedLayers) {
|
|
1060
|
+
if (!chosenLayer || layer.paramNames.length < chosenLayer.paramNames.length) {
|
|
1061
|
+
chosenLayer = layer;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
} else {
|
|
1065
|
+
chosenLayer = matchedLayers.at(-1);
|
|
1066
|
+
}
|
|
1067
|
+
layersToExecute = chosenLayer ? [chosenLayer] : [];
|
|
1068
|
+
} else {
|
|
1069
|
+
layersToExecute = matchedLayers;
|
|
1070
|
+
}
|
|
1055
1071
|
const middlewareChain = [];
|
|
1056
1072
|
for (const layer of layersToExecute) {
|
|
1057
1073
|
middlewareChain.push(
|
package/dist/index.mjs
CHANGED
|
@@ -927,8 +927,11 @@ var RouterImplementation = class {
|
|
|
927
927
|
const previousPrefix = this.opts.prefix || "";
|
|
928
928
|
this.opts.prefix = normalizedPrefix;
|
|
929
929
|
for (const route of this.stack) {
|
|
930
|
-
if (
|
|
931
|
-
|
|
930
|
+
if (typeof route.path === "string" && previousPrefix) {
|
|
931
|
+
const stripBoundary = previousPrefix + "/";
|
|
932
|
+
if (route.path === previousPrefix || route.path.startsWith(stripBoundary)) {
|
|
933
|
+
route.path = route.path.slice(previousPrefix.length) || "/";
|
|
934
|
+
}
|
|
932
935
|
}
|
|
933
936
|
route.setPrefix(normalizedPrefix);
|
|
934
937
|
}
|
|
@@ -1010,9 +1013,22 @@ var RouterImplementation = class {
|
|
|
1010
1013
|
* @private
|
|
1011
1014
|
*/
|
|
1012
1015
|
_buildMiddlewareChain(matchedLayers, requestPath) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
+
let layersToExecute;
|
|
1017
|
+
if (this.exclusive) {
|
|
1018
|
+
let chosenLayer;
|
|
1019
|
+
if (this.opts.exclusive === "specificity") {
|
|
1020
|
+
for (const layer of matchedLayers) {
|
|
1021
|
+
if (!chosenLayer || layer.paramNames.length < chosenLayer.paramNames.length) {
|
|
1022
|
+
chosenLayer = layer;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
} else {
|
|
1026
|
+
chosenLayer = matchedLayers.at(-1);
|
|
1027
|
+
}
|
|
1028
|
+
layersToExecute = chosenLayer ? [chosenLayer] : [];
|
|
1029
|
+
} else {
|
|
1030
|
+
layersToExecute = matchedLayers;
|
|
1031
|
+
}
|
|
1016
1032
|
const middlewareChain = [];
|
|
1017
1033
|
for (const layer of layersToExecute) {
|
|
1018
1034
|
middlewareChain.push(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koa/router",
|
|
3
3
|
"description": "Router middleware for Koa.",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.5.0",
|
|
5
5
|
"author": "Koa.js",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/koajs/router/issues",
|
|
@@ -28,31 +28,31 @@
|
|
|
28
28
|
"debug": "^4.4.3",
|
|
29
29
|
"http-errors": "^2.0.1",
|
|
30
30
|
"koa-compose": "^4.1.0",
|
|
31
|
-
"path-to-regexp": "^8.
|
|
31
|
+
"path-to-regexp": "^8.4.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@commitlint/cli": "^20.
|
|
35
|
-
"@commitlint/config-conventional": "^20.
|
|
34
|
+
"@commitlint/cli": "^20.5.3",
|
|
35
|
+
"@commitlint/config-conventional": "^20.5.3",
|
|
36
36
|
"@eslint/js": "^10.0.1",
|
|
37
37
|
"@koa/bodyparser": "^6.1.0",
|
|
38
|
-
"@types/debug": "^4.1.
|
|
38
|
+
"@types/debug": "^4.1.13",
|
|
39
39
|
"@types/jsonwebtoken": "^9.0.10",
|
|
40
|
-
"@types/koa": "^3.0.
|
|
41
|
-
"@types/node": "^25.
|
|
40
|
+
"@types/koa": "^3.0.2",
|
|
41
|
+
"@types/node": "^25.6.0",
|
|
42
42
|
"@types/supertest": "^7.2.0",
|
|
43
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
44
|
-
"@typescript-eslint/parser": "^8.
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^8.59.1",
|
|
44
|
+
"@typescript-eslint/parser": "^8.59.1",
|
|
45
45
|
"c8": "^11.0.0",
|
|
46
46
|
"chalk": "^5.6.2",
|
|
47
|
-
"eslint": "^10.0
|
|
48
|
-
"eslint-plugin-unicorn": "^
|
|
47
|
+
"eslint": "^10.3.0",
|
|
48
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
49
49
|
"husky": "^9.1.7",
|
|
50
|
-
"joi": "^18.
|
|
50
|
+
"joi": "^18.1.2",
|
|
51
51
|
"jsonwebtoken": "^9.0.3",
|
|
52
|
-
"koa": "^3.
|
|
52
|
+
"koa": "^3.2.0",
|
|
53
53
|
"lint-staged": "^16.4.0",
|
|
54
|
-
"np": "^11.0
|
|
55
|
-
"prettier": "^3.8.
|
|
54
|
+
"np": "^11.2.0",
|
|
55
|
+
"prettier": "^3.8.3",
|
|
56
56
|
"rimraf": "^6.1.3",
|
|
57
57
|
"supertest": "^7.2.2",
|
|
58
58
|
"ts-node": "^10.9.2",
|