swagger-typescript-api
swagger-typescript-api copied to clipboard
Support for dates
Problem
Currently this library seems to ignore format
information on data types. Most formats just add some metadata, so they are fine to skip, but format: date-time
actually has semantic meaning that could be understood by a typescript client.
Right now, if we have a model definition like this:
"SomeType": {
"properties": {
"created": {
"type": "string",
"format": "date-time"
}
}
}
it generates this kind of model:
interface SomeType {
created: string;
}
There is no way for the client to know that this string represents a date. It would be really useful if it could generate this model instead:
interface SomeType {
created: Date;
}
Implementation
I realize that adding custom data transformations is tricky and probably outside the scope of this library. But making only dates work might actually be possible.
Serializing data would be relatively straightforward. JSON serialization would just work. For form serialization there would need to be a special case for Date
instances.
The main challenge for implementation seems to make safeParseResponse work, because type information is not available at run-time. I think the only way to make that work is generate a custom parser per API type. Is that outside the scope of this library too?
Further steps
I'd be happy to lend a hand if you think this would be a useful addition to the library. I am aware that templates can be customized, so I might also be able to work around this if necessary.
Hello @vincentvanderweele!
Currently library is parsing field format
.
But I decided to not add Date
instance for string/date-time
because it can be difficult for serialization.
If you have interest how library works with types please take a look at #next branch, src\schema.js
8 line, object types
Ah nice that you're already parsing formats! I now also see that the current version is the latest release using mustache templates, so I won't go too crazy with custom templates just now.
Hello @vincentvanderweele
I don't know what's better, add parser for string/date-time
format or if user decide for yourself (probably --date-time
option) needs to parse date-time format or not
What do you think ?
Hi @js2me!
I have a hard time to imagine why anyone would rather have a string than a Date
instance, so for me the automatic parser would make most sense. But it would of course be a breaking change, so other users might not be too happy with that decision :)
The opt-in would work equally well for me, so maybe that's the safer choice?
According to the documentation, the string can be of different types, two of them are date
and date-time
. If there is this format, then it is ligical that I need a date,
not a string
. In other cases, the format is simply not indicated and the date of other formats is given (for those who need it). Just add some clarification.
Anyway, someone who currently wants to use Date instances instead of date strings just can customize it with onParseSchema
hook
And update templates to formatting Date instances
For newcomers, this is how i implemented the thing :
generateApi({
...
hooks: {
onParseSchema: (originalSchema, parsedSchema) => {
// Convert type string to Date when needed
if (originalSchema.type === 'string' && ['date-time', 'date'].indexOf(originalSchema.format) > -1) {
parsedSchema.content = 'Date';
}
return parsedSchema;
},
},
});
It is missing hierarchical transformations of inputs/outputs data.
Are you guys interested in this?
Basically generate transformation function/s per interesting type which invokes other transformations per interested member during this.request()
@acacode seems old issue, but no solution yet?
I played around it, but didn't find appropriate solution, but axios interceptors, which causes performance issues.
What if wrap this.http.request()
call in route clients to handle date fields (based on schema) like dateField = source.dateField ? new Date(source.dateField) : undefined
after getting response - seems to be good solution.
At least NSwag typescript generator handling it this way.
Because currently, even if you use workarounds provided above, you have Date
fields in TS interfaces, but in runtime there are strings.
For newcomers, this is how i implemented the thing :
generateApi({ ... hooks: { onParseSchema: (originalSchema, parsedSchema) => { // Convert type string to Date when needed if (originalSchema.type === 'string' && ['date-time', 'date'].indexOf(originalSchema.format) > -1) { parsedSchema.content = 'Date'; } return parsedSchema; }, }, });
And where it must be written? In command line? Guess not.
@kedzoo It's for programmatic usage of the library.