openapi-typescript-codegen icon indicating copy to clipboard operation
openapi-typescript-codegen copied to clipboard

Duplicate identifier for parameters with the same name but different location/in

Open jesperkristensen opened this issue 5 years ago • 7 comments

I am using an OpenAPI v3 spec generated by NSwag where the Parameters Object of one of the Operations has two parameters with the same name, but with different Locations ("in": "query" vs. "in": "path")

According to the spec, this should be valid: "A unique parameter is defined by a combination of a name and location."

When I generate code for this spec, the code has a typescript error "error TS2300: Duplicate identifier".

...
    "/MyPath/{myParam}": {
      "get": {
        ...,
        "parameters": [
          {
            "name": "myParam",
            "in": "query",
            "schema": {
              "type": "string",
              "nullable": true
            },
            "x-position": 1
          },
          {
            "name": "myParam",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "x-position": 2
          }
        ],
...

jesperkristensen avatar Dec 02 '20 07:12 jesperkristensen

Good point @jesperkristensen will schedule this for the next release

ferdikoomen avatar Dec 16 '20 18:12 ferdikoomen

any news?

reslear avatar Oct 24 '21 13:10 reslear

I'm seeing something similar where an in: path parameter from https://github.com/Asana/developer-docs/blob/adce34cf63465d2f934a6d6e8c1b636adcf6960f/defs/asana_oas.yaml#L7616-L7618 as defined in https://github.com/Asana/developer-docs/blob/adce34cf63465d2f934a6d6e8c1b636adcf6960f/defs/asana_oas.yaml#L1026-L1035 is duplicated:

$ rm -rf junk && npx [email protected] --input=https://raw.githubusercontent.com/Asana/developer-docs/master/defs/asana_oas.yaml --output=junk
$ grep -h -r -A 3 'public static getProjectStatusesForProject' junk/
    public static getProjectStatusesForProject(
        projectGid: string,
        projectGid: string,
        optPretty?: boolean,

tv42 avatar Dec 07 '21 19:12 tv42

Having similar issue:

in:

    "/admin/customFieldSettings/bundles/build/{id}" : {
      "description" : "This resource provides operations with sets of builds.",
      "get" : {
        "parameters" : [ {
          "name" : "fields",
          "in" : "query",
          "schema" : {
            "type" : "string"
          },
          "example" : "$type,id"
        }, {
          "name" : "id",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "single BuildBundle",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/BuildBundle"
                }
              }
            }
          }
        }
      },
      "post" : {
        "parameters" : [ {
          "name" : "fields",
          "in" : "query",
          "schema" : {
            "type" : "string"
          },
          "example" : "$type,id"
        }, {
          "name" : "id",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/BuildBundle"
              }
            }
          }
        },
        "responses" : {
          "200" : {
            "description" : "single BuildBundle",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/BuildBundle"
                }
              }
            }
          }
        }
      },
      "delete" : {
        "parameters" : [ {
          "name" : "id",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK"
          }
        }
      },
      "parameters" : [ {
        "name" : "id",
        "in" : "path",
        "required" : true,
        "schema" : {
          "type" : "string"
        }
      } ]
    },

out

    /**
     * @param fields 
     * @param skip 
     * @param top 
     * @returns BuildBundle collection of BuildBundle
     * @throws ApiError
     */
    public static getAdminCustomFieldSettingsBundlesBuild(
fields?: string,
skip?: number,
top?: number,
): CancelablePromise<Array<BuildBundle>> {
        return __request(OpenAPI, {
            method: 'GET',
            url: '/admin/customFieldSettings/bundles/build',
            query: {
                'fields': fields,
                '$skip': skip,
                '$top': top,
            },
        });
    }

    /**
     * @param fields 
     * @param requestBody 
     * @returns BuildBundle single BuildBundle
     * @throws ApiError
     */
    public static postAdminCustomFieldSettingsBundlesBuild(
fields?: string,
requestBody?: BuildBundle,
): CancelablePromise<BuildBundle> {
        return __request(OpenAPI, {
            method: 'POST',
            url: '/admin/customFieldSettings/bundles/build',
            query: {
                'fields': fields,
            },
            body: requestBody,
            mediaType: 'application/json',
        });
    }

    /**
     * @param id 
     * @param id 
     * @param fields 
     * @returns BuildBundle single BuildBundle
     * @throws ApiError
     */
    public static getAdminCustomFieldSettingsBundlesBuild1(
id: string,
id: string,
fields?: string,
): CancelablePromise<BuildBundle> {
        return __request(OpenAPI, {
            method: 'GET',
            url: '/admin/customFieldSettings/bundles/build/{id}',
            path: {
                'id': id,
                'id': id,
            },
            query: {
                'fields': fields,
            },
        });
    }

    /**
     * @param id 
     * @param id 
     * @param fields 
     * @param requestBody 
     * @returns BuildBundle single BuildBundle
     * @throws ApiError
     */
    public static postAdminCustomFieldSettingsBundlesBuild1(
id: string,
id: string,
fields?: string,
requestBody?: BuildBundle,
): CancelablePromise<BuildBundle> {
        return __request(OpenAPI, {
            method: 'POST',
            url: '/admin/customFieldSettings/bundles/build/{id}',
            path: {
                'id': id,
                'id': id,
            },
            query: {
                'fields': fields,
            },
            body: requestBody,
            mediaType: 'application/json',
        });
    }

    /**
     * @param id 
     * @param id 
     * @returns any OK
     * @throws ApiError
     */
    public static deleteAdminCustomFieldSettingsBundlesBuild(
id: string,
id: string,
): CancelablePromise<any> {
        return __request(OpenAPI, {
            method: 'DELETE',
            url: '/admin/customFieldSettings/bundles/build/{id}',
            path: {
                'id': id,
                'id': id,
            },
        });
    }

xobotyi avatar Mar 11 '22 11:03 xobotyi

same problem with in: cookie, in: query

      parameters:
        - name: state
          description: Base64 encoded JSON representation of object with `redirectURL` field
          schema:
            type: string
          required: true
          in: query
        - name: state
          description: Service set secure cookie with base64 encoded JSON representation of object with `redirectURL` field
          schema:
            type: string
          required: true
          in: cookie

kobzarvs avatar Jul 06 '22 07:07 kobzarvs

fix PR: https://github.com/ferdikoomen/openapi-typescript-codegen/pull/1126

kobzarvs avatar Jul 06 '22 19:07 kobzarvs

Seeing a similar issue here:

"impersonationUserId": {
      "name": "User-Id",
      "in": "header",
      "type": "string",
      "format": "uuid",
      "required": false,
      "description": "",
      "x-example": "User123"
    },

and:

"userId": {
      "name": "userId",
      "in": "path",
      "type": "string",
      "format": "uuid",
      "required": true,
      "description": "",
      "x-example": "User123"
    },

Both are output as userId on the options object because they have a similar "name" property. But one is in the header and one is in the path.

akinnee avatar Sep 22 '22 23:09 akinnee