OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.85k stars 6.59k forks source link

[BUG][JS] Generated JS SDK result in the following error when called : end() was called twice. This is not supported in superagent #12073

Open Thytu opened 2 years ago

Thytu commented 2 years ago

Bug Report Checklist

Description

I use FastAPI to generate my routes, and the following command to produce the sdk:

docker run --network=host --rm \
        -v $(pwd)/clients:/tmp \
        openapitools/openapi-generator-cli:v4.0.0 generate \
        -i localhost:8080/openapi.json \
        -o /tmp/{language} \
        -D modelDocs=false \
        -D apiDocs=false \
        -D apiTests=false \
        -D modelTests=false \
        -D npmVersion=3.5.2 \
        -D supportsES6=true \
        -g javascript

When producing the following code it result into this error message : .end() was called twice. This is not supported in superagent

Executed code:

useEffect(() => {

    const api =  new MyApi()

    api.apiClient.basePath = 'http://localhost:8080'

    api.produceSomethigGet().then(res => {
      console.log(res)
    })
  }, [])
openapi-generator version

V4.0.0

OpenAPI declaration file content or url

https://gist.github.com/Thytu/517d892fadd685c921e7b0d780b1cd21

Generation Details
Steps to reproduce

Generate SDK:

docker run --network=host --rm \
        -v $(pwd)/clients:/tmp \
        openapitools/openapi-generator-cli:v4.0.0 generate \
        -i localhost:8080/openapi.json \
        -o /tmp/{language} \
        -D modelDocs=false \
        -D apiDocs=false \
        -D apiTests=false \
        -D modelTests=false \
        -D npmVersion=3.5.2 \
        -D supportsES6=true \
        -g javascript

Call SDK:

useEffect(() => {

    const api =  new MyApi()

    api.apiClient.basePath = 'http://localhost:8080'

    api.produceSomethigGet().then(res => {
      console.log(res)
    })
  }, [])
Related issues/PRs
Suggest a fix

I saw that if I change a bit the client code it does word:

Unchanged callApi function:

callApi(path, httpMethod, pathParams,
        queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
        returnType, apiBasePath, callback) {

        var url = this.buildUrl(path, pathParams, apiBasePath);
        var request = superagent(httpMethod, url);

        if (this.plugins !== null) {
            for (var index in this.plugins) {
                if (this.plugins.hasOwnProperty(index)) {
                    request.use(this.plugins[index])
                }
            }
        }

        // apply authentications
        this.applyAuthToRequest(request, authNames);

        // set query parameters
        if (httpMethod.toUpperCase() === 'GET' && this.cache === false) {
            queryParams['_'] = new Date().getTime();
        }

        request.query(this.normalizeParams(queryParams));

        // set header parameters
        request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));

        // set requestAgent if it is set by user
        if (this.requestAgent) {
          request.agent(this.requestAgent);
        }

        // set request timeout
        request.timeout(this.timeout);

        var contentType = this.jsonPreferredMime(contentTypes);
        if (contentType) {
            // Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746)
            if(contentType != 'multipart/form-data') {
                request.type(contentType);
            }
        } else if (!request.header['Content-Type']) {
            request.type('application/json');
        }

        if (contentType === 'application/x-www-form-urlencoded') {
            request.send(querystring.stringify(this.normalizeParams(formParams)));
        } else if (contentType == 'multipart/form-data') {
            var _formParams = this.normalizeParams(formParams);
            for (var key in _formParams) {
                if (_formParams.hasOwnProperty(key)) {
                    if (this.isFileParam(_formParams[key])) {
                        // file field
                        request.attach(key, _formParams[key]);
                    } else {
                        request.field(key, _formParams[key]);
                    }
                }
            }
        } else if (bodyParam !== null && bodyParam !== undefined) {
            request.send(bodyParam);
        }

        var accept = this.jsonPreferredMime(accepts);
        if (accept) {
            request.accept(accept);
        }

        if (returnType === 'Blob') {
          request.responseType('blob');
        } else if (returnType === 'String') {
          request.responseType('string');
        }

        // Attach previously saved cookies, if enabled
        if (this.enableCookies){
            if (typeof window === 'undefined') {
                this.agent._attachCookies(request);
            }
            else {
                request.withCredentials();
            }
        }

        request.end((error, response) => {
            if (callback) {
                var data = null;
                if (!error) {
                    try {
                        data = this.deserialize(response, returnType);
                        if (this.enableCookies && typeof window === 'undefined'){
                            this.agent._saveCookies(response);
                        }
                    } catch (err) {
                        error = err;
                    }
                }

                callback(error, data, response);
            }
        });

        return request;
    }

Changed callApi function:

   callApi(path, httpMethod, pathParams,
        queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
        returnType, apiBasePath, callback) {

        var url = this.buildUrl(path, pathParams, apiBasePath);
        var request = superagent(httpMethod, url);

        if (this.plugins !== null) {
            for (var index in this.plugins) {
                if (this.plugins.hasOwnProperty(index)) {
                    request.use(this.plugins[index])
                }
            }
        }

        // apply authentications
        this.applyAuthToRequest(request, authNames);

        // set query parameters
        if (httpMethod.toUpperCase() === 'GET' && this.cache === false) {
            queryParams['_'] = new Date().getTime();
        }

        request.query(this.normalizeParams(queryParams));

        // set header parameters
        request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));

        // set requestAgent if it is set by user
        if (this.requestAgent) {
          request.agent(this.requestAgent);
        }

        // set request timeout
        request.timeout(this.timeout);

        var contentType = this.jsonPreferredMime(contentTypes);
        if (contentType) {
            // Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746)
            if(contentType != 'multipart/form-data') {
                request.type(contentType);
            }
        } else if (!request.header['Content-Type']) {
            request.type('application/json');
        }

        if (contentType === 'application/x-www-form-urlencoded') {
            request.send(querystring.stringify(this.normalizeParams(formParams)));
        } else if (contentType == 'multipart/form-data') {
            var _formParams = this.normalizeParams(formParams);
            for (var key in _formParams) {
                if (_formParams.hasOwnProperty(key)) {
                    if (this.isFileParam(_formParams[key])) {
                        // file field
                        request.attach(key, _formParams[key]);
                    } else {
                        request.field(key, _formParams[key]);
                    }
                }
            }
        } else if (bodyParam !== null && bodyParam !== undefined) {
            request.send(bodyParam);
        }

        var accept = this.jsonPreferredMime(accepts);
        if (accept) {
            request.accept(accept);
        }

        if (returnType === 'Blob') {
          request.responseType('blob');
        } else if (returnType === 'String') {
          request.responseType('string');
        }

        // Attach previously saved cookies, if enabled
        if (this.enableCookies){
            if (typeof window === 'undefined') {
                this.agent._attachCookies(request);
            }
            else {
                request.withCredentials();
            }
        }

        // request.end((error, response) => {
        //     if (callback) {
        //         var data = null;
        //         if (!error) {
        //             try {
        //                 data = this.deserialize(response, returnType);
        //                 if (this.enableCookies && typeof window === 'undefined'){
        //                     this.agent._saveCookies(response);
        //                 }
        //             } catch (err) {
        //                 error = err;
        //             }
        //         }

        //         callback(error, data, response);
        //     }
        // });

        return request;
    }
ccaspanello commented 4 months ago

I am also experiencing the same issue.