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
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…