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

parameters defined directly under a path no longer gets merged to parameters defined under a specific operation for that path #1065

Closed
2 tasks
olivierbeaulieu opened this issue Apr 3, 2023 · 7 comments · Fixed by #1090
Labels
bug Something isn't working

Comments

@olivierbeaulieu
Copy link

Description

When parameters are defined for all operations under a path (common usage is for path params), as of v6 they are no longer added to the parameters of every operation under it.

In the examples below, notice how thread_id use to be added to the definition of get_comment_resource and post_comment_resource. Under v6, that is no longer the case.

OpenAPI

{
  "openapi": "3.0.2",
  "servers": [],
  "paths": {
    "/v1/auth/comments/{thread_id}": {
      "get": {
        "operationId": "get_comment_resource",
        "parameters": [
          {
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "start",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "type": "string"
          }
        }
      },
      "parameters": [
        {
          "in": "path",
          "name": "thread_id",
          "required": true,
          "type": "string"
        }
      ],
      "post": {
        "operationId": "post_comment_resource",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "body": {
                    "type": "string"
                  },
                  "parent_id": {
                    "type": "string"
                  }
                },
                "required": ["body"],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "type": "string"
          }
        }
      }
    }
  },
  "components": {
    "schemas": []
  }
}

Generated TS

/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */

export interface paths {
  '/v1/auth/comments/{thread_id}': {
    get: operations['get_comment_resource']
    post: operations['post_comment_resource']
    parameters: {
      path: {
        thread_id: string
      }
    }
  }
}

export type webhooks = Record<string, never>
export type external = Record<string, never>

export interface operations {
  get_comment_resource: {
    parameters: {
      query: {
        page_size?: number
        start?: string
      }
    }
    responses: {
      200: never
    }
  }
  post_comment_resource: {
    requestBody: {
      content: {
        'application/json': {
          body: string
          parent_id?: string
        }
      }
    }
    responses: {
      201: never
    }
  }
}

*Expected TS, output from v5.4.1

/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */

export interface paths {
  '/v1/auth/comments/{thread_id}': {
    get: operations['get_comment_resource']
    post: operations['post_comment_resource']
    parameters: {
      path: {
        thread_id: unknown
      }
    }
  }
}

export interface operations {
  get_comment_resource: {
    parameters: {
      path: {
        thread_id: unknown
      }
      query: {
        page_size?: number
        start?: unknown
      }
    }
    responses: {
      200: unknown
    }
  }
  post_comment_resource: {
    parameters: {
      path: {
        thread_id: unknown
      }
    }
    responses: {
      201: unknown
    }
    requestBody: {
      content: {
        'application/json': {
          body: string
          parent_id?: string
        }
      }
    }
  }
}

export interface external {}

Checklist

  • My OpenAPI schema passes a validator
  • I’m willing to open a PR for this (see CONTRIBUTING.md)
@olivierbeaulieu olivierbeaulieu added the bug Something isn't working label Apr 3, 2023
@drwpow
Copy link
Contributor

drwpow commented Apr 3, 2023

A bug was fixed in the last few days that should have addressed this. Can you confirm this is in the latest version (6.2.1)?

@olivierbeaulieu
Copy link
Author

This is in 6.2.1 yes!

@drwpow
Copy link
Contributor

drwpow commented Apr 3, 2023

OK. Then it’s probably a minor, fixable oversight. #1061 fixed several longstanding issues with parameters that had existed in all previous versions. So this specific bug should be able to be fixed without too much fuss.

@drwpow
Copy link
Contributor

drwpow commented Apr 7, 2023

Ah I think your schema is invalid—it should be:

  {
    "in": "path",
    "name": "thread_id",
    "required": true,
-   "type": "string"
+   "schema": { "type": "string" }
  }

Sidenote: that’s why the [ ] My schema passes a validator check is required. This library does NOT validate your schema since other tools can do that.

I noticed a few other validation errors in your schema, but I believe this one could be causing the issue. After all the validation errors are fixed, please let me know if it’s still generating unexpected output

@drwpow drwpow added the question Further information is requested label Apr 7, 2023
@olivierbeaulieu
Copy link
Author

Sorry about that! I can't share the actual spec publicly, so I made an attempt at simplifying it - but clearly poorly. The original spec is definitely valid. Here's an updated example that actually is valid:

{
  "openapi": "3.0.2",
  "info": {
    "title": "Foo",
    "version": "1.0.0"
  },
  "servers": [],
  "paths": {
    "/v1/auth/comments/{thread_id}": {
      "get": {
        "operationId": "get_comment_resource",
        "parameters": [
          {
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "start",
            "required": false,
            "schema": {
              "nullable": true,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedResponseCommentDumpSchema"
                }
              }
            },
            "description": "Success"
          }
        },
        "security": [],
        "summary": "Returns comments associated with a given thread",
        "tags": ["Comments"]
      },
      "parameters": [
        {
          "in": "path",
          "name": "thread_id",
          "required": true,
          "schema": {
            "format": "uuid",
            "type": "string"
          },
          "style": "simple"
        }
      ],
      "post": {
        "operationId": "post_comment_resource",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateComment"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Success"
          }
        },
        "security": [],
        "summary": "Create a comment and add to thread",
        "tags": ["Comments"]
      }
    }
  },
  "components": {
    "schemas": {
      "PaginatedResponseCommentDumpSchema": {
        "properties": {
          "total_count": {
            "type": "integer"
          }
        },
        "type": "object"
      },
      "CreateComment": {
        "properties": {
          "body": {},
          "mentions": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "message": {
            "default": "",
            "type": "string"
          }
        },
        "type": "object"
      }
    }
  }
}

@mitchell-merry
Copy link
Contributor

Minimal reproduction:

paths:
  /bar:
    get: {}
    post: {}
    parameters:
    - name: my_param
      in: query
      schema:
        type: string

generates:

export interface paths {
  "/bar": {
    get: {
    };
    post: {
    };
    parameters?: {
      query?: {
        my_param?: string;
      };
    };
  };
}

Honestly, I'm pretty confused. We have a test for this: https://github.com/drwpow/openapi-typescript/blob/main/test/paths-object.test.ts#L24-L95 which passes, but if I take that exact schema and try it locally I see the behavior described in this issue.

@drwpow
Copy link
Contributor

drwpow commented Apr 26, 2023

Ahh I see now! @olivierbeaulieu thanks for providing a complete example. Yes this is an issue with how the operations get hoisted up and merged together—there is a bug in that bit of magic. But shouldn’t be too hard to fix!

@drwpow drwpow removed the question Further information is requested label Apr 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants