forked from loafle/openapi-generator-original
Remove restrictions for additional property types (#11802)
When a schema specifies additionalProperties: true, we need not restrict those properties to a particular type. This change sets the schemas for them to AnyType instead of object. From a generation perspective, this only changes the output for generators that differentiate between AnyType and object in their type mappings; most do not. This fixes at least one bug in the Go and TypeScript generators.
This commit is contained in:
parent
e783e9b780
commit
f6231d2488
@ -1200,12 +1200,11 @@ public class ModelUtils {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
if (addProps == null || (addProps instanceof Boolean && (Boolean) addProps)) {
|
if (addProps == null || (addProps instanceof Boolean && (Boolean) addProps)) {
|
||||||
// Return ObjectSchema to specify any object (map) value is allowed.
|
// Return an empty schema as the properties can take on any type per
|
||||||
// Set nullable to specify the value of additional properties may be
|
// the spec. See
|
||||||
// the null value.
|
// https://github.com/OpenAPITools/openapi-generator/issues/9282 for
|
||||||
// Free-form additionalProperties don't need to have an inner
|
// more details.
|
||||||
// additional properties, the type is already free-form.
|
return new Schema();
|
||||||
return new ObjectSchema().additionalProperties(Boolean.FALSE).nullable(Boolean.TRUE);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
export interface {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
|
export interface {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
|
||||||
{{#additionalPropertiesType}}
|
{{#additionalPropertiesType}}
|
||||||
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
|
[key: string]: {{{additionalPropertiesType}}}{{^additionalPropertiesIsAnyType}}{{#hasVars}} | any{{/hasVars}}{{/additionalPropertiesIsAnyType}};
|
||||||
|
|
||||||
{{/additionalPropertiesType}}
|
{{/additionalPropertiesType}}
|
||||||
{{#vars}}
|
{{#vars}}
|
||||||
|
@ -449,7 +449,7 @@ public class DefaultCodegenTest {
|
|||||||
// extended with any undeclared properties.
|
// extended with any undeclared properties.
|
||||||
Schema addProps = ModelUtils.getAdditionalProperties(openAPI, componentSchema);
|
Schema addProps = ModelUtils.getAdditionalProperties(openAPI, componentSchema);
|
||||||
Assert.assertNotNull(addProps);
|
Assert.assertNotNull(addProps);
|
||||||
Assert.assertTrue(addProps instanceof ObjectSchema);
|
Assert.assertEquals(addProps, new Schema());
|
||||||
CodegenModel cm = codegen.fromModel("AdditionalPropertiesClass", componentSchema);
|
CodegenModel cm = codegen.fromModel("AdditionalPropertiesClass", componentSchema);
|
||||||
Assert.assertNotNull(cm.getAdditionalProperties());
|
Assert.assertNotNull(cm.getAdditionalProperties());
|
||||||
|
|
||||||
@ -494,7 +494,7 @@ public class DefaultCodegenTest {
|
|||||||
Assert.assertNull(map_with_undeclared_properties_anytype_1_sc.getAdditionalProperties());
|
Assert.assertNull(map_with_undeclared_properties_anytype_1_sc.getAdditionalProperties());
|
||||||
addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_1_sc);
|
addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_1_sc);
|
||||||
Assert.assertNotNull(addProps);
|
Assert.assertNotNull(addProps);
|
||||||
Assert.assertTrue(addProps instanceof ObjectSchema);
|
Assert.assertEquals(addProps, new Schema());
|
||||||
Assert.assertNotNull(map_with_undeclared_properties_anytype_1_cp.getAdditionalProperties());
|
Assert.assertNotNull(map_with_undeclared_properties_anytype_1_cp.getAdditionalProperties());
|
||||||
|
|
||||||
// map_with_undeclared_properties_anytype_2
|
// map_with_undeclared_properties_anytype_2
|
||||||
@ -504,7 +504,7 @@ public class DefaultCodegenTest {
|
|||||||
Assert.assertNull(map_with_undeclared_properties_anytype_2_sc.getAdditionalProperties());
|
Assert.assertNull(map_with_undeclared_properties_anytype_2_sc.getAdditionalProperties());
|
||||||
addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_2_sc);
|
addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_2_sc);
|
||||||
Assert.assertNotNull(addProps);
|
Assert.assertNotNull(addProps);
|
||||||
Assert.assertTrue(addProps instanceof ObjectSchema);
|
Assert.assertEquals(addProps, new Schema());
|
||||||
Assert.assertNotNull(map_with_undeclared_properties_anytype_2_cp.getAdditionalProperties());
|
Assert.assertNotNull(map_with_undeclared_properties_anytype_2_cp.getAdditionalProperties());
|
||||||
|
|
||||||
// map_with_undeclared_properties_anytype_3
|
// map_with_undeclared_properties_anytype_3
|
||||||
@ -517,7 +517,7 @@ public class DefaultCodegenTest {
|
|||||||
Assert.assertEquals(map_with_undeclared_properties_anytype_3_sc.getAdditionalProperties(), Boolean.TRUE);
|
Assert.assertEquals(map_with_undeclared_properties_anytype_3_sc.getAdditionalProperties(), Boolean.TRUE);
|
||||||
addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_3_sc);
|
addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_3_sc);
|
||||||
Assert.assertNotNull(addProps);
|
Assert.assertNotNull(addProps);
|
||||||
Assert.assertTrue(addProps instanceof ObjectSchema);
|
Assert.assertEquals(addProps, new Schema());
|
||||||
Assert.assertNotNull(map_with_undeclared_properties_anytype_3_cp.getAdditionalProperties());
|
Assert.assertNotNull(map_with_undeclared_properties_anytype_3_cp.getAdditionalProperties());
|
||||||
|
|
||||||
// empty_map
|
// empty_map
|
||||||
@ -2769,6 +2769,26 @@ public class DefaultCodegenTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdditionalPropertiesAnyType() {
|
||||||
|
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_9282.yaml");
|
||||||
|
final DefaultCodegen codegen = new DefaultCodegen();
|
||||||
|
codegen.setOpenAPI(openAPI);
|
||||||
|
|
||||||
|
CodegenProperty anyTypeSchema = codegen.fromProperty("", new Schema());
|
||||||
|
|
||||||
|
Schema sc;
|
||||||
|
CodegenModel cm;
|
||||||
|
|
||||||
|
sc = openAPI.getComponents().getSchemas().get("AdditionalPropertiesTrue");
|
||||||
|
cm = codegen.fromModel("AdditionalPropertiesTrue", sc);
|
||||||
|
assertEquals(cm.getVars().get(0).additionalProperties, anyTypeSchema);
|
||||||
|
|
||||||
|
sc = openAPI.getComponents().getSchemas().get("AdditionalPropertiesAnyType");
|
||||||
|
cm = codegen.fromModel("AdditionalPropertiesAnyType", sc);
|
||||||
|
assertEquals(cm.getVars().get(0).additionalProperties, anyTypeSchema);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsXPresence() {
|
public void testIsXPresence() {
|
||||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7651.yaml");
|
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7651.yaml");
|
||||||
|
@ -22,6 +22,7 @@ import io.swagger.v3.oas.models.OpenAPI;
|
|||||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||||
import io.swagger.v3.oas.models.media.IntegerSchema;
|
import io.swagger.v3.oas.models.media.IntegerSchema;
|
||||||
import io.swagger.v3.oas.models.media.MapSchema;
|
import io.swagger.v3.oas.models.media.MapSchema;
|
||||||
|
import io.swagger.v3.oas.models.media.ObjectSchema;
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
import org.openapitools.codegen.CodegenConstants;
|
import org.openapitools.codegen.CodegenConstants;
|
||||||
import org.openapitools.codegen.CodegenType;
|
import org.openapitools.codegen.CodegenType;
|
||||||
@ -90,6 +91,13 @@ public class AbstractGoCodegenTest {
|
|||||||
ModelUtils.setGenerateAliasAsModel(true);
|
ModelUtils.setGenerateAliasAsModel(true);
|
||||||
defaultValue = codegen.getTypeDeclaration(schema);
|
defaultValue = codegen.getTypeDeclaration(schema);
|
||||||
Assert.assertEquals(defaultValue, "map[string]NestedArray");
|
Assert.assertEquals(defaultValue, "map[string]NestedArray");
|
||||||
|
|
||||||
|
// Create object schema with additionalProperties set to true
|
||||||
|
schema = new ObjectSchema().additionalProperties(Boolean.TRUE);
|
||||||
|
|
||||||
|
ModelUtils.setGenerateAliasAsModel(false);
|
||||||
|
defaultValue = codegen.getTypeDeclaration(schema);
|
||||||
|
Assert.assertEquals(defaultValue, "map[string]interface{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class P_AbstractGoCodegen extends AbstractGoCodegen {
|
private static class P_AbstractGoCodegen extends AbstractGoCodegen {
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
AdditionalPropertiesTrue:
|
||||||
|
description: additionalProperties set to true
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
child:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
|
||||||
|
AdditionalPropertiesAnyType:
|
||||||
|
description: additionalProperties set to any type explicitly
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
child:
|
||||||
|
type: object
|
||||||
|
additionalProperties: {}
|
@ -59,10 +59,10 @@ export interface AdditionalPropertiesClass {
|
|||||||
'map_with_undeclared_properties_anytype_2'?: object;
|
'map_with_undeclared_properties_anytype_2'?: object;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {{ [key: string]: object; }}
|
* @type {{ [key: string]: any; }}
|
||||||
* @memberof AdditionalPropertiesClass
|
* @memberof AdditionalPropertiesClass
|
||||||
*/
|
*/
|
||||||
'map_with_undeclared_properties_anytype_3'?: { [key: string]: object; };
|
'map_with_undeclared_properties_anytype_3'?: { [key: string]: any; };
|
||||||
/**
|
/**
|
||||||
* an object with no declared properties and no undeclared properties, hence it\'s an empty map.
|
* an object with no declared properties and no undeclared properties, hence it\'s an empty map.
|
||||||
* @type {object}
|
* @type {object}
|
||||||
@ -1706,7 +1706,7 @@ export interface Whale {
|
|||||||
* @interface Zebra
|
* @interface Zebra
|
||||||
*/
|
*/
|
||||||
export interface Zebra {
|
export interface Zebra {
|
||||||
[key: string]: object | any;
|
[key: string]: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -173,7 +173,7 @@ export interface ArrayTest {
|
|||||||
* @interface Banana
|
* @interface Banana
|
||||||
*/
|
*/
|
||||||
export interface Banana {
|
export interface Banana {
|
||||||
[key: string]: object | any;
|
[key: string]: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user