forked from loafle/openapi-generator-original
Fix, tests for Issue #2258 "[JavaScript] Generator options and template improvements"
This commit is contained in:
@@ -6,20 +6,35 @@ import java.util.*;
|
||||
|
||||
public class CodegenModel {
|
||||
public String parent, parentSchema;
|
||||
public List<String> interfaces;
|
||||
|
||||
// References to parent and interface CodegenModels. Only set when code generator supports inheritance.
|
||||
public CodegenModel parentModel;
|
||||
public List<CodegenModel> interfaceModels;
|
||||
|
||||
public String name, classname, description, classVarName, modelJson, dataType;
|
||||
public String classFilename; // store the class file name, mainly used for import
|
||||
public String unescapedDescription;
|
||||
public String discriminator;
|
||||
public String defaultValue;
|
||||
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
|
||||
public List<CodegenProperty> allVars;
|
||||
public List<String> allowableValues;
|
||||
|
||||
// list of all required parameters
|
||||
public Set<String> mandatory = new HashSet<String>();
|
||||
|
||||
// Sorted sets of required parameters.
|
||||
public Set<String> mandatory = new TreeSet<String>();
|
||||
public Set<String> allMandatory;
|
||||
|
||||
public Set<String> imports = new TreeSet<String>();
|
||||
public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum;
|
||||
public ExternalDocs externalDocs;
|
||||
|
||||
public Map<String, Object> vendorExtensions;
|
||||
|
||||
{
|
||||
// By default these are the same collections. Where the code generator supports inheritance, composed models
|
||||
// store the complete closure of owned and inherited properties in allVars and allMandatory.
|
||||
allVars = vars;
|
||||
allMandatory = mandatory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +45,12 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -124,8 +127,36 @@ public class DefaultCodegen {
|
||||
}
|
||||
|
||||
// override with any special post-processing for all models
|
||||
@SuppressWarnings("static-method")
|
||||
@SuppressWarnings({ "static-method", "unchecked" })
|
||||
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
|
||||
if (supportsInheritance) {
|
||||
// Index all CodegenModels by name.
|
||||
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
|
||||
for (Entry<String, Object> entry : objs.entrySet()) {
|
||||
String modelName = entry.getKey();
|
||||
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
|
||||
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
|
||||
for (Map<String, Object> mo : models) {
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
allModels.put(modelName, cm);
|
||||
}
|
||||
}
|
||||
// Fix up all parent and interface CodegenModel references.
|
||||
for (CodegenModel cm : allModels.values()) {
|
||||
if (cm.parent != null) {
|
||||
cm.parentModel = allModels.get(cm.parent);
|
||||
}
|
||||
if (cm.interfaces != null && !cm.interfaces.isEmpty()) {
|
||||
cm.interfaceModels = new ArrayList<CodegenModel>(cm.interfaces.size());
|
||||
for (String intf : cm.interfaces) {
|
||||
CodegenModel intfModel = allModels.get(intf);
|
||||
if (intfModel != null) {
|
||||
cm.interfaceModels.add(intfModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
@@ -945,8 +976,18 @@ public class DefaultCodegen {
|
||||
// TODO
|
||||
} else if (model instanceof ComposedModel) {
|
||||
final ComposedModel composed = (ComposedModel) model;
|
||||
Map<String, Property> properties = new HashMap<String, Property>();
|
||||
Map<String, Property> properties = new LinkedHashMap<String, Property>();
|
||||
List<String> required = new ArrayList<String>();
|
||||
Map<String, Property> allProperties;
|
||||
List<String> allRequired;
|
||||
if (supportsInheritance) {
|
||||
allProperties = new LinkedHashMap<String, Property>();
|
||||
allRequired = new ArrayList<String>();
|
||||
m.allVars = new ArrayList<CodegenProperty>();
|
||||
} else {
|
||||
allProperties = null;
|
||||
allRequired = null;
|
||||
}
|
||||
// parent model
|
||||
final RefModel parent = (RefModel) composed.getParent();
|
||||
if (parent != null) {
|
||||
@@ -954,31 +995,29 @@ public class DefaultCodegen {
|
||||
m.parentSchema = parentRef;
|
||||
m.parent = toModelName(parent.getSimpleRef());
|
||||
addImport(m, m.parent);
|
||||
if (!supportsInheritance && allDefinitions != null) {
|
||||
if (allDefinitions != null) {
|
||||
final Model parentModel = allDefinitions.get(m.parentSchema);
|
||||
if (parentModel instanceof ModelImpl) {
|
||||
final ModelImpl _parent = (ModelImpl) parentModel;
|
||||
if (_parent.getProperties() != null) {
|
||||
properties.putAll(_parent.getProperties());
|
||||
}
|
||||
if (_parent.getRequired() != null) {
|
||||
required.addAll(_parent.getRequired());
|
||||
}
|
||||
if (supportsInheritance) {
|
||||
addProperties(allProperties, allRequired, parentModel, allDefinitions);
|
||||
} else {
|
||||
addProperties(properties, required, parentModel, allDefinitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
// interfaces (intermediate models)
|
||||
if (allDefinitions != null && composed.getInterfaces() != null) {
|
||||
if (composed.getInterfaces() != null) {
|
||||
if (m.interfaces == null)
|
||||
m.interfaces = new ArrayList<String>();
|
||||
for (RefModel _interface : composed.getInterfaces()) {
|
||||
final String interfaceRef = toModelName(_interface.getSimpleRef());
|
||||
final Model interfaceModel = allDefinitions.get(interfaceRef);
|
||||
if (interfaceModel instanceof ModelImpl) {
|
||||
final ModelImpl _interfaceModel = (ModelImpl) interfaceModel;
|
||||
if (_interfaceModel.getProperties() != null) {
|
||||
properties.putAll(_interfaceModel.getProperties());
|
||||
}
|
||||
if (_interfaceModel.getRequired() != null) {
|
||||
required.addAll(_interfaceModel.getRequired());
|
||||
m.interfaces.add(interfaceRef);
|
||||
addImport(m, interfaceRef);
|
||||
if (allDefinitions != null) {
|
||||
final Model interfaceModel = allDefinitions.get(interfaceRef);
|
||||
if (supportsInheritance) {
|
||||
addProperties(allProperties, allRequired, interfaceModel, allDefinitions);
|
||||
} else {
|
||||
addProperties(properties, required, interfaceModel, allDefinitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -990,15 +1029,12 @@ public class DefaultCodegen {
|
||||
child = allDefinitions.get(childRef);
|
||||
}
|
||||
if (child != null && child instanceof ModelImpl) {
|
||||
final ModelImpl _child = (ModelImpl) child;
|
||||
if (_child.getProperties() != null) {
|
||||
properties.putAll(_child.getProperties());
|
||||
}
|
||||
if (_child.getRequired() != null) {
|
||||
required.addAll(_child.getRequired());
|
||||
addProperties(properties, required, child, allDefinitions);
|
||||
if (supportsInheritance) {
|
||||
addProperties(allProperties, allRequired, child, allDefinitions);
|
||||
}
|
||||
}
|
||||
addVars(m, properties, required);
|
||||
addVars(m, properties, required, allProperties, allRequired);
|
||||
} else {
|
||||
ModelImpl impl = (ModelImpl) model;
|
||||
if(impl.getEnum() != null && impl.getEnum().size() > 0) {
|
||||
@@ -1014,7 +1050,7 @@ public class DefaultCodegen {
|
||||
addVars(m, impl.getProperties(), impl.getRequired());
|
||||
}
|
||||
|
||||
if(m.vars != null) {
|
||||
if (m.vars != null) {
|
||||
for(CodegenProperty prop : m.vars) {
|
||||
postProcessModelProperty(m, prop);
|
||||
}
|
||||
@@ -1022,6 +1058,28 @@ public class DefaultCodegen {
|
||||
return m;
|
||||
}
|
||||
|
||||
protected void addProperties(Map<String, Property> properties, List<String> required, Model model,
|
||||
Map<String, Model> allDefinitions) {
|
||||
|
||||
if (model instanceof ModelImpl) {
|
||||
ModelImpl mi = (ModelImpl) model;
|
||||
if (mi.getProperties() != null) {
|
||||
properties.putAll(mi.getProperties());
|
||||
}
|
||||
if (mi.getRequired() != null) {
|
||||
required.addAll(mi.getRequired());
|
||||
}
|
||||
} else if (model instanceof RefModel) {
|
||||
String interfaceRef = toModelName(((RefModel) model).getSimpleRef());
|
||||
Model interfaceModel = allDefinitions.get(interfaceRef);
|
||||
addProperties(properties, required, interfaceModel, allDefinitions);
|
||||
} else if (model instanceof ComposedModel) {
|
||||
for (Model component :((ComposedModel) model).getAllOf()) {
|
||||
addProperties(properties, required, component, allDefinitions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Camelize the method name of the getter and setter
|
||||
*
|
||||
@@ -1263,6 +1321,7 @@ public class DefaultCodegen {
|
||||
property.containerType = "map";
|
||||
MapProperty ap = (MapProperty) p;
|
||||
CodegenProperty cp = fromProperty("inner", ap.getAdditionalProperties());
|
||||
property.items = cp;
|
||||
|
||||
property.baseType = getSwaggerType(p);
|
||||
if (!languageSpecificPrimitives.contains(cp.baseType)) {
|
||||
@@ -2157,45 +2216,65 @@ public class DefaultCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void addVars(CodegenModel m, Map<String, Property> properties, Collection<String> required) {
|
||||
if (properties != null && properties.size() > 0) {
|
||||
private void addVars(CodegenModel m, Map<String, Property> properties, List<String> required) {
|
||||
addVars(m, properties, required, null, null);
|
||||
}
|
||||
|
||||
private void addVars(CodegenModel m, Map<String, Property> properties, List<String> required,
|
||||
Map<String, Property> allProperties, List<String> allRequired) {
|
||||
|
||||
if (properties != null && !properties.isEmpty()) {
|
||||
m.hasVars = true;
|
||||
m.hasEnums = false;
|
||||
final int totalCount = properties.size();
|
||||
final Set<String> mandatory = required == null ? Collections.<String>emptySet() : new HashSet<String>(required);
|
||||
int count = 0;
|
||||
for (Map.Entry<String, Property> entry : properties.entrySet()) {
|
||||
final String key = entry.getKey();
|
||||
final Property prop = entry.getValue();
|
||||
|
||||
if (prop == null) {
|
||||
LOGGER.warn("null property for " + key);
|
||||
} else {
|
||||
final CodegenProperty cp = fromProperty(key, prop);
|
||||
cp.required = mandatory.contains(key) ? true : null;
|
||||
if (cp.isEnum) {
|
||||
m.hasEnums = true;
|
||||
}
|
||||
count += 1;
|
||||
if (count != totalCount) {
|
||||
cp.hasMore = true;
|
||||
}
|
||||
if (cp.isContainer != null) {
|
||||
addImport(m, typeMapping.get("array"));
|
||||
}
|
||||
addImport(m, cp.baseType);
|
||||
addImport(m, cp.complexType);
|
||||
m.vars.add(cp);
|
||||
}
|
||||
}
|
||||
|
||||
m.mandatory = mandatory;
|
||||
|
||||
Set<String> mandatory = required == null ? Collections.<String> emptySet()
|
||||
: new TreeSet<String>(required);
|
||||
addVars(m, m.vars, properties, mandatory);
|
||||
m.allMandatory = m.mandatory = mandatory;
|
||||
} else {
|
||||
m.emptyVars = true;
|
||||
m.hasVars = false;
|
||||
m.hasEnums = false;
|
||||
}
|
||||
|
||||
if (allProperties != null) {
|
||||
Set<String> allMandatory = allRequired == null ? Collections.<String> emptySet()
|
||||
: new TreeSet<String>(allRequired);
|
||||
addVars(m, m.allVars, allProperties, allMandatory);
|
||||
m.allMandatory = allMandatory;
|
||||
}
|
||||
}
|
||||
|
||||
private void addVars(CodegenModel m, List<CodegenProperty> vars, Map<String, Property> properties, Set<String> mandatory) {
|
||||
final int totalCount = properties.size();
|
||||
int count = 0;
|
||||
for (Map.Entry<String, Property> entry : properties.entrySet()) {
|
||||
final String key = entry.getKey();
|
||||
final Property prop = entry.getValue();
|
||||
|
||||
if (prop == null) {
|
||||
LOGGER.warn("null property for " + key);
|
||||
} else {
|
||||
final CodegenProperty cp = fromProperty(key, prop);
|
||||
cp.required = mandatory.contains(key) ? true : null;
|
||||
if (cp.isEnum) {
|
||||
// FIXME: if supporting inheritance, when called a second time for allProperties it is possible for
|
||||
// m.hasEnums to be set incorrectly if allProperties has enumerations but properties does not.
|
||||
m.hasEnums = true;
|
||||
}
|
||||
count++;
|
||||
if (count != totalCount) {
|
||||
cp.hasMore = true;
|
||||
}
|
||||
if (cp.isContainer != null) {
|
||||
addImport(m, typeMapping.get("array"));
|
||||
}
|
||||
addImport(m, cp.baseType);
|
||||
addImport(m, cp.complexType);
|
||||
vars.add(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,23 +47,27 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
@SuppressWarnings("hiding")
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JavascriptClientCodegen.class);
|
||||
|
||||
private static final String PROJECT_NAME = "projectName";
|
||||
private static final String MODULE_NAME = "moduleName";
|
||||
private static final String PROJECT_DESCRIPTION = "projectDescription";
|
||||
private static final String PROJECT_VERSION = "projectVersion";
|
||||
private static final String PROJECT_LICENSE_NAME = "projectLicenseName";
|
||||
private static final String USE_PROMISES = "usePromises";
|
||||
private static final String OMIT_MODEL_METHODS = "omitModelMethods";
|
||||
public static final String PROJECT_NAME = "projectName";
|
||||
public static final String MODULE_NAME = "moduleName";
|
||||
public static final String PROJECT_DESCRIPTION = "projectDescription";
|
||||
public static final String PROJECT_VERSION = "projectVersion";
|
||||
public static final String PROJECT_LICENSE_NAME = "projectLicenseName";
|
||||
public static final String USE_PROMISES = "usePromises";
|
||||
public static final String USE_INHERITANCE = "useInheritance";
|
||||
public static final String EMIT_MODEL_METHODS = "emitModelMethods";
|
||||
public static final String EMIT_JS_DOC = "emitJSDoc";
|
||||
|
||||
protected String projectName;
|
||||
protected String moduleName;
|
||||
protected String projectDescription;
|
||||
protected String projectVersion;
|
||||
protected String projectLicenseName;
|
||||
|
||||
protected String sourceFolder = "src";
|
||||
protected String localVariablePrefix = "";
|
||||
protected boolean usePromises = false;
|
||||
protected boolean omitModelMethods = false;
|
||||
protected boolean usePromises;
|
||||
protected boolean emitModelMethods;
|
||||
protected boolean emitJSDoc = true;
|
||||
protected String apiDocPath = "docs/";
|
||||
protected String modelDocPath = "docs/";
|
||||
|
||||
@@ -105,8 +109,36 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
);
|
||||
defaultIncludes = new HashSet<String>(languageSpecificPrimitives);
|
||||
|
||||
instantiationTypes.put("array", "Array");
|
||||
instantiationTypes.put("list", "Array");
|
||||
instantiationTypes.put("map", "Object");
|
||||
typeMapping.clear();
|
||||
typeMapping.put("array", "Array");
|
||||
typeMapping.put("map", "Object");
|
||||
typeMapping.put("List", "Array");
|
||||
typeMapping.put("boolean", "Boolean");
|
||||
typeMapping.put("string", "String");
|
||||
typeMapping.put("int", "Integer"); // Huh? What is JS Integer?
|
||||
typeMapping.put("float", "Number");
|
||||
typeMapping.put("number", "Number");
|
||||
typeMapping.put("DateTime", "Date"); // Should this be dateTime?
|
||||
typeMapping.put("Date", "Date"); // Should this be date?
|
||||
typeMapping.put("long", "Integer");
|
||||
typeMapping.put("short", "Integer");
|
||||
typeMapping.put("char", "String");
|
||||
typeMapping.put("double", "Number");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("integer", "Integer");
|
||||
// binary not supported in JavaScript client right now, using String as a workaround
|
||||
typeMapping.put("ByteArray", "String"); // I don't see ByteArray defined in the Swagger docs.
|
||||
typeMapping.put("binary", "String");
|
||||
|
||||
importMapping.clear();
|
||||
|
||||
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC).defaultValue("src"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.LOCAL_VARIABLE_PREFIX, CodegenConstants.LOCAL_VARIABLE_PREFIX_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
|
||||
cliOptions.add(new CliOption(PROJECT_NAME,
|
||||
"name of the project (Default: generated from info.title or \"swagger-js-client\")"));
|
||||
cliOptions.add(new CliOption(MODULE_NAME,
|
||||
@@ -120,9 +152,15 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
cliOptions.add(new CliOption(USE_PROMISES,
|
||||
"use Promises as return values from the client API, instead of superagent callbacks")
|
||||
.defaultValue(Boolean.FALSE.toString()));
|
||||
cliOptions.add(new CliOption(OMIT_MODEL_METHODS,
|
||||
"omits generation of getters and setters for model classes")
|
||||
cliOptions.add(new CliOption(EMIT_MODEL_METHODS,
|
||||
"generate getters and setters for model properties")
|
||||
.defaultValue(Boolean.FALSE.toString()));
|
||||
cliOptions.add(new CliOption(EMIT_JS_DOC,
|
||||
"generate JSDoc comments")
|
||||
.defaultValue(Boolean.TRUE.toString()));
|
||||
cliOptions.add(new CliOption(USE_INHERITANCE,
|
||||
"use JavaScript prototype chains & delegation for inheritance")
|
||||
.defaultValue(Boolean.TRUE.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,59 +182,47 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
typeMapping = new HashMap<String, String>();
|
||||
typeMapping.put("array", "Array");
|
||||
typeMapping.put("List", "Array");
|
||||
typeMapping.put("map", "Object");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("boolean", "Boolean");
|
||||
typeMapping.put("char", "String");
|
||||
typeMapping.put("string", "String");
|
||||
typeMapping.put("short", "Integer");
|
||||
typeMapping.put("int", "Integer");
|
||||
typeMapping.put("integer", "Integer");
|
||||
typeMapping.put("long", "Integer");
|
||||
typeMapping.put("float", "Number");
|
||||
typeMapping.put("double", "Number");
|
||||
typeMapping.put("number", "Number");
|
||||
typeMapping.put("DateTime", "Date");
|
||||
typeMapping.put("Date", "Date");
|
||||
typeMapping.put("file", "File");
|
||||
// binary not supported in JavaScript client right now, using String as a workaround
|
||||
typeMapping.put("binary", "String");
|
||||
|
||||
importMapping.clear();
|
||||
if (additionalProperties.containsKey(PROJECT_NAME)) {
|
||||
setProjectName(((String) additionalProperties.get(PROJECT_NAME)));
|
||||
}
|
||||
if (additionalProperties.containsKey(MODULE_NAME)) {
|
||||
setModuleName(((String) additionalProperties.get(MODULE_NAME)));
|
||||
}
|
||||
if (additionalProperties.containsKey(PROJECT_DESCRIPTION)) {
|
||||
setProjectDescription(((String) additionalProperties.get(PROJECT_DESCRIPTION)));
|
||||
}
|
||||
if (additionalProperties.containsKey(PROJECT_VERSION)) {
|
||||
setProjectVersion(((String) additionalProperties.get(PROJECT_VERSION)));
|
||||
}
|
||||
if (additionalProperties.containsKey(PROJECT_LICENSE_NAME)) {
|
||||
setProjectLicenseName(((String) additionalProperties.get(PROJECT_LICENSE_NAME)));
|
||||
}
|
||||
if (additionalProperties.containsKey(CodegenConstants.LOCAL_VARIABLE_PREFIX)) {
|
||||
setLocalVariablePrefix((String) additionalProperties.get(CodegenConstants.LOCAL_VARIABLE_PREFIX));
|
||||
}
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||
}
|
||||
if (additionalProperties.containsKey(USE_PROMISES)) {
|
||||
setUsePromises(Boolean.parseBoolean((String)additionalProperties.get(USE_PROMISES)));
|
||||
}
|
||||
if (additionalProperties.containsKey(USE_INHERITANCE)) {
|
||||
setUseInheritance(Boolean.parseBoolean((String)additionalProperties.get(USE_INHERITANCE)));
|
||||
} else {
|
||||
supportsInheritance = true;
|
||||
}
|
||||
if (additionalProperties.containsKey(EMIT_MODEL_METHODS)) {
|
||||
setEmitModelMethods(Boolean.parseBoolean((String)additionalProperties.get(EMIT_MODEL_METHODS)));
|
||||
}
|
||||
if (additionalProperties.containsKey(EMIT_JS_DOC)) {
|
||||
setEmitJSDoc(Boolean.parseBoolean((String)additionalProperties.get(EMIT_JS_DOC)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preprocessSwagger(Swagger swagger) {
|
||||
super.preprocessSwagger(swagger);
|
||||
|
||||
if (additionalProperties.containsKey(PROJECT_NAME)) {
|
||||
projectName = ((String) additionalProperties.get(PROJECT_NAME));
|
||||
}
|
||||
if (additionalProperties.containsKey(MODULE_NAME)) {
|
||||
moduleName = ((String) additionalProperties.get(MODULE_NAME));
|
||||
}
|
||||
if (additionalProperties.containsKey(PROJECT_DESCRIPTION)) {
|
||||
projectDescription = ((String) additionalProperties.get(PROJECT_DESCRIPTION));
|
||||
}
|
||||
if (additionalProperties.containsKey(PROJECT_VERSION)) {
|
||||
projectVersion = ((String) additionalProperties.get(PROJECT_VERSION));
|
||||
}
|
||||
if (additionalProperties.containsKey(CodegenConstants.LOCAL_VARIABLE_PREFIX)) {
|
||||
localVariablePrefix = (String) additionalProperties.get(CodegenConstants.LOCAL_VARIABLE_PREFIX);
|
||||
}
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
sourceFolder = (String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER);
|
||||
}
|
||||
if (additionalProperties.containsKey(USE_PROMISES)) {
|
||||
usePromises = Boolean.parseBoolean((String)additionalProperties.get(USE_PROMISES));
|
||||
}
|
||||
if (additionalProperties.containsKey(OMIT_MODEL_METHODS)) {
|
||||
omitModelMethods = Boolean.parseBoolean((String)additionalProperties.get(OMIT_MODEL_METHODS));
|
||||
}
|
||||
|
||||
if (swagger.getInfo() != null) {
|
||||
Info info = swagger.getInfo();
|
||||
if (StringUtils.isBlank(projectName) && info.getTitle() != null) {
|
||||
@@ -211,9 +237,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
// when projectDescription is not specified, use info.description
|
||||
projectDescription = info.getDescription();
|
||||
}
|
||||
if (info.getLicense() != null) {
|
||||
License license = info.getLicense();
|
||||
if (additionalProperties.get(PROJECT_LICENSE_NAME) == null) {
|
||||
if (additionalProperties.get(PROJECT_LICENSE_NAME) == null) {
|
||||
// when projectLicense is not specified, use info.license
|
||||
if (info.getLicense() != null) {
|
||||
License license = info.getLicense();
|
||||
additionalProperties.put(PROJECT_LICENSE_NAME, license.getName());
|
||||
}
|
||||
}
|
||||
@@ -237,10 +264,14 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
additionalProperties.put(MODULE_NAME, moduleName);
|
||||
additionalProperties.put(PROJECT_DESCRIPTION, escapeText(projectDescription));
|
||||
additionalProperties.put(PROJECT_VERSION, projectVersion);
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
additionalProperties.put(CodegenConstants.LOCAL_VARIABLE_PREFIX, localVariablePrefix);
|
||||
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
additionalProperties.put(CodegenConstants.SOURCE_FOLDER, sourceFolder);
|
||||
additionalProperties.put(USE_PROMISES, usePromises);
|
||||
additionalProperties.put(OMIT_MODEL_METHODS, omitModelMethods);
|
||||
additionalProperties.put(USE_INHERITANCE, supportsInheritance);
|
||||
additionalProperties.put(EMIT_MODEL_METHODS, emitModelMethods);
|
||||
additionalProperties.put(EMIT_JS_DOC, emitJSDoc);
|
||||
|
||||
// make api and model doc path available in mustache template
|
||||
additionalProperties.put("apiDocPath", apiDocPath);
|
||||
@@ -260,12 +291,56 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
|
||||
return outputFolder + '/' + sourceFolder + '/' + apiPackage().replace('.', '/');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
|
||||
return outputFolder + '/' + sourceFolder + '/' + modelPackage().replace('.', '/');
|
||||
}
|
||||
|
||||
public void setSourceFolder(String sourceFolder) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public void setLocalVariablePrefix(String localVariablePrefix) {
|
||||
this.localVariablePrefix = localVariablePrefix;
|
||||
}
|
||||
|
||||
public void setModuleName(String moduleName) {
|
||||
this.moduleName = moduleName;
|
||||
}
|
||||
|
||||
public void setProjectDescription(String projectDescription) {
|
||||
this.projectDescription = projectDescription;
|
||||
}
|
||||
|
||||
public void setProjectVersion(String projectVersion) {
|
||||
this.projectVersion = projectVersion;
|
||||
}
|
||||
|
||||
public void setProjectLicenseName(String projectLicenseName) {
|
||||
this.projectLicenseName = projectLicenseName;
|
||||
}
|
||||
|
||||
public void setUsePromises(boolean usePromises) {
|
||||
this.usePromises = usePromises;
|
||||
}
|
||||
|
||||
public void setUseInheritance(boolean useInheritance) {
|
||||
this.supportsInheritance = useInheritance;
|
||||
}
|
||||
|
||||
public void setEmitModelMethods(boolean emitModelMethods) {
|
||||
this.emitModelMethods = emitModelMethods;
|
||||
}
|
||||
|
||||
public void setEmitJSDoc(boolean emitJSDoc) {
|
||||
this.emitJSDoc = emitJSDoc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -607,6 +682,92 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
private String trimBrackets(String s) {
|
||||
if (s != null) {
|
||||
int beginIdx = s.charAt(0) == '[' ? 1 : 0;
|
||||
int endIdx = s.length();
|
||||
if (s.charAt(endIdx - 1) == ']')
|
||||
endIdx--;
|
||||
return s.substring(beginIdx, endIdx);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getModelledType(String dataType) {
|
||||
return "module:" + (StringUtils.isEmpty(modelPackage) ? "" : (modelPackage + "/")) + dataType;
|
||||
}
|
||||
|
||||
private String getJSDocTypeWithBraces(CodegenModel cm, CodegenProperty cp) {
|
||||
return "{" + getJSDocType(cm, cp) + "}";
|
||||
}
|
||||
|
||||
private String getJSDocType(CodegenModel cm, CodegenProperty cp) {
|
||||
if (Boolean.TRUE.equals(cp.isContainer)) {
|
||||
if (cp.containerType.equals("array"))
|
||||
return "Array.<" + getJSDocType(cm, cp.items) + ">";
|
||||
else if (cp.containerType.equals("map"))
|
||||
return "Object.<String, " + getJSDocType(cm, cp.items) + ">";
|
||||
}
|
||||
String dataType = trimBrackets(cp.datatypeWithEnum);
|
||||
if (cp.isEnum) {
|
||||
dataType = cm.classname + '.' + dataType;
|
||||
}
|
||||
if (isModelledType(cp))
|
||||
dataType = getModelledType(dataType);
|
||||
return dataType;
|
||||
}
|
||||
|
||||
private boolean isModelledType(CodegenProperty cp) {
|
||||
// N.B. enums count as modelled types, file is not modelled (SuperAgent uses some 3rd party library).
|
||||
return cp.isEnum || !languageSpecificPrimitives.contains(cp.baseType == null ? cp.datatype : cp.baseType);
|
||||
}
|
||||
|
||||
private String getJSDocTypeWithBraces(CodegenParameter cp) {
|
||||
return "{" + getJSDocType(cp) + "}";
|
||||
}
|
||||
|
||||
private String getJSDocType(CodegenParameter cp) {
|
||||
String dataType = trimBrackets(cp.dataType);
|
||||
if (isModelledType(cp))
|
||||
dataType = getModelledType(dataType);
|
||||
if (Boolean.TRUE.equals(cp.isListContainer)) {
|
||||
return "Array.<" + dataType + ">";
|
||||
} else if (Boolean.TRUE.equals(cp.isMapContainer)) {
|
||||
return "Object.<String, " + dataType + ">";
|
||||
}
|
||||
return dataType;
|
||||
}
|
||||
|
||||
private boolean isModelledType(CodegenParameter cp) {
|
||||
// N.B. enums count as modelled types, file is not modelled (SuperAgent uses some 3rd party library).
|
||||
return cp.isEnum || !languageSpecificPrimitives.contains(cp.baseType == null ? cp.dataType : cp.baseType);
|
||||
}
|
||||
|
||||
private String getJSDocTypeWithBraces(CodegenOperation co) {
|
||||
String jsDocType = getJSDocType(co);
|
||||
return jsDocType == null ? null : "{" + jsDocType + "}";
|
||||
}
|
||||
|
||||
private String getJSDocType(CodegenOperation co) {
|
||||
String returnType = trimBrackets(co.returnType);
|
||||
if (returnType != null) {
|
||||
if (isModelledType(co))
|
||||
returnType = getModelledType(returnType);
|
||||
if (Boolean.TRUE.equals(co.isListContainer)) {
|
||||
return "Array.<" + returnType + ">";
|
||||
} else if (Boolean.TRUE.equals(co.isMapContainer)) {
|
||||
return "Object.<String, " + returnType + ">";
|
||||
}
|
||||
}
|
||||
return returnType;
|
||||
}
|
||||
|
||||
private boolean isModelledType(CodegenOperation co) {
|
||||
// This seems to be the only way to tell whether an operation return type is modelled.
|
||||
return !Boolean.TRUE.equals(co.returnTypeIsPrimitive);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
// Generate and store argument list string of each operation into
|
||||
@@ -615,7 +776,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
if (operations != null) {
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation operation : ops) {
|
||||
List<String> argList = new ArrayList();
|
||||
List<String> argList = new ArrayList<String>();
|
||||
boolean hasOptionalParams = false;
|
||||
for (CodegenParameter p : operation.allParams) {
|
||||
if (p.required != null && p.required) {
|
||||
@@ -631,20 +792,46 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
argList.add("callback");
|
||||
}
|
||||
operation.vendorExtensions.put("x-codegen-argList", StringUtils.join(argList, ", "));
|
||||
|
||||
// Store JSDoc type specification into vendor-extension: x-jsdoc-type.
|
||||
for (CodegenParameter cp : operation.allParams) {
|
||||
String jsdocType = getJSDocTypeWithBraces(cp);
|
||||
cp.vendorExtensions.put("x-jsdoc-type", jsdocType);
|
||||
}
|
||||
String jsdocType = getJSDocTypeWithBraces(operation);
|
||||
operation.vendorExtensions.put("x-jsdoc-type", jsdocType);
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
|
||||
// Collect each model's required property names in *document order*.
|
||||
// NOTE: can't use 'mandatory' as it is built from ModelImpl.getRequired(), which sorts names
|
||||
// alphabetically and in any case the document order of 'required' and 'properties' can differ.
|
||||
List<String> required = new ArrayList<String>();
|
||||
List<String> allRequired = supportsInheritance ? new ArrayList<String>() : required;
|
||||
cm.vendorExtensions.put("x-required", required);
|
||||
cm.vendorExtensions.put("x-all-required", allRequired);
|
||||
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
Map<String, Object> allowableValues = var.allowableValues;
|
||||
|
||||
// Add JSDoc @type value for this property.
|
||||
String jsDocType = getJSDocTypeWithBraces(cm, var);
|
||||
var.vendorExtensions.put("x-jsdoc-type", jsDocType);
|
||||
|
||||
if (Boolean.TRUE.equals(var.required)) {
|
||||
required.add(var.name);
|
||||
}
|
||||
|
||||
// handle ArrayProperty
|
||||
if (var.items != null) {
|
||||
allowableValues = var.items.allowableValues;
|
||||
@@ -679,6 +866,15 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
|
||||
}
|
||||
allowableValues.put("enumVars", enumVars);
|
||||
}
|
||||
|
||||
if (supportsInheritance) {
|
||||
for (CodegenProperty var : cm.allVars) {
|
||||
if (Boolean.TRUE.equals(var.required)) {
|
||||
allRequired.add(var.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set vendor-extension: x-codegen-hasMoreRequired
|
||||
CodegenProperty lastRequired = null;
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
|
||||
Reference in New Issue
Block a user