UNPKG

ern-api-gen

Version:

Electrode Native API generator

1,337 lines 103 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* tslint:disable:variable-name */ const ExampleGenerator_1 = __importDefault(require("./examples/ExampleGenerator")); const CliOption_1 = __importDefault(require("./CliOption")); const CodegenConstants_1 = __importDefault(require("./CodegenConstants")); const CodegenModelFactory_1 = __importDefault(require("./CodegenModelFactory")); const CodegenModelType_1 = __importDefault(require("./CodegenModelType")); const camelCase_1 = __importDefault(require("lodash/camelCase")); const factory_1 = __importDefault(require("./models/factory")); const properties_1 = require("./models/properties"); const parameters_1 = require("./models/parameters"); const System_1 = __importDefault(require("./java/System")); const LoggerFactory_1 = __importDefault(require("./java/LoggerFactory")); const File_1 = __importDefault(require("./java/File")); const StringBuilder_1 = __importDefault(require("./java/StringBuilder")); const javaUtil_1 = require("./java/javaUtil"); const StringUtils_1 = __importDefault(require("./java/StringUtils")); const Json_1 = __importDefault(require("./java/Json")); const StringEscapeUtils_1 = __importDefault(require("./java/StringEscapeUtils")); const ArrayModel_1 = __importDefault(require("./models/ArrayModel")); const ComposedModel_1 = __importDefault(require("./models/ComposedModel")); const ModelImpl_1 = __importDefault(require("./models/ModelImpl")); const RefModel_1 = __importDefault(require("./models/RefModel")); const ApiKeyAuthDefinition_1 = __importDefault(require("./models/auth/ApiKeyAuthDefinition")); const BasicAuthDefinition_1 = __importDefault(require("./models/auth/BasicAuthDefinition")); const In_1 = require("./models/auth/In"); const PropertyBuilder_1 = __importDefault(require("./models/PropertyBuilder")); const path_1 = __importDefault(require("path")); const _count2 = (_, i) => ++i; const COMMON_PREFIX_RE = new RegExp('[a-zA-Z0-9]+\\z', 'g'); const sortByFlag = (one, another) => { const oneRequired = one.required == null ? false : one.required; const anotherRequired = another.required == null ? false : another.required; if (oneRequired === anotherRequired) { return 0; } else if (oneRequired) { return -1; } else { return 1; } }; class DefaultCodegen { /** * Default constructor. * This method will map between Swagger type and language-specified type, as well as mapping * between Swagger type and the corresponding import statement for the language. This will * also add some language specified CLI options, if any. * * * returns string presentation of the example path (it's a constructor) */ constructor() { this.__outputFolder = ''; this.__languageSpecificPrimitives = javaUtil_1.newHashSet(); this.__modelPackage = ''; this.__apiPackage = ''; this.modelNamePrefix = ''; this.modelNameSuffix = ''; this.__testPackage = ''; this.__apiTemplateFiles = javaUtil_1.newHashMap(); this.__apiDataTemplateFile = javaUtil_1.newHashMap(); this.__modelTemplateFiles = javaUtil_1.newHashMap(); this.__apiTestTemplateFiles = javaUtil_1.newHashMap(); this.__modelTestTemplateFiles = javaUtil_1.newHashMap(); this.__apiDocTemplateFiles = javaUtil_1.newHashMap(); this.__modelDocTemplateFiles = javaUtil_1.newHashMap(); this.commonTemplateDir = '_common'; this.__additionalProperties = javaUtil_1.newHashMap(); this.__vendorExtensions = javaUtil_1.newHashMap(); this.__supportingFiles = []; this.__cliOptions = []; this.__supportedLibraries = javaUtil_1.newHashMap(); this.sortParamsByRequiredFlag = true; this.ensureUniqueParams = true; this.specialCharReplacements = javaUtil_1.newHashMap(); this.skipOverwrite = false; this.supportsInheritance = false; this.__defaultIncludes = javaUtil_1.newHashSet('double', 'int', 'long', 'short', 'char', 'float', 'String', 'boolean', 'Boolean', 'Double', 'Void', 'Integer', 'Long', 'Float'); this.__typeMapping = javaUtil_1.newHashMap(['array', 'List'], ['map', 'Map'], ['List', 'List'], ['boolean', 'Boolean'], ['string', 'String'], ['int', 'Integer'], ['float', 'Float'], ['number', 'BigDecimal'], ['DateTime', 'Date'], ['long', 'Long'], ['short', 'Short'], ['char', 'String'], ['double', 'Double'], ['object', 'Object'], ['integer', 'Integer'], ['ByteArray', 'byte[]'], ['binary', 'byte[]']); this.__instantiationTypes = javaUtil_1.newHashMap(); this.__reservedWords = javaUtil_1.newHashSet(); this.__importMapping = javaUtil_1.newHashMap(['BigDecimal', 'java.math.BigDecimal'], ['UUID', 'java.util.UUID'], ['File', 'java.io.File'], ['Date', 'java.util.Date'], ['Timestamp', 'java.sql.Timestamp'], ['Map', 'java.util.Map'], ['HashMap', 'java.util.HashMap'], ['Array', 'java.util.List'], ['ArrayList', 'java.util.ArrayList'], ['List', 'java.util.*'], ['Set', 'java.util.*'], ['DateTime', 'org.joda.time.*'], ['LocalDateTime', 'org.joda.time.*'], ['LocalDate', 'org.joda.time.*'], ['LocalTime', 'org.joda.time.*']); this.initalizeCliOptions(); this.initalizeSpecialCharacterMapping(); } static addHasMore(objs) { if (objs == null) { return; } if (Array.isArray(objs)) { for (let i = 0, l = objs.length, lm = l - 1; i < l; i++) { if (i > 0) { objs[i].secondaryParam = true; } objs[i].hasMore = i < lm; } return objs; } // what? insanity for (let i = 0; i < objs.size - 1; i++) { if (i > 0) { objs.put('secondaryParam', true); } objs.put('hasMore', i < objs.size - 1); } return objs; } /** * Underscore the given word. * Copied from Twitter elephant bird * https://github.com/twitter/elephant-bird/blob/master/core/src/main/java/com/twitter/elephantbird/util/Strings.java * * @param word The word * @return The underscored version of the word */ static underscore(word) { const firstPattern = '([A-Z]+)([A-Z][a-z])'; const secondPattern = '([a-z\\d])([A-Z])'; const replacementPattern = '$1_$2'; word = word.replace(new RegExp('\\.', 'g'), '/'); word = word.replace(new RegExp('\\$', 'g'), '__'); word = word.replace(new RegExp(firstPattern, 'g'), replacementPattern); word = word.replace(new RegExp(secondPattern, 'g'), replacementPattern); word = word.split('-').join('_'); word = word.toLowerCase(); return word; } /** * Camelize name (parameter, property, method, etc) * * @param word string to be camelize * @param lowercaseFirstLetter lower case for first letter if set to true * @return camelized string */ static camelize(word, lowercaseFirstLetter = false) { word = camelCase_1.default(word); return (word && word[0][lowercaseFirstLetter ? 'toLowerCase' : 'toUpperCase']() + word.substring(1)); } /** * Generate the next name for the given name, i.e. append "2" to the base name if not ending with a number, * otherwise increase the number by 1. For example: * status => status2 * status2 => status3 * myName100 => myName101 * * @param name The base name * @return The next name for the base name */ static generateNextName(name) { const re = /(\d{1,})/; if (re.test(name)) { return name.replace(re, _count2); } return name + '2'; } initalizeCliOptions() { this.__cliOptions.push(CliOption_1.default.newBoolean(CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG, CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG_DESC).defaultValue('true')); this.__cliOptions.push(CliOption_1.default.newBoolean(CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS, CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS_DESC).defaultValue('true')); } cliOptions() { return this.__cliOptions; } processOpts() { if (this.__additionalProperties.containsKey(CodegenConstants_1.default.TEMPLATE_DIR)) { this.setTemplateDir(this.__additionalProperties.get(CodegenConstants_1.default.TEMPLATE_DIR)); } if (this.__additionalProperties.containsKey(CodegenConstants_1.default.MODEL_PACKAGE)) { this.setModelPackage(this.__additionalProperties.get(CodegenConstants_1.default.MODEL_PACKAGE)); } if (this.__additionalProperties.containsKey(CodegenConstants_1.default.API_PACKAGE)) { this.setApiPackage(this.__additionalProperties.get(CodegenConstants_1.default.API_PACKAGE)); } if (this.__additionalProperties.containsKey(CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG)) { this.setSortParamsByRequiredFlag(Boolean(this.__additionalProperties.get(CodegenConstants_1.default.SORT_PARAMS_BY_REQUIRED_FLAG))); } if (this.__additionalProperties.containsKey(CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS)) { this.setEnsureUniqueParams(Boolean(this.__additionalProperties.get(CodegenConstants_1.default.ENSURE_UNIQUE_PARAMS))); } if (this.__additionalProperties.containsKey(CodegenConstants_1.default.MODEL_NAME_PREFIX)) { this.setModelNamePrefix(this.__additionalProperties.get(CodegenConstants_1.default.MODEL_NAME_PREFIX)); } if (this.__additionalProperties.containsKey(CodegenConstants_1.default.MODEL_NAME_SUFFIX)) { this.setModelNameSuffix(this.__additionalProperties.get(CodegenConstants_1.default.MODEL_NAME_SUFFIX)); } } addLicenseFile() { return true; } addSwaggerIgnoreFile() { return true; } postProcessAllModels(objs) { if (this.supportsInheritance) { const allModels = javaUtil_1.newHashMap(); for (const [key, inner] of objs) { const modelName = this.toModelName(key); for (const mo of inner.get('models')) { allModels.put(modelName, mo.get('model')); } } for (const [key, cm] of allModels) { if (cm.parent != null) { cm.parentModel = allModels.get(cm.parent); } if (javaUtil_1.isNotEmptySet(cm.interfaces)) { cm.interfaceModels = []; for (const intf of cm.interfaces) { const intfModel = allModels.get(intf); if (intfModel != null) { cm.interfaceModels.push(intfModel); } } } } } return objs; } postProcessModels(objs) { return objs; } /** * post process enum defined in model's properties * * @param objs Map of models * @return maps of models with better enum support */ postProcessModelsEnum(objs) { const models = objs.get('models'); for (const mo of models) { const cm = mo.get('model'); if (cm.isEnum && cm.allowableValues != null) { const allowableValues = cm.allowableValues; const values = allowableValues.get('values'); const enumVars = []; const commonPrefix = this.findCommonPrefixOfVars(values); const truncateIdx = commonPrefix.length; cm.allowableValues.put('enumVars', enumVars); for (const value of values) { let enumName; if (truncateIdx === 0) { enumName = value.toString(); } else { enumName = value.toString().substring(truncateIdx); if ('' === enumName) { enumName = value.toString(); } } enumVars.push(javaUtil_1.newHashMap(['name', this.toEnumVarName(enumName, cm.dataType)], ['value', this.toEnumValue(value.toString(), cm.dataType)])); } } for (const _var of cm.vars) { this.updateCodegenPropertyEnum(_var); } } return objs; } /** * Returns the common prefix of variables for enum naming * * @param vars List of variable names * @return the common prefix for naming */ findCommonPrefixOfVars(listStr) { try { const prefix = StringUtils_1.default.getCommonPrefix(listStr); return prefix.replace(COMMON_PREFIX_RE, ''); } catch (e) { Log.trace(e); return ''; } } /** * Return the enum default value in the language specifed format * * @param value enum variable name * @param datatype data type * @return the default value for the enum */ toEnumDefaultValue(value, datatype) { return datatype + '.' + value; } /** * Return the enum value in the language specifed format * e.g. status becomes "status" * * @param value enum variable name * @param datatype data type * @return the sanitized value for enum */ toEnumValue(value, datatype) { if ('number' === '' + datatype.toLowerCase()) { return value; } return '"' + this.escapeText(value) + '"'; } /** * Return the sanitized variable name for enum * * @param value enum variable name * @param datatype data type * @return the sanitized variable name for enum */ toEnumVarName(value, datatype) { const __var = value.replace(new RegExp('\\W+', 'g'), '_').toUpperCase(); if (__var.match('\\d.*')) { return '_' + __var; } else { return __var; } } postProcessOperations(objs) { return objs; } postProcessSupportingFileData(objs) { return objs; } postProcessModelProperty(model, property) { // Empty } postProcessParameter(parameter) { // Empty } preprocessSwagger(swagger) { // Empty } processSwagger(swagger) { // Empty } escapeText(input) { if (input == null) { return input; } return this.escapeUnsafeCharacters(StringEscapeUtils_1.default.unescapeJava(StringEscapeUtils_1.default.escapeJava(input) .split('\\/') .join('/')) .replace(new RegExp('[\\t\\n\\r]', 'g'), ' ') .split('\\') .join('\\\\') .split('"') .join('\\"')); } /** * override with any special text escaping logic to handle unsafe * characters so as to avoid code injection * @param input String to be cleaned up * @return string with unsafe characters removed or escaped */ escapeUnsafeCharacters(input) { Log.warn('escapeUnsafeCharacters should be overriden in the code generator with proper logic to escape unsafe characters'); return input; } /** * Escape single and/or double quote to avoid code injection * @param input String to be cleaned up * @return string with quotation mark removed or escaped */ escapeQuotationMark(input) { Log.warn('escapeQuotationMark should be overriden in the code generator with proper logic to escape single/double quote'); return input.split('"').join('\\"'); } defaultIncludes() { return this.__defaultIncludes; } typeMapping() { return this.__typeMapping; } instantiationTypes() { return this.__instantiationTypes; } reservedWords() { return this.__reservedWords; } languageSpecificPrimitives() { return this.__languageSpecificPrimitives; } importMapping() { return this.__importMapping; } testPackage() { return this.__testPackage; } modelPackage() { return this.__modelPackage; } apiPackage() { return this.__apiPackage; } fileSuffix() { return this.__fileSuffix; } templateDir() { return this.__templateDir; } embeddedTemplateDir() { if (this.__embeddedTemplateDir != null) { return this.__embeddedTemplateDir; } else { return this.__templateDir; } } getCommonTemplateDir() { return this.commonTemplateDir; } etCommonTemplateDir(commonTemplateDir) { this.commonTemplateDir = commonTemplateDir; } apiDocTemplateFiles() { return this.__apiDocTemplateFiles; } modelDocTemplateFiles() { return this.__modelDocTemplateFiles; } apiTestTemplateFiles() { return this.__apiTestTemplateFiles; } modelTestTemplateFiles() { return this.__modelTestTemplateFiles; } apiTemplateFiles() { return this.__apiTemplateFiles; } apiDataTemplateFile() { return this.__apiDataTemplateFile; } modelTemplateFiles() { return this.__modelTemplateFiles; } apiFileFolder() { return (this.__outputFolder + path_1.default.sep + this.apiPackage() .split('.') .join(path_1.default.sep)); } /** * Checks to see if an API file needs to be generated for this template, helps to apply some logic when you have more than one api file which is condition based. * @param templateName * @param operation * @returns {boolean} */ shouldGenerateApiFor(templateName, operation) { return true; } modelFileFolder() { return (this.__outputFolder + path_1.default.sep + this.modelPackage() .split('.') .join(path_1.default.sep)); } apiTestFileFolder() { return (this.__outputFolder + path_1.default.sep + this.testPackage() .split('.') .join(path_1.default.sep)); } modelTestFileFolder() { return (this.__outputFolder + path_1.default.sep + this.testPackage() .split('.') .join(path_1.default.sep)); } apiDocFileFolder() { return this.__outputFolder; } modelDocFileFolder() { return this.__outputFolder; } additionalProperties() { return this.__additionalProperties; } vendorExtensions() { return this.__vendorExtensions; } supportingFiles() { return this.__supportingFiles; } outputFolder() { return this.__outputFolder; } setOutputDir(dir) { this.__outputFolder = dir; } getOutputDir() { return this.outputFolder(); } setTemplateDir(templateDir) { this.__templateDir = templateDir; } setModelPackage(modelPackage) { this.__modelPackage = modelPackage; } setModelNamePrefix(modelNamePrefix) { this.modelNamePrefix = modelNamePrefix; } setModelNameSuffix(modelNameSuffix) { this.modelNameSuffix = modelNameSuffix; } setApiPackage(apiPackage) { this.__apiPackage = apiPackage; } setSortParamsByRequiredFlag(sortParamsByRequiredFlag) { this.sortParamsByRequiredFlag = sortParamsByRequiredFlag; } setEnsureUniqueParams(ensureUniqueParams) { this.ensureUniqueParams = ensureUniqueParams; } /** * Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33) * * @param pattern the pattern (regular expression) * @return properly-escaped pattern */ toRegularExpression(pattern) { return this.escapeText(pattern); } /** * Return the file name of the Api Test * * @param name the file name of the Api * @return the file name of the Api */ toApiFilename(name) { return this.toApiName(name); } /** * Return the file name of the Api Documentation * * @param name the file name of the Api * @return the file name of the Api */ toApiDocFilename(name) { return this.toApiName(name); } /** * Return the file name of the Api Test * * @param name the file name of the Api * @return the file name of the Api */ toApiTestFilename(name) { return this.toApiName(name) + 'Test'; } /** * Return the variable name in the Api * * @param name the varible name of the Api * @return the snake-cased variable name */ toApiVarName(name) { return this.snakeCase(name); } /** * Return the capitalized file name of the model * * @param name the model name * @return the file name of the model */ toModelFilename(name) { return this.initialCaps(name); } /** * Return the capitalized file name of the model test * * @param name the model name * @return the file name of the model */ toModelTestFilename(name) { return this.initialCaps(name) + 'Test'; } /** * Return the capitalized file name of the model documentation * * @param name the model name * @return the file name of the model */ toModelDocFilename(name) { return this.initialCaps(name); } /** * Return the operation ID (method name) * * @param operationId operation ID * @return the sanitized method name */ toOperationId(operationId) { if (StringUtils_1.default.isEmpty(operationId)) { throw new Error('Empty method name (operationId) not allowed'); } return operationId; } /** * Return the variable name by removing invalid characters and proper escaping if * it's a reserved word. * * @param name the variable name * @return the sanitized variable name */ toVarName(name) { if (this.__reservedWords.contains(name)) { return this.escapeReservedWord(name); } else { return name; } } /** * Return the parameter name by removing invalid characters and proper escaping if * it's a reserved word. * * @param name Codegen property object * @return the sanitized parameter name */ toParamName(name) { name = this.removeNonNameElementToCamelCase(name); if (this.__reservedWords.contains(name)) { return this.escapeReservedWord(name); } return name; } /** * Return the Enum name (e.g. StatusEnum given 'status') * * @param property Codegen property * @return the Enum name */ toEnumName(property) { return StringUtils_1.default.capitalize(property.name) + 'Enum'; } /** * Return the escaped name of the reserved word * * @param name the name to be escaped * @return the escaped reserved word * * throws Runtime exception as reserved word is not allowed (default behavior) */ escapeReservedWord(name) { throw new Error('reserved word ' + name + ' not allowed'); } /** * Return the fully-qualified "Model" name for import * * @param name the name of the "Model" * @return the fully-qualified "Model" name for import */ toModelImport(name) { if ('' === this.modelPackage()) { return name; } else { return this.modelPackage() + '.' + name; } } /** * Return the fully-qualified "Api" name for import * * @param name the name of the "Api" * @return the fully-qualified "Api" name for import */ toApiImport(name) { return this.apiPackage() + '.' + name; } /** * Initalize special character mapping */ initalizeSpecialCharacterMapping() { this.specialCharReplacements.put('$', 'Dollar'); this.specialCharReplacements.put('^', 'Caret'); this.specialCharReplacements.put('|', 'Pipe'); this.specialCharReplacements.put('=', 'Equal'); this.specialCharReplacements.put('*', 'Star'); this.specialCharReplacements.put('-', 'Minus'); this.specialCharReplacements.put('&', 'Ampersand'); this.specialCharReplacements.put('%', 'Percent'); this.specialCharReplacements.put('#', 'Hash'); this.specialCharReplacements.put('@', 'At'); this.specialCharReplacements.put('!', 'Exclamation'); this.specialCharReplacements.put('+', 'Plus'); this.specialCharReplacements.put(':', 'Colon'); this.specialCharReplacements.put('>', 'Greater_Than'); this.specialCharReplacements.put('<', 'Less_Than'); this.specialCharReplacements.put('.', 'Period'); this.specialCharReplacements.put('_', 'Underscore'); this.specialCharReplacements.put('<=', 'Less_Than_Or_Equal_To'); this.specialCharReplacements.put('>=', 'Greater_Than_Or_Equal_To'); this.specialCharReplacements.put('!=', 'Not_Equal'); } /** * Return the symbol name of a symbol * * @param input Symbol (e.g. $) * @return Symbol name (e.g. Dollar) */ getSymbolName(input) { return this.specialCharReplacements.get(input); } /** * Return the instantiation type of the property, especially for map and array * * @param p Swagger property object * @return string presentation of the instantiation type of the property */ toInstantiationType(p) { if (p != null && p instanceof properties_1.MapProperty) { const ap = p; const additionalProperties2 = ap.getAdditionalProperties(); const type = additionalProperties2.getType(); if (null == type) { Log.error('No Type defined for Additional Property ' + additionalProperties2 + '\n\tIn Property: ' + p); } const inner = this.getSwaggerType(additionalProperties2); return this.__instantiationTypes.get('map') + '<String, ' + inner + '>'; } else if (p != null && p instanceof properties_1.ArrayProperty) { const ap = p; const inner = this.getSwaggerType(ap.getItems()); return this.__instantiationTypes.get('array') + '<' + inner + '>'; } else { return null; } } /** * Return the example value of the parameter. * * @param p Swagger property object */ setParameterExampleValue(p) { // Empty } /** * Return the example value of the property * * @param p Swagger property object * @return string presentation of the example value of the property */ toExampleValue(p) { if (p.getExample() != null) { return p.getExample().toString(); } if (p instanceof properties_1.StringProperty) { return 'null'; } else if (p instanceof properties_1.BooleanProperty) { return 'null'; } else if (p instanceof properties_1.DateProperty) { return 'null'; } else if (p instanceof properties_1.DateTimeProperty) { return 'null'; } else if (p instanceof properties_1.DoubleProperty) { const dp = p; if (dp.getExample() != null) { return dp.getExample().toString(); } return 'null'; } else if (p instanceof properties_1.FloatProperty) { const dp = p; if (dp.getExample() != null) { return dp.getExample().toString(); } return 'null'; } else if (p instanceof properties_1.IntegerProperty) { const dp = p; if (dp.getExample() != null) { return dp.getExample().toString(); } return 'null'; } else if (p instanceof properties_1.LongProperty) { const dp = p; if (dp.getExample() != null) { return dp.getExample().toString(); } return 'null'; } else { return 'null'; } } /** * Return the default value of the property * * @param p Swagger property object * @return string presentation of the default value of the property */ toDefaultValue(p) { if (p != null && p instanceof properties_1.StringProperty) { return 'null'; } else if (p != null && p instanceof properties_1.BooleanProperty) { return 'null'; } else if (p != null && p instanceof properties_1.DateProperty) { return 'null'; } else if (p != null && p instanceof properties_1.DateTimeProperty) { return 'null'; } else if (p != null && p instanceof properties_1.DoubleProperty) { const dp = p; if (dp.getDefault() != null) { return dp.getDefault().toString(); } return 'null'; } else if (p != null && p instanceof properties_1.FloatProperty) { const dp = p; if (dp.getDefault() != null) { return dp.getDefault().toString(); } return 'null'; } else if (p != null && p instanceof properties_1.IntegerProperty) { const dp = p; if (dp.getDefault() != null) { return dp.getDefault().toString(); } return 'null'; } else if (p != null && p instanceof properties_1.LongProperty) { const dp = p; if (dp.getDefault() != null) { return dp.getDefault().toString(); } return 'null'; } else { return 'null'; } } /** * Return the property initialized from a data object * Useful for initialization with a plain object in Javascript * * @param name Name of the property object * @param p Swagger property object * @return string presentation of the default value of the property */ toDefaultValueWithParam(name, p) { return ' = data.' + name + ';'; } /** * returns the swagger type for the property * @param p Swagger property object * @return string presentation of the type */ getSwaggerType(p) { let datatype = null; if (p != null && p instanceof properties_1.StringProperty && 'number' === p.getFormat()) { datatype = 'BigDecimal'; } else if (p != null && p instanceof properties_1.StringProperty) { datatype = 'string'; } else if (p != null && p instanceof properties_1.ByteArrayProperty) { datatype = 'ByteArray'; } else if (p != null && p instanceof properties_1.BinaryProperty) { datatype = 'binary'; } else if (p != null && p instanceof properties_1.BooleanProperty) { datatype = 'boolean'; } else if (p != null && p instanceof properties_1.DateProperty) { datatype = 'date'; } else if (p != null && p instanceof properties_1.DateTimeProperty) { datatype = 'DateTime'; } else if (p != null && p instanceof properties_1.DoubleProperty) { datatype = 'double'; } else if (p != null && p instanceof properties_1.FloatProperty) { datatype = 'float'; } else if (p != null && p instanceof properties_1.IntegerProperty) { datatype = 'integer'; } else if (p != null && p instanceof properties_1.LongProperty) { datatype = 'long'; } else if (p != null && p instanceof properties_1.MapProperty) { datatype = 'map'; } else if (p != null && p instanceof properties_1.DecimalProperty) { datatype = 'number'; } else if (p != null && p instanceof properties_1.UUIDProperty) { datatype = 'UUID'; } else if (p != null && p instanceof properties_1.RefProperty) { try { const r = p; datatype = r.get$ref(); if (datatype.indexOf('#/definitions/') === 0) { datatype = datatype.substring('#/definitions/'.length); } } catch (e) { Log.warn('Error obtaining the datatype from RefProperty:' + p + '. Datatype default to Object'); Log.trace(e); datatype = 'Object'; } } else { if (p != null) { datatype = p.getType(); } } return datatype; } /** * Return the snake-case of the string * * @param name string to be snake-cased * @return snake-cased string */ snakeCase(name) { return StringUtils_1.default.snakeCase(name); } /** * Capitalize the string * * @param name string to be capitalized * @return capitalized string */ initialCaps(name) { return StringUtils_1.default.capitalize(name); } /** * Output the type declaration of a given name * * @param name name * @return a string presentation of the type */ getTypeDeclaration(name) { if (name == null || typeof name === 'string') { return name; } let swaggerType = this.getSwaggerType(name); if (this.__typeMapping.containsKey(swaggerType)) { swaggerType = this.__typeMapping.get(swaggerType); } return swaggerType; } /** * Output the API (class) name (capitalized) ending with "Api" * Return DefaultApi if name is empty * * @param name the name of the Api * @return capitalized Api name ending with "Api" */ toApiName(name) { if (name.length === 0) { return 'DefaultApi'; } return this.initialCaps(name) + 'Api'; } /** * Output the proper model name (capitalized) * * @param name the name of the model * @return capitalized model name */ toModelName(name) { return this.initialCaps(this.modelNamePrefix + name + this.modelNameSuffix); } /** * Convert Swagger Model object to Codegen Model object * * @param name the name of the model * @param model Swagger Model object * @param allDefinitions a map of all Swagger models from the spec * @return Codegen Model object */ fromModel(name, model, allDefinitions = null) { const m = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.MODEL); if (this.__reservedWords.contains(name)) { m.name = this.escapeReservedWord(name); } else { m.name = name; } m.description = this.escapeText(model.getDescription()); m.unescapedDescription = model.getDescription(); m.classname = this.toModelName(name); m.classVarName = this.toVarName(name); m.classFilename = this.toModelFilename(name); m.modelJson = Json_1.default.pretty(model); m.externalDocs = model.getExternalDocs(); m.vendorExtensions = model.getVendorExtensions(); if (model != null && model instanceof ModelImpl_1.default) { m.discriminator = model.getDiscriminator(); } if (model != null && model instanceof ArrayModel_1.default) { const am = model; const arrayProperty = new properties_1.ArrayProperty().items(am.getItems()); m.hasEnums = false; m.isArrayModel = true; m.arrayModelType = this.fromProperty(name, arrayProperty).complexType; this.addParentContainer(m, name, arrayProperty); } else if (model != null && model instanceof RefModel_1.default) { // Empty } else if (model != null && model instanceof ComposedModel_1.default) { const composed = model; const properties = javaUtil_1.newHashMap(); const required = []; let allProperties; let allRequired; if (this.supportsInheritance) { allProperties = javaUtil_1.newHashMap(); allRequired = []; m.allVars = []; } else { allProperties = null; allRequired = null; } let parent = composed.getParent(); if (composed.getInterfaces() != null) { if (m.interfaces == null) { m.interfaces = []; } for (const _interface of composed.getInterfaces()) { let interfaceModel = null; if (allDefinitions != null) { interfaceModel = allDefinitions.get(_interface.getSimpleRef()); } if (parent == null && (interfaceModel != null && interfaceModel instanceof ModelImpl_1.default) && interfaceModel.getDiscriminator() != null) { parent = _interface; } else { const interfaceRef = this.toModelName(_interface.getSimpleRef()); m.interfaces.push(interfaceRef); this.addImport(m, interfaceRef); if (allDefinitions != null) { if (this.supportsInheritance) { this.addProperties(allProperties, allRequired, interfaceModel, allDefinitions); } else { this.addProperties(properties, required, interfaceModel, allDefinitions); } } } } } if (parent != null) { const parentRef = parent.getSimpleRef(); m.parentSchema = parentRef; m.parent = this.toModelName(parent.getSimpleRef()); this.addImport(m, m.parent); if (allDefinitions != null) { const parentModel = allDefinitions.get(m.parentSchema); if (this.supportsInheritance) { this.addProperties(allProperties, allRequired, parentModel, allDefinitions); } else { this.addProperties(properties, required, parentModel, allDefinitions); } } } let child = composed.getChild(); if (child != null && (child != null && child instanceof RefModel_1.default) && allDefinitions != null) { const childRef = child.getSimpleRef(); child = allDefinitions.get(childRef); } if (child != null && (child != null && child instanceof ModelImpl_1.default)) { this.addProperties(properties, required, child, allDefinitions); if (this.supportsInheritance) { this.addProperties(allProperties, allRequired, child, allDefinitions); } } this.addVars(m, properties, required, allProperties, allRequired); } else { const impl = model; if (impl.getEnum() != null && impl.getEnum().length > 0) { m.isEnum = true; m.allowableValues = javaUtil_1.newHashMap(); m.allowableValues.put('values', impl.getEnum()); const p = PropertyBuilder_1.default.build(impl.getType(), impl.getFormat(), null); m.dataType = this.getSwaggerType(p); } if (impl.getAdditionalProperties && impl.getAdditionalProperties() != null) { this.addAdditionPropertiesToCodeGenModel(m, impl); } this.addVars(m, impl.getProperties(), impl.getRequired()); } if (m.vars != null) { for (const prop of m.vars) { this.postProcessModelProperty(m, prop); } } return m; } addAdditionPropertiesToCodeGenModel(codegenModel, swaggerModel) { const mapProperty = new properties_1.MapProperty(swaggerModel.getAdditionalProperties()); this.addParentContainer(codegenModel, codegenModel.name, mapProperty); } addProperties(properties, required, model, allDefinitions) { if (model != null && model instanceof ModelImpl_1.default) { const mi = model; if (mi.getProperties() != null) { properties.putAll(mi.getProperties()); } if (mi.getRequired() != null) { required.push(...mi.getRequired()); } } else if (model != null && model instanceof RefModel_1.default) { const interfaceRef = model.getSimpleRef(); const interfaceModel = allDefinitions.get(interfaceRef); this.addProperties(properties, required, interfaceModel, allDefinitions); } else if (model != null && model instanceof ComposedModel_1.default) { for (const component of model.getAllOf()) { this.addProperties(properties, required, component, allDefinitions); } } } /** * Camelize the method name of the getter and setter * * @param name string to be camelized * @return Camelized string */ getterAndSetterCapitalize(name) { if (name == null || name.length === 0) { return name; } return DefaultCodegen.camelize(this.toVarName(name)); } /** * Convert Swagger Property object to Codegen Property object * * @param name name of the property * @param p Swagger property object * @return Codegen Property object */ fromProperty(name, p) { if (p == null) { Log.error('unexpected missing property for name ' + name); return null; } const property = CodegenModelFactory_1.default.newInstance(CodegenModelType_1.default.PROPERTY); property.name = this.toVarName(name); property.baseName = name; property.nameInCamelCase = DefaultCodegen.camelize(property.name, false); property.description = this.escapeText(p.getDescription()); property.unescapedDescription = p.getDescription(); property.getter = 'get' + this.getterAndSetterCapitalize(name); property.setter = 'set' + this.getterAndSetterCapitalize(name); property.example = this.toExampleValue(p); property.defaultValue = this.toDefaultValue(p); property.defaultValueWithParam = this.toDefaultValueWithParam(name, p); property.jsonSchema = Json_1.default.pretty(p); property.isReadOnly = p.getReadOnly(); property.vendorExtensions = p.getVendorExtensions(); const type = this.getSwaggerType(p); const allowableValues = javaUtil_1.newHashMap(); if (p instanceof properties_1.AbstractNumericProperty) { const np = p; property.minimum = np.getMinimum(); property.maximum = np.getMaximum(); property.exclusiveMinimum = np.getExclusiveMinimum(); property.exclusiveMaximum = np.getExclusiveMaximum(); if (property.minimum != null || property.maximum != null || property.exclusiveMinimum != null || property.exclusiveMaximum != null) { property.hasValidation = true; } if (np.getMinimum() != null) { allowableValues.put('min', np.getMinimum()); } if (np.getMaximum() != null) { allowableValues.put('max', np.getMaximum()); } } if (p instanceof properties_1.StringProperty) { const sp = p; property.maxLength = sp.getMaxLength(); property.minLength = sp.getMinLength(); property.datatype = type; property.isString = true; property.isPrimitive = true; property.pattern = this.toRegularExpression(sp.getPattern()); if (property.pattern != null || property.minLength != null || property.maxLength != null) { property.hasValidation = true; } property.isString = true; } else if (p instanceof properties_1.BaseIntegerProperty && !(p instanceof properties_1.IntegerProperty) && !(p instanceof properties_1.LongProperty)) { property.isInteger = true; } else if (p instanceof properties_1.IntegerProperty) { property.isInteger = true; } else if (p instanceof properties_1.LongProperty) { property.isLong = true; } else if (p instanceof properties_1.BooleanProperty) { property.isBoolean = true; } else if (p instanceof properties_1.BinaryProperty) { property.isBinary = true; } else if (p instanceof properties_1.UUIDProperty) { property.isString = true; } else if (p instanceof properties_1.ByteArrayProperty) { property.isByteArray = true; } else if (p instanceof properties_1.DecimalProperty && !(p instanceof properties_1.DoubleProperty) && !(p instanceof properties_1.FloatProperty)) { property.isFloat = true; } else if (p instanceof properties_1.DoubleProperty) { property.isDouble = true; } else if (p instanceof properties_1.FloatProperty) { property.isFloat = true; } else if (p instanceof properties_1.DateProperty) { property.isDate = true; } else if (p instanceof properties_1.DateTimeProperty) { property.isDateTime = true; } if (p.getEnum() != null) { const _enum = p.getEnum(); property._enum = _enum; property.isEnum = true; allowableValues.put('values', _enum); } if (!allowableValues.isEmpty()) { property.allowableValues = allowableValues; } property.datatype = this.getTypeDeclaration(p); property.dataFormat = p.getFormat(); if (property.isEnum) { property.datatypeWithEnum = this.toEnumName(property); property.enumName = this.toEnumName(property); } else { property.datatypeWithEnum = property.datatype; } property.baseType = this.getSwaggerType(p); if (p != null && p instanceof properties_1.ArrayProperty) { property.isContainer = true; property.isListContainer = true; property.containerType = 'array'; property.baseType = this.getSwaggerType(p); const cp = this.fromProperty(property.name, p.getItems()); this.updatePropertyForArray(property, cp); } else if (p != null && p instanceof properties_1.MapProperty) { property.isContainer = true; property.isMapContainer = true; property.containerType = 'map'; property.baseType = this.getSwaggerType(p); const cp = this.fromProperty('inner', p.getAdditionalProperties()); this.updatePropertyForMap(property, cp); } else { this.setNonArrayMapProperty(property, type); } return property; } /** * Update property for array(list) container * @param property Codegen property * @param innerProperty Codegen inner property of map or list */ updatePropertyForArray(property, innerProperty) { if (innerProperty == null) { Log.warn('skipping invalid array property ' + Json_1.default.pretty(property)); } else { if (!this.__languageSpecificPrimitives.contains(innerProperty.baseType)) { property.complexType = innerProperty.baseType; } else { property.isPrimitiveType = true; property.baseType = innerProperty.baseType; } property.items = innerProperty; if (this.isPropertyInnerMostEnum(property)) { property.isEnum = true; this.updateDataTypeWithEnumForArray(property); property.allowableValues = this.getInnerEnumAllowableValues(property); } } } /** * Update property for map container * @param property Codegen property * @param innerProperty Codeg