diff --git a/.github/workflows/update-specs-and-client-libraries.yaml b/.github/workflows/update-specs-and-client-libraries.yaml index df2586a5..e6a24d73 100644 --- a/.github/workflows/update-specs-and-client-libraries.yaml +++ b/.github/workflows/update-specs-and-client-libraries.yaml @@ -76,7 +76,7 @@ jobs: python_version: ${{ steps.generator.outputs.python_urllib3_version }} ruby_version: ${{ steps.generator.outputs.ruby_faraday_version }} container: - image: openapitools/openapi-generator-cli:v7.6.0 + image: openapitools/openapi-generator-cli:v7.9.0 env: OPENAPI_GENERATOR_COMMAND: docker-entrypoint.sh BUMP_CLIENT_LIBRARY_VERSION: ${{ inputs.type-of-change }} diff --git a/generators/java/okhttp-gson/templates/SHA256SUM b/generators/java/okhttp-gson/templates/SHA256SUM index 067ec654..dcbce58d 100644 --- a/generators/java/okhttp-gson/templates/SHA256SUM +++ b/generators/java/okhttp-gson/templates/SHA256SUM @@ -1,7 +1,7 @@ 16502193337397367078434a27f67edfc6410f4c06d12db876155885d6a49394 ./README.mustache -7b635a5f3fcc4cb2ace38f0dd0ca8252a78090e592a6c35fe5a08f7bc407ef6b ./libraries/okhttp-gson/ApiClient.mustache -133ba02513dba3fa805f364770b5a2fcc87a4c6ed0cf7afd322376e03143859f ./libraries/okhttp-gson/api.mustache +9866a9e83531d72f155a0fdea252cfe5d340deea3d6e2da7eb64c941dc88577a ./libraries/okhttp-gson/ApiClient.mustache +7db4829dd39d1e769cfe38a07e976684f71e5db4077030ea1b423703958da223 ./libraries/okhttp-gson/api.mustache 0e77feaf2d6b0818194161ac7e621189aa6e7900b45d46fa4ff1232894bb1a7a ./libraries/okhttp-gson/oneof_model.mustache -9a768c6d6b3ffcf21e5aa73e2d23ca524deb4b8503e73b0bc7e48e54403e5afb ./libraries/okhttp-gson/pojo.mustache -e83ff873cc6a5a7e064b4732ab4bfbb3fa32660d015b9ca1b6bdb5884335c506 ./libraries/okhttp-gson/pom.mustache +f20b6129f3b473ecaa4e39f760bb1028d6c1f832928fa2f460131e2c54d66ed0 ./libraries/okhttp-gson/pojo.mustache +2f63581598dd2ba1373a51c0c3dfbcfa2a43d25f278a048c04c6679ef03f1224 ./libraries/okhttp-gson/pom.mustache diff --git a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/ApiClient.mustache b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/ApiClient.mustache index aaee1442..342d5a51 100644 --- a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/ApiClient.mustache +++ b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/ApiClient.mustache @@ -627,6 +627,29 @@ public class ApiClient { throw new RuntimeException("No AWS4 authentication configured!"); } + /** + * Helper method to set credentials for AWSV4 Signature + * + * @param accessKey Access Key + * @param secretKey Secret Key + * @param sessionToken Session Token + * @param region Region + * @param service Service to access to + */ + public void setAWS4Configuration(String accessKey, String secretKey, String sessionToken, String region, String service) { + {{#withAWSV4Signature}} + for (Authentication auth : authentications.values()) { + if (auth instanceof AWS4Auth) { + ((AWS4Auth) auth).setCredentials(accessKey, secretKey, sessionToken); + ((AWS4Auth) auth).setRegion(region); + ((AWS4Auth) auth).setService(service); + return; + } + } + {{/withAWSV4Signature}} + throw new RuntimeException("No AWS4 authentication configured!"); + } + /** * Set the User-Agent header's value (by adding to the default header map). * @@ -939,6 +962,30 @@ public class ApiClient { } {{/dynamicOperations}} + /** + * Formats the specified free-form query parameters to a list of {@code Pair} objects. + * + * @param value The free-form query parameters. + * @return A list of {@code Pair} objects. + */ + public List freeFormParameterToPairs(Object value) { + List params = new ArrayList<>(); + + // preconditions + if (value == null || !(value instanceof Map )) { + return params; + } + + final Map valuesMap = (Map) value; + + for (Map.Entry entry : valuesMap.entrySet()) { + params.add(new Pair(entry.getKey(), parameterToString(entry.getValue()))); + } + + return params; + } + + /** * Formats the specified collection path parameter to a string value. * @@ -1192,7 +1239,7 @@ public class ApiClient { * @throws java.io.IOException If fail to prepare file for download */ public File prepareDownloadFile(Response response) throws IOException { - {{! Code extrated to getFilenameFromResponse }} + {{! Code extracted to getFilenameFromResponse }} String filename = getFilenameFromResponse(response); String prefix = null; @@ -1402,10 +1449,6 @@ public class ApiClient { * @throws {{invokerPackage}}.ApiException If fail to serialize the request body object */ public Request buildRequest(String baseUrl, String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map cookieParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException { - // aggregate queryParams (non-collection) and collectionQueryParams into allQueryParams - List allQueryParams = new ArrayList(queryParams); - allQueryParams.addAll(collectionQueryParams); - final String url = buildUrl(baseUrl, path, queryParams, collectionQueryParams); // prepare HTTP request body @@ -1433,10 +1476,12 @@ public class ApiClient { reqBody = serialize(body, contentType); } + List updatedQueryParams = new ArrayList<>(queryParams); + // update parameters with authentication settings - updateParamsForAuth(authNames, allQueryParams, headerParams, cookieParams, requestBodyToString(reqBody), method, URI.create(url)); + updateParamsForAuth(authNames, updatedQueryParams, headerParams, cookieParams, requestBodyToString(reqBody), method, URI.create(url)); - final Request.Builder reqBuilder = new Request.Builder().url(url); + final Request.Builder reqBuilder = new Request.Builder().url(buildUrl(baseUrl, path, updatedQueryParams, collectionQueryParams)); processHeaderParams(headerParams, reqBuilder); processCookieParams(cookieParams, reqBuilder); diff --git a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/api.mustache b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/api.mustache index c659d9b3..52817018 100644 --- a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/api.mustache +++ b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/api.mustache @@ -170,7 +170,7 @@ public class {{classname}} { {{^dynamicOperations}} {{#queryParams}} if ({{paramName}} != null) { - {{#collectionFormat}}localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("{{{.}}}", {{/collectionFormat}}{{^collectionFormat}}localVarQueryParams.addAll(localVarApiClient.parameterToPair({{/collectionFormat}}"{{baseName}}", {{paramName}})); + {{#isFreeFormObject}}localVarQueryParams.addAll(localVarApiClient.freeFormParameterToPairs({{paramName}}));{{/isFreeFormObject}}{{^isFreeFormObject}}{{#collectionFormat}}localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("{{{.}}}", {{/collectionFormat}}{{^collectionFormat}}localVarQueryParams.addAll(localVarApiClient.parameterToPair({{/collectionFormat}}"{{baseName}}", {{paramName}}));{{/isFreeFormObject}} } {{/queryParams}} diff --git a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/oneof_model.mustache b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/oneof_model.mustache index 3f5786c4..7c00259b 100644 --- a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/oneof_model.mustache +++ b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/oneof_model.mustache @@ -49,15 +49,21 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im {{#composedSchemas}} {{#oneOf}} {{^isArray}} + {{^isMap}} {{^vendorExtensions.x-duplicated-data-type}} final TypeAdapter<{{{dataType}}}> adapter{{{dataType}}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}.class)); {{/vendorExtensions.x-duplicated-data-type}} + {{/isMap}} {{/isArray}} {{#isArray}} - final Type typeInstance = new TypeToken<{{{dataType}}}>(){}.getType(); - final TypeAdapter<{{{dataType}}}> adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = (TypeAdapter<{{{dataType}}}>) gson.getDelegateAdapter(this, TypeToken.get(typeInstance)); + final Type typeInstance{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = new TypeToken<{{{dataType}}}>(){}.getType(); + final TypeAdapter<{{{dataType}}}> adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = (TypeAdapter<{{{dataType}}}>) gson.getDelegateAdapter(this, TypeToken.get(typeInstance{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}})); {{/isArray}} + {{#isMap}} + final Type typeInstance{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = new TypeToken<{{{dataType}}}>(){}.getType(); + final TypeAdapter<{{{dataType}}}> adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = (TypeAdapter<{{{dataType}}}>) gson.getDelegateAdapter(this, TypeToken.get(typeInstance{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}})); + {{/isMap}} {{/oneOf}} {{/composedSchemas}} @@ -76,8 +82,9 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im {{#oneOf}} {{^vendorExtensions.x-duplicated-data-type}} // check if the actual instance is of the type `{{{dataType}}}` - if (value.getActualInstance() instanceof {{#isArray}}List{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) { + if (value.getActualInstance() instanceof {{#isArray}}List{{/isArray}}{{#isMap}}Map{{/isMap}}{{^isMap}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isMap}}) { {{#isPrimitiveType}} + {{^isMap}} {{! Updated code - BEGIN }} {{#isArray}} JsonElement element = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}.toJsonTree(({{{dataType}}})value.getActualInstance()); @@ -88,6 +95,12 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im elementAdapter.write(out, element); {{! Updated code - END }} return; + {{/isMap}} + {{#isMap}} + JsonObject object = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}.toJsonTree(({{{dataType}}})value.getActualInstance()).getAsJsonObject(); + elementAdapter.write(out, object); + return; + {{/isMap}} {{/isPrimitiveType}} {{^isPrimitiveType}} {{#isArray}} @@ -99,6 +112,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im } {{/isArray}} {{/isPrimitiveType}} + {{^isMap}} {{^isArray}} {{^isPrimitiveType}} JsonElement element = adapter{{{dataType}}}.toJsonTree(({{{dataType}}})value.getActualInstance()); @@ -106,6 +120,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im return; {{/isPrimitiveType}} {{/isArray}} + {{/isMap}} } {{/vendorExtensions.x-duplicated-data-type}} {{/oneOf}} @@ -157,6 +172,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im try { // validate the JSON object to see if any exception is thrown {{^isArray}} + {{^isMap}} {{#isNumber}} if (!jsonElement.getAsJsonPrimitive().isNumber()) { throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); @@ -177,6 +193,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im actualAdapter = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}; {{/isPrimitiveType}} {{/isNumber}} + {{/isMap}} {{/isArray}} {{#isArray}} if (!jsonElement.isJsonArray()) { @@ -208,6 +225,38 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im } actualAdapter = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}; {{/isArray}} + {{#isMap}} + if (!jsonElement.isJsonObject()) { + throw new IllegalArgumentException(String.format("Expected json element to be a object type in the JSON string but got `%s`", jsonElement.toString())); + } + + {{^isFreeFormObject}} + Map map = jsonElement.getAsJsonObject().asMap(); + // validate map items + for(JsonElement element : map.values()) { + {{#items}} + {{#isNumber}} + if (!jsonElement.getAsJsonPrimitive().isNumber()) { + throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); + } + {{/isNumber}} + {{^isNumber}} + {{#isPrimitiveType}} + if (!element.getAsJsonPrimitive().is{{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}}()) { + throw new IllegalArgumentException(String.format("Expected array items to be of type {{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}} in the JSON string but got `%s`", jsonElement.toString())); + } + {{/isPrimitiveType}} + {{/isNumber}} + {{^isNumber}} + {{^isPrimitiveType}} + {{{dataType}}}.validateJsonElement(element); + {{/isPrimitiveType}} + {{/isNumber}} + {{/items}} + } + {{/isFreeFormObject}} + actualAdapter = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}; + {{/isMap}} match++; log.log(Level.FINER, "Input data matches schema '{{{dataType}}}'"); } catch (Exception e) { @@ -256,13 +305,11 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im super("oneOf", {{#isNullable}}Boolean.TRUE{{/isNullable}}{{^isNullable}}Boolean.FALSE{{/isNullable}}); } - {{#oneOf}} - public {{classname}}({{{.}}} o) { + public {{classname}}(Object o) { super("oneOf", {{#isNullable}}Boolean.TRUE{{/isNullable}}{{^isNullable}}Boolean.FALSE{{/isNullable}}); setActualInstance(o); } - {{/oneOf}} static { {{#composedSchemas}} {{#oneOf}} @@ -297,7 +344,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im {{#composedSchemas}} {{#oneOf}} {{^vendorExtensions.x-duplicated-data-type}} - if (instance instanceof {{#isArray}}List{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) { + if (instance instanceof {{#isArray}}List{{/isArray}}{{#isMap}}Map{{/isMap}}{{^isMap}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isMap}}) { {{#isArray}} List list = (List) instance; if (list.get(0) instanceof {{{items.dataType}}}) { @@ -341,7 +388,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im */ {{! Suppress unchecked cast warning }} @SuppressWarnings("unchecked") - public {{{dataType}}} get{{#isArray}}{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}() throws ClassCastException { + public {{{dataType}}} get{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}() throws ClassCastException { return ({{{dataType}}})super.getActualInstance(); } {{/vendorExtensions.x-duplicated-data-type}} @@ -364,6 +411,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im // validate the json string with {{{dataType}}} try { {{^hasVars}} + {{^isMap}} {{^isArray}} {{#isNumber}} if (!jsonElement.getAsJsonPrimitive().isNumber()) { @@ -383,6 +431,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im {{/isPrimitiveType}} {{/isNumber}} {{/isArray}} + {{/isMap}} {{#isArray}} if (!jsonElement.isJsonArray()) { throw new IllegalArgumentException(String.format("Expected json element to be a array type in the JSON string but got `%s`", jsonElement.toString())); @@ -411,6 +460,37 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im {{/items}} } {{/isArray}} + {{#isMap}} + if (!jsonElement.isJsonObject()) { + throw new IllegalArgumentException(String.format("Expected json element to be a object type in the JSON string but got `%s`", jsonElement.toString())); + } + + {{^isFreeFormObject}} + Map map = jsonElement.getAsJsonObject().asMap(); + // validate map items + for(JsonElement element : map.values()) { + {{#items}} + {{#isNumber}} + if (!jsonElement.getAsJsonPrimitive().isNumber()) { + throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); + } + {{/isNumber}} + {{^isNumber}} + {{#isPrimitiveType}} + if (!element.getAsJsonPrimitive().is{{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}}()) { + throw new IllegalArgumentException(String.format("Expected array items to be of type {{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}} in the JSON string but got `%s`", jsonElement.toString())); + } + {{/isPrimitiveType}} + {{/isNumber}} + {{^isNumber}} + {{^isPrimitiveType}} + {{{dataType}}}.validateJsonElement(element); + {{/isPrimitiveType}} + {{/isNumber}} + {{/items}} + } + {{/isFreeFormObject}} + {{/isMap}} {{/hasVars}} {{#hasVars}} {{{.}}}.validateJsonElement(jsonElement); diff --git a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pojo.mustache b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pojo.mustache index 5e5a5d9b..57598cdb 100644 --- a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pojo.mustache +++ b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pojo.mustache @@ -13,7 +13,6 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; -import java.lang.reflect.Type; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -59,25 +58,10 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens {{/isEnum}} public static final String SERIALIZED_NAME_{{nameInSnakeCase}} = "{{baseName}}"; {{#withXml}} - {{#isXmlAttribute}} - @XmlAttribute(name = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") - {{/isXmlAttribute}} - {{^isXmlAttribute}} - {{^isContainer}} - @XmlElement({{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}name = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") - {{/isContainer}} - {{#isContainer}} - // Is a container wrapped={{isXmlWrapped}} - {{#items}} - // items.name={{name}} items.baseName={{baseName}} items.xmlName={{xmlName}} items.xmlNamespace={{xmlNamespace}} - // items.example={{example}} items.type={{dataType}} - @XmlElement({{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}name = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") - {{/items}} - {{#isXmlWrapped}} - @XmlElementWrapper({{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}name = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}") - {{/isXmlWrapped}} - {{/isContainer}} - {{/isXmlAttribute}} + @Xml{{#isXmlAttribute}}Attribute{{/isXmlAttribute}}{{^isXmlAttribute}}Element{{/isXmlAttribute}}(name = "{{items.xmlName}}{{^items.xmlName}}{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}{{/items.xmlName}}"{{#xmlNamespace}}, namespace = "{{.}}"{{/xmlNamespace}}) + {{#isXmlWrapped}} + @XmlElementWrapper(name = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}"{{#xmlNamespace}}, namespace = "{{.}}"{{/xmlNamespace}}) + {{/isXmlWrapped}} {{/withXml}} {{#deprecated}} @Deprecated @@ -148,7 +132,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens {{/isMap}} {{/isReadOnly}} - /** + /** {{#description}} * {{.}} {{/description}} @@ -165,7 +149,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens {{#deprecated}} * @deprecated {{/deprecated}} - **/ + */ {{#deprecated}} @Deprecated {{/deprecated}} @@ -354,12 +338,12 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens {{/requiredVars}} } - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to {{classname}} - */ + /** + * Validates the JSON Element and throws an exception if issues found + * + * @param jsonElement JSON Element + * @throws IOException if the JSON Element is invalid with respect to {{classname}} + */ public static void validateJsonElement(JsonElement jsonElement) throws IOException { if (jsonElement == null) { if (!{{classname}}.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null @@ -585,22 +569,22 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens } {{/hasChildren}} - /** - * Create an instance of {{classname}} given an JSON string - * - * @param jsonString JSON string - * @return An instance of {{classname}} - * @throws IOException if the JSON string is invalid with respect to {{classname}} - */ + /** + * Create an instance of {{classname}} given an JSON string + * + * @param jsonString JSON string + * @return An instance of {{classname}} + * @throws IOException if the JSON string is invalid with respect to {{classname}} + */ public static {{{classname}}} fromJson(String jsonString) throws IOException { return JSON.getGson().fromJson(jsonString, {{{classname}}}.class); } - /** - * Convert an instance of {{classname}} to an JSON string - * - * @return JSON string - */ + /** + * Convert an instance of {{classname}} to an JSON string + * + * @return JSON string + */ public String toJson() { return JSON.getGson().toJson(this); } diff --git a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pom.mustache b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pom.mustache index ba88c570..f908f797 100644 --- a/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pom.mustache +++ b/generators/java/okhttp-gson/templates/libraries/okhttp-gson/pom.mustache @@ -395,14 +395,9 @@ {{/withAWSV4Signature}} - javax.ws.rs - jsr311-api - ${jsr311-api-version} - - - javax.ws.rs - javax.ws.rs-api - ${javax.ws.rs-api-version} + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta.ws.rs-api-version} @@ -429,7 +424,7 @@ {{#swagger2AnnotationLibrary}} 2.2.15 {{/swagger2AnnotationLibrary}} - 4.11.0 + 4.12.0 2.10.1 3.14.0 {{#openApiNullable}} @@ -440,19 +435,18 @@ {{/joda}} {{#useJakartaEe}} 2.1.1 + 3.0.2 {{/useJakartaEe}} {{^useJakartaEe}} 1.3.5 + 2.0.2 {{/useJakartaEe}} -{{#performBeanValidation}} + {{#performBeanValidation}} 3.0.3 -{{/performBeanValidation}} -{{#useBeanValidation}} - 3.0.2 -{{/useBeanValidation}} - 5.10.0 + {{/performBeanValidation}} + 5.10.3 1.10.0 - 2.1.1 + 2.1.6 1.1.1 UTF-8 2.43.0 diff --git a/generators/php/templates/ObjectSerializer.mustache b/generators/php/templates/ObjectSerializer.mustache index bfd1b836..664eaaf0 100644 --- a/generators/php/templates/ObjectSerializer.mustache +++ b/generators/php/templates/ObjectSerializer.mustache @@ -185,6 +185,10 @@ class ObjectSerializer case 'boolean': return !in_array($value, [false, 0], true); + # For string values, '' is considered empty. + case 'string': + return $value === ''; + # For all the other types, any value at this point can be considered empty. default: return true; @@ -256,6 +260,11 @@ class ObjectSerializer $value = $flattenArray($value, $paramName); + // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values + if ($openApiType === 'array' && $style === 'deepObject' && $explode) { + return $value; + } + if ($openApiType === 'object' && ($style === 'deepObject' || $explode)) { return $value; } diff --git a/generators/php/templates/SHA256SUM b/generators/php/templates/SHA256SUM index 1c63395d..c05cd4b7 100644 --- a/generators/php/templates/SHA256SUM +++ b/generators/php/templates/SHA256SUM @@ -1,6 +1,6 @@ bb92a3f3107664c296ebc45c75bff7c88abf8b765565f4656a05e24234cb6d67 ./Configuration.mustache -557173b27efb57eeba6187b8b64963a49964ade8f5f6418bd514ece483f392dd ./ObjectSerializer.mustache +76386901de81eba7d06fa8be77fc23e319bf7deb904cce3eea7edab7bdfb55ad ./ObjectSerializer.mustache 8eebaed003795c011df87fecd1f89c630dd3f23282d80e7f407f62009e2cd0ee ./README.mustache 2d94750ad5d913f8b7fbba24681c7cc1d75e96c89ec46c379e6625c825b39020 ./model_generic.mustache 37d3333c7c3dbc6f6bffe64ce076bc512a2a1e61e986738c8e023bb745168e9a ./phpunit.xml.mustache diff --git a/generators/python/urllib3/templates/SHA256SUM b/generators/python/urllib3/templates/SHA256SUM index c8a7d27b..fab4914b 100644 --- a/generators/python/urllib3/templates/SHA256SUM +++ b/generators/python/urllib3/templates/SHA256SUM @@ -1,7 +1,7 @@ 47fdf5141b3d999914c33faff1626c6ac2f00f87fcf9653814084f1dc67351d9 ./README.mustache 6a196e67020d765512f0c8c88afc39ef9d3cacdd50a9eba6731a6dbb1997c6e5 ./__init__package.mustache -e589dfcb5f8243b7e87998c012262d20db37c8dd985759232aad5e846bccd2bb ./configuration.mustache -5b0f4e5cf6a265530e0c63089e02c61b4b43e20a99859e615a4add2017479cdb ./pyproject.mustache -36cae3e3b78cb80e1bdcc3c3f30ff58dc03d04561ed1559a92bfb07b934a8cf2 ./rest.mustache -911e968c3503210fccd044a47de5dc833564ac41d08e3f386cd88d772cfa1488 ./setup.mustache +2001a188ffeaeb931e2272f56445bfdb83f078bf2deeb7868021d8a321c3ce8f ./configuration.mustache +5e1131256ad0adbae73204efd8932db30b808b99cfd2ffde6be6ec60ed690fac ./pyproject.mustache +47d0cfca6043fc2c8bd2b5a09704e22b6a412c9ed425c3a83b6ab719cc129986 ./rest.mustache +bdd482446d4f3601bebe6fb59dba40748d9e59dc709e9033a354802ff8187eeb ./setup.mustache diff --git a/generators/python/urllib3/templates/configuration.mustache b/generators/python/urllib3/templates/configuration.mustache index 7cef1857..39318218 100644 --- a/generators/python/urllib3/templates/configuration.mustache +++ b/generators/python/urllib3/templates/configuration.mustache @@ -51,6 +51,7 @@ class Configuration: values before. :param ssl_ca_cert: str - the path to a file of concatenated CA certificates in PEM format. + :param retries: Number of retries for API requests. {{#hasAuthMethods}} :Example: @@ -149,7 +150,11 @@ conf = {{{packageName}}}.Configuration( {{/hasHttpSignatureMethods}} server_index=None, server_operation_index=None, server_operation_variables=None, + ignore_operation_servers=False, ssl_ca_cert=None, + retries=None, + *, + debug: Optional[bool] = None ) -> None: """Constructor """ @@ -166,6 +171,9 @@ conf = {{{packageName}}}.Configuration( self.server_operation_variables = server_operation_variables or {} """Default server variables """ + self.ignore_operation_servers = ignore_operation_servers + """Ignore operation servers + """ self.temp_folder_path = None """Temp file folder for downloading files """ @@ -203,7 +211,10 @@ conf = {{{packageName}}}.Configuration( self.logger_file = None """Debug file location """ - self.debug = False + if debug is not None: + self.debug = debug + else: + self.__debug = False """Debug switch """ @@ -254,7 +265,7 @@ conf = {{{packageName}}}.Configuration( self.safe_chars_for_path_param = '' """Safe chars for path_param """ - self.retries = None + self.retries = retries """Adding retries to override urllib3 default value 3 """ # Enable client side validation diff --git a/generators/python/urllib3/templates/pyproject.mustache b/generators/python/urllib3/templates/pyproject.mustache index eb4a409a..19011ccd 100644 --- a/generators/python/urllib3/templates/pyproject.mustache +++ b/generators/python/urllib3/templates/pyproject.mustache @@ -5,40 +5,40 @@ description = "Python library for the Onfido API" {{! customized authors = ["OpenAPI Generator Community <{{infoEmail}}{{^infoEmail}}team@openapitools.org{{/infoEmail}}>"] {{! removed infoName field since wronlgy set }} license = "{{{licenseInfo}}}{{^licenseInfo}}NoLicense{{/licenseInfo}}" readme = "README.md" -repository = "https://github.com/{{{gitUserId}}}/{{{gitRepoId}}}" +repository = "https://{{{gitHost}}}/{{{gitUserId}}}/{{{gitRepoId}}}" keywords = ["OpenAPI", "OpenAPI-Generator", "onfido", "identity"] {{! cutomized keywords }} include = ["{{packageName}}/py.typed"] -packages = [{ include = "{{{packageName}}}" }] {{! Added section }} [tool.poetry.urls] "Onfido API documentation" = "{{ documentationUrl }}" [tool.poetry.dependencies] -python = "^3.7" +python = "^3.8" -urllib3 = ">= 1.25.3" -python-dateutil = ">=2.8.2" +urllib3 = ">= 1.25.3 < 3.0.0" +python-dateutil = ">= 2.8.2" {{#asyncio}} aiohttp = ">= 3.8.4" aiohttp-retry = ">= 2.8.3" {{/asyncio}} {{#tornado}} -tornado = ">=4.2,<5" +tornado = ">=4.2 <5" {{/tornado}} {{#hasHttpSignatureMethods}} pem = ">= 19.3.0" pycryptodome = ">= 3.9.0" {{/hasHttpSignatureMethods}} -pydantic = ">=2" -typing-extensions = ">=4.7.1" +pydantic = ">= 2" +typing-extensions = ">= 4.7.1" [tool.poetry.dev-dependencies] -pytest = ">=7.2.1" -tox = ">=3.9.0" -flake8 = ">=4.0.0" -types-python-dateutil = ">=2.8.19.14" -mypy = "1.4.1" +pytest = ">= 7.2.1" +pytest-cov = ">= 2.8.1" +tox = ">= 3.9.0" +flake8 = ">= 4.0.0" +types-python-dateutil = ">= 2.8.19.14" +mypy = ">= 1.5" [build-system] diff --git a/generators/python/urllib3/templates/rest.mustache b/generators/python/urllib3/templates/rest.mustache index 5ea2d1c1..4c3621cb 100644 --- a/generators/python/urllib3/templates/rest.mustache +++ b/generators/python/urllib3/templates/rest.mustache @@ -171,7 +171,7 @@ class RESTClientObject: ): request_body = None if body is not None: - request_body = json.dumps(body) + request_body = json.dumps(body{{#setEnsureAsciiToFalse}}, ensure_ascii=False{{/setEnsureAsciiToFalse}}) r = self.pool_manager.request( method, url, @@ -218,7 +218,7 @@ class RESTClientObject: headers=headers, preload_content=False ) - elif headers['Content-Type'] == 'text/plain' and isinstance(body, bool): + elif headers['Content-Type'].startswith('text/') and isinstance(body, bool): request_body = "true" if body else "false" r = self.pool_manager.request( method, diff --git a/generators/python/urllib3/templates/setup.mustache b/generators/python/urllib3/templates/setup.mustache index d9826d53..e8363240 100644 --- a/generators/python/urllib3/templates/setup.mustache +++ b/generators/python/urllib3/templates/setup.mustache @@ -12,23 +12,23 @@ from setuptools import setup, find_packages # noqa: H301 # http://pypi.python.org/pypi/setuptools NAME = "{{{projectName}}}-python" {{! package name updated with -python suffix }} VERSION = "{{packageVersion}}" -PYTHON_REQUIRES = ">=3.7" +PYTHON_REQUIRES = ">= 3.8" {{#apiInfo}} {{#apis}} {{#-last}} REQUIRES = [ - "urllib3 >= 1.25.3, < 2.1.0", - "python-dateutil", + "urllib3 >= 1.25.3, < 3.0.0", + "python-dateutil >= 2.8.2", {{#asyncio}} - "aiohttp >= 3.0.0", + "aiohttp >= 3.8.4", "aiohttp-retry >= 2.8.3", {{/asyncio}} {{#tornado}} - "tornado>=4.2,<5", + "tornado>=4.2, < 5", {{/tornado}} {{#hasHttpSignatureMethods}} - "pem>=19.3.0", - "pycryptodome>=3.9.0", + "pem >= 19.3.0", + "pycryptodome >= 3.9.0", {{/hasHttpSignatureMethods}} "pydantic >= 2", "typing-extensions >= 4.7.1", diff --git a/generators/ruby/faraday/templates/SHA256SUM b/generators/ruby/faraday/templates/SHA256SUM index e474fcb8..65cb70b2 100644 --- a/generators/ruby/faraday/templates/SHA256SUM +++ b/generators/ruby/faraday/templates/SHA256SUM @@ -1,5 +1,5 @@ 631eea1aeb59eff826cd4975334d66bdf7ad14d3feacdf35ed5b07f33548981e ./Gemfile.mustache -88dc22838f416232553b387453a2ebecf01d66508d8657d5313320cc03ceb6a2 ./README.mustache -b9af426fa4b72082dad184722e97c61366cceab0d247b477b2834e38aa6c3411 ./configuration.mustache +0394740e8dc344748f61724a7fb304c23daf1e66922efa995c195968a0919ef4 ./README.mustache +8d952d2c3d4d49e0811a470b7e5e8c7c8dc798cf2f32e69d4501fc26be91a29a ./configuration.mustache e66f0139c35c8b1d88c19787b2379ee9e6857ced963624c9a945ee68f3b41b2f ./gemspec.mustache diff --git a/generators/ruby/faraday/templates/configuration.mustache b/generators/ruby/faraday/templates/configuration.mustache index 096394b3..d782bcf0 100644 --- a/generators/ruby/faraday/templates/configuration.mustache +++ b/generators/ruby/faraday/templates/configuration.mustache @@ -81,6 +81,14 @@ module {{moduleName}} # @return [true, false] attr_accessor :debugging + # Set this to ignore operation servers for the API client. This is useful when you need to + # send requests to a different server than the one specified in the OpenAPI document. + # Will default to the base url defined in the spec but can be overridden by setting + # `scheme`, `host`, `base_path` directly. + # Default to false. + # @return [true, false] + attr_accessor :ignore_operation_servers + # Defines the logger used for debugging. # Default to `Rails.logger` (when in Rails) or logging to STDOUT. # @@ -157,6 +165,7 @@ module {{moduleName}} @configure_session_blocks = [] {{/isHttpx}} @debugging = false + @ignore_operation_servers = false @inject_format = false @force_ending_format = false @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT) @@ -193,6 +202,7 @@ module {{moduleName}} # Returns base URL for specified operation based on server settings def base_url(operation = nil) + return "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '') if ignore_operation_servers if operation_server_settings.key?(operation) then index = server_operation_index.fetch(operation, server_index) server_url(index.nil? ? 0 : index, server_operation_variables.fetch(operation, server_variables), operation_server_settings[operation]) @@ -253,7 +263,7 @@ module {{moduleName}} type: 'api_key', in: {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}}, key: '{{keyParamName}}', - value: api_key_with_prefix('{{name}}'{{#vendorExtensions.x-auth-id-alias}}, '{{.}}'{{/vendorExtensions.x-auth-id-alias}}) + value: api_key_with_prefix('{{name}}'{{#vendorExtensions.x-auth-id-alias}}, '{{.}}'{{/vendorExtensions.x-auth-id-alias}}){{! Use name instead of keyParamName }} }, {{/isApiKey}} {{#isBasic}} diff --git a/generators/typescript-axios/config.yaml b/generators/typescript-axios/config.yaml index 4d062529..7670c16d 100644 --- a/generators/typescript-axios/config.yaml +++ b/generators/typescript-axios/config.yaml @@ -4,6 +4,7 @@ npmVersion: ${CLIENT_LIBRARY_VERSION} enumUnknownDefaultCase: true supportsES6: true withNodeImports: true +axiosVersion: ^1.7.4 httpUserAgent: onfido-node/${CLIENT_LIBRARY_VERSION} # Type mapping doesn't work with this generator # typeMappings: diff --git a/generators/typescript-axios/templates/SHA256SUM b/generators/typescript-axios/templates/SHA256SUM index aa7bea21..636ad183 100644 --- a/generators/typescript-axios/templates/SHA256SUM +++ b/generators/typescript-axios/templates/SHA256SUM @@ -1,8 +1,8 @@ e13ee7c0cad9a79bab00e8b2a7942bc5a78f63115ece3dfd71a6472bdb02dd22 ./README.mustache 3a077701e62c4d0942657c78cf0116cbe58436e34d723d81aaed7ed0d56d2ed1 ./api.mustache -0f4ea3b4db29a3bbada4c5ad5e4b08fa598305ba09aa29d237edee1634f8805b ./apiInner.mustache +00efb349f77aed31bd52a6cea64d3b32d4713bc24399b377883ec28b5b38b24a ./apiInner.mustache d8d68213e1a9a9983f89f688aaf31360f69d34a871cab4fc94f59a40279b13d9 ./configuration.mustache 5030fcd1954b4d981f2d06fce4900fe29c97c7b74ee66f2eb5f45e81b9252a94 ./index.mustache -28f5e210e99474200c8e5f13e4f2374c1556406eb71c15e808d81913000cd549 ./package.mustache +62bbc44c32ed454a215fc76636eaca819f012b65486485fda7499f7937557cc4 ./package.mustache 89b381b068d1849cc98721643c923ee153a5bdd69e19306dda59114ba0a2e243 ./tsconfig.mustache diff --git a/generators/typescript-axios/templates/apiInner.mustache b/generators/typescript-axios/templates/apiInner.mustache index 51dfc34a..c8418d85 100644 --- a/generators/typescript-axios/templates/apiInner.mustache +++ b/generators/typescript-axios/templates/apiInner.mustache @@ -194,12 +194,12 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur {{/contentType}} {{^contentType}} {{paramName}}.forEach((element) => { - localVarFormParams.{{#multipartFormData}}append{{/multipartFormData}}{{^multipartFormData}}set{{/multipartFormData}}('{{baseName}}', element as any); + localVarFormParams.{{#multipartFormData}}append{{/multipartFormData}}{{^multipartFormData}}set{{/multipartFormData}}('{{baseName}}{{#useSquareBracketsInArrayNames}}[]{{/useSquareBracketsInArrayNames}}', element as any); }) {{/contentType}} {{/isCollectionFormatMulti}} {{^isCollectionFormatMulti}} - localVarFormParams.{{#multipartFormData}}append{{/multipartFormData}}{{^multipartFormData}}set{{/multipartFormData}}('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}})); + localVarFormParams.{{#multipartFormData}}append{{/multipartFormData}}{{^multipartFormData}}set{{/multipartFormData}}('{{baseName}}{{#useSquareBracketsInArrayNames}}[]{{/useSquareBracketsInArrayNames}}', {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}})); {{/isCollectionFormatMulti}} }{{/isArray}} {{^isArray}} @@ -309,7 +309,7 @@ export const {{classname}}Factory = function (configuration?: Configuration, bas }, {{/useSingleRequestParameter}} {{^useSingleRequestParameter}} - {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: any): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}> { + {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}> { return localVarFp.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options).then((request) => request(axios, basePath)); }, {{/useSingleRequestParameter}} @@ -331,15 +331,27 @@ export interface {{classname}}Interface { {{#summary}} * @summary {{&summary}} {{/summary}} + {{#useSingleRequestParameter}} + {{#allParams.0}} + * @param {{=<% %>=}}{<%& classname %><%& operationIdCamelCase %>Request}<%={{ }}=%> requestParameters Request parameters. + {{/allParams.0}} + {{/useSingleRequestParameter}} + {{^useSingleRequestParameter}} {{#allParams}} * @param {{=<% %>=}}{<%#isEnum%><%&datatypeWithEnum%><%/isEnum%><%^isEnum%><%&dataType%><%#isNullable%> | null<%/isNullable%><%/isEnum%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}} {{description}} {{/allParams}} + {{/useSingleRequestParameter}} * @param {*} [options] Override http request option.{{#isDeprecated}} * @deprecated{{/isDeprecated}} * @throws {RequiredError} * @memberof {{classname}}Interface */ + {{#useSingleRequestParameter}} + {{nickname}}({{#allParams.0}}requestParameters{{^hasRequiredParams}}?{{/hasRequiredParams}}: {{classname}}{{operationIdCamelCase}}Request, {{/allParams.0}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}>; + {{/useSingleRequestParameter}} + {{^useSingleRequestParameter}} {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}>; + {{/useSingleRequestParameter}} {{/operation}} } @@ -454,4 +466,4 @@ export type {{operationIdCamelCase}}{{enumName}} = typeof {{operationIdCamelCase {{/isEnum}} {{/allParams}} {{/operation}} -{{/operations}} +{{/operations}} \ No newline at end of file diff --git a/generators/typescript-axios/templates/package.mustache b/generators/typescript-axios/templates/package.mustache index 98448292..711cb54e 100644 --- a/generators/typescript-axios/templates/package.mustache +++ b/generators/typescript-axios/templates/package.mustache @@ -51,7 +51,7 @@ } }, "dependencies": { - "axios": "^1.7.4" {{! Updated minimum Axios version to solve Dependabot alert }} + "axios": "{{axiosVersion}}" }, "devDependencies": { {{! Added dependencies for tests development - BEGIN }} diff --git a/shell/generate.sh b/shell/generate.sh index 87dfbce9..30480c8e 100755 --- a/shell/generate.sh +++ b/shell/generate.sh @@ -10,7 +10,7 @@ COMMON_CONFIG_FILE="generators/common/config.yaml" GENERATORS=${*:-`find generators -name 'config.yaml' -exec dirname {} \; | sed 's/generators\///'`} GENERATED_CONFIG_FILES="" -OPENAPI_GENERATOR_VERSION=${OPENAPI_GENERATOR_VERSION:-v7.6.0} +OPENAPI_GENERATOR_VERSION=${OPENAPI_GENERATOR_VERSION:-v7.9.0} OPENAPI_GENERATOR_COMMAND=${OPENAPI_GENERATOR_COMMAND:-\ docker run --rm -v "$(pwd):/local" -w /local \ openapitools/openapi-generator-cli:${OPENAPI_GENERATOR_VERSION}} @@ -57,6 +57,7 @@ function semver_bump() { } function validate_templates_checksum() { + OVERRIDE_COMMAND="" GENERATOR_NAME=$1 LIBRARY_NAME=$2 LIBRARY="" @@ -88,12 +89,9 @@ function validate_templates_checksum() { then if [ ! -z "$OUR_SHASUM" ] && [[ "$LIB_SHASUM" != "$OUR_SHASUM" ]]; # We do have checksum and doesn't match then - echo -e "\n################################################################################\n" - echo -e " !!! Error while building generator ${GENERATOR}!!!\n" - echo " SHA256SUM for template $FILENAME changed, diff reported below. To overwrite template, run:" - echo " cp generated/templates/${GENERATOR}/$FILENAME generators/${GENERATOR}/templates/" - echo - diff ${GENERATED_PATH}/$FILENAME ${GENERATORS_PATH}/$FILENAME || true + LIBRARY_TEMPLATE="generated/templates/${GENERATOR}/$(echo $FILENAME | sed 's/^\.\///')" + TEMPLATE_SUBPATH="$(dirname $FILENAME/ | sed -E 's/^\.\/?//' )" + OVERRIDE_COMMAND="${OVERRIDE_COMMAND}\n\tcp ${LIBRARY_TEMPLATE} generators/${GENERATOR}/templates/${TEMPLATE_SUBPATH}" RESULT=1 fi @@ -111,6 +109,14 @@ function validate_templates_checksum() { mv ${GENERATORS_PATH}/SHA256SUM.new ${GENERATORS_PATH}/SHA256SUM fi + if [ "$RESULT" -ne "0" ]; + then + echo -e "\n################################################################################\n" + echo -e "ERROR while building generator ${GENERATOR}: SHA256SUM for template(s) changed with OpenAPI generator ${OPENAPI_GENERATOR_VERSION}!\n" + echo -e "Please overwrite the template(s) and carefully check what has changed by running:\n${OVERRIDE_COMMAND}\n" + echo -e "\tgit add -p generators/${GENERATOR}/templates/\n" + fi + return $RESULT }