Skip to content

[TypeScript][Angular] represent swagger enums as union of literal types #6233

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

Merged
merged 4 commits into from
Oct 7, 2017
Merged

Conversation

bedag-moo
Copy link
Contributor

@bedag-moo bedag-moo commented Aug 3, 2017

PR checklist

  • Read the contribution guidelines.
  • Ran the shell script under ./bin/ to update Petstore sample so that CIs can verify the change. (For instance, only need to run ./bin/{LANG}-petstore.sh and ./bin/security/{LANG}-petstore.sh if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates). Windows batch files can be found in .\bin\windows\.
  • Filed the PR against the correct branch: master for non-breaking changes and 3.0.0 branch for breaking (non-backward compatible) changes.

Description of the PR

This PR changes the angular-typescript generator to emit a union of literals for swagger enums, e.g.:

export type StatusEnum = 'open' | 'inProgress' | 'resolved' | 'closed';

or

export type ResponseCode = 200 | 404;

enabling their easy use in angular templates, structural subtyping
among enums (in particular, different instances of the same enum
are now mutually assignable), improving type safety by preventing
incorrect widening, and permitting numeric enum values
(albeit without descriptive names)

Fixes #6206, #5146, #3500

@bedag-moo
Copy link
Contributor Author

The Travis failure seems to be an infrastructure issue unrelated to this PR:

[ERR!] GitHub API: GitHub rate limit reached.
To increase the limit use GitHub authentication.
See: https://github.com/DefinitelyTyped/tsd#tsdrc

@bobvanderlinden
Copy link

This change is very much appreciated. I'd like to copy my JSON example for the schema into typescript and have it checked. At the moment this isn't possible because all enum values need to be changed to their reference even though it's structurally the same and the server would send that exact JSON as well.

In addition, this would also solve problems with numerical (or other) enums.

That said, this PR at the moment contains a number of unrelated changes, which might lessen motivation to merge for the Swagger maintainers.

Copy link

@bobvanderlinden bobvanderlinden left a comment

Choose a reason for hiding this comment

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

There seems to be many changes that were made by your editor/linter. It would help if those were removed from the PR (or made in a separate PR).

@@ -73,7 +73,7 @@ export class StoreService {
}

/**
* For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors

Choose a reason for hiding this comment

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

This change seems unrelated.

@@ -104,7 +104,7 @@ export class StoreService {
}

/**
* For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
* For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions

Choose a reason for hiding this comment

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

This change seems unrelated.

*
* @summary Add a new pet to the store

Choose a reason for hiding this comment

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

This change seems unrelated.

*
* @summary Deletes a pet

Choose a reason for hiding this comment

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

This change seems unrelated.

* Multiple status values can be provided with comma separated strings
* @summary Finds Pets by status

Choose a reason for hiding this comment

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

This change seems unrelated.

* Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
* For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
* @summary Find purchase order by ID

Choose a reason for hiding this comment

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

This change seems unrelated.

*
* @summary Place an order for a pet

Choose a reason for hiding this comment

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

This change seems unrelated.

@@ -2,18 +2,18 @@ export interface ConfigurationParameters {
apiKeys?: {[ key: string ]: string};
username?: string;
password?: string;
accessToken?: string;
accessToken?: string | (() => string);

Choose a reason for hiding this comment

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

This change seems unrelated.

password?: string;
accessToken?: string | (() => string);
basePath?: string;
withCredentials?: boolean;

Choose a reason for hiding this comment

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

This change seems unrelated.

@@ -35,6 +35,6 @@
"typescript": "^2.1.5"
},
"publishConfig": {
"registry": "https://skimdb.npmjs.com/registry"
"registry":"https://skimdb.npmjs.com/registry"

Choose a reason for hiding this comment

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

This change seems unrelated.

@bobvanderlinden
Copy link

Hmm, I just saw that this PR was made against 2.3.0, but this is actually a breaking change. Existing implementations that rely on the TypeScript codegen will break. I'm guessing you need to make the PR against 3.0.0.

@bedag-moo
Copy link
Contributor Author

It's a breaking change for an unreleased feature, so I thought the earlier release was fine as well. (TypeScript support in 2.2.x is pretty much nonexistent AFAIK), but of course I'd be happy to rebase if a maintainer asked.

As you can see from the commit history, the "unrelated changes" were made by the shell scripts the PR checklist instructed me to run. If the maintainers don't want that, they can cherry-pick my first commit instead (and update the PR checklist).

@bobvanderlinden
Copy link

You're absolutely right. Sorry for the confusion. Tested it locally on an existing project and it is working wonderfully. Hopefully this PR will be merged soon.

@wing328 wing328 changed the base branch from 2.3.0 to master September 1, 2017 14:12
@bedag-moo
Copy link
Contributor Author

@wing328: Hm ... why did you change the base branch? This PR builds upon other work in the 2.3.0 branch that (as far as I know) has not yet been merged to master. Do you mean to tell me to rebase on master?

As an aside, is there anything I can do to accelerate the review process?

@wing328
Copy link
Contributor

wing328 commented Sep 12, 2017

@bedag-moo as explained in another thread, 2.3.0 is now the master after we released stable version v2.2.3

Please rebase on the latest master to help resolve the merge conflicts.

Also thanks @bobvanderlinden for testing this PR.

enabling their easy use in angular templates, structural subtyping
among enums (in particular, different instances of the same enum
are now mutually assignable), improving type safety by preventing
incorrect widening, and permitting numeric enum values
(albeit without descriptive names)

Fixes #6206, #5146, #3500
@bedag-moo bedag-moo closed this Sep 12, 2017
@bedag-moo bedag-moo reopened this Sep 12, 2017
@bedag-moo
Copy link
Contributor Author

I manually merged my changes (a rebase didn't work as the files had been moved), and regenerated the samples.

@bobvanderlinden
Copy link

@bedag-moo Could you give this another look?

@bedag-moo
Copy link
Contributor Author

@bobvanderlinden: What do you want me to look at?

@bobvanderlinden
Copy link

bobvanderlinden commented Sep 15, 2017

Sorry, meant to mention @wing328 . That's what I get replying from mobile ;)

@wing328 could you give this another look?

@wing328
Copy link
Contributor

wing328 commented Sep 18, 2017

cc @TiFu @taxpon @sebastianhaas @kenisteward @Vrolijkx for review.

Copy link
Contributor

@sebastianhaas sebastianhaas left a comment

Choose a reason for hiding this comment

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

I'd vote for the style-related changes I've pointed out- apart from that this looks good to me :) Thanks for the PR

{{/enumVars}}
{{/allowableValues}}
}
export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
Copy link
Contributor

Choose a reason for hiding this comment

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

{{/enumVars}}
{{/allowableValues}}
}
export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
{{/isEnum}}
{{/vars}}
}{{/hasEnums}}
Copy link
Contributor

Choose a reason for hiding this comment

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

See above.

}{{/hasEnums}}i
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm afraid you accidentally inserted an i there 🙈

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, indeed. Fixed.

@wing328
Copy link
Contributor

wing328 commented Oct 7, 2017

@bedag-moo
Copy link
Contributor Author

Because the typescript compiler gives compilation errors when you try to do the stuff I describe there. In particular, check out the following code:


enum IssueStatusEnum {
  Open = 'open',
  InProgress = 'inProgress',
  Resolved = 'resolved',
  Closed = 'closed',
}

// used in a different place in the api, but conceptually the same enum
enum TransitionTargetEnum {
  Open = 'open',
  InProgress = 'inProgress',
  Resolved = 'resolved',
  Closed = 'closed',
}

const badgeType: {[K: IssueStatusEnum]: string} = {
  Open: "danger",
  InProgress: "warning",
  Resolved: "info",
  Closed: "success",
}

let t: TransitionTargetEnum;
t = IssueStatusEnum.Open;

which gives

Error:(41, 20) TS1023:An index signature parameter type must be 'string' or 'number'.
Error:(49, 1) TS2322:Type 'IssueStatusEnum.Open' is not assignable to type 'TransitionTargetEnum'.

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo
Can you try to compile with TypeScript version 2.4 or later?

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo
Can you try in playground ?
and send me link
https://www.typescriptlang.org/play/

@bedag-moo
Copy link
Contributor Author

I did compile with Typescript 2.4, and if you copy the above code to the playground you can see the errors yourself.

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo
code bellow compiles

enum IssueStatusEnum {
  Open = 'open',
  InProgress = 'inProgress',
  Resolved = 'resolved',
  Closed = 'closed',
}

// used in a different place in the api, but conceptually the same enum
enum TransitionTargetEnum {
  Open = 'open',
  InProgress = 'inProgress',
  Resolved = 'resolved',
  Closed = 'closed',
}

const badgeType: {[K: IssueStatusEnum]: string} = {
  Open: "danger",
  InProgress: "warning",
  Resolved: "info",
  Closed: "success",
}

let t: TransitionTargetEnum | IssueStatusEnum;
t = IssueStatusEnum.Open;```

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo
let t: TransitionTargetEnum | IssueStatusEnum;

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo @wing328 @sebastianhaas
On positive side of this pull request is that generated js code
is more efficient !
So in my opinion this could be not default option in code generation

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo
const could be replace by function
that take enum parametar and return string

@bedag-moo
Copy link
Contributor Author

... and how would you implement that function without sacrificing clarity or type safety?

@topce
Copy link
Contributor

topce commented Oct 18, 2017

@bedag-moo
switch case by enum or union of enums
not sure why you have two enums with different name !?
maybe there is some more elegant solution should not be too difficult

@topce
Copy link
Contributor

topce commented Oct 19, 2017

@bedag-moo
for example

`function getBadgeType1(issueStatusEnum: IssueStatusEnum): string {
  switch (issueStatusEnum) {
    case IssueStatusEnum.Open: {
      return "danger";
    }
    case IssueStatusEnum.InProgress: {
      return "warning";
    }
    case IssueStatusEnum.Resolved: {
      return "info";
    }
    case IssueStatusEnum.Closed: {
      return "success";
    }
  }
}`

@topce
Copy link
Contributor

topce commented Oct 19, 2017

@bedag-moo @sebastianhaas @bobvanderlinden

If you wanted not to break compatibility with previous version
it was possible by still keeping old enums with cast any
and add new type with union of string literals
and finally create new type as union of those types
With this done in model in api use new union type
So if end user pass old Enum it is OK
if user pass string it also pass.
When migrating to angular 5 just remove any in enum

@topce
Copy link
Contributor

topce commented Oct 19, 2017

@bedag-moo @bobvanderlinden @sebastianhaas @wing328
for example

type IssueStatusType = 'open' | 'inProgress' | 'resolved' | 'closed'; 
enum IssueStatusEnum {
  Open = 'open',
  InProgress = 'inProgress',
  Resolved = 'resolved',
  Closed = 'closed'
}
type IssueStatus = IssueStatusType | IssueStatusEnum ;
// export all types so user use what she want
// use in rest api calls IssueStatus 

Just trying to help ;-)
Good work guys !!!

@bobvanderlinden
Copy link

bobvanderlinden commented Oct 19, 2017

@topce Thanks for the clarification. My main issue was that I couldn't use JSON as test fixtures because string wasn't accepted as a value for an enum. Like in this example.

This PR was a good alternative, as swagger defines possible string or int values and doesn't really define an enum. These concepts are unfortunately not the same in TypeScript.

Your example illustrates a good workaround to keep everyone happy. Even though the implementation doesn't look that pretty to me, it does seem like a good solution for swagger-codegen for the moment.

That said, it is dawning on me that this is probably a deficiency of TypeScript itself. TypeScript should be able to assign a constant 'string' to an enum MyString { StringValue = 'string' }, but at the same time do not allow arbitrary values to be assigned. Would all of you agree that this is a desired feature in TypeScript? In that case I'd gladly make an issue.

EDIT: I found a matching issue on TypeScript, but it is currently closed unfortunately.

@topce
Copy link
Contributor

topce commented Oct 19, 2017

@bobvanderlinden Interesting. Thank you for explanation!
If TS team does not wont to fix it workaround would be

enum ExampleEnum {
    ExampleValueA = 'a',
    ExampleValueB = 'b'
}

type ExampleType = 'a' | 'b';

type Example = ExampleType | ExampleEnum; 

const example: Example = 'a';

@bobvanderlinden
Copy link

I found that it isn't really a good workaround when the rest of your code uses ExampleEnum or ExampleType. You probably do not want to use Example in all of your code because it removes the ability to (for instance) do exhaustive switch-cases.

Additionally, the behavior of string-enums and string-unions being differently typed is intended (see this new post). It's unfortunate, but we'll have to deal with that.

That being said, @RyanCavanaugh mentioned here that the intent of string-enums is to be able to change its underlying value without changing all of the code that relies on it. In the case of Swagger and this PR always need to change the code when the swagger definition changes, so I'd say string-union is appropriate and string-enum is not.

@topce
Copy link
Contributor

topce commented Oct 23, 2017

I put in my previous comments pros and cons for both solution.
I understand that @bedag-moo and @bobvanderlinden
value more simplicity then compatibility with previous version .
I respect your opinion and arguments .

tzimisce012 pushed a commit to tzimisce012/swagger-codegen that referenced this pull request Oct 23, 2017
* [Java] fix bug to only remove "CustomInstantDeserializer" for Play v2.5 (swagger-api#6444)

* fix bug to only remove CustomInstantDeserializer for play25

* revise logic

* fix logic for CustomInstantDeserializer.java

* [Swift3/Swift4] update all cocoapods for swift3/swift4 (swagger-api#6441)

* [Swift] update all cocoapods for swift3/swift4

* fix subspec specification

* [Java] Handle Long in enum correctly (swagger-api#6342)

Resolves swagger-api#6338

* [All generators] Supports of hyphen-case to camelCase (swagger-api#6399)

* Supports of hyphen-case to camelCase

* Add unit tests for the new section in the camelize function.

* [ANDROID][volley] Handle UnsupportedEncodingException in invokeAPI (swagger-api#6436)

* [ANDROID][volley] Handle UnsupportedEncodingException in invokeAPI (Issue swagger-api#6432)
The constructor of StringEntity can throw UnsupportedEncodingException, which is not catch nor thrown by createRequest method.
Therefore the build of android client fails with:

ApiInvoker.java:448: error: unreported exception UnsupportedEncodingException; must be caught or declared to be thrown

This commit adds a try ... catch on UnsupportedEncodingException in invokeAPI methods and declare this exception to be thrown in createRequest

* [ANDROID][volley] Handle UnsupportedEncodingException in invokeAPI (Issue swagger-api#6432)
The constructor of StringEntity can throw UnsupportedEncodingException, which is not catch nor thrown by createRequest method.
Therefore the build of android client fails with:

ApiInvoker.java:448: error: unreported exception UnsupportedEncodingException; must be caught or declared to be thrown

This commit adds a try ... catch on UnsupportedEncodingException in invokeAPI methods and declare this exception to be thrown in createRequest

* [ANDROID][Volley] Handle UnsupportedEncodingException (Issue swagger-api#6432)
Throw more precise ApiException

* [haskell-http-client] update readme; improve lens generation; fix dateFormat (swagger-api#6448)

* point readme links to canonical locations

* use lenses for non-required model fields, instead of traversals

* fix .gitignore generation

* fix dateFormat cli option bug

* add jfastnacht to php tech comm

* Genesys acquired Interactive Intelligence (swagger-api#6453)

See http://www.genesys.com/about/newsroom/news/genesys-completes-acquisition-of-interactive-intelligence

* [haskell-http-client] update documentation; refactoring; add 'strictFields' cli option (swagger-api#6458)

* update readme; remove unused DeriveAnyClass extension

* refactor request/param utility functions

* add strictFields cli option

* add CONTRIBUTING.md

* add note to deprecate swift generator

* [C#] Enabled inheritance to prevent property duplication (swagger-api#6335)

* Issue#3829. [CSharp] Enabled inheritance to prevent property duplication when using allOf and discriminator

* tabs removed

* Petstore sample updated

* update c# petstore samples

* add presentation by Jesse Collis

* add square blog post by roykachouh, retrofit post

* fix NPE in get swagger type (swagger-api#6462)

* add R to the list of supported languages

* add more links to presentations, blog posts, etc

* add https://pycon.jp/2017/ja/ presentation

* add more blog posts

* [Python][Flask] Upgraded connxion to 1.1.15 (now supports multi collection format arrays) (swagger-api#6463)

* [Python][Flask] Upgraded connxion to 1.1.15 (now supports multi collection format arrays)

* Was modified by ./bin/python-petstore.sh

* [ObjC] fix NPE when getting swagger type (swagger-api#6465)

* fix npe in swagger type (objc)

* remove trailing spaces

* Better logic to handle tags with special characters (swagger-api#6466)

* better logic to handle tag with special characters

* update test cases

* comment out swift test cases

* restore the swift tests

* fix link to fehguy twitter account

* Handle when response is a file URL. (swagger-api#6469)

This is the equivalent change in the swift4 module which was made in the swift3 module in this PR:

swagger-api#6274

This updates AlamofireImplementations.mustache to handle when the response is an URL. It also makes changes in the generated sample code for:

* default configuration (no promisekit or rxswift)
* promisekit
* rxswift

Also, in order to build, the generated code needed to be updated with the change in CodableHelper which changes dataDecodingStrategy to ".base64" from its previous definition in earlier Xcode 9 betas.
*

* Support object schemas with only additionalProperties. (swagger-api#6492)

Previously, we had implemented the Codable protocol by simply claiming conformance, and making sure that each of our internal classes also implemented the Codable protocol. So our model classes looked like:

class MyModel: Codable {
   var propInt: Int
   var propString: String
}

class MyOtherModel: Codable {
   var propModel: MyModel
}

Previously, our additionalProperties implementation would have meant an object schema with an additionalProperties of Int type would have looked like:

class MyModelWithAdditionalProperties: Codable {
   var additionalProperties: [String: Int]
}

But the default implementation of Codable would have serialized MyModelWithAdditionalProperties like this:

{
  "additionalProperties": {
    "myInt1": 1,
    "myInt2": 2,
    "myInt3": 3
  }
}

The default implementation would put the additionalProperties in its own dictionary (which would be incorrect), as opposed to the desired serialization of:

{
  "myInt1": 1,
  "myInt2": 2,
  "myInt3": 3
}

So therefore, the only way to support this was to do our own implementation of the Codable protocol. The Codable protocol is actually two protocols: Encodable and Decodable.

So therefore, this change generates implementations of Encodable and Decodable for each generated model class. So the new generated classes look like:

class MyModel: Codable {
   var propInt: Int
   var propString: String

   // Encodable protocol methods

   public func encode(to encoder: Encoder) throws {

        var container = encoder.container(keyedBy: String.self)

        try container.encode(propInt, forKey: "propInt")
        try container.encode(propString, forKey: "propString")
    }

    // Decodable protocol methods

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: String.self)

        propInt = try container.decode(Int.self, forKey: "propInt")
        propString = try container.decode(String.self, forKey: "propString")
    }

}

class MyOtherModel: Codable {
   var propModel: MyModel

   // Encodable protocol methods

   public func encode(to encoder: Encoder) throws {

        var container = encoder.container(keyedBy: String.self)

        try container.encode(propModel, forKey: "propModel")
    }

    // Decodable protocol methods

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: String.self)

        propModel = try container.decode(MyModel.self, forKey: "propModel")
    }

}

* Add support for reserved-words-mappings to cpprest (swagger-api#6501)

* Also handles automatic escaping for reserved words, i.e.
  by default, no need to provide a mapping.
Fix swagger-api#6498

* [haskell-http-client] use katip logger, default strict (swagger-api#6478)

* change strictFields cli option default to True;

* use katip logging; add cli-option for monad-logger

* fix date parsing

* remove package.yaml

* [Python] Add configuration.{connection_pool_maxsize, assert_hostname} (swagger-api#6508)

* Backport kubernetes client features:

- assert_hostname
- connection_pool_maxsize
- cleanups

* Update petstore sample

* [QT5][CPP] Fixing issue with maps in models (swagger-api#6479)

* [QT5][CPP] Fixing issue with maps in models

- Adjusted init function to init map correctly
- Adjusted cleanup function to cleanup maps correctly

* Fixed formatting for samples

* Eliminate all Java compilation warnings for swift4 codegen module (swagger-api#6467)

* [6313] Add imports to perl objects. (swagger-api#6500)

* update perl petstore sample

* [PHP] Fix swagger-api#6474: Bug with 'format: date' when using --model-name-prefix (swagger-api#6510)

* Add test case which repeats the issue swagger-api#6474

* Add "date" to type mapping

* Update samples

./bin/php-petstore.sh
./bin/security/php-petstore.sh

* [Java] Added Play! WS filters support for retrofit2 client  (swagger-api#6499)

* added play! ws filters support

* samples updated

* Fix abcsum with abcsun

* various readme update

* add https://www.elastic.co/ to list of co using sw

* Fixing conversion when it's an item of a collection + add missing isUuid in objects (swagger-api#6473)

* Add Jenkins World 2017 talk. (swagger-api#6542)

* update elasticsearch to elastic

* produce correct enum for jaxrs resteasy eap (swagger-api#6489)

* Add link to Gradle Swagger Generator Plugin (swagger-api#6481)

* Zend Expressive fix and upgrade to version 2 (swagger-api#6461)

* upgraded zend-expressive from version 1 to 2

* Changed error handler for compatibility with Zend Expressive 2

* generated newest sample files for Petstore ze-ph

* removed ErrorMiddleware because it is never been used anymore. Regenerated samples

* removed ErrorMiddleware Template from Codegen

* remove ErrorMiddleware from petstore sample

* Fixed some code styles

* regenerated ze-ph samples with corrected code styles

* added new line at the end of the file

* Propsed fix for the ApiClient runtime crash (swagger-api#6523)

* update cpprest petstore samples

* [TypeScript][Angular] Better support for "Accept", "Content-Type" (swagger-api#6454)

* add consumes and produces as corresponding headers if present

* add check for empty array
fix copy/paste error

* fix styling

* add isJsonMime
filter produces- and consumes-Arrays for json-mime items

* update ts angular v2, v4 petstore samples

* [Typescript-jQuery] Fix for issue swagger-api#6505 (swagger-api#6541)

* Fix that prevented the default version to generate the model files

* Add generated samples

* update ts jquery petstore samples

* [typescript-angular] apply encodeURIComponent to path-parameter (swagger-api#6525)

* swagger-api#6524: [typescript-angular] apply encodeURIComponent to path-parameter

* swagger-api#6524: [typescript-angular2] update samples

* swagger-api#6524: [typescript-angularjs] update samples

* [PHP] Improve Model template (swagger-api#6460)

* Update samples

./bin/php-petstore.sh

* Remove unnecessary implements entry

ModelInterface, ArrayAccess are already implemented in parent

* Remove field `container` which is already defined in parent

* Change snake case to lower camel case

- invalid_properties
- allowed_values

* Improve doc commenct style

* Improve description length

* Improve length

* Doc comment short description must start with a capital letter

* Add a line between @param and @return

* Delete an additinal blank line at end of doc comment

* Udpate petstore-security-test

* [Java][RESTEasy] fix resteasy dependency issue in pom.xml (swagger-api#6556)

* fix resteasy dependency issue

* add java resteasy petstore to circleci test

* fix swagger-api#6353 (swagger-api#6514)

* [PHP] Improve Api template (swagger-api#6507)

* Improve spacing in doc comment

* Improve grouping of parameter tags

* Improve line length

* Fix undefined variable $_tempBody

* Improve indent

* [Scala] Decommission "async-scala" generator (swagger-api#6552)

* remove async-scala generator

* remove async-scala related scripts

* add ackintosh to php tech committee

* use parameter name as description if not defined (swagger-api#6557)

* add scala test, rearrange test order

* Bugfix: Handle all different types of security (swagger-api#6528)

The only special handling was for security definition type `apiKey`
in `query`. All the other security configurations should result in the
same generated code.
Moves the handling of the special query parameters outside of the
`parameters without specific cardinality` section.
To cover the scenario where `elif` was being used, simply leverage the
builtin `continue` statement to stop processing the specific query
parameter and continue to the next available query parameter, if any.

Manually test with multiple different combinations.

Resolves: swagger-api#6526

* [Bash] Add test setting for Bash client (swagger-api#6558)

* add pom.xml and travis.yml for bash

* create travis.yml.bak, test .travis.yml.bash

* restore travis.yml

* Add class prefix to tag with numbers (swagger-api#6561)

* add class prefix to tag with numbers, update java to default tag name

* update codegen test

* add encodeURIComponent to encode path parameters (swagger-api#6551)

* add link to netflix blog

* add new item to copy technical committee in PR

* revise wording for PR template

* [Scala] Add support for PATCH via X-HTTP-Method-Override (swagger-api#6539)

* Added support for http PATCH to the scala client using X-HTTP-Method-Override header

* Update Petstore sample

* [Java] Play! framework + retrofit2 client exception converter, bug fixes (swagger-api#6543)

* added exception converter

* underscore removal fix

* samples updated

* added test

* test whitespace

* [python] Add default Configuration (swagger-api#6554)

* Add default configuration

* Fix assert_hostname bug in rest.py

* Update petstore sample

* add "npm run build" to ts angular

* Bugfix: Resolve lint errors for generated client (swagger-api#6563)

Updates the bash client template to allow the generated client code
to be free of lint errors.

Resolves: swagger-api#6562

* Fix some bugs for the R client (swagger-api#6535)

* * Fix bugs in api.mustache, model.mustache, mostly bracket errors or small typos
* Added section about installation in README.mustace
TODO: fix tests in testthat
TODO: fix bug in description.mustace regarding package name

* Updates to sample for R client caused by running ./bin/r-petstore.sh (or .\bin\windows\r-petstore.bat)

* Add R specific files to .gitignore

* [R] add additional files generated by the petstore sample. (see swagger-api#6520)

* add SAP blog post by Radu Simen

* add links to https://shinesolutions.com/

* update swift link, add kotlin, powershell

* [Elixir] Add Elixir Petstore sample to Shippable CI (swagger-api#6575)

* add elixir petstore to shippable ci

* use oracle sdk

* [Elixir] Improve Elixir client (swagger-api#6550)

* Fix dependencies and generate model classes

* Better elixir client generation.

Responses are parsed and serialized by Poison into the model structs.
Use shared helper functions to generate the request.
Extract client connection configuration from api calls.

Elixir client can sanitize the operationId

Correctly output the model variables. Fix typos

Fix path replacement when there are multiple replacements

Cannot separate globally shared parameters from operations

Error handling for the tesla response

update templates

Can generate clients that compile

Can make requests - parse optional params, build query

Add oauth to connection. Fix connection directory

Add basic auth helper for creating a connection

Fix map types. Fix guard clauses for creaing connections

Add licenceInfo template. Parse config for moduleName via standard invokerPackage option

Can provide and inject a license header into all source files

fix location of connection.ex

Move shared code into reusable modules

Elixir filenames should be underscored

Fix visibility of helper functions

Parse the packageName from config options

Handle date and datetime fields with DateTime.from_iso8601

Fix indentation

Update documentation, add typespecs

Generate a standard elixir .gitignore

typespec is calculated recursively in java

Use the JSON middleware and using Poison.Decoder.decode on already parsed structs

move decoded struct into java

Fix handling of non-json responses

Switch basic auth to use the provided Tesla.Middleware.BasicAuth

Update README template to include the appDescription

Update sample elixir client

remove junk client models that don't belong with petstore

Only implement Poison.Decoder protocol if needed

Update samples with skipped Poison.Deocder impl

* Handle multipart file uploads

Handle building form params in the body

Files are handled as strings for input

* Requests with no defined return type will return the Tesla.Env response

* Run the bin/elixir-petstore.sh

* Use valid JS RegEx (swagger-api#6584)

* fix elixir model naming

* Feature: Adds doc generation (swagger-api#6570)

Reference swagger-api#2359

* fix JS help text

* Bugfix: Path replacement regex not working (swagger-api#6580)

A previous change to make the regex a variable to allow proper linting
resulted in the regexp not having access to the value associated with
the variable and the path variable not being replaced.

Moves the regexp variable inside the for loop to allow the value to be
used and the path variable to be replaced with the provided value.

* Swift3: non dictionary body type (swagger-api#6531)

* Adding support for non dictionary body types.

* Adding test for rest of the swift3 types

* Cleaning up implementation of makeRequest and adding better error handling.

* Adding ClientError for error produced before request is sent.

* Changing how encoding of body data is handled.

* Cleaning up code that was modified.

* add jvelilla to eiffel tech committee

* add kenjones-cisco to bash tech comm

* [CPPREST] Fixed multipart files upload implementation (swagger-api#6518)

* [Scala] format the Scala code style templete (swagger-api#6532)

* The templete of scala code style refactor

* more reformat

* more reformat

* generate petstore client

* update tech comm, fix broken link to 2.0.17

* add cbornet to python tech committee

* Add optional support for HttpClient (swagger-api#6295)

* fix compilation error in eclipse

by updating package declarations in moved files
(eclipse validates that package and folder names match)

* permit specifying the full angular version

simplifying the templates by moving trivial case splits to the model

* remove dead code

this method is never called ...

* support HttpClient in addition to Http, clean up generated code

Fixes swagger-api#6080

* added new sample, and regenerated existing samples

* updated samples

this time with the freshly build generator ...

* improve formatting

* updated samples

* fix compilation error in generated code

the overload for blobs does not have a type parameter

* added the first test for the utils package

* fix extra trainling commas in function argument lists

* regenerated samples

* fix comma in method without parameters

* use String() to convert num, update TS angular samples

* add haskell to shippable ci (swagger-api#6600)

* [haskell-http-client] fixes for fake-endpoints (swagger-api#6597)

* fix compile errors / sanitization for petstore-with-fake-endpoints-models-for-testing.yaml
* correct mimetype logic
* add makefile

* Pre-calculate type aliases before processing models (swagger-api#6559)

A type alias in this context is where a model is simply another name for a
primitive type, such as `MyString` in the following model definitions:

    MyList:
      type: array
      items:
        $ref: '#/definitions/MyString'
    MyString:
      type: string

It is valid to use a type alias as a property in another object or array model,
even if the object/array is defined before the alias is, as in the example
above. However, the current alias logic only looks "back" in list of previously
defined models, meaning that `MyList` would not know that `MyString` is an
alias. This change fixes the incorrect behavior by pre-calculating the list of
aliases before any models are processed. It also changes the test endpoint to
verify the correct behavior even when an object is defined before an alias it
uses.

* [NancyFx] provide option to override package context (swagger-api#6593)

* Retrofit2: Return ResponseBody if response if file.

Until now
--------------------
If a swagger endpoint returned a file (e.g. an image), then the Retrofit2
template has choosen the return type java.io.File. However, retrofit cannot
deal with this and throws a com.google.gson.stream.MalformedJsonException.

New:
-------------------
If a swagger endpoint returns a file, then the corresponding Retrofit2 endpoint
will return a okhttp3.ResponseBody which can be used to retrieve the file.

* Add the option packageContext for nancyFx which allows a better adjustment of the namespace.

* run nancyfx-petstore-server.bat

* Fix for self-referential imports in typescript-angular client (swagger-api#6450)

* cache stack in shippable ci

* cache elixir deps

* add links to blog posts in techium.jp

* add partial header to haskell http client (swagger-api#6606)

* [nancyfx] fix interface prefix (swagger-api#6595)

* Retrofit2: Return ResponseBody if response if file.

Until now
--------------------
If a swagger endpoint returned a file (e.g. an image), then the Retrofit2
template has choosen the return type java.io.File. However, retrofit cannot
deal with this and throws a com.google.gson.stream.MalformedJsonException.

New:
-------------------
If a swagger endpoint returns a file, then the corresponding Retrofit2 endpoint
will return a okhttp3.ResponseBody which can be used to retrieve the file.

* fix Interface Prefix

* CsharpDotNet2Client - Use clientPackage in additionalProperties (swagger-api#6581)

* CsharpDotNet2Client - Use clientPackage in additionalProperties if provided

* Give execution rights for csharp-dotnet2-petstore.sh

* Fix generation of C#.net2 apiPackage, modelPackage, clientPackage

* Fix modelPackage property missing when generating models

* Initialize clientPackage in constructor

* add link to ntt presentation

* rename silex-PHP to php-silex (swagger-api#6612)

* rename CsharpDotNet2 to csharp-dotnet2 (swagger-api#6611)

* add new language "ada"

* [Ada] Adding Ada support for client code generator (swagger-api#6602)

* Ada language support (generic generator)

Implement the AbstractAdaCodegen class with the Ada keywords and global
behavior for Ada language

* Ada language support (main generator)

Implement the AdaCodegen class for the Ada client and server code generator
Initial implementation based on a mix from CppRestClientCodegen, NodeJSServerCodegen

* Ada language support: register the AdaCodegen generator class

* Ada language license template

* Ada language model templates (spec and body)

* Ada language client spec and body templates

* Ada language server spec and body templates

* Fix escaping Ada keywords for parameter name

* Generate GNAT project and update type mappings
- Use 'p_' as escape prefix for parameter names because identifiers are not allowed to start with '_'
- Add GNAT project file generation
- Update the type mappings to use the Swagger package types

* Fix generation of operations with no parameters

* Fix instantiation of Ada.Containers.Vectors package in generated model files

* New template for the GNAT project file generation

* Fix datatype generation for Ada language
- Override the getTypeDeclaration function to specify the datatype
- Fix definition of language predefined types

* Add a Serialize procedure declaration for the Ada model generation

* Add a Serialize procedure for the Ada template model generation

* Fix operation name and parameter name for Ada
- Declare and implement toAdaIdentifier function to verify and turn some identifier
  to Ada identifier following Ada style
- Override toOperationId and use toAdaIdentifier for generation of operation name
- Update toParamName to use toAdaIdentifier

* Media type support for Ada code generator
- Implement postProcessMediaTypes function to add a 'adaMediaType' member
  to each media type and map it to some Ada enumeration
- Post process the 'produces' and 'consumes' media type of an operation

* Use x-has-notes extension to avoid emitting notes when they are empty

* First generation for Ada client operation body

* Add a x-has-uniq-produces and x-has-uniq-consumes to media types
to indicate that the list contains only one item, this is necessary
for Ada generator for generation of arrays with one item only

* Add a postProcessParameter for Ada code generator to emit a x-is-model-type attribute

* Update Ada client body template for the serialization of data

* Fix postProcessParameter in Ada code generator to take into account file parameters

* Update the Ada client body to support form parameters

* Fix type name used for mapped types in the Ada generator

* Declare a Deserialize procedure for the Ada generated model

* Override the fromOperation for Ada client code generator
- Emit a x-codegen-response extension with the response description type
- Emit a x-id-model-type extension for each type property

* Update the Ada client package spec template to declare the result type

* Add support to extract response and return result in Ada client code

* Fix Ada postProcessModels to handle container properties and emit a correct x-is-model-type attribute

* Add support for Deserialize procedure in the Ada model generator

* Fix indentation of generated Ada client body package

* Add projectName option to configure the GNAT project name

* Update the GNAT project name for the Ada code generator

* Cleanup implementation and remove unused code

* Cleanup implementation and remove unused code

* Fix javadoc errors

* Use 'ada' for the language name to follow swagger-codegen convention
Add (beta) to the help description
Fix a NPE that occurs with incomplete yaml descriptions

* Typo error fix (swagger-api#6620)

* [R] Added ApiClient and fixed other issues (swagger-api#6571)

* Added namespace mustache to be generated

* Fixed syntax issues with package generation

* Added Response and Element mustache templates

* Added ApiClient

* Fix: Only required parameters needed for api operations

* Added documentation generated code

* Regenerated petstore samples

* Fixed url paths for operations

* Fixed based on comments in issues swagger-api#6520

* Regenerated petstore samples

* add link to MS machine learning server

* Note precisely which clients and servers can be used with Haskell. (swagger-api#6625)

* [Elixir] Improve Elixir Client about primitive type spec (swagger-api#6623)

Fix following dialyzer warnings in the sample:

```
:0: Unknown type 'Elixir.Float':t/0
:0: Unknown type 'Elixir.Integer':t/0
```

* fix inconsistent java naming (swagger-api#6624)

* [PHP] Fix: Type object not handled properly in setParameterExampleValue (swagger-api#6619)

* Add test which reproduce the warning swagger-api#5338

swagger-api#5338 (comment)
`[main] WARN io.swagger.codegen.languages.PhpClientCodegen - Type object not handled properly in setParameterExampleValue`

* Fix Type object not handled properly in setParameterExampleValue

* Update samples

- /bin/php-petstore.sh
- /bin/security/php-petstore.sh

* [GO CLIENT] Fix issue with generating code for API key  (swagger-api#6630)

* [GO CLIENT] Fix Go security query parameter generation by using correct string literal and using the Add method.

* Add generated files.

* [objc] Let the developer specify the timezone to be used for date serialisation (swagger-api#6628)

* [objc] Update deployment target to 8.0

Updates the test project deployment target to 8.0, as that's the lowest
supported by the latest XCode.

* [objc] Update petstore tests based on current master

Makes sure the tests are based on the latest version of master.

* [objc] Allow specifying the serialization timezone

Now it's possible to specify the timezone used for serializing dates

* [haskell-http-client] add support for auth methods (swagger-api#6622)

* add support for auth methods

* use newtypes for required params

* fix duplicate operationId issues

* prevent aliasing of vendorextension references in fromOperation

* add --fast to stack ci build

* [Scala] Properly handle csv collectionFormat (swagger-api#6540)

* Add support for lists of path parameters (eg instances), and default params for optional case classes

* Update Petstore sample

* Revert defaulting of case class fields to None

* Update Petstore sample

* represent swagger enums as union of literal types (swagger-api#6233)

* represent swagger enums as union of literal types

enabling their easy use in angular templates, structural subtyping
among enums (in particular, different instances of the same enum
are now mutually assignable), improving type safety by preventing
incorrect widening, and permitting numeric enum values
(albeit without descriptive names)

Fixes swagger-api#6206, swagger-api#5146, swagger-api#3500

* update samples

* restore blank lines at end of file

* fix typo

* add ada style guide

* [Ada] Adding Ada client samples (swagger-api#6634)

* Add Ada client petstore samples
- Add script to generate Ada client support with swagger-codegen
- Add files to build the Ada sample
- Add main program to use the generated client samples API
  and connect to the server to perform some operations

* Add some description for the samples

* Update the documentation to explain how to build, how to use the generated Ada client code

* Issue 5431 Support jaxrs client api interfaces (swagger-api#6412)

* Adds the ability to create code for an interface-based jaxrs client.

* Adds shell script and sample files for jaxrs-spec-interface

* rebase into adds shell

* Fixes bug in creation of Produces/Consumes in method annotation. Allows for instance "application/json; charset=utf-8"

* Fixes generated pom.xml

* Generate pom.xml by default

* Prettier output from api.mustache

* Fixes bug in mediatype, allowing charset-specification in swagger.yaml.

* Merges generation of interface-based jaxrs client/api into jaxrs-spec.

* Moves jaxrs-spec server interface to match location of jaxrs-spec server

* Makes Generated-annotation in genereated classes slightly prettier.

* [JavaScript] Fix licenseNames (swagger-api#6605)

* [JavaScript] Fix licenseName in package.mustache

* Fix invalid SPDX license expression in resources/2_0

* Update JavaScript samples

* remove unused JS files

* swagger-api#3904 Inheritance support java client retrofit gson (swagger-api#4729)

* merge with master

* remove zoo specific artifact names

* fix duplicate doublequote

* swagger-api#3904 add samples for retrofit2

* swagger-api#3904 clean json field retrieval

* swagger-api#3904 allow non-abstract parent class

* Fix class path for DeferredResult (swagger-api#6452)

* fix NPE reported in swagger-api#6519 (swagger-api#6635)

* fix underscore to handle spaces (swagger-api#6637)

* add link to ada's article

* use japanese name of taxpon

* Fix for regression in issue: swagger-api#6472 (swagger-api#6480)

* add java version to pom in resteasy eap java8

* update java server samples

* Updated feign library dependency to io.github.openfeign (swagger-api#6652)

Changed groupId from “com.netflix.feign” to “io.github.openfeign” from
gradle and sbt mustache templates.

* Add Serializable import to JaxRS-spec models if serializableModel is set (swagger-api#6651)

* Swift4: Fix inline enum issue (swagger-api#6640)

* Add addiitional files from upstream

* Remove mis-added files

* Fix compilation issue with Swift4 inline enums.

This change fixes this issue: swagger-api#6607

The problem was that I was using "datatype" instead of "datatypeWithEnum" in the model.mustache file.

When you have a the following model property:

"myInlineStringEnum": {
  "type": "string",
  "enum": [
    "inlineStringEnumValue1",
    "inlineStringEnumValue2",
    "inlineStringEnumValue3"
  ]
}

Then we were generating:

public enum MyInlineStringEnum: String, Codable {
  case inlinestringenumvalue1 = "inlineStringEnumValue1"
  case inlinestringenumvalue2 = "inlineStringEnumValue2"
  case inlinestringenumvalue3 = "inlineStringEnumValue3"
}

However, when we decode this, we were using type of the enum ("datatype") rather than the enum type itself ("datatypeWithEnum"). So we were generating:

myInlineStringEnum = try container.decodeIfPresent(String.self, forKey: "myInlineStringEnum")

rather than:

myInlineStringEnum = try container.decodeIfPresent(MyInlineStringEnum.self, forKey: "myInlineStringEnum")

* [angular-typescript] fix using form data (swagger-api#6574)

* swagger-api#6457: fix sending form params

* swagger-api#6457: fix sending form params using files

* swagger-api#6457: fix sending form params with files for angular 4.3

* swagger-api#6457: generate samples

* swagger-api#6457: [typescript-angular] fix form data submission in IE/Edge

* re-apply [typescript-angular] add customized encoder to use '+' char in query parameter swagger-api#6306 (swagger-api#6334)

* adapt for HttpClient: [typescript-angular] add customized encoder to use '+' char in query parameter swagger-api#6306 (swagger-api#6334)

* generate samples

* swagger-api#6457: fix url parameter encoder imports for angular <4.3

* swagger-api#6457: generate samples

* [haskell-http-client] bug fixes; path & newtype generation issues (swagger-api#6638)

* fix path generation/param-substitution issues

* fix newtype de-duplication issues

* refactoring only

* correct version in comments

* prevent duplicate MimeTypes

* sort parameter newtypes

* comment out swift test due to build image changes

* revise wordings for powershell generator

* Update README.md (swagger-api#6656)

Add my slide to README.md

* Updated api client, Required parameters {{#required}} .. {{/required}}, are mapped to Eiffel (swagger-api#6653)

Void Safety Rules, optional parameters are translated to detachable TYPE.
Validation Rules are mapped to preconditions, at the moment maximun and minimun
validation has been added.
Improved API_CLIENT.parameter_to_tuple feature to accept a LIST [ANY] instead of LIST [STRING_32].
Improved model template to generate the model output.

* [kotlin] Fix syntax errors on localVariableHeader in api.mustache (swagger-api#6660)

* Swift4: Add additional initializer for initializing model object with properties. (swagger-api#6642)

* Add addiitional files from upstream

* Remove mis-added files

* Add additional swift4 initializer for initializing model object with properties.

This change fixes this issue: swagger-api#6641

It adds an additional initializer which allows model objects to be initialized using the properties. For exxample, if we had this model:

    "ErrorInfo": {
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "format": "int32"
        },
        "message": {
          "type": "string"
        },
        "details": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "description": "Example Error object"
    },

This we generate an initializer for this model object like this:

    public init(code: Int?, message: String?, details: [String]?) {
        self.code = code
        self.message = message
        self.details = details
    }

* Add hasVars checks around initializers and re-run all scripts to re-generate

* [PHP][Symfony] Generate valid PHP code (swagger-api#6578)

Fixes swagger-api#5985

We were experiencing syntax issues when generating the Petstore example. See some of the examples below:

StoreApiInterface.php
namespace Swagger\Server\Api;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Swagger\Server\Model\Order;
**use maparray&lt;string,int&gt;;**
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

UserApiInterface.php
public function createUsersWithArrayInput(**User[]** $body);
public function createUsersWithListInput(User[] $body);
As far as I know, it is not possible to use array of objects in this way.

PetApiInterface.php
namespace Swagger\Server\Api;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Swagger\Server\Model\Pet;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Swagger\Server\Model\ApiResponse;
**use string[];**
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

public function findPetsByStatus(string[] $status);
public function findPetsByTags(string[] $tags);

* add Edubits to swift tech comm

* add back petstore test (swagger-api#6663)

* add jaz-ah to swift, android tech committee

* golang: trailing whitespace fails gofmt (swagger-api#6669)

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>

* update go petstore samples

* - Removed unnecessary line in in Restbed Codegen Constructor (swagger-api#6675)

- Updated samples

* Included Open Systems International in the list of companies using Swagger Codegen (swagger-api#6692)

* Add operationId as nickname to @ApiOperation (swagger-api#6688)

* Add operationId as nickname to @ApiOperation

* Refresh samples after adding nicknames to @ApiOperation

* Swagger eiffel:fix (swagger-api#6674)

* Updated api client, Required parameters {{#required}} .. {{/required}}, are mapped to Eiffel
Void Safety Rules, optional parameters are translated to detachable TYPE.
Validation Rules are mapped to preconditions, at the moment maximun and minimun
validation has been added.
Improved API_CLIENT.parameter_to_tuple feature to accept a LIST [ANY] instead of LIST [STRING_32].
Improved model template to generate the model output.

* Updated API_CLIENT.parameter_to_string feature, missing STRING representation.

* Updating sample using the latest modifications.

* [kotlin] Fix causing NoClassDefFoundError at runtime on Android device (swagger-api#6661)

* Fix causing NoClassDefFoundError at runtime on Android device.

* Add samples modified by bin/kotlin-client-petstore.sh

* Add enum support for flask (swagger-api#6684)

* update python flask petstore samples

* There was no validation when a required field was null, creating crash and null pointer exception further down the line in the business code. Now, it throws a InvalidArgumentException. (swagger-api#6673)

* Added support for enums in Dart. (swagger-api#6516)

* Added support for enums in Dart.

* Pick non-private names for enum values.

The _ prefix denotes a private member in Dart, so avoid generating enum values starting with this character.

* Properly encode enum values into query paramters.

* Various cleanups.

* Add support for x-enum-values extension.
Use class instead of enum for better ergonomy.
Better generated enum names.

* Fixed test.

* Support enum descriptions.

* Adding a new Scala client codegen (swagger-api#6572)

* Adding a Scalaz codegen client

* Fixing imports and removing commented code

* Adding the bash file and updating the Pet store samples for Scalaz.

* Finalizing Scalaz generation so that it works for the Petstore.yaml

* Removing some unnecessary files and comments

* Removing some files that were accidentally generated for the wrong Scala

* add tbrown1979 as template creator for scalaz

* add scalaz to cirleci

* add beta to scalaz generator

* Add http://www.nttdata.com (swagger-api#6713)

* [PHP] Fix swagger-api#5338: InvalidArgumentException (swagger-api#6685)

* Add endpoint definition which reproduces swagger-api#5338 bug

* Update samples

* Add test case which reproduces swagger-api#5338 bug

* Fix "InvalidArgumentException: Invalid resource type: object"

* Update samples

- ./bin/php-petstore.sh
- ./bin/security/php-petstore.sh

* [Elixir Client]Improve elixir client typings (swagger-api#6665)

* [Elixir Client] Improve primitive typings

* [Elixir Client] Add type to models

Fix following dialyzer warnings in the sample:

```
:0: Unknown type 'Elixir.SwaggerPetstore.Model.ApiResponse':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.Client':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.Order':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.OuterBoolean':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.OuterComposite':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.OuterNumber':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.OuterString':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.Pet':t/0
:0: Unknown type 'Elixir.SwaggerPetstore.Model.User':t/0
```

* revise go header, minor formatting fix (swagger-api#6695)

* JAXRS-SPEC: fix container return type (swagger-api#6659)

* JAXRS-SPEC: fix container return type

* Run
./bin/jaxrs-spec-petstore-server.sh
./bin/jaxrs-spec-petstore-server-interface.sh

* add jaxrs-spec-interface to circle ci

* [C++] Sanitize operation ids. (swagger-api#6664)

* [C++] Sanitize operation ids.

* [C++] Handle reserved words in `toOperationId`.

* [C++] Re-order reserved words alphabetically.

* [C++] Add missing reserved words.

* ContentType selection fix for csharp. (swagger-api#6633)

* ContentType selection fix for csharp.
Updated to reflect java implementation. Previously any request body of type string was having the content type overridden to 'application/json'.  This prevented custom json ContentTypes

* updated the petshop codegen for C#

* Fixed content type selection test for csharp

* Replaced tabs with 4 spaces

* Removed trailing space / string comparison

* Prefix local vars to prevent conflict with params (swagger-api#6717)

* Prefix local vars to prevent conflict with params

Fixes swagger-api#6698

* Update test snapshots

* update all petstore security samples

* add resteasy-all shell script

* new files genreated by security shell scripts

* [haskell-http-client] handle Alias models + refactoring. (swagger-api#6712)

* handle Alias models with newtypes

* add inlineConsumesContentTypes cli option

* generate swagger.yaml instead of swagger.json

* check for/validate unhandled authMethods

* refactoring

* Fix spring api operation annotation (swagger-api#6700)

* * Fix apioperation annotation using generics in class reference for spring server generation

* * Regenerate classes for new spring template

* [Java][JAX-RS-CXF] Add JsonProperty to POJO (swagger-api#6710)

* Included Open Systems International in the list of companies using Swagger Codegen

* Force Jackson to use the real names of the properties of the Data type defined in the YAML

* Update of the Petstore CXF server sample

* Update of the Petstore CXF client sample

* Update of the Petstore CXF server annotated base path sample

* Update of the Petstore CXF server non spring application sample

* Changed {{name}} for {{baseName}} following the correction posted by @wing328

* Update of the Petstore CXF server sample

* [New Generator] Rust API client/server generator (swagger-api#6613)

* Rust API client/server generator

* `Future::boxed()` has been deprecated - replace with `Box::new(...)`

* rebasing to rust

* MMMLS211 use empty vec over none

* MMMLS211 rebuild after merge from rust

* MMMLS211 YAML array examples not wrapped in Some()

* MMMLS211 Array parameters bad mustache fix

* MMMLS211 don't parse map containers

* MMMLS211 Tidy container types

* MMMLS-211 rebuild example

* MMMLS211 mvn rebuild

* Percent-decode parameters contained in the path

* Produce warnings when unknown fields are present

We still accept unknown fields and discard them. However, to improve
diagnosability, we now write a warning log and return a `Warning`
header.

Note that this is server-only

* Markup

* MMMLS211: Make optional arrays Options again

* 211 markups

* Temporary attempt at tweaking Cow ownership tweak while merging changes from rust branch

* Remove to_string call while parsing path parameters, which requires definining a temporary var in a block because rust can't tell where a Cow reference gets dropped

* Fix rustfmt to the correct version

* Fix rustfmt to the correct version

* Add more response information to ApiError in client

* Re-add missing brace

* Code review markups

* Allow converting out of wrapper types

* Store arrays in new-types too

* Use a new hyper_client every request

* Add vec-like traits to array types

* Xml support - new branch

* Moved conversion from serde_xml_rs::Error to ApiError from swagger-rs to client code until upstream PR is accepted

* MMSUB-172 Don't set Content-Type when there's no body.

If we don't have a body we've serialized, then don't declare
any content type for the nonexistent body.

This is really important for 204 No Content responses, but it's
also morally important for all other non-bodied responses.

* MMSUB-172 Move to swagger 0.6.

* Manually implement debug for the client

* Allow `Context` to be bound to `Api`, and not passed on every function call

* Support "." in parameter names

* Support generate's "--reserved-words-mappings" option

* Support "." in parameter names

* Support generate's "--reserved-words-mappings" option

* bug fixes (swagger-api#6743)

* [Rust] rename rust2 to rust-server (swagger-api#6747)

* rename rust2 to rust-server

* update rust-server batch file to use petstore test spec

* Bugfix/6750 name clash between npm request and parameter called request (swagger-api#6753)

* rename request to $request

* update examples files

* rename $request to localVarRequest

* rename oder variables to localVar...

* revert changes to fakes yaml (swagger-api#6758)

* revert changes to fakes yaml

the yaml currently includes invalid definitions that do not exist: ('#/definitions/xmlObject').
revert to known good yaml state.

* update template creators

* [JavaScript] Handle custom request.agent (swagger-api#6737)

* Handle custom request.agent

* better semantic

* update JS petstore samples

* update ruby petstore samples

* Fixed link to open issues (correct label is 'help wanted') (swagger-api#6779)

* remove unused files from Ruby petstore client

* [Java][JAXRS-CXF] Improve API documentation in the CXF Server stub and Client generation (swagger-api#6708)

* Inclusion of API documentation in CXF Server stub generation

* Inclusion of API documentation in CXF client generation

* Update of the Petstore CXF server sample

* Update of the Petstore CXF client sample

* Update of the Petstore CXF server annotated base path sample

* Update of the Petstore CXF server non spring application sample

* Changed {{{appDescription}}} to {{appDescription}} to use the HTML-escaped value in handling special characters like <, > in the description following the correction made by @wing328

* Update of the Petstore CXF samples

* Add Metaswitch to list of companies (swagger-api#6773)

* Update README.md (swagger-api#6783)

Add my company to `Companies/Projects using Swagger Codegen`

* Fixed Python client docstrings (swagger-api#6780)

* Updated api_client and configuration docstrings

ApiClient: Removed host param, added configuration and cookie param

Configuration: Docstrings are only read from the @Property decorated
function, not the setter, moved the more descriptive docstrings from the
setters to property functions

* Ran bin/python-petstore.sh

* [TypeScript-Angular] Path URI Encoding Update (swagger-api#6769)

* Replaced the method for updating path to prep for URL encoding.
The new method will switch TypeScript-Angular variables from snake_case to camelCase in the URL generation.

Imported StringBuffer, Matcher, and Pattern, since the new solution needs them.
Some extra whitespace on blank lines was removed.

* Since these were not up to date with the current master, I ran them and am commiting them here.
This way, the changes are shown here instead of after future commits.

* Simplified the code for the path conversion A LOT.
New version is much simpler to follow, and very efficient - only one iteration through the length of the string.
Removed regex Matcher and Pattern classes, since they weren't needed anymore.

*  [PHP][Symfony] Enhancements (swagger-api#6615)

* Removed commented code

* Input validation is now supported as strict JSON validation

* [PHP][Symfony] Improve the implementation
Closes swagger-api#6614

* Generated code is tested to assure it compiles and updated README to dynamically load dependencies via composer

* Updated shell script because shippable tests were failing

* Allow using help command with run-in-docker.sh (swagger-api#6706)

* Change version

* Add baikal repositories
@kenisteward
Copy link
Contributor

@bobvanderlinden isn't the purpose of a enum so you don't mistype or misasign values?

I have never come into a case where I've had an enum and wanted to assign the value myself instead of just using Enum.Value

Especially with intellisense it's easier to do enum.value than to type in 'somevalue' and have it tell you that it's wrong.

I hate that I missed this whole conversation. In the case of enums, I think it is much better practice to just do Enum.Value

Please let me know why you would like to do myenum:Enum = 'EnumVal' instead.

I would definitely be more inclined to accept this change if you could still do Enum.Value.

@sebastianhaas Do you have any opinion on this?

@kenisteward
Copy link
Contributor

I've found a better solution that i'll be adding soon that will allow for both and backwards comparability to 1.8

@kenisteward
Copy link
Contributor

kenisteward commented Oct 24, 2017

@bedag-moo @bobvanderlinden @topce @Vrolijkx @TiFu @taxpon
I made improvements on this in #6788 Now we have full backward compatibility with those who use enums in the MS prescribed way as well as those who want to set it via the value itself (which you can technically do with regular enums. But this makes it to where we should be able to use any string type in the future as well.

type MyStringEnum = "member1" | "member2";

const MyStringEnum = {
    Member1: "member1" as MyStringEnum,
    Member2: "member2" as MyStringEnum
};

// implicit typing example
let myVariable = MyStringEnum.Member1; // ok
myVariable = "member2";                // ok
myVariable = "some other value";       // error, desired

// explict typing example
let myExplicitlyTypedVariable: MyStringEnum;
myExplicitlyTypedVariable = MyStringEnum.Member1; // ok
myExplicitlyTypedVariable = "member2";            // ok
myExplicitlyTypedVariable = "some other value";   // error, desired

this allows us to not have to check for typescript as everyone by now should be at least past 1.8. This gives the best of both worlds.

Since this is relatively harmless and requires less programming that determining what typescript they have (we can force a peer dependency of 1.8 or higher) I think i prefer this over true string enums even though I use true string enums in app development. Here compatibility would be better expecially because no one should change this code anyway.

Credit: https://stackoverflow.com/a/35257367 David Sherret.

TS Playground

@bobvanderlinden
Copy link

I'm not sure that's actually the desired behavior. From typescripts perspective that enum now has 4 possible values instead of 2. A switch will always need a default: even though this will never be used at runtime.

I still think this is a defect of typescript itself, but as mentioned in microsoft/TypeScript#17690 it is the intended behavior.

As for swagger, it's a choice of 3 evils. I'm not sure which one is best. If backwards compatibility is imported I'd say to revert this PR. The new suggestion will mess up switch statements in existing projects.

I still like hat we can use example json structures in tests and mocks. Even though auto completion does not always work nicely, the typechecker will still inform you about typos.

It's just a preference, opinions of more people are very welcome.

@bedag-moo
Copy link
Contributor Author

Meta: Isn't it rather late to discuss this after merging the PR? I filed an issue about the proposed change back in July (#6206) and waited weeks before implementation, then I implemented it and it spents months in review, got merged, and now we start talking?

But since all interested parties are now here, let me reiterate the reasons for this change:

  1. In swagger, enums are an anonymous collection of possible values. Typescript union types are an anonymous collection of possible values. Typesscript enums are named types, and assignment compatibility is checked by name rather than the set of possible values. To preserve assignment compatibility for different uses of an enum in the swagger contract, swagger-codegen would have to reuse the typescript enum declaration. This would require a major extension of swagger-codegen, because such duplicate elimination is not currently supported by the code generation engine (as far as I know).
  2. union types offer equivalent compile time type safety to enums
  3. union types offer code completion in visual studio code (if you trigger code completion within the string literal, it will suggest possible values), but not (yet?) in IntelliJ.
  4. union types can be used as index types, but enum types can not:
    const colorOf: {[S in Issue.StatusEnum]: string} = {
      open: 'danger',
      closed: 'success',
      resolved: 'info',
      inProgress: 'warn'
    }
    
    which can be used like
    const color = colorOf[issue.status];
    
    such simple lookup tables are therefore only possible for union types.
  5. union types can be easily used in templates, i.e.
    <div [ngSwitch]="issue.state">
      <div *ngSwitchCase="'open'"> 
    
    while enum types additionally require the enum to be imported and published in a component field so we can use it in the template.

Any revision of this PR should continue to support these 5 properties (assignability, type safety, code completion, support for index types, ngSwitch). If we can additionally improve code completion, and not break backwards compatibility, I'm all ears :-)

@kenisteward : That's an interesting idea, because it preserves the above properties while emulating the previous api. (Bob, I could not reproduce your statement about 4 possible values; the playground says there is a variable and a type named MyStringEnum, but typescript seems to treat these as separate declarations?)

Thinking of switch statements however, I did find a small disadvantage of Keni's pattern, because typescript seems unable to verify exhaustiveness for non-literal switch cases:

function indirect(e: MyStringEnum) {  // "not all code paths return a value" under -noImplicitReturn
    switch (e) { 
        case MyStringEnum.Member1:
            return 1;
        case MyStringEnum.Member2:
            return 2;
    }
}

function direct(e: MyStringEnum) { // does not error under -noImplicitReturn
    switch (e) {
        case "member1":
            return 1;
        case "member2":
            return 2;
    }
}

playground link

But as switches over actual enum types are not considered exhaustive either (without a default), this merely mirrors the previous state.

Whether the improved backwards compatibility and code completion is worth the added complexity in the generator is a matter of taste; I am fine with either solution as long as my precious union types are not rolled back ;-)

@kenisteward
Copy link
Contributor

kenisteward commented Oct 24, 2017

@bedag-moo My apologizes for not fully analyzing this sooner. I only commented here to keep the conversation in an organized area when I could have just opened a new issue to append changes to this.

  1. In swagger, enums are an anonymous collection of possible values. Typescript union types are an anonymous collection of possible values.

This may be true, but when creating these clients we need to think of how people will (and want) to consume them. Generally, when a person thinks of an enum, (I think) they assume that they are going to use:

let e: Enum = Enum.Value

and not

let e: Enum = 'value'

because of this it would be important to support actual enums or at least the facade of being one

2 union types offer equivalent compile time type safety to enums

truth

  1. union types offer code completion in visual studio code (if you trigger code completion within the string literal, it will suggest possible values), but not (yet?) in IntelliJ.

OH.....MY.....GOD how have i missed this freaking feature! lol. This is great! Instantly just enabled this! However, because i'm not sure if all IDE's implement this support but I know that the ones that support TS do support enum completion that is why I say we should still support let e: Enum = Enum.Value

4 union types can be used as index types, but enum types can not

This works perfectly for me with an enum. Not sure why it isn't working for you.
TS Playground

5 union types can be easily used in templates

So enums are just objects when they are translated. Thinking of it in that light, you can't expose an object to the template unless it is a property of that component. That's just Angular specification.

But to that note you can do exactly the same thing for an enum in the template.

// somewhere else
export class SomeType {
   someValue: Enum
   constructor() {
    // sets someValue to what you want it to be
   }
}
// in some componnent
@input() templateDataValue: SomeType;

// in some component template
<div [ngSwitch]="templateDataValue.someValue">
  <div *ngSwitchCase="'open'"> 

Did you have some runtime error or other issue?

Thinking of switch statements however,

I did the same thing using the original type union and it also didn't force a default. I also didn't get any errors when I took out a whole value.

Note: I'm using 2.5.2

Edit: I didn't have returns set at all so it wasn't giving me the error. I reproduced the same thing that both you and bob said in the sense that you are required to provide a default if using noImplcitReturns

@kenisteward
Copy link
Contributor

kenisteward commented Oct 24, 2017

@bobvanderlinden This is true. If there is an issue for that why not just program it to return one of the values by default? ie

  // Enum has 3 values
  b (v: Enum) {
    switch (v) {
        case Enum.Value3
             return something();
        case Enum.Value2
            return something2();
       default:
            return something3();
    }
  }

The code is strongly typed already so you know it should be one of those values (unless someone did something nefarious like cast to any and back.

Otherwise implement the default as throwing an error cause it's a value that it shouldn't be which is best practices anyway.

@bedag-moo
Copy link
Contributor Author

1 In swagger, enums are an anonymous collection of possible values. Typescript union types are an anonymous collection of possible values.

This may be true, but when creating these clients we need to think of how people will (and want) to consume them.

Certainly, and I would not violate expectations lightly, but how else can we make different uses of the same enum assignment compatible? I think assignment compatibility is a justified expectation as well, and since it is related to correctness and type safety, it seems more important than a syntactic difference.

4 union types can be used as index types, but enum types can not

This works perfectly for me with an enum. Not sure why it isn't working for you.

Oops, I had tried with {[K: MyEnum]: string} rather than {[K in MyEnum]: string}. The latter indeed works flawlessly, though it is slightly surprising that its maps enum values rather than names. But that's good enough for me :-)

5 union types can be easily used in templates

But to that note you can do exactly the same thing for an enum in the template.

Oh, you're right. It seemed so obvious that since const e: Enum = 'open' was illegal, so would e === 'open', but apparently the compiler is more lax with comparisions and switch statements, so this works even in ahead-of-time compilation :-)

@topce
Copy link
Contributor

topce commented Oct 24, 2017

@bedag-moo I report problem (breaking compatibility} same day i spotted it
Better late than never
As I explained in previous comments I would prefer to use enums instead of strings or numbers
Use cases that you mention were not relevant for project I am working on
I am more on same page as @kenisteward
but I see your and @bobvanderlinden have different opinion and I respect that

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.

Typescript: Why not use string-literal types to represent enums of type string?
6 participants