@nestia/sdk 3.0.5 → 3.1.0-dev.20240426
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/lib/NestiaSdkApplication.d.ts +1 -0
- package/lib/NestiaSdkApplication.js +17 -17
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/analyses/AccessorAnalyzer.d.ts +3 -2
- package/lib/analyses/AccessorAnalyzer.js.map +1 -1
- package/lib/analyses/ExceptionAnalyzer.d.ts +11 -3
- package/lib/analyses/ExceptionAnalyzer.js +23 -18
- package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
- package/lib/analyses/GenericAnalyzer.d.ts +1 -0
- package/lib/analyses/ImportAnalyzer.d.ts +6 -1
- package/lib/analyses/ImportAnalyzer.js +27 -29
- package/lib/analyses/ImportAnalyzer.js.map +1 -1
- package/lib/analyses/PathAnalyzer.d.ts +0 -5
- package/lib/analyses/PathAnalyzer.js +0 -32
- package/lib/analyses/PathAnalyzer.js.map +1 -1
- package/lib/analyses/{ReflectAnalyzer.d.ts → ReflectControllerAnalyzer.d.ts} +3 -4
- package/lib/analyses/ReflectControllerAnalyzer.js +145 -0
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -0
- package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +10 -0
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +224 -0
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -0
- package/lib/analyses/ReflectMetadataAnalyzer.d.ts +8 -0
- package/lib/analyses/ReflectMetadataAnalyzer.js +34 -0
- package/lib/analyses/ReflectMetadataAnalyzer.js.map +1 -0
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.d.ts +10 -0
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +78 -0
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -0
- package/lib/analyses/SecurityAnalyzer.js +1 -1
- package/lib/analyses/SecurityAnalyzer.js.map +1 -1
- package/lib/analyses/TypedControllerAnalyzer.d.ts +9 -0
- package/lib/analyses/TypedControllerAnalyzer.js +77 -0
- package/lib/analyses/TypedControllerAnalyzer.js.map +1 -0
- package/lib/analyses/TypedHttpOperationAnalyzer.d.ts +16 -0
- package/lib/analyses/TypedHttpOperationAnalyzer.js +251 -0
- package/lib/analyses/TypedHttpOperationAnalyzer.js.map +1 -0
- package/lib/analyses/TypedWebSocketOperationAnalyzer.d.ts +16 -0
- package/lib/analyses/TypedWebSocketOperationAnalyzer.js +218 -0
- package/lib/analyses/TypedWebSocketOperationAnalyzer.js.map +1 -0
- package/lib/executable/internal/NestiaConfigLoader.d.ts +1 -0
- package/lib/generates/CloneGenerator.d.ts +3 -4
- package/lib/generates/CloneGenerator.js +8 -8
- package/lib/generates/CloneGenerator.js.map +1 -1
- package/lib/generates/E2eGenerator.d.ts +3 -4
- package/lib/generates/E2eGenerator.js +7 -7
- package/lib/generates/E2eGenerator.js.map +1 -1
- package/lib/generates/SdkGenerator.d.ts +4 -4
- package/lib/generates/SdkGenerator.js +8 -8
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.d.ts +5 -2
- package/lib/generates/SwaggerGenerator.js +15 -13
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/E2eFileProgrammer.d.ts +4 -5
- package/lib/generates/internal/E2eFileProgrammer.js +13 -12
- package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
- package/lib/generates/internal/FilePrinter.d.ts +1 -0
- package/lib/generates/internal/ImportDictionary.d.ts +1 -0
- package/lib/generates/internal/SdkAliasCollection.d.ts +9 -8
- package/lib/generates/internal/SdkAliasCollection.js +20 -20
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.d.ts +1 -1
- package/lib/generates/internal/SdkDistributionComposer.js +36 -2
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.d.ts +4 -4
- package/lib/generates/internal/SdkFileProgrammer.js +10 -7
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneProgrammer.d.ts +13 -0
- package/lib/generates/internal/{SdkCloneProgrammer.js → SdkHttpCloneProgrammer.js} +14 -14
- package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +12 -0
- package/lib/generates/internal/{SdkFunctionProgrammer.js → SdkHttpFunctionProgrammer.js} +12 -12
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +12 -0
- package/lib/generates/internal/{SdkNamespaceProgrammer.js → SdkHttpNamespaceProgrammer.js} +26 -26
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkHttpRouteProgrammer.d.ts +8 -0
- package/lib/generates/internal/{SdkRouteProgrammer.js → SdkHttpRouteProgrammer.js} +11 -11
- package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +13 -0
- package/lib/generates/internal/{SdkSimulationProgrammer.js → SdkHttpSimulationProgrammer.js} +18 -18
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkRouteDirectory.d.ts +3 -2
- package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
- package/lib/generates/internal/SdkTypeProgrammer.d.ts +4 -3
- package/lib/generates/internal/SdkTypeProgrammer.js +33 -33
- package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.d.ts +8 -0
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +115 -0
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +8 -0
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +79 -0
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -0
- package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +6 -5
- package/lib/generates/internal/SwaggerSchemaGenerator.js +3 -1
- package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -1
- package/lib/structures/INestiaProject.d.ts +1 -0
- package/lib/structures/IReflectController.d.ts +15 -0
- package/lib/structures/{IRoute.js → IReflectController.js} +1 -1
- package/lib/structures/IReflectController.js.map +1 -0
- package/lib/structures/{IController.d.ts → IReflectHttpOperation.d.ts} +15 -25
- package/lib/structures/IReflectHttpOperation.js +3 -0
- package/lib/structures/IReflectHttpOperation.js.map +1 -0
- package/lib/structures/IReflectWebSocketOperation.d.ts +16 -0
- package/lib/structures/IReflectWebSocketOperation.js +3 -0
- package/lib/structures/IReflectWebSocketOperation.js.map +1 -0
- package/lib/structures/ISwaggerError.d.ts +2 -2
- package/lib/structures/ITypeTuple.d.ts +1 -0
- package/lib/structures/{IRoute.d.ts → ITypedHttpRoute.d.ts} +12 -12
- package/lib/structures/{IController.js → ITypedHttpRoute.js} +1 -1
- package/lib/structures/ITypedHttpRoute.js.map +1 -0
- package/lib/structures/ITypedWebSocketRoute.d.ts +54 -0
- package/lib/structures/ITypedWebSocketRoute.js +3 -0
- package/lib/structures/ITypedWebSocketRoute.js.map +1 -0
- package/lib/structures/TypeEntry.d.ts +1 -0
- package/lib/utils/VersioningStrategy.d.ts +6 -0
- package/lib/utils/VersioningStrategy.js +22 -0
- package/lib/utils/VersioningStrategy.js.map +1 -0
- package/package.json +8 -6
- package/src/NestiaSdkApplication.ts +36 -34
- package/src/analyses/AccessorAnalyzer.ts +12 -5
- package/src/analyses/ExceptionAnalyzer.ts +49 -39
- package/src/analyses/ImportAnalyzer.ts +123 -104
- package/src/analyses/PathAnalyzer.ts +0 -41
- package/src/analyses/ReflectControllerAnalyzer.ts +155 -0
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +290 -0
- package/src/analyses/ReflectMetadataAnalyzer.ts +53 -0
- package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +96 -0
- package/src/analyses/SecurityAnalyzer.ts +2 -1
- package/src/analyses/TypedControllerAnalyzer.ts +92 -0
- package/src/analyses/TypedHttpOperationAnalyzer.ts +352 -0
- package/src/analyses/TypedWebSocketOperationAnalyzer.ts +368 -0
- package/src/generates/CloneGenerator.ts +17 -15
- package/src/generates/E2eGenerator.ts +10 -12
- package/src/generates/SdkGenerator.ts +19 -12
- package/src/generates/SwaggerGenerator.ts +31 -21
- package/src/generates/internal/E2eFileProgrammer.ts +20 -24
- package/src/generates/internal/SdkAliasCollection.ts +38 -33
- package/src/generates/internal/SdkDistributionComposer.ts +13 -4
- package/src/generates/internal/SdkFileProgrammer.ts +17 -13
- package/src/generates/internal/{SdkCloneProgrammer.ts → SdkHttpCloneProgrammer.ts} +14 -15
- package/src/generates/internal/{SdkFunctionProgrammer.ts → SdkHttpFunctionProgrammer.ts} +24 -23
- package/src/generates/internal/{SdkNamespaceProgrammer.ts → SdkHttpNamespaceProgrammer.ts} +44 -49
- package/src/generates/internal/{SdkRouteProgrammer.ts → SdkHttpRouteProgrammer.ts} +12 -13
- package/src/generates/internal/{SdkSimulationProgrammer.ts → SdkHttpSimulationProgrammer.ts} +23 -25
- package/src/generates/internal/SdkRouteDirectory.ts +3 -2
- package/src/generates/internal/SdkTypeProgrammer.ts +43 -37
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +378 -0
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +248 -0
- package/src/generates/internal/SwaggerSchemaGenerator.ts +26 -21
- package/src/structures/IReflectController.ts +17 -0
- package/src/structures/{IController.ts → IReflectHttpOperation.ts} +78 -94
- package/src/structures/IReflectWebSocketOperation.ts +17 -0
- package/src/structures/ISwaggerError.ts +2 -2
- package/src/structures/{IRoute.ts → ITypedHttpRoute.ts} +14 -12
- package/src/structures/ITypedWebSocketRoute.ts +67 -0
- package/src/utils/VersioningStrategy.ts +28 -0
- package/lib/analyses/ControllerAnalyzer.d.ts +0 -7
- package/lib/analyses/ControllerAnalyzer.js +0 -269
- package/lib/analyses/ControllerAnalyzer.js.map +0 -1
- package/lib/analyses/ReflectAnalyzer.js +0 -377
- package/lib/analyses/ReflectAnalyzer.js.map +0 -1
- package/lib/generates/internal/SdkCloneProgrammer.d.ts +0 -12
- package/lib/generates/internal/SdkCloneProgrammer.js.map +0 -1
- package/lib/generates/internal/SdkFunctionProgrammer.d.ts +0 -11
- package/lib/generates/internal/SdkFunctionProgrammer.js.map +0 -1
- package/lib/generates/internal/SdkNamespaceProgrammer.d.ts +0 -11
- package/lib/generates/internal/SdkNamespaceProgrammer.js.map +0 -1
- package/lib/generates/internal/SdkRouteProgrammer.d.ts +0 -7
- package/lib/generates/internal/SdkRouteProgrammer.js.map +0 -1
- package/lib/generates/internal/SdkSimulationProgrammer.d.ts +0 -12
- package/lib/generates/internal/SdkSimulationProgrammer.js.map +0 -1
- package/lib/structures/IController.js.map +0 -1
- package/lib/structures/IRoute.js.map +0 -1
- package/src/analyses/ControllerAnalyzer.ts +0 -402
- package/src/analyses/ReflectAnalyzer.ts +0 -471
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HOST_METADATA,
|
|
3
|
+
PATH_METADATA,
|
|
4
|
+
SCOPE_OPTIONS_METADATA,
|
|
5
|
+
} from "@nestjs/common/constants";
|
|
6
|
+
|
|
7
|
+
import { INestiaProject } from "../structures/INestiaProject";
|
|
8
|
+
import { IReflectController } from "../structures/IReflectController";
|
|
9
|
+
import { IReflectHttpOperation } from "../structures/IReflectHttpOperation";
|
|
10
|
+
import { IReflectWebSocketOperation } from "../structures/IReflectWebSocketOperation";
|
|
11
|
+
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
12
|
+
import { ReflectHttpOperationAnalyzer } from "./ReflectHttpOperationAnalyzer";
|
|
13
|
+
import { ReflectMetadataAnalyzer } from "./ReflectMetadataAnalyzer";
|
|
14
|
+
import { ReflectWebSocketOperationAnalyzer } from "./ReflectWebSocketOperationAnalyzer";
|
|
15
|
+
|
|
16
|
+
type IModule = {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export namespace ReflectControllerAnalyzer {
|
|
21
|
+
export const analyze =
|
|
22
|
+
(project: INestiaProject) =>
|
|
23
|
+
async (
|
|
24
|
+
unique: WeakSet<any>,
|
|
25
|
+
file: string,
|
|
26
|
+
prefixes: string[],
|
|
27
|
+
target?: Function,
|
|
28
|
+
): Promise<IReflectController[]> => {
|
|
29
|
+
const module: IModule = await (async () => {
|
|
30
|
+
try {
|
|
31
|
+
return await import(file);
|
|
32
|
+
} catch (exp) {
|
|
33
|
+
console.log(
|
|
34
|
+
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",
|
|
35
|
+
);
|
|
36
|
+
console.log(`Error on "${file}" file. Check your code.`);
|
|
37
|
+
console.log(exp);
|
|
38
|
+
console.log(
|
|
39
|
+
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",
|
|
40
|
+
);
|
|
41
|
+
process.exit(-1);
|
|
42
|
+
}
|
|
43
|
+
})();
|
|
44
|
+
const ret: IReflectController[] = [];
|
|
45
|
+
|
|
46
|
+
for (const [key, value] of Object.entries(module)) {
|
|
47
|
+
if (typeof value !== "function" || unique.has(value)) continue;
|
|
48
|
+
else if ((target ?? value) !== value) continue;
|
|
49
|
+
else unique.add(value);
|
|
50
|
+
|
|
51
|
+
const result: IReflectController | null = _Analyze_controller(project)({
|
|
52
|
+
file,
|
|
53
|
+
name: key,
|
|
54
|
+
creator: value,
|
|
55
|
+
prefixes,
|
|
56
|
+
});
|
|
57
|
+
if (result !== null) ret.push(result);
|
|
58
|
+
}
|
|
59
|
+
return ret;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/* ---------------------------------------------------------
|
|
63
|
+
CONTROLLER
|
|
64
|
+
--------------------------------------------------------- */
|
|
65
|
+
const _Analyze_controller =
|
|
66
|
+
(project: INestiaProject) =>
|
|
67
|
+
(props: {
|
|
68
|
+
file: string;
|
|
69
|
+
name: string;
|
|
70
|
+
creator: any;
|
|
71
|
+
prefixes: string[];
|
|
72
|
+
}): IReflectController | null => {
|
|
73
|
+
//----
|
|
74
|
+
// VALIDATIONS
|
|
75
|
+
//----
|
|
76
|
+
// MUST BE TYPE OF A CREATOR WHO HAS THE CONSTRUCTOR
|
|
77
|
+
if (
|
|
78
|
+
!(
|
|
79
|
+
props.creator instanceof Function &&
|
|
80
|
+
props.creator.constructor instanceof Function
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
return null;
|
|
84
|
+
// MUST HAVE THOSE MATADATA
|
|
85
|
+
else if (
|
|
86
|
+
ArrayUtil.has(
|
|
87
|
+
Reflect.getMetadataKeys(props.creator),
|
|
88
|
+
PATH_METADATA,
|
|
89
|
+
HOST_METADATA,
|
|
90
|
+
SCOPE_OPTIONS_METADATA,
|
|
91
|
+
) === false
|
|
92
|
+
)
|
|
93
|
+
return null;
|
|
94
|
+
|
|
95
|
+
//----
|
|
96
|
+
// CONSTRUCTION
|
|
97
|
+
//----
|
|
98
|
+
// BASIC INFO
|
|
99
|
+
const meta: IReflectController = {
|
|
100
|
+
constructor: props.creator,
|
|
101
|
+
prototype: props.creator.prototype,
|
|
102
|
+
file: props.file,
|
|
103
|
+
name: props.name,
|
|
104
|
+
operations: [],
|
|
105
|
+
prefixes: props.prefixes,
|
|
106
|
+
paths: ReflectMetadataAnalyzer.paths(props.creator).filter((str) => {
|
|
107
|
+
if (str.includes("*") === true) {
|
|
108
|
+
project.warnings.push({
|
|
109
|
+
file: props.file,
|
|
110
|
+
controller: props.name,
|
|
111
|
+
function: null,
|
|
112
|
+
message: "@nestia/sdk does not compose wildcard controller.",
|
|
113
|
+
});
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}),
|
|
118
|
+
versions: ReflectMetadataAnalyzer.versions(props.creator),
|
|
119
|
+
security: ReflectMetadataAnalyzer.securities(props.creator),
|
|
120
|
+
swaggerTgas:
|
|
121
|
+
Reflect.getMetadata("swagger/apiUseTags", props.creator) ?? [],
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// PARSE CHILDREN DATA
|
|
125
|
+
for (const [key, value] of _Get_prototype_entries(props.creator)) {
|
|
126
|
+
if (typeof value !== "function") continue;
|
|
127
|
+
const next = {
|
|
128
|
+
controller: meta,
|
|
129
|
+
name: key,
|
|
130
|
+
function: value,
|
|
131
|
+
};
|
|
132
|
+
const child: IReflectHttpOperation | IReflectWebSocketOperation | null =
|
|
133
|
+
ReflectWebSocketOperationAnalyzer.analyze(project)(next) ??
|
|
134
|
+
ReflectHttpOperationAnalyzer.analyze(project)(next);
|
|
135
|
+
if (child !== null) meta.operations.push(child);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// RETURNS
|
|
139
|
+
return meta;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
function _Get_prototype_entries(creator: any): Array<[string, unknown]> {
|
|
143
|
+
const keyList = Object.getOwnPropertyNames(creator.prototype);
|
|
144
|
+
const entries: Array<[string, unknown]> = keyList.map((key) => [
|
|
145
|
+
key,
|
|
146
|
+
creator.prototype[key],
|
|
147
|
+
]);
|
|
148
|
+
|
|
149
|
+
const parent = Object.getPrototypeOf(creator);
|
|
150
|
+
if (parent.prototype !== undefined)
|
|
151
|
+
entries.push(..._Get_prototype_entries(parent));
|
|
152
|
+
|
|
153
|
+
return entries;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HEADERS_METADATA,
|
|
3
|
+
HTTP_CODE_METADATA,
|
|
4
|
+
INTERCEPTORS_METADATA,
|
|
5
|
+
METHOD_METADATA,
|
|
6
|
+
PATH_METADATA,
|
|
7
|
+
ROUTE_ARGS_METADATA,
|
|
8
|
+
} from "@nestjs/common/constants";
|
|
9
|
+
import { RouteParamtypes } from "@nestjs/common/enums/route-paramtypes.enum";
|
|
10
|
+
import { ranges } from "tstl";
|
|
11
|
+
|
|
12
|
+
import { IErrorReport } from "../structures/IErrorReport";
|
|
13
|
+
import { INestiaProject } from "../structures/INestiaProject";
|
|
14
|
+
import { IReflectController } from "../structures/IReflectController";
|
|
15
|
+
import { IReflectHttpOperation } from "../structures/IReflectHttpOperation";
|
|
16
|
+
import { ParamCategory } from "../structures/ParamCategory";
|
|
17
|
+
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
18
|
+
import { PathAnalyzer } from "./PathAnalyzer";
|
|
19
|
+
import { ReflectMetadataAnalyzer } from "./ReflectMetadataAnalyzer";
|
|
20
|
+
|
|
21
|
+
export namespace ReflectHttpOperationAnalyzer {
|
|
22
|
+
export const analyze =
|
|
23
|
+
(project: INestiaProject) =>
|
|
24
|
+
(props: {
|
|
25
|
+
controller: IReflectController;
|
|
26
|
+
function: Function;
|
|
27
|
+
name: string;
|
|
28
|
+
}): IReflectHttpOperation | null => {
|
|
29
|
+
if (
|
|
30
|
+
ArrayUtil.has(
|
|
31
|
+
Reflect.getMetadataKeys(props.function),
|
|
32
|
+
PATH_METADATA,
|
|
33
|
+
METHOD_METADATA,
|
|
34
|
+
) === false
|
|
35
|
+
)
|
|
36
|
+
return null;
|
|
37
|
+
|
|
38
|
+
const errors: IErrorReport[] = [];
|
|
39
|
+
|
|
40
|
+
//----
|
|
41
|
+
// CONSTRUCTION
|
|
42
|
+
//----
|
|
43
|
+
// BASIC INFO
|
|
44
|
+
const encrypted: boolean = hasInterceptor("EncryptedRouteInterceptor")(
|
|
45
|
+
props.function,
|
|
46
|
+
);
|
|
47
|
+
const query: boolean = hasInterceptor("TypedQueryRouteInterceptor")(
|
|
48
|
+
props.function,
|
|
49
|
+
);
|
|
50
|
+
const method: string =
|
|
51
|
+
METHODS[Reflect.getMetadata(METHOD_METADATA, props.function)];
|
|
52
|
+
if (method === undefined || method === "OPTIONS") return null;
|
|
53
|
+
|
|
54
|
+
const parameters: IReflectHttpOperation.IParameter[] = (() => {
|
|
55
|
+
const nestParameters: NestParameters | undefined = Reflect.getMetadata(
|
|
56
|
+
ROUTE_ARGS_METADATA,
|
|
57
|
+
props.controller.constructor,
|
|
58
|
+
props.name,
|
|
59
|
+
);
|
|
60
|
+
if (nestParameters === undefined) return [];
|
|
61
|
+
|
|
62
|
+
const output: IReflectHttpOperation.IParameter[] = [];
|
|
63
|
+
for (const tuple of Object.entries(nestParameters)) {
|
|
64
|
+
const child: IReflectHttpOperation.IParameter | null =
|
|
65
|
+
_Analyze_http_parameter(...tuple);
|
|
66
|
+
if (child !== null) output.push(child);
|
|
67
|
+
}
|
|
68
|
+
return output.sort((x, y) => x.index - y.index);
|
|
69
|
+
})();
|
|
70
|
+
|
|
71
|
+
// VALIDATE BODY
|
|
72
|
+
const body: IReflectHttpOperation.IParameter | undefined =
|
|
73
|
+
parameters.find((param) => param.category === "body");
|
|
74
|
+
if (body !== undefined && (method === "GET" || method === "HEAD")) {
|
|
75
|
+
project.errors.push({
|
|
76
|
+
file: props.controller.file,
|
|
77
|
+
controller: props.controller.name,
|
|
78
|
+
function: props.name,
|
|
79
|
+
message: `"body" parameter cannot be used in the "${method}" method.`,
|
|
80
|
+
});
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// DO CONSTRUCT
|
|
85
|
+
const meta: IReflectHttpOperation = {
|
|
86
|
+
protocol: "http",
|
|
87
|
+
function: props.function,
|
|
88
|
+
name: props.name,
|
|
89
|
+
method: method === "ALL" ? "POST" : method,
|
|
90
|
+
paths: ReflectMetadataAnalyzer.paths(props.function).filter((str) => {
|
|
91
|
+
if (str.includes("*") === true) {
|
|
92
|
+
project.warnings.push({
|
|
93
|
+
file: props.controller.file,
|
|
94
|
+
controller: props.controller.name,
|
|
95
|
+
function: props.name,
|
|
96
|
+
message: "@nestia/sdk does not compose wildcard method.",
|
|
97
|
+
});
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
}),
|
|
102
|
+
versions: ReflectMetadataAnalyzer.versions(props.function),
|
|
103
|
+
parameters,
|
|
104
|
+
status: Reflect.getMetadata(HTTP_CODE_METADATA, props.function),
|
|
105
|
+
encrypted,
|
|
106
|
+
contentType: encrypted
|
|
107
|
+
? "text/plain"
|
|
108
|
+
: query
|
|
109
|
+
? "application/x-www-form-urlencoded"
|
|
110
|
+
: Reflect.getMetadata(HEADERS_METADATA, props.function)?.find(
|
|
111
|
+
(h: Record<string, string>) =>
|
|
112
|
+
typeof h?.name === "string" &&
|
|
113
|
+
typeof h?.value === "string" &&
|
|
114
|
+
h.name.toLowerCase() === "content-type",
|
|
115
|
+
)?.value ?? "application/json",
|
|
116
|
+
security: ReflectMetadataAnalyzer.securities(props.function),
|
|
117
|
+
exceptions: ReflectMetadataAnalyzer.exceptions(props.function),
|
|
118
|
+
swaggerTags: [
|
|
119
|
+
...new Set([
|
|
120
|
+
...props.controller.swaggerTgas,
|
|
121
|
+
...(Reflect.getMetadata("swagger/apiUseTags", props.function) ??
|
|
122
|
+
[]),
|
|
123
|
+
]),
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// VALIDATE PATH ARGUMENTS
|
|
128
|
+
for (const controllerLocation of props.controller.paths)
|
|
129
|
+
for (const metaLocation of meta.paths) {
|
|
130
|
+
// NORMALIZE LOCATION
|
|
131
|
+
const location: string = PathAnalyzer.join(
|
|
132
|
+
controllerLocation,
|
|
133
|
+
metaLocation,
|
|
134
|
+
);
|
|
135
|
+
if (location.includes("*")) continue;
|
|
136
|
+
|
|
137
|
+
// LIST UP PARAMETERS
|
|
138
|
+
const binded: string[] | null = PathAnalyzer.parameters(location);
|
|
139
|
+
if (binded === null) {
|
|
140
|
+
project.errors.push({
|
|
141
|
+
file: props.controller.file,
|
|
142
|
+
controller: props.controller.name,
|
|
143
|
+
function: props.name,
|
|
144
|
+
message: `invalid path (${JSON.stringify(location)})`,
|
|
145
|
+
});
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const parameters: string[] = meta.parameters
|
|
149
|
+
.filter((param) => param.category === "param")
|
|
150
|
+
.map((param) => param.field!)
|
|
151
|
+
.sort();
|
|
152
|
+
|
|
153
|
+
// DO VALIDATE
|
|
154
|
+
if (ranges.equal(binded.sort(), parameters) === false)
|
|
155
|
+
errors.push({
|
|
156
|
+
file: props.controller.file,
|
|
157
|
+
controller: props.controller.name,
|
|
158
|
+
function: props.name,
|
|
159
|
+
message: `binded arguments in the "path" between function's decorator and parameters' decorators are different (function: [${binded.join(
|
|
160
|
+
", ",
|
|
161
|
+
)}], parameters: [${parameters.join(", ")}]).`,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// RETURNS
|
|
166
|
+
if (errors.length) {
|
|
167
|
+
project.errors.push(...errors);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return meta;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
function _Analyze_http_parameter(
|
|
174
|
+
key: string,
|
|
175
|
+
param: INestParam,
|
|
176
|
+
): IReflectHttpOperation.IParameter | null {
|
|
177
|
+
const symbol: string = key.split(":")[0];
|
|
178
|
+
if (symbol.indexOf("__custom") !== -1)
|
|
179
|
+
return _Analyze_http_custom_parameter(param);
|
|
180
|
+
|
|
181
|
+
const typeIndex: RouteParamtypes = Number(symbol[0]) as RouteParamtypes;
|
|
182
|
+
if (isNaN(typeIndex) === true) return null;
|
|
183
|
+
|
|
184
|
+
const type: ParamCategory | undefined = getNestParamType(typeIndex);
|
|
185
|
+
if (type === undefined) return null;
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
custom: false,
|
|
189
|
+
name: key,
|
|
190
|
+
category: type,
|
|
191
|
+
index: param.index,
|
|
192
|
+
field: param.data,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function _Analyze_http_custom_parameter(
|
|
197
|
+
param: INestParam,
|
|
198
|
+
): IReflectHttpOperation.IParameter | null {
|
|
199
|
+
if (param.factory === undefined) return null;
|
|
200
|
+
else if (
|
|
201
|
+
param.factory.name === "EncryptedBody" ||
|
|
202
|
+
param.factory.name === "PlainBody" ||
|
|
203
|
+
param.factory.name === "TypedQueryBody" ||
|
|
204
|
+
param.factory.name === "TypedBody" ||
|
|
205
|
+
param.factory.name === "TypedFormDataBody"
|
|
206
|
+
)
|
|
207
|
+
return {
|
|
208
|
+
custom: true,
|
|
209
|
+
category: "body",
|
|
210
|
+
index: param.index,
|
|
211
|
+
name: param.name,
|
|
212
|
+
field: param.data,
|
|
213
|
+
encrypted: param.factory.name === "EncryptedBody",
|
|
214
|
+
contentType:
|
|
215
|
+
param.factory.name === "PlainBody" ||
|
|
216
|
+
param.factory.name === "EncryptedBody"
|
|
217
|
+
? "text/plain"
|
|
218
|
+
: param.factory.name === "TypedQueryBody"
|
|
219
|
+
? "application/x-www-form-urlencoded"
|
|
220
|
+
: param.factory.name === "TypedFormDataBody"
|
|
221
|
+
? "multipart/form-data"
|
|
222
|
+
: "application/json",
|
|
223
|
+
};
|
|
224
|
+
else if (param.factory.name === "TypedHeaders")
|
|
225
|
+
return {
|
|
226
|
+
custom: true,
|
|
227
|
+
category: "headers",
|
|
228
|
+
name: param.name,
|
|
229
|
+
index: param.index,
|
|
230
|
+
field: param.data,
|
|
231
|
+
};
|
|
232
|
+
else if (param.factory.name === "TypedParam")
|
|
233
|
+
return {
|
|
234
|
+
custom: true,
|
|
235
|
+
category: "param",
|
|
236
|
+
name: param.name,
|
|
237
|
+
index: param.index,
|
|
238
|
+
field: param.data,
|
|
239
|
+
};
|
|
240
|
+
else if (param.factory.name === "TypedQuery")
|
|
241
|
+
return {
|
|
242
|
+
custom: true,
|
|
243
|
+
name: param.name,
|
|
244
|
+
category: "query",
|
|
245
|
+
index: param.index,
|
|
246
|
+
field: undefined,
|
|
247
|
+
};
|
|
248
|
+
else return null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface INestParam {
|
|
253
|
+
name: string;
|
|
254
|
+
index: number;
|
|
255
|
+
factory?: (...args: any) => any;
|
|
256
|
+
data: string | undefined;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
type NestParameters = {
|
|
260
|
+
[key: string]: INestParam;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const hasInterceptor =
|
|
264
|
+
(name: string) =>
|
|
265
|
+
(proto: any): boolean => {
|
|
266
|
+
const meta = Reflect.getMetadata(INTERCEPTORS_METADATA, proto);
|
|
267
|
+
if (Array.isArray(meta) === false) return false;
|
|
268
|
+
return meta.some((elem) => elem?.constructor?.name === name);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// https://github.com/nestjs/nest/blob/master/packages/common/enums/route-paramtypes.enum.ts
|
|
272
|
+
const getNestParamType = (value: RouteParamtypes) => {
|
|
273
|
+
if (value === RouteParamtypes.BODY) return "body";
|
|
274
|
+
else if (value === RouteParamtypes.HEADERS) return "headers";
|
|
275
|
+
else if (value === RouteParamtypes.QUERY) return "query";
|
|
276
|
+
else if (value === RouteParamtypes.PARAM) return "param";
|
|
277
|
+
return undefined;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// node_modules/@nestjs/common/lib/enums/request-method.enum.ts
|
|
281
|
+
const METHODS = [
|
|
282
|
+
"GET",
|
|
283
|
+
"POST",
|
|
284
|
+
"PUT",
|
|
285
|
+
"DELETE",
|
|
286
|
+
"PATCH",
|
|
287
|
+
"ALL",
|
|
288
|
+
"OPTIONS",
|
|
289
|
+
"HEAD",
|
|
290
|
+
];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { VERSION_NEUTRAL } from "@nestjs/common";
|
|
2
|
+
import { PATH_METADATA, VERSION_METADATA } from "@nestjs/common/constants";
|
|
3
|
+
import { VersionValue } from "@nestjs/common/interfaces";
|
|
4
|
+
|
|
5
|
+
import { IReflectHttpOperation } from "../structures/IReflectHttpOperation";
|
|
6
|
+
import { SecurityAnalyzer } from "./SecurityAnalyzer";
|
|
7
|
+
|
|
8
|
+
export namespace ReflectMetadataAnalyzer {
|
|
9
|
+
export const exceptions = (
|
|
10
|
+
value: any,
|
|
11
|
+
): Record<
|
|
12
|
+
number | "2XX" | "3XX" | "4XX" | "5XX",
|
|
13
|
+
IReflectHttpOperation.IException
|
|
14
|
+
> => {
|
|
15
|
+
const entire: IReflectHttpOperation.IException[] | undefined =
|
|
16
|
+
Reflect.getMetadata("nestia/TypedException", value);
|
|
17
|
+
return Object.fromEntries(
|
|
18
|
+
(entire ?? []).map((exp) => [exp.status, exp]),
|
|
19
|
+
) as Record<
|
|
20
|
+
number | "2XX" | "3XX" | "4XX" | "5XX",
|
|
21
|
+
IReflectHttpOperation.IException
|
|
22
|
+
>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const paths = (target: any): string[] => {
|
|
26
|
+
const value: string | string[] = Reflect.getMetadata(PATH_METADATA, target);
|
|
27
|
+
if (typeof value === "string") return [value];
|
|
28
|
+
else if (value.length === 0) return [""];
|
|
29
|
+
else return value;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const securities = (value: any): Record<string, string[]>[] => {
|
|
33
|
+
const entire: Record<string, string[]>[] | undefined = Reflect.getMetadata(
|
|
34
|
+
"swagger/apiSecurity",
|
|
35
|
+
value,
|
|
36
|
+
);
|
|
37
|
+
return entire ? SecurityAnalyzer.merge(...entire) : [];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const versions = (
|
|
41
|
+
target: any,
|
|
42
|
+
): Array<string | typeof VERSION_NEUTRAL> | undefined => {
|
|
43
|
+
const value: VersionValue | undefined = Reflect.getMetadata(
|
|
44
|
+
VERSION_METADATA,
|
|
45
|
+
target,
|
|
46
|
+
);
|
|
47
|
+
return value === undefined
|
|
48
|
+
? undefined
|
|
49
|
+
: Array.isArray(value)
|
|
50
|
+
? value
|
|
51
|
+
: [value];
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ranges } from "tstl";
|
|
2
|
+
|
|
3
|
+
import { IErrorReport } from "../structures/IErrorReport";
|
|
4
|
+
import { INestiaProject } from "../structures/INestiaProject";
|
|
5
|
+
import { IReflectController } from "../structures/IReflectController";
|
|
6
|
+
import { IReflectWebSocketOperation } from "../structures/IReflectWebSocketOperation";
|
|
7
|
+
import { PathAnalyzer } from "./PathAnalyzer";
|
|
8
|
+
import { ReflectMetadataAnalyzer } from "./ReflectMetadataAnalyzer";
|
|
9
|
+
|
|
10
|
+
export namespace ReflectWebSocketOperationAnalyzer {
|
|
11
|
+
export const analyze =
|
|
12
|
+
(project: INestiaProject) =>
|
|
13
|
+
(props: {
|
|
14
|
+
controller: IReflectController;
|
|
15
|
+
function: Function;
|
|
16
|
+
name: string;
|
|
17
|
+
}): IReflectWebSocketOperation | null => {
|
|
18
|
+
const route: { paths: string[] } | undefined = Reflect.getMetadata(
|
|
19
|
+
"nestia/WebSocketRoute",
|
|
20
|
+
props.function,
|
|
21
|
+
);
|
|
22
|
+
if (route === undefined) return null;
|
|
23
|
+
|
|
24
|
+
const errors: IErrorReport[] = [];
|
|
25
|
+
const parameters: IReflectWebSocketOperation.IParameter[] = (
|
|
26
|
+
(Reflect.getMetadata(
|
|
27
|
+
"nestia/WebSocketRoute/Parameters",
|
|
28
|
+
props.controller.prototype,
|
|
29
|
+
props.name,
|
|
30
|
+
) ?? []) as IReflectWebSocketOperation.IParameter[]
|
|
31
|
+
).sort((a, b) => a.index - b.index);
|
|
32
|
+
if (parameters.find((p) => (p.category === "acceptor") === undefined))
|
|
33
|
+
errors.push({
|
|
34
|
+
file: props.controller.file,
|
|
35
|
+
controller: props.controller.name,
|
|
36
|
+
function: props.name,
|
|
37
|
+
message: "@WebSocketRoute.Acceptor() is essentially required",
|
|
38
|
+
});
|
|
39
|
+
if (parameters.length !== props.function.length)
|
|
40
|
+
errors.push({
|
|
41
|
+
file: props.controller.file,
|
|
42
|
+
controller: props.controller.name,
|
|
43
|
+
function: props.name,
|
|
44
|
+
message: [
|
|
45
|
+
"Every parameters must be one of below:",
|
|
46
|
+
" - @WebSocketRoute.Acceptor()",
|
|
47
|
+
" - @WebSocketRoute.Driver()",
|
|
48
|
+
" - @WebSocketRoute.Header()",
|
|
49
|
+
" - @WebSocketRoute.Param()",
|
|
50
|
+
" - @WebSocketRoute.Query()",
|
|
51
|
+
].join("\n"),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const fields: string[] = parameters
|
|
55
|
+
.filter((p) => p.category === "param")
|
|
56
|
+
.map((p) => p.field)
|
|
57
|
+
.sort();
|
|
58
|
+
for (const cLoc of props.controller.paths)
|
|
59
|
+
for (const mLoc of route.paths) {
|
|
60
|
+
const location: string = PathAnalyzer.join(cLoc, mLoc);
|
|
61
|
+
if (location.includes("*")) continue;
|
|
62
|
+
|
|
63
|
+
const binded: string[] | null = PathAnalyzer.parameters(location);
|
|
64
|
+
if (binded === null) {
|
|
65
|
+
errors.push({
|
|
66
|
+
file: props.controller.file,
|
|
67
|
+
controller: props.controller.name,
|
|
68
|
+
function: props.name,
|
|
69
|
+
message: `invalid path (${JSON.stringify(location)})`,
|
|
70
|
+
});
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (ranges.equal(binded.sort(), fields) === false)
|
|
74
|
+
errors.push({
|
|
75
|
+
file: props.controller.file,
|
|
76
|
+
controller: props.controller.name,
|
|
77
|
+
function: props.name,
|
|
78
|
+
message: `binded arguments in the "path" between function's decorator and parameters' decorators are different (function: [${binded.join(
|
|
79
|
+
", ",
|
|
80
|
+
)}], parameters: [${fields.join(", ")}]).`,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (errors.length) {
|
|
84
|
+
project.errors.push(...errors);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
protocol: "websocket",
|
|
89
|
+
target: props.function,
|
|
90
|
+
name: props.name,
|
|
91
|
+
paths: route.paths,
|
|
92
|
+
versions: ReflectMetadataAnalyzer.versions(props.function),
|
|
93
|
+
parameters,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MapUtil } from "../utils/MapUtil";
|
|
2
2
|
|
|
3
3
|
export namespace SecurityAnalyzer {
|
|
4
|
-
const none = Symbol("none");
|
|
5
4
|
export const merge = (...entire: Record<string, string[]>[]) => {
|
|
6
5
|
const dict: Map<string | typeof none, Set<string>> = new Map();
|
|
7
6
|
for (const obj of entire) {
|
|
@@ -21,4 +20,6 @@ export namespace SecurityAnalyzer {
|
|
|
21
20
|
});
|
|
22
21
|
return output;
|
|
23
22
|
};
|
|
23
|
+
|
|
24
|
+
const none = Symbol("none");
|
|
24
25
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { INestiaProject } from "../structures/INestiaProject";
|
|
4
|
+
import { IReflectController } from "../structures/IReflectController";
|
|
5
|
+
import { IReflectHttpOperation } from "../structures/IReflectHttpOperation";
|
|
6
|
+
import { IReflectWebSocketOperation } from "../structures/IReflectWebSocketOperation";
|
|
7
|
+
import { ITypedHttpRoute } from "../structures/ITypedHttpRoute";
|
|
8
|
+
import { ITypedWebSocketRoute } from "../structures/ITypedWebSocketRoute";
|
|
9
|
+
import { GenericAnalyzer } from "./GenericAnalyzer";
|
|
10
|
+
import { TypedHttpOperationAnalyzer } from "./TypedHttpOperationAnalyzer";
|
|
11
|
+
import { TypedWebSocketOperationAnalyzer } from "./TypedWebSocketOperationAnalyzer";
|
|
12
|
+
|
|
13
|
+
export namespace TypedControllerAnalyzer {
|
|
14
|
+
export const analyze =
|
|
15
|
+
(project: INestiaProject) =>
|
|
16
|
+
async (
|
|
17
|
+
sourceFile: ts.SourceFile,
|
|
18
|
+
controller: IReflectController,
|
|
19
|
+
): Promise<Array<ITypedHttpRoute | ITypedWebSocketRoute>> => {
|
|
20
|
+
// FIND CONTROLLER CLASS
|
|
21
|
+
const ret: Array<ITypedHttpRoute | ITypedWebSocketRoute> = [];
|
|
22
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
23
|
+
if (
|
|
24
|
+
ts.isClassDeclaration(node) &&
|
|
25
|
+
node.name?.escapedText === controller.name
|
|
26
|
+
) {
|
|
27
|
+
// ANALYZE THE CONTROLLER
|
|
28
|
+
ret.push(..._Analyze_controller(project)(controller, node));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return ret;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/* ---------------------------------------------------------
|
|
36
|
+
CLASS
|
|
37
|
+
--------------------------------------------------------- */
|
|
38
|
+
const _Analyze_controller =
|
|
39
|
+
(project: INestiaProject) =>
|
|
40
|
+
(
|
|
41
|
+
controller: IReflectController,
|
|
42
|
+
classNode: ts.ClassDeclaration,
|
|
43
|
+
): Array<ITypedHttpRoute | ITypedWebSocketRoute> => {
|
|
44
|
+
const classType: ts.InterfaceType = project.checker.getTypeAtLocation(
|
|
45
|
+
classNode,
|
|
46
|
+
) as ts.InterfaceType;
|
|
47
|
+
const generics: GenericAnalyzer.Dictionary = GenericAnalyzer.analyze(
|
|
48
|
+
project.checker,
|
|
49
|
+
classNode,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const ret: Array<ITypedHttpRoute | ITypedWebSocketRoute> = [];
|
|
53
|
+
for (const symbol of classType.getProperties()) {
|
|
54
|
+
// GET METHOD DECLARATION
|
|
55
|
+
const declaration: ts.Declaration | undefined = (symbol.declarations ||
|
|
56
|
+
[])[0];
|
|
57
|
+
if (!declaration || !ts.isMethodDeclaration(declaration)) continue;
|
|
58
|
+
|
|
59
|
+
// IDENTIFIER MUST BE
|
|
60
|
+
const identifier = declaration.name;
|
|
61
|
+
if (!ts.isIdentifier(identifier)) continue;
|
|
62
|
+
|
|
63
|
+
// ANALYZED WITH THE REFLECTED-FUNCTION
|
|
64
|
+
const operation:
|
|
65
|
+
| IReflectHttpOperation
|
|
66
|
+
| IReflectWebSocketOperation
|
|
67
|
+
| undefined = controller.operations.find(
|
|
68
|
+
(f) => f.name === identifier.escapedText,
|
|
69
|
+
);
|
|
70
|
+
if (operation === undefined) continue;
|
|
71
|
+
|
|
72
|
+
const routes: ITypedHttpRoute[] | ITypedWebSocketRoute[] =
|
|
73
|
+
operation.protocol === "http"
|
|
74
|
+
? TypedHttpOperationAnalyzer.analyze(project)({
|
|
75
|
+
controller,
|
|
76
|
+
generics,
|
|
77
|
+
operation,
|
|
78
|
+
declaration,
|
|
79
|
+
symbol,
|
|
80
|
+
})
|
|
81
|
+
: TypedWebSocketOperationAnalyzer.analyze(project)({
|
|
82
|
+
controller,
|
|
83
|
+
operation,
|
|
84
|
+
declaration,
|
|
85
|
+
symbol,
|
|
86
|
+
generics,
|
|
87
|
+
});
|
|
88
|
+
ret.push(...routes);
|
|
89
|
+
}
|
|
90
|
+
return ret;
|
|
91
|
+
};
|
|
92
|
+
}
|