Skip to content

chore: add support for non-discriminator, oneOf query parameters#216

Merged
mcnulty-fp merged 6 commits into
mainfrom
chore/INTER-2038-oneof-union-support
May 15, 2026
Merged

chore: add support for non-discriminator, oneOf query parameters#216
mcnulty-fp merged 6 commits into
mainfrom
chore/INTER-2038-oneof-union-support

Conversation

@mcnulty-fp
Copy link
Copy Markdown
Contributor

@mcnulty-fp mcnulty-fp commented May 14, 2026

This PR updates the handling for oneOf constructs that do not use a discriminator to allow query parameters to use a union type to expand the accepted types for a parameter without breaking backward compatibility. This functionality will be used for the pending changes to expand start and end to accept a date-time string.

#217 contains the generated code changes that result from these templates when using a schema that includes the changes for start and `end.

These template changes will also require additions to .openapi-generator-ignore to ignore the models that would be generated for the oneOf schema construct but aren't needed. #217 shows what that will look like.

Itemized changes:

  • Update api template to use union types for request parameters that use the oneOf construct without a discriminator rather than a generated wrapper model. This ensures that oneOf can be used to expand a parameters types without breaking backward compatibility.
  • Update ObjectSerializer template to support the int|\DateTime type, which is will be used to by the pending start and end types. New combinations of oneOf schemas will require similar changes in the future.
  • Update README.mustache to skip references to models without variables. The referenced models will be ignored in .openapi-generator-ignore moving forward.
  • Update api_doc template to generate correct examples and type references for oneOf request parameters.
  • Update generated ObjectSerializer.php
  • Add unit tests for added functionality to ObjectSerializer

- Update `api` template to use union types for request parameters
  that use the `oneOf` construct without a discriminator rather
  than a generated wrapper model. This ensures that `oneOf` can
  be used to expand a parameters types without breaking backward
  compatibility.
- Update `ObjectSerializer` template to support the `int|\DateTime` type,
  which is will be used to by the pending `start` and `end` types.
  New combinations of `oneOf` schemas will require similar changes
  in the future.
- Update `README.mustache` to skip references to models without
  variables. The referenced models will be ignored in
  .openapi-generator-ignore moving forward.
- Update `api_doc` template to generate correct examples and type
  references for `oneOf` request parameters.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

🟢 Coverage increased by 86.26%

Code Coverage Report

Coverage Report

St. Category Percentage Covered / Total
🟢 Statements 86.26% 3013 / 3493
🟢 Functions 86.26% 1212 / 1405
Files Coverage
St. File Methods Statements Total Coverage
🔴 src/Model/BotResult.php 0.00% 0.00% 0.00%
🔴 src/Model/ErrorCode.php 0.00% 0.00% 0.00%
🔴 src/Model/IncrementalIdentificationStatus.php 0.00% 0.00% 0.00%
🔴 src/Model/ModelInterface.php 0.00% 0.00% 0.00%
🔴 src/Model/ProxyConfidence.php 0.00% 0.00% 0.00%
🔴 src/Model/RareDevicePercentileBucket.php 0.00% 0.00% 0.00%
🔴 src/Model/RuleActionType.php 0.00% 0.00% 0.00%
🔴 src/Model/SearchEventsBot.php 0.00% 0.00% 0.00%
🔴 src/Model/SearchEventsIncrementalIdentificationStatus.php 0.00% 0.00% 0.00%
🔴 src/Model/SearchEventsRareDevicePercentileBucket.php 0.00% 0.00% 0.00%
🔴 src/Model/SearchEventsSdkPlatform.php 0.00% 0.00% 0.00%
🔴 src/Model/SearchEventsVpnConfidence.php 0.00% 0.00% 0.00%
🔴 src/Model/TamperingConfidence.php 0.00% 0.00% 0.00%
🔴 src/Model/VpnConfidence.php 0.00% 0.00% 0.00%
🔴 src/Sealed/DecryptionAlgorithm.php 0.00% 0.00% 0.00%

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the PHP SDK’s OpenAPI Generator templates and generated serializer to better support oneOf request parameters without a discriminator, primarily to allow query parameters to accept expanded types (e.g., int|\DateTime) without requiring wrapper models.

Changes:

  • Adjusts API templates to alter how parameter types are emitted when oneOf is present without a discriminator.
  • Extends ObjectSerializer::toQueryValue() to format \DateTime when the OpenAPI type is the union int|\DateTime.
  • Updates README/API docs templates to avoid referencing empty models and to improve oneOf parameter examples/type rendering.
  • Updates generated src/ObjectSerializer.php accordingly.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
template/README.mustache Skips listing models with no variables in the README model section.
template/ObjectSerializer.mustache Adds query serialization handling for `int
template/api.mustache Changes emitted param doc/signature typing for non-discriminator oneOf parameters.
template/api_doc.mustache Adjusts generated docs/examples for oneOf request parameters.
src/ObjectSerializer.php Regenerates serializer with `int
Comments suppressed due to low confidence (2)

template/api.mustache:112

  • In the method signature, non-discriminator oneOf parameters are typed as the first schema only ({{schema.dataType}}). This will still reject the additional oneOf alternatives at runtime (PHP type checks) and undermines the goal of accepting expanded types; generate a proper union type (e.g., int|\DateTime) or otherwise loosen the type when hasDiscriminatorWithNonEmptyMapping is false.
    public function {{operationId}}({{#allParams}}{{#isArray}}array{{/isArray}}{{#isMap}}array{{/isMap}}{{^isArray}}{{^isMap}}{{^composedSchemas.oneOf}}{{{dataType}}}{{/composedSchemas.oneOf}}{{#composedSchemas.oneOf}}{{#-first}}{{^hasDiscriminatorWithNonEmptyMapping}}{{{schema.dataType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{#hasDiscriminatorWithNonEmptyMapping}}{{{dataType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{/-first}}{{/composedSchemas.oneOf}}{{/isMap}}{{/isArray}} ${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
    {

src/ObjectSerializer.php:198

  • The new "int|\DateTime" branch is executed after the emptiness check. Since isEmptyValue() doesn’t understand union OpenAPI types, integer 0 will be considered empty for openApiType "int|\DateTime", which can incorrectly drop/blank query values. Update the emptiness logic to handle union types (or normalize based on runtime value type).
        # Handle int and DateTime union in query
        if ('int|\DateTime' === $openApiType || '\DateTime|int' === $openApiType) {
            if ($value instanceof \DateTime) {
                return ["$paramName" => $value->format(self::$dateTimeFormat)];
            }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread template/api.mustache
Comment thread template/api_doc.mustache
Comment thread src/ObjectSerializer.php
Comment thread template/ObjectSerializer.mustache
@github-actions
Copy link
Copy Markdown
Contributor

⚠️ This PR doesn't contain any changesets. If there are user-facing changes, don't forget to run:

pnpm exec changeset

to create a changeset.

@mcnulty-fp mcnulty-fp requested a review from Copilot May 14, 2026 17:55
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (4)

template/api.mustache:145

  • Same issue as above for the WithHttpInfo method signature: oneOf parameters use schema.dataType/schema.complexType but the signature still defaults optional params to null. Ensure the type hint includes nullability for optional/nullable oneOf params to avoid a PHP fatal error in generated clients.
     * @deprecated
    {{/isDeprecated}}
     */
    public function {{operationId}}WithHttpInfo({{#allParams}}{{#isArray}}array{{/isArray}}{{#isMap}}array{{/isMap}}{{^isArray}}{{^isMap}}{{^composedSchemas.oneOf}}{{{dataType}}}{{/composedSchemas.oneOf}}{{#composedSchemas.oneOf}}{{#-first}}{{^hasDiscriminatorWithNonEmptyMapping}}{{{schema.dataType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{#hasDiscriminatorWithNonEmptyMapping}}{{{schema.complexType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{/-first}}{{/composedSchemas.oneOf}}{{/isMap}}{{/isArray}} ${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): array
    {

template/api.mustache:222

  • Same issue as above for the Async method signature: oneOf parameters emitted via schema.dataType/schema.complexType need to include nullability when the parameter is optional/nullable, otherwise the default null will be invalid for the union/class type.
     * @deprecated
    {{/isDeprecated}}
     */
    public function {{operationId}}Async({{#allParams}}{{#isArray}}array{{/isArray}}{{#isMap}}array{{/isMap}}{{^isArray}}{{^isMap}}{{^composedSchemas.oneOf}}{{{dataType}}}{{/composedSchemas.oneOf}}{{#composedSchemas.oneOf}}{{#-first}}{{^hasDiscriminatorWithNonEmptyMapping}}{{{schema.dataType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{#hasDiscriminatorWithNonEmptyMapping}}{{{schema.complexType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{/-first}}{{/composedSchemas.oneOf}}{{/isMap}}{{/isArray}} ${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): PromiseInterface
    {

template/api.mustache:256

  • Same issue as above for the AsyncWithHttpInfo method signature: optional oneOf params default to null, so the emitted union/class type must include null (e.g., add "|null" / nullable handling) to prevent fatal errors in generated code.
     * @deprecated
    {{/isDeprecated}}
     */
    public function {{operationId}}AsyncWithHttpInfo({{#allParams}}{{#isArray}}array{{/isArray}}{{#isMap}}array{{/isMap}}{{^isArray}}{{^isMap}}{{^composedSchemas.oneOf}}{{{dataType}}}{{/composedSchemas.oneOf}}{{#composedSchemas.oneOf}}{{#-first}}{{^hasDiscriminatorWithNonEmptyMapping}}{{{schema.dataType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{#hasDiscriminatorWithNonEmptyMapping}}{{{schema.complexType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{/-first}}{{/composedSchemas.oneOf}}{{/isMap}}{{/isArray}} ${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): PromiseInterface
    {

template/api.mustache:299

  • Same issue as above for the Request method signature: optional oneOf params still default to null, but the type hint for oneOf comes from schema.dataType/schema.complexType and may be non-nullable. Ensure nullable handling is included for optional/nullable oneOf parameters so generated code parses and runs.
     * @deprecated
    {{/isDeprecated}}
     */
    public function {{operationId}}Request({{#allParams}}{{#isArray}}array{{/isArray}}{{#isMap}}array{{/isMap}}{{^isArray}}{{^isMap}}{{^composedSchemas.oneOf}}{{{dataType}}}{{/composedSchemas.oneOf}}{{#composedSchemas.oneOf}}{{#-first}}{{^hasDiscriminatorWithNonEmptyMapping}}{{{schema.dataType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{#hasDiscriminatorWithNonEmptyMapping}}{{{schema.complexType}}}{{/hasDiscriminatorWithNonEmptyMapping}}{{/-first}}{{/composedSchemas.oneOf}}{{/isMap}}{{/isArray}} ${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): Request
    {

Comment thread template/api.mustache
@mcnulty-fp mcnulty-fp marked this pull request as ready for review May 14, 2026 18:26
@mcnulty-fp mcnulty-fp merged commit e7637fc into main May 15, 2026
20 checks passed
@mcnulty-fp mcnulty-fp deleted the chore/INTER-2038-oneof-union-support branch May 15, 2026 12:30
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.

3 participants