Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,62 +1,73 @@
package io.swagger.codegen.languages;

import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.io.File;

import org.apache.commons.lang3.StringUtils;
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"));

languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"string",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object",
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",
"Array",
"Date",
"number",
"any"
));
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");
));
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");
//TODO binary should be mapped to byte array
// mapped to String as a workaround
typeMapping.put("binary", "string");
Expand All @@ -66,7 +77,7 @@ public AbstractTypeScriptClientCodegen() {
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() {
Expand Down Expand Up @@ -104,24 +115,24 @@ public String modelFileFolder() {
}

@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) {
Expand All @@ -130,70 +141,70 @@ public String toVarName(String name) {
}

@Override
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(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
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(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);
}

// 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;
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}

// 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;
@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);
}

// 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) {
Expand All @@ -217,8 +228,8 @@ public void setModelPropertyNaming(String naming) {
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'");
}
}

Expand All @@ -232,9 +243,9 @@ public String getNameUsingModelPropertyNaming(String name) {
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'");
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
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 {
Expand Down Expand Up @@ -114,28 +115,45 @@ public String getTypeDeclaration(Property p) {
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);
}

private String addModelPrefix(String swaggerType) {
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);
Expand Down
Loading