-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
[Typescript Fetch] Handle date parameters in the URL path #19313
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 Fetch] Handle date parameters in the URL path #19313
Conversation
|
Hopefully this PR is helpful, I have currently run into this behavior breaking calls to an API. A couple questions I had:
|
macjohnny
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution!
| {{/hasFormParams}} | ||
| const response = await this.request({ | ||
| path: `{{{path}}}`{{#pathParams}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(String(requestParameters['{{paramName}}']))){{/pathParams}}, | ||
| path: `{{{path}}}`{{#pathParams}}{{#isDateTimeType}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(requestParameters['{{paramName}}'].toISOString())){{/isDateTimeType}}{{^isDateTimeType}}{{#isDateType}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(requestParameters['{{paramName}}'].toISOString().substring(0,10))){{/isDateType}}{{^isDateType}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(String(requestParameters['{{paramName}}']))){{/isDateType}}{{/isDateTimeType}}{{/pathParams}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about
| path: `{{{path}}}`{{#pathParams}}{{#isDateTimeType}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(requestParameters['{{paramName}}'].toISOString())){{/isDateTimeType}}{{^isDateTimeType}}{{#isDateType}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(requestParameters['{{paramName}}'].toISOString().substring(0,10))){{/isDateType}}{{^isDateType}}.replace(`{${"{{baseName}}"}}`, encodeURIComponent(String(requestParameters['{{paramName}}']))){{/isDateType}}{{/isDateTimeType}}{{/pathParams}}, | |
| path: `{{{path}}}`.replace(`{${"{{baseName}}"}}`, | |
| {{#pathParams}} | |
| {{#isDateTimeType}} | |
| encodeURIComponent(requestParameters['{{paramName}}'].toISOString()) | |
| {{/isDateTimeType}} | |
| {{^isDateTimeType}} | |
| {{#isDateType}} | |
| encodeURIComponent(requestParameters['{{paramName}}'].toISOString().substring(0,10)) | |
| {{/isDateType}} | |
| {^isDateType}} | |
| encodeURIComponent(String(requestParameters['{{paramName}}'])) | |
| {{/isDateType}} | |
| {{/isDateTimeType}} | |
| {{/pathParams}}, |
to simplify the template?
moreover, encodeURIComponent(requestParameters['{{paramName}}'].toISOString().substring(0,10)) is problematic because devs might be using a local date, and this converts the date to be in UTC. But at least this matches
Line 114 in f8a5051
| '{{baseName}}': {{^required}}value['{{name}}'] == null ? undefined : {{/required}}({{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}(value['{{name}}']{{#isNullable}} as any{{/isNullable}}).toISOString().substring(0,10)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do the expanded style. I wasn't sure what the standards (if any are for the generated code, so I was trying to maintain the style of that. But your version makes the template more readable.
Regarding the iso string handling, I pretty much just copied the code above that is handling query params (line 140 of this file). So while I don't disagree about the UTC thing, I think if that is an issue it might need to be addressed as part of a larger change
I can add the null handling stuff you have, but are path params allowed to be nullable? I'll admit I don't know the spec well enough to be sure but that seems really weird. I suppose in that case though that putting in null as the path value is the correct behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the nullable bit, my reading of the spec (both version 2 and version 3.1.0) is that a path parameter can't be null because the required property must be set to true: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#fixed-fields-10
Determines whether this parameter is mandatory. If the parameter location is "path", this property is REQUIRED and its value MUST be true. Otherwise, the property MAY be included and its default value is false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also just add the null-safe operator „.?“ to be cautious
|
@scottaj thanks for your contribution |
|
I did run those commands from the PR template. I don't believe any of the samples have a date as a path param, so running those did not result in any changes in git. |
|
please run to re-generate the samples from your changed code. |
Couldn't get handlebars to format the inline replaces in a sane way without collapsing everything onto one very ugly line. This way keeps some sane template formatting while still outputting workable code.
|
@macjohnny I updated the template and examples. I ended up changing the template code structure because I could not get handlebars to format the inline |
|
Thanks @scottaj for putting this together. I also need this change... @macjohnny any reason to not merge this change? |
|
oops, this one slipped my mind. @scottaj can you merge the most recent master and re-generate the samples please? |
| let urlPath = `{{{path}}}`; | ||
| {{#pathParams}} | ||
| {{#isDateTimeType}} | ||
| urlPath = urlPath.replace(`{${"{{baseName}}"}}`, encodeURIComponent((requestParameters['{{paramName}}'] as any).toISOString())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also check here whether it actually is a date object, i.e. instanceof Date
same below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it isn't a date what should we do? Obvious options seem to be to stringify whatever it is, or throw an error in the generated code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, just to call out, none of the other parameter types are making that check now (query params, form params). Assume that if I add the check I should update all those to have the same handling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah if its not a Date, just stringify. not sure this can happen in typescript-fetch, but just to be sure.
the other places (query params) should probably also have some safeguard, but ideally in a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added type checking to date params: 373a34c
|
@macjohnny Merged with master, regenerated samples, and updated the Date checking |
|
somehow circleci failed can you merge the latest master again? |
…-fetch/dates-in-path-params
|
I merged master again. I am seeing this error for CircleCI:
I haven't touched any CI configs, and i don't think I would be the one to give permission to that? So I'm not sure what to do. |
|
@scottaj sorry i dont know how to fix the circle ci config issue. can you please create a new PR, based on the latest master? maybe you can also try the steps described in https://support.circleci.com/hc/en-us/articles/12504745606171-Why-am-I-seeing-the-Could-not-find-a-usable-config-yml-you-may-have-revoked-the-CircleCI-OAuth-app-message |
17f6d99 to
b24c0be
Compare
|
@macjohnny that was a good call. I followed the steps in that link and reset everything for CircleCI and now it seems to have worked. |
If a schema contains a date or date-time parameter in the url path, the typescript-fetch generator will expect that parameter to be passed as a JavaScript
Dateobject. When serializing date objects for other parameter types, the generator serializes them as ISO8601 strings. For path parameters however, it is currently just stringifying the date object, leading to values like'Tue Aug 06 2024 17:49:37 GMT-0600 (Mountain Daylight Time)'instead of'2024-08-06T23:49:37.781Z'. This causes issues with many webservers that expect the date to be in the ISO8601 format.This pull request changes the behavior of path params to match the existing behavior of query and body params and use the ISO8601 format.
I didn't see a past issue for this exact problem, some relevant issues and past PRs I did find:
CC: @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02) @davidgamero (2022/03) @mkusaka (2022/04)
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
master(upcoming 7.6.0 minor release - breaking changes with fallbacks),8.0.x(breaking changes without fallbacks)