ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
136 stars 64 forks source link

OneOf with several fields declared as required generates `anydata` type #6127

Closed dilanSachi closed 1 month ago

dilanSachi commented 8 months ago

Description: Consider the following component schema.

    RenderRequest:
      oneOf:
        - required:
            - url
        - required:
            - html
      properties:
        block_ads:
          description: Whether to block ads on the rendered page
          type: boolean
        click_accept:
          description: Whether to automatically click accept buttons on the rendered page
          type: boolean
        delay:
          description: The amount of milliseconds to delay before taking a screenshot
          type: string
        format:
          description: The format of the rendered output
          enum:
            - png
            - jpg
            - pdf
            - svg
            - mp4
            - webp
            - webm
            - html
          type: string
        full_page:
          description: Whether to capture the full page
          type: boolean
        gpu:
          description: Whether to enable GPU rendering
          type: boolean
        height:
          description: The viewport height of the rendered output
          type: integer
        hide_cookie_banners:
          description: Whether to hide cookie banners on the rendered page
          type: boolean
        html:
          description: The raw HTML to render as an image or video
          type: string
        metadata:
          description: Whether to return metadata about the URL
          type: boolean
        retina:
          description: Whether to render the image in retina quality
          type: boolean
        selector:
          description: The CSS selector of an element you would like to capture
          type: string
        thumb_height:
          description: The height of the thumbnail image
          type: integer
        thumb_width:
          description: The width of the thumbnail image
          type: integer
        url:
          description: The URL to render as an image or video
          type: string
        wait_for:
          description: CSS selector of an element to wait to be present in the web page before rendering
          type: string
        wait_to_leave:
          description: CSS selector of an element, such as a loading spinner, to wait to leave the web page before rendering
          type: string
        wait_until:
          description: When
          enum:
            - requestsfinished
            - mostrequestsfinished
            - loaded
            - domloaded
          type: string
        width:
          description: The viewport width of the rendered output
          type: integer
      type: object

Atm, what we generate for this is,

public type RenderRequest anydata|anydata;

As it is difficult to denote oneof & required types in a ballerina record. We can either generate 2 records with the 2 required oneof fields or generate a union type with the 2 required fields.

TharmiganK commented 8 months ago

Do you mean something like this:

public type RenderRequestOptional record {|
    boolean block_ads?;
    boolean click_accept?;
    string delay?;
    "png"| "jpg"| "pdf"| "svg"| "mp4"| "webp"| "webm"| "html" format?;
    boolean full_page?;
    boolean gpu?;
    int height?;
    boolean hide_cookie_banners?;
    string html?;
    boolean metadata?;
    boolean retina?;
    string selector?;
    int thumb_height?;
    int thumb_width?;
    string url?;
    string wait_for?;
    string wait_to_leave?;
    "requestsfinished"|"mostrequestsfinished"|"loaded"|"domloaded" wait_until?;
    int width?;
|};

public type RenderRequestWithUrl record {|
    *RenderRequestOptional;
    string url;
|};

public type RenderRequestWithHtml record {|
    *RenderRequestOptional;
    string html;
|};

public type RenderRequest RenderRequestWithUrl|RenderRequestWithHtml;
dilanSachi commented 8 months ago

Added a question on OAS spec also - https://github.com/OAI/OpenAPI-Specification/issues/3618

dilanSachi commented 8 months ago

According to the above discussion, this is a valid schema definition.

TharmiganK commented 8 months ago

As per the discussion, the record should have exactly one of url or html. In that case the generated records should look like this:

// Note that the `url` and `html` fields are not defined in this record
public type RenderRequestCommon record {|
    boolean block_ads?;
    boolean click_accept?;
    string delay?;
    "png"| "jpg"| "pdf"| "svg"| "mp4"| "webp"| "webm"| "html" format?;
    boolean full_page?;
    boolean gpu?;
    int height?;
    boolean hide_cookie_banners?;
    boolean metadata?;
    boolean retina?;
    string selector?;
    int thumb_height?;
    int thumb_width?;
    string wait_for?;
    string wait_to_leave?;
    "requestsfinished"|"mostrequestsfinished"|"loaded"|"domloaded" wait_until?;
    int width?;
|};

public type RenderRequestWithUrl record {|
    *RenderRequestOptional;
    string url;
|};

public type RenderRequestWithHtml record {|
    *RenderRequestOptional;
    string html;
|};

public type RenderRequest RenderRequestWithUrl|RenderRequestWithHtml;
dilanSachi commented 7 months ago

As this is a rare case and will be complex to implement, we only generate public type RenderRequest anydata; at the moment. Will unmark this as a bug and consider this as an improvement.

lnash94 commented 1 month ago

Close this issue since this is not in the 80% case