-
-
Notifications
You must be signed in to change notification settings - Fork 7.8k
/
Copy pathroute-info-path-extractor.ts
126 lines (109 loc) · 3.93 KB
/
route-info-path-extractor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { VersioningType } from '@nestjs/common';
import {
RouteInfo,
VersioningOptions,
VersionValue,
} from '@nestjs/common/interfaces';
import {
addLeadingSlash,
stripEndSlash,
} from '@nestjs/common/utils/shared.utils';
import { ApplicationConfig } from '../application-config';
import { ExcludeRouteMetadata } from '../router/interfaces/exclude-route-metadata.interface';
import { isRouteExcluded } from '../router/utils';
import { RoutePathFactory } from './../router/route-path-factory';
export class RouteInfoPathExtractor {
private readonly routePathFactory: RoutePathFactory;
private readonly prefixPath: string;
private readonly excludedGlobalPrefixRoutes: ExcludeRouteMetadata[];
private readonly versioningConfig?: VersioningOptions;
constructor(private readonly applicationConfig: ApplicationConfig) {
this.routePathFactory = new RoutePathFactory(applicationConfig);
this.prefixPath = stripEndSlash(
addLeadingSlash(this.applicationConfig.getGlobalPrefix()),
);
this.excludedGlobalPrefixRoutes =
this.applicationConfig.getGlobalPrefixOptions().exclude!;
this.versioningConfig = this.applicationConfig.getVersioning();
}
public extractPathsFrom({ path, method, version }: RouteInfo): string[] {
const versionPaths = this.extractVersionPathFrom(version);
if (this.isAWildcard(path)) {
const entries =
versionPaths.length > 0
? versionPaths
.map(versionPath => [
this.prefixPath + versionPath + '$',
this.prefixPath + versionPath + addLeadingSlash(path),
])
.flat()
: this.prefixPath
? [this.prefixPath + '$', this.prefixPath + addLeadingSlash(path)]
: [addLeadingSlash(path)];
return Array.isArray(this.excludedGlobalPrefixRoutes)
? [
...entries,
...this.excludedGlobalPrefixRoutes
.map(route =>
Array.isArray(versionPaths) && versionPaths.length > 0
? versionPaths.map(v => v + addLeadingSlash(route.path))
: addLeadingSlash(route.path),
)
.flat(),
]
: entries;
}
return this.extractNonWildcardPathsFrom({ path, method, version });
}
public extractPathFrom(route: RouteInfo): string[] {
if (this.isAWildcard(route.path) && !route.version) {
return [addLeadingSlash(route.path)];
}
return this.extractNonWildcardPathsFrom(route);
}
private isAWildcard(path: string): boolean {
const isSimpleWildcard = ['*', '/*', '/*/', '(.*)', '/(.*)'];
if (isSimpleWildcard.includes(path)) {
return true;
}
const wildcardRegexp = /^\/\{.*\}.*|^\/\*.*$/;
return wildcardRegexp.test(path);
}
private extractNonWildcardPathsFrom({
path,
method,
version,
}: RouteInfo): string[] {
const versionPaths = this.extractVersionPathFrom(version);
if (
Array.isArray(this.excludedGlobalPrefixRoutes) &&
isRouteExcluded(this.excludedGlobalPrefixRoutes, path, method)
) {
if (!versionPaths.length) {
return [addLeadingSlash(path)];
}
return versionPaths.map(
versionPath => versionPath + addLeadingSlash(path),
);
}
if (!versionPaths.length) {
return [this.prefixPath + addLeadingSlash(path)];
}
return versionPaths.map(
versionPath => this.prefixPath + versionPath + addLeadingSlash(path),
);
}
private extractVersionPathFrom(versionValue?: VersionValue): string[] {
if (!versionValue || this.versioningConfig?.type !== VersioningType.URI)
return [];
const versionPrefix = this.routePathFactory.getVersionPrefix(
this.versioningConfig,
);
if (Array.isArray(versionValue)) {
return versionValue.map(version =>
addLeadingSlash(versionPrefix + version.toString()),
);
}
return [addLeadingSlash(versionPrefix + versionValue.toString())];
}
}