Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 22, 2025

Problem

The @hey-api/transformers plugin did not support discriminated unions (oneOf with discriminator). When using schemas with discriminator and oneOf, the plugin would generate a warning and fail to produce transformer functions:

❗️ Transformers warning: schema {...} is too complex and won't be currently processed.

This prevented users from combining discriminated unions with transformers for date-time and other transformable properties.

Example

Given an OpenAPI schema with a discriminated union:

{
  "Animal": {
    "oneOf": [
      { "$ref": "#/components/schemas/Dog" },
      { "$ref": "#/components/schemas/Cat" }
    ],
    "discriminator": {
      "propertyName": "type"
    }
  },
  "Dog": {
    "properties": {
      "type": { "type": "string", "enum": ["dog"] },
      "firstBark": { "type": "string", "format": "date-time" }
    }
  },
  "Cat": {
    "properties": {
      "type": { "type": "string", "enum": ["cat"] },
      "firstMeow": { "type": "string", "format": "date-time" }
    }
  }
}

Previously, no transformer would be generated. Now, the plugin correctly generates:

const dogSchemaResponseTransformer = (data: any) => {
    if (data.firstBark) {
        data.firstBark = new Date(data.firstBark);
    }
    return data;
};

const catSchemaResponseTransformer = (data: any) => {
    if (data.firstMeow) {
        data.firstMeow = new Date(data.firstMeow);
    }
    return data;
};

Solution

  1. Added discriminated union support: Modified the transformers plugin to handle schemas with logicalOperator === 'or' by processing each variant and collecting all transformations.

  2. Made transformations defensive: All property transformations now include existence checks to prevent creating Invalid Date objects when properties don't exist on certain union variants.

Changes

  • Modified packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts to:
    • Process oneOf schemas with discriminators
    • Add safety checks for all property transformations
  • Added test case: specs/3.1.x/transformers-discriminator-one-of.json
  • Updated test snapshots across all OpenAPI versions

Testing

  • All 612 existing tests pass
  • New test case validates discriminated union transformer generation
  • Manual verification confirms correct behavior with the issue's example

Closes #2806

Original prompt

This section details on the original issue you should resolve

<issue_title>Polymorphism/discriminator/oneOf in combination with transformers</issue_title>
<issue_description>### Description

We are trying to combine oneOf + discriminator with transformers, but it seems the transformer code doesn't support it?

Are there any plans to support this combination?

Reproducible example or configuration

openapi-ts --file openapi-ts.config.ts --input openapi.json

openapi-ts.config.ts:

import { defineConfig } from "@hey-api/openapi-ts";
export default defineConfig({
    input: "openapi.json",
    output: "src/openapi",
    plugins: [
        "@tanstack/react-query",
        {
            name: "@hey-api/typescript",
            enums: "typescript"
        },
        {
            name: "@hey-api/sdk",
            transformer: true
        },
        {
            bigInt: true,
            dates: true,
            name: "@hey-api/transformers"
        }
    ]
});

OpenAPI specification (optional)

{
    "openapi": "3.0.4",
    "paths": {
        "/api/pets/{id}": {
            "get": {
                "operationId": "getPeyById",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Animal"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "Animal": {
                "oneOf": [{
                        "$ref": "#/components/schemas/Dog"
                    }, {
                        "$ref": "#/components/schemas/Cat"
                    }
                ],
                "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                        "dog": "#/components/schemas/Dog",
                        "cat": "#/components/schemas/Cat"
                    }
                }
            },
            "Dog": {
                "type": "object",
                "properties": {
                    "barkVolume": {
                        "type": "integer"
                    },
                    "firstBark": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Cat": {
                "type": "object",
                "properties": {
                    "whiskerLength": {
                        "type": "integer"
                    },
                    "firstMeow": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            }
        }
    }
}

System information (optional)

@hey-api/openapi-ts: 0.86.0
node: 24.10.0</issue_description>

<agent_instructions>The @hey-api/transformers plugin should handle simple discriminator cases with oneOf</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Fixes #2808


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@changeset-bot
Copy link

changeset-bot bot commented Oct 22, 2025

⚠️ No Changeset found

Latest commit: dd32d1f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Oct 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
hey-api-docs Ready Ready Preview Comment Oct 22, 2025 7:11am

Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>
Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix transformer support for oneOf and discriminator feat(transformers): add support for discriminator/oneOf schemas Oct 22, 2025
Copilot AI requested a review from mrlubos October 22, 2025 07:16
Copilot finished work on behalf of mrlubos October 22, 2025 07:16
@jeremyfiel
Copy link

when considering support for OAS 3.1/OAS3.2+), an alternative and recommended approach for discriminated unions is to use if, then conditional statements which were introduced in JSON Schema draft-07. These would only be a viable option for OAS 3.1 or later. They can be quite verbose, but are much easier to read and understand than the discriminator keyword.

#2764 here's an example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Polymorphism/discriminator/oneOf in combination with transformers An error is reported when a non-existent ref is referenced in the Swagger schema.

3 participants