@tsoa-next/cli 7.1.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 +3 -0
- package/dist/cli.d.ts +44 -0
- package/dist/cli.js +356 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/metadataGeneration/controllerGenerator.d.ts +30 -0
- package/dist/metadataGeneration/controllerGenerator.js +229 -0
- package/dist/metadataGeneration/controllerGenerator.js.map +1 -0
- package/dist/metadataGeneration/exceptions.d.ts +13 -0
- package/dist/metadataGeneration/exceptions.js +53 -0
- package/dist/metadataGeneration/exceptions.js.map +1 -0
- package/dist/metadataGeneration/extension.d.ts +5 -0
- package/dist/metadataGeneration/extension.js +85 -0
- package/dist/metadataGeneration/extension.js.map +1 -0
- package/dist/metadataGeneration/initializer-value.d.ts +6 -0
- package/dist/metadataGeneration/initializer-value.js +154 -0
- package/dist/metadataGeneration/initializer-value.js.map +1 -0
- package/dist/metadataGeneration/metadataGenerator.d.ts +29 -0
- package/dist/metadataGeneration/metadataGenerator.js +220 -0
- package/dist/metadataGeneration/metadataGenerator.js.map +1 -0
- package/dist/metadataGeneration/methodGenerator.d.ts +45 -0
- package/dist/metadataGeneration/methodGenerator.js +367 -0
- package/dist/metadataGeneration/methodGenerator.js.map +1 -0
- package/dist/metadataGeneration/parameterGenerator.d.ts +33 -0
- package/dist/metadataGeneration/parameterGenerator.js +552 -0
- package/dist/metadataGeneration/parameterGenerator.js.map +1 -0
- package/dist/metadataGeneration/transformer/dateTransformer.d.ts +6 -0
- package/dist/metadataGeneration/transformer/dateTransformer.js +28 -0
- package/dist/metadataGeneration/transformer/dateTransformer.js.map +1 -0
- package/dist/metadataGeneration/transformer/enumTransformer.d.ts +12 -0
- package/dist/metadataGeneration/transformer/enumTransformer.js +75 -0
- package/dist/metadataGeneration/transformer/enumTransformer.js.map +1 -0
- package/dist/metadataGeneration/transformer/primitiveTransformer.d.ts +11 -0
- package/dist/metadataGeneration/transformer/primitiveTransformer.js +70 -0
- package/dist/metadataGeneration/transformer/primitiveTransformer.js.map +1 -0
- package/dist/metadataGeneration/transformer/propertyTransformer.d.ts +12 -0
- package/dist/metadataGeneration/transformer/propertyTransformer.js +101 -0
- package/dist/metadataGeneration/transformer/propertyTransformer.js.map +1 -0
- package/dist/metadataGeneration/transformer/referenceTransformer.d.ts +10 -0
- package/dist/metadataGeneration/transformer/referenceTransformer.js +81 -0
- package/dist/metadataGeneration/transformer/referenceTransformer.js.map +1 -0
- package/dist/metadataGeneration/transformer/transformer.d.ts +9 -0
- package/dist/metadataGeneration/transformer/transformer.js +39 -0
- package/dist/metadataGeneration/transformer/transformer.js.map +1 -0
- package/dist/metadataGeneration/typeResolver.d.ts +52 -0
- package/dist/metadataGeneration/typeResolver.js +1202 -0
- package/dist/metadataGeneration/typeResolver.js.map +1 -0
- package/dist/module/generate-routes.d.ts +9 -0
- package/dist/module/generate-routes.js +90 -0
- package/dist/module/generate-routes.js.map +1 -0
- package/dist/module/generate-spec.d.ts +9 -0
- package/dist/module/generate-spec.js +79 -0
- package/dist/module/generate-spec.js.map +1 -0
- package/dist/routeGeneration/defaultRouteGenerator.d.ts +12 -0
- package/dist/routeGeneration/defaultRouteGenerator.js +119 -0
- package/dist/routeGeneration/defaultRouteGenerator.js.map +1 -0
- package/dist/routeGeneration/routeGenerator.d.ts +56 -0
- package/dist/routeGeneration/routeGenerator.js +257 -0
- package/dist/routeGeneration/routeGenerator.js.map +1 -0
- package/dist/routeGeneration/templates/express.hbs +221 -0
- package/dist/routeGeneration/templates/hapi.hbs +267 -0
- package/dist/routeGeneration/templates/koa.hbs +218 -0
- package/dist/swagger/specGenerator.d.ts +33 -0
- package/dist/swagger/specGenerator.js +253 -0
- package/dist/swagger/specGenerator.js.map +1 -0
- package/dist/swagger/specGenerator2.d.ts +27 -0
- package/dist/swagger/specGenerator2.js +476 -0
- package/dist/swagger/specGenerator2.js.map +1 -0
- package/dist/swagger/specGenerator3.d.ts +158 -0
- package/dist/swagger/specGenerator3.js +646 -0
- package/dist/swagger/specGenerator3.js.map +1 -0
- package/dist/swagger/specGenerator31.d.ts +24 -0
- package/dist/swagger/specGenerator31.js +75 -0
- package/dist/swagger/specGenerator31.js.map +1 -0
- package/dist/utils/decoratorUtils.d.ts +9 -0
- package/dist/utils/decoratorUtils.js +118 -0
- package/dist/utils/decoratorUtils.js.map +1 -0
- package/dist/utils/flowUtils.d.ts +1 -0
- package/dist/utils/flowUtils.js +8 -0
- package/dist/utils/flowUtils.js.map +1 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.js +55 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/genericTypeGuards.d.ts +1 -0
- package/dist/utils/genericTypeGuards.js +8 -0
- package/dist/utils/genericTypeGuards.js.map +1 -0
- package/dist/utils/headerTypeHelpers.d.ts +5 -0
- package/dist/utils/headerTypeHelpers.js +27 -0
- package/dist/utils/headerTypeHelpers.js.map +1 -0
- package/dist/utils/importClassesFromDirectories.d.ts +4 -0
- package/dist/utils/importClassesFromDirectories.js +20 -0
- package/dist/utils/importClassesFromDirectories.js.map +1 -0
- package/dist/utils/internalTypeGuards.d.ts +5 -0
- package/dist/utils/internalTypeGuards.js +66 -0
- package/dist/utils/internalTypeGuards.js.map +1 -0
- package/dist/utils/isVoidType.d.ts +2 -0
- package/dist/utils/isVoidType.js +16 -0
- package/dist/utils/isVoidType.js.map +1 -0
- package/dist/utils/jsDocUtils.d.ts +8 -0
- package/dist/utils/jsDocUtils.js +122 -0
- package/dist/utils/jsDocUtils.js.map +1 -0
- package/dist/utils/jsonUtils.d.ts +1 -0
- package/dist/utils/jsonUtils.js +12 -0
- package/dist/utils/jsonUtils.js.map +1 -0
- package/dist/utils/pathUtils.d.ts +9 -0
- package/dist/utils/pathUtils.js +37 -0
- package/dist/utils/pathUtils.js.map +1 -0
- package/dist/utils/specMerge.d.ts +2 -0
- package/dist/utils/specMerge.js +36 -0
- package/dist/utils/specMerge.js.map +1 -0
- package/dist/utils/swaggerUtils.d.ts +3 -0
- package/dist/utils/swaggerUtils.js +22 -0
- package/dist/utils/swaggerUtils.js.map +1 -0
- package/dist/utils/unspecifiedObject.d.ts +3 -0
- package/dist/utils/unspecifiedObject.js +3 -0
- package/dist/utils/unspecifiedObject.js.map +1 -0
- package/dist/utils/validatorUtils.d.ts +5 -0
- package/dist/utils/validatorUtils.js +241 -0
- package/dist/utils/validatorUtils.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataGenerator = void 0;
|
|
4
|
+
const minimatch_1 = require("minimatch");
|
|
5
|
+
const typescript_1 = require("typescript");
|
|
6
|
+
const decoratorUtils_1 = require("../utils/decoratorUtils");
|
|
7
|
+
const importClassesFromDirectories_1 = require("../utils/importClassesFromDirectories");
|
|
8
|
+
const controllerGenerator_1 = require("./controllerGenerator");
|
|
9
|
+
const exceptions_1 = require("./exceptions");
|
|
10
|
+
const typeResolver_1 = require("./typeResolver");
|
|
11
|
+
class MetadataGenerator {
|
|
12
|
+
compilerOptions;
|
|
13
|
+
ignorePaths;
|
|
14
|
+
rootSecurity;
|
|
15
|
+
defaultNumberType;
|
|
16
|
+
controllerNodes = new Array();
|
|
17
|
+
typeChecker;
|
|
18
|
+
program;
|
|
19
|
+
referenceTypeMap = {};
|
|
20
|
+
modelDefinitionPosMap = {};
|
|
21
|
+
expressionOrigNameMap = {};
|
|
22
|
+
constructor(entryFile, compilerOptions, ignorePaths, controllers, rootSecurity = [], defaultNumberType = 'double', esm = false) {
|
|
23
|
+
this.compilerOptions = compilerOptions;
|
|
24
|
+
this.ignorePaths = ignorePaths;
|
|
25
|
+
this.rootSecurity = rootSecurity;
|
|
26
|
+
this.defaultNumberType = defaultNumberType;
|
|
27
|
+
typeResolver_1.TypeResolver.clearCache();
|
|
28
|
+
this.program = controllers ? this.setProgramToDynamicControllersFiles(controllers, esm) : (0, typescript_1.createProgram)([entryFile], compilerOptions || {});
|
|
29
|
+
this.typeChecker = this.program.getTypeChecker();
|
|
30
|
+
}
|
|
31
|
+
Generate() {
|
|
32
|
+
this.extractNodeFromProgramSourceFiles();
|
|
33
|
+
const controllers = this.buildControllers();
|
|
34
|
+
this.checkForMethodSignatureDuplicates(controllers);
|
|
35
|
+
this.checkForPathParamSignatureDuplicates(controllers);
|
|
36
|
+
return {
|
|
37
|
+
controllers,
|
|
38
|
+
referenceTypeMap: this.referenceTypeMap,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
setProgramToDynamicControllersFiles(controllers, esm) {
|
|
42
|
+
const allGlobFiles = (0, importClassesFromDirectories_1.importClassesFromDirectories)(controllers, esm ? ['.mts', '.ts', '.cts'] : ['.ts']);
|
|
43
|
+
if (allGlobFiles.length === 0) {
|
|
44
|
+
throw new exceptions_1.GenerateMetadataError(`[${controllers.join(', ')}] globs found 0 controllers.`);
|
|
45
|
+
}
|
|
46
|
+
return (0, typescript_1.createProgram)(allGlobFiles, this.compilerOptions || {});
|
|
47
|
+
}
|
|
48
|
+
extractNodeFromProgramSourceFiles() {
|
|
49
|
+
this.program.getSourceFiles().forEach(sf => {
|
|
50
|
+
if (this.ignorePaths && this.ignorePaths.length) {
|
|
51
|
+
for (const path of this.ignorePaths) {
|
|
52
|
+
if ((0, minimatch_1.minimatch)(sf.fileName, path)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
(0, typescript_1.forEachChild)(sf, node => {
|
|
58
|
+
if ((0, typescript_1.isClassDeclaration)(node) && (0, decoratorUtils_1.getDecorators)(node, identifier => identifier.text === 'Route').length) {
|
|
59
|
+
this.controllerNodes.push(node);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
checkForMethodSignatureDuplicates = (controllers) => {
|
|
65
|
+
const map = {};
|
|
66
|
+
controllers.forEach(controller => {
|
|
67
|
+
controller.methods.forEach(method => {
|
|
68
|
+
const signature = method.path ? `@${method.method}(${controller.path}/${method.path})` : `@${method.method}(${controller.path})`;
|
|
69
|
+
const methodDescription = `${controller.name}#${method.name}`;
|
|
70
|
+
if (map[signature]) {
|
|
71
|
+
map[signature].push(methodDescription);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
map[signature] = [methodDescription];
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
let message = '';
|
|
79
|
+
Object.keys(map).forEach(signature => {
|
|
80
|
+
const controllers = map[signature];
|
|
81
|
+
if (controllers.length > 1) {
|
|
82
|
+
message += `Duplicate method signature ${signature} found in controllers: ${controllers.join(', ')}\n`;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
if (message) {
|
|
86
|
+
throw new exceptions_1.GenerateMetadataError(message);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
checkForPathParamSignatureDuplicates = (controllers) => {
|
|
90
|
+
const paramRegExp = new RegExp('{(\\w*)}|:(\\w+)', 'g');
|
|
91
|
+
let PathDuplicationType;
|
|
92
|
+
(function (PathDuplicationType) {
|
|
93
|
+
PathDuplicationType[PathDuplicationType["FULL"] = 0] = "FULL";
|
|
94
|
+
PathDuplicationType[PathDuplicationType["PARTIAL"] = 1] = "PARTIAL";
|
|
95
|
+
})(PathDuplicationType || (PathDuplicationType = {}));
|
|
96
|
+
const collisions = [];
|
|
97
|
+
function addCollision(type, method, controller, collidesWith) {
|
|
98
|
+
let existingCollision = collisions.find(collision => collision.type === type && collision.method === method && collision.controller === controller);
|
|
99
|
+
if (!existingCollision) {
|
|
100
|
+
existingCollision = {
|
|
101
|
+
type,
|
|
102
|
+
method,
|
|
103
|
+
controller,
|
|
104
|
+
collidesWith: [],
|
|
105
|
+
};
|
|
106
|
+
collisions.push(existingCollision);
|
|
107
|
+
}
|
|
108
|
+
existingCollision.collidesWith.push(collidesWith);
|
|
109
|
+
}
|
|
110
|
+
controllers.forEach(controller => {
|
|
111
|
+
const methodRouteGroup = {};
|
|
112
|
+
// Group all ts methods with HTTP method decorator into same object in same controller.
|
|
113
|
+
controller.methods.forEach(method => {
|
|
114
|
+
if (methodRouteGroup[method.method] === undefined) {
|
|
115
|
+
methodRouteGroup[method.method] = [];
|
|
116
|
+
}
|
|
117
|
+
const params = method.path.match(paramRegExp);
|
|
118
|
+
methodRouteGroup[method.method].push({
|
|
119
|
+
method, // method.name + ": " + method.path) as any,
|
|
120
|
+
path: params?.reduce((s, a) => {
|
|
121
|
+
// replace all params with {} placeholder for comparison
|
|
122
|
+
return s.replace(a, '{}');
|
|
123
|
+
}, method.path) || method.path,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
Object.keys(methodRouteGroup).forEach((key) => {
|
|
127
|
+
const methodRoutes = methodRouteGroup[key];
|
|
128
|
+
// check each route with the routes that are defined before it
|
|
129
|
+
for (let i = 0; i < methodRoutes.length; i += 1) {
|
|
130
|
+
for (let j = 0; j < i; j += 1) {
|
|
131
|
+
if (methodRoutes[i].path === methodRoutes[j].path) {
|
|
132
|
+
// full match
|
|
133
|
+
addCollision(PathDuplicationType.FULL, methodRoutes[i].method, controller, methodRoutes[j].method);
|
|
134
|
+
}
|
|
135
|
+
else if (methodRoutes[i].path.split('/').length === methodRoutes[j].path.split('/').length &&
|
|
136
|
+
methodRoutes[j].path
|
|
137
|
+
.substr(methodRoutes[j].path.lastIndexOf('/')) // compare only the "last" part of the path
|
|
138
|
+
.split('/')
|
|
139
|
+
.some(v => !!v) && // ensure the comparison path has a value
|
|
140
|
+
methodRoutes[i].path.split('/').every((v, index) => {
|
|
141
|
+
const comparisonPathPart = methodRoutes[j].path.split('/')[index];
|
|
142
|
+
// if no params, compare values
|
|
143
|
+
if (!v.includes('{}')) {
|
|
144
|
+
return v === comparisonPathPart;
|
|
145
|
+
}
|
|
146
|
+
// otherwise check if route starts with comparison route
|
|
147
|
+
return v.startsWith(methodRoutes[j].path.split('/')[index]);
|
|
148
|
+
})) {
|
|
149
|
+
// partial match - reorder routes!
|
|
150
|
+
addCollision(PathDuplicationType.PARTIAL, methodRoutes[i].method, controller, methodRoutes[j].method);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
// print warnings for each collision (grouped by route)
|
|
157
|
+
collisions.forEach(collision => {
|
|
158
|
+
let message = '';
|
|
159
|
+
if (collision.type === PathDuplicationType.FULL) {
|
|
160
|
+
message = `Duplicate path parameter definition signature found in controller `;
|
|
161
|
+
}
|
|
162
|
+
else if (collision.type === PathDuplicationType.PARTIAL) {
|
|
163
|
+
message = `Overlapping path parameter definition signature found in controller `;
|
|
164
|
+
}
|
|
165
|
+
message += collision.controller.name;
|
|
166
|
+
message += ` [ method ${collision.method.method.toUpperCase()} ${collision.method.name} route: ${collision.method.path} ] collides with `;
|
|
167
|
+
message += collision.collidesWith
|
|
168
|
+
.map((method) => {
|
|
169
|
+
return `[ method ${method.method.toUpperCase()} ${method.name} route: ${method.path} ]`;
|
|
170
|
+
})
|
|
171
|
+
.join(', ');
|
|
172
|
+
message += '\n';
|
|
173
|
+
console.warn(message);
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
TypeChecker() {
|
|
177
|
+
return this.typeChecker;
|
|
178
|
+
}
|
|
179
|
+
AddReferenceType(referenceType) {
|
|
180
|
+
if (!referenceType.refName) {
|
|
181
|
+
throw new Error('no reference type name found');
|
|
182
|
+
}
|
|
183
|
+
this.referenceTypeMap[referenceType.refName] = referenceType;
|
|
184
|
+
}
|
|
185
|
+
GetReferenceType(refName) {
|
|
186
|
+
return this.referenceTypeMap[refName];
|
|
187
|
+
}
|
|
188
|
+
CheckModelUnicity(refName, positions) {
|
|
189
|
+
if (!this.modelDefinitionPosMap[refName]) {
|
|
190
|
+
this.modelDefinitionPosMap[refName] = positions;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const origPositions = this.modelDefinitionPosMap[refName];
|
|
194
|
+
if (!(origPositions.length === positions.length && positions.every(pos => origPositions.find(origPos => pos.pos === origPos.pos && pos.fileName === origPos.fileName)))) {
|
|
195
|
+
throw new Error(`Found 2 different model definitions for model ${refName}: orig: ${JSON.stringify(origPositions)}, act: ${JSON.stringify(positions)}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
CheckExpressionUnicity(formattedRefName, refName) {
|
|
200
|
+
if (!this.expressionOrigNameMap[formattedRefName]) {
|
|
201
|
+
this.expressionOrigNameMap[formattedRefName] = refName;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
if (this.expressionOrigNameMap[formattedRefName] !== refName) {
|
|
205
|
+
throw new Error(`Found 2 different type expressions for formatted name "${formattedRefName}": orig: "${this.expressionOrigNameMap[formattedRefName]}", act: "${refName}"`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
buildControllers() {
|
|
210
|
+
if (this.controllerNodes.length === 0) {
|
|
211
|
+
throw new Error('no controllers found, check tsoa configuration');
|
|
212
|
+
}
|
|
213
|
+
return this.controllerNodes
|
|
214
|
+
.map(classDeclaration => new controllerGenerator_1.ControllerGenerator(classDeclaration, this, this.rootSecurity))
|
|
215
|
+
.filter(generator => generator.IsValid())
|
|
216
|
+
.map(generator => generator.Generate());
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.MetadataGenerator = MetadataGenerator;
|
|
220
|
+
//# sourceMappingURL=metadataGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadataGenerator.js","sourceRoot":"","sources":["../../src/metadataGeneration/metadataGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { MetadataGenerator } from './metadataGenerator';
|
|
3
|
+
import { Tsoa } from '@tsoa-next/runtime';
|
|
4
|
+
type HttpMethod = 'options' | 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head';
|
|
5
|
+
export declare class MethodGenerator {
|
|
6
|
+
private readonly node;
|
|
7
|
+
private readonly current;
|
|
8
|
+
private readonly commonResponses;
|
|
9
|
+
private readonly parentPath?;
|
|
10
|
+
private readonly parentTags?;
|
|
11
|
+
private readonly parentSecurity?;
|
|
12
|
+
private readonly isParentHidden?;
|
|
13
|
+
protected method?: HttpMethod;
|
|
14
|
+
protected path?: string;
|
|
15
|
+
private produces?;
|
|
16
|
+
private consumes?;
|
|
17
|
+
constructor(node: ts.MethodDeclaration, current: MetadataGenerator, commonResponses: Tsoa.Response[], parentPath?: string | undefined, parentTags?: string[] | undefined, parentSecurity?: Tsoa.Security[] | undefined, isParentHidden?: boolean | undefined);
|
|
18
|
+
IsValid(): this is {
|
|
19
|
+
method: HttpMethod;
|
|
20
|
+
path: string;
|
|
21
|
+
};
|
|
22
|
+
Generate(): Tsoa.Method;
|
|
23
|
+
private buildParameters;
|
|
24
|
+
private validateBodyParameters;
|
|
25
|
+
private validateQueryParameters;
|
|
26
|
+
private getExtensions;
|
|
27
|
+
private getCurrentLocation;
|
|
28
|
+
private processMethodDecorators;
|
|
29
|
+
private getProduces;
|
|
30
|
+
private getConsumes;
|
|
31
|
+
private getMethodResponses;
|
|
32
|
+
private getMethodSuccessResponse;
|
|
33
|
+
private getHeadersFromDecorator;
|
|
34
|
+
private getSchemaFromDecorator;
|
|
35
|
+
private getMethodSuccessExamples;
|
|
36
|
+
private supportsPathMethod;
|
|
37
|
+
private getIsDeprecated;
|
|
38
|
+
private getOperationId;
|
|
39
|
+
private getTags;
|
|
40
|
+
private getSecurity;
|
|
41
|
+
private getIsHidden;
|
|
42
|
+
private getDecoratorsByIdentifier;
|
|
43
|
+
private getProducesAdapter;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MethodGenerator = void 0;
|
|
37
|
+
const ts = __importStar(require("typescript"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const isVoidType_1 = require("../utils/isVoidType");
|
|
40
|
+
const decoratorUtils_1 = require("./../utils/decoratorUtils");
|
|
41
|
+
const jsDocUtils_1 = require("./../utils/jsDocUtils");
|
|
42
|
+
const extension_1 = require("./extension");
|
|
43
|
+
const exceptions_1 = require("./exceptions");
|
|
44
|
+
const parameterGenerator_1 = require("./parameterGenerator");
|
|
45
|
+
const typeResolver_1 = require("./typeResolver");
|
|
46
|
+
const headerTypeHelpers_1 = require("../utils/headerTypeHelpers");
|
|
47
|
+
class MethodGenerator {
|
|
48
|
+
node;
|
|
49
|
+
current;
|
|
50
|
+
commonResponses;
|
|
51
|
+
parentPath;
|
|
52
|
+
parentTags;
|
|
53
|
+
parentSecurity;
|
|
54
|
+
isParentHidden;
|
|
55
|
+
method;
|
|
56
|
+
path;
|
|
57
|
+
produces;
|
|
58
|
+
consumes;
|
|
59
|
+
constructor(node, current, commonResponses, parentPath, parentTags, parentSecurity, isParentHidden) {
|
|
60
|
+
this.node = node;
|
|
61
|
+
this.current = current;
|
|
62
|
+
this.commonResponses = commonResponses;
|
|
63
|
+
this.parentPath = parentPath;
|
|
64
|
+
this.parentTags = parentTags;
|
|
65
|
+
this.parentSecurity = parentSecurity;
|
|
66
|
+
this.isParentHidden = isParentHidden;
|
|
67
|
+
this.processMethodDecorators();
|
|
68
|
+
}
|
|
69
|
+
IsValid() {
|
|
70
|
+
return this.method !== undefined && this.path !== undefined;
|
|
71
|
+
}
|
|
72
|
+
Generate() {
|
|
73
|
+
if (!this.IsValid()) {
|
|
74
|
+
throw new exceptions_1.GenerateMetadataError("This isn't a valid a controller method.");
|
|
75
|
+
}
|
|
76
|
+
let nodeType = this.node.type;
|
|
77
|
+
if (!nodeType) {
|
|
78
|
+
const typeChecker = this.current.typeChecker;
|
|
79
|
+
const signature = typeChecker.getSignatureFromDeclaration(this.node);
|
|
80
|
+
const implicitType = typeChecker.getReturnTypeOfSignature(signature);
|
|
81
|
+
nodeType = typeChecker.typeToTypeNode(implicitType, undefined, ts.NodeBuilderFlags.NoTruncation);
|
|
82
|
+
}
|
|
83
|
+
const type = new typeResolver_1.TypeResolver(nodeType, this.current).resolve();
|
|
84
|
+
const responses = this.commonResponses.concat(this.getMethodResponses());
|
|
85
|
+
const { response: successResponse, status: successStatus } = this.getMethodSuccessResponse(type);
|
|
86
|
+
responses.push(successResponse);
|
|
87
|
+
const parameters = this.buildParameters();
|
|
88
|
+
const additionalResponses = parameters.filter((p) => p.in === 'res');
|
|
89
|
+
responses.push(...additionalResponses);
|
|
90
|
+
return {
|
|
91
|
+
extensions: this.getExtensions(),
|
|
92
|
+
deprecated: this.getIsDeprecated(),
|
|
93
|
+
description: (0, jsDocUtils_1.getJSDocDescription)(this.node),
|
|
94
|
+
isHidden: this.getIsHidden(),
|
|
95
|
+
method: this.method,
|
|
96
|
+
name: this.node.name.text,
|
|
97
|
+
operationId: this.getOperationId(),
|
|
98
|
+
parameters,
|
|
99
|
+
path: this.path,
|
|
100
|
+
produces: this.produces,
|
|
101
|
+
consumes: this.consumes,
|
|
102
|
+
responses,
|
|
103
|
+
successStatus,
|
|
104
|
+
security: this.getSecurity(),
|
|
105
|
+
summary: (0, jsDocUtils_1.getJSDocComment)(this.node, 'summary'),
|
|
106
|
+
tags: this.getTags(),
|
|
107
|
+
type,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
buildParameters() {
|
|
111
|
+
if (!this.IsValid()) {
|
|
112
|
+
throw new exceptions_1.GenerateMetadataError("This isn't a valid a controller method.");
|
|
113
|
+
}
|
|
114
|
+
const fullPath = path.join(this.parentPath || '', this.path);
|
|
115
|
+
const method = this.method;
|
|
116
|
+
const parameters = this.node.parameters
|
|
117
|
+
.map(p => {
|
|
118
|
+
try {
|
|
119
|
+
return new parameterGenerator_1.ParameterGenerator(p, method, fullPath, this.current).Generate();
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
const methodId = this.node.name;
|
|
123
|
+
const controllerId = this.node.parent.name;
|
|
124
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
125
|
+
throw new exceptions_1.GenerateMetadataError(`${message} \n in '${controllerId.text}.${methodId.text}'`);
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
.reduce((flattened, params) => [...flattened, ...params], []);
|
|
129
|
+
this.validateBodyParameters(parameters);
|
|
130
|
+
this.validateQueryParameters(parameters);
|
|
131
|
+
return parameters;
|
|
132
|
+
}
|
|
133
|
+
validateBodyParameters(parameters) {
|
|
134
|
+
const bodyParameters = parameters.filter(p => p.in === 'body');
|
|
135
|
+
const bodyProps = parameters.filter(p => p.in === 'body-prop');
|
|
136
|
+
const hasFormDataParameters = parameters.some(p => p.in === 'formData');
|
|
137
|
+
const hasBodyParameter = bodyProps.length + bodyParameters.length > 0;
|
|
138
|
+
if (bodyParameters.length > 1) {
|
|
139
|
+
throw new exceptions_1.GenerateMetadataError(`Only one body parameter allowed in '${this.getCurrentLocation()}' method.`);
|
|
140
|
+
}
|
|
141
|
+
if (bodyParameters.length > 0 && bodyProps.length > 0) {
|
|
142
|
+
throw new exceptions_1.GenerateMetadataError(`Choose either during @Body or @BodyProp in '${this.getCurrentLocation()}' method.`);
|
|
143
|
+
}
|
|
144
|
+
if (hasBodyParameter && hasFormDataParameters) {
|
|
145
|
+
throw new Error(`@Body or @BodyProp cannot be used with @FormField, @UploadedFile, or @UploadedFiles in '${this.getCurrentLocation()}' method.`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
validateQueryParameters(parameters) {
|
|
149
|
+
const queryParameters = parameters.filter(p => p.in === 'query');
|
|
150
|
+
const queriesParameters = parameters.filter(p => p.in === 'queries');
|
|
151
|
+
if (queriesParameters.length > 1) {
|
|
152
|
+
throw new exceptions_1.GenerateMetadataError(`Only one queries parameter allowed in '${this.getCurrentLocation()}' method.`);
|
|
153
|
+
}
|
|
154
|
+
if (queriesParameters.length > 0 && queryParameters.length > 0) {
|
|
155
|
+
throw new exceptions_1.GenerateMetadataError(`Choose either during @Query or @Queries in '${this.getCurrentLocation()}' method.`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
getExtensions() {
|
|
159
|
+
const extensionDecorators = this.getDecoratorsByIdentifier(this.node, 'Extension');
|
|
160
|
+
if (!extensionDecorators || !extensionDecorators.length) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
return (0, extension_1.getExtensions)(extensionDecorators, this.current);
|
|
164
|
+
}
|
|
165
|
+
getCurrentLocation() {
|
|
166
|
+
const methodId = this.node.name;
|
|
167
|
+
const controllerId = this.node.parent.name;
|
|
168
|
+
return `${controllerId.text}.${methodId.text}`;
|
|
169
|
+
}
|
|
170
|
+
processMethodDecorators() {
|
|
171
|
+
const pathDecorators = (0, decoratorUtils_1.getDecorators)(this.node, identifier => this.supportsPathMethod(identifier.text));
|
|
172
|
+
if (!pathDecorators || !pathDecorators.length) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (pathDecorators.length > 1) {
|
|
176
|
+
throw new exceptions_1.GenerateMetadataError(`Only one path decorator in '${this.getCurrentLocation()}' method, Found: ${pathDecorators.map(d => d.text).join(', ')}`);
|
|
177
|
+
}
|
|
178
|
+
const decorator = pathDecorators[0];
|
|
179
|
+
this.method = decorator.text.toLowerCase();
|
|
180
|
+
// if you don't pass in a path to the method decorator, we'll just use the base route
|
|
181
|
+
// todo: what if someone has multiple no argument methods of the same type in a single controller?
|
|
182
|
+
// we need to throw an error there
|
|
183
|
+
this.path = (0, decoratorUtils_1.getPath)(decorator, this.current.typeChecker);
|
|
184
|
+
this.produces = this.getProduces();
|
|
185
|
+
this.consumes = this.getConsumes();
|
|
186
|
+
}
|
|
187
|
+
getProduces() {
|
|
188
|
+
const produces = (0, decoratorUtils_1.getProduces)(this.node, this.current.typeChecker);
|
|
189
|
+
return produces.length ? produces : undefined;
|
|
190
|
+
}
|
|
191
|
+
getConsumes() {
|
|
192
|
+
const consumesDecorators = this.getDecoratorsByIdentifier(this.node, 'Consumes');
|
|
193
|
+
if (!consumesDecorators || !consumesDecorators.length) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (consumesDecorators.length > 1) {
|
|
197
|
+
throw new exceptions_1.GenerateMetadataError(`Only one Consumes decorator in '${this.getCurrentLocation()}' method, Found: ${consumesDecorators.map(d => d.text).join(', ')}`);
|
|
198
|
+
}
|
|
199
|
+
const [decorator] = consumesDecorators;
|
|
200
|
+
const [consumes] = (0, decoratorUtils_1.getDecoratorValues)(decorator, this.current.typeChecker);
|
|
201
|
+
return consumes;
|
|
202
|
+
}
|
|
203
|
+
getMethodResponses() {
|
|
204
|
+
const responseExamplesByName = {};
|
|
205
|
+
const decorators = this.getDecoratorsByIdentifier(this.node, 'Response');
|
|
206
|
+
if (!decorators || !decorators.length) {
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
return decorators.map(decorator => {
|
|
210
|
+
const [name, description, example, produces] = (0, decoratorUtils_1.getDecoratorValues)(decorator, this.current.typeChecker);
|
|
211
|
+
if (example !== undefined) {
|
|
212
|
+
responseExamplesByName[name] = responseExamplesByName[name] ? [...responseExamplesByName[name], example] : [example];
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
description: description || '',
|
|
216
|
+
examples: responseExamplesByName[name] || undefined,
|
|
217
|
+
name: name || '200',
|
|
218
|
+
produces: this.getProducesAdapter(produces),
|
|
219
|
+
schema: this.getSchemaFromDecorator(decorator, 0),
|
|
220
|
+
headers: this.getHeadersFromDecorator(decorator, 1),
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
getMethodSuccessResponse(type) {
|
|
225
|
+
const decorators = this.getDecoratorsByIdentifier(this.node, 'SuccessResponse');
|
|
226
|
+
const examplesWithLabels = this.getMethodSuccessExamples();
|
|
227
|
+
if (!decorators || !decorators.length) {
|
|
228
|
+
const returnsDescription = (0, jsDocUtils_1.getJSDocComment)(this.node, 'returns') || 'Ok';
|
|
229
|
+
return {
|
|
230
|
+
response: {
|
|
231
|
+
description: (0, isVoidType_1.isVoidType)(type) ? 'No content' : returnsDescription,
|
|
232
|
+
examples: examplesWithLabels?.map(ex => ex.example),
|
|
233
|
+
exampleLabels: examplesWithLabels?.map(ex => ex.label),
|
|
234
|
+
name: (0, isVoidType_1.isVoidType)(type) ? '204' : '200',
|
|
235
|
+
produces: this.produces,
|
|
236
|
+
schema: type,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
if (decorators.length > 1) {
|
|
241
|
+
throw new exceptions_1.GenerateMetadataError(`Only one SuccessResponse decorator allowed in '${this.getCurrentLocation()}' method.`);
|
|
242
|
+
}
|
|
243
|
+
const [firstDecorator] = decorators;
|
|
244
|
+
const [name, description, produces] = (0, decoratorUtils_1.getDecoratorValues)(firstDecorator, this.current.typeChecker);
|
|
245
|
+
const headers = this.getHeadersFromDecorator(firstDecorator, 0);
|
|
246
|
+
return {
|
|
247
|
+
response: {
|
|
248
|
+
description: description || '',
|
|
249
|
+
examples: examplesWithLabels?.map(ex => ex.example),
|
|
250
|
+
exampleLabels: examplesWithLabels?.map(ex => ex.label),
|
|
251
|
+
name: name || '200',
|
|
252
|
+
produces: this.getProducesAdapter(produces),
|
|
253
|
+
schema: type,
|
|
254
|
+
headers,
|
|
255
|
+
},
|
|
256
|
+
status: name && /^\d+$/.test(name) ? parseInt(name, 10) : undefined,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
getHeadersFromDecorator({ parent: expression }, headersIndex) {
|
|
260
|
+
if (!ts.isCallExpression(expression)) {
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
return (0, headerTypeHelpers_1.getHeaderType)(expression.typeArguments, headersIndex, this.current);
|
|
264
|
+
}
|
|
265
|
+
getSchemaFromDecorator({ parent: expression }, schemaIndex) {
|
|
266
|
+
if (!ts.isCallExpression(expression) || !expression.typeArguments?.length) {
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
return new typeResolver_1.TypeResolver(expression.typeArguments[schemaIndex], this.current).resolve();
|
|
270
|
+
}
|
|
271
|
+
getMethodSuccessExamples() {
|
|
272
|
+
const exampleDecorators = this.getDecoratorsByIdentifier(this.node, 'Example');
|
|
273
|
+
if (!exampleDecorators || !exampleDecorators.length) {
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
const examples = exampleDecorators.map(exampleDecorator => {
|
|
277
|
+
const [example, label] = (0, decoratorUtils_1.getDecoratorValues)(exampleDecorator, this.current.typeChecker);
|
|
278
|
+
return { example, label };
|
|
279
|
+
});
|
|
280
|
+
return examples || undefined;
|
|
281
|
+
}
|
|
282
|
+
supportsPathMethod(method) {
|
|
283
|
+
return ['options', 'get', 'post', 'put', 'patch', 'delete', 'head'].some(m => m === method.toLowerCase());
|
|
284
|
+
}
|
|
285
|
+
getIsDeprecated() {
|
|
286
|
+
if ((0, jsDocUtils_1.isExistJSDocTag)(this.node, tag => tag.tagName.text === 'deprecated')) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
const depDecorators = this.getDecoratorsByIdentifier(this.node, 'Deprecated');
|
|
290
|
+
if (!depDecorators || !depDecorators.length) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
if (depDecorators.length > 1) {
|
|
294
|
+
throw new exceptions_1.GenerateMetadataError(`Only one Deprecated decorator allowed in '${this.getCurrentLocation()}' method.`);
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
getOperationId() {
|
|
299
|
+
const opDecorators = this.getDecoratorsByIdentifier(this.node, 'OperationId');
|
|
300
|
+
if (!opDecorators || !opDecorators.length) {
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
if (opDecorators.length > 1) {
|
|
304
|
+
throw new exceptions_1.GenerateMetadataError(`Only one OperationId decorator allowed in '${this.getCurrentLocation()}' method.`);
|
|
305
|
+
}
|
|
306
|
+
const values = (0, decoratorUtils_1.getDecoratorValues)(opDecorators[0], this.current.typeChecker);
|
|
307
|
+
return values && values[0];
|
|
308
|
+
}
|
|
309
|
+
getTags() {
|
|
310
|
+
const tagsDecorators = this.getDecoratorsByIdentifier(this.node, 'Tags');
|
|
311
|
+
if (!tagsDecorators || !tagsDecorators.length) {
|
|
312
|
+
return this.parentTags;
|
|
313
|
+
}
|
|
314
|
+
if (tagsDecorators.length > 1) {
|
|
315
|
+
throw new exceptions_1.GenerateMetadataError(`Only one Tags decorator allowed in '${this.getCurrentLocation()}' method.`);
|
|
316
|
+
}
|
|
317
|
+
const tags = (0, decoratorUtils_1.getDecoratorValues)(tagsDecorators[0], this.current.typeChecker);
|
|
318
|
+
if (tags && this.parentTags) {
|
|
319
|
+
tags.push(...this.parentTags);
|
|
320
|
+
}
|
|
321
|
+
return tags;
|
|
322
|
+
}
|
|
323
|
+
getSecurity() {
|
|
324
|
+
const noSecurityDecorators = this.getDecoratorsByIdentifier(this.node, 'NoSecurity');
|
|
325
|
+
const securityDecorators = this.getDecoratorsByIdentifier(this.node, 'Security');
|
|
326
|
+
if (noSecurityDecorators?.length > 1) {
|
|
327
|
+
throw new exceptions_1.GenerateMetadataError(`Only one NoSecurity decorator allowed in '${this.getCurrentLocation()}' method.`);
|
|
328
|
+
}
|
|
329
|
+
if (noSecurityDecorators?.length && securityDecorators?.length) {
|
|
330
|
+
throw new exceptions_1.GenerateMetadataError(`NoSecurity decorator cannot be used in conjunction with Security decorator in '${this.getCurrentLocation()}' method.`);
|
|
331
|
+
}
|
|
332
|
+
if (noSecurityDecorators?.length) {
|
|
333
|
+
return [];
|
|
334
|
+
}
|
|
335
|
+
if (!securityDecorators || !securityDecorators.length) {
|
|
336
|
+
return this.parentSecurity || [];
|
|
337
|
+
}
|
|
338
|
+
return securityDecorators.map(d => (0, decoratorUtils_1.getSecurites)(d, this.current.typeChecker));
|
|
339
|
+
}
|
|
340
|
+
getIsHidden() {
|
|
341
|
+
const hiddenDecorators = this.getDecoratorsByIdentifier(this.node, 'Hidden');
|
|
342
|
+
if (!hiddenDecorators || !hiddenDecorators.length) {
|
|
343
|
+
return !!this.isParentHidden;
|
|
344
|
+
}
|
|
345
|
+
if (this.isParentHidden) {
|
|
346
|
+
throw new exceptions_1.GenerateMetadataError(`Hidden decorator cannot be set on '${this.getCurrentLocation()}' it is already defined on the controller`);
|
|
347
|
+
}
|
|
348
|
+
if (hiddenDecorators.length > 1) {
|
|
349
|
+
throw new exceptions_1.GenerateMetadataError(`Only one Hidden decorator allowed in '${this.getCurrentLocation()}' method.`);
|
|
350
|
+
}
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
getDecoratorsByIdentifier(node, id) {
|
|
354
|
+
return (0, decoratorUtils_1.getDecorators)(node, identifier => identifier.text === id);
|
|
355
|
+
}
|
|
356
|
+
getProducesAdapter(produces) {
|
|
357
|
+
if (Array.isArray(produces)) {
|
|
358
|
+
return produces;
|
|
359
|
+
}
|
|
360
|
+
else if (typeof produces === 'string') {
|
|
361
|
+
return [produces];
|
|
362
|
+
}
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
exports.MethodGenerator = MethodGenerator;
|
|
367
|
+
//# sourceMappingURL=methodGenerator.js.map
|