Skip to content
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: file upload and Typescript dependency updates #4852

Conversation

russtacular
Copy link

PR checklist

  • Read the contribution guildelines.
  • Ran the shell/batch script under ./bin/ to update Petstore sample so that CIs can verify the change. (For instance, only need to run ./bin/{LANG}-petstore.sh and ./bin/security/{LANG}-petstore.sh if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates)
  • Filed the PR against the correct branch: master for non-breaking changes and 2.3.0 branch for breaking (non-backward compatible) changes.

Description of the PR

This updates the typescript-fetch client with the latest dependencies based on work originally done in #4153 but in need of updates due to additional changes to @types/isomorphic-fetch that were causing build errors.

Additionally this adds the ability to upload files using the typescript-fetch client as requested in #3921. Given the limitations of the mustache template, I assumed that form parameters did not include files but, if so, it set a flag that caused the form parameters to be appended to a FormData object which is uploaded with a Content-Type: 'multipart/form-data' header opposed to the standard 'application/x-www-form-urlencoded'

@wing328
Copy link
Contributor

wing328 commented Mar 5, 2017

@russtacular thanks for the PR.

@Vrolijkx @leonyu would you please take a look when you've time? Thanks.

Copy link
Contributor

@Vrolijkx Vrolijkx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great only one remark.

@@ -6,16 +6,18 @@
"browser": "./dist/api.js",
"typings": "./dist/api.d.ts",
"dependencies": {
{{^supportsES6}}"core-js": "^2.4.0",
{{/supportsES6}}"isomorphic-fetch": "^2.2.1"
"@types/node": "6.0.46",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to also have this in the angular2 && angular clients.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started looking at updating angular2 but I'm having issues building the copy in master using either TS 1.8.10 or my installed typescript@next developers build. I'm sure my unfamiliarity with building and using the angular generated libraries isn't helping either!

I can look into this but I think it may require more extensive changes and that it's likely better suited for a follow up PR. Is that okay with you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure.

{{/isFile}}formData["{{baseName}}"] = params["{{paramName}}"];
{{/formParams}}

if (isMultipartData) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not instead of this if statement in all the generated code. Use a Mustache if. This way you don't need the next strange code:

let isMultipartData = false;
isMultipartData = true;

maybe do something like this:

{{#isFile}}
  let body = new FormData();
  for (let key in formData) {
     body.append(key, formData[key]);
  }
 fetchOptions.body = body;
 contentTypeHeader = { "Content-Type": "multipart/form-data" };
{{/isFile}}
{{^isFile}}
   fetchOptions.body = querystring.stringify(formData);
   contentTypeHeader = { "Content-Type": "application/x-www-form-urlencoded" };
{{#isFile}}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally used a very similar implementation to the one you suggested and also mentioned in #3921 but noticed that, since {{#isFile}} is scoped to the individual parameter, it didn't work for requests that included a file and regular form parameters. I checked again and, unless I'm looping through the individual formParams, {{#isFile}} always maps to false.

Is there a Mustache template variable available that tracks if any of the included FormData attributes is of type file? If so, that would allow me to simplify the mustache template to essentially match your suggestion and get rid of the seemingly extraneous code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a Mustache template variable available that tracks if any of the included FormData attributes is of type file?

Not that I'm aware of. If it helps, we can introduce the variable.

@russtacular
Copy link
Author

russtacular commented Mar 9, 2017

Hold off on this PR for a bit… I think it needs a small update and I'm also going to see about adding that form-level variable.

Notably I need to remove the explicit set of the content-type header, otherwise I'll make the same mistake that #3932 fixed.

russtacular and others added 5 commits March 9, 2017 17:40
Also removes references to typings in the Readme
Ensures that content-type is set for urlencoded forms but is specifically
left unset for multipart form data since the content-type header value
is dynamically generated to include a boundary.
…ile-upload-and-dependency-updates

* swagger/master: (59 commits)
  [Java][Retrofit2] update gradle, sbt build file with latest dependencies (swagger-api#5238)
  update retrofit2 dependencies (swagger-api#5235)
  Issue swagger-api#3084: remove timestamps from undertow samples (swagger-api#5231)
  add port 80 to swagger spec (swagger-api#5232)
  fix msf4j bin script
  fix c# docstring typo (swagger-api#5223)
  add comments to csharp methods (swagger-api#5222)
  fix retrofit2 indentation (swagger-api#5221)
  Updating samples for spring-stubs, springboot-delegate, springboot-delegate-j8. (swagger-api#5211)
  export top level enumeration types in typescript-fetch mode (swagger-api#4820)
  [Erlang] pretty print swagger json (swagger-api#5215)
  add ci test for msf4j server (swagger-api#5220)
  Updating samples for JaxRS servers: Spec + CXF-CDI. (swagger-api#5213)
  Update samples for JaxRS/RestEasy/Joda. (swagger-api#5205)
  Update samples for Undertow. (swagger-api#5207)
  Update samples for okhttp-gson-parcelableModel. (swagger-api#5208)
  Update samples for Java Inflector. (swagger-api#5204)
  [java][msf4j] Update msf4j samples (and fix artifact name) (swagger-api#5210)
  Update samples for Ruby-Client + Rails server. (swagger-api#5214)
  [ASP.NET] Issue swagger-api#5196: add packageGuid parameter to AspNetCoreServerCodegen. (swagger-api#5199)
  ...
@wing328
Copy link
Contributor

wing328 commented Apr 24, 2017

@russtacular the CI (travis) failed with the following errors:


  StoreApiFactory
    without custom request options
      ✓ should get inventory
    with custom request options
      ✓ should get inventory


  26 passing (180ms)
  2 failing

  1) PetApi without custom request options should not set a content-type header when uploading a file:
     ReferenceError: File is not defined
      at Context.<anonymous> (dist/test/PetApi.js:49:120)

  2) PetApi with custom request options should not set a content-type header when uploading a file:
     ReferenceError: File is not defined
      at Context.<anonymous> (dist/test/PetApi.js:49:120)

Would you please take a look when you've time?

@zetlan
Copy link

zetlan commented May 17, 2017

Is there a timeline on this one? It would solve the same problem I'm having with file uploads via generated code.

@russtacular
Copy link
Author

@wing328 @zetlan — Thanks for prodding me on this, I definitely still want to get this fix merged. The failing test, however, points out a bit of a problem with using isomorphic-fetch and trying to maintain compatibility with both browsers and Node.

Node doesn't support FormData which causes the node test to fail but the browser-based tests to pass. The options for fixing this are:

  • Use a shim to try and support FormData in a Node environment. This doesn't seem like a great option except for the fact that should maintain compatibility with any server-side usage but makes the TS Fetch client reliant on more niche and also not as actively maintained shim libraries.
  • Remove the expectation that TS Fetch work in Node environments unless they provide a FormData shim. That would keep client size down and we could conceivably still rely on packages like JSDom or similar to provide a FormData shim to enable Node-based tests to run.
  • Replace isomorphic-fetch with whatwg-fetch and break its ability to run in Node. Given that there's already a TS Node client, maybe this is fine, although it does kind of kill the dream of isomorphic type/javascript.

Those are the options I see, although I could definitely be missing something obvious. I happy to submit a fix that uses any of the options I identified above but I don't feel like I can make that decision unilaterally since I don't know how others are using this client (at Bitly, we're only using the generated TS Fetch client within browsers).

@AmazingTurtle
Copy link

Can someone have a look at this please? @russtacular

});

it('should not set a content-type header when uploading a file', () => {
return new PetApi(parameterInspector).uploadFile({ petId: fixture.id, file: new File(['snoopy'], 'Snoopy.png')}).then(({arguments: [url, init]}) => {
Copy link

@AmazingTurtle AmazingTurtle Jan 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File is not defined, that's why tests are failing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AmazingTurtle good catch!

@wing328
Copy link
Contributor

wing328 commented Jan 20, 2018

cc @TiFu @taxpon @sebastianhaas @kenisteward @Vrolijkx to review and see how we can proceed with this PR.

@Alexuy
Copy link

Alexuy commented Jun 27, 2018

Hey, guys! What about this issue? When you planning to fix that bug?

@Place1
Copy link

Place1 commented Jun 27, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants