mirror of
https://github.com/jlengrand/openapi-generator.git
synced 2026-05-16 00:21:19 +00:00
Merge pull request #2917 from Vrolijkx/feature/typescript_angular2_should_generate_correct_output
Feature/typescript angular2 should generate correct output
This commit is contained in:
@@ -1,62 +1,73 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import io.swagger.codegen.*;
|
||||
import io.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.FileProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
|
||||
protected String modelPropertyNaming= "camelCase";
|
||||
protected Boolean supportsES6 = true;
|
||||
|
||||
public AbstractTypeScriptClientCodegen() {
|
||||
super();
|
||||
supportsInheritance = true;
|
||||
setReservedWordsLowerCase(Arrays.asList(
|
||||
// local variable names used in API methods (endpoints)
|
||||
"varLocalPath", "queryParameters", "headerParams", "formParams", "useFormData", "varLocalDeferred",
|
||||
"requestOptions",
|
||||
// Typescript reserved words
|
||||
"abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
|
||||
public AbstractTypeScriptClientCodegen() {
|
||||
super();
|
||||
supportsInheritance = true;
|
||||
setReservedWordsLowerCase(Arrays.asList(
|
||||
// local variable names used in API methods (endpoints)
|
||||
"varLocalPath", "queryParameters", "headerParams", "formParams", "useFormData", "varLocalDeferred",
|
||||
"requestOptions",
|
||||
// Typescript reserved words
|
||||
"abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
|
||||
|
||||
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
|
||||
"string",
|
||||
"String",
|
||||
"boolean",
|
||||
"Boolean",
|
||||
"Double",
|
||||
"Integer",
|
||||
"Long",
|
||||
"Float",
|
||||
"Object",
|
||||
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
|
||||
"string",
|
||||
"String",
|
||||
"boolean",
|
||||
"Boolean",
|
||||
"Double",
|
||||
"Integer",
|
||||
"Long",
|
||||
"Float",
|
||||
"Object",
|
||||
"Array",
|
||||
"Date",
|
||||
"number",
|
||||
"any"
|
||||
));
|
||||
instantiationTypes.put("array", "Array");
|
||||
));
|
||||
instantiationTypes.put("array", "Array");
|
||||
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("Array", "Array");
|
||||
typeMapping.put("array", "Array");
|
||||
typeMapping.put("List", "Array");
|
||||
typeMapping.put("boolean", "boolean");
|
||||
typeMapping.put("string", "string");
|
||||
typeMapping.put("int", "number");
|
||||
typeMapping.put("float", "number");
|
||||
typeMapping.put("number", "number");
|
||||
typeMapping.put("long", "number");
|
||||
typeMapping.put("short", "number");
|
||||
typeMapping.put("char", "string");
|
||||
typeMapping.put("double", "number");
|
||||
typeMapping.put("object", "any");
|
||||
typeMapping.put("integer", "number");
|
||||
typeMapping.put("Map", "any");
|
||||
typeMapping.put("DateTime", "Date");
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("Array", "Array");
|
||||
typeMapping.put("array", "Array");
|
||||
typeMapping.put("List", "Array");
|
||||
typeMapping.put("boolean", "boolean");
|
||||
typeMapping.put("string", "string");
|
||||
typeMapping.put("int", "number");
|
||||
typeMapping.put("float", "number");
|
||||
typeMapping.put("number", "number");
|
||||
typeMapping.put("long", "number");
|
||||
typeMapping.put("short", "number");
|
||||
typeMapping.put("char", "string");
|
||||
typeMapping.put("double", "number");
|
||||
typeMapping.put("object", "any");
|
||||
typeMapping.put("integer", "number");
|
||||
typeMapping.put("Map", "any");
|
||||
typeMapping.put("DateTime", "Date");
|
||||
//TODO binary should be mapped to byte array
|
||||
// mapped to String as a workaround
|
||||
typeMapping.put("binary", "string");
|
||||
@@ -66,7 +77,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
|
||||
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SUPPORTS_ES6, CodegenConstants.SUPPORTS_ES6_DESC).defaultValue("false"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
@@ -104,24 +115,24 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
public String toParamName(String name) {
|
||||
// replace - with _ e.g. created-at => created_at
|
||||
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$"))
|
||||
return name;
|
||||
// if it's all uppper case, do nothing
|
||||
if (name.matches("^[A-Z_]*$"))
|
||||
return name;
|
||||
|
||||
// camelize the variable name
|
||||
// pet_id => petId
|
||||
name = camelize(name, true);
|
||||
// camelize the variable name
|
||||
// pet_id => petId
|
||||
name = camelize(name, true);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name) || name.matches("^\\d.*"))
|
||||
name = escapeReservedWord(name);
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name) || name.matches("^\\d.*"))
|
||||
name = escapeReservedWord(name);
|
||||
|
||||
return name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
@@ -130,70 +141,70 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String name) {
|
||||
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
public String toModelName(String name) {
|
||||
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
|
||||
|
||||
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||
name = modelNamePrefix + "_" + name;
|
||||
if (!StringUtils.isEmpty(modelNamePrefix)) {
|
||||
name = modelNamePrefix + "_" + name;
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||
name = name + "_" + modelNameSuffix;
|
||||
}
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(name)) {
|
||||
String modelName = camelize("model_" + name);
|
||||
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||
return modelName;
|
||||
}
|
||||
|
||||
// model name starts with number
|
||||
if (name.matches("^\\d.*")) {
|
||||
String modelName = camelize("model_" + name); // e.g. 200Response => Model200Response (after camelize)
|
||||
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
|
||||
return modelName;
|
||||
}
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(modelNameSuffix)) {
|
||||
name = name + "_" + modelNameSuffix;
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
// should be the same as the model name
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
return "{ [key: string]: "+ getTypeDeclaration(inner) + "; }";
|
||||
} else if (p instanceof FileProperty) {
|
||||
return "any";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
// model name cannot use reserved keyword, e.g. return
|
||||
if (isReservedWord(name)) {
|
||||
String modelName = camelize("model_" + name);
|
||||
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||
return modelName;
|
||||
}
|
||||
|
||||
// model name starts with number
|
||||
if (name.matches("^\\d.*")) {
|
||||
String modelName = camelize("model_" + name); // e.g. 200Response => Model200Response (after camelize)
|
||||
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
|
||||
return modelName;
|
||||
}
|
||||
|
||||
// camelize the model name
|
||||
// phone_number => PhoneNumber
|
||||
return camelize(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
// should be the same as the model name
|
||||
return toModelName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(Property p) {
|
||||
if (p instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) p;
|
||||
Property inner = ap.getItems();
|
||||
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (p instanceof MapProperty) {
|
||||
MapProperty mp = (MapProperty) p;
|
||||
Property inner = mp.getAdditionalProperties();
|
||||
return "{ [key: string]: "+ getTypeDeclaration(inner) + "; }";
|
||||
} else if (p instanceof FileProperty) {
|
||||
return "any";
|
||||
}
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type))
|
||||
return type;
|
||||
} else
|
||||
type = swaggerType;
|
||||
return toModelName(type);
|
||||
}
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type))
|
||||
return type;
|
||||
} else
|
||||
type = swaggerType;
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
@@ -217,8 +228,8 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
|
||||
this.modelPropertyNaming = naming;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
naming + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
naming + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,9 +243,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
|
||||
case camelCase: return camelize(name, true);
|
||||
case PascalCase: return camelize(name);
|
||||
case snake_case: return underscore(name);
|
||||
default: throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
name + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
default: throw new IllegalArgumentException("Invalid model property naming '" +
|
||||
name + "'. Must be 'original', 'camelCase', " +
|
||||
"'PascalCase' or 'snake_case'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.BooleanProperty;
|
||||
import io.swagger.models.properties.FileProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.ObjectProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCodegen {
|
||||
@@ -114,14 +115,19 @@ public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCod
|
||||
MapProperty mp = (MapProperty)p;
|
||||
inner = mp.getAdditionalProperties();
|
||||
return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }";
|
||||
} else if(p instanceof FileProperty || p instanceof ObjectProperty) {
|
||||
return "any";
|
||||
} else {
|
||||
return p instanceof FileProperty ? "any" : super.getTypeDeclaration(p);
|
||||
return super.getTypeDeclaration(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwaggerType(Property p) {
|
||||
String swaggerType = super.getSwaggerType(p);
|
||||
if(languageSpecificPrimitives.contains(swaggerType)) {
|
||||
return swaggerType;
|
||||
}
|
||||
return addModelPrefix(swaggerType);
|
||||
}
|
||||
|
||||
@@ -129,13 +135,25 @@ public class TypeScriptAngular2ClientCodegen extends AbstractTypeScriptClientCod
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(swaggerType)) {
|
||||
type = typeMapping.get(swaggerType);
|
||||
if (languageSpecificPrimitives.contains(type))
|
||||
return type;
|
||||
} else
|
||||
} else {
|
||||
type = swaggerType;
|
||||
}
|
||||
|
||||
if (!startsWithLanguageSpecificPrimitiv(type)) {
|
||||
type = "models." + swaggerType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private boolean startsWithLanguageSpecificPrimitiv(String type) {
|
||||
for (String langPrimitive:languageSpecificPrimitives) {
|
||||
if (type.startsWith(langPrimitive)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessParameter(CodegenParameter parameter) {
|
||||
super.postProcessParameter(parameter);
|
||||
|
||||
Reference in New Issue
Block a user