@koa/router 15.5.0 → 15.6.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 +23 -1
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/index.mjs +6 -0
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
- ✅ **405 Method Not Allowed** - Automatic method validation
|
|
41
41
|
- ✅ **501 Not Implemented** - Proper HTTP status codes
|
|
42
42
|
- ✅ **Async/Await** - Full promise-based middleware support
|
|
43
|
+
- ✅ **Clean ctx.params** - Only URL parameters you define are present in `ctx.params`; no internal routing keys leak out
|
|
43
44
|
|
|
44
45
|
## Installation
|
|
45
46
|
|
|
@@ -457,7 +458,26 @@ router.get('/users', (ctx) => {
|
|
|
457
458
|
// Responds to /api/v1/users, /api/v2/users, etc.
|
|
458
459
|
```
|
|
459
460
|
|
|
460
|
-
**
|
|
461
|
+
**Middleware on a parameterized prefix:**
|
|
462
|
+
|
|
463
|
+
When `router.use()` is attached to a router whose prefix contains URL parameters, `ctx.params` inside the middleware will contain **only** the parameters defined by the prefix — no internal routing keys are ever added.
|
|
464
|
+
|
|
465
|
+
```javascript
|
|
466
|
+
const router = new Router({ prefix: '/:tenantId' });
|
|
467
|
+
|
|
468
|
+
// Auth / authz middleware — receives only the defined prefix param
|
|
469
|
+
router.use(async (ctx, next) => {
|
|
470
|
+
console.log(ctx.params); // => { tenantId: 'acme' } (no extraneous keys)
|
|
471
|
+
await next();
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
router.get('/users', (ctx) => {
|
|
475
|
+
console.log(ctx.params); // => { tenantId: 'acme' }
|
|
476
|
+
ctx.body = ctx.params;
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
This is particularly useful when running **strict parameter validation** inside a `router.use()` middleware — the shape of `ctx.params` is predictable and contains only what you defined.
|
|
461
481
|
|
|
462
482
|
### URL Parameters
|
|
463
483
|
|
|
@@ -565,6 +585,8 @@ router.use('/nested', nestedRouter.routes());
|
|
|
565
585
|
|
|
566
586
|
**Note:** Middleware path boundaries are correctly enforced. Middleware scoped to `/api` will only run for routes matching `/api/*`, not for unrelated routes.
|
|
567
587
|
|
|
588
|
+
**Note:** When `router.use()` is used on a router with a parameterized prefix (e.g. `prefix: '/:id'`), `ctx.params` inside that middleware will contain **only** the parameters defined by the prefix and route path — no internal wildcard keys are exposed. See [Router Prefixes](#router-prefixes) for a full example.
|
|
589
|
+
|
|
568
590
|
### router.prefix()
|
|
569
591
|
|
|
570
592
|
Set the path prefix for a Router instance after initialization.
|
package/dist/index.d.mts
CHANGED
|
@@ -821,6 +821,12 @@ type LayerOptions = {
|
|
|
821
821
|
* Ignore captures in route matching
|
|
822
822
|
*/
|
|
823
823
|
ignoreCaptures?: boolean;
|
|
824
|
+
/**
|
|
825
|
+
* Ignore a generated wildcard route parameter when populating ctx.params
|
|
826
|
+
*
|
|
827
|
+
* @internal
|
|
828
|
+
*/
|
|
829
|
+
ignoreWildcardParameter?: string | number;
|
|
824
830
|
/**
|
|
825
831
|
* Treat path as a regular expression
|
|
826
832
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -821,6 +821,12 @@ type LayerOptions = {
|
|
|
821
821
|
* Ignore captures in route matching
|
|
822
822
|
*/
|
|
823
823
|
ignoreCaptures?: boolean;
|
|
824
|
+
/**
|
|
825
|
+
* Ignore a generated wildcard route parameter when populating ctx.params
|
|
826
|
+
*
|
|
827
|
+
* @internal
|
|
828
|
+
*/
|
|
829
|
+
ignoreWildcardParameter?: string | number;
|
|
824
830
|
/**
|
|
825
831
|
* Treat path as a regular expression
|
|
826
832
|
*/
|
package/dist/index.js
CHANGED
|
@@ -310,6 +310,9 @@ var Layer = class {
|
|
|
310
310
|
const parameterDefinition = this.paramNames[captureIndex];
|
|
311
311
|
if (parameterDefinition && capturedValue && capturedValue.length > 0) {
|
|
312
312
|
const parameterName = parameterDefinition.name;
|
|
313
|
+
if (this.opts.ignoreWildcardParameter === parameterName && parameterDefinition.type === "wildcard") {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
313
316
|
parameterValues[parameterName] = safeDecodeURIComponent(capturedValue);
|
|
314
317
|
}
|
|
315
318
|
}
|
|
@@ -942,9 +945,11 @@ var RouterImplementation = class {
|
|
|
942
945
|
finalPath = middlewarePath;
|
|
943
946
|
usePathToRegexp = false;
|
|
944
947
|
}
|
|
948
|
+
const ignoreWildcardParameter = effectiveExplicitPath === "" && middlewarePath === "{/*rest}" ? "rest" : void 0;
|
|
945
949
|
this.register(finalPath, [], middleware, {
|
|
946
950
|
end: isRootPath,
|
|
947
951
|
ignoreCaptures: !effectiveHasExplicitPath && !prefixHasParameters,
|
|
952
|
+
ignoreWildcardParameter,
|
|
948
953
|
pathAsRegExp: usePathToRegexp
|
|
949
954
|
});
|
|
950
955
|
}
|
|
@@ -1397,6 +1402,7 @@ var RouterImplementation = class {
|
|
|
1397
1402
|
strict: options.strict || false,
|
|
1398
1403
|
prefix: options.prefix || "",
|
|
1399
1404
|
ignoreCaptures: options.ignoreCaptures,
|
|
1405
|
+
ignoreWildcardParameter: options.ignoreWildcardParameter,
|
|
1400
1406
|
pathAsRegExp: options.pathAsRegExp
|
|
1401
1407
|
});
|
|
1402
1408
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -271,6 +271,9 @@ var Layer = class {
|
|
|
271
271
|
const parameterDefinition = this.paramNames[captureIndex];
|
|
272
272
|
if (parameterDefinition && capturedValue && capturedValue.length > 0) {
|
|
273
273
|
const parameterName = parameterDefinition.name;
|
|
274
|
+
if (this.opts.ignoreWildcardParameter === parameterName && parameterDefinition.type === "wildcard") {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
274
277
|
parameterValues[parameterName] = safeDecodeURIComponent(capturedValue);
|
|
275
278
|
}
|
|
276
279
|
}
|
|
@@ -903,9 +906,11 @@ var RouterImplementation = class {
|
|
|
903
906
|
finalPath = middlewarePath;
|
|
904
907
|
usePathToRegexp = false;
|
|
905
908
|
}
|
|
909
|
+
const ignoreWildcardParameter = effectiveExplicitPath === "" && middlewarePath === "{/*rest}" ? "rest" : void 0;
|
|
906
910
|
this.register(finalPath, [], middleware, {
|
|
907
911
|
end: isRootPath,
|
|
908
912
|
ignoreCaptures: !effectiveHasExplicitPath && !prefixHasParameters,
|
|
913
|
+
ignoreWildcardParameter,
|
|
909
914
|
pathAsRegExp: usePathToRegexp
|
|
910
915
|
});
|
|
911
916
|
}
|
|
@@ -1358,6 +1363,7 @@ var RouterImplementation = class {
|
|
|
1358
1363
|
strict: options.strict || false,
|
|
1359
1364
|
prefix: options.prefix || "",
|
|
1360
1365
|
ignoreCaptures: options.ignoreCaptures,
|
|
1366
|
+
ignoreWildcardParameter: options.ignoreWildcardParameter,
|
|
1361
1367
|
pathAsRegExp: options.pathAsRegExp
|
|
1362
1368
|
});
|
|
1363
1369
|
}
|
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.6.0",
|
|
5
5
|
"author": "Koa.js",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/koajs/router/issues",
|
|
@@ -31,27 +31,27 @@
|
|
|
31
31
|
"path-to-regexp": "^8.4.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@commitlint/cli": "^
|
|
35
|
-
"@commitlint/config-conventional": "^
|
|
34
|
+
"@commitlint/cli": "^21.0.2",
|
|
35
|
+
"@commitlint/config-conventional": "^21.0.2",
|
|
36
36
|
"@eslint/js": "^10.0.1",
|
|
37
37
|
"@koa/bodyparser": "^6.1.0",
|
|
38
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.3",
|
|
41
|
+
"@types/node": "^25.9.1",
|
|
42
42
|
"@types/supertest": "^7.2.0",
|
|
43
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
44
|
-
"@typescript-eslint/parser": "^8.
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^8.60.0",
|
|
44
|
+
"@typescript-eslint/parser": "^8.60.0",
|
|
45
45
|
"c8": "^11.0.0",
|
|
46
46
|
"chalk": "^5.6.2",
|
|
47
|
-
"eslint": "^10.
|
|
47
|
+
"eslint": "^10.4.1",
|
|
48
48
|
"eslint-plugin-unicorn": "^64.0.0",
|
|
49
49
|
"husky": "^9.1.7",
|
|
50
|
-
"joi": "^18.1
|
|
50
|
+
"joi": "^18.2.1",
|
|
51
51
|
"jsonwebtoken": "^9.0.3",
|
|
52
|
-
"koa": "^3.2.
|
|
53
|
-
"lint-staged": "^
|
|
54
|
-
"np": "^11.2.
|
|
52
|
+
"koa": "^3.2.1",
|
|
53
|
+
"lint-staged": "^17.0.6",
|
|
54
|
+
"np": "^11.2.1",
|
|
55
55
|
"prettier": "^3.8.3",
|
|
56
56
|
"rimraf": "^6.1.3",
|
|
57
57
|
"supertest": "^7.2.2",
|