@koa/router 15.5.0 → 15.7.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 +29 -23
- package/dist/index.mjs +29 -23
- package/package.json +14 -14
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
|
}
|
|
@@ -516,12 +519,12 @@ var Layer = class {
|
|
|
516
519
|
* @private
|
|
517
520
|
*/
|
|
518
521
|
_insertParamMiddleware(middlewareStack, parameterMiddleware, parameterNamesList, currentParameterPosition) {
|
|
519
|
-
let
|
|
522
|
+
let isInserted = false;
|
|
520
523
|
for (let stackIndex = 0; stackIndex < middlewareStack.length; stackIndex++) {
|
|
521
524
|
const existingMiddleware = middlewareStack[stackIndex];
|
|
522
525
|
if (!existingMiddleware.param) {
|
|
523
526
|
middlewareStack.splice(stackIndex, 0, parameterMiddleware);
|
|
524
|
-
|
|
527
|
+
isInserted = true;
|
|
525
528
|
break;
|
|
526
529
|
}
|
|
527
530
|
const existingParameterPosition = parameterNamesList.indexOf(
|
|
@@ -529,11 +532,11 @@ var Layer = class {
|
|
|
529
532
|
);
|
|
530
533
|
if (existingParameterPosition > currentParameterPosition) {
|
|
531
534
|
middlewareStack.splice(stackIndex, 0, parameterMiddleware);
|
|
532
|
-
|
|
535
|
+
isInserted = true;
|
|
533
536
|
break;
|
|
534
537
|
}
|
|
535
538
|
}
|
|
536
|
-
if (!
|
|
539
|
+
if (!isInserted) {
|
|
537
540
|
middlewareStack.push(parameterMiddleware);
|
|
538
541
|
}
|
|
539
542
|
}
|
|
@@ -562,9 +565,9 @@ var Layer = class {
|
|
|
562
565
|
_applyPrefix(prefixPath) {
|
|
563
566
|
const isRootPath = this.path === "/";
|
|
564
567
|
const isStrictMode = this.opts.strict === true;
|
|
565
|
-
const
|
|
566
|
-
const
|
|
567
|
-
if (
|
|
568
|
+
const isPrefixHasParameters = prefixPath.includes(":");
|
|
569
|
+
const isPathIsRawRegex = this.opts.pathAsRegExp === true && typeof this.path === "string";
|
|
570
|
+
if (isPrefixHasParameters && isPathIsRawRegex) {
|
|
568
571
|
const currentPath = this.path;
|
|
569
572
|
if (currentPath === String.raw`(?:\/|$)` || currentPath === String.raw`(?:\\\/|$)`) {
|
|
570
573
|
this.path = "{/*rest}";
|
|
@@ -581,9 +584,9 @@ var Layer = class {
|
|
|
581
584
|
* @private
|
|
582
585
|
*/
|
|
583
586
|
_reconfigurePathMatching(prefixPath) {
|
|
584
|
-
const
|
|
587
|
+
const isTreatAsRegExp = this.opts.pathAsRegExp === true;
|
|
585
588
|
const prefixHasParameters = prefixPath && prefixPath.includes(":");
|
|
586
|
-
if (prefixHasParameters &&
|
|
589
|
+
if (prefixHasParameters && isTreatAsRegExp) {
|
|
587
590
|
const options = normalizeLayerOptionsToPathToRegexp(this.opts);
|
|
588
591
|
const { regexp, keys } = compilePathToRegexp(
|
|
589
592
|
this.path,
|
|
@@ -592,7 +595,7 @@ var Layer = class {
|
|
|
592
595
|
this.regexp = regexp;
|
|
593
596
|
this.paramNames = keys;
|
|
594
597
|
this.opts.pathAsRegExp = false;
|
|
595
|
-
} else if (
|
|
598
|
+
} else if (isTreatAsRegExp) {
|
|
596
599
|
const pathString = this.path;
|
|
597
600
|
const anchoredPattern = pathString.startsWith("^") ? pathString : `^${pathString}`;
|
|
598
601
|
this.regexp = this.path instanceof RegExp ? this.path : new RegExp(anchoredPattern);
|
|
@@ -780,10 +783,10 @@ var RouterImplementation = class {
|
|
|
780
783
|
return temporaryLayer.url(...arguments_);
|
|
781
784
|
}
|
|
782
785
|
use(...middleware) {
|
|
783
|
-
let explicitPath;
|
|
784
786
|
if (this._isPathArray(middleware[0])) {
|
|
785
787
|
return this._useWithPathArray(middleware);
|
|
786
788
|
}
|
|
789
|
+
let explicitPath;
|
|
787
790
|
const hasExplicitPath = this._hasExplicitPath(middleware[0]);
|
|
788
791
|
if (hasExplicitPath) {
|
|
789
792
|
explicitPath = middleware.shift();
|
|
@@ -921,31 +924,33 @@ var RouterImplementation = class {
|
|
|
921
924
|
* @private
|
|
922
925
|
*/
|
|
923
926
|
_registerMiddleware(middleware, explicitPath, hasExplicitPath) {
|
|
924
|
-
const
|
|
927
|
+
const isPrefixHasParameters = hasPathParameters(
|
|
925
928
|
this.opts.prefix || "",
|
|
926
929
|
this.opts
|
|
927
930
|
);
|
|
928
931
|
const effectiveExplicitPath = (() => {
|
|
929
932
|
if (explicitPath !== void 0) return explicitPath;
|
|
930
|
-
if (
|
|
933
|
+
if (isPrefixHasParameters) return "";
|
|
931
934
|
return;
|
|
932
935
|
})();
|
|
933
|
-
const
|
|
936
|
+
const isEffectiveHasExplicitPath = hasExplicitPath || explicitPath === void 0 && isPrefixHasParameters;
|
|
934
937
|
const { path: middlewarePath, pathAsRegExp } = determineMiddlewarePath(
|
|
935
938
|
effectiveExplicitPath,
|
|
936
|
-
|
|
939
|
+
isPrefixHasParameters
|
|
937
940
|
);
|
|
938
941
|
let finalPath = middlewarePath;
|
|
939
|
-
let
|
|
940
|
-
const isRootPath =
|
|
941
|
-
if (
|
|
942
|
+
let isUsePathToRegexp = pathAsRegExp;
|
|
943
|
+
const isRootPath = isEffectiveHasExplicitPath && middlewarePath === "/";
|
|
944
|
+
if (isEffectiveHasExplicitPath && typeof middlewarePath === "string") {
|
|
942
945
|
finalPath = middlewarePath;
|
|
943
|
-
|
|
946
|
+
isUsePathToRegexp = false;
|
|
944
947
|
}
|
|
948
|
+
const ignoreWildcardParameter = effectiveExplicitPath === "" && middlewarePath === "{/*rest}" ? "rest" : void 0;
|
|
945
949
|
this.register(finalPath, [], middleware, {
|
|
946
950
|
end: isRootPath,
|
|
947
|
-
ignoreCaptures: !
|
|
948
|
-
|
|
951
|
+
ignoreCaptures: !isEffectiveHasExplicitPath && !isPrefixHasParameters,
|
|
952
|
+
ignoreWildcardParameter,
|
|
953
|
+
pathAsRegExp: isUsePathToRegexp
|
|
949
954
|
});
|
|
950
955
|
}
|
|
951
956
|
/**
|
|
@@ -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
|
}
|
|
@@ -1467,8 +1473,8 @@ var RouterImplementation = class {
|
|
|
1467
1473
|
if (layer.match(path)) {
|
|
1468
1474
|
matchResult.path.push(layer);
|
|
1469
1475
|
const isMiddleware = layer.methods.length === 0;
|
|
1470
|
-
const
|
|
1471
|
-
if (isMiddleware ||
|
|
1476
|
+
const isMatchesMethod = layer.methods.includes(normalizedMethod);
|
|
1477
|
+
if (isMiddleware || isMatchesMethod) {
|
|
1472
1478
|
matchResult.pathAndMethod.push(layer);
|
|
1473
1479
|
if (layer.methods.length > 0) {
|
|
1474
1480
|
matchResult.route = true;
|
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
|
}
|
|
@@ -477,12 +480,12 @@ var Layer = class {
|
|
|
477
480
|
* @private
|
|
478
481
|
*/
|
|
479
482
|
_insertParamMiddleware(middlewareStack, parameterMiddleware, parameterNamesList, currentParameterPosition) {
|
|
480
|
-
let
|
|
483
|
+
let isInserted = false;
|
|
481
484
|
for (let stackIndex = 0; stackIndex < middlewareStack.length; stackIndex++) {
|
|
482
485
|
const existingMiddleware = middlewareStack[stackIndex];
|
|
483
486
|
if (!existingMiddleware.param) {
|
|
484
487
|
middlewareStack.splice(stackIndex, 0, parameterMiddleware);
|
|
485
|
-
|
|
488
|
+
isInserted = true;
|
|
486
489
|
break;
|
|
487
490
|
}
|
|
488
491
|
const existingParameterPosition = parameterNamesList.indexOf(
|
|
@@ -490,11 +493,11 @@ var Layer = class {
|
|
|
490
493
|
);
|
|
491
494
|
if (existingParameterPosition > currentParameterPosition) {
|
|
492
495
|
middlewareStack.splice(stackIndex, 0, parameterMiddleware);
|
|
493
|
-
|
|
496
|
+
isInserted = true;
|
|
494
497
|
break;
|
|
495
498
|
}
|
|
496
499
|
}
|
|
497
|
-
if (!
|
|
500
|
+
if (!isInserted) {
|
|
498
501
|
middlewareStack.push(parameterMiddleware);
|
|
499
502
|
}
|
|
500
503
|
}
|
|
@@ -523,9 +526,9 @@ var Layer = class {
|
|
|
523
526
|
_applyPrefix(prefixPath) {
|
|
524
527
|
const isRootPath = this.path === "/";
|
|
525
528
|
const isStrictMode = this.opts.strict === true;
|
|
526
|
-
const
|
|
527
|
-
const
|
|
528
|
-
if (
|
|
529
|
+
const isPrefixHasParameters = prefixPath.includes(":");
|
|
530
|
+
const isPathIsRawRegex = this.opts.pathAsRegExp === true && typeof this.path === "string";
|
|
531
|
+
if (isPrefixHasParameters && isPathIsRawRegex) {
|
|
529
532
|
const currentPath = this.path;
|
|
530
533
|
if (currentPath === String.raw`(?:\/|$)` || currentPath === String.raw`(?:\\\/|$)`) {
|
|
531
534
|
this.path = "{/*rest}";
|
|
@@ -542,9 +545,9 @@ var Layer = class {
|
|
|
542
545
|
* @private
|
|
543
546
|
*/
|
|
544
547
|
_reconfigurePathMatching(prefixPath) {
|
|
545
|
-
const
|
|
548
|
+
const isTreatAsRegExp = this.opts.pathAsRegExp === true;
|
|
546
549
|
const prefixHasParameters = prefixPath && prefixPath.includes(":");
|
|
547
|
-
if (prefixHasParameters &&
|
|
550
|
+
if (prefixHasParameters && isTreatAsRegExp) {
|
|
548
551
|
const options = normalizeLayerOptionsToPathToRegexp(this.opts);
|
|
549
552
|
const { regexp, keys } = compilePathToRegexp(
|
|
550
553
|
this.path,
|
|
@@ -553,7 +556,7 @@ var Layer = class {
|
|
|
553
556
|
this.regexp = regexp;
|
|
554
557
|
this.paramNames = keys;
|
|
555
558
|
this.opts.pathAsRegExp = false;
|
|
556
|
-
} else if (
|
|
559
|
+
} else if (isTreatAsRegExp) {
|
|
557
560
|
const pathString = this.path;
|
|
558
561
|
const anchoredPattern = pathString.startsWith("^") ? pathString : `^${pathString}`;
|
|
559
562
|
this.regexp = this.path instanceof RegExp ? this.path : new RegExp(anchoredPattern);
|
|
@@ -741,10 +744,10 @@ var RouterImplementation = class {
|
|
|
741
744
|
return temporaryLayer.url(...arguments_);
|
|
742
745
|
}
|
|
743
746
|
use(...middleware) {
|
|
744
|
-
let explicitPath;
|
|
745
747
|
if (this._isPathArray(middleware[0])) {
|
|
746
748
|
return this._useWithPathArray(middleware);
|
|
747
749
|
}
|
|
750
|
+
let explicitPath;
|
|
748
751
|
const hasExplicitPath = this._hasExplicitPath(middleware[0]);
|
|
749
752
|
if (hasExplicitPath) {
|
|
750
753
|
explicitPath = middleware.shift();
|
|
@@ -882,31 +885,33 @@ var RouterImplementation = class {
|
|
|
882
885
|
* @private
|
|
883
886
|
*/
|
|
884
887
|
_registerMiddleware(middleware, explicitPath, hasExplicitPath) {
|
|
885
|
-
const
|
|
888
|
+
const isPrefixHasParameters = hasPathParameters(
|
|
886
889
|
this.opts.prefix || "",
|
|
887
890
|
this.opts
|
|
888
891
|
);
|
|
889
892
|
const effectiveExplicitPath = (() => {
|
|
890
893
|
if (explicitPath !== void 0) return explicitPath;
|
|
891
|
-
if (
|
|
894
|
+
if (isPrefixHasParameters) return "";
|
|
892
895
|
return;
|
|
893
896
|
})();
|
|
894
|
-
const
|
|
897
|
+
const isEffectiveHasExplicitPath = hasExplicitPath || explicitPath === void 0 && isPrefixHasParameters;
|
|
895
898
|
const { path: middlewarePath, pathAsRegExp } = determineMiddlewarePath(
|
|
896
899
|
effectiveExplicitPath,
|
|
897
|
-
|
|
900
|
+
isPrefixHasParameters
|
|
898
901
|
);
|
|
899
902
|
let finalPath = middlewarePath;
|
|
900
|
-
let
|
|
901
|
-
const isRootPath =
|
|
902
|
-
if (
|
|
903
|
+
let isUsePathToRegexp = pathAsRegExp;
|
|
904
|
+
const isRootPath = isEffectiveHasExplicitPath && middlewarePath === "/";
|
|
905
|
+
if (isEffectiveHasExplicitPath && typeof middlewarePath === "string") {
|
|
903
906
|
finalPath = middlewarePath;
|
|
904
|
-
|
|
907
|
+
isUsePathToRegexp = false;
|
|
905
908
|
}
|
|
909
|
+
const ignoreWildcardParameter = effectiveExplicitPath === "" && middlewarePath === "{/*rest}" ? "rest" : void 0;
|
|
906
910
|
this.register(finalPath, [], middleware, {
|
|
907
911
|
end: isRootPath,
|
|
908
|
-
ignoreCaptures: !
|
|
909
|
-
|
|
912
|
+
ignoreCaptures: !isEffectiveHasExplicitPath && !isPrefixHasParameters,
|
|
913
|
+
ignoreWildcardParameter,
|
|
914
|
+
pathAsRegExp: isUsePathToRegexp
|
|
910
915
|
});
|
|
911
916
|
}
|
|
912
917
|
/**
|
|
@@ -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
|
}
|
|
@@ -1428,8 +1434,8 @@ var RouterImplementation = class {
|
|
|
1428
1434
|
if (layer.match(path)) {
|
|
1429
1435
|
matchResult.path.push(layer);
|
|
1430
1436
|
const isMiddleware = layer.methods.length === 0;
|
|
1431
|
-
const
|
|
1432
|
-
if (isMiddleware ||
|
|
1437
|
+
const isMatchesMethod = layer.methods.includes(normalizedMethod);
|
|
1438
|
+
if (isMiddleware || isMatchesMethod) {
|
|
1433
1439
|
matchResult.pathAndMethod.push(layer);
|
|
1434
1440
|
if (layer.methods.length > 0) {
|
|
1435
1441
|
matchResult.route = true;
|
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.7.0",
|
|
5
5
|
"author": "Koa.js",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/koajs/router/issues",
|
|
@@ -31,28 +31,28 @@
|
|
|
31
31
|
"path-to-regexp": "^8.4.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@commitlint/cli": "^
|
|
35
|
-
"@commitlint/config-conventional": "^
|
|
34
|
+
"@commitlint/cli": "^21.2.0",
|
|
35
|
+
"@commitlint/config-conventional": "^21.2.0",
|
|
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": "^
|
|
40
|
+
"@types/koa": "^3.0.3",
|
|
41
|
+
"@types/node": "^26.1.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.62.1",
|
|
44
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
45
45
|
"c8": "^11.0.0",
|
|
46
46
|
"chalk": "^5.6.2",
|
|
47
|
-
"eslint": "^10.
|
|
48
|
-
"eslint-plugin-unicorn": "^
|
|
47
|
+
"eslint": "^10.6.0",
|
|
48
|
+
"eslint-plugin-unicorn": "^70.0.0",
|
|
49
49
|
"husky": "^9.1.7",
|
|
50
|
-
"joi": "^18.
|
|
50
|
+
"joi": "^18.2.3",
|
|
51
51
|
"jsonwebtoken": "^9.0.3",
|
|
52
|
-
"koa": "^3.2.
|
|
53
|
-
"lint-staged": "^
|
|
54
|
-
"np": "^11.2.
|
|
55
|
-
"prettier": "^3.
|
|
52
|
+
"koa": "^3.2.1",
|
|
53
|
+
"lint-staged": "^17.0.8",
|
|
54
|
+
"np": "^11.2.1",
|
|
55
|
+
"prettier": "^3.9.4",
|
|
56
56
|
"rimraf": "^6.1.3",
|
|
57
57
|
"supertest": "^7.2.2",
|
|
58
58
|
"ts-node": "^10.9.2",
|