@nestjs/core 10.4.15 → 10.4.17
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/hooks/utils/get-instances-grouped-by-hierarchy-level.d.ts +3 -0
- package/hooks/utils/get-instances-grouped-by-hierarchy-level.js +30 -0
- package/hooks/utils/get-sorted-hierarchy-levels.d.ts +1 -0
- package/hooks/utils/get-sorted-hierarchy-levels.js +10 -0
- package/injector/opaque-key-factory/by-reference-module-opaque-key-factory.js +3 -2
- package/injector/topology-tree/topology-tree.d.ts +8 -0
- package/injector/topology-tree/topology-tree.js +51 -0
- package/injector/topology-tree/tree-node.d.ts +14 -0
- package/injector/topology-tree/tree-node.js +54 -0
- package/package.json +2 -2
- package/router/legacy-route-converter.d.ts +4 -1
- package/router/legacy-route-converter.js +19 -6
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { InjectionToken } from '@nestjs/common';
|
|
2
|
+
import { InstanceWrapper } from '../../injector/instance-wrapper';
|
|
3
|
+
export declare function getInstancesGroupedByHierarchyLevel(...collections: Array<Map<InjectionToken, InstanceWrapper> | Array<[InjectionToken, InstanceWrapper]>>): Map<number, unknown[]>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getInstancesGroupedByHierarchyLevel = getInstancesGroupedByHierarchyLevel;
|
|
4
|
+
function getInstancesGroupedByHierarchyLevel(...collections) {
|
|
5
|
+
const groupedByHierarchyLevel = new Map();
|
|
6
|
+
for (const collection of collections) {
|
|
7
|
+
for (const [_, wrapper] of collection) {
|
|
8
|
+
if (!wrapper.isDependencyTreeStatic()) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const level = wrapper.hierarchyLevel;
|
|
12
|
+
if (!groupedByHierarchyLevel.has(level)) {
|
|
13
|
+
groupedByHierarchyLevel.set(level, []);
|
|
14
|
+
}
|
|
15
|
+
const byHierarchyLevelGroup = groupedByHierarchyLevel.get(level);
|
|
16
|
+
if (wrapper.isTransient) {
|
|
17
|
+
const staticTransientInstances = wrapper
|
|
18
|
+
.getStaticTransientInstances()
|
|
19
|
+
.filter(i => !!i)
|
|
20
|
+
.map(i => i.instance);
|
|
21
|
+
byHierarchyLevelGroup.push(...staticTransientInstances);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (wrapper.instance) {
|
|
25
|
+
byHierarchyLevelGroup.push(wrapper.instance);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return groupedByHierarchyLevel;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getSortedHierarchyLevels(groups: Map<number, unknown[]>, order?: 'ASC' | 'DESC'): number[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSortedHierarchyLevels = getSortedHierarchyLevels;
|
|
4
|
+
function getSortedHierarchyLevels(groups, order = 'ASC') {
|
|
5
|
+
const comparator = order === 'ASC'
|
|
6
|
+
? (a, b) => a - b
|
|
7
|
+
: (a, b) => b - a;
|
|
8
|
+
const levels = Array.from(groups.keys()).sort(comparator);
|
|
9
|
+
return levels;
|
|
10
|
+
}
|
|
@@ -23,9 +23,10 @@ class ByReferenceModuleOpaqueKeyFactory {
|
|
|
23
23
|
moduleId = this.generateRandomString();
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
+
const delimiter = ':';
|
|
26
27
|
moduleId = dynamicMetadata
|
|
27
|
-
? `${this.generateRandomString()}
|
|
28
|
-
: `${this.generateRandomString()}
|
|
28
|
+
? `${this.generateRandomString()}${delimiter}${this.hashString(moduleCls.name + JSON.stringify(dynamicMetadata))}`
|
|
29
|
+
: `${this.generateRandomString()}${delimiter}${this.hashString(moduleCls.toString())}`;
|
|
29
30
|
}
|
|
30
31
|
originalRef[K_MODULE_ID] = moduleId;
|
|
31
32
|
return moduleId;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TopologyTree = void 0;
|
|
4
|
+
const tree_node_1 = require("./tree-node");
|
|
5
|
+
class TopologyTree {
|
|
6
|
+
constructor(moduleRef) {
|
|
7
|
+
this.links = new Map();
|
|
8
|
+
this.root = new tree_node_1.TreeNode({
|
|
9
|
+
value: moduleRef,
|
|
10
|
+
parent: null,
|
|
11
|
+
});
|
|
12
|
+
this.links.set(moduleRef, this.root);
|
|
13
|
+
this.traverseAndMapToTree(this.root);
|
|
14
|
+
}
|
|
15
|
+
walk(callback) {
|
|
16
|
+
function walkNode(node, depth = 1) {
|
|
17
|
+
callback(node.value, depth);
|
|
18
|
+
node.children.forEach(child => walkNode(child, depth + 1));
|
|
19
|
+
}
|
|
20
|
+
walkNode(this.root);
|
|
21
|
+
}
|
|
22
|
+
traverseAndMapToTree(node, depth = 1) {
|
|
23
|
+
if (!node.value.imports) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
node.value.imports.forEach(child => {
|
|
27
|
+
if (!child) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (this.links.has(child)) {
|
|
31
|
+
const existingSubtree = this.links.get(child);
|
|
32
|
+
if (node.hasCycleWith(child)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const existingDepth = existingSubtree.getDepth();
|
|
36
|
+
if (existingDepth < depth) {
|
|
37
|
+
existingSubtree.relink(node);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const childNode = new tree_node_1.TreeNode({
|
|
42
|
+
value: child,
|
|
43
|
+
parent: node,
|
|
44
|
+
});
|
|
45
|
+
node.addChild(childNode);
|
|
46
|
+
this.links.set(child, childNode);
|
|
47
|
+
this.traverseAndMapToTree(childNode, depth + 1);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.TopologyTree = TopologyTree;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class TreeNode<T> {
|
|
2
|
+
readonly value: T;
|
|
3
|
+
readonly children: Set<TreeNode<T>>;
|
|
4
|
+
private parent;
|
|
5
|
+
constructor({ value, parent }: {
|
|
6
|
+
value: T;
|
|
7
|
+
parent: TreeNode<T> | null;
|
|
8
|
+
});
|
|
9
|
+
addChild(child: TreeNode<T>): void;
|
|
10
|
+
removeChild(child: TreeNode<T>): void;
|
|
11
|
+
relink(parent: TreeNode<T>): void;
|
|
12
|
+
getDepth(): number;
|
|
13
|
+
hasCycleWith(target: T): boolean;
|
|
14
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TreeNode = void 0;
|
|
4
|
+
class TreeNode {
|
|
5
|
+
constructor({ value, parent }) {
|
|
6
|
+
this.children = new Set();
|
|
7
|
+
this.value = value;
|
|
8
|
+
this.parent = parent;
|
|
9
|
+
}
|
|
10
|
+
addChild(child) {
|
|
11
|
+
this.children.add(child);
|
|
12
|
+
}
|
|
13
|
+
removeChild(child) {
|
|
14
|
+
this.children.delete(child);
|
|
15
|
+
}
|
|
16
|
+
relink(parent) {
|
|
17
|
+
this.parent?.removeChild(this);
|
|
18
|
+
this.parent = parent;
|
|
19
|
+
this.parent.addChild(this);
|
|
20
|
+
}
|
|
21
|
+
getDepth() {
|
|
22
|
+
const visited = new Set();
|
|
23
|
+
let depth = 0;
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
25
|
+
let current = this;
|
|
26
|
+
while (current) {
|
|
27
|
+
depth++;
|
|
28
|
+
current = current.parent;
|
|
29
|
+
// Stop on cycle
|
|
30
|
+
if (visited.has(current)) {
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
visited.add(current);
|
|
34
|
+
}
|
|
35
|
+
return depth;
|
|
36
|
+
}
|
|
37
|
+
hasCycleWith(target) {
|
|
38
|
+
const visited = new Set();
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
40
|
+
let current = this;
|
|
41
|
+
while (current) {
|
|
42
|
+
if (current.value === target) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
current = current.parent;
|
|
46
|
+
if (visited.has(current)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
visited.add(current);
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.TreeNode = TreeNode;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/core",
|
|
3
|
-
"version": "10.4.
|
|
3
|
+
"version": "10.4.17",
|
|
4
4
|
"description": "Nest - modern, fast, powerful node.js web framework (@core)",
|
|
5
5
|
"author": "Kamil Mysliwiec",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"uid": "2.0.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@nestjs/common": "10.4.
|
|
39
|
+
"@nestjs/common": "10.4.17"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@nestjs/common": "^10.0.0",
|
|
@@ -5,9 +5,12 @@ export declare class LegacyRouteConverter {
|
|
|
5
5
|
* path-to-regexp used by Express>=v5 and @fastify/middie>=v9 no longer support unnamed wildcards.
|
|
6
6
|
* This method attempts to convert the old syntax to the new one, and logs an error if it fails.
|
|
7
7
|
* @param route The route to convert.
|
|
8
|
+
* @param options Options object.
|
|
8
9
|
* @returns The converted route, or the original route if it cannot be converted.
|
|
9
10
|
*/
|
|
10
|
-
static tryConvert(route: string
|
|
11
|
+
static tryConvert(route: string, options?: {
|
|
12
|
+
logs?: boolean;
|
|
13
|
+
}): string;
|
|
11
14
|
static printError(route: string): void;
|
|
12
15
|
static printWarning(route: string): void;
|
|
13
16
|
}
|
|
@@ -9,39 +9,52 @@ class LegacyRouteConverter {
|
|
|
9
9
|
* path-to-regexp used by Express>=v5 and @fastify/middie>=v9 no longer support unnamed wildcards.
|
|
10
10
|
* This method attempts to convert the old syntax to the new one, and logs an error if it fails.
|
|
11
11
|
* @param route The route to convert.
|
|
12
|
+
* @param options Options object.
|
|
12
13
|
* @returns The converted route, or the original route if it cannot be converted.
|
|
13
14
|
*/
|
|
14
|
-
static tryConvert(route) {
|
|
15
|
-
// Normalize path to eliminate additional
|
|
15
|
+
static tryConvert(route, options) {
|
|
16
|
+
// Normalize path to eliminate additional if statements.
|
|
16
17
|
const routeWithLeadingSlash = route.startsWith('/') ? route : `/${route}`;
|
|
17
18
|
const normalizedRoute = route.endsWith('/')
|
|
18
19
|
? routeWithLeadingSlash
|
|
19
20
|
: `${routeWithLeadingSlash}/`;
|
|
21
|
+
const loggingEnabled = options?.logs ?? true;
|
|
22
|
+
const printWarning = loggingEnabled
|
|
23
|
+
? this.printWarning.bind(this)
|
|
24
|
+
: () => { };
|
|
20
25
|
if (normalizedRoute.endsWith('/(.*)/')) {
|
|
21
26
|
// Skip printing warning for the "all" wildcard.
|
|
22
27
|
if (normalizedRoute !== '/(.*)/') {
|
|
23
|
-
|
|
28
|
+
printWarning(route);
|
|
24
29
|
}
|
|
25
30
|
return route.replace('(.*)', '{*path}');
|
|
26
31
|
}
|
|
27
32
|
if (normalizedRoute.endsWith('/*/')) {
|
|
28
33
|
// Skip printing warning for the "all" wildcard.
|
|
29
34
|
if (normalizedRoute !== '/*/') {
|
|
30
|
-
|
|
35
|
+
printWarning(route);
|
|
31
36
|
}
|
|
32
37
|
return route.replace('*', '{*path}');
|
|
33
38
|
}
|
|
34
39
|
if (normalizedRoute.endsWith('/+/')) {
|
|
35
|
-
|
|
40
|
+
printWarning(route);
|
|
36
41
|
return route.replace('/+', '/*path');
|
|
37
42
|
}
|
|
43
|
+
// When route includes any wildcard segments in the middle.
|
|
44
|
+
if (normalizedRoute.includes('/*/')) {
|
|
45
|
+
printWarning(route);
|
|
46
|
+
// Replace each /*/ segment with a named parameter using different name for each segment.
|
|
47
|
+
return route.replaceAll('/*/', (match, offset) => {
|
|
48
|
+
return `/*path${offset}/`;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
38
51
|
return route;
|
|
39
52
|
}
|
|
40
53
|
static printError(route) {
|
|
41
54
|
this.logger.error(UNSUPPORTED_PATH_MESSAGE `${route}`);
|
|
42
55
|
}
|
|
43
56
|
static printWarning(route) {
|
|
44
|
-
this.logger.warn(UNSUPPORTED_PATH_MESSAGE `${route}` + ' Attempting to convert...');
|
|
57
|
+
this.logger.warn(UNSUPPORTED_PATH_MESSAGE `${route}` + ' Attempting to auto-convert...');
|
|
45
58
|
}
|
|
46
59
|
}
|
|
47
60
|
exports.LegacyRouteConverter = LegacyRouteConverter;
|