astahmer / openapi-zod-client

Generate a zodios (typescript http client with zod validation) from an OpenAPI spec (json/yaml)

Home Page:openapi-zod-client.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Invalid generated makeApi endpoints object, if path specific parameters are defined

pkoo opened this issue · comments

With the release of v1.5.x a change has been added, which will create an invalid makeApi endpoints object.
The previous version (1.4.20) ignored the parameters object under a PathItem.

Within the OpenAPI Spec, a parameters entry can exist in a PathItem, which then has to be respected for each operation in that path.
OpenAPI spec

If an OpenAPI has multiple PathItem's, each with own path-specific parameters, the generated endpoints object also has multiple wrong method definitions in it.

This is a currently (v1.5.1) generated makeApi endpoint which contains (multiple) method: "parameters" objects:

const endpoints = makeApi([
    {
        method: "parameters",
        path: "/otherPets/:petId",
        requestFormat: "json",
        response: z.void(),
    },
    {
        method: "get",
        path: "/otherPets/:petId",
        requestFormat: "json",
        response: z.void(),
    },
    {
        method: "parameters",
        path: "/pet/:petId",
        requestFormat: "json",
        response: z.void(),
    },
    {
        method: "get",
        path: "/pet/:petId",
        requestFormat: "json",
        response: z.void(),
    },
    {
        method: "put",
        path: "/pet/:petId",
        description: `Update an existing pet by Id`,
        requestFormat: "json",
        parameters: [
            {
                name: "body",
                type: "Body",
                schema: Pet,
            },
        ],
        response: Pet,
    },
]);

I would like, that the path-specific parameters would be added to each operation.parameters object in that path.

const endpoints = makeApi([
    {
        method: "get",
        path: "/otherPets/:petId",
        requestFormat: "json",
        parameters: [
            {
                name: "petId", 
                type: "Path",
                schema: z.string().min(1).max(10).required()
            }
        ],
        response: Pet,
    },
    {
        method: "get",
        path: "/pet/:petId",
        requestFormat: "json",
        parameters: [
            {
                name: "petId", 
                type: "Path",
                schema: z.string().min(1).max(10).required()
            }, {
                name: "XCorrelationID",
                type: "Header",
                schema: z.string().min(36).max(256).required()
            }
        ],
        response: Pet,
    },
    {
        method: "put",
        path: "/pet/:petId",
        description: `Update an existing pet by Id`,
        requestFormat: "json",
        parameters: [
            {
                name: "petId", 
                type: "Path",
                schema: z.string().min(1).max(10)
            }, {
                name: "XCorrelationID",
                type: "Header",
                schema: z.string().min(36).max(256)
            },
            {
                name: "body",
                type: "Body",
                schema: Pet,
            },
        ],
        response: Pet,
    },
]);

Here is a reduced OpenAPI to reproduce the behaviour via https://openapi-zod-client.vercel.app

openapi: 3.0.3
info:
  title: Swagger Petstore - OpenAPI 3.0
  description: |-
    This is a sample Pet Store Server based on the OpenAPI 3.0 specification.  You can find out more about
    Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
    You can now help us improve the API whether it's by making changes to the definition itself or to the code.
    That way, with time, we can improve the API in general, and expose some of the new features in OAS3.

    _If you're looking for the Swagger 2.0/OAS 2.0 version of Petstore, then click [here](https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml). Alternatively, you can load via the `Edit > Load Petstore OAS 2.0` menu option!_

    Some useful links:
    - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
    - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
  termsOfService: http://swagger.io/terms/
  contact:
    email: apiteam@swagger.io
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.11
externalDocs:
  description: Find out more about Swagger
  url: http://swagger.io
servers:
  - url: https://petstore3.swagger.io/api/v3
tags:
  - name: pet
    description: Everything about your Pets
    externalDocs:
      description: Find out more
      url: http://swagger.io
  - name: store
    description: Access to Petstore orders
    externalDocs:
      description: Find out more about our store
      url: http://swagger.io
  - name: user
    description: Operations about user
paths:
  /pet/:petId:
    parameters:
    - name: petId
      in: path
      description: |-
        Identifier of the pet
      required: true
      schema:
        maxLength: 10
        minLength: 1
        type: string
    - name: X-Correlation-ID
      in: header
      schema:
        minLength: 36
        maxLength: 256
        type: string
      required: true
    get:
      operationId: getPetById
      responses:
        200:
          application/json:
            schema:
                $ref: "#/components/schemas/Pet"
    put:
      operationId: updatePetById
      summary: Update an existing pet
      description: Update an existing pet by Id
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Pet"
      responses:
        "200":
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pet"
  /otherPets/:petId:
    parameters:
    - name: petId
      in: path
      description: |-
        Identifier of the pet
      required: true
      schema:
        maxLength: 10
        minLength: 1
        type: string
    get:
      operationId: getOtherPetById
      responses:
        200:
          application/json:
            schema:
                $ref: "#/components/schemas/Pet"
components:
  schemas:
    Pet:
      required:
        - name
        - photoUrls
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 10
        name:
          type: string
          example: doggie
        category:
          $ref: "#/components/schemas/Category"
        photoUrls:
          type: array
          xml:
            wrapped: true
          items:
            type: string
            xml:
              name: photoUrl
        tags:
          type: array
          xml:
            wrapped: true
          items:
            $ref: "#/components/schemas/Tag"
        status:
          type: string
          description: pet status in the store
          enum:
            - available
            - pending
            - sold
      xml:
        name: pet
    Category:
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 1
        name:
          type: string
          example: Dogs
      xml:
        name: category
    Tag:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
      xml:
        name: tag

hey, by quickly looking it seems that this PR introduced the issue since I can reproduce on the preview deployment associated

i'll investigate later, unless you are already on it ?

Unfortunately not, I just can see/confirm that #74 introduced the issue.

Hope that I can get some spare time to also dig deeper into the library - and hopefully add this as a feature.

didnt know about this common parameters ! pretty cool

just pushed a PR, can you confirm this is working as intended here ? @pkoo

Yes, I tested it with quite a large API and it looks good to me.

I also did a review of your changes and added two suggestions, hope that is okay for you.

Definitely a big thank you for your fast response and change proposal!

great ! and thank you for both the review & the sponsor ! 🙏

just pushed the changes you asked, if it's fine with you we can merge