diff --git a/bin/configs/java-okhttp-gson.yaml b/bin/configs/java-okhttp-gson.yaml index a5c109e1a38d..f404858c2776 100644 --- a/bin/configs/java-okhttp-gson.yaml +++ b/bin/configs/java-okhttp-gson.yaml @@ -10,6 +10,7 @@ parameterNameMappings: _type: underscoreType type_: typeWithUnderscore additionalProperties: + defaultToEmptyContainer: "array?|array|map?" artifactId: petstore-okhttp-gson hideGenerationTimestamp: true useOneOfDiscriminatorLookup: true diff --git a/docs/customization.md b/docs/customization.md index a7be58f96b91..bf0958c8b964 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -401,6 +401,32 @@ or --import-mappings Pet=my.models.MyPet --import-mappings Order=my.models.MyOrder ``` +## Default Values + +To customize the default values for containers, one can leverage the option `defaultToEmptyContainer` to customize what to initalize for array/set/map by respecting the default values in the spec + +Set optional array and map default value to an empty container +``` +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/output --additional-properties defaultToEmptyContainer="array?|map?" +``` + +Set nullable array (required) default value to an empty container +``` +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/output --additional-properties defaultToEmptyContainer="?array" +``` + +Set nullable array (optional) default value to an empty container +``` +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/output --additional-properties defaultToEmptyContainer="?array?" +``` + +To simply enable this option to respect default values in the specification (basically null if not specified): +``` +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/output --additional-properties defaultToEmptyContainer="" +``` + +Note: not all generators support this generator's option (e.g. --additional-properties defaultToEmptyContainer="?array" in CLI) so please test to confirm. Java generators are the first to implement this feature. We welcome PRs to support this option in other generators. Related PR: https://github.com/OpenAPITools/openapi-generator/pull/21269 + ## Name Mapping One can map the property name using `nameMappings` option and parameter name using `parameterNameMappings` option to something else. Consider the following schema: diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 97e859e80c59..33918bed8462 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -334,6 +334,12 @@ apiTemplateFiles are for API outputs only (controllers/handlers). // Whether to automatically hardcode params that are considered Constants by OpenAPI Spec @Setter protected boolean autosetConstants = false; + @Setter @Getter boolean arrayDefaultToEmpty, arrayNullableDefaultToEmpty, arrayOptionalNullableDefaultToEmpty, arrayOptionalDefaultToEmpty; + @Setter @Getter boolean mapDefaultToEmpty, mapNullableDefaultToEmpty, mapOptionalNullableDefaultToEmpty, mapOptionalDefaultToEmpty; + @Setter @Getter protected boolean defaultToEmptyContainer; + final String DEFAULT_TO_EMPTY_CONTAINER = "defaultToEmptyContainer"; + final List EMPTY_LIST = new ArrayList(); + @Override public boolean getAddSuffixToDuplicateOperationNicknames() { return addSuffixToDuplicateOperationNicknames; @@ -392,8 +398,12 @@ public void processOpts() { convertPropertyToBooleanAndWriteBack(CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT, this::setDisallowAdditionalPropertiesIfNotPresent); convertPropertyToBooleanAndWriteBack(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE, this::setEnumUnknownDefaultCase); convertPropertyToBooleanAndWriteBack(CodegenConstants.AUTOSET_CONSTANTS, this::setAutosetConstants); - } + if (additionalProperties.containsKey(DEFAULT_TO_EMPTY_CONTAINER) && additionalProperties.get(DEFAULT_TO_EMPTY_CONTAINER) instanceof String) { + parseDefaultToEmptyContainer((String) additionalProperties.get(DEFAULT_TO_EMPTY_CONTAINER)); + defaultToEmptyContainer = true; + } + } /*** * Preset map builder with commonly used Mustache lambdas. @@ -4226,6 +4236,11 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo } } + // override defaultValue if it's not set and defaultToEmptyContainer is set + if (p.getDefault() == null && defaultToEmptyContainer) { + updateDefaultToEmptyContainer(property, p); + } + // set the default value property.defaultValue = toDefaultValue(property, p); property.defaultValueWithParam = toDefaultValueWithParam(name, p); @@ -4235,6 +4250,99 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo return property; } + /** + * update container's default to empty container according rules provided by the user. + * + * @param cp codegen property + * @param p schema + */ + void updateDefaultToEmptyContainer(CodegenProperty cp, Schema p) { + if (cp.isArray) { + if (!cp.required) { // optional + if (cp.isNullable && arrayOptionalNullableDefaultToEmpty) { // nullable + p.setDefault(EMPTY_LIST); + } else if (!cp.isNullable && arrayOptionalDefaultToEmpty) { // non-nullable + p.setDefault(EMPTY_LIST); + } + } else { // required + if (cp.isNullable && arrayNullableDefaultToEmpty) { // nullable + p.setDefault(EMPTY_LIST); + } else if (!cp.isNullable && arrayDefaultToEmpty) { // non-nullable + p.setDefault(EMPTY_LIST); + } + } + } else if (cp.isMap) { + if (!cp.required) { // optional + if (cp.isNullable && mapOptionalNullableDefaultToEmpty) { // nullable + p.setDefault(EMPTY_LIST); + } else if (!cp.isNullable && mapOptionalDefaultToEmpty) { // non-nullable + p.setDefault(EMPTY_LIST); + } + } else { // required + if (cp.isNullable && mapNullableDefaultToEmpty) { // nullable + p.setDefault(EMPTY_LIST); + } else if (!cp.isNullable && mapOptionalDefaultToEmpty) { // non-nullable + p.setDefault(EMPTY_LIST); + } + } + } + } + + /** + * Parse the rules for defaulting to the empty container. + * + * @param input a set of rules separated by `|` + */ + void parseDefaultToEmptyContainer(String input) { + String[] inputs = ((String) input).split("[|]"); + String containerType; + for (String rule: inputs) { + if (StringUtils.isEmpty(rule)) { + LOGGER.error("updateDefaultToEmptyContainer: Skipped empty input in `{}`.", input); + continue; + } + + if (rule.startsWith("?") && rule.endsWith("?")) { // nullable optional + containerType = rule.substring(1, rule.length() - 1); + if ("array".equalsIgnoreCase(containerType)) { + arrayOptionalNullableDefaultToEmpty = true; + } else if ("map".equalsIgnoreCase(containerType)) { + mapOptionalNullableDefaultToEmpty = true; + } else { + LOGGER.error("Skipped invalid container type `{}` in `{}`.", containerType, input); + } + } else if (rule.startsWith("?")) { // nullable (required) + containerType = rule.substring(1, rule.length()); + if ("array".equalsIgnoreCase(containerType)) { + arrayNullableDefaultToEmpty = true; + } else if ("map".equalsIgnoreCase(containerType)) { + mapNullableDefaultToEmpty = true; + } else { + LOGGER.error("Skipped invalid container type `{}` in `{}`.", containerType, input); + } + } else if (rule.endsWith("?")) { // optional + containerType = rule.substring(0, rule.length()-1); + if ("array".equalsIgnoreCase(containerType)) { + arrayOptionalDefaultToEmpty = true; + } else if ("map".equalsIgnoreCase(containerType)) { + mapOptionalDefaultToEmpty = true; + } else { + LOGGER.error("Skipped invalid container type `{}` in the rule `{}`.", containerType, input); + } + } else { // required + containerType = rule; + if ("array".equalsIgnoreCase(containerType)) { + arrayDefaultToEmpty = true; + } else if ("map".equalsIgnoreCase(containerType)) { + mapDefaultToEmpty = true; + } else { + LOGGER.error("Skipped invalid container type `{}` in the rule `{}`.", containerType, input); + } + } + + } + } + /** * Update property for array(list) container * diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index 8a624b0bbf86..234ba57ceb74 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -1240,7 +1240,7 @@ public String toArrayDefaultValue(CodegenProperty cp, Schema schema) { if (schema.getDefault() instanceof ArrayNode) { // array of default values ArrayNode _default = (ArrayNode) schema.getDefault(); if (_default.isEmpty()) { // e.g. default: [] - return getDefaultCollectionType(schema); + return getDefaultCollectionType(schema, ""); } List final_values = _values; @@ -1253,6 +1253,11 @@ public String toArrayDefaultValue(CodegenProperty cp, Schema schema) { _default.forEach((element) -> { final_values.add(String.valueOf(element)); }); + + if (_default != null && _default.isEmpty() && defaultToEmptyContainer) { + // e.g. [] with the option defaultToEmptyContainer enabled + return getDefaultCollectionType(schema, ""); + } } else { // single value _values = java.util.Collections.singletonList(String.valueOf(schema.getDefault())); } @@ -1306,7 +1311,10 @@ public String toArrayDefaultValue(CodegenProperty cp, Schema schema) { public String toDefaultValue(CodegenProperty cp, Schema schema) { schema = ModelUtils.getReferencedSchema(this.openAPI, schema); if (ModelUtils.isArraySchema(schema)) { - if (schema.getDefault() == null) { + if (defaultToEmptyContainer) { + // if default to empty container option is set, respect the default values provided in the spec + return toArrayDefaultValue(cp, schema); + } else if (schema.getDefault() == null) { // nullable or containerDefaultToNull set to true if (cp.isNullable || containerDefaultToNull) { return null; @@ -1323,6 +1331,16 @@ public String toDefaultValue(CodegenProperty cp, Schema schema) { return null; } + if (defaultToEmptyContainer) { + // respect the default values provided in the spec when the option is enabled + if (schema.getDefault() != null) { + return String.format(Locale.ROOT, "new %s<>()", + instantiationTypes().getOrDefault("map", "HashMap")); + } else { + return null; + } + } + // nullable or containerDefaultToNull set to true if (cp.isNullable || containerDefaultToNull) { return null; @@ -1418,12 +1436,31 @@ private String getDefaultCollectionType(Schema schema) { private String getDefaultCollectionType(Schema schema, String defaultValues) { String arrayFormat = "new %s<>(Arrays.asList(%s))"; + + if (defaultToEmptyContainer) { + // respect the default value in the spec + if (defaultValues == null) { // default value not provided + return null; + } else if (defaultValues.isEmpty()) { // e.g. [] to indicates empty container + arrayFormat = "new %s<>()"; + return getDefaultCollectionType(arrayFormat, defaultValues, ModelUtils.isSet(schema)); + } else { // default value not empty + return getDefaultCollectionType(arrayFormat, defaultValues, ModelUtils.isSet(schema)); + } + } + if (defaultValues == null || defaultValues.isEmpty()) { + // default to empty container even though default value is null + // to respect default values provided in the spec, set the option `defaultToEmptyContainer` properly defaultValues = ""; arrayFormat = "new %s<>()"; } - if (ModelUtils.isSet(schema)) { + return getDefaultCollectionType(arrayFormat, defaultValues, ModelUtils.isSet(schema)); + } + + private String getDefaultCollectionType(String arrayFormat, String defaultValues, boolean isSet) { + if (isSet) { return String.format(Locale.ROOT, arrayFormat, instantiationTypes().getOrDefault("set", "LinkedHashSet"), defaultValues); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 328a8acdb348..30a7c092d8c9 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -5501,4 +5501,35 @@ public void testEnumFieldShouldBeFinal_issue21018() throws IOException { JavaFileAssert.assertThat(files.get("SomeObject.java")) .fileContains("private final String value"); } + + @Test + public void testCollectionTypesWithDefaults_issue_collection() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/java/issue_collection.yaml", null, new ParseOptions()).getOpenAPI(); + SpringCodegen codegen = new SpringCodegen(); + codegen.setLibrary(SPRING_CLOUD_LIBRARY); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.model"); + codegen.additionalProperties().put(CodegenConstants.API_NAME_SUFFIX, "Controller"); + codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "xyz.controller"); + codegen.additionalProperties().put(CodegenConstants.MODEL_NAME_SUFFIX, "Dto"); + codegen.additionalProperties().put("defaultToEmptyContainer", "array"); + + ClientOptInput input = new ClientOptInput() + .openAPI(openAPI) + .config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + Map files = generator.opts(input).generate().stream() + .collect(Collectors.toMap(File::getName, Function.identity())); + + JavaFileAssert.assertThat(files.get("PetDto.java")) + .fileContains("private @Nullable List<@Valid TagDto> tags;") + .fileContains("private List<@Valid TagDto> tagsRequiredList = new ArrayList<>();") + .fileContains("private @Nullable List stringList;") + .fileContains("private List stringRequiredList = new ArrayList<>();"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/java/issue_collection.yaml b/modules/openapi-generator/src/test/resources/3_0/java/issue_collection.yaml new file mode 100644 index 000000000000..3ec1aa6ff213 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/java/issue_collection.yaml @@ -0,0 +1,75 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +paths: + '/pet/{petId}': + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found +components: + schemas: + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - tagsRequiredList + - stringRequiredList + properties: + tags: + type: array + items: + $ref: '#/components/schemas/Tag' + tagsRequiredList: + type: array + items: + $ref: '#/components/schemas/Tag' + stringList: + type: array + items: + type: string + stringRequiredList: + type: array + items: + type: string diff --git a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml index 7c6f5a5ec3ce..ff7831f581a2 100644 --- a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml +++ b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml @@ -108,6 +108,7 @@ paths: name: status required: true schema: + default: [] items: default: available enum: @@ -122,11 +123,13 @@ paths: content: application/xml: schema: + default: [] items: $ref: '#/components/schemas/Pet' type: array application/json: schema: + default: [] items: $ref: '#/components/schemas/Pet' type: array @@ -156,6 +159,7 @@ paths: name: tags required: true schema: + default: [] items: type: string type: array @@ -165,11 +169,13 @@ paths: content: application/xml: schema: + default: [] items: $ref: '#/components/schemas/Pet' type: array application/json: schema: + default: [] items: $ref: '#/components/schemas/Pet' type: array @@ -342,6 +348,7 @@ paths: additionalProperties: format: int32 type: integer + default: [] type: object description: successful operation security: @@ -739,6 +746,7 @@ paths: name: enum_header_string_array required: false schema: + default: [] items: default: $ enum: @@ -766,6 +774,7 @@ paths: name: enum_query_string_array required: false schema: + default: [] items: default: $ enum: @@ -1054,6 +1063,7 @@ paths: schema: additionalProperties: type: string + default: [] type: object description: request body required: true @@ -1195,6 +1205,7 @@ paths: name: pipe required: true schema: + default: [] items: type: string type: array @@ -1204,6 +1215,7 @@ paths: name: ioutil required: true schema: + default: [] items: type: string type: array @@ -1213,6 +1225,7 @@ paths: name: http required: true schema: + default: [] items: type: string type: array @@ -1222,6 +1235,7 @@ paths: name: url required: true schema: + default: [] items: type: string type: array @@ -1231,6 +1245,7 @@ paths: name: context required: true schema: + default: [] items: type: string type: array @@ -1558,6 +1573,7 @@ components: - username: foo - username: bar schema: + default: [] items: $ref: '#/components/schemas/User' type: array @@ -1741,6 +1757,7 @@ components: example: doggie type: string photoUrls: + default: [] items: type: string type: array @@ -1748,6 +1765,7 @@ components: name: photoUrl wrapped: true tags: + default: [] items: $ref: '#/components/schemas/Tag' type: array @@ -1841,6 +1859,7 @@ components: Address: additionalProperties: type: integer + default: [] type: object Animal: discriminator: @@ -1990,12 +2009,15 @@ components: map_property: additionalProperties: type: string + default: [] type: object map_of_map_property: additionalProperties: additionalProperties: type: string + default: [] type: object + default: [] type: object anytype_1: {} map_with_undeclared_properties_anytype_1: @@ -2005,6 +2027,7 @@ components: type: object map_with_undeclared_properties_anytype_3: additionalProperties: true + default: [] type: object empty_map: additionalProperties: false @@ -2014,6 +2037,7 @@ components: map_with_undeclared_properties_string: additionalProperties: type: string + default: [] type: object type: object MixedPropertiesAndAdditionalPropertiesClass: @@ -2027,6 +2051,7 @@ components: map: additionalProperties: $ref: '#/components/schemas/Animal' + default: [] type: object type: object List: @@ -2081,7 +2106,9 @@ components: additionalProperties: additionalProperties: type: string + default: [] type: object + default: [] type: object map_of_enum_string: additionalProperties: @@ -2089,31 +2116,39 @@ components: - UPPER - lower type: string + default: [] type: object direct_map: additionalProperties: type: boolean + default: [] type: object indirect_map: additionalProperties: type: boolean + default: [] type: object type: object ArrayTest: properties: array_of_string: + default: [] items: type: string type: array array_array_of_integer: + default: [] items: + default: [] items: format: int64 type: integer type: array type: array array_array_of_model: + default: [] items: + default: [] items: $ref: '#/components/schemas/ReadOnlyFirst' type: array @@ -2127,6 +2162,7 @@ components: ArrayOfNumberOnly: properties: ArrayNumber: + default: [] items: type: number type: array @@ -2134,7 +2170,9 @@ components: ArrayOfArrayOfNumberOnly: properties: ArrayArrayNumber: + default: [] items: + default: [] items: type: number type: array @@ -2148,6 +2186,7 @@ components: - $ type: string array_enum: + default: [] items: enum: - fish @@ -2157,11 +2196,13 @@ components: type: object FreeFormObject: additionalProperties: true + default: [] description: A schema consisting only of additional properties type: object MapOfString: additionalProperties: type: string + default: [] description: A schema consisting only of additional properties of type string type: object OuterEnum: @@ -2217,6 +2258,7 @@ components: StringBooleanMap: additionalProperties: type: boolean + default: [] type: object FileSchemaTestClass: example: @@ -2229,6 +2271,7 @@ components: file: $ref: '#/components/schemas/File' files: + default: [] items: $ref: '#/components/schemas/File' type: array @@ -2308,6 +2351,7 @@ components: nullable: true type: array array_items_nullable: + default: [] items: nullable: true type: object @@ -2327,6 +2371,7 @@ components: additionalProperties: nullable: true type: object + default: [] type: object type: object fruit: @@ -2456,6 +2501,7 @@ components: nullableShape: $ref: '#/components/schemas/NullableShape' shapes: + default: [] items: $ref: '#/components/schemas/Shape' type: array @@ -2551,6 +2597,7 @@ components: - $ref: '#/components/schemas/GrandparentAnimal' type: object ArrayOfEnums: + default: [] items: $ref: '#/components/schemas/OuterEnum' type: array @@ -2575,6 +2622,7 @@ components: deprecatedRef: $ref: '#/components/schemas/DeprecatedObject' bars: + default: [] deprecated: true items: $ref: '#/components/schemas/Bar' @@ -2592,6 +2640,7 @@ components: example: doggie type: string photoUrls: + default: [] items: type: string type: array @@ -2599,6 +2648,7 @@ components: name: photoUrl wrapped: true tags: + default: [] items: $ref: '#/components/schemas/Tag' type: array @@ -2628,6 +2678,7 @@ components: example: doggie type: string array_allof_dog_property: + default: [] items: $ref: '#/components/schemas/ArrayOfInlineAllOf_array_allof_dog_property_inner' type: array @@ -2656,6 +2707,7 @@ components: type: string type: array WithoutDefault: + default: [] items: type: string type: array @@ -2692,6 +2744,7 @@ components: - type: boolean description: Values of scalar type using anyOf Array: + default: [] description: Values of array type items: $ref: '#/components/schemas/Scalar' @@ -2723,6 +2776,7 @@ components: example: doggie type: string photoUrls: + default: [] items: type: string type: array @@ -2730,6 +2784,7 @@ components: name: photoUrl wrapped: true tags: + default: [] items: allOf: - $ref: '#/components/schemas/Tag' @@ -2790,6 +2845,7 @@ components: example: doggie type: string photoUrls: + default: [] items: type: string type: array @@ -2797,6 +2853,7 @@ components: name: photoUrl wrapped: true tags: + default: [] items: allOf: - $ref: '#/components/schemas/Tag' @@ -2841,13 +2898,15 @@ components: ArrayOneOf: oneOf: - type: integer - - items: + - default: [] + items: type: string type: array ArrayAnyOf: anyOf: - type: integer - - items: + - default: [] + items: type: string type: array ModelWithOneOfAnyOfProperties: @@ -2887,6 +2946,7 @@ components: testEnumParameters_request: properties: enum_form_string_array: + default: [] description: Form parameter enum test (string array) items: default: $ @@ -2992,18 +3052,22 @@ components: type: object _fake_oneOfWIthSameErasure_get_200_response: oneOf: - - items: + - default: [] + items: type: string type: array - - items: + - default: [] + items: type: integer type: array _fake_anyOfWIthSameErasure_get_200_response: anyOf: - - items: + - default: [] + items: type: string type: array - - items: + - default: [] + items: type: integer type: array testInlineFreeformAdditionalProperties_request: @@ -3032,6 +3096,7 @@ components: oneOf: - type: string - additionalProperties: true + default: [] type: object ArrayOfInlineAllOf_array_allof_dog_property_inner: allOf: @@ -3072,6 +3137,7 @@ components: AllOfModelArrayAnyOf_allOf_linkListColumn1: properties: value: + default: [] items: $ref: '#/components/schemas/AllOfModelArrayAnyOf_allOf_linkListColumn1_value' type: array