swagger_parser icon indicating copy to clipboard operation
swagger_parser copied to clipboard

`"anyOf"` keyword doesn't implement any relationship with a parent model

Open tsinis opened this issue 1 year ago • 0 comments

Steps to reproduce

Hey, again @Carapacik, thanks for a great package!

I have a question related to the "anyOf" declaration in the JSON schemas, looks like the parent class doesn't utilize/reference members of the "anyOf" list at all.

  1. Clone swagger_parser/example.
  2. Replace schemes/openapi.json content with the content of test anyOf schema.
  3. Provide json_serializer: freezed in the swagger_parser.yaml.
  4. dart pub get.
  5. dart run swagger_parser.

Fruit class is not anyhow related to the Apple/Banana at all, so the "anyOf" keyword has no practical effect.

Expected results

// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:freezed_annotation/freezed_annotation.dart';

import 'apple.dart';
import 'banana.dart';

part 'fruit.freezed.dart';
part 'fruit.g.dart';

@Freezed()
class Fruit with _$Fruit {
  const factory Fruit.apple(Apple apple, {required String color}) = _AppleFruit;
  const factory Fruit.banana(Banana banana, {required String color}) =
      _BananaFruit;

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

Actual results

// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:freezed_annotation/freezed_annotation.dart';

part 'fruit.freezed.dart';
part 'fruit.g.dart';

@Freezed()
class Fruit with _$Fruit {
  const factory Fruit({
    required String color,
  }) = _Fruit;
  
  factory Fruit.fromJson(Map<String, Object?> json) => _$FruitFromJson(json);
}

Your OpenApi snippet

{
  "openapi": "3.0.1",
  "info": {
    "title": "fruity",
    "version": "0.0.1"
  },
  "paths": {
    "/": {
      "get": {
        "responses": {
          "200": {
            "description": "desc",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/fruit"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "fruit": {
        "title": "fruit",
        "type": "object",
        "properties": {
          "color": {
            "type": "string"
          }
        },
        "anyOf": [
          {
            "$ref": "#/components/schemas/apple"
          },
          {
            "$ref": "#/components/schemas/banana"
          }
        ]
      },
      "apple": {
        "title": "apple",
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          }
        }
      },
      "banana": {
        "title": "banana",
        "type": "object",
        "properties": {
          "count": {
            "type": "number"
          }
        }
      }
    }
  }
}

Code sample

Since Fruit is a union/sealed class, that might be either banana or apple - it should be reflected in the Fruit's freezed class declaration. Otherwise "anyOf" doesn't have any effect on resulted code-gen.

Code sample
  /// This is sadly not working :( because Apple and Banana are not related to the Fruit.
  const fruit = Fruit.apple(Apple(kind: "gala"), color: "red");

  print('this is ${fruit.color} and');

  fruit.when(
      apple: (apple, _) => print("it's ${apple.kind} apple!"),
      banana: (banana, _) => print("it's ${banana.count} banana(s)!"));

Logs

Logs
Building package executable... 
Built swagger_parser:swagger_parser.

┃  ____ _ _ _ ____ ____ ____ ____ ____     ___  ____ ____ ____ ____ ____ 
┃  [__  | | | |__| | __ | __ |___ |__/     |__] |__| |__/ [__  |___ |__/ 
┃  ___] |_|_| |  | |__] |__] |___ |  \ ___ |    |  | |  \ ___] |___ |  \
┃

Generate...
> swagger v0.0.1: 
    1 rest clients, 1 requests, 3 data classes.
    6 files with 105 lines of code.
    Success (0.014 seconds)

The generation was completed successfully. You can run the generation using build_runner.

Dart version and used packages versions

Dart version
#### General info

- Dart 3.3.4 (stable) (Tue Apr 16 19:56:12 2024 +0000) on "macos_arm64"
- on macos / Version 14.4.1 (Build 23E224)
- locale is en-US

#### Project info

- sdk constraint: '^3.3.0'
- dependencies: dio, freezed_annotation, json_annotation, path, retrofit
- dev_dependencies: analyzer, build_runner, freezed, json_serializable, retrofit_generator, swagger_parser
- elided dependencies: 1
Packages version
environment:
  sdk: ^3.3.0

dependencies:
  dio: ^5.4.3+1
  freezed_annotation: ^2.4.1
  json_annotation: ^4.8.1
  path: ^1.9.0
  retrofit: ^4.1.0

dev_dependencies:
  analyzer: ^6.4.1
  build_runner: ^2.4.9
  freezed: ^2.5.2
  index_generator: ^3.4.1
  json_serializable: ^6.7.1
  retrofit_generator: ^8.1.0
  swagger_parser: ^1.17.2

tsinis avatar Apr 19 '24 13:04 tsinis