swagger_parser icon indicating copy to clipboard operation
swagger_parser copied to clipboard

Nullable allOf not being handled correctly

Open ObviouslyRichB opened this issue 4 months ago • 2 comments

Steps to reproduce

Update all packages to latest Generate a schema that uses allOf + nullable Run generate and build

I have posted my swagger.yaml settings below

Expected results

@Freezed() abstract class MatterInfoScreenResponse with _$MatterInfoScreenResponse { const factory MatterInfoScreenResponse({ @JsonKey(name: 'info_screen_data') MatterInfoScreen? infoScreenData, }) = _MatterInfoScreenResponse;

factory MatterInfoScreenResponse.fromJson(Map<String, Object?> json) => _$MatterInfoScreenResponseFromJson(json); }

Actual results

@Freezed() abstract class MatterInfoScreenResponse with _$MatterInfoScreenResponse { const factory MatterInfoScreenResponse({ @JsonKey(name: 'info_screen_data') required MatterInfoScreen infoScreenData, }) = _MatterInfoScreenResponse;

factory MatterInfoScreenResponse.fromJson(Map<String, Object?> json) => _$MatterInfoScreenResponseFromJson(json); }

Your OpenApi snippet

Schema component

    MatterInfoScreenResponse:
      type: object
      properties:
        info_screen_data:
          allOf:
          - $ref: '#/components/schemas/MatterInfoScreen'
          nullable: true

Here we can see that redocly is correctly displaying the object as nullable.

Image

Code sample

Code sample
swagger_parser:
  # Sets the url of the OpenApi schema.
  schema_path: api-docs.yaml

  # Required. Sets output directory for generated files (Clients and DTOs).
  output_directory: lib/src/

  # Optional. Set API name for folder and export file
  # If not specified, the file name is used.
  name: manage_api

  # Optional. Sets the programming language.
  # Current available languages are: dart, kotlin.
  language: dart

  # Optional (dart only).
  # Current available serializers are: json_serializable, freezed, dart_mappable.
  json_serializer: freezed

  # Optional. Set default content-type for all requests.
  default_content_type: "application/json"

  # Optional (dart only).
  # Support @Extras annotation for interceptors.
  # If the value is 'true', then the annotation will be added to all requests.
  extras_parameter_by_default: false

  # Optional (dart only).
  # It is used if the value does not have the annotations 'required' and 'nullable'.
  # If the value is 'true', then value be 'required', if the value is 'false', then 'nullable'.
  required_by_default: false

  # Optional (dart only). Set 'true' to generate root client
  # with interface and all clients instances.
  root_client: true

  # Optional (dart only). Set root client name.
  root_client_name: ManageApiClient

  # Optional (dart only). Set 'true' to generate export file.
  export_file: true

  # Optional. Set to 'true' to put the all api in its folder.
  put_in_folder: false

  # Optional. Set 'true' to put all clients in clients folder.
  put_clients_in_folder: false

  # Optional. Set to 'true' to squash all clients in one client.
  merge_clients: false

  # Optional. Set postfix for Client class and file.
  client_postfix: Api

  # Optional. Set 'true' to use only the endpoint path for the method name.
  # Set 'false' to use operationId
  path_method_name: false

  # Optional (dart only). Set 'true' to include toJson() in enums.
  # If set to false, serialization will use .name instead.
  enums_to_json: true

  # Optional. Set 'true' to set enum prefix from parent component.
  enums_parent_prefix: true

  # Optional (dart only). Set 'true' to maintain backwards compatibility
  # when adding new values on the backend.
  unknown_enum_value: false

  # Optional. Set 'false' to not put a comment at the beginning of the generated files.
  mark_files_as_generated: true

  # Optional (dart only). Set 'true' to wrap all request return types with HttpResponse.
  # Setting to true because manage API adds pagination to the headers.
  original_http_response: false

  # Optional (dart & freezed only). Set 'true' to use Freezed 3.x code generation syntax.
  # Set 'false' to maintain compatibility with Freezed 2.x.
  use_freezed3: true

  # DART ONLY
  # Optional. Set `true` to use MultipartFile instead of File as argument type for file parameters.
  use_multipart_file: true

  # Optional. Set regex replacement rules for the names of the generated classes/enums.
  # All rules are applied in order.
  #  # https://github.com/Carapacik/swagger_parser/issues/243
  #  replacement_rules:
  #    - pattern: "$"
  #      replacement: "Dto"
  #
  #  # Optional. Skip parameters with names.
  #  skipped_parameters:
  #    - 'X-Some-Token'

Logs

Logs
[Paste your logs here]

Dart version and used packages versions

Dart version
environment:
  sdk: '>=3.8.0 <4.0.0'
  flutter: ">=3.32.0"

dependencies:
  dio: ^5.8.0+1
  freezed_annotation: ^3.1.0
  json_annotation: ^4.9.0
  retrofit: ^4.7.1
  swagger_parser: ^1.28.0

dev_dependencies:
  build_runner: ^2.6.1
  freezed: ^3.2.0
  json_serializable: ^6.10.0
  lints: ^6.0.0
  retrofit_generator: ^10.0.2

ObviouslyRichB avatar Aug 07 '25 16:08 ObviouslyRichB

Note on this one, I have tried generating a 3.1.0 schema and this does seem to be generating nullable components correctly - perhaps the parser is assuming latest rather than 3.0.3?

ObviouslyRichB avatar Aug 07 '25 17:08 ObviouslyRichB

I faced the same issue and generated a v2.x version just to fix it. on asp core

app.UseSwagger(options => { options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi2_0; });

Kemorave avatar Aug 11 '25 13:08 Kemorave