From a8015ad8c1ce07cb2582b64e377b3a8856bfa2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85smund=20Grammeltvedt?= Date: Mon, 10 Feb 2020 07:47:29 +0100 Subject: [PATCH] [typescript] Make additional properties access safer (#5207) * [typescript-fetch] Make additional properties access safer Instead of asserting that any key access returns a valid property, force the consumer to check that the value is defined. * Update tests * Put null-safe additional props behind and flag and share * Undo over copy * Update docs * Rearrange code * Move to unit tests --- docs/generators/javascript-flowtyped.md | 1 + docs/generators/typescript-angular.md | 1 + docs/generators/typescript-angularjs.md | 1 + docs/generators/typescript-aurelia.md | 1 + docs/generators/typescript-axios.md | 1 + docs/generators/typescript-fetch.md | 1 + docs/generators/typescript-inversify.md | 1 + docs/generators/typescript-jquery.md | 1 + docs/generators/typescript-node.md | 1 + docs/generators/typescript-redux-query.md | 1 + docs/generators/typescript-rxjs.md | 1 + .../AbstractTypeScriptClientCodegen.java | 19 +++++++++++++++++- .../TypeScriptFetchClientCodegen.java | 9 +-------- .../TypeScriptReduxQueryClientCodegen.java | 9 +-------- .../TypeScriptRxjsClientCodegen.java | 9 +-------- ...ypeScriptAngularClientOptionsProvider.java | 3 +++ ...eScriptAngularJsClientOptionsProvider.java | 3 +++ ...ypeScriptAureliaClientOptionsProvider.java | 3 +++ .../TypeScriptFetchClientOptionsProvider.java | 3 +++ .../TypeScriptNodeClientOptionsProvider.java | 3 +++ .../fetch/TypeScriptFetchModelTest.java | 20 +++++++++++++++++++ .../dart2/openapi/.openapi-generator/VERSION | 2 +- 22 files changed, 68 insertions(+), 26 deletions(-) diff --git a/docs/generators/javascript-flowtyped.md b/docs/generators/javascript-flowtyped.md index 125b0778a84..a76a585a9bc 100644 --- a/docs/generators/javascript-flowtyped.md +++ b/docs/generators/javascript-flowtyped.md @@ -13,6 +13,7 @@ sidebar_label: javascript-flowtyped |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-angular.md b/docs/generators/typescript-angular.md index 654963adc7f..587ee3ae4b1 100644 --- a/docs/generators/typescript-angular.md +++ b/docs/generators/typescript-angular.md @@ -18,6 +18,7 @@ sidebar_label: typescript-angular |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |providedInRoot|Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).| |false| |serviceFileSuffix|The suffix of the file of the generated service (service<suffix>.ts).| |.service| diff --git a/docs/generators/typescript-angularjs.md b/docs/generators/typescript-angularjs.md index 2fcbf81476e..dbc6a2a64c1 100644 --- a/docs/generators/typescript-angularjs.md +++ b/docs/generators/typescript-angularjs.md @@ -10,6 +10,7 @@ sidebar_label: typescript-angularjs |enumNameSuffix|Suffix that will be appended to all enum names. A special 'v4-compat' value enables the backward-compatible behavior (as pre v4.2.3)| |v4-compat| |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |PascalCase| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-aurelia.md b/docs/generators/typescript-aurelia.md index e12293e9562..27bde7c6f21 100644 --- a/docs/generators/typescript-aurelia.md +++ b/docs/generators/typescript-aurelia.md @@ -12,6 +12,7 @@ sidebar_label: typescript-aurelia |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-axios.md b/docs/generators/typescript-axios.md index 961fa500dd3..b5d27f7a6ad 100644 --- a/docs/generators/typescript-axios.md +++ b/docs/generators/typescript-axios.md @@ -13,6 +13,7 @@ sidebar_label: typescript-axios |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url of your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-fetch.md b/docs/generators/typescript-fetch.md index 933dce1f141..75ed9fedb0e 100644 --- a/docs/generators/typescript-fetch.md +++ b/docs/generators/typescript-fetch.md @@ -13,6 +13,7 @@ sidebar_label: typescript-fetch |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prefixParameterInterfaces|Setting this property to true will generate parameter interface declarations prefixed with API class name to avoid name conflicts.| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| diff --git a/docs/generators/typescript-inversify.md b/docs/generators/typescript-inversify.md index e4daf3bb9e8..b607f548eb8 100644 --- a/docs/generators/typescript-inversify.md +++ b/docs/generators/typescript-inversify.md @@ -13,6 +13,7 @@ sidebar_label: typescript-inversify |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-jquery.md b/docs/generators/typescript-jquery.md index 3f28481c3e2..e0669652e13 100644 --- a/docs/generators/typescript-jquery.md +++ b/docs/generators/typescript-jquery.md @@ -14,6 +14,7 @@ sidebar_label: typescript-jquery |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-node.md b/docs/generators/typescript-node.md index 54eee1ac863..5bc56aa7890 100644 --- a/docs/generators/typescript-node.md +++ b/docs/generators/typescript-node.md @@ -13,6 +13,7 @@ sidebar_label: typescript-node |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-redux-query.md b/docs/generators/typescript-redux-query.md index b46f0fafe58..eae6cc52892 100644 --- a/docs/generators/typescript-redux-query.md +++ b/docs/generators/typescript-redux-query.md @@ -13,6 +13,7 @@ sidebar_label: typescript-redux-query |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/docs/generators/typescript-rxjs.md b/docs/generators/typescript-rxjs.md index 7cbfaf70210..e6715137116 100644 --- a/docs/generators/typescript-rxjs.md +++ b/docs/generators/typescript-rxjs.md @@ -13,6 +13,7 @@ sidebar_label: typescript-rxjs |npmName|The name under which you want to publish generated npm package. Required to generate a full package| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0| +|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false| |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java index 75a7c18c783..ef1b689b7af 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java @@ -55,6 +55,8 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp public static final String ENUM_NAME_SUFFIX_DESC_CUSTOMIZED = CodegenConstants.ENUM_NAME_SUFFIX_DESC + " A special '" + ENUM_NAME_SUFFIX_V4_COMPAT + "' value enables the backward-compatible behavior (as pre v4.2.3)"; + public static final String NULL_SAFE_ADDITIONAL_PROPS = "nullSafeAdditionalProps"; + public static final String NULL_SAFE_ADDITIONAL_PROPS_DESC = "Set to make additional properties types declare that their indexer may return undefined"; // NOTE: SimpleDateFormat is not thread-safe and may not be static unless it is thread-local @SuppressWarnings("squid:S5164") @@ -63,6 +65,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp protected String modelPropertyNaming = "camelCase"; protected ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = ENUM_PROPERTY_NAMING_TYPE.PascalCase; protected Boolean supportsES6 = false; + protected Boolean nullSafeAdditionalProps = false; protected HashSet languageGenericTypes; protected String npmName = null; protected String npmVersion = "1.0.0"; @@ -174,6 +177,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp this.cliOptions.add(CliOption.newBoolean(SNAPSHOT, "When setting this property to true, the version will be suffixed with -SNAPSHOT." + this.SNAPSHOT_SUFFIX_FORMAT.get().toPattern(), false)); + this.cliOptions.add(new CliOption(NULL_SAFE_ADDITIONAL_PROPS, NULL_SAFE_ADDITIONAL_PROPS_DESC).defaultValue(String.valueOf(this.getNullSafeAdditionalProps()))); } @@ -204,6 +208,10 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp additionalProperties.put("supportsES6", getSupportsES6()); } + if (additionalProperties.containsKey(NULL_SAFE_ADDITIONAL_PROPS)) { + setNullSafeAdditionalProps(Boolean.valueOf(additionalProperties.get(NULL_SAFE_ADDITIONAL_PROPS).toString())); + } + if (additionalProperties.containsKey(NPM_NAME)) { this.setNpmName(additionalProperties.get(NPM_NAME).toString()); } @@ -380,7 +388,8 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">"; } else if (ModelUtils.isMapSchema(p)) { Schema inner = ModelUtils.getAdditionalProperties(p); - return "{ [key: string]: " + getTypeDeclaration(inner) + "; }"; + String nullSafeSuffix = getNullSafeAdditionalProps() ? " | undefined" : ""; + return "{ [key: string]: " + getTypeDeclaration(inner) + nullSafeSuffix + "; }"; } else if (ModelUtils.isFileSchema(p)) { return "any"; } else if (ModelUtils.isBinarySchema(p)) { @@ -723,6 +732,14 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp return supportsES6; } + public Boolean getNullSafeAdditionalProps() { + return nullSafeAdditionalProps; + } + + public void setNullSafeAdditionalProps(Boolean value) { + nullSafeAdditionalProps = value; + } + public String getNpmName() { return npmName; } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java index 7e6bdd3d131..d4f7e979de5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java @@ -134,14 +134,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege @Override public String getTypeDeclaration(Schema p) { - Schema inner; - if (ModelUtils.isArraySchema(p)) { - inner = ((ArraySchema) p).getItems(); - return this.getSchemaType(p) + "<" + this.getTypeDeclaration(inner) + ">"; - } else if (ModelUtils.isMapSchema(p)) { - inner = ModelUtils.getAdditionalProperties(p); - return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }"; - } else if (ModelUtils.isFileSchema(p)) { + if (ModelUtils.isFileSchema(p)) { return "Blob"; } else if (ModelUtils.isBinarySchema(p)) { return "Blob"; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptReduxQueryClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptReduxQueryClientCodegen.java index 020752f84a0..ac7c0d8d240 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptReduxQueryClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptReduxQueryClientCodegen.java @@ -103,14 +103,7 @@ public class TypeScriptReduxQueryClientCodegen extends AbstractTypeScriptClientC @Override public String getTypeDeclaration(Schema p) { - Schema inner; - if (ModelUtils.isArraySchema(p)) { - inner = ((ArraySchema) p).getItems(); - return this.getSchemaType(p) + "<" + this.getTypeDeclaration(inner) + ">"; - } else if (ModelUtils.isMapSchema(p)) { - inner = ModelUtils.getAdditionalProperties(p); - return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }"; - } else if (ModelUtils.isFileSchema(p)) { + if (ModelUtils.isFileSchema(p)) { return "Blob"; } else if (ModelUtils.isBinarySchema(p)) { return "Blob"; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptRxjsClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptRxjsClientCodegen.java index b2f2dc213d3..fb421d1255d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptRxjsClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptRxjsClientCodegen.java @@ -109,14 +109,7 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen @Override public String getTypeDeclaration(Schema p) { - Schema inner; - if (ModelUtils.isArraySchema(p)) { - inner = ((ArraySchema) p).getItems(); - return this.getSchemaType(p) + "<" + this.getTypeDeclaration(inner) + ">"; - } else if (ModelUtils.isMapSchema(p)) { - inner = ModelUtils.getAdditionalProperties(p); - return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }"; - } else if (ModelUtils.isFileSchema(p)) { + if (ModelUtils.isFileSchema(p)) { return "Blob"; } else if (ModelUtils.isBinarySchema(p)) { return "Blob"; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java index d65ba459df6..5635465a632 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java @@ -19,12 +19,14 @@ package org.openapitools.codegen.options; import com.google.common.collect.ImmutableMap; import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import java.util.Map; public class TypeScriptAngularClientOptionsProvider implements OptionsProvider { public static final String SUPPORTS_ES6_VALUE = "false"; + public static final String NULL_SAFE_ADDITIONAL_PROPS_VALUE = "false"; public static final String ENUM_NAME_SUFFIX = "Enum"; public static final String STRING_ENUMS_VALUE = "false"; public static final String SORT_PARAMS_VALUE = "false"; @@ -59,6 +61,7 @@ public class TypeScriptAngularClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.ENUM_PROPERTY_NAMING, ENUM_PROPERTY_NAMING_VALUE) .put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE) .put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE) + .put(AbstractTypeScriptClientCodegen.NULL_SAFE_ADDITIONAL_PROPS, NULL_SAFE_ADDITIONAL_PROPS_VALUE) .put(CodegenConstants.ENUM_NAME_SUFFIX, ENUM_NAME_SUFFIX) .put(TypeScriptAngularClientCodegen.STRING_ENUMS, STRING_ENUMS_VALUE) .put(TypeScriptAngularClientCodegen.NPM_NAME, NMP_NAME) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularJsClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularJsClientOptionsProvider.java index 11aa70a681a..2ab399a12bb 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularJsClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularJsClientOptionsProvider.java @@ -19,11 +19,13 @@ package org.openapitools.codegen.options; import com.google.common.collect.ImmutableMap; import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen; import java.util.Map; public class TypeScriptAngularJsClientOptionsProvider implements OptionsProvider { public static final String SUPPORTS_ES6_VALUE = "false"; + public static final String NULL_SAFE_ADDITIONAL_PROPS_VALUE = "false"; public static final String ENUM_NAME_SUFFIX = "Enum"; public static final String SORT_PARAMS_VALUE = "false"; public static final String SORT_MODEL_PROPERTIES_VALUE = "false"; @@ -44,6 +46,7 @@ public class TypeScriptAngularJsClientOptionsProvider implements OptionsProvider return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE) .put(CodegenConstants.SORT_MODEL_PROPERTIES_BY_REQUIRED_FLAG, SORT_MODEL_PROPERTIES_VALUE) .put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE) + .put(AbstractTypeScriptClientCodegen.NULL_SAFE_ADDITIONAL_PROPS, NULL_SAFE_ADDITIONAL_PROPS_VALUE) .put(CodegenConstants.ENUM_NAME_SUFFIX, ENUM_NAME_SUFFIX) .put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE) .put(CodegenConstants.ENUM_PROPERTY_NAMING, ENUM_PROPERTY_NAMING_VALUE) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAureliaClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAureliaClientOptionsProvider.java index 2ec182979cc..9c72ca44ab9 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAureliaClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAureliaClientOptionsProvider.java @@ -20,6 +20,7 @@ package org.openapitools.codegen.options; import com.google.common.collect.ImmutableMap; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.languages.TypeScriptAureliaClientCodegen; +import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen; import java.util.Map; @@ -28,6 +29,7 @@ public class TypeScriptAureliaClientOptionsProvider implements OptionsProvider { public static final String SORT_MODEL_PROPERTIES_VALUE = "false"; public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true"; public static final Boolean SUPPORTS_ES6_VALUE = false; + public static final Boolean NULL_SAFE_ADDITIONAL_PROPS_VALUE = false; public static final String ENUM_NAME_SUFFIX = "Enum"; public static final String ENUM_PROPERTY_NAMING_VALUE = "PascalCase"; public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase"; @@ -50,6 +52,7 @@ public class TypeScriptAureliaClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.ENUM_PROPERTY_NAMING, ENUM_PROPERTY_NAMING_VALUE) .put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE) .put(CodegenConstants.SUPPORTS_ES6, String.valueOf(SUPPORTS_ES6_VALUE)) + .put(AbstractTypeScriptClientCodegen.NULL_SAFE_ADDITIONAL_PROPS, String.valueOf(NULL_SAFE_ADDITIONAL_PROPS_VALUE)) .put(CodegenConstants.ENUM_NAME_SUFFIX, ENUM_NAME_SUFFIX) .put(TypeScriptAureliaClientCodegen.NPM_NAME, NPM_NAME) .put(TypeScriptAureliaClientCodegen.NPM_VERSION, NPM_VERSION) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java index fe637cfe52b..196e220fb32 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptFetchClientOptionsProvider.java @@ -20,6 +20,7 @@ package org.openapitools.codegen.options; import com.google.common.collect.ImmutableMap; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.languages.TypeScriptFetchClientCodegen; +import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen; import java.util.Map; @@ -28,6 +29,7 @@ public class TypeScriptFetchClientOptionsProvider implements OptionsProvider { public static final String SORT_MODEL_PROPERTIES_VALUE = "false"; public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true"; public static final Boolean SUPPORTS_ES6_VALUE = false; + public static final Boolean NULL_SAFE_ADDITIONAL_PROPS_VALUE = false; public static final String ENUM_NAME_SUFFIX = "Enum"; public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase"; public static final String ENUM_PROPERTY_NAMING_VALUE = "PascalCase"; @@ -52,6 +54,7 @@ public class TypeScriptFetchClientOptionsProvider implements OptionsProvider { .put(CodegenConstants.ENUM_PROPERTY_NAMING, ENUM_PROPERTY_NAMING_VALUE) .put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE) .put(CodegenConstants.SUPPORTS_ES6, String.valueOf(SUPPORTS_ES6_VALUE)) + .put(AbstractTypeScriptClientCodegen.NULL_SAFE_ADDITIONAL_PROPS, String.valueOf(NULL_SAFE_ADDITIONAL_PROPS_VALUE)) .put(CodegenConstants.ENUM_NAME_SUFFIX, ENUM_NAME_SUFFIX) .put(TypeScriptFetchClientCodegen.NPM_NAME, NMP_NAME) .put(TypeScriptFetchClientCodegen.NPM_VERSION, NMP_VERSION) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptNodeClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptNodeClientOptionsProvider.java index a369f1a2f56..23da17ea1c4 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptNodeClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptNodeClientOptionsProvider.java @@ -19,6 +19,7 @@ package org.openapitools.codegen.options; import com.google.common.collect.ImmutableMap; import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.languages.AbstractTypeScriptClientCodegen; import org.openapitools.codegen.languages.TypeScriptAngularClientCodegen; import java.util.Map; @@ -26,6 +27,7 @@ import java.util.Map; public class TypeScriptNodeClientOptionsProvider implements OptionsProvider { public static final String SUPPORTS_ES6_VALUE = "false"; + public static final String NULL_SAFE_ADDITIONAL_PROPS_VALUE = "false"; public static final String ENUM_NAME_SUFFIX = "Enum"; public static final String SORT_PARAMS_VALUE = "false"; public static final String SORT_MODEL_PROPERTIES_VALUE = "false"; @@ -50,6 +52,7 @@ public class TypeScriptNodeClientOptionsProvider implements OptionsProvider { return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE) .put(CodegenConstants.SORT_MODEL_PROPERTIES_BY_REQUIRED_FLAG, SORT_MODEL_PROPERTIES_VALUE) .put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE) + .put(AbstractTypeScriptClientCodegen.NULL_SAFE_ADDITIONAL_PROPS, NULL_SAFE_ADDITIONAL_PROPS_VALUE) .put(CodegenConstants.ENUM_NAME_SUFFIX, ENUM_NAME_SUFFIX) .put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE) .put(CodegenConstants.ENUM_PROPERTY_NAMING, ENUM_PROPERTY_NAMING_VALUE) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java index ec451b308d3..1cd429fbeb9 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchModelTest.java @@ -294,4 +294,24 @@ public class TypeScriptFetchModelTest { } + @Test(description = "Add null safe additional property indexer when enabled") + public void testNullSafeAdditionalProps() { + final Schema model = new Schema() + .additionalProperties(new StringSchema()); + final DefaultCodegen codegen = new TypeScriptFetchClientCodegen(); + codegen.additionalProperties().put("nullSafeAdditionalProps", true); + codegen.processOpts(); + + Assert.assertEquals(codegen.getTypeDeclaration(model), "{ [key: string]: string | undefined; }"); + } + + @Test(description = "Don't add null safe additional property indexer by default") + public void testWithoutNullSafeAdditionalProps() { + final Schema model = new Schema() + .additionalProperties(new StringSchema()); + final DefaultCodegen codegen = new TypeScriptFetchClientCodegen(); + codegen.processOpts(); + + Assert.assertEquals(codegen.getTypeDeclaration(model), "{ [key: string]: string; }"); + } } diff --git a/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION b/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION index 9aadf8cf657..bfbf77eb7fa 100644 --- a/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION +++ b/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION @@ -1 +1 @@ -4.3.0-SNAPSHOT +4.3.0-SNAPSHOT \ No newline at end of file