Merge branch 'swagger-codegen_renamed' into 'master' (#183)

* Added vendorExtensions.x-isPrimitive. (#7991)

* Added vendorExtensions.x-isPrimitive.

Switch template for constructFromObject.

* Reflect review indication.

* [typescript-angular] AOT-compatible API client (via ng-packagr and ngc) (#7984)

* typescript-angular: uses ng-packagr for the build

see https://github.com/swagger-api/swagger-codegen/issues/6722
see https://github.com/swagger-api/swagger-codegen/pull/6735/

* this should make everybody happy: Angular 2/4/5 AOT support

- uses ngc when targeting Angular 2 (as seen in https://github.com/swagger-api/swagger-codegen/pull/6735)
- uses ng-packagr 1 when targeting Angular 4
- uses ng-packagr 2 when targeting Angular 5

* removes bogus import

* cleans / updates Petstore samples, adds a new sample for Angular 5

* typo in README

* fixes broken travis build. adds pom.xml files again

This reverts commit 471d248a2e9b5d8eed10c71644c222c053e007b0.

* makes usage of `dist` more clear

and i feel generally better when `npm run build` is called explicitly.

- for ng-packagr 2 is doesn't matter, since the final package.json does not have any scripts
- for old ng-packagr 1 it matters, scripts are copied to the final package.json which breaks installation via `npm install {{npmName}} --save` (it runs `npm run build` again)

* typescript-angular: small improvements as suggested by @macjohnny

* angular-typescript: updated petstore samples, 3rd try

* Issue 5542, always generate pom and readme (#7977)

* Issue 5542, generate pom.xml with separate parameter. InterfaceOnly=true for not generating pom.xml not works in every situation.

* Issue 5542, generate pom.xml with separate parameter. InterfaceOnly=true for not generating pom.xml not works in every situation.

* Issue #5542 Always generate pom.xml and README.md

* [TypeScript][Angular] fix date path parameters (#7476, #7302) (#7479)

* #7476, #7302: [TypeScript][Angular] fix date path parameters, fix path parameters with :.+ in it

* #7476, #7302: [TypeScript][Angular] fix date path parameters, fix path parameters with :.+ in it

* #7476, #7302: [TypeScript][Angular] fix date path parameters, fix path parameters with :.+ in it

* #7476: generate samples

* code cleanup

* #7476: improve variable description

* #7302: revert character skipping, since it will now have the same parameter name in the method signature and in the api path

* #7302: generate samples

* typescript-angular: added Interfaces to api exports if withInterfaces is selected (#7975)

* added Interfaces to api exports if withInterfaces is selected

* removed import of interface classes

* added gererated petstore example api.ts

* Fix Issue 8014

* Adapted to work with Angular2 Http and Angular 4.3+ HttpClient

* removed unnecessary (others) for ng HttpClient from Interface

* Golang Client Refactor (body and model in errors, typed optional parameters) (#7987)

* Return abstracted errors with model data if available.

* update tests with error models.

* Return error models on the abstract type.

* dont leak FH

* duplicate of PR #7752 for issue #7511

* Change optional parameters to structs.

* update documentation

* fix circleCI failure

* [typescript][angular] query parameter with null value should not be set (#8033)

* #7893: [typescript][angular] fix optional query parameter null value

* #7893: [typescript][angular] generate samples

* #7893: [typescript][angular] generate samples

* Version rest-assured has been updated to 3.1.0 (#8052)

* [Dart] Fixes TypeError in Dart 2 mode (#7959)

* Properly convert lists to dart types

* Updated sample petstore client

* Fixed maps in Dart strong mode
Fixed list parsing for null-elements

* change parseDate in es6/APIClient (#7973)

* [PHP] Improve duplicated validation logic (#7954)

* Improve duplicated validation logic

* Update the samples
This commit is contained in:
Jérémie Bresson
2018-04-22 10:32:30 +02:00
committed by William Cheng
parent 35f0cc221d
commit 07dfbad29d
26 changed files with 388 additions and 235 deletions

View File

@@ -79,12 +79,11 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
typeMapping.put("UUID", "string");
importMapping = new HashMap<String, String>();
importMapping.put("time.Time", "time");
importMapping.put("*os.File", "os");
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Go package name (convention: lowercase).")
.defaultValue("swagger"));
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
.defaultValue(Boolean.TRUE.toString()));
}
@@ -96,8 +95,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name)
{
public String escapeReservedWord(String name) {
// Can't start with an underscore, as our fields need to start with an
// UppercaseLetter so that Go treats them as public/visible.
@@ -109,7 +107,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// - X_Name
// ... or maybe a suffix?
// - Name_ ... think this will work.
if(this.reservedWordsMappings().containsKey(name)) {
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return camelize(name) + '_';
@@ -159,7 +157,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
public String toModelFilename(String name) {
return toModel("model_" + name);
return toModel("model_" + name);
}
public String toModel(String name) {
@@ -181,7 +179,8 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// model name starts with number
if (name.matches("^\\d.*")) {
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + ("model_" + name));
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to "
+ ("model_" + name));
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
}
@@ -205,28 +204,26 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
* @param parameter CodegenParameter object to be processed.
*/
@Override
public void postProcessParameter(CodegenParameter parameter){
public void postProcessParameter(CodegenParameter parameter) {
// Give the base class a chance to process
super.postProcessParameter(parameter);
char firstChar = parameter.paramName.charAt(0);
if (Character.isUpperCase(firstChar)) {
char nameFirstChar = parameter.paramName.charAt(0);
if (Character.isUpperCase(nameFirstChar)) {
// First char is already uppercase, just use paramName.
parameter.vendorExtensions.put("x-exportParamName", parameter.paramName);
} else {
// It's a lowercase first char, let's convert it to uppercase
StringBuilder sb = new StringBuilder(parameter.paramName);
sb.setCharAt(0, Character.toUpperCase(nameFirstChar));
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
}
// It's a lowercase first char, let's convert it to uppercase
StringBuilder sb = new StringBuilder(parameter.paramName);
sb.setCharAt(0, Character.toUpperCase(firstChar));
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
}
@Override
public String getTypeDeclaration(Schema p) {
if(ModelUtils.isArraySchema(p)) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
return "[]" + getTypeDeclaration(inner);
@@ -244,11 +241,11 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
return typeMapping.get(openAPIType);
}
if(typeMapping.containsValue(openAPIType)) {
if (typeMapping.containsValue(openAPIType)) {
return openAPIType;
}
if(languageSpecificPrimitives.contains(openAPIType)) {
if (languageSpecificPrimitives.contains(openAPIType)) {
return openAPIType;
}
@@ -259,12 +256,11 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
String type = null;
if(typeMapping.containsKey(openAPIType)) {
if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
if(languageSpecificPrimitives.contains(type))
if (languageSpecificPrimitives.contains(type))
return (type);
}
else
} else
type = openAPIType;
return type;
}
@@ -275,7 +271,8 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(sanitizedOperationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize("call_" + operationId));
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
+ camelize("call_" + operationId));
sanitizedOperationId = "call_" + sanitizedOperationId;
}
@@ -305,21 +302,48 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
iterator.remove();
}
// if their is a return type, import encoding/json and if needed encoding/xml
// this will only import "fmt" if there are items in pathParams
for (CodegenOperation operation : operations) {
if(operation.returnBaseType != null ) {
imports.add(createMapping("import", "encoding/json"));
if (withXml)
imports.add(createMapping("import", "encoding/xml"));
if (operation.pathParams != null && operation.pathParams.size() > 0) {
imports.add(createMapping("import", "fmt"));
break; //just need to import once
}
}
// this will only import "fmt" if there are items in pathParams
boolean addedOptionalImport = false;
boolean addedTimeImport = false;
boolean addedOSImport = false;
for (CodegenOperation operation : operations) {
if(operation.pathParams != null && operation.pathParams.size() > 0) {
imports.add(createMapping("import", "fmt"));
break; //just need to import once
for (CodegenParameter param : operation.allParams) {
// import "os" if the operation uses files
if (!addedOSImport && param.dataType == "*os.File") {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
// import "time" if the operation has a required time parameter.
if (param.required) {
if (!addedTimeImport && param.dataType == "time.Time") {
imports.add(createMapping("import", "time"));
addedTimeImport = true;
}
}
// import "optionals" package if the parameter is primitive and optional
if (!param.required && param.isPrimitiveType) {
if (!addedOptionalImport) {
imports.add(createMapping("import", "github.com/antihax/optional"));
addedOptionalImport = true;
}
// We need to specially map Time type to the optionals package
if (param.dataType == "time.Time") {
param.vendorExtensions.put("x-optionalDataType", "Time");
continue;
}
// Map optional type to dataType
param.vendorExtensions.put("x-optionalDataType",
param.dataType.substring(0, 1).toUpperCase() + param.dataType.substring(1));
}
}
}
@@ -353,6 +377,25 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
iterator.remove();
}
boolean addedTimeImport = false;
boolean addedOSImport = false;
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
for (Map<String, Object> m : models) {
Object v = m.get("model");
if (v instanceof CodegenModel) {
CodegenModel model = (CodegenModel) v;
for (CodegenProperty param : model.vars) {
if (!addedTimeImport && param.baseType == "time.Time") {
imports.add(createMapping("import", "time"));
addedTimeImport = true;
}
if (!addedOSImport && param.baseType == "*os.File") {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
}
}
}
// recursively add import for mapping one type to multiple imports
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
if (recursiveImports == null)
@@ -379,8 +422,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
protected boolean needToImport(String type) {
return !defaultIncludes.contains(type)
&& !languageSpecificPrimitives.contains(type);
return !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type);
}
public void setPackageName(String packageName) {
@@ -398,7 +440,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
return input.replace("*/", "*_/").replace("/*", "/_*");
}
public Map<String, String> createMapping(String key, String value){
public Map<String, String> createMapping(String key, String value) {
Map<String, String> customImport = new HashMap<String, String>();
customImport.put(key, value);

View File

@@ -82,7 +82,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
supportedLibraries.put("resteasy", "HTTP client: Resteasy client 3.1.3.Final. JSON processing: Jackson 2.8.9");
supportedLibraries.put("vertx", "HTTP client: VertX client 3.2.4. JSON processing: Jackson 2.8.9");
supportedLibraries.put("google-api-client", "HTTP client: Google API client 1.23.0. JSON processing: Jackson 2.8.9");
supportedLibraries.put("rest-assured", "HTTP client: rest-assured : 3.0.6. JSON processing: Gson 2.6.1. Only for Java8");
supportedLibraries.put("rest-assured", "HTTP client: rest-assured : 3.1.0. JSON processing: Gson 2.6.1. Only for Java8");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
libraryOption.setEnum(supportedLibraries);

View File

@@ -810,6 +810,11 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
if (model.getAdditionalProperties() != null) {
codegenModel.getVendorExtensions().put("x-isMap", true);
codegenModel.getVendorExtensions().put("x-itemType", getSchemaType((Schema) model.getAdditionalProperties()));
} else {
String type = model.getType();
if (isPrimitiveType(type)){
codegenModel.vendorExtensions.put("x-isPrimitive", true);
}
}
}
@@ -894,6 +899,11 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
return !Boolean.TRUE.equals(co.returnTypeIsPrimitive);
}
private boolean isPrimitiveType(String type) {
final String[] primitives = {"number", "integer", "string", "boolean", "null"};
return Arrays.asList(primitives).contains(type);
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {

View File

@@ -217,9 +217,10 @@ public class SpringCodegen extends AbstractJavaCodegen
}
}
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
if (!this.interfaceOnly) {
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
if (library.equals(DEFAULT_LIBRARY)) {
supportingFiles.add(new SupportingFile("homeController.mustache",

View File

@@ -57,8 +57,9 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
apiPackage = "api";
modelPackage = "model";
this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package"));
this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package"));
this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." +
" Required to generate a full angular package"));
this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package. Default is '1.0.0'"));
this.cliOptions.add(new CliOption(NPM_REPOSITORY,
"Use this property to set an url your private npmRepo in the package.json"));
this.cliOptions.add(new CliOption(SNAPSHOT,
@@ -86,7 +87,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
@Override
public String getHelp() {
return "Generates a TypeScript Angular (2.x or 4.x) client library.";
return "Generates a TypeScript Angular (2.x - 5.x) client library.";
}
@Override
@@ -105,8 +106,18 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("README.mustache", getIndexDirectory(), "README.md"));
// determine NG version
SemVer ngVersion;
if (additionalProperties.containsKey(NG_VERSION)) {
ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString());
} else {
ngVersion = new SemVer("4.3.0");
LOGGER.info("generating code for Angular {} ...", ngVersion);
LOGGER.info(" (you can select the angular version by setting the additionalProperty ngVersion)");
}
if (additionalProperties.containsKey(NPM_NAME)) {
addNpmPackageGeneration();
addNpmPackageGeneration(ngVersion);
}
if (additionalProperties.containsKey(WITH_INTERFACES)) {
@@ -120,15 +131,6 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
taggedUnions = Boolean.parseBoolean(additionalProperties.get(TAGGED_UNIONS).toString());
}
// determine NG version
SemVer ngVersion;
if (additionalProperties.containsKey(NG_VERSION)) {
ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString());
} else {
ngVersion = new SemVer("4.3.0");
LOGGER.info("generating code for Angular {} ...", ngVersion);
LOGGER.info(" (you can select the angular version by setting the additionalProperty ngVersion)");
}
additionalProperties.put(NG_VERSION, ngVersion);
additionalProperties.put("injectionToken", ngVersion.atLeast("4.0.0") ? "InjectionToken" : "OpaqueToken");
additionalProperties.put("injectionTokenTyped", ngVersion.atLeast("4.0.0"));
@@ -138,7 +140,8 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
}
}
private void addNpmPackageGeneration() {
private void addNpmPackageGeneration(SemVer ngVersion) {
if (additionalProperties.containsKey(NPM_NAME)) {
this.setNpmName(additionalProperties.get(NPM_NAME).toString());
}
@@ -157,6 +160,20 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
}
// for Angular 2 AOT support we will use good-old ngc,
// Angular Package format wasn't invented at this time and building was much more easier
if (!ngVersion.atLeast("4.0.0")) {
LOGGER.warn("Please update your legacy Angular " + ngVersion + " project to benefit from 'Angular Package Format' support.");
additionalProperties.put("useNgPackagr", false);
} else {
additionalProperties.put("useNgPackagr", true);
supportingFiles.add(new SupportingFile("ng-package.mustache", getIndexDirectory(), "ng-package.json"));
}
// Libraries generated with v1.x of ng-packagr will ship with AoT metadata in v3, which is intended for Angular v4.
// Libraries generated with v2.x of ng-packagr will ship with AoT metadata in v4, which is intended for Angular v5 (and Angular v6).
additionalProperties.put("useOldNgPackagr", !ngVersion.atLeast("5.0.0"));
//Files for building our lib
supportingFiles.add(new SupportingFile("package.mustache", getIndexDirectory(), "package.json"));
supportingFiles.add(new SupportingFile("typings.mustache", getIndexDirectory(), "typings.json"));
@@ -280,15 +297,20 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
insideCurly--;
// Add the more complicated component instead of just the brace.
CodegenParameter parameter = findPathParameterByName(op, parameterName.toString());
pathBuffer.append(toVarName(parameterName.toString()));
if (parameter != null && parameter.isDateTime) {
pathBuffer.append(".toISOString()");
}
pathBuffer.append("))}");
parameterName.setLength(0);
break;
default:
char nextChar = op.path.charAt(i);
if (insideCurly > 0) {
parameterName.append(op.path.charAt(i));
parameterName.append(nextChar);
} else {
pathBuffer.append(op.path.charAt(i));
pathBuffer.append(nextChar);
}
break;
}
@@ -308,6 +330,21 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
return operations;
}
/**
* Finds and returns a path parameter of an operation by its name
* @param operation
* @param parameterName
* @return
*/
private CodegenParameter findPathParameterByName(CodegenOperation operation, String parameterName) {
for(CodegenParameter param : operation.pathParams) {
if (param.baseName.equals(parameterName)) {
return param;
}
}
return null;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessModels(objs);