-1

Summary I am using swagger-codegen-js to generate typescript files according to the swagger.json defined by an external api.

packages used "swagger-js-codegen": "^1.12.0",

Alleged Problem The return type on the method listMovies on the generated TS file is simply Promise<Request.Response> and not Promise<Array<Movie>>, i did expect it to be array of movies as the response clearly state the schema and thought/assumed that would be translated.

Given a json along the lines of the following, the

 "/movies": {
    "get": {
      "description": "Lists movies",
      "operationId": "listMovies",
      "responses": {
        "200": {
          "description": "Movie",
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/definitions/Movie"
            }
          }
        },
        "default": {
          "$ref": "#/responses/genericError"
        }
      }
    },
 "definitions": {
  "Movie": {
    "description": "something",
    "type": "object",
    "properties": {
      "archivedAt": {
        "description": "When the movie was archived",
        "type": "string",
        "format": "nullable-date-time",
        "x-go-name": "ArchivedAt",
        "readOnly": true
      }
  }
}

Generated TS Method

 /**
 * Lists movies
 * @method
 * @name Api#listMovies
 */
listMovies(parameters: {
    $queryParameters ? : any,
    $domain ? : string
}): Promise <request.Response> {
    const domain = parameters.$domain ? parameters.$domain : this.domain;
    let path = '/movies';
    .
    .
    .
        this.request('GET', domain + path, body, headers, queryParameters, form, reject, resolve);
    });
}

The script i use to generate the above ts file is straight from the github sample

const generateTSFilesUsingSwaggerJsCodegen = function () {
var fs = require('fs');
var CodeGen = require('swagger-js-codegen').CodeGen;

var file = 'build/sample.json';
var swagger = JSON.parse(fs.readFileSync(file, 'UTF-8'));
var tsSourceCode = CodeGen.getTypescriptCode({ className: 'Api', swagger: swagger, imports: ['../../typings/tsd.d.ts'] });
fs.writeFileSync('src/api/api.ts', tsSourceCode)

}

Am i missing something on the wire up/options passed or is this the expected generated file given the json file and that i need to write custom script to get what I want?

Jaya
  • 3,721
  • 4
  • 32
  • 48

2 Answers2

2

It is only possible to edit the codegen to change this.

But you can just use the body of the return value

<restMethod>(<paramters>).then(respose: <request.Response>) {
  let responseObject: Array<ListMovies> = response.body as Array<ListMovies>;
  ...
}

If you want to adapt the codegen, pull it from git and change the following files:

lib/codegen.js:

var getViewForSwagger2 = function(opts, type){
var swagger = opts.swagger;
var methods = [];
var authorizedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'];
var data = {
    isNode: type === 'node' || type === 'react',
    isES6: opts.isES6 || type === 'react',
    description: swagger.info.description,
    isSecure: swagger.securityDefinitions !== undefined,
    moduleName: opts.moduleName,
    className: opts.className,
    imports: opts.imports,
    domain: (swagger.schemes && swagger.schemes.length > 0 && swagger.host && swagger.basePath) ? swagger.schemes[0] + '://' + swagger.host + swagger.basePath.replace(/\/+$/g,'') : '',
    methods: [],
    definitions: []
};

_.forEach(swagger.definitions, function(definition, name){
    data.definitions.push({
        name: name,
        description: definition.description,
        tsType: ts.convertType(definition, swagger)
    });
});

the last _.forEach is moved from the bottom of the method to here.

var method = {
            path: path,
            className: opts.className,
            methodName: methodName,
            method: M,
            isGET: M === 'GET',
            isPOST: M === 'POST',
            summary: op.description || op.summary,
            externalDocs: op.externalDocs,
            isSecure: swagger.security !== undefined || op.security !== undefined,
                          isSecureToken: secureTypes.indexOf('oauth2') !== -1,
                          isSecureApiKey: secureTypes.indexOf('apiKey') !== -1,
                          isSecureBasic: secureTypes.indexOf('basic') !== -1,
            parameters: [],
            responseSchema: {},
            headers: []
        };
        if (op.responses && op.responses["200"]) {
            method.responseSchema = ts.convertType(op.responses["200"], swagger);
        } else {
            method.responseSchema = {
                "tsType": "any"
            }
        }

this is starting at line 102. add responseSchema to method and append the if / else

templates/typescript-class.mustache (line 68)

resolve(response.body);

templates/typescript-method.mustache (line 69)

}): Promise<{{#responseSchema.isRef}}{{responseSchema.target}}{{/responseSchema.isRef}}{{^responseSchema.isRef}}{{responseSchema.tsType}}{{/responseSchema.isRef}}{{#responseSchema.isArray}}<{{responseSchema.elementType.target}}>{{/responseSchema.isArray}}> {

That only works for simple types, Object types and arrays of simple / object types. I did not implement the enum types.

A Loewer
  • 176
  • 5
0

That seems like the expected behaviour.

The TypeScript Mustache template outputs a fixed value:

    ...
}): Promise<request.Response> {
    ...
creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
Juan Mellado
  • 14,973
  • 5
  • 47
  • 54
  • My question was or is - when the definition for 200 type response in the schema is defined as type of `Array` , is it possible to output that and not the generic `Promise` which i know from reading the documentation that is the default. Is there anything that could be done to the wire up to get what am looking for – Jaya Mar 12 '18 at 22:15
  • You could write your own template, but I don't see any template variable carrying the response type of the method. Still thinking that the library, in its current version, is designed to output always that fixed value. – Juan Mellado Mar 13 '18 at 06:23