diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java index 8178ed30e8e..3e3647f513b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java @@ -79,12 +79,11 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege typeMapping.put("UUID", "string"); importMapping = new HashMap(); - 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> models = (List>) objs.get("models"); + for (Map 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> recursiveImports = (List>) 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 createMapping(String key, String value){ + public Map createMapping(String key, String value) { Map customImport = new HashMap(); customImport.put(key, value); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java index 65fd29d0418..20a5ce80324 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -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); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavascriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavascriptClientCodegen.java index 80d7b674107..b17c8382899 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavascriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavascriptClientCodegen.java @@ -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 postProcessOperations(Map objs) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index fd665e9e102..515927ebac5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -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", diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java index 50c255330bc..b6212bb10a0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java @@ -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 postProcessModels(Map objs) { Map result = super.postProcessModels(objs); diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/api.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/api.mustache index 1d1a5d9ae54..4e784645989 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/api.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/api.mustache @@ -30,11 +30,8 @@ public class {{classname}} { private RequestSpecBuilder reqSpec; - private JSON json; - private {{classname}}(RequestSpecBuilder reqSpec) { this.reqSpec = reqSpec; - this.json = new JSON(); } public static {{classname}} {{classVarName}}(RequestSpecBuilder reqSpec) { @@ -53,26 +50,6 @@ public class {{classname}} { {{/operation}} {{/operations}} - /** - * Get JSON - * - * @return JSON object - */ - public JSON getJSON() { - return json; - } - - /** - * Set JSON - * - * @param json JSON object - * @return {{classname}} - */ - public {{classname}} setJSON(JSON json) { - this.json = json; - return this; - } - /** * Customise request specification */ @@ -152,7 +129,7 @@ public class {{classname}} { */ public {{{returnType}}} executeAs(Function handler) { Type type = new TypeToken<{{{returnType}}}>(){}.getType(); - return getJSON().deserialize(execute(handler).asString(), type); + return execute(handler).as(type); } {{/returnType}} {{#bodyParams}} @@ -161,7 +138,7 @@ public class {{classname}} { * @param {{paramName}} ({{{dataType}}}) {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} */ public {{operationIdCamelCase}}Oper body({{{dataType}}} {{paramName}}) { - reqSpec.setBody(getJSON().serialize({{paramName}})); + reqSpec.setBody({{paramName}}); return this; } {{/bodyParams}} diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.gradle.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.gradle.mustache index fc67b62d13e..54b90483f4c 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.gradle.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.gradle.mustache @@ -95,7 +95,7 @@ if(hasProperty('target') && target == 'android') { ext { swagger_annotations_version = "1.5.15" - rest_assured_version = "3.0.6" + rest_assured_version = "3.1.0" junit_version = "4.12" gson_version = "2.6.1" gson_fire_version = "1.8.2" diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.sbt.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.sbt.mustache index 289345c3a0a..68f3eff08d0 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.sbt.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/build.sbt.mustache @@ -10,7 +10,7 @@ lazy val root = (project in file(".")). resolvers += Resolver.mavenLocal, libraryDependencies ++= Seq( "io.swagger" % "swagger-annotations" % "1.5.15", - "io.rest-assured" % "scala-support" % "3.0.6", + "io.rest-assured" % "scala-support" % "3.1.0", "com.google.code.gson" % "gson" % "2.6.1", "io.gsonfire" % "gson-fire" % "1.8.2" % "compile", {{#joda}} diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/pom.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/pom.mustache index 80f043340c2..1d0c1711389 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/pom.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/rest-assured/pom.mustache @@ -246,7 +246,7 @@ UTF-8 1.5.15 - 3.0.6 + 3.1.0 2.6.1 1.8.2 1.0.0 diff --git a/modules/openapi-generator/src/main/resources/Javascript/es6/ApiClient.mustache b/modules/openapi-generator/src/main/resources/Javascript/es6/ApiClient.mustache index 0e2a92da149..c3caec29101 100644 --- a/modules/openapi-generator/src/main/resources/Javascript/es6/ApiClient.mustache +++ b/modules/openapi-generator/src/main/resources/Javascript/es6/ApiClient.mustache @@ -505,7 +505,7 @@ export default class ApiClient { * @returns {Date} The parsed date object. */{{/emitJSDoc}} static parseDate(str) { - return new Date(str.replace(/T/i, ' ')); + return new Date(str); } {{#emitJSDoc}}/** diff --git a/modules/openapi-generator/src/main/resources/Javascript/partial_model_generic.mustache b/modules/openapi-generator/src/main/resources/Javascript/partial_model_generic.mustache index e955fda3869..74d410ddec8 100644 --- a/modules/openapi-generator/src/main/resources/Javascript/partial_model_generic.mustache +++ b/modules/openapi-generator/src/main/resources/Javascript/partial_model_generic.mustache @@ -36,6 +36,12 @@ * @return {{=< >=}}{module:<#invokerPackage>/<#modelPackage>/}<={{ }}=> The populated {{classname}} instance. */ {{/emitJSDoc}} +{{#vendorExtensions.x-isPrimitive}} + exports.constructFromObject = function(data, obj) { + return data; + } +{{/vendorExtensions.x-isPrimitive}} +{{^vendorExtensions.x-isPrimitive}} exports.constructFromObject = function(data, obj) { if (data){{! TODO: support polymorphism: discriminator property on data determines class to instantiate.}} { obj = obj || new exports(); @@ -48,6 +54,7 @@ {{/vars}} } return obj; } +{{/vendorExtensions.x-isPrimitive}} {{#useInheritance}}{{#parentModel}} exports.prototype = Object.create({{classname}}.prototype); exports.prototype.constructor = exports; diff --git a/modules/openapi-generator/src/main/resources/dart/api.mustache b/modules/openapi-generator/src/main/resources/dart/api.mustache index 99a49364e33..c70d88013ba 100644 --- a/modules/openapi-generator/src/main/resources/dart/api.mustache +++ b/modules/openapi-generator/src/main/resources/dart/api.mustache @@ -90,7 +90,18 @@ class {{classname}} { if(response.statusCode >= 400) { throw new ApiException(response.statusCode, response.body); } else if(response.body != null) { - return {{#returnType}}apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}} {{/returnType}}; + return + {{#isListContainer}} + {{#returnType}}(apiClient.deserialize(response.body, '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();{{/returnType}} + {{/isListContainer}} + {{^isListContainer}} + {{#isMapContainer}} + {{#returnType}}new {{{returnType}}}.from(apiClient.deserialize(response.body, '{{{returnType}}}')) {{/returnType}}; + {{/isMapContainer}} + {{^isMapContainer}} + {{#returnType}}apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}} {{/returnType}}; + {{/isMapContainer}} + {{/isListContainer}} } else { return {{#returnType}}null{{/returnType}}; } diff --git a/modules/openapi-generator/src/main/resources/dart/class.mustache b/modules/openapi-generator/src/main/resources/dart/class.mustache index 83e04bba4f2..66366a78705 100644 --- a/modules/openapi-generator/src/main/resources/dart/class.mustache +++ b/modules/openapi-generator/src/main/resources/dart/class.mustache @@ -19,11 +19,18 @@ class {{classname}} { {{^isDateTime}} {{name}} = {{#complexType}} - {{#isListContainer}}{{complexType}}.listFromJson(json['{{name}}']){{/isListContainer}}{{^isListContainer}} - {{#isMapContainer}}{{complexType}}.mapFromJson(json['{{name}}']){{/isMapContainer}} - {{^isMapContainer}}new {{complexType}}.fromJson(json['{{name}}']){{/isMapContainer}}{{/isListContainer}} + {{#isListContainer}}{{complexType}}.listFromJson(json['{{name}}']){{/isListContainer}}{{^isListContainer}} + {{#isMapContainer}}{{complexType}}.mapFromJson(json['{{name}}']){{/isMapContainer}} + {{^isMapContainer}}new {{complexType}}.fromJson(json['{{name}}']){{/isMapContainer}}{{/isListContainer}} {{/complexType}} - {{^complexType}}json['{{name}}']{{/complexType}}; + {{^complexType}} + {{#isListContainer}} + (json['{{name}}'] as List).map((item) => item as {{items.datatype}}).toList() + {{/isListContainer}} + {{^isListContainer}} + json['{{name}}'] + {{/isListContainer}} + {{/complexType}}; {{/isDateTime}} {{/vars}} } @@ -36,12 +43,8 @@ class {{classname}} { }; } - static List<{{classname}}> listFromJson(List> json) { - var list = new List<{{classname}}>(); - if (json != null && json.length > 0) { - json.forEach((Map value) => list.add(new {{classname}}.fromJson(value))); - } - return list; + static List<{{classname}}> listFromJson(List json) { + return json == null ? new List<{{classname}}>() : json.map((value) => new {{classname}}.fromJson(value)).toList(); } static Map mapFromJson(Map> json) { diff --git a/modules/openapi-generator/src/main/resources/go/api.mustache b/modules/openapi-generator/src/main/resources/go/api.mustache index a7bb7a7f876..1aa817ca8d1 100644 --- a/modules/openapi-generator/src/main/resources/go/api.mustache +++ b/modules/openapi-generator/src/main/resources/go/api.mustache @@ -7,7 +7,7 @@ import ( "net/http" "net/url" "strings" - "golang.org/x/net/context" + "context" {{#imports}} "{{import}}" {{/imports}} ) @@ -20,22 +20,30 @@ var ( type {{classname}}Service service {{#operation}} -/* {{{classname}}}Service{{#summary}} {{.}}{{/summary}}{{#notes}} +/* +{{{classname}}}Service{{#summary}} {{.}}{{/summary}}{{#notes}} {{notes}}{{/notes}} - * @param ctx context.Context for authentication, logging, tracing, etc. -{{#allParams}}{{#required}}@param {{paramName}}{{#description}} {{.}}{{/description}} -{{/required}}{{/allParams}}{{#hasOptionalParams}}@param optional (nil or map[string]interface{}) with one or more of: -{{#allParams}}{{^required}} @param "{{paramName}}" ({{dataType}}){{#description}} {{.}}{{/description}} -{{/required}}{{/allParams}}{{/hasOptionalParams}}@return {{#returnType}}{{{returnType}}}{{/returnType}}*/ -func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}}, {{/hasParams}}{{#allParams}}{{#required}}{{paramName}} {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}}{{#hasOptionalParams}}localVarOptionals map[string]interface{}{{/hasOptionalParams}}) ({{#returnType}}{{{returnType}}}, {{/returnType}}*http.Response, error) { + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). +{{#allParams}}{{#required}} * @param {{paramName}}{{#description}} {{.}}{{/description}} +{{/required}}{{/allParams}}{{#hasOptionalParams}} * @param optional nil or *{{{nickname}}}Opts - Optional Parameters: +{{#allParams}}{{^required}} * @param "{{vendorExtensions.x-exportParamName}}" ({{#isPrimitiveType}}optional.{{vendorExtensions.x-optionalDataType}}{{/isPrimitiveType}}{{^isPrimitiveType}}optional.Interface of {{dataType}}{{/isPrimitiveType}}) - {{#description}} {{.}}{{/description}} +{{/required}}{{/allParams}}{{/hasOptionalParams}} +{{#returnType}}@return {{{returnType}}}{{/returnType}} +*/ +{{#hasOptionalParams}} + +type {{{nickname}}}Opts struct { {{#allParams}}{{^required}} +{{#isPrimitiveType}} {{vendorExtensions.x-exportParamName}} optional.{{vendorExtensions.x-optionalDataType}}{{/isPrimitiveType}}{{^isPrimitiveType}} {{vendorExtensions.x-exportParamName}} optional.Interface{{/isPrimitiveType}}{{/required}}{{/allParams}} +} + +{{/hasOptionalParams}} +func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams}}, {{/hasParams}}{{#allParams}}{{#required}}{{paramName}} {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}}{{#hasOptionalParams}}localVarOptionals *{{{nickname}}}Opts{{/hasOptionalParams}}) ({{#returnType}}{{{returnType}}}, {{/returnType}}*http.Response, error) { var ( localVarHttpMethod = strings.ToUpper("{{httpMethod}}") localVarPostBody interface{} localVarFileName string localVarFileBytes []byte -{{#returnType}} - successPayload {{returnType}} -{{/returnType}} + {{#returnType}}localVarReturnValue {{{returnType}}}{{/returnType}} ) // create path and map variables @@ -46,32 +54,25 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} localVarQueryParams := url.Values{} localVarFormParams := url.Values{} {{#allParams}} - {{^required}} - {{#isPrimitiveType}} - if err := typeCheckParameter(localVarOptionals["{{paramName}}"], "{{{dataType}}}", "{{paramName}}"); err != nil { - return {{#returnType}}successPayload, {{/returnType}}nil, err - } - {{/isPrimitiveType}} - {{/required}} {{#required}} {{#minItems}} if len({{paramName}}) < {{minItems}} { - return {{#returnType}}successPayload, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minItems}} elements") + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minItems}} elements") } {{/minItems}} {{#maxItems}} if len({{paramName}}) > {{maxItems}} { - return {{#returnType}}successPayload, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxItems}} elements") + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxItems}} elements") } {{/maxItems}} {{#minLength}} if strlen({{paramName}}) < {{minLength}} { - return {{#returnType}}successPayload, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minLength}} elements") + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have at least {{minLength}} elements") } {{/minLength}} {{#maxLength}} if strlen({{paramName}}) > {{maxLength}} { - return {{#returnType}}successPayload, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxLength}} elements") + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must have less than {{maxLength}} elements") } {{/maxLength}} {{#minimum}} @@ -82,7 +83,7 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} {{^isString}} if {{paramName}} < {{minimum}} { {{/isString}} - return {{#returnType}}successPayload, {{/returnType}}nil, reportError("{{paramName}} must be greater than {{minimum}}") + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must be greater than {{minimum}}") } {{/minimum}} {{#maximum}} @@ -93,7 +94,7 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} {{^isString}} if {{paramName}} > {{maximum}} { {{/isString}} - return {{#returnType}}successPayload, {{/returnType}}nil, reportError("{{paramName}} must be less than {{maximum}}") + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} must be less than {{maximum}}") } {{/maximum}} {{/required}} @@ -105,8 +106,8 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} localVarQueryParams.Add("{{baseName}}", parameterToString({{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")) {{/required}} {{^required}} - if localVarTempParam, localVarOk := localVarOptionals["{{paramName}}"].({{dataType}}); localVarOk { - localVarQueryParams.Add("{{baseName}}", parameterToString(localVarTempParam, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")) + if localVarOptionals != nil && localVarOptionals.{{vendorExtensions.x-exportParamName}}.IsSet() { + localVarQueryParams.Add("{{baseName}}", parameterToString(localVarOptionals.{{vendorExtensions.x-exportParamName}}.Value(), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")) } {{/required}} {{/queryParams}} @@ -138,8 +139,8 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} localVarHeaderParams["{{baseName}}"] = parameterToString({{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}") {{/required}} {{^required}} - if localVarTempParam, localVarOk := localVarOptionals["{{paramName}}"].({{dataType}}); localVarOk { - localVarHeaderParams["{{baseName}}"] = parameterToString(localVarTempParam, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}") + if localVarOptionals != nil && localVarOptionals.{{vendorExtensions.x-exportParamName}}.IsSet() { + localVarHeaderParams["{{baseName}}"] = parameterToString(localVarOptionals.{{vendorExtensions.x-exportParamName}}.Value(), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}") } {{/required}} {{/headerParams}} @@ -148,9 +149,13 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} {{#formParams}} {{#isFile}} {{^required}} - var localVarFile ({{dataType}}) - if localVarTempParam, localVarOk := localVarOptionals["{{paramName}}"].({{dataType}}); localVarOk { - localVarFile = localVarTempParam + var localVarFile {{dataType}} + if localVarOptionals != nil && localVarOptionals.{{vendorExtensions.x-exportParamName}}.IsSet() { + localVarFileOk := false + localVarFile, localVarFileOk = localVarOptionals.{{vendorExtensions.x-exportParamName}}.Value().({{dataType}}) + if !localVarFileOk { + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} should be {{dataType}}") + } } {{/required}} if localVarFile != nil { @@ -165,8 +170,8 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} localVarFormParams.Add("{{baseName}}", parameterToString({{paramName}}, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")) {{/required}} {{^required}} - if localVarTempParam, localVarOk := localVarOptionals["{{paramName}}"].({{dataType}}); localVarOk { - localVarFormParams.Add("{{baseName}}", parameterToString(localVarTempParam, "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")) + if localVarOptionals != nil && localVarOptionals.{{vendorExtensions.x-exportParamName}}.IsSet() { + localVarFormParams.Add("{{baseName}}", parameterToString(localVarOptionals.{{vendorExtensions.x-exportParamName}}.Value(), "{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}")) } {{/required}} {{/isFile}} @@ -178,8 +183,13 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} localVarPostBody = &{{paramName}} {{/required}} {{^required}} - if localVarTempParam, localVarOk := localVarOptionals["{{paramName}}"].({{dataType}}); localVarOk { - localVarPostBody = &localVarTempParam + if localVarOptionals != nil && localVarOptionals.{{vendorExtensions.x-exportParamName}}.IsSet() { + {{#isPrimitiveType}}localVarPostBody = &localVarOptionals.{{vendorExtensions.x-exportParamName}}.Value(){{/isPrimitiveType}} + {{^isPrimitiveType}}localVarOptional{{vendorExtensions.x-exportParamName}}, localVarOptional{{vendorExtensions.x-exportParamName}}ok := localVarOptionals.{{vendorExtensions.x-exportParamName}}.Value().({{{dataType}}}) + if !localVarOptional{{vendorExtensions.x-exportParamName}}ok { + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, reportError("{{paramName}} should be {{dataType}}") + } + localVarPostBody = &localVarOptional{{vendorExtensions.x-exportParamName}}{{/isPrimitiveType}} } {{/required}} {{/bodyParams}} @@ -195,42 +205,63 @@ func (a *{{{classname}}}Service) {{{nickname}}}(ctx context.Context{{#hasParams} } else { key = auth.Key } - {{#isKeyInHeader}}localVarHeaderParams["{{keyParamName}}"] = key{{/isKeyInHeader}}{{#isKeyInQuery}}localVarQueryParams.Add("{{keyParamName}}", key){{/isKeyInQuery}} + {{#isKeyInHeader}}localVarHeaderParams["{{keyParamName}}"] = key{{/isKeyInHeader}} + {{#isKeyInQuery}}localVarQueryParams.Add("{{keyParamName}}", key){{/isKeyInQuery}} } } {{/isApiKey}} {{/authMethods}} r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) if err != nil { - return {{#returnType}}successPayload, {{/returnType}}nil, err + return {{#returnType}}localVarReturnValue, {{/returnType}}nil, err } localVarHttpResponse, err := a.client.callAPI(r) if err != nil || localVarHttpResponse == nil { - return {{#returnType}}successPayload, {{/returnType}}localVarHttpResponse, err + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, err } - defer localVarHttpResponse.Body.Close() - if localVarHttpResponse.StatusCode >= 300 { - bodyBytes, _ := ioutil.ReadAll(localVarHttpResponse.Body) - return {{#returnType}}successPayload, {{/returnType}}localVarHttpResponse, reportError("Status: %v, Body: %s", localVarHttpResponse.Status, bodyBytes) + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, err } -{{#returnType}} - {{#withXml}} - contentType := localVarHttpResponse.Header.Get("content-type") - if strings.Contains(contentType, "application/xml") { - if err = xml.NewDecoder(localVarHttpResponse.Body).Decode(&successPayload); err != nil { - return successPayload, localVarHttpResponse, err + + {{#returnType}} + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")); + if err == nil { + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, err } - - return successPayload, localVarHttpResponse, err } - {{/withXml}} + {{/returnType}} - if err = json.NewDecoder(localVarHttpResponse.Body).Decode(&successPayload); err != nil { - return {{#returnType}}successPayload, {{/returnType}}localVarHttpResponse, err + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + {{#responses}}{{#dataType}} + if localVarHttpResponse.StatusCode == {{{code}}} { + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + if err != nil { + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, err + } + + var v {{{dataType}}} + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")); + if err != nil { + newErr.error = err.Error() + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, newErr + } + newErr.model = v + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, newErr + } + {{/dataType}}{{/responses}} + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, newErr } -{{/returnType}} - return {{#returnType}}successPayload, {{/returnType}}localVarHttpResponse, err + return {{#returnType}}localVarReturnValue, {{/returnType}}localVarHttpResponse, nil } {{/operation}}{{/operations}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/go/api_doc.mustache b/modules/openapi-generator/src/main/resources/go/api_doc.mustache index 635a91e3ed8..76e823ebb83 100644 --- a/modules/openapi-generator/src/main/resources/go/api_doc.mustache +++ b/modules/openapi-generator/src/main/resources/go/api_doc.mustache @@ -20,16 +20,16 @@ Method | HTTP request | Description {{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **ctx** | **context.Context** | context for logging, tracing, authentication, etc.{{/-last}}{{/allParams}}{{#allParams}}{{#required}} + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc.{{/-last}}{{/allParams}}{{#allParams}}{{#required}} **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{^isFile}}[**{{dataType}}**]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/required}}{{/allParams}}{{#hasOptionalParams}} - **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + **optional** | ***{{{nickname}}}Opts** | optional parameters | nil if no parameters ### Optional Parameters -Optional parameters are passed through a map[string]interface{}. +Optional parameters are passed through a pointer to a {{{nickname}}}Opts struct {{#allParams}}{{#-last}} Name | Type | Description | Notes ------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}{{#allParams}} - **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{^isFile}}[**{{dataType}}**]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/allParams}}{{/hasOptionalParams}} +{{^required}} **{{paramName}}** | {{#isFile}}**optional.Interface of {{dataType}}**{{/isFile}}{{#isPrimitiveType}}**optional.{{vendorExtensions.x-optionalDataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{^isFile}}[**optional.Interface of {{dataType}}**]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}}| {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/required}}{{/allParams}}{{/hasOptionalParams}} ### Return type diff --git a/modules/openapi-generator/src/main/resources/go/client.mustache b/modules/openapi-generator/src/main/resources/go/client.mustache index 38c7a7e2720..c2b2d9ea5e6 100644 --- a/modules/openapi-generator/src/main/resources/go/client.mustache +++ b/modules/openapi-generator/src/main/resources/go/client.mustache @@ -20,7 +20,7 @@ import ( "time" "unicode/utf8" - "golang.org/x/net/context" + "context" "golang.org/x/oauth2" ) @@ -303,6 +303,21 @@ func (c *APIClient) prepareRequest( return localVarRequest, nil } +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if strings.Contains(contentType, "application/xml") { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } else if strings.Contains(contentType, "application/json") { + if err = json.Unmarshal(b, v); err != nil { + return err + } + return nil + } + return errors.New("undefined response type") +} + // Add a file to the multipart request func addFile(w *multipart.Writer, fieldName, path string) error { file, err := os.Open(path) @@ -337,6 +352,8 @@ func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err e _, err = bodyBuf.Write(b) } else if s, ok := body.(string); ok { _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) } else if jsonCheck.MatchString(contentType) { err = json.NewEncoder(bodyBuf).Encode(body) } else if xmlCheck.MatchString(contentType) { @@ -427,3 +444,25 @@ func CacheExpires(r *http.Response) time.Time { func strlen(s string) int { return utf8.RuneCountInString(s) } + +// GenericSwaggerError Provides access to the body, error and model on returned errors. +type GenericSwaggerError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericSwaggerError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericSwaggerError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericSwaggerError) Model() interface{} { + return e.model +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/go/model.mustache b/modules/openapi-generator/src/main/resources/go/model.mustache index 65996a1a9fb..cc8c45cb27d 100644 --- a/modules/openapi-generator/src/main/resources/go/model.mustache +++ b/modules/openapi-generator/src/main/resources/go/model.mustache @@ -12,7 +12,6 @@ const ( {{#allowableValues}} {{#enumVars}} {{^-first}} - {{/-first}} {{name}} {{{classname}}} = "{{{value}}}" {{/enumVars}} @@ -22,7 +21,6 @@ const ( type {{classname}} struct { {{#vars}} {{^-first}} - {{/-first}} {{#description}} // {{{description}}} diff --git a/modules/openapi-generator/src/main/resources/php/model_generic.mustache b/modules/openapi-generator/src/main/resources/php/model_generic.mustache index 9daf49f1379..e9f01ef8268 100644 --- a/modules/openapi-generator/src/main/resources/php/model_generic.mustache +++ b/modules/openapi-generator/src/main/resources/php/model_generic.mustache @@ -259,65 +259,7 @@ class {{classname}} {{#parentSchema}}extends {{{parent}}} {{/parentSchema}}{{^pa */ public function valid() { - {{#parent}} - if (!parent::valid()) { - return false; - } - {{/parent}} - - {{#vars}} - {{#required}} - if ($this->container['{{name}}'] === null) { - return false; - } - {{/required}} - {{#isEnum}} - {{^isContainer}} - $allowedValues = $this->{{getter}}AllowableValues(); - if (!is_null($this->container['{{name}}']) && !in_array($this->container['{{name}}'], $allowedValues, true)) { - return false; - } - {{/isContainer}} - {{/isEnum}} - {{#hasValidation}} - {{#maxLength}} - if (mb_strlen($this->container['{{name}}']) > {{maxLength}}) { - return false; - } - {{/maxLength}} - {{#minLength}} - if (mb_strlen($this->container['{{name}}']) < {{minLength}}) { - return false; - } - {{/minLength}} - {{#maximum}} - if ($this->container['{{name}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}) { - return false; - } - {{/maximum}} - {{#minimum}} - if ($this->container['{{name}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}) { - return false; - } - {{/minimum}} - {{#pattern}} - if (!preg_match("{{{pattern}}}", $this->container['{{name}}'])) { - return false; - } - {{/pattern}} - {{#maxItems}} - if (count($this->container['{{name}}']) > {{maxItems}}) { - return false; - } - {{/maxItems}} - {{#minItems}} - if (count($this->container['{{name}}']) < {{minItems}}) { - return false; - } - {{/minItems}} - {{/hasValidation}} - {{/vars}} - return true; + return count($this->listInvalidProperties()) === 0; } {{#vars}} diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache index 4025896cafa..7f7acecf7fe 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/README.mustache @@ -2,7 +2,7 @@ ### Building -To build an compile the typescript sources to javascript use: +To install the required dependencies and to build the typescript sources run: ``` npm install npm run build @@ -10,11 +10,16 @@ npm run build ### publishing +{{#useNgPackagr}} +First build the package than run ```npm publish dist``` (don't forget to specify the `dist` folder!) +{{/useNgPackagr}} +{{^useNgPackagr}} First build the package than run ```npm publish``` +{{/useNgPackagr}} ### consuming -navigate to the folder of your consuming project and run one of next commando's. +Navigate to the folder of your consuming project and run one of next commands. _published:_ @@ -22,24 +27,41 @@ _published:_ npm install {{npmName}}@{{npmVersion}} --save ``` -_unPublished (not recommended):_ +_without publishing (not recommended):_ ``` +{{#useNgPackagr}} +npm install PATH_TO_GENERATED_PACKAGE/dist --save +{{/useNgPackagr}} +{{^useNgPackagr}} npm install PATH_TO_GENERATED_PACKAGE --save +{{/useNgPackagr}} ``` _using `npm link`:_ +{{#useNgPackagr}} +In PATH_TO_GENERATED_PACKAGE/dist: +{{/useNgPackagr}} +{{^useNgPackagr}} In PATH_TO_GENERATED_PACKAGE: +{{/useNgPackagr}} ``` npm link ``` In your project: ``` -npm link {{npmName}}@{{npmVersion}} +npm link {{npmName}} ``` +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + In your Angular project: diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache index 01274db96bb..7d8e4b567cc 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache @@ -26,7 +26,7 @@ import { {{classname}} } from '../{{filename}}'; import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; {{#withInterfaces}} -import { {{classname}}Interface } from './{{classname}}Interface'; +import { {{classname}}Interface } from './{{classFilename}}Interface'; {{/withInterfaces}} {{#operations}} @@ -149,7 +149,7 @@ export class {{classname}} { } {{/isListContainer}} {{^isListContainer}} - if ({{paramName}} !== undefined) { + if ({{paramName}} !== undefined && {{paramName}} !== null) { {{#isDateTime}} {{#useHttpClient}}queryParameters = {{/useHttpClient}}queryParameters.set('{{baseName}}', {{paramName}}.toISOString()); {{/isDateTime}} diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/apiInterface.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/apiInterface.mustache index 1acd887ce5d..1427ff27ad7 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/apiInterface.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/apiInterface.mustache @@ -1,9 +1,19 @@ {{>licenseInfo}} +{{#useHttpClient}} +import { HttpHeaders } from '@angular/common/http'; +{{/useHttpClient}} +{{^useHttpClient}} import { Headers } from '@angular/http'; +{{/useHttpClient}} import { Observable } from 'rxjs/Observable'; -import * as models from '../model/models'; + +{{#imports}} +import { {{classname}} } from '../{{filename}}'; +{{/imports}} + + import { Configuration } from '../configuration'; {{#operations}} @@ -14,9 +24,9 @@ import { Configuration } from '../configurat */ {{/description}} export interface {{classname}}Interface { - defaultHeaders: Headers; + defaultHeaders: {{#useHttpClient}}Http{{/useHttpClient}}Headers; configuration: Configuration; - [others: string]: any; + {{^useHttpClient}}[others: string]: any;{{/useHttpClient}} {{#operation}} /** diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/apis.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/apis.mustache index 9d3e92349d0..514b5e0d10f 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/apis.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/apis.mustache @@ -4,6 +4,9 @@ export * from './{{ classFilename }}'; import { {{ classname }} } from './{{ classFilename }}'; {{/operations}} +{{#withInterfaces}} +export * from './{{ classFilename }}Interface' +{{/withInterfaces}} {{/apis}} export const APIS = [{{#apis}}{{#operations}}{{ classname }}{{/operations}}{{^-last}}, {{/-last}}{{/apis}}]; {{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache index 2ee1824f5f7..82e8458f39e 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/configuration.mustache @@ -28,8 +28,8 @@ export class Configuration { * Select the correct content-type to use for a request. * Uses {@link Configuration#isJsonMime} to determine the correct content-type. * If no content type is found return the first found type if the contentTypes is not empty - * @param {string[]} contentTypes - the array of content types that are available for selection - * @returns {string} the selected content-type or undefined if no selection could be made. + * @param contentTypes - the array of content types that are available for selection + * @returns the selected content-type or undefined if no selection could be made. */ public selectHeaderContentType (contentTypes: string[]): string | undefined { if (contentTypes.length == 0) { @@ -47,8 +47,8 @@ export class Configuration { * Select the correct accept content-type to use for a request. * Uses {@link Configuration#isJsonMime} to determine the correct accept content-type. * If no content type is found return the first found type if the contentTypes is not empty - * @param {string[]} accepts - the array of content types that are available for selection. - * @returns {string} the selected content-type or undefined if no selection could be made. + * @param accepts - the array of content types that are available for selection. + * @returns the selected content-type or undefined if no selection could be made. */ public selectHeaderAccept(accepts: string[]): string | undefined { if (accepts.length == 0) { @@ -69,8 +69,8 @@ export class Configuration { * application/json; charset=UTF8 * APPLICATION/JSON * application/vnd.company+json - * @param {string} mime - MIME (Multipurpose Internet Mail Extensions) - * @return {boolean} True if the given MIME is JSON, false otherwise. + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. */ public isJsonMime(mime: string): boolean { const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/ng-package.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/ng-package.mustache new file mode 100644 index 00000000000..3b17900dc9c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/typescript-angular/ng-package.mustache @@ -0,0 +1,6 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "index.ts" + } +} diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/package.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/package.mustache index 2c9810e8559..afc69fb7146 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/package.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/package.mustache @@ -7,12 +7,20 @@ "swagger-client" ], "license": "Unlicense", + {{#useNgPackagr}} + "scripts": { + "build": "ng-packagr -p ng-package.json" + }, + {{/useNgPackagr}} + {{^useNgPackagr}} "main": "dist/index.js", + "module": "dist/index.js", "typings": "dist/index.d.ts", "scripts": { - "build": "tsc --outDir dist/", + "build": "ngc", "postinstall": "npm run build" }, + {{/useNgPackagr}} "peerDependencies": { "@angular/core": "^{{ngVersion}}", "@angular/http": "^{{ngVersion}}", @@ -24,11 +32,13 @@ "zone.js": "^0.7.6" }, "devDependencies": { + "@angular/compiler-cli": "^{{ngVersion}}", "@angular/core": "^{{ngVersion}}", "@angular/http": "^{{ngVersion}}", "@angular/common": "^{{ngVersion}}", "@angular/compiler": "^{{ngVersion}}", - "@angular/platform-browser": "^{{ngVersion}}", + "@angular/platform-browser": "^{{ngVersion}}",{{#useNgPackagr}} + "ng-packagr": {{#useOldNgPackagr}}"^1.6.0"{{/useOldNgPackagr}}{{^useOldNgPackagr}}"^2.4.1"{{/useOldNgPackagr}},{{/useNgPackagr}} "reflect-metadata": "^0.1.3", "rxjs": "^5.4.0", "zone.js": "^0.7.6", diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/tsconfig.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/tsconfig.mustache index 3ed5f2c0b10..930d4036184 100644 --- a/modules/openapi-generator/src/main/resources/typescript-angular/tsconfig.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-angular/tsconfig.mustache @@ -21,5 +21,9 @@ "filesGlob": [ "./model/*.ts", "./api/*.ts" - ] + ]{{^useNgPackagr}}, + "angularCompilerOptions": { + "genDir": "dist", + "skipTemplateCodegen": true + }{{/useNgPackagr}} }