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] Fix uploading files #2900

Merged
merged 21 commits into from
May 31, 2019

Conversation

janbuchar
Copy link
Contributor

@janbuchar janbuchar commented May 15, 2019

The current master converts anything that is not FormData to JSON. This behavior causes operations that accept a file to send requests where the payload is an empty JSON object.

This PR adds another branch that lets Blobs pass without modification.

@TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @nicokoenig (2018/09) @topce (2018/10)

@auto-labeler
Copy link

auto-labeler bot commented May 15, 2019

👍 Thanks for opening this issue!
🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

@@ -23,7 +23,7 @@ import {
} from '../models';

export interface AddPetRequest {
body: Pet;
pet: Pet;
Copy link
Member

Choose a reason for hiding this comment

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

Look like you're using an old version. please pull the latest master and merge into your branch and then update the samples again.

@wing328
Copy link
Member

wing328 commented May 20, 2019

please copy the TS technical committee as stated in the PR template.

@wing328 wing328 added this to the 4.0.1 milestone May 20, 2019
.join('&');
}

export function mapValues(data: any, fn: (item: any) => any) {
Copy link
Member

Choose a reason for hiding this comment

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

this should not be removed. did you generate the samples with the most recent master merged into your branch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm completely stumped now. I tried merging upstream/master into my branch before your review. After that, I pulled upstream master into my master and merged it into my branch. This got me back to where I was before @wing328 reviewed my changes.

Copy link
Member

Choose a reason for hiding this comment

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

@Teyras are you sure you re-generated the samples after merging origin/master?

.join('&');
}

export function mapValues(data: any, fn: (item: any) => any) {
Copy link
Member

Choose a reason for hiding this comment

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

please run mvn clean before re-generating the samples.
the mapValues function actually is available in your version of

export function mapValues(data: any, fn: (item: any) => any) {
return Object.keys(data).reduce(
(acc, key) => ({ ...acc, [key]: fn(data[key]) }),
{}
);
}

but it is removed in the generated samples, which indicates that the version you use for generating the samples is not the one you want to merge...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wow. That seems to have un-removed mapValues, but the body parameter was renamed back to pet again. My code seems to be haunted.

Copy link
Member

Choose a reason for hiding this comment

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

the body to pet renaming could be due to general changes, not necessarily related to your code.

Copy link
Member

@macjohnny macjohnny left a comment

Choose a reason for hiding this comment

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

LGTM

@janbuchar
Copy link
Contributor Author

@macjohnny is there anything to do before this can be merged?

@macjohnny
Copy link
Member

the ci tests detected a discrepancy between the generated samples.
https://circleci.com/gh/OpenAPITools/openapi-generator/6662#tests/containers/2

please ensure that

  • you merge the most recent master into your branch
  • then run mvn clean
  • then re-generate the samples
  • make sure to commit all changed files

@macjohnny
Copy link
Member

@wing328
Copy link
Member

wing328 commented May 22, 2019

@macjohnny is right

@Teyras let me know if you need help merging the latest master of the official repo into your branch.

@macjohnny
Copy link
Member

@Teyras the typescript-fetch tests fail because the tests need to be adapted due to changes of the body-parameter name (this is not related to your PR):

return api.addPet({ body: fixture }).then(() => {

should be

return api.addPet({ pet: fixture }).then(() => {

and

return api.updatePet({ body: result }).then(() => {

should be

return api.updatePet({ pet: result }).then(() => {

could you please push those changes?

@macjohnny
Copy link
Member

macjohnny commented May 22, 2019

the tests fail due to

 1) PetApi without custom request options should add and delete Pet:
     ReferenceError: Blob is not defined
      at PetApi.BaseAPI.createFetchParams (/home/travis/build/OpenAPITools/openapi-generator/samples/client/petstore/typescript-fetch/builds/with-npm-version/dist/runtime.js:175:81)

I still don't understand why, since Blob is defined here

https://github.com/microsoft/TypeScript/blob/de96b412724979ad089a1e9edecb217bad91725a/lib/lib.dom.d.ts#L2253-L2257

and this should be included in the tsconfig.json

@macjohnny
Copy link
Member

@Teyras any idea how to fix it?

@janbuchar
Copy link
Contributor Author

@macjohnny nope, Blob is a part of the File API so I would expect it to exist, just like FormData exists. What environment is used to run the tests?

@janbuchar
Copy link
Contributor Author

@macjohnny I think the problem is that the tests run in node, which doesn't have the Blob API. We could install a polyfill (https://www.npmjs.com/package/blob), but we'd have to find a way to make it available without importing it.

@janbuchar
Copy link
Contributor Author

@macjohnny I think that the argument that we should avoid BC breaks still holds - the client was fine in node environments, at least until you tried to upload a Blob to an API (which you couldn't anyway).

If we are to support node, we should probably also find a way to upload Buffer instances...

@macjohnny
Copy link
Member

@Teyras If I am not mistaken the declare var Blob: any; approach should avoid a breaking change.

@janbuchar
Copy link
Contributor Author

@macjohnny Won't it crash on node during the instanceof call because Blob is undefined?

@macjohnny
Copy link
Member

macjohnny commented May 23, 2019

@macjohnny Won't it crash on node during the instanceof call because Blob is undefined?
you are right. but this could be avoided by adding

if (typeof Blob === 'undefined') const Blob = function(){}
then the instanceof Blob should just return false

@janbuchar
Copy link
Contributor Author

@macjohnny that looks like a sound solution. However, I think we should also add support for Buffer, since node-fetch supports it in request bodies. What do you think?

@macjohnny
Copy link
Member

adding support for Buffer sounds good

const headerParameters: runtime.HTTPHeaders = {};

if (this.configuration && this.configuration.accessToken) {
// oauth required
if (typeof this.configuration.accessToken === 'function') {
headerParameters["Authorization"] = this.configuration.accessToken("petstore_auth", ["read:pets"]);
headerParameters["Authorization"] = this.configuration.accessToken("petstore_auth", ["write:pets", "read:pets"]);
Copy link
Member

Choose a reason for hiding this comment

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

why does this change?

Copy link
Member

Choose a reason for hiding this comment

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

It would be due to a fix in oauth scope to propagate these values probably.

@@ -3,6 +3,9 @@

export const BASE_PATH = "{{{basePath}}}".replace(/\/+$/, "");

const Blob = Blob !== undefined ? Blob : function() {};
Copy link
Member

Choose a reason for hiding this comment

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

CI fails due to runtime.ts(17,14): error TS2448: Block-scoped variable 'Blob' used before its declaration.
In https://www.typescriptlang.org/play/index.html you can try

const Blob = Blob !== undefined ? Blob : function () { };

function isBl(a: any) {
    return a instanceof Blob;
}

which does not work.
However, this works:

if (typeof Blob === 'undefined') {
    const Blob = function () { };
}

function isBl(a: any) {
    return a instanceof Blob;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey, seeing isBl gave me an idea - we could make a function that checks if the argument is a Blob and also returns false when Blob is undefined. I think it would be cleaner than conditionally defining consts.

Copy link
Member

Choose a reason for hiding this comment

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

sounds good

@@ -3,6 +3,9 @@

export const BASE_PATH = "{{{basePath}}}".replace(/\/+$/, "");

const isBlob = (value: any) => Blob !== undefined && value instanceof Blob;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const isBlob = (value: any) => Blob !== undefined && value instanceof Blob;
const isBlob = (value: any) => typeof Blob !== 'undefined' && value instanceof Blob;

since Blob is not necessarily a declared variable

Copy link
Member

Choose a reason for hiding this comment

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

@macjohnny
Copy link
Member

the samples seem to have been generated with a different version. it is strange that in each commit e.g. the body: Pet and pet: Pet change back and forth. @Teyras are you using the same very command each time you generate the samples? are you sure you always run mvn clean before generating the samples?

@@ -3,6 +3,9 @@

export const BASE_PATH = "{{{basePath}}}".replace(/\/+$/, "");

const isBlob = (value: any) => typeof Blob !== 'undefined' && value instanceof Blob;
const isBuffer = (value: any) => typeof Buffer !== 'undefined' && value instanceof Buffer;
Copy link
Member

@macjohnny macjohnny May 24, 2019

Choose a reason for hiding this comment

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

maybe it is easier to only support Blob, since Buffer does not exist in the dom typings https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts
or we need to add typings which include Buffer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be enough to install @types/node, which seems pretty sensible.

Copy link
Member

Choose a reason for hiding this comment

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

but I imagine a user wouldn't want to install @types/node for a web project, since the node API won't be available in the web...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think a user would care much... create-react-app for typescript installs @types/node too.

@janbuchar
Copy link
Contributor Author

@macjohnny It is possible I occassionally swap /bin/openapi3/typescript-fetch-petstore-all.sh and /bin/typescript-fetch-petstore-all.sh

@janbuchar
Copy link
Contributor Author

@macjohnny could we merge this if I add @types/node or do you think that removing Buffer support is better? Also, does the order of sample generation command I mentioned in the previous command matter?

@macjohnny
Copy link
Member

@Teyras I think removing buffer support is better for the time being, as it makes this PR 100% backwards compatible.
Concerning the sample generation, I would use bin/typescript-fetch-petstore-all.sh, as this is the script that also the CI uses to check whether the samples are up to date (see

"./bin/typescript-fetch-petstore-all.sh"
)

janbuchar and others added 2 commits May 29, 2019 12:50
…tApi.ts

Co-Authored-By: Esteban Marin <estebanmarin@gmx.ch>
…tApi.ts

Co-Authored-By: Esteban Marin <estebanmarin@gmx.ch>
@macjohnny
Copy link
Member

@wing328 can you re-start the circle-ci tests?

@wing328
Copy link
Member

wing328 commented May 31, 2019

All tests passed 👍

@wing328 wing328 merged commit c509d98 into OpenAPITools:master May 31, 2019
@wing328
Copy link
Member

wing328 commented Jun 3, 2019

@Teyras thanks again for your contribution, which has been included in the v4.0.1 release (https://twitter.com/oas_generator/status/1135534738658062336)

jimschubert added a commit to jimschubert/openapi-generator that referenced this pull request Jun 5, 2019
* 4.1.x: (56 commits)
  sync master
  Update compatibility table
  Ruby client: escape path parameters (OpenAPITools#3039)
  [gradle plugin] Release 4.0.1 fixes (OpenAPITools#3051)
  Update version to 4.0.2-SNAPSHOT (OpenAPITools#3047)
  Map number to double time since float is also parsed as double in Qt5 C++ (OpenAPITools#3046)
  Prepare 4.0.1 release (OpenAPITools#3041)
  [gradle] Reworking publishing pipeline (OpenAPITools#2886)
  [typescript-fetch] Fix uploading files (OpenAPITools#2900)
  Resolves OpenAPITools#2962 - Add properties config to Maven parameters (OpenAPITools#2963)
  fix(golang): Check error of xml Encode (OpenAPITools#3027)
  [C++][Restbed] Add handler callback methods (OpenAPITools#2911)
  Remove null checks for C# value types (OpenAPITools#2933)
  [python-server] Support python 3.7 for all server-generators (OpenAPITools#2884)
  Use golang's provided method names (gin) (OpenAPITools#2983)
  [python] Adding constructor parameters to Configuration and improving documentation (OpenAPITools#3002)
  Add new option to maven plugin's readme (OpenAPITools#3025)
  Engine param in maven plugin. (OpenAPITools#2881)
  Added support for patterns on model properties (OpenAPITools#2948)
  [csharp] Make API response headers dictionary case insensitive (OpenAPITools#2998)
  ...
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.

3 participants