Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"bundle" command improperly de-indents "examples:" section, resulting in invalid spec #466

Open
kdipippo opened this issue Feb 29, 2024 · 2 comments

Comments

@kdipippo
Copy link

kdipippo commented Feb 29, 2024

Summary of Issue

I'm working through the flagged issues on the OpenAPI spec I'm using, especially with the flagged entries for where examples are missing so I can try to use this setup downstream for mocking API calls in tests. However, I've been wrestling with getting them cleared out and realized part of the issue is due to this indentation.

See the snippet at the bottom of this issue for what de-indentation is taking place. This only flags a warning on this repo with linting but causes problems with other tooling I'm working with.

EDIT: I think I'm actually just thrown on how to get that message "schema is missing examples or example to go away, no matter how I indent it when I go in manually into bundle.yaml. i.e. I copied the examples in both these places and still see the message 🤷‍♀️

responses:
    "200":
        description: Successfully retrieved simple response objects.
        content:
            application/json:
                schema:
                    type: object
                    properties: ...
                    examples:
                        apiReturnedItems: ...
                        apiReturnedEmpty: ...
                examples:
                    apiReturnedItems: ...
                    apiReturnedEmpty: ...
    "500": ...

Small Sample to Replicate Bug

openapi.yaml
openapi: 3.1.0
info:
    description: Example API spec
    version: v1
    title: Example API
    contact:
        name: Example Team
        email: [email protected]
        url: https://www.example-team.com/
    license:
        name: Example License
        url: https://www.example-license.com/
tags:
    - name: ExampleCall
      description: Example call
servers:
    - url: https://example-server.com:1234
paths:
    /api/v1/example-call:
        $ref: example-call.yaml
components:
    securitySchemes:
        BearerAuth:
            type: http
            description: Bearer token authentication.
            scheme: bearer
example-call.yaml
get:
    summary: Perform example call
    description: Example call for figuring out how to add schema and media-type examples.
    security:
        - BearerAuth: []
    tags:
        - ExampleCall
    operationId: getExampleCall
    parameters:
        - name: limit
          description: Limit to number of results
          in: query
          required: false
          schema:
            type: integer
            example: 10
          example: 10
    responses:
        "200":
            description: Successfully retrieved simple response objects.
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            Message:
                                type: string
                                description: Message response string.
                                minLength: 1
                                example: "Results found"
                            Items:
                                type: array
                                description: Array of objects returned.
                                items:
                                    type: object
                                    properties:
                                        Name:
                                            type: string
                                            description: Name field.
                                            minLength: 1
                                            example: "Example name 1"
                                    example:
                                        Name: "Example name 1"
                                example:
                                    - Name: "Example name 1"
                                    - Name: "Example name 2"
                            Count:
                                type:
                                - string
                                - "null"
                                description: Count of objects returned, null if error occured.
                                example: ""
                        examples:
                            apiReturnedItems:
                                summary: API returned items found.
                                value:
                                    Message: "Results found"
                                    Items:
                                        - Name: "Example name 1"
                                        - Name: "Example name 2"
                                    Count: "2"
                            apiReturnedEmpty:
                                summary: API returned empty results.
                                value:
                                    Message: "No results found"
                                    Items: []
                                    Count: "0"
                    example:
                        Message: "No results found"
                        Items: []
                        Count: "0"
        "500":
            description: Internal server error encountered.
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            Message:
                                type: string
                                description: Message response string.
                                minLength: 1
                                example: "Results found"
                            Items:
                                type: array
                                description: Array of objects returned.
                                items:
                                    type: object
                                    properties:
                                        Name:
                                            type: string
                                            description: Name field.
                                            minLength: 1
                                            example: "Example name 1"
                                    example:
                                        Name: "Example name 1"
                                example:
                                    - Name: "Example name 1"
                                    - Name: "Example name 2"
                            Count:
                                type:
                                - string
                                - "null"
                                description: Count of objects returned, null if error occured.
                                example: ""
                        examples:
                            apiErrorEncountered:
                                summary: API error encountered.
                                value:
                                    Message: "API error encountered"
                                    Items: []
                                    Count: null
                    example:
                        Message: null
                        Items: []

I'm using "@quobix/vacuum": "^0.9.9". With these two files, I run the following commands:

node_modules/@quobix/vacuum/bin/vacuum bundle openapi.yaml bundle.yaml
node_modules/@quobix/vacuum/bin/vacuum lint bundle.yaml -d

Result shows 2 warnings for "schema is missing examples or example". This is because the bundle command is de-indenting the first examples: in the spec:

Before: example-call.yaml

responses:
    "200":
        description: Successfully retrieved simple response objects.
        content:
            application/json:
                schema:
                    type: object
                    properties: ...
                    examples:
                        apiReturnedItems: ...
                        apiReturnedEmpty: ...
                example: ...
    "500": ...

After: bundle.yaml

responses:
    "200":
        description: Successfully retrieved simple response objects.
        content:
            application/json:
                schema:
                    type: object
                    properties: ...
                examples:
                    apiReturnedItems: ...
                    apiReturnedEmpty: ...
                example: ...
    "500": ...
@daveshanley
Copy link
Owner

I will need to load this one into my test rig and debug it.

@kdipippo
Copy link
Author

kdipippo commented Mar 5, 2024

Wondered if maybe I had incorrectly structured the file. Media Type object lists that it itself has examples while the schema object inside the Media Type object also has example, but maybe the latter is deprecated in favor of the examples array on the outer object.

But when I use my small sample with the below format in example-call.yaml:

"200":
  content:
    application/json:
      schema:
        type: object
        properties:
        example:
          ExampleField: "this is a entry field"
      examples:

And run the bundle command (node_modules/@quobix/vacuum/bin/vacuum bundle openapi.yaml bundle.yaml with version "^0.9.10"), the result is transformed into:

"200":
  content:
    application/json:
      schema:
        type: object
        properties:
        example:
          ExampleField: "this is a entry field"
      example: # <--- appears as duplicate
        ExampleField: "this is a entry field"
      examples:

Sample Files

openapi.yaml
openapi: 3.1.0
info:
    description: Example API spec
    version: v1
    title: Example API
    contact:
        name: Example Team
        email: [email protected]
        url: https://www.example-team.com/
    license:
        name: Example License
        url: https://www.example-license.com/
tags:
    - name: ExampleCall
      description: Example call
servers:
    - url: https://example-server.com:1234
paths:
    /api/v1/example-call:
        $ref: example-call.yaml
components:
    securitySchemes:
        BearerAuth:
            type: http
            description: Bearer token authentication.
            scheme: bearer
example-call.yaml
get:
    summary: Perform example call
    description: Example call for figuring out how to add schema and media-type examples.
    security:
        - BearerAuth: []
    tags:
        - ExampleCall
    operationId: getExampleCall
    parameters:
        - name: limit
          description: Limit to number of results
          in: query
          required: false
          schema:
            type: integer
            example: 10
          example: 10
    responses:
        "200":
            description: Successfully retrieved simple response objects.
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            Message:
                                type: string
                                description: Message response string.
                                minLength: 1
                                example: "Results found"
                            Items:
                                type: array
                                description: Array of objects returned.
                                items:
                                    type: object
                                    properties:
                                        Name:
                                            type: string
                                            description: Name field.
                                            minLength: 1
                                            example: "Example name 1"
                                    example:
                                        Name: "Example name 1"
                                example:
                                    - Name: "Example name 1"
                                    - Name: "Example name 2"
                            Count:
                                type:
                                - string
                                - "null"
                                description: Count of objects returned, null if error occured.
                                example: ""
                        examples:
                            apiReturnedItems:
                                summary: API returned items found.
                                value:
                                    Message: "Results found"
                                    Items:
                                        - Name: "Example name 1"
                                        - Name: "Example name 2"
                                    Count: "2"
                            apiReturnedEmpty:
                                summary: API returned empty results.
                                value:
                                    Message: "No results found"
                                    Items: []
                                    Count: "0"
        "500":
            description: Internal server error encountered.
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            Message:
                                type: string
                                description: Message response string.
                                minLength: 1
                                example: "Results found"
                            Items:
                                type: array
                                description: Array of objects returned.
                                items:
                                    type: object
                                    properties:
                                        Name:
                                            type: string
                                            description: Name field.
                                            minLength: 1
                                            example: "Example name 1"
                                    example:
                                        Name: "Example name 1"
                                example:
                                    - Name: "Example name 1"
                                    - Name: "Example name 2"
                            Count:
                                type:
                                - string
                                - "null"
                                description: Count of objects returned, null if error occured.
                                example: ""
                        example:
                            Message: "THIS EXAMPLE GETS DUPLICATED IN THE RESULT"
                            Items:
                                - Name: "Example name 1"
                                - Name: "Example name 2"
                            Count: null
                    examples:
                        apiErrorEncountered:
                            summary: API error encountered.
                            value:
                                Message: "API error encountered"
                                Items: []
                                Count: null
Makefile
install:
	npm install @quobix/vacuum

bundle:
	node_modules/@quobix/vacuum/bin/vacuum bundle openapi.yaml bundle.yaml

lint:
	node_modules/@quobix/vacuum/bin/vacuum lint bundle.yaml -d

Search for the text "THIS EXAMPLE GETS DUPLICATED IN THE RESULT" which appears once only in example-call.yaml but appears twice in bundle.yaml.

My bundle.yaml result
openapi: 3.1.0
info:
    description: Example API spec
    version: v1
    title: Example API
    contact:
        name: Example Team
        email: [email protected]
        url: https://www.example-team.com/
    license:
        name: Example License
        url: https://www.example-license.com/
tags:
    - name: ExampleCall
      description: Example call
servers:
    - url: https://example-server.com:1234
paths:
    /api/v1/example-call:
        get:
            summary: Perform example call
            description: Example call for figuring out how to add schema and media-type examples.
            security:
                - BearerAuth: []
            tags:
                - ExampleCall
            operationId: getExampleCall
            parameters:
                - name: limit
                  description: Limit to number of results
                  in: query
                  required: false
                  schema:
                    type: integer
                    example: 10
                  example: 10
            responses:
                "200":
                    description: Successfully retrieved simple response objects.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    Message:
                                        type: string
                                        description: Message response string.
                                        minLength: 1
                                        example: "Results found"
                                    Items:
                                        type: array
                                        description: Array of objects returned.
                                        items:
                                            type: object
                                            properties:
                                                Name:
                                                    type: string
                                                    description: Name field.
                                                    minLength: 1
                                                    example: "Example name 1"
                                            example:
                                                Name: "Example name 1"
                                        example:
                                            - Name: "Example name 1"
                                            - Name: "Example name 2"
                                    Count:
                                        type:
                                            - string
                                            - "null"
                                        description: Count of objects returned, null if error occured.
                                        example: ""
                            examples:
                                apiReturnedItems:
                                    summary: API returned items found.
                                    value:
                                        Message: "Results found"
                                        Items:
                                            - Name: "Example name 1"
                                            - Name: "Example name 2"
                                        Count: "2"
                                apiReturnedEmpty:
                                    summary: API returned empty results.
                                    value:
                                        Message: "No results found"
                                        Items: []
                                        Count: "0"
                "500":
                    description: Internal server error encountered.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    Message:
                                        type: string
                                        description: Message response string.
                                        minLength: 1
                                        example: "Results found"
                                    Items:
                                        type: array
                                        description: Array of objects returned.
                                        items:
                                            type: object
                                            properties:
                                                Name:
                                                    type: string
                                                    description: Name field.
                                                    minLength: 1
                                                    example: "Example name 1"
                                            example:
                                                Name: "Example name 1"
                                        example:
                                            - Name: "Example name 1"
                                            - Name: "Example name 2"
                                    Count:
                                        type:
                                            - string
                                            - "null"
                                        description: Count of objects returned, null if error occured.
                                        example: ""
                                example:
                                    Message: "THIS EXAMPLE GETS DUPLICATED IN THE RESULT"
                                    Items:
                                        - Name: "Example name 1"
                                        - Name: "Example name 2"
                                    Count: null
                            example:
                                Message: "THIS EXAMPLE GETS DUPLICATED IN THE RESULT"
                                Items:
                                    - Name: "Example name 1"
                                    - Name: "Example name 2"
                                Count: null
                            examples:
                                apiErrorEncountered:
                                    summary: API error encountered.
                                    value:
                                        Message: "API error encountered"
                                        Items: []
                                        Count: null
components:
    securitySchemes:
        BearerAuth:
            type: http
            description: Bearer token authentication.
            scheme: bearer

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

No branches or pull requests

2 participants