UNPKG

typescript-swagger

Version:

Generate Swagger files from a decorator library like typescript-rest or a @decorators/express.

375 lines (373 loc) 17.4 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ParameterGenerator = void 0; var ts = require("typescript"); var type_1 = require("../decorator/type"); var utils_1 = require("../decorator/utils"); var resolver_1 = require("./resolver"); var utils_2 = require("./resolver/utils"); var supportedParameterKeys = [ 'SERVER_CONTEXT', 'SERVER_PARAMS', 'SERVER_QUERY', 'SERVER_FORM', 'SERVER_BODY', 'SERVER_HEADERS', 'SERVER_COOKIES', 'SERVER_PATH_PARAMS', 'SERVER_FILES_PARAM' ]; var ParameterGenerator = /** @class */ (function () { function ParameterGenerator(parameter, method, path, current) { this.parameter = parameter; this.method = method; this.path = path; this.current = current; } ParameterGenerator.prototype.generate = function () { var decorators = utils_1.getDecorators(this.parameter); var decoratorNames = decorators.map(function (decorator) { return decorator.text; }); for (var i = 0; i < supportedParameterKeys.length; i++) { var handler = type_1.Decorator.getRepresentationHandler(supportedParameterKeys[i], this.current.decoratorMap); var names = handler.getNames(); var index = -1; for (var j = 0; j < names.length; j++) { index = decoratorNames.indexOf(names[j]); if (index !== -1) { break; } } if (index === -1) { continue; } this.decorator = decorators[index]; this.decoratorHandler = handler; switch (supportedParameterKeys[i]) { case 'SERVER_CONTEXT': return this.getContextParameter(); case 'SERVER_PARAMS': return this.getRequestParameter(); case 'SERVER_FORM': return this.getFormParameter(); case 'SERVER_QUERY': return this.getQueryParameter(); case 'SERVER_BODY': return this.getBodyParameter(); case 'SERVER_HEADERS': return this.getHeaderParameter(); case 'SERVER_COOKIES': return this.getCookieParameter(); case 'SERVER_PATH_PARAMS': return this.getPathParameter(); case 'SERVER_FILE_PARAM': return this.getFileParameter(); case 'SERVER_FILES_PARAM': return this.getFileParameter(true); } } return this.getBodyParameter(); }; ParameterGenerator.prototype.getCurrentLocation = function () { var methodId = this.parameter.parent.name; var controllerId = this.parameter.parent.parent.name; return controllerId.text + "." + methodId.text; }; ParameterGenerator.prototype.getRequestParameter = function () { var parameterName = this.parameter.name.text; var name = parameterName; var type = this.getValidatedType(this.parameter); if (!this.supportsBodyParameters(this.method)) { throw new Error("Param can't support '" + this.getCurrentLocation() + "' method."); } if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { name = argument; } } return { description: this.getParameterDescription(this.parameter), in: 'param', name: name || parameterName, parameterName: parameterName, required: !this.parameter.questionToken, type: type }; }; ParameterGenerator.prototype.getContextParameter = function () { var parameterName = this.parameter.name.text; return { description: this.getParameterDescription(this.parameter), in: 'context', name: parameterName, parameterName: parameterName, required: !this.parameter.questionToken, type: null }; }; /* private getFileParameter(parameter: ts.ParameterDeclaration): Parameter { const parameterName = (parameter.name as ts.Identifier).text; if (!this.supportsBodyParameters(this.method)) { throw new Error(`FileParam can't support '${this.getCurrentLocation()}' method.`); } return { description: this.getParameterDescription(parameter), in: 'formData', name: getDecoratorTextValue(this.parameter, ident => ident.text === 'FileParam') || parameterName, parameterName: parameterName, required: !parameter.questionToken, type: { typeName: 'file' } }; } */ ParameterGenerator.prototype.getFileParameter = function (isArray) { var parameterName = this.parameter.name.text; var name = parameterName; if (!this.supportsBodyParameters(this.method)) { throw new Error("File(s)Param can't support '" + this.getCurrentLocation() + "' method."); } if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { name = argument; } } var elementType = { typeName: 'file' }; var type; if (isArray) { type = { typeName: 'array', elementType: elementType }; } else { type = elementType; } return { description: this.getParameterDescription(this.parameter), in: 'formData', name: name || parameterName, parameterName: parameterName, required: !this.parameter.questionToken && !this.parameter.initializer, type: type }; }; ParameterGenerator.prototype.getFormParameter = function () { var parameterName = this.parameter.name.text; var name = parameterName; var type = this.getValidatedType(this.parameter); if (!this.supportsBodyParameters(this.method)) { throw new Error("Form can't support '" + this.getCurrentLocation() + "' method."); } if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { name = argument; } } return { description: this.getParameterDescription(this.parameter), in: 'formData', name: name || parameterName, parameterName: parameterName, required: !this.parameter.questionToken && !this.parameter.initializer, type: type }; }; ParameterGenerator.prototype.getCookieParameter = function () { var parameterName = this.parameter.name.text; var name = parameterName; var type = this.getValidatedType(this.parameter); if (!this.supportPathDataType(type)) { throw new Error("Cookie can't support '" + this.getCurrentLocation() + "' method."); } if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { name = argument; } } return { description: this.getParameterDescription(this.parameter), in: 'cookie', name: name || parameterName, parameterName: parameterName, required: !this.parameter.questionToken && !this.parameter.initializer, type: type }; }; ParameterGenerator.prototype.getBodyParameter = function () { var parameterName = this.parameter.name.text; var name = parameterName; var type = this.getValidatedType(this.parameter); if (!this.supportsBodyParameters(this.method)) { throw new Error("Body can't support " + this.method + " method"); } if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { name = argument; } } return { description: this.getParameterDescription(this.parameter), in: 'body', name: name || parameterName, parameterName: parameterName, required: !this.parameter.questionToken && !this.parameter.initializer, type: type }; }; ParameterGenerator.prototype.getHeaderParameter = function () { var parameterName = this.parameter.name.text; var name = parameterName; var type = this.getValidatedType(this.parameter); if (!this.supportPathDataType(type)) { throw new InvalidParameterException("Parameter '" + parameterName + "' can't be passed as a header parameter in '" + this.getCurrentLocation() + "'."); } if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { name = argument; } } return { description: this.getParameterDescription(this.parameter), in: 'header', name: name || parameterName, parameterName: parameterName, required: !this.parameter.questionToken && !this.parameter.initializer, type: type }; }; ParameterGenerator.prototype.getQueryParameter = function () { var parameterName = this.parameter.name.text; var type = this.getValidatedType(this.parameter); if (!this.supportQueryDataType(type)) { /* const arrayType = getCommonPrimitiveAndArrayUnionType(parameter.type); if (arrayType && this.supportQueryDataType(arrayType)) { type = arrayType; } else { throw new InvalidParameterException(`Parameter '${parameterName}' can't be passed as a query parameter in '${this.getCurrentLocation()}'.`); } */ // throw new InvalidParameterException(`Parameter '${parameterName}' can't be passed as a query parameter in '${this.getCurrentLocation()}'.`); } var name = parameterName; var options = {}; if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var properties = this.decoratorHandler.getPropertiesByTypes(this.decorator.text, ['SIMPLE', 'OPTIONS']); // tslint:disable-next-line:forin for (var key in properties) { if (!properties.hasOwnProperty(key)) { continue; } switch (key) { case 'SIMPLE': var propertyName = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, properties[key]); if (typeof propertyName !== 'undefined') { name = propertyName; } break; case 'OPTIONS': var propertyOptions = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, properties[key]); if (typeof propertyOptions !== 'undefined') { options = propertyOptions; } break; } } } return { allowEmptyValue: options.allowEmptyValue, collectionFormat: options.collectionFormat, default: utils_2.getInitializerValue(this.parameter.initializer, this.current.typeChecker, type), description: this.getParameterDescription(this.parameter), in: 'query', maxItems: options.maxItems, minItems: options.minItems, name: name, parameterName: parameterName, required: !this.parameter.questionToken && !this.parameter.initializer, type: type }; }; ParameterGenerator.prototype.getPathParameter = function () { var parameterName = this.parameter.name.text; var pathName = parameterName; var type = this.getValidatedType(this.parameter); if (typeof this.decoratorHandler !== 'undefined' && typeof this.decorator !== 'undefined') { var argument = this.decoratorHandler.getDecoratorPropertyValueAsItem(this.decorator, this.decoratorHandler.getPropertyByType(this.decorator.text)); if (typeof argument === 'string') { pathName = argument; } } if (!this.supportPathDataType(type)) { throw new InvalidParameterException("Parameter '" + parameterName + ":" + type + "' can't be passed as a path parameter in '" + this.getCurrentLocation() + "'."); } if ((!this.path.includes("{" + pathName + "}")) && (!this.path.includes(":" + pathName))) { throw new Error("Parameter '" + parameterName + "' can't match in path: '" + this.path + "'"); } return { description: this.getParameterDescription(this.parameter), in: 'path', name: pathName, parameterName: parameterName, required: true, type: type }; }; ParameterGenerator.prototype.getParameterDescription = function (node) { var symbol = this.current.typeChecker.getSymbolAtLocation(node.name); if (symbol) { var comments = symbol.getDocumentationComment(this.current.typeChecker); if (comments.length) { return ts.displayPartsToString(comments); } } return ''; }; ParameterGenerator.prototype.supportsBodyParameters = function (method) { return ['delete', 'post', 'put', 'patch', 'get'].some(function (m) { return m === method; }); }; ParameterGenerator.prototype.supportPathDataType = function (parameterType) { return ['string', 'integer', 'long', 'float', 'double', 'date', 'datetime', 'buffer', 'boolean', 'enum'].find(function (t) { return t === parameterType.typeName; }); }; ParameterGenerator.prototype.supportQueryDataType = function (parameterType) { // Copied from supportPathDataType and added 'array'. Not sure if all options apply to queries, but kept to avoid breaking change. return ['string', 'integer', 'long', 'float', 'double', 'date', 'datetime', 'buffer', 'boolean', 'enum', 'array', 'object'].find(function (t) { return t === parameterType.typeName; }); }; ParameterGenerator.prototype.getValidatedType = function (parameter) { var typeNode = parameter.type; if (!typeNode) { var type = this.current.typeChecker.getTypeAtLocation(parameter); typeNode = this.current.typeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.NoTruncation); } return new resolver_1.TypeNodeResolver(typeNode, this.current, parameter).resolve(); }; return ParameterGenerator; }()); exports.ParameterGenerator = ParameterGenerator; var InvalidParameterException = /** @class */ (function (_super) { __extends(InvalidParameterException, _super); function InvalidParameterException() { return _super !== null && _super.apply(this, arguments) || this; } return InvalidParameterException; }(Error)); //# sourceMappingURL=parameterGenerator.js.map