Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Issues
  • #10930
Closed
Open
Issue created Nov 22, 2021 by Administrator@rootContributor3 of 4 checklist items completed3/4 checklist items

[BUG] [dart-dio-next] Models inside anyOf missing type information

Created by: josh-burton

Bug Report Checklist

  • [x ] Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • [x ] Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When a model has a parameter of type allOf with only one child type, specific type information about that type is lost and it is parsed as a generic model.

For example if we have a model User with a field type, which is defined as allOf and then a inner type enum:

      "User": {
        "type": "object",
        "properties": {
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UserType"
              }
            ],
            "description": "type of user"
          }
        }
      },
      "UserType": {
        "type": "string",
        "title": "UserType",
        "enum": [
          "admin",
          "user"
        ]
      }

The model definition of UserType below has "isEnum": true, but the variable/field definition of UserType in User model definition has "isEnum": false and "isModel": true.

This model is an enum and `"isEnum" should always be true.

Debug model output ``` [ { "importPath": "lib.src.model.User", "model": { "anyOf": [], "oneOf": [], "allOf": [], "anyOfProps": [], "allOfProps": [], "oneOfProps": [], "name": "User", "classname": "User", "classVarName": "user", "modelJson": "{\n \"type\" : \"object\",\n \"properties\" : {\n \"type\" : {\n \"description\" : \"type of user\",\n \"allOf\" : [ {\n \"$ref\" : \"#/components/schemas/UserType\"\n } ]\n }\n }\n}", "dataType": "JsonObject", "classFilename": "user", "isAlias": false, "isString": false, "isInteger": false, "isLong": false, "isNumber": false, "isNumeric": false, "isFloat": false, "isDouble": false, "isDate": false, "isDateTime": false, "isShort": false, "isUnboundedInteger": false, "isBoolean": false, "additionalPropertiesIsAnyType": false, "vars": [ { "openApiType": "UserType", "baseName": "type", "complexType": "UserType", "getter": "getType", "setter": "setType", "description": "type of user", "dataType": "UserType", "datatypeWithEnum": "UserType", "name": "type", "defaultValueWithParam": " = data.type;", "baseType": "UserType", "unescapedDescription": "type of user", "example": "null", "jsonSchema": "{\n \"description\" : \"type of user\",\n \"allOf\" : [ {\n \"$ref\" : \"#/components/schemas/UserType\"\n } ]\n}", "exclusiveMinimum": false, "exclusiveMaximum": false, "required": false, "deprecated": false, "hasMoreNonReadOnly": false, "isPrimitiveType": false, "isModel": true, "isContainer": false, "isString": false, "isNumeric": false, "isInteger": false, "isShort": false, "isLong": false, "isUnboundedInteger": false, "isNumber": false, "isFloat": false, "isDouble": false, "isDecimal": false, "isByteArray": false, "isBinary": false, "isFile": false, "isBoolean": false, "isDate": false, "isDateTime": false, "isUuid": false, "isUri": false, "isEmail": false, "isNull": false, "isFreeFormObject": false, "isAnyType": true, "isArray": false, "isMap": false, "isEnum": false, "isReadOnly": false, "isWriteOnly": false, "isNullable": true, "isSelfReference": false, "isCircularReference": false, "isDiscriminator": false, "vars": [], "requiredVars": [], "vendorExtensions": { "x-index": 1 }, "hasValidation": false, "isInherited": false, "nameInCamelCase": "Type", "nameInSnakeCase": "TYPE", "uniqueItems": false, "isXmlAttribute": false, "isXmlWrapped": false, "additionalPropertiesIsAnyType": false, "hasVars": false, "hasRequired": false, "hasDiscriminatorWithNonEmptyMapping": false, "datatype": "UserType", "iexclusiveMaximum": false } ], "allVars": [ { "openApiType": "UserType", "baseName": "type", "complexType": "UserType", "getter": "getType", "setter": "setType", "description": "type of user", "dataType": "UserType", "datatypeWithEnum": "UserType", "name": "type", "defaultValueWithParam": " = data.type;", "baseType": "UserType", "unescapedDescription": "type of user", "example": "null", "jsonSchema": "{\n \"description\" : \"type of user\",\n \"allOf\" : [ {\n \"$ref\" : \"#/components/schemas/UserType\"\n } ]\n}", "exclusiveMinimum": false, "exclusiveMaximum": false, "required": false, "deprecated": false, "hasMoreNonReadOnly": false, "isPrimitiveType": false, "isModel": true, "isContainer": false, "isString": false, "isNumeric": false, "isInteger": false, "isShort": false, "isLong": false, "isUnboundedInteger": false, "isNumber": false, "isFloat": false, "isDouble": false, "isDecimal": false, "isByteArray": false, "isBinary": false, "isFile": false, "isBoolean": false, "isDate": false, "isDateTime": false, "isUuid": false, "isUri": false, "isEmail": false, "isNull": false, "isFreeFormObject": false, "isAnyType": true, "isArray": false, "isMap": false, "isEnum": false, "isReadOnly": false, "isWriteOnly": false, "isNullable": true, "isSelfReference": false, "isCircularReference": false, "isDiscriminator": false, "vars": [], "requiredVars": [], "vendorExtensions": { "x-index": 1 }, "hasValidation": false, "isInherited": false, "nameInCamelCase": "Type", "nameInSnakeCase": "TYPE", "uniqueItems": false, "isXmlAttribute": false, "isXmlWrapped": false, "additionalPropertiesIsAnyType": false, "hasVars": false, "hasRequired": false, "hasDiscriminatorWithNonEmptyMapping": false, "datatype": "UserType", "iexclusiveMaximum": false } ], "requiredVars": [], "optionalVars": [ { "openApiType": "UserType", "baseName": "type", "complexType": "UserType", "getter": "getType", "setter": "setType", "description": "type of user", "dataType": "UserType", "datatypeWithEnum": "UserType", "name": "type", "defaultValueWithParam": " = data.type;", "baseType": "UserType", "unescapedDescription": "type of user", "example": "null", "jsonSchema": "{\n \"description\" : \"type of user\",\n \"allOf\" : [ {\n \"$ref\" : \"#/components/schemas/UserType\"\n } ]\n}", "exclusiveMinimum": false, "exclusiveMaximum": false, "required": false, "deprecated": false, "hasMoreNonReadOnly": false, "isPrimitiveType": false, "isModel": true, "isContainer": false, "isString": false, "isNumeric": false, "isInteger": false, "isShort": false, "isLong": false, "isUnboundedInteger": false, "isNumber": false, "isFloat": false, "isDouble": false, "isDecimal": false, "isByteArray": false, "isBinary": false, "isFile": false, "isBoolean": false, "isDate": false, "isDateTime": false, "isUuid": false, "isUri": false, "isEmail": false, "isNull": false, "isFreeFormObject": false, "isAnyType": true, "isArray": false, "isMap": false, "isEnum": false, "isReadOnly": false, "isWriteOnly": false, "isNullable": true, "isSelfReference": false, "isCircularReference": false, "isDiscriminator": false, "vars": [], "requiredVars": [], "vendorExtensions": {}, "hasValidation": false, "isInherited": false, "nameInCamelCase": "Type", "nameInSnakeCase": "TYPE", "uniqueItems": false, "isXmlAttribute": false, "isXmlWrapped": false, "additionalPropertiesIsAnyType": false, "hasVars": false, "hasRequired": false, "hasDiscriminatorWithNonEmptyMapping": false, "datatype": "UserType", "iexclusiveMaximum": false } ], "readOnlyVars": [], "readWriteVars": [ { "openApiType": "UserType", "baseName": "type", "complexType": "UserType", "getter": "getType", "setter": "setType", "description": "type of user", "dataType": "UserType", "datatypeWithEnum": "UserType", "name": "type", "defaultValueWithParam": " = data.type;", "baseType": "UserType", "unescapedDescription": "type of user", "example": "null", "jsonSchema": "{\n \"description\" : \"type of user\",\n \"allOf\" : [ {\n \"$ref\" : \"#/components/schemas/UserType\"\n } ]\n}", "exclusiveMinimum": false, "exclusiveMaximum": false, "required": false, "deprecated": false, "hasMoreNonReadOnly": false, "isPrimitiveType": false, "isModel": true, "isContainer": false, "isString": false, "isNumeric": false, "isInteger": false, "isShort": false, "isLong": false, "isUnboundedInteger": false, "isNumber": false, "isFloat": false, "isDouble": false, "isDecimal": false, "isByteArray": false, "isBinary": false, "isFile": false, "isBoolean": false, "isDate": false, "isDateTime": false, "isUuid": false, "isUri": false, "isEmail": false, "isNull": false, "isFreeFormObject": false, "isAnyType": true, "isArray": false, "isMap": false, "isEnum": false, "isReadOnly": false, "isWriteOnly": false, "isNullable": true, "isSelfReference": false, "isCircularReference": false, "isDiscriminator": false, "vars": [], "requiredVars": [], "vendorExtensions": {}, "hasValidation": false, "isInherited": false, "nameInCamelCase": "Type", "nameInSnakeCase": "TYPE", "uniqueItems": false, "isXmlAttribute": false, "isXmlWrapped": false, "additionalPropertiesIsAnyType": false, "hasVars": false, "hasRequired": false, "hasDiscriminatorWithNonEmptyMapping": false, "datatype": "UserType", "iexclusiveMaximum": false } ], "parentVars": [], "mandatory": [], "allMandatory": [], "imports": [ "package:digitalworkkit_visitor_api/src/model/user_type.dart" ], "hasVars": true, "emptyVars": false, "hasMoreModels": false, "hasEnums": false, "isEnum": false, "hasValidation": false, "isNullable": false, "hasRequired": false, "hasOptional": true, "isArray": false, "hasChildren": false, "isMap": true, "isNull": false, "isDeprecated": false, "hasOnlyReadOnly": false, "vendorExtensions": { "x-has-vars": true }, "isAdditionalPropertiesTrue": false, "uniqueItems": false, "exclusiveMinimum": false, "exclusiveMaximum": false, "isModel": false, "hasDiscriminatorWithNonEmptyMapping": false, "isAnyType": false, "isClassnameSanitized": false } }, { "importPath": "lib.src.model.UserType", "model": { "anyOf": [], "oneOf": [], "allOf": [], "anyOfProps": [], "allOfProps": [], "oneOfProps": [], "name": "UserType", "classname": "UserType", "title": "UserType", "classVarName": "userType", "modelJson": "{\n \"title\" : \"UserType\",\n \"type\" : \"string\",\n \"enum\" : [ \"admin\", \"user\" ]\n}", "dataType": "String", "classFilename": "user_type", "isAlias": false, "isString": true, "isInteger": false, "isLong": false, "isNumber": false, "isNumeric": false, "isFloat": false, "isDouble": false, "isDate": false, "isDateTime": false, "isShort": false, "isUnboundedInteger": false, "isBoolean": false, "additionalPropertiesIsAnyType": false, "vars": [], "allVars": [], "requiredVars": [], "optionalVars": [], "readOnlyVars": [], "readWriteVars": [], "parentVars": [], "allowableValues": { "values": [ "admin", "user" ], "enumVars": [ { "name": "admin", "isString": true, "value": "'admin'" }, { "name": "user", "isString": true, "value": "'user'" } ] }, "mandatory": [], "allMandatory": [], "imports": [], "hasVars": false, "emptyVars": false, "hasMoreModels": false, "hasEnums": false, "isEnum": true, "hasValidation": false, "isNullable": false, "hasRequired": false, "hasOptional": false, "isArray": false, "hasChildren": false, "isMap": false, "isNull": false, "isDeprecated": false, "hasOnlyReadOnly": true, "vendorExtensions": { "x-has-vars": false }, "isAdditionalPropertiesTrue": false, "uniqueItems": false, "exclusiveMinimum": false, "exclusiveMaximum": false, "isModel": false, "hasDiscriminatorWithNonEmptyMapping": false, "isAnyType": false, "isClassnameSanitized": false } } ] ```

This causes issues when generating a client with dart-dio-next, as it will generate deserialization logic that doesn't compile:

      switch (key) {
        case r'type':
          final valueDes = serializers.deserialize(value,
              specifiedType: const FullType.nullable(UserType)) as UserType?;
          if (valueDes == null) continue;
          result.type.replace(valueDes);
          break;
      }

The line that doesn't compile is result.type.replace(valueDes);, as the UserType EnumClass doesn't have a replace method.

The replace method is generated there because the generator thinks the UserType field is a model, but it's actually an enum.

openapi-generator version

5.3.0

OpenAPI declaration file content or url

sample json spec: https://gist.github.com/josh-burton/8062bc64212db27e2a2f879ae65c07dd

Generation Details

dart-dio-next with built value

Steps to reproduce

Generate the client, run pub run build_runner build.

Related issues/PRs

https://github.com/OpenAPITools/openapi-generator/pull/6914

Suggest a fix

I think the true fix for this would be parsing the allOf block correctly. A work around in dart-dio-next would be ok too but I'm not sure how we can work around it when we don't know the actual type of the model.

@kuhnroyal @wing328

Assignee
Assign to
Time tracking