swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
17.09k stars 6.03k forks source link

[JavaScript][ES6] TypeError: Cannot call a class as a function #7640

Open beatgrabe opened 6 years ago

beatgrabe commented 6 years ago
Description

Composition of model definitions does not work with es6 javascript, leading into a TypeError: Cannot call a class as a function when sources are compiled with babel, which is according to ES6 Spec 9.2.1 (Point 2) appropriate bahaviour.

This is the related line in the mustache template:

{{#interfaceModels}}{{classname}}.call(this{{#vendorExtensions.x-all-required}}, {{name}}{{/vendorExtensions.x-all-required}});{{/interfaceModels}}

For example in the Cat.js of the petstore sample this compiles to:

import Animal from './Animal';

export default class Cat {

    constructor(className) {
        Animal.call(this, className);  // <--- Throws Error
    }
    …
}

Animal.call(this, className) throws error, because es6 class constructors cannot be called as normal functions, like it is done here with Function.prototype.call, when for my case the sources are transpiled by babel.

Babel uses an internal function to check if a class is called as function and then throws:

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

Here ist the related REPL.

Swagger-codegen version

swagger-codegen-cli-2.3.1

Swagger declaration file content or url

Refering the perstore example.

Command line used for generation

config.json

{
    "projectName":  "...",
    "projectDescription":  "...",
    "projectVersion":  "0.0.0",
    "useES6": true
}

shell command

java -jar swagger-codegen-cli-2.3.1.jar generate -i config.json -l javascript
Steps to reproduce

Using a model definition which implements another model definition and generating a javascript client library which uses es6 standard.

Suggest a fix/enhancement

For now I am using my own partial_model_generic.mustache template commenting out the related code line. But I am not sure, what would be the appropriate javascript fix, since es6 does not support interfaces. So I will leave this question open for discussion and I will be open to file a PR at appropriate time.

JasonFreeberg commented 4 years ago

Is there a workaround? I'm running into this issue on 3.0.21 and I'm stuck.

georgedias commented 3 years ago

As of Swagger Codegen 3.0.25 the issue is still prominent.

The generated ES6 code should have the module import references associated with the proper extension for generated modules, (ex, import GeneratedClass from './GeneratedModule.js'

The workaround is to modify the handlebar (for the API 3.0 specs) templates such that the generated import have a .js extension. Additionally, the package.mustache template needs to have the "type": "module" entry.