-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
[BUG][typescript-axios] Generated JavaScript Sets are not serialized/deserialized #11746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I ran into the same issue. As a workaround, as suggested here: #8258 (comment) adding this typemapping fixed it for me: (gradle kotlin dsl)
|
when requests go over the wire, sets should become arrays. OpenAPITools/openapi-generator#11746 for reference
* feat: serialize sets to array for payloads when requests go over the wire, sets should become arrays. OpenAPITools/openapi-generator#11746 for reference --- Co-authored-by: Drew Kimberly <[email protected]>
I'm running into the same problem. We use the typescript-axios generator from OpenAPI Generator (maven Plugin - v. 6.6.0).
in the process of the typescript code generation, we get
when using the generated client to send the object to the backend (SpringBoot Server) it results into a json with an empty object instead of an array: As a result our springboot controller can not handle the request. Is a fix of this bug planned? |
@JulienDeBerlin the quick fix is to just cast your stuff to an array/set in TypeScript. |
Hi @BernhardPosselt, i guess I could convert the set into an array and then write my own axios client that accepts this customed object as param. But the all idea of using openapi was for us to use the generated DTOs and clients. |
You always want a wrapper around the generated client because the generated client will inevitably change when you upgrade the lib. The wrapper around it will allow you to change behavior in one place and not in multiple locations. So put those casts there ;) |
Actually i already use a wrapper arround the client because it was the only way i found to customize the basePath. But in that case, i'm not sure how it can help me. For instance this is one of methods in the generated client:
The expected param is of type Resource (generated based on the openapi description): export interface Resource {
} but in that case I wouldn't use the generated method at all. May be I'm missing the point. |
use saveResource({
// other stuff here
catalogTitles: ['a', 'b'] as unknown as Set<string>,
}) |
Got it, it's all about to silence TypeScript's type-checking. It works and was a great help. Thanks. |
This PR fixes the serialization problem: #17790 |
If you want a quick and dirty(!) hack that can break with any change to the generator, you can add this after generating the client: # HACK: Will be solved by https://github.com/OpenAPITools/openapi-generator/pull/17790/files
(
cd "YOUR_OUTPUT_DIRECTORY"
convert_maps_and_sets='(function convertMapsAndSetsToPlain(value: any): any {if (typeof value !== "object" || !value) {return value;} if (value instanceof Set) { return Array.from(value).map(item => convertMapsAndSetsToPlain(item)); } if (value instanceof Map) { return Object.fromEntries([...value.entries()].map(([k, v]) => [k, convertMapsAndSetsToPlain(v)])); } if (Array.isArray(value)) { return value.map(it => convertMapsAndSetsToPlain(it)); } return Object.fromEntries(Object.entries(value) .map(([k, v]) => [k, convertMapsAndSetsToPlain(v)])); })'
for f in `find . -name '*.ts' -type f`; do
if cat "$f" | grep -q 'convertMapsAndSets'; then
continue
fi
sed -i '' -e "s/JSON.stringify(\(.*\))$/JSON.stringify(${convert_maps_and_sets}(\1))/g" "$f"
done
) |
@macjohnny This can be closed now too. Which version will the fix land in? |
looking at https://github.com/OpenAPITools/openapi-generator/milestones, this should be released in april |
The fix (#17790) got reverted in Version |
@cauterize do you want to fix this? |
This is sadly way beyond my skills 🙁 We are using a common workaround on the Typescript side for now. // Workaround for typed Sets in generated service methods
// https://github.com/OpenAPITools/openapi-generator/issues/14055
// https://github.com/OpenAPITools/openapi-generator/issues/11746
export const mapSetForContracts = <T>(set: Set<T>): Set<T> => {
return Array.from(set.values()) as unknown as Set<T>;
}; I just wanted to reopen this for transparency reasons. |
Because we have `uniqueItems: true` in our service definition yaml, fields with `type: array` are generated as `Set`s by the typescript generator. Serialization/deserialization of these types is [broken](OpenAPITools/openapi-generator#11746) so where we use these APIs [we pass arrays with `@ts-expect-error` anyway](https://github.com/ipfs/helia-remote-pinning/blob/main/src/heliaRemotePinner.ts#L155). It doesn't look possible to override the use of Set by the generator in a way that works (`type-mappings=set=array` produces uncompilable code) so manually change the generated code. Also adds a note to the readme reminding people to do it. BREAKING CHANGE: fields that were Sets such as `PinResults.results` and `PinsGetRequest.cid` are now Arrays
Because we have `uniqueItems: true` in our service definition yaml, fields with `type: array` are generated as `Set`s by the typescript generator. Serialization/deserialization of these types is [broken](OpenAPITools/openapi-generator#11746) so where we use these APIs [we pass arrays with `@ts-expect-error` anyway](https://github.com/ipfs/helia-remote-pinning/blob/main/src/heliaRemotePinner.ts#L155). It doesn't look possible to override the use of Set by the generator in a way that works (`type-mappings=set=array` produces uncompilable code) so manually change the generated code. Also adds a note to the readme reminding people to do it. BREAKING CHANGE: fields that were Sets such as `PinResults.results` and `PinsGetRequest.cid` are now Arrays
Because we have `uniqueItems: true` in our service definition yaml, fields with `type: array` are generated as `Set`s by the typescript generator. Serialization/deserialization of these types is [broken](OpenAPITools/openapi-generator#11746) so where we use these APIs [we pass arrays with `@ts-expect-error` anyway](https://github.com/ipfs/helia-remote-pinning/blob/main/src/heliaRemotePinner.ts#L155). It doesn't look possible to override the use of Set by the generator in a way that works (`type-mappings=set=array` produces uncompilable code) so manually change the generated code. Also adds a note to the readme reminding people to do it. BREAKING CHANGE: fields that were Sets such as `PinResults.results` and `PinsGetRequest.cid` are now Arrays
Because we have `uniqueItems: true` in our service definition yaml, fields with `type: array` are generated as `Set`s by the typescript generator. Serialization/deserialization of these types is [broken](OpenAPITools/openapi-generator#11746) so where we use these APIs [we pass arrays with `@ts-expect-error` anyway](https://github.com/ipfs/helia-remote-pinning/blob/main/src/heliaRemotePinner.ts#L155). It doesn't look possible to override the use of Set by the generator in a way that works (`type-mappings=set=array` produces uncompilable code) so manually change the generated code. Also adds a note to the readme reminding people to do it. BREAKING CHANGE: fields that were Sets such as `PinResults.results` and `PinsGetRequest.cid` are now Arrays
Because we have `uniqueItems: true` in our service definition yaml, fields with `type: array` are generated as `Set`s by the typescript generator. Serialization/deserialization of these types is [broken](OpenAPITools/openapi-generator#11746) so where we use these APIs [we pass arrays with `@ts-expect-error` anyway](https://github.com/ipfs/helia-remote-pinning/blob/main/src/heliaRemotePinner.ts#L155). It doesn't look possible to override the use of Set by the generator in a way that works (`type-mappings=set=array` produces uncompilable code) so manually change the generated code. Also adds a note to the readme reminding people to do it. BREAKING CHANGE: fields that were Sets such as `PinResults.results` and `PinsGetRequest.cid` are now Arrays
Bug Report Checklist
Description
The following schema generates a JavaScript Set property:
Generated object:
However when sending this request to the server, the value is not de-serialized as an array but just replaced with an empty object ("a":{}).
Similarly, when inspecting the returned data from an API, the actual values on the JavaScript object are not wrapped in a set, but return as an array.
openapi-generator version
4.5.0
Suggest a fix
Either don't generate Set and use a T[] or add conversions for sending and receiving sets
The text was updated successfully, but these errors were encountered: