Skip to content

Add support for top-level oneOf/union schemas in OpenAPI spec - #62

Open
tomasweigenast wants to merge 13 commits into
masreplay:mainfrom
tomasweigenast:main
Open

Add support for top-level oneOf/union schemas in OpenAPI spec#62
tomasweigenast wants to merge 13 commits into
masreplay:mainfrom
tomasweigenast:main

Conversation

@tomasweigenast

Copy link
Copy Markdown

Disclaimer

This pull request was fully generated using GitHub Agent. I reviewed all the changes, validated the approach, and tested the implementation with my own examples. No code in this PR was written manually by me; the agent produced all of it. This was my first time using GitHub Agent, and the results were satisfactory based on the tests performed :)

Summary

This PR adds support for parsing and generating Dart/freezed code from top-level oneOf schemas in OpenAPI specifications. Previously, oneOf was only supported when nested inside another schema's property. Check out #58

Problem

The generator did not support this OpenAPI pattern:

"OrderLineChange": {
  "type": "object",
  "oneOf": [
    {"$ref": "#/components/schemas/CreateOrderLine"},
    {"$ref": "#/components/schemas/UpdateOrderLine"},
    {"$ref": "#/components/schemas/DeleteOrderLine"}
  ],
  "discriminator": {
    "propertyName": "type",
    "mapping": {
      "create": "#/components/schemas/CreateOrderLine",
      "update": "#/components/schemas/UpdateOrderLine",
      "delete": "#/components/schemas/DeleteOrderLine"
    }
  }
}

Solution

  • Added oneOf and discriminator fields to OpenApiSchemas class
  • Modified ModelGenerator to detect top-level oneOf schemas
  • Added buildFromTopLevelSchema method in UnionModelStrategy
  • Properties from referenced schemas are inlined directly into union constructors
  • Static const String key fields are generated and shared across union cases

Generated Output Example

@Freezed(unionKey: r"type")
sealed class OrderLineChange with _$OrderLineChange {
  static const String productIdKey_ = r'product_id';
  static const String quantityKey_ = r'quantity';

  const factory OrderLineChange.create({
    @JsonKey(name: OrderLineChange.productIdKey_) required String productId,
    @JsonKey(name: OrderLineChange.quantityKey_) required int quantity,
  }) = OrderLineChangeCreate;

  const factory OrderLineChange.update({...}) = OrderLineChangeUpdate;
}

Summary

I’m not sure whether this will be merged or if additional work is required (for example, adding tests), but I ran into this issue and needed a solution. I’m sharing it in case it’s useful to others.

Copilot AI and others added 10 commits December 26, 2025 23:59
Co-authored-by: tomasweigenast <31850785+tomasweigenast@users.noreply.github.com>
Co-authored-by: tomasweigenast <31850785+tomasweigenast@users.noreply.github.com>
Co-authored-by: tomasweigenast <31850785+tomasweigenast@users.noreply.github.com>
…eezed toJson generation

Co-authored-by: tomasweigenast <31850785+tomasweigenast@users.noreply.github.com>
…using wrapper value parameter

Co-authored-by: tomasweigenast <31850785+tomasweigenast@users.noreply.github.com>
…lasses

Co-authored-by: tomasweigenast <31850785+tomasweigenast@users.noreply.github.com>
…d-parser

Add support for top-level oneOf/union schemas in OpenAPI spec
@masreplay
masreplay self-requested a review January 28, 2026 09:50
@masreplay masreplay self-assigned this Jan 28, 2026
@masreplay masreplay added the enhancement New feature or request label Jan 28, 2026
OpenAPI 3.1 omits "type" entirely for pure enum schemas and permits a
literal null inside "enum" for nullable enums. Both previously crashed
the fromJson parser with a cast exception.
…quired flag

Query/path/header params used "has a schema default" as a proxy for
required, ignoring the parameter's actual `required` field, and left
params nullable-optional with no default sometimes non-nullable
(uncompilable generated code). Also filter the null sentinel out of
enum member generation (OpenAPI 3.1 nullable-enum idiom) instead of
emitting it as a bogus enum case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants