fabien0102 / openapi-codegen

A tool for generating code base on an OpenAPI schema.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pathParams in kebab-case not recognized by resolveUrl and resolvePathParam

antoniel opened this issue · comments

Hi there,

I found an issue in the resolveUrl function and the resolvePathParam function in prefixContext.ts, where pathParams in kebab-case are not recognized correctly. For example, the function fails to recognize a URL like /some/{some-data-id}/foo.

The problem seems to be caused by the pathParams URL replacement not recognizing words generated in kebab-case format. As the type GetSomeSomeTemplateDataIdFooPathParams generates keys in camelCase format, we also need to convert the object access to camelCase.

I suggest the following solution for resolveUrl:

const resolveUrl = (url: string, queryParams: Record<string, string> = {}, pathParams: Record<string, string> = {}) => {
  let query = new URLSearchParams(queryParams).toString()
  if (query) query = `?${query}`
  return (
    url.replace(/\{[\w-]*\}/g, (key) => {
      const keyWithoutCurlyBrackets = key.slice(1, -1)
      return pathParams[parseToCamelCaseIfKebabCase(keyWithoutCurlyBrackets)]
    }) + query
  )
}

export const parseToCamelCaseIfKebabCase = (key: string) => {
  if (key.includes('-')) {
    return key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())
  }
  return key
}

Additionally, the same issue occurs in the resolvePathParam function in prefixContext.ts, and the same fix should be applied. Here's how the updated resolvePathParam function should look:

// Helpers
const resolvePathParam = (key: string, pathParams: Record<string, string>) => {
  if (key.startsWith('{') && key.endsWith('}')) {
    return pathParams[parseToCamelCaseIfKebabCase(key.slice(1, -1))]
  }
  return key
}

I hope this helps in addressing the issue. Please let me know if you need any further clarification or if there's a better approach to handle this problem. If you find this solution acceptable, I'd be more than happy to contribute by submitting a pull request with the proposed changes.

Thanks!

I don't have my computer around to try out, but I'm not sure I get the issue. Normally the path params are parsed in camelCase, this is expected, this is to have a better user API at the end.

Can you actually provide an OpenAPI spec as example with the generated output?

I will check if you we have a unit test for this ;)

As you mentioned, the path parameters are indeed passed in camelCase and that part works correctly. However, the current regex in resolveUrl, /\{\w*\}/g, acts on the raw URL coming from the OpenAPI file, and this regex does not match words separated by dashes "-". That's why I made a modification to use a new regex: /\{[\w-]*\}/g.

Currently, if we have an input for /templates/{template-data-id}/assets, we end up with an output:
path: /templates/%7Btemplate-data-id%7D/assets

Adding bellow an OpenAPI spec where this behavior is reproducible:

openapi: 3.1.0
info:
  title: test
  version: '1.0'
paths:
  '/templates/{template-data-id}/assets':
    parameters:
      - schema:
          type: integer
          format: int64
        name: template-data-id
        in: path
        required: true
    get:
      summary: Test
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    asset_id:
                      type: integer
                      format: int64
        '400':
          $ref: '#/components/responses/Error-Response'
        '401':
          $ref: '#/components/responses/Error-Response'
        '500':
          description: Internal Server Error
components:
  responses:
    Error-Response:
      description: Error response
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
            required:
              - error
    Success-Response:
      description: Example response
      content:
        application/json:
          schema:
            type: object
            properties:
              ok:
                type: boolean
            required:
              - ok
current {\w*} proposal {[\w-]*}
image image

Oki, I get it! And indeed a PR to fix this will be welcome, the fix seams legit :) good catch!

Figured out that the same issue follow also for pathParams declared as sneak_case, I'll add it on the #165

Should be fixed in the 6.2.3 😁
Thanks again for the report and nice repro steps!

You can revert your change in the context and fetcher template normally since I fixed the components generation directly (cf #166)

the new regex in the latest release breaks generation with multiple path params,
e.g. instead of /api/apps/{appId}/versions/{version} it generates /api/apps/{appIdVersionsVersion}

Indeed! This is why you should never rush to push something in production 😅 Fixing…