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 b442b76
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 14 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();
};

0 comments on commit b442b76

Please sign in to comment.