Skip to content

Commit

Permalink
fix(fetch): take param serializer setting into account
Browse files Browse the repository at this point in the history
  • Loading branch information
AllieJonsson committed Jan 8, 2025
1 parent de20293 commit cf1f4b5
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 43 deletions.
7 changes: 5 additions & 2 deletions docs/src/pages/reference/configuration/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,8 @@ Use this property to add a custom params serializer to all requests that use que

If you provide an object you can also add a default property to use an export default function.

If this is not specified, params are serialized as per `axios` default when using `axios`, or by using `URLSearchParams` when using `fetch`.

Example:

```js
Expand Down Expand Up @@ -1759,9 +1761,10 @@ export const customParamsSerializerFn = (

Type: `Object`

Use this property to add a default params serializer. Current options are: `qs`.
Use this property to decide how params are serialized. This is only taken into account when `paramsSerializer` is not defined.
Currently, only `qs` is the available option. Read more about `qs` and it's settings [here](https://www.npmjs.com/package/qs).

All options are then passed to the chosen serializer.
If this is not specified, params are serialized as per `axios` default when using `axios`, or by using `URLSearchParams` when using `fetch`.

Example:

Expand Down
56 changes: 44 additions & 12 deletions packages/fetch/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
generateBodyOptions,
isObject,
resolveRef,
GeneratorDependency,
ClientDependenciesBuilder,
} from '@orval/core';
import {
PathItemObject,
Expand Down Expand Up @@ -86,23 +88,30 @@ export const generateRequestFunction = (
normalizedParams.append(key, value === null ? 'null' : value.toString())
}`;

const getUrlFnImplementation = `export const ${getUrlFnName} = (${getUrlFnProps}) => {
${
queryParams
? ` const normalizedParams = new URLSearchParams();
const queryImplementation = queryParams
? override.paramsSerializer
? `const normalizedParams = ${override.paramsSerializer.name}(params);`
: override.paramsSerializerOptions?.qs
? `const normalizedParams = qs.stringify(params, ${JSON.stringify(
override.paramsSerializerOptions!.qs,
)});`
: `const normalizedParams = new URLSearchParams();
Object.entries(params || {}).forEach(([key, value]) => {
${explodeArrayImplementation}
${!isExplodeParametersOnly ? nomalParamsImplementation : ''}
});`
: ''
}
: '';
const returnQueryImplementation = queryParams
? override.paramsSerializer || override.paramsSerializerOptions?.qs
? `return normalizedParams ? \`${route}${'?${normalizedParams}'}\` : \`${route}\``
: `return normalizedParams.size ? \`${route}${'?${normalizedParams.toString()}'}\` : \`${route}\``
: `return \`${route}\``;

${
queryParams
? `return normalizedParams.size ? \`${route}${'?${normalizedParams.toString()}'}\` : \`${route}\``
: `return \`${route}\``
}
const getUrlFnImplementation = `export const ${getUrlFnName} = (${getUrlFnProps}) => {
${queryImplementation}
${returnQueryImplementation}
}\n`;

const isNdJson = response.contentTypes.some(
Expand Down Expand Up @@ -235,9 +244,32 @@ export const generateClient: ClientBuilder = (verbOptions, options) => {
};
};

const PARAMS_SERIALIZER_DEPENDENCIES: GeneratorDependency[] = [
{
exports: [
{
name: 'qs',
default: true,
values: true,
syntheticDefaultImport: true,
},
],
dependency: 'qs',
},
];

const getFetchDependencies: ClientDependenciesBuilder = (
_: boolean,
hasParamsSerializerOptions: boolean,
) => {
return [
...(hasParamsSerializerOptions ? PARAMS_SERIALIZER_DEPENDENCIES : []),
];
};

const fetchClientBuilder: ClientGeneratorsBuilder = {
client: generateClient,
dependencies: () => [],
dependencies: getFetchDependencies,
};

export const builder = () => () => fetchClientBuilder;
Expand Down
31 changes: 31 additions & 0 deletions tests/configs/default.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,35 @@ export default defineConfig({
target: '../specifications/petstore.yaml',
},
},
paramsSerializer: {
output: {
target: '../generated/default/params-serializer/endpoints.ts',
schemas: '../generated/default/params-serializer/model',
override: {
paramsSerializer: {
path: '../mutators/params-serializer.ts',
name: 'customParamsSerializer',
},
},
},
input: {
target: '../specifications/petstore.yaml',
},
},
paramsSerializerOptions: {
output: {
target: '../generated/default/params-serializer-options/endpoints.ts',
schemas: '../generated/default/params-serializer-options/model',
override: {
paramsSerializerOptions: {
qs: {
arrayFormat: 'repeat',
},
},
},
},
input: {
target: '../specifications/petstore.yaml',
},
},
});
33 changes: 33 additions & 0 deletions tests/configs/fetch.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,37 @@ export default defineConfig({
target: '../specifications/parameters.yaml',
},
},
paramsSerializer: {
output: {
target: '../generated/fetch/params-serializer/endpoints.ts',
schemas: '../generated/fetch/params-serializer/model',
client: 'fetch',
override: {
paramsSerializer: {
path: '../mutators/params-serializer.ts',
name: 'customParamsSerializer',
},
},
},
input: {
target: '../specifications/petstore.yaml',
},
},
paramsSerializerOptions: {
output: {
target: '../generated/fetch/params-serializer-options/endpoints.ts',
schemas: '../generated/fetch/params-serializer-options/model',
client: 'fetch',
override: {
paramsSerializerOptions: {
qs: {
arrayFormat: 'repeat',
},
},
},
},
input: {
target: '../specifications/petstore.yaml',
},
},
});
11 changes: 11 additions & 0 deletions tests/mutators/params-serializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const customParamsSerializer = (params: Record<string, any>): string => {
const normalizedParams = new URLSearchParams();

Object.entries(params || {}).forEach(([key, value]) => {
if (value !== undefined) {
normalizedParams.append(key, value === null ? 'null' : value.toString());
}
});

return normalizedParams.toString();
};
58 changes: 29 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1253,23 +1253,23 @@ __metadata:
languageName: node
linkType: hard

"@orval/angular@npm:7.3.0, @orval/angular@workspace:packages/angular":
"@orval/angular@npm:7.4.0, @orval/angular@workspace:packages/angular":
version: 0.0.0-use.local
resolution: "@orval/angular@workspace:packages/angular"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
languageName: unknown
linkType: soft

"@orval/axios@npm:7.3.0, @orval/axios@workspace:packages/axios":
"@orval/axios@npm:7.4.0, @orval/axios@workspace:packages/axios":
version: 0.0.0-use.local
resolution: "@orval/axios@workspace:packages/axios"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
languageName: unknown
linkType: soft

"@orval/core@npm:7.3.0, @orval/core@workspace:packages/core":
"@orval/core@npm:7.4.0, @orval/core@workspace:packages/core":
version: 0.0.0-use.local
resolution: "@orval/core@workspace:packages/core"
dependencies:
Expand Down Expand Up @@ -1308,62 +1308,62 @@ __metadata:
languageName: unknown
linkType: soft

"@orval/fetch@npm:7.3.0, @orval/fetch@workspace:packages/fetch":
"@orval/fetch@npm:7.4.0, @orval/fetch@workspace:packages/fetch":
version: 0.0.0-use.local
resolution: "@orval/fetch@workspace:packages/fetch"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
languageName: unknown
linkType: soft

"@orval/hono@npm:7.3.0, @orval/hono@workspace:packages/hono":
"@orval/hono@npm:7.4.0, @orval/hono@workspace:packages/hono":
version: 0.0.0-use.local
resolution: "@orval/hono@workspace:packages/hono"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/zod": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
"@orval/zod": "npm:7.4.0"
"@types/lodash.uniq": "npm:^4.5.7"
lodash.uniq: "npm:^4.5.0"
languageName: unknown
linkType: soft

"@orval/mock@npm:7.3.0, @orval/mock@workspace:packages/mock":
"@orval/mock@npm:7.4.0, @orval/mock@workspace:packages/mock":
version: 0.0.0-use.local
resolution: "@orval/mock@workspace:packages/mock"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
lodash.get: "npm:^4.4.2"
lodash.omit: "npm:^4.5.0"
openapi3-ts: "npm:^4.2.2"
languageName: unknown
linkType: soft

"@orval/query@npm:7.3.0, @orval/query@workspace:packages/query":
"@orval/query@npm:7.4.0, @orval/query@workspace:packages/query":
version: 0.0.0-use.local
resolution: "@orval/query@workspace:packages/query"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/fetch": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
"@orval/fetch": "npm:7.4.0"
"@types/lodash.omitby": "npm:^4.6.7"
lodash.omitby: "npm:^4.6.0"
vitest: "npm:^0.34.6"
languageName: unknown
linkType: soft

"@orval/swr@npm:7.3.0, @orval/swr@workspace:packages/swr":
"@orval/swr@npm:7.4.0, @orval/swr@workspace:packages/swr":
version: 0.0.0-use.local
resolution: "@orval/swr@workspace:packages/swr"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/fetch": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
"@orval/fetch": "npm:7.4.0"
languageName: unknown
linkType: soft

"@orval/zod@npm:7.3.0, @orval/zod@workspace:packages/zod":
"@orval/zod@npm:7.4.0, @orval/zod@workspace:packages/zod":
version: 0.0.0-use.local
resolution: "@orval/zod@workspace:packages/zod"
dependencies:
"@orval/core": "npm:7.3.0"
"@orval/core": "npm:7.4.0"
"@types/lodash.uniq": "npm:^4.5.7"
lodash.uniq: "npm:^4.5.0"
languageName: unknown
Expand Down Expand Up @@ -7578,15 +7578,15 @@ __metadata:
resolution: "orval@workspace:packages/orval"
dependencies:
"@apidevtools/swagger-parser": "npm:^10.1.0"
"@orval/angular": "npm:7.3.0"
"@orval/axios": "npm:7.3.0"
"@orval/core": "npm:7.3.0"
"@orval/fetch": "npm:7.3.0"
"@orval/hono": "npm:7.3.0"
"@orval/mock": "npm:7.3.0"
"@orval/query": "npm:7.3.0"
"@orval/swr": "npm:7.3.0"
"@orval/zod": "npm:7.3.0"
"@orval/angular": "npm:7.4.0"
"@orval/axios": "npm:7.4.0"
"@orval/core": "npm:7.4.0"
"@orval/fetch": "npm:7.4.0"
"@orval/hono": "npm:7.4.0"
"@orval/mock": "npm:7.4.0"
"@orval/query": "npm:7.4.0"
"@orval/swr": "npm:7.4.0"
"@orval/zod": "npm:7.4.0"
"@types/inquirer": "npm:^9.0.6"
"@types/js-yaml": "npm:^4.0.8"
"@types/lodash.uniq": "npm:^4.5.8"
Expand Down

0 comments on commit cf1f4b5

Please sign in to comment.