-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
[typescript-angular] Support custom types (serialization/deserialization/imports) (momentjs) #1875
Comments
👍 Thanks for opening this issue! The team will review the labels and make any necessary changes. |
This sounds absolutely reasonable, take a look at #4170. |
I would like to use UUIDs for the ids of my entities and luxon for any timestamps. Using the default openapi generator for typescript-angular clients both of these fields are generated as Example of current generated model:
Example of generated model that I would like to have:
Are there any further ideas or solutions for serialization and deserialization of non-primitive or non-default-JS types like |
We have a fully-custom generator to handle this case (along with some other customizations). Do any of the other language generators support this use-case (to use as a reference point)? I'd love to upstream as much as I can to help others (and make it easier on myself to maintain). |
@sarumont Would you be able to share that? |
@KillDozerX2 Unfortunately, not at this point in time. It's somewhat proprietary but mostly not ready for a larger audience than some other internal teams, and I don't have the bandwidth (or the priority) to make it better right now... :) |
@fultonm I got Datetime working by modifying the template, have you tried that yet? |
Maybe you meant @flaute I am not a part of this haha. |
@flaute I managed to achieve kindof what you want for Luxon support, but it works only with the typescript axios generator** (or any other axios one). You may not be able to use that; but I found this issue while googling so I guess it's a good place to share my solution. What I do is take advantage of the axios interceptors features. First I edited the command I run to generate the code to change the mustache templates and also change Date types to luxon's type; here is my command:
What you are interested in are the last two arguments:
Second I needed to tweak the generated code to make the Datetime type of luxon resolvable and intercepting response to convert string dates to luxon's Datetime, this is done by retrieving the original mustache template with the following command:
I'll give you my current mustache template (with unchanged lines removed for clarity) but I'm almost certain there are bugs about timezones probably and also it certainly improvable A LOT. /* tslint:disable */
/* eslint-disable */
{{>licenseInfo}}
{{^withSeparateModelsAndApi}}
import {DateTime} from "luxon";
...
import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError } from './base';
// Parse dates as Luxon dates
const regexDate = /^\d{4}-\d{2}-\d{2}$/;
const regexDatetime = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{2}:\d{2}$/;
function parseDateInArray(data: Array<any>): Array<any> {
return data.map((item) => genericParseDate(item));
}
function parseDateInObject(data: Object): Object {
for (const [key, value] of Object.entries(data)) {
data[key] = genericParseDate(data[key]);
}
return data;
}
function genericParseDate(data?: any): any {
if (data && Array.isArray(data)) {
data = parseDateInArray(data);
} else if (data && typeof data === "object") {
data = parseDateInObject(data);
} else if (data && typeof data === "string") {
if (data.match(regexDatetime)) {
return DateTime.fromISO(data);
} else if (data.match(regexDate)) {
let s = data + "T00:00:00.000";
return DateTime.fromISO(s);
}
}
return data;
}
globalAxios.interceptors.response.use(
function (response) {
response.data = genericParseDate(response.data);
return response;
},
function (error) {
return Promise.reject(error);
},
);
{{#models}}
...
{{/withSeparateModelsAndApi}} |
What @BancarelValentin has provided there should be quite easily doable for typescript-angular as well. You can use something like https://angular.io/guide/http-interceptor-use-cases#custom-json-parsing and https://stackoverflow.com/a/29971466 to convert the data to anything you like: Date, moment or Luxon objects. This has the effect that any real text fields that contain date-looking data, will be parsed when they should not. To be implemented in the generator, the solution would need to track the objects and fields and actually "know" which fields are dates and date-times, but implementing that is much more work. |
Hi,
I would like to be able to support custom types. This would mean:
My concrete case is that I want to use momentjs for date/time types in models and as parameters.
What I tried to do was:
But even then there seems to be no support for any kind pluggable serialization/deserialization. Maybe this could be achieved using custom providers? Maybe this is something to consider for #802.
I can imagine this is quite a common use case but could not find much about how to handle this.
My question is basically how would I achieve having working generated code where every date formatted string is replaced with a Moment type (Other than just writing my own templates).
Thanks
The text was updated successfully, but these errors were encountered: