GithubHelp home page GithubHelp logo

wcandillon / swagger-js-codegen Goto Github PK

View Code? Open in Web Editor NEW
692.0 27.0 286.0 497 KB

A Swagger Codegen for typescript, nodejs & angularjs

License: Apache License 2.0

JavaScript 44.34% HTML 55.66%

swagger-js-codegen's Introduction

Swagger to JS & Typescript Codegen

Circle CI NPM version

We are looking for a new maintainer

This project is no longer actively maintained by its creator. Please let us know if you would like to become a maintainer. At the time we wrote this package, the swagger didn't have generators for JavaScript nor TypeScript. Now there are great alternatives of this package available.

This package generates a nodejs, reactjs or angularjs class from a swagger specification file. The code is generated using mustache templates and is quality checked by jshint and beautified by js-beautify.

The typescript generator is based on superagent and can be used for both nodejs and the browser via browserify/webpack.

Installation

npm install swagger-js-codegen

Example

var fs = require('fs');
var CodeGen = require('swagger-js-codegen').CodeGen;

var file = 'swagger/spec.json';
var swagger = JSON.parse(fs.readFileSync(file, 'UTF-8'));
var nodejsSourceCode = CodeGen.getNodeCode({ className: 'Test', swagger: swagger });
var angularjsSourceCode = CodeGen.getAngularCode({ className: 'Test', swagger: swagger });
var reactjsSourceCode = CodeGen.getReactCode({ className: 'Test', swagger: swagger });
var tsSourceCode = CodeGen.getTypescriptCode({ className: 'Test', swagger: swagger, imports: ['../../typings/tsd.d.ts'] });
console.log(nodejsSourceCode);
console.log(angularjsSourceCode);
console.log(reactjsSourceCode);
console.log(tsSourceCode);

Custom template

var source = CodeGen.getCustomCode({
    moduleName: 'Test',
    className: 'Test',
    swagger: swaggerSpec,
    template: {
        class: fs.readFileSync('my-class.mustache', 'utf-8'),
        method: fs.readFileSync('my-method.mustache', 'utf-8'),
        type: fs.readFileSync('my-type.mustache', 'utf-8')
    }
});

Options

In addition to the common options listed below, getCustomCode() requires a template field:

template: { class: "...", method: "..." }

getAngularCode(), getNodeCode(), and getCustomCode() each support the following options:

  moduleName:
    type: string
    description: Your AngularJS module name
  className:
    type: string
  lint:
    type: boolean
    description: whether or not to run jslint on the generated code
  esnext:
    type: boolean
    description: passed through to jslint
  beautify:
    type: boolean
    description: whether or not to beautify the generated code
  mustache:
    type: object
    description: See the 'Custom Mustache Variables' section below
  imports:
    type: array
    description: Typescript definition files to be imported.
  swagger:
    type: object
    required: true
    description: swagger object

Template Variables

The following data are passed to the mustache templates:

isNode:
  type: boolean
isES6:
  type: boolean
description:
  type: string
  description: Provided by your options field: 'swagger.info.description'
isSecure:
  type: boolean
  description: false unless 'swagger.securityDefinitions' is defined
moduleName:
  type: string
  description: Your AngularJS module name - provided by your options field
className:
  type: string
  description: Provided by your options field
domain:
  type: string
  description: If all options defined: swagger.schemes[0] + '://' + swagger.host + swagger.basePath
methods:
  type: array
  items:
    type: object
    properties:
      path:
        type: string
      className:
        type: string
        description: Provided by your options field
      methodName:
        type: string
        description: Generated from the HTTP method and path elements or 'x-swagger-js-method-name' field
      method:
        type: string
        description: 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'
        enum:
        - GET
        - POST
        - PUT
        - DELETE
        - PATCH
        - COPY
        - HEAD
        - OPTIONS
        - LINK
        - UNLIK
        - PURGE
        - LOCK
        - UNLOCK
        - PROPFIND
      isGET:
        type: string
        description: true if method === 'GET'
      summary:
        type: string
        description: Provided by the 'description' or 'summary' field in the schema
      externalDocs:
        type: object
        properties:
          url:
            type: string
            description: The URL for the target documentation. Value MUST be in the format of a URL.
            required: true
          description:
            type: string
            description: A short description of the target documentation. GitHub-Markdown syntax can be used for rich text representation.
      isSecure:
        type: boolean
        description: true if the 'security' is defined for the method in the schema
      parameters:
        type: array
        description: Includes all of the properties defined for the parameter in the schema plus:
        items:
          camelCaseName:
            type: string
          isSingleton:
            type: boolean
            description: true if there was only one 'enum' defined for the parameter
          singleton:
            type: string
            description: the one and only 'enum' defined for the parameter (if there is only one)
          isBodyParameter:
            type: boolean
          isPathParameter:
            type: boolean
          isQueryParameter:
            type: boolean
          isPatternType:
            type: boolean
            description: true if *in* is 'query', and 'pattern' is defined
          isHeaderParameter:
            type: boolean
          isFormParameter:
            type: boolean

Custom Mustache Variables

You can also pass in your own variables for the mustache templates by adding a mustache object:

var source = CodeGen.getCustomCode({
    ...
    mustache: {
      foo: 'bar',
      app_build_id: env.BUILD_ID,
      app_version: pkg.version
    }
});

Swagger Extensions

x-proxy-header

Some proxies and application servers inject HTTP headers into the requests. Server-side code may use these fields, but they are not required in the client API.

eg: https://cloud.google.com/appengine/docs/go/requests#Go_Request_headers

  /locations:
    get:
      parameters:
      - name: X-AppEngine-Country
        in: header
        x-proxy-header: true
        type: string
        description: Provided by AppEngine eg - US, AU, GB
      - name: country
        in: query
        type: string
        description: |
          2 character country code.
          If not specified, will default to the country provided in the X-AppEngine-Country header
      ...

Grunt task

There is a grunt task that enables you to integrate the code generation in your development pipeline. This is extremely convenient if your application is using APIs which are documented/specified in the swagger format.

Who is using it?

28.io is using this project to generate their nodejs and angularjs language bindings.

swagger-js-codegen's People

Contributors

adufilie avatar bartlomn avatar biggora avatar borisirota avatar bradygaster avatar chdanielmueller avatar chrisjamesc avatar dciccale avatar dependabot[bot] avatar hacklone avatar hirse avatar legneato avatar mahnunchik avatar manuelvanrijn avatar mdautry avatar mgmarino avatar nalbion avatar pieterjandesmedt avatar pizzapete avatar pouyanh avatar rajit avatar samratshaw avatar wcandillon avatar zuhito avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swagger-js-codegen's Issues

How to keep method organization

We have our methods organized by tags (and path), but when swagger-js-codegen produces js code all methods end up clubbed into one object.

So how to keep methods organized by tags (to get js code organized similarly how swagger ui presents it) ?

lodash not in npm package

For the swagger-2.0 branch only: there's a dependency on lodash in codegen.js that is not in the package.json file, so it doesn't get installed automatically by npm.

module.js:340
throw err;
      ^
Error: Cannot find module 'lodash'

error during code generation

I'm getting the following error when trying to generate node code

Error: Expected an identifier and instead saw '='. in  Test.prototype.User.exists__head_Users_{id} = function(parameters){ (E030)
    at node_modules/swagger-js-codegen/lib/codegen.js:214:23

the only place I can find anything like that in the json file is here

"/Users/{id}": {
            "head": {
                "tags": ["User"],
                "summary": "Check whether a model instance exists in the data source.",
                "operationId": "User.exists__head_Users_{id}",
                "parameters": [{
                    "name": "id",
                    "in": "path",
                    "description": "Model id",
                    "required": true,
                    "type": "string",
                    "format": "JSON"
                }],
                "responses": {
                    "200": {
                        "description": "Request was successful",
                        "schema": {
                            "type": "object"
                        }
                    }
                },
                "deprecated": false
            },

the json file passes the online validation at http://bigstickcarpet.com/swagger-parser/www/index.html with no errors or warnings, so I don't quite know where or what the problem is ;)

thanks

Samples

It'd be great to have samples demonstrating the generated code in HTML pages. I'm having some difficulty wiring up the factories into a single controller. A simple pet store demo would be quite helpful.

params not being added to method

Hi there!

I have just recently updated to the latest version of swagger-js-codegen and since then have been struggling with an issue: suddenly all parameters have despaired from their respective methods.

Fiddling with the code I found the problem might be in this line:
https://github.com/wcandillon/swagger-js-codegen/blob/master/lib/codegen.js#L89

where lodash chain method has been used as _.chain(params).forEach(...); without calling .value(); in the end of the chain. By not calling the .value method of the chain, the forEach loop never runs and hence parameters never get added to the method. I'm not sure if this is a recent change in swagger-js-codegen or in lodash.

There are two simple ways to fix the problem:

  1. Change _.chain(params).forEach(...); to _.forEach(params, ...); (which I think is the cleanest solution)
  2. Add .value() to the end of the chain.

I can submit a PR if desired but I figured I'd post this issue here first to make sure I got this right.

don't generate client code for OPTIONS requests

OPTIONS requests are automatically sent by browsers when CORS behaviour is required. AWS API Gateway requires that OPTIONS requests are included in the schema, but they don't need to be included in generated code.

Paths with a period result in error during codegen

Paths with a period in them, such as a version number, result in an error:

/Users/jason/dev/pi/pi-codegen/node_modules/swagger-js-codegen/lib/codegen.js:214
            throw new Error(lint.errors[0].reason + ' in ' + lint.errors[0].evidence);
            ^

Error: Unexpected '.'. in  Test.prototype.getFeedsMapsV1.4Venues = function(parameters){
    at /Users/jason/dev/pi/pi-codegen/node_modules/swagger-js-codegen/lib/codegen.js:214:19
    at Array.forEach (native)
    at getCode (/Users/jason/dev/pi/pi-codegen/node_modules/swagger-js-codegen/lib/codegen.js:212:17)
    at Object.exports.CodeGen.getNodeCode (/Users/jason/dev/pi/pi-codegen/node_modules/swagger-js-codegen/lib/codegen.js:225:16)
    at Object.<anonymous> (/Users/jason/dev/pi/pi-codegen/app.js:6:32)
    at Module._compile (module.js:430:26)
    at Object.Module._extensions..js (module.js:448:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:471:10)

The path in question was /feeds/maps/v1.4/venues

Quoting the path, or trying to escape the period doesn't work.

Add support for "global" path object parameters

Hi,

As specified in the spec, the paths object can contain parameters property as well and not only http method names.

As I see in the code, it expects only http methods.

I use this when using path templating so instead of declaring the path parameter in every operation, I declare it once to be "global" of some specific path.

Swagger Example:

  /campaigns/{campaignId}:
    x-swagger-router-controller: campaignsCtrl
    parameters:
      -
        name: campaignId
        in: path
        description: campaign's id 
        required: true
        type: string
    get:
      summary: get campaign
      description: get campaign
      operationId: findById
      responses:
        200:
          description: single marpack
        default:
          description: Error
    delete:
      summary: Delete campaign
      description: Delete campaign
      operationId: delete
      responses:
        204:
          description: campaign deleted
        404:
          description: campaign not found
        default:
          description: Error

Thanks,
Boris

Generate Definitions from swagger

Hi,

I'd like to use swagger-js-codegen to generate Typescript Code from a swagger-file to get errors in case the REST interface changed. But I'm getting a lot of errors due to the missing Definitions.

I found the ts-barnch that has the code required to generate the Definitions, but it looks outdated compared to the master-branch.

What is the plan with ts-branch? Is there any work going on regarding generating the Definitions?

I created a fork to fix a problem where an array does not have an items definition. Should I implement the Definition-generation and create a pull-request?

support swagger 2.0 vendor extensions

Hi,

Swagger 2.0 spec support vendor extensions.

I'm using Apigee's x-swagger-router-controller and the code fails (make sense):

TypeError: Cannot call method 'forEach' of undefined
    at /node_modules/swagger-js-codegen/lib/codegen.js:56:27
    at forOwn (/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:2105:15)
    at Function.forEach (/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:3302:9)
    at /node_modules/swagger-js-codegen/lib/codegen.js:45:11
    at forOwn (/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:2105:15)
    at Function.forEach (/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:3302:9)
    at getViewForSwagger2 (/node_modules/swagger-js-codegen/lib/codegen.js:43:7)
    at getCode (/node_modules/swagger-js-codegen/lib/codegen.js:131:49)
    at Object.exports.CodeGen.getNodeCode (/node_modules/swagger-js-codegen/lib/codegen.js:169:16)
    at Object.<anonymous> (/test.js:6:32)

Swagger.yaml example:

  /users:
    x-swagger-router-controller: usersCtrl
    post:
      summary: Add user
      description: Add user
      operationId: add
      parameters:
        -
          name: user
          in: body
          description: user's object
          required: true
          schema:
            $ref: "#/definitions/User"
      responses:
        201:
          description: New user created
          headers:
            Location: 
              description: New user id
              type: string
        default:
          description: Error
          schema:
            $ref: "#/definitions/ErrorResponse"
    delete:
      summary: Delete user
      description: Delete user
      operationId: delete
      responses:
        204:
          description: User deleted
        404:
          description: User not found
        default:
          description: Error
          schema:
            $ref: "#/definitions/ErrorResponse"

definitions:

  User:
    required:
      - userName
      - password
      - email
    properties: 
      userName: 
        type: string
      password: 
        type: string
      email: 
        type: string

  ErrorResponse:
    required:
      - message
    properties:
      message:
        type: string

Thanks,
Boris

Get an error: Class properties must be methods

test.js created from by pasting the Example from README.md:

$ node test.js
xxx\node_modules\swagger-js-codegen\lib\codegen.js:231
        throw new Error(error.reason + ' in ' + error.evidence + ' ('
              ^
Error: Class properties must be methods. Expected '(' but instead saw 'domain'. in     private domain: string; (E054)
    at xxx\node_modules\swagger-js-codegen\lib\codegen.js:231:23
    at Array.forEach (native)
    at getCode (xxx\node_modules\swagger-js-codegen\lib\codegen.js:229:21)
    at Object.exports.CodeGen.getTypescriptCode (xxx\node_modules\swagger-js-codegen\lib\codegen.js:247:16)
    at Object.<anonymous> (xxx\test.js:8:28)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)

Not really sure where to start looking. The word "domain" isn't used in my spec file.

ETA: It looks like it fails linting... when I paste my spec into www.jshint.com, it doesn't produce any errors. Oh, I guess it lints what it generates. Ignoring the errors now to see what the result is.

`form` param trashes the ability to send `json`

First off, thank you for the awesome work on this library!

Summary

The generated code always looks like:

request({
            method: 'POST',
            uri: domain + path,
            qs: queryParameters,
            headers: headers,
            body: body,
            form: form,
            rejectUnauthorized: false
        }, function(error, response, body) {

And sending a request with json does not work. In order to fix this ... form needs to be removed entirely and body: body, needs to change to be json:body

Long Story

I recently used swagger-js-codegen with a framework known as strongloop/loopback and ran into some issues so I've created a demo branch to make them easy to replicate: https://github.com/ShoppinPal/loopback-example-full-stack/tree/feature/nodejs-client

In total I always have to tweak 5-8 things in a generated file before I can use it. But for each tweak, I'm not sure who is the culprit preventing me from getting a perfectly generated file out-of-the-box:

  1. could it be the code generator?
  2. could it be the swagger spec itself?
  3. could it be the default template which should be replaced with a custom one because one size does not fit all?

So I'll be filing a separate issue per "tweak" and counting on your help to either fix a real issue or better my understanding of how to accomplish what I need.

x-swagger-js-method-name got lost?

Hey,

I've updated my code-generator dependencies to the newest swagger-js-codegen and figured out, that the support for x-swagger-js-method-name has been removed.
Because you still mention it in README.md I did some research and found out that this feature was removed by the commit d89298b and then shipped with versions > 1.2.0

If it happened accidently I would like to see it back again. My generated clients need this function and I would appreciate to use all the new features and bug fixes since 1.1.8 ;-)

Cheers
leachiM2k

Cannot call method 'forEach' of undefined

I'm trying to use the code generator in a relatively basic demo scenario. I'm using the code below to access the demonstration Swagger 2.0 pet store JSON document here:

https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-simple.json

Here's my Node.js code for a complete repro of what I'm trying to accomplish:

var request = require('request');
var CodeGen = require('swagger-js-codegen').CodeGen;

request('https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-simple.json', function(err, response, body){
    console.log(body);

    var angularjsSourceCode = CodeGen.getAngularCode({ className: 'Test', swagger: body }); 
    console.log(angularjsSourceCode);
});

The error I'm receiving is:
TypeError: Cannot call method 'forEach' of undefined
at getView (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\node_modules\swagger-js-codegen\lib\codegen
.js:86:18)
at getCode (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\node_modules\swagger-js-codegen\lib\codegen
.js:124:72)
at Object.exports.CodeGen.getAngularCode (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\node_modules
swagger-js-codegen\lib\codegen.js:150:16)
at Request._callback (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\run.js:13:36)
at Request.self.callback (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\node_modules\request\request.
js:372:22)
at Request.emit (events.js:98:17)
at Request. (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\node_modules\request\request.js
:1317:14)
at Request.emit (events.js:117:20)
at IncomingMessage. (C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration\node_modules\request\re
quest.js:1265:12)
at IncomingMessage.emit (events.js:117:20)
C:\Users\bradyg\Cloud\Sources\AngularSwaggerClientGeneration>

How to use typescript generation

Hello,

I'm trying to use typescript generation, but I'm not sure how to do it. Could someone give me more information about :

  • The imports property, what is it for ? CodeGen.getTypescriptCode({ className: 'Test', swagger: swagger, imports: ['../../typings/tsd.d.ts'] });
  • Is it required? it seems to work without?
  • Is there any way to generate the models automatically ?
  • I'm using hapi-swagger and when models are not explicitly named I have name like : "Model 2" or "Model 6" which is badly handled by the code generation process like this one :
    parameters: { 'body' ? : Model 2, $queryParameters ? : {}, $domain ? : string }
    But maybe the issue is on hapi-swagger side ? could you confirm ?

Thanks a lot.

Add 'Authorization: Bearer TOKEN' header to authenticated requests

Hi,

The swagger spec supports Security Definitions Object and allows to authenticated specific paths while adding them the security property to a path:

  /secure_path:
    get:
      description: description
      operationId: secured_operation
      security:
        - oauth2: ['read']
      responses:
        "200":
          description: Success

I think that as a starting point, adding the requested header to paths that contains the security property will be great (because support for more robust mechanism which takes into account not only the oauth2 flow but the api-key flow as well will take time).

Not quite sure though what is the best way to inject the token (which can be changed dynamically). Maybe register on some event from the rootScope that the user will have to call on token change?

Thanks,
Boris

Add CLI?

Your project looks super awesome! It would be neat to have a CLI so codegen could be called through an npm script or likewise. Iโ€™d be interested in contributing if you want!

swagger-JS-codegen sending content-type 'text/plain' when requesting it consume 'application/json'

So I have newly upgraded to Swagger 2 from 1.x, and am experiencing an odd issue. One of my APIs is getting an incorrect content-type injected into the header and I have no idea where from, you can see below in the SwaggerJSON, The DELETE function even says it consumes application/json, but the CURL(copied from inspect panel) for it sends 'Content-Type: text/plain;charset=UTF-8'. I have provided the CREATE function as a cursory example to show that otherwise the api works fine. I think this is an issue with swagger-js-codegen because if I put the same request into the api-docs it works fine.

Swagger JSON

{
  "/api/entities/{id}/labels": {
    "delete": {
      "consumes": [
        "application/json"
      ],
      "operationId": "deleteEntityLabel",
      "parameters": [
        {
          "default": "16_appiniteDev",
          "description": "The id of the entity to be edited",
          "in": "path",
          "name": "id",
          "required": true,
          "type": "string"
        },
        {
          "description": "The label/labels to be deleted",
          "in": "body",
          "name": "labels",
          "required": true,
          "schema": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        }
      ],
      "produces": [
        "application/json"
      ],
      "responses": {
        "200": {
          "description": "OK",
          "schema": {
            "$ref": "#/definitions/ResponseEntity"
          }
        },
        "204": {
          "description": "No Content"
        },
        "401": {
          "description": "Unauthorized"
        },
        "403": {
          "description": "Forbidden"
        }
      },
      "summary": "Deletes Labels for Entities",
      "tags": [
        "entity-resource"
      ]
    },
    "post": {
      "consumes": [
        "application/json"
      ],
      "operationId": "createEntityLabel",
      "parameters": [
        {
          "default": "16_appiniteDev",
          "description": "The id of the entity to be edited",
          "in": "path",
          "name": "id",
          "required": true,
          "type": "string"
        },
        {
          "description": "The array of labels to be set",
          "in": "body",
          "name": "labels",
          "required": true,
          "schema": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        }
      ],
      "produces": [
        "application/json"
      ],
      "responses": {
        "200": {
          "description": "OK",
          "schema": {
            "$ref": "#/definitions/ResponseEntity"
          }
        },
        "201": {
          "description": "Created"
        },
        "401": {
          "description": "Unauthorized"
        },
        "403": {
          "description": "Forbidden"
        },
        "404": {
          "description": "Not Found"
        }
      },
      "summary": "Creates Labels for Entities",
      "tags": [
        "entity-resource"
      ]
    }
  }
}

DELETE
JAVA/SPRING
    /**
     * DELETE /entities/{id}/labels -> delete labels for an entity
     *
     * @param id
     * @param labels
     * @throws ServiceException
     */
    @RequestMapping(value = "/entities/{id}/labels", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    @ApiOperation(value = "Deletes Labels for Entities", nickname = "deleteEntityLabel", consumes = "application/json")

    public ResponseEntity deleteLabels(
            @ApiParam(value = "The id of the entity to be edited", required = true, defaultValue = "16_appiniteDev") @PathVariable final String id,
            @ApiParam(value = "The label/labels to be deleted", required = true, defaultValue = "[\"label1\",\"label2\",\"label3\"]") @NotNull final @RequestBody String[] labels

    ) throws ServiceException {
        boolean isAppEntity = false;
        User user = userService.getUserWithAuthorities();
        String[] type = id.split("_");
        if (StringUtils.isNumeric(type[0]) && !type[1].startsWith(type[0])) {
            isAppEntity = true;

        }

        entityService.deleteTags(id, labels, user, isAppEntity);
        Map<String, String> response = new LinkedHashMap<>();
        response.put(Constants.RESPONSE_ENTITY_HEADER_MESSAGE,
                "Labels deleted successfully");
        return new ResponseEntity(response, HttpStatus.OK);
    }

CURL FROM APP
curl 'http://localhost:8080//api/entities/52_QA42/labels?cacheBuster=1472070679337' -X DELETE -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: text/plain;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'x-auth-token: admin:1472097365429:8e6524e252e2aebb786b7738c44fe385' -H 'Referer: http://localhost:8080/' -H 'Cookie: NG_TRANSLATE_LANG_KEY=%22en%22' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '["Bug13124"]' --compressed


CREATE
JAVA/SPRING
    /**
     * POST /entities/{id}/labels -> add labels for a non hadoop entity
     *
     * @param id
     * @param labels
     * @throws ServiceException
     */
    @RequestMapping(value = "/entities/{id}/labels", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    @ApiOperation(value = "Creates Labels for Entities", nickname = "createEntityLabel")
    public ResponseEntity addLabels(
            @ApiParam(value = "The id of the entity to be edited", required = true, defaultValue = "16_appiniteDev") @PathVariable final String id,
            @ApiParam(value = "The array of labels to be set", required = true, defaultValue = "[\"label1\",\"label2\",\"label3\"]") @NotNull final @RequestBody String[] labels)
            throws ServiceException {
        boolean isAppEntity = false;
        User user = userService.getUserWithAuthorities();
        String[] type = id.split("_");
        if (StringUtils.isNumeric(type[0]) && !type[1].startsWith(type[0])) {
            isAppEntity = true;

        }

        entityService.addTags(id, labels, user, isAppEntity);
        Map<String, String> response = new LinkedHashMap<>();
        response.put(Constants.RESPONSE_ENTITY_HEADER_MESSAGE,
                "Labels added successfully");
        return new ResponseEntity(response, HttpStatus.OK);
    }

CURL FROM APP
curl 'http://localhost:8080//api/entities/52_QA42/labels?cacheBuster=1472071851544' -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'x-auth-token: admin:1472097365429:8e6524e252e2aebb786b7738c44fe385' -H 'Referer: http://localhost:8080/' -H 'Cookie: NG_TRANSLATE_LANG_KEY=%22en%22' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '["test"]' --compressed

Any Ideas?

Explicitly specify Content-Type

If the content type is either specified in the operation or as overall "consumes" property it should be added as header.
I got problems with this as my API checks for the Content-Type property.

Make `methodName` in `codegen.js` customizable

I want to submit a PR in order to make the following line of code in codegen.js configurable:
methodName: op.nickname,
but I don't understand the library very well so I wanted to pick your brain first.

I want to do something like:
methodName: (opts['nickname']) ? opts['nickname'](op) : op.nickname,
so that by default if someone didn't want to customize the methodName, everything will remain backward compatible and just work. But if folks did want to change it then passing in a method to perform such a transformation would be how they accomplish this.

In the pseudo-code I wrote above, can you confirm if opts is the correct argument via which an action like passing in a custom function to this library would/should be performed?

Basic Auth Support

Does the Node.js template support basic auth? It looks like it only accepts API tokens....

Client Side Library with Fetch API

Hi @wcandillon,
Thanks for this usefull library.

I've started working on generating a Client Side library that use Fetch API to make request.
I would like also to support a write to file option.

Does this feature are of you interest?

Other question, as I'm not familiar with Vows, would a problem to have some tests running under a more traditional Mocha/Chai environment?

query string parameter names should not be transformed with respect to case

According to the W3 spec for URIs, query string parameter names should be considered case-sensitive unless the scheme being used specifically calls them out as being case-insensitive. See this. Note that the HTTP spec here does not specify that query parameters are case-insensitive, therefore they must be treated as case-sensitive per the URI spec.

When presented with a query string parameter whose name is all uppercase, TOK for example, the generator assumes the name of the parameter provided in the params input to the operation will be in camel case (lower case first letter, so tOK in this example). The discrepancy between the name of the field in the params input will become a source of confusion and is not consistent with the specification of the path.

In any case, it is my responsibility as the API provider to document the API correctly and I would prefer that the API present the _exact_ interface that I specify in the JSON. The generator should not perform any transformation of the parameter names anywhere, in my opinion, regardless of whatever conventions may be common in the language. In other words, no assumptions should be made by the generator about conventions that may be in use by the API.

So this:

{
    . . . 
    "schemes": ["https"],
    "paths": {
        "/thing/{id}": {
            "get": {
                "summary": "Get a thing",
                "description": "A route to get a thing.",
                "operationId": "getThingById",
                "parameters": [{
                    "name": "TOK",
                    "in": "query",
                    "description": "application token whose name will get transformed to tOK, which is NOT OK",
                    "required": true,
                    "type": "string"
                }],
    . . . 
}

Gets transformed into something like this:

if (parameters['tOK'] !== undefined) {
    queryParameters['TOK'] = parameters['tOK'];
}

Sample thing.json file available if needed.

Generated HTTP method is empty for AngularJS client

I am not sure if this issue exists in generated nodejs code, it does exist for generated AngularJS when swagger spec JSON is loaded from ServiceStack's Swagger API.

        var method = {
            path: api.path,
            className: opts.className,
            methodName: op.nickname,
            method: op.method,
            isGET: op.method === 'GET',
            summary: op.summary,
            parameters: op.parameters
        };

should be fixed to

        var method = {
            path: api.path,
            className: opts.className,
            methodName: op.nickname,
            method: op.method || op.httpMethod,
            isGET: (op.method || op.httpMethod) === 'GET',
            summary: op.summary,
            parameters: op.parameters
        };

Global parameters $ref issue

Hi,

I'm familiar with the "#/parameters/PARAM_NAME" syntax when accessing globals.
It seems that the code expecting it to be without the prefix "#/parameters".

I guess that this prefix is needed because there are few objects that defines global parameters (there is the definitions object as well).

I think that the best solution to handle $ref will be something like:

var value;
if (obj.$ref.indexOf('#/') === -1) {
    //backwards compatibility
} else {
    var paths  = obj.$ref.split('/');
    var collection = paths[1];
    var key = paths[2];
    value = swagger[collection][key];
}

Edit: just noticed that there is no need to access the definition object so I guess the code for the general solution is useless and value = swagger.parameters[obj.$ref.split('/')[2]]; will be good enough :)

Thanks,
Boris

Minimum swagger json gives TypeError: Cannot read property 'toUpperCase' of undefined

For some reason, a minimum json (from Swagger Editor) gives TypeError: Cannot read property 'toUpperCase' of undefined

cat test.js

var fs = require('fs');
var CodeGen = require('swagger-js-codegen').CodeGen;

var file = 'swagger/min.json';
var swagger = JSON.parse(fs.readFileSync(file, 'UTF-8'));
var angularjsSourceCode = CodeGen.getAngularCode({ className: 'Test', swagger: swagger });
console.log(angularjsSourceCode);

cat swagger/min.json

{
"swagger" : "2.0",
"info" : {
"version" : "0.0.0",
"title" : "Simple API"
},
"paths" : {
"/" : {
"get" : {
"parameters" : [ ],
"responses" : {
"200" : {
"description" : "OK"
}
}
}
}
}
}

node test.js

/home/ob/node_modules/swagger-js-codegen/lib/codegen.js:33
return m.toLowerCase() + result[0].toUpperCase() + result.substring(1);
^
TypeError: Cannot read property 'toUpperCase' of undefined
at getPathToMethodName (/home/ob/node_modules/swagger-js-codegen/lib/codegen.js:33:39)
at /home/ob/node_modules/swagger-js-codegen/lib/codegen.js:63:130
at forOwn (/home/ob/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:2105:15)
at Function.forEach (/home/ob/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:3302:9)
at /home/ob/node_modules/swagger-js-codegen/lib/codegen.js:56:11
at forOwn (/home/ob/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:2105:15)
at Function.forEach (/home/ob/node_modules/swagger-js-codegen/node_modules/lodash/dist/lodash.js:3302:9)
at getViewForSwagger2 (/home/ob/node_modules/swagger-js-codegen/lib/codegen.js:49:7)
at getCode (/home/ob/node_modules/swagger-js-codegen/lib/codegen.js:159:49)
at Object.exports.CodeGen.getAngularCode (/home/ob/node_modules/swagger-js-codegen/lib/codegen.js:194:16)

angular : how to add responseType:'arraybuffer' to options of generated service method ?

Hi,

Using a swagger.json file generated from Java code annotated with "@ApiOperation" etc. (see https://github.com/swagger-api/swagger-core/wiki/Annotations) , I end up with this "options" object in my generated Angular js code

  var options = {
                    timeout: parameters.$timeout,
                    method: 'GET',
                    url: url,
                    params: queryParameters,
                    data: body,
                    headers: headers,
                };

This is cool but I need to specify the responseType also, ie have something like

  var options = {
                    timeout: parameters.$timeout,
                    method: 'GET',
                    url: url,
                    params: queryParameters,
                    data: body,
                    headers: headers,
                    responseType: 'arraybuffer'    // <--- This
                };

But without going into modifications of the mustache templates, the only configuration I can give on a method level is through the queryParameters we see above.

So can i specify easily this option somewhere on the generator itself ?
If not, is there possibly some option in the Java code and Annotation ("@ApiOperation" etc.) maaayybe ??
Or is through modification of the mustache templates actually the only way ?

Thanks a lot for your help.

Syntax for attaching methods via prototype is broken?

Summary

My generated code has methods like:

module.exports.user = function(domain) {
  var request = require('request');
  var Q = require('q');
  ...
  this.prototype.updateAttributes = function(parameters) {...};
};

This results in errors such as TypeError: Cannot set property 'updateAttributes' of undefined ... in order to fix this, the generated code needs to be tweaked like so:

var request = require('request');
var Q = require('q');
var user = function(domain) {
  this.domain = domain;
  ...
};
user.prototype.updateAttributes = function(parameters) {...};
module.exports.user = user;

Long Story

I recently used swagger-js-codegen with a framework known as strongloop/loopback and ran into some issues so I've created a demo branch to make them easy to replicate: https://github.com/ShoppinPal/loopback-example-full-stack/tree/feature/nodejs-client

In total I always have to tweak 5-8 things in a generated file before I can use it. But for each tweak, I'm not sure who is the culprit preventing me from getting a perfectly generated file out-of-the-box:

  1. could it be the code generator?
  2. could it be the swagger spec itself?
  3. could it be the default template which should be replaced with a custom one because one size does not fit all?

So I'll be filing a separate issue per "tweak" and counting on your help to either fix a real issue or better my understanding of how to accomplish what I need.

Generator ignores produces value (Accept headers).

Within my JSON schema I've got the 'produces' key set to 'application/pdf'.

"consumes": ["application/json"],
"produces": ["application/pdf"],

After generating the service it keeps requesting the API with 'application/json'.

Swagger body parameters

I'm not sure if this is me misunderstanding the Swagger specification, or if this is a bug, but I'll go ahead and lay it out.

According to the specification, a Path Item Object can contain a field named parameters, which is an array of either Parameter Objects or Reference Objects. Let's focus on the parameter objects.

The parameter object contains a number of fields, including the required field in. This field can be one of the following possible values: "query", "header", "path", "formData" or "body".

In my case, I have a Swagger, in one of my Path Item Objects, I have a singular parameter object in my parameters field. This singular parameter object's in field is set to body. According to the specification, if in is set to body, another parameter must be present, schema, which is of type Schema Object, which is based on the JSON Schema Specification Draft 4.

In this schema object, I can define one to many properties that should essentially be considered body parameters. But, my issue is that the template variable parameters does not contain the variables that are defined as body parameters, it only contains one parameter named body.

Here is my swagger:

{
    "swagger": "2.0",
    "info": {
        "title": "",
        "version": "",
        "description": ""
    },
    "paths": {
        "/some/resource": {
            "post": {
                "responses": {
                    "200": {
                        "description": "OK",
                        "headers": {},
                        "examples": {
                            "application/json": {
                                "prop1": "a string"
                            }
                        },
                        "schema": {
                            "type": "object",
                            "properties": {
                                "prop1": {
                                    "type": "string",
                                    "required": true
                                }
                            }
                        }
                    }
                },
                "summary": "Some resource",
                "description": "",
                "tags": [
                    "(no tags)"
                ],
                "parameters": [
                    {
                        "name": "body",
                        "in": "body",
                        "schema": {
                            "type": "object",
                            "properties": {
                                "prop1": {
                                    "type": "string",
                                    "required": true
                                }
                            }
                        }
                    }
                ]
            }
        }
      }
}

And here is the resulting Node.js code, specifically the portion that uses the method isBodyParameter:

if (parameters['body'] !== undefined) {
        body = parameters['body'];
    }

There is no mention of the body parameter param1. It would be very helpful if, when one of the Swagger parameters is in body and there is a schema defined, those body parameters would be accessible via the template variables.

Ideas / comments?

Thanks,
-Max

Support custom templates

I'm using swagger-js-codegen to generate a library in a unique environment (Node + Browserify + Ember). Right now, I'm using a forked version with custom templates. It would be nice if the codegen could be used with custom templates without making an entire fork. Something like:

var CodeGen = require('swagger-js-codegen').CodeGen;
var generator = CodeGen.generatorFor({
  class_template: "custom_class_template.js",
  method_template: "...",
  request_template: "..."
});

var file = 'swagger/spec.json';
var swagger = JSON.parse(fs.readFileSync(file, 'UTF-8'));
var code = generator.getCode(swagger);

Proposal - add client side validation

Currently there is support for required and partial support for pattern (is there a reason why its supported only in query parameters ?).

I think that for the node client it can be very convenient right away.
The angular client is more complex because in order to provide a good user experience its need to be through the form validation mechanism.

Anyway, I'm using the angular client and I'll try to think what is the best way to use one validation mechanism (based on the swagger spec) while still embracing angular forms -> I'm trying to use the swagger as one source of truth whenever I can without making manual syncing ๐Ÿ˜‰

The amazing swagger-tools project already implemented this kind of validation but as a middleware for the server side. I submitted this issue in order to maybe taking advantage of that.

I think that support for that will make this project even more awesome :)

@wcandillon Is it something that you think should be part of this project ?

Boris :)

Support for 2.0 spec path parameters

The codegen throws an error whenever a path parameter is used in the 2.0 spec:
Error: Expected an assignment or function call and instead saw an expression.

Add Response to Template Variables

In Swagger I can specify successful responses with a data model.
I need to write a TypeScript integration that specifies the response accordingly. This is impossible since the response model is not part of the template variables.

Can you help me?

support passing arguments on $broadcast and $on events in angular client

A use case for that can be listening to getToken event and then automatically add the new generated token. something like:

var api = new API();

api.$on($scope, '/auth/token', function (token) {
    api.setToken(token);
});

api.getToken().then(function (data) {
    ...
    api.$broadcast('/auth/token', data.token);
    ...
}, function (err) { ... });

Moreover, attaching the path attribute to the method in order to create one source of truth (the swagger spec) for the events mechanism (no need to dig in the implementation to check the path and to change it manually when changed in the spec).
In the method template it will look like this:

...
{{&className}}.prototype.{{&methodName}}.path = '{{&path}}';

And the above example will be like this:

var api = new API();

api.$on($scope, api.getToken.path, function (token) {
    api.setToken(token);
});

api.getToken().then(function (data) {
    ...
    api.$broadcast(api.getToken.path, data.token);
    ...
}, function (err) { ... });

What do you think ? sound reasonable ?

Boris :)

split class into models

is it possible to move the models into their own module ? for example, if I have users and customers,

instead of

myclass.prototype.User_create = function(parameters) {

I could have

User.prototype.create = function()

which looks a lot better in code - User.create()

I also would like to know what's happened here :

myclass.prototype.User_prototype___findById__accessTokens 
myclass.prototype.User_prototype___get__accessTokens

are these methods than can be overridden by the x- stuff ?

the reason why I ask is that in the documentation, there is this example:

// A PUT to this path in a swagger schema:  /records/{id}/meta
// is intended to update a "meta" property on a specific "Record" entity.
// ...swagger-js-codegen generates a method named:
MyApi.prototype.putEntitiesByIdMeta = function(parameters) {

which looks nothing like my generated code ;)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.