diff --git a/.gitignore b/.gitignore
index a4ac179d18d..56cc80cae68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -232,3 +232,7 @@ samples/client/petstore/elm/index.html
# C
samples/client/petstore/c/build
samples/client/petstore/c/*.so
+
+# Ruby
+samples/openapi3/client/petstore/ruby/Gemfile.lock
+samples/openapi3/client/petstore/ruby-faraday/Gemfile.lock
diff --git a/.travis.yml b/.travis.yml
index f47f448b874..b4bd3d852f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -94,6 +94,12 @@ before_install:
# - Rely on `kerl` for [pre-compiled versions available](https://docs.travis-ci.com/user/languages/erlang#Choosing-OTP-releases-to-test-against). Rely on installation path chosen by [`travis-erlang-builder`](https://github.com/travis-ci/travis-erlang-builder/blob/e6d016b1a91ca7ecac5a5a46395bde917ea13d36/bin/compile#L18).
# - . ~/otp/18.2.1/activate && erl -version
#- curl -f -L -o ./rebar3 https://s3.amazonaws.com/rebar3/rebar3 && chmod +x ./rebar3 && ./rebar3 version && export PATH="${TRAVIS_BUILD_DIR}:$PATH"
+ # install Qt 5.10
+ - sudo add-apt-repository --yes ppa:beineri/opt-qt-5.10.1-trusty
+ - sudo apt-get update -qq
+ - sudo apt-get install qt510-meta-minimal
+ - source /opt/qt510/bin/qt510-env.sh
+ - qmake -v
# show host table to confirm petstore.swagger.io is mapped to localhost
- cat /etc/hosts
diff --git a/CI/.drone.yml b/CI/.drone.yml
index d45a1a431ea..5480eb2a9a6 100644
--- a/CI/.drone.yml
+++ b/CI/.drone.yml
@@ -2,8 +2,19 @@ kind: pipeline
name: default
steps:
-- name: test
+# test Java 11 HTTP client
+- name: java11-test
image: hirokimatsumoto/alpine-openjdk-11
commands:
- ./mvnw clean install
- ./mvnw --quiet verify -Psamples.droneio
+# test ocaml petstore client
+- name: ocaml-test
+ image: ocaml/opam2:4.07
+ commands:
+ - sudo apt-get -y install m4
+ - cd samples/client/petstore/ocaml
+ - opam install ppx_deriving_yojson cohttp ppx_deriving cohttp-lwt-unix
+ - eval $(opam env)
+ - sudo chmod -R 777 .
+ - dune build --build-dir=./_build
diff --git a/CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/ApiClientTest.java b/CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/ApiClientTest.java
index 6181e8afa2d..626901593bd 100644
--- a/CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/ApiClientTest.java
+++ b/CI/samples.ci/client/petstore/java/test-manual/okhttp-gson/ApiClientTest.java
@@ -10,6 +10,7 @@ import java.util.TimeZone;
import org.junit.*;
import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
public class ApiClientTest {
@@ -329,24 +330,18 @@ public class ApiClientTest {
assertEquals("sun.gif", apiClient.sanitizeFilename(".\\sun.gif"));
}
-
@Test
- public void testInterceptorCleanupWithNewClient() {
+ public void testNewHttpClient() {
OkHttpClient oldClient = apiClient.getHttpClient();
- assertEquals(1, oldClient.networkInterceptors().size());
-
- OkHttpClient newClient = new OkHttpClient();
- apiClient.setHttpClient(newClient);
- assertEquals(1, apiClient.getHttpClient().networkInterceptors().size());
- apiClient.setHttpClient(newClient);
- assertEquals(1, apiClient.getHttpClient().networkInterceptors().size());
+ apiClient.setHttpClient(oldClient.newBuilder().build());
+ assertThat(apiClient.getHttpClient(), is(not(oldClient)));
}
- @Test
- public void testInterceptorCleanupWithSameClient() {
- OkHttpClient oldClient = apiClient.getHttpClient();
- assertEquals(1, oldClient.networkInterceptors().size());
- apiClient.setHttpClient(oldClient);
- assertEquals(1, apiClient.getHttpClient().networkInterceptors().size());
+ /**
+ * Tests the invariant that the HttpClient for the ApiClient must never be null
+ */
+ @Test(expected = NullPointerException.class)
+ public void testNullHttpClient() {
+ apiClient.setHttpClient(null);
}
}
diff --git a/README.md b/README.md
index e56010617bf..52f285a3678 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
-[](https://gitter.im/OpenAPITools/openapi-generator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://join.slack.com/t/openapi-generator/shared_invite/enQtNzAyNDMyOTU0OTE1LTY5ZDBiNDI5NzI5ZjQ1Y2E5OWVjMjZkYzY1ZGM2MWQ4YWFjMzcyNDY5MGI4NjQxNDBiMTlmZTc5NjY2ZTQ5MGM)
[](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22)
[](https://twitter.com/oas_generator)
@@ -59,7 +59,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
| | Languages/Frameworks |
|-|-|
-**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later), **C++** (cpp-restsdk, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 7.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node, Rxjs)
+**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later), **C++** (cpp-restsdk, Qt5, Tizen), **Clojure**, **Dart (1.x, 2.x)**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client), **Kotlin**, **Lua**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, scalaz, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (AngularJS, Angular (2.x - 7.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node, Rxjs)
**Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples)), **Kotlin** (Spring Boot, Ktor), **PHP** (Laravel, Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra)
**API documentation generators** | **HTML**, **Confluence Wiki**
**Configuration files** | [**Apache2**](https://httpd.apache.org/)
@@ -101,8 +101,9 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
OpenAPI Generator Version | Release Date | Notes
---------------------------- | ------------ | -----
5.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/5.0.0-SNAPSHOT/)| 13.05.2020 | Major release with breaking changes (no fallback)
-4.1.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.1.0-SNAPSHOT/)| 31.07.2019 | Minor release (breaking changes with fallbacks)
-[4.0.3](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.0.3) (latest stable release) | 09.07.2019 | Patch release (bug fixes, minor enhancements, etc)
+4.2.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.2.0-SNAPSHOT/)| 09.10.2019 | Minor release (breaking changes with fallbacks)
+4.1.1 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.1.1-SNAPSHOT/)| 23.08.2019 | Patch release (bug fixes, enhancements)
+[4.1.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.1.0) (latest stable release) | 09.08.2019 | Minor release (breaking changes with fallbacks)
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
@@ -158,16 +159,16 @@ See the different versions of the [openapi-generator-cli](https://mvnrepository.
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
-JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.0.3/openapi-generator-cli-4.0.3.jar`
+JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.0/openapi-generator-cli-4.1.0.jar`
For **Mac/Linux** users:
```sh
-wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.0.3/openapi-generator-cli-4.0.3.jar -O openapi-generator-cli.jar
+wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.0/openapi-generator-cli-4.1.0.jar -O openapi-generator-cli.jar
```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```
-Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.0.3/openapi-generator-cli-4.0.3.jar
+Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.0/openapi-generator-cli-4.1.0.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -382,10 +383,10 @@ openapi-generator version
```
-Or install a particular OpenAPI Generator version (e.g. v4.0.3):
+Or install a particular OpenAPI Generator version (e.g. v4.1.0):
```sh
-npm install @openapitools/openapi-generator-cli@cli-4.0.3 -g
+npm install @openapitools/openapi-generator-cli@cli-4.1.0 -g
```
Or install it as dev-dependency:
@@ -409,7 +410,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g php -o c:\temp\php_api_client`)
-You can also download the JAR (latest release) directly from [maven.org](http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.0.3/openapi-generator-cli-4.0.3.jar)
+You can also download the JAR (latest release) directly from [maven.org](http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/4.1.0/openapi-generator-cli-4.1.0.jar)
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
@@ -550,6 +551,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [CAM](https://www.cam-inc.co.jp/)
- [Camptocamp](https://www.camptocamp.com/en)
- [codecentric AG](https://www.codecentric.de/)
+- [Commencis](https://www.commencis.com/)
- [Cupix](https://www.cupix.com/)
- [DB Systel](https://www.dbsystel.de)
- [FormAPI](https://formapi.io/)
@@ -594,6 +596,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2018/12/09 - [openapi-generator をカスタマイズする方法](https://qiita.com/watiko/items/0961287c02eac9211572) by [@watiko](https://qiita.com/watiko)
- 2019/01/03 - [Calling a Swagger service from Apex using openapi-generator](https://lekkimworld.com/2019/01/03/calling-a-swagger-service-from-apex-using-openapi-generator/) by [Mikkel Flindt Heisterberg](https://lekkimworld.com)
- 2019/01/13 - [OpenAPI GeneratorでRESTful APIの定義書から色々自動生成する](https://ky-yk-d.hatenablog.com/entry/2019/01/13/234108) by [@ky_yk_d](https://twitter.com/ky_yk_d)
+- 2019/01/20 - [Contract-First API Development with OpenAPI Generator and Connexion](https://medium.com/commencis/contract-first-api-development-with-openapi-generator-and-connexion-b21bbf2f9244) by [Anil Can Aydin](https://github.com/anlcnydn)
- 2019/01/30 - [Rapid Application Development With API First Approach Using Open-API Generator](https://dzone.com/articles/rapid-api-development-using-open-api-generator) by [Milan Sonkar](https://dzone.com/users/828329/milan_sonkar.html)
- 2019/02/02 - [平静を保ち、コードを生成せよ 〜 OpenAPI Generator誕生の背景と軌跡 〜](https://speakerdeck.com/akihito_nakano/gunmaweb34) by [中野暁人](https://github.com/ackintosh) at [Gunma.web #34 スキーマ駆動開発](https://gunmaweb.connpass.com/event/113974/)
- 2019/02/20 - [An adventure in OpenAPI V3 code generation](https://mux.com/blog/an-adventure-in-openapi-v3-api-code-generation/) by [Phil Cluff](https://mux.com/blog/author/philc/)
@@ -673,16 +676,19 @@ Here is a list of template creators:
* Java (Vertx): @lopesmcc
* Java (Google APIs Client Library): @charlescapps
* Java (Rest-assured): @viclovsky
+ * Java (Java 11 Native HTTP client): @bbdouglas
* Javascript/NodeJS: @jfiala
* Javascript (Closure-annotated Angular) @achew22
* Javascript (Flow types) @jaypea
* JMeter: @davidkiss
* Kotlin: @jimschubert [:heart:](https://www.patreon.com/jimschubert)
* Lua: @daurnimator
+ * OCaml: @cgensoul
* Perl: @wing328 [:heart:](https://www.patreon.com/wing328)
* PHP (Guzzle): @baartosz
* PowerShell: @beatcracker
* R: @ramnov
+ * Ruby (Faraday): @meganemura @dkliban
* Rust: @farcaller
* Rust (rust-server): @metaswitch
* Scala (scalaz & http4s): @tbrown1979
@@ -725,6 +731,7 @@ Here is a list of template creators:
* JAX-RS RestEasy (JBoss EAP): @jfiala
* Kotlin: @jimschubert [:heart:](https://www.patreon.com/jimschubert)
* Kotlin (Spring Boot): @dr4ke616
+ * NodeJS Express: @YishTish
* PHP Laravel: @renepardon
* PHP Lumen: @abcsun
* PHP Slim: @jfastnacht
@@ -802,13 +809,14 @@ If you want to join the committee, please kindly apply by sending an email to te
| Lua | @daurnimator (2017/08) |
| NodeJS/Javascript | @CodeNinjai (2017/07) @frol (2017/07) @cliffano (2017/07) |
| ObjC | |
+| OCaml | @cgensoul (2019/08) |
| Perl | @wing328 (2017/07) [:heart:](https://www.patreon.com/wing328) @yue9944882 (2019/06) |
| PHP | @jebentier (2017/07), @dkarlovi (2017/07), @mandrean (2017/08), @jfastnacht (2017/09), @ackintosh (2017/09) [:heart:](https://www.patreon.com/ackintosh/overview), @ybelenko (2018/07), @renepardon (2018/12) |
| PowerShell | |
| Python | @taxpon (2017/07) @frol (2017/07) @mbohlool (2017/07) @cbornet (2017/09) @kenjones-cisco (2017/11) @tomplus (2018/10) @Jyhess (2019/01) |
| R | @Ramanth (2019/07) @saigiridhar21 (2019/07) |
| Ruby | @cliffano (2017/07) @zlx (2017/09) @autopp (2019/02) |
-| Rust | @frol (2017/07) @farcaller (2017/08) @bjgill (2017/12) |
+| Rust | @frol (2017/07) @farcaller (2017/08) @bjgill (2017/12) @richardwhiuk (2019/07) |
| Scala | @clasnake (2017/07), @jimschubert (2017/09) [:heart:](https://www.patreon.com/jimschubert), @shijinkui (2018/01), @ramzimaalej (2018/03) |
| Swift | @jgavris (2017/07) @ehyche (2017/08) @Edubits (2017/09) @jaz-ah (2017/09) @d-date (2018/03) |
| TypeScript | @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @nicokoenig (2018/09) @topce (2018/10) @akehir (2019/07) |
diff --git a/bin/nodejs-express-petstore-server.sh b/bin/nodejs-express-petstore-server.sh
new file mode 100755
index 00000000000..8ebaac9de10
--- /dev/null
+++ b/bin/nodejs-express-petstore-server.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
+ags="generate -t modules/openapi-generator/src/main/resources/nodejs-express-server -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g nodejs-express-server -o samples/server/petstore/nodejs-express-server -Dservice $@"
+
+java $JAVA_OPTS -jar $executable $ags
diff --git a/bin/ocaml-petstore.sh b/bin/ocaml-petstore.sh
new file mode 100755
index 00000000000..9b3cb70990e
--- /dev/null
+++ b/bin/ocaml-petstore.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
+
+args="generate -t modules/openapi-generator/src/main/resources/ocaml -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g ocaml -o samples/client/petstore/ocaml --additional-properties packageName=petstore_client $@"
+
+echo "java ${JAVA_OPTS} -jar ${executable} ${args}"
+java $JAVA_OPTS -jar $executable $args
diff --git a/bin/openapi3/ocaml-client-petstore.sh b/bin/openapi3/ocaml-client-petstore.sh
new file mode 100755
index 00000000000..ccd51527f17
--- /dev/null
+++ b/bin/openapi3/ocaml-client-petstore.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DdebugOperations -DloggerPath=conf/log4j.properties"
+
+args="generate -t modules/openapi-generator/src/main/resources/ocaml -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ocaml -o samples/openapi3/client/petstore/ocaml/ --additional-properties packageName=petstore_client $@"
+
+echo "java ${JAVA_OPTS} -jar ${executable} ${args}"
+java $JAVA_OPTS -jar $executable $args
diff --git a/bin/openapi3/php-symfony-petstore.sh b/bin/openapi3/php-symfony-petstore.sh
index 8e59eea2d40..8c6ce35bd0b 100755
--- a/bin/openapi3/php-symfony-petstore.sh
+++ b/bin/openapi3/php-symfony-petstore.sh
@@ -23,7 +23,7 @@ if [ ! -d "${APP_DIR}" ]; then
fi
# Make sure that we are regenerating the sample by removing any existing target directory
-TARGET_DIR="$SCRIPT_DIR/../../samples/server/petstore/php-symfony/SymfonyBundle-php"
+TARGET_DIR="$SCRIPT_DIR/../../samples/openapi3/server/petstore/php-symfony/SymfonyBundle-php"
if [ -d "$TARGET_DIR" ]; then
rm -rf $TARGET_DIR
fi
diff --git a/bin/openapi3/ruby-client-faraday-petstore.sh b/bin/openapi3/ruby-client-faraday-petstore.sh
new file mode 100755
index 00000000000..4110205ea15
--- /dev/null
+++ b/bin/openapi3/ruby-client-faraday-petstore.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn clean package
+fi
+
+# purge lib/doc folder
+echo "purge ruby petstore lib, docs folder"
+rm -Rf samples/openapi3/client/petstore/ruby-faraday/lib
+rm -Rf samples/openapi3/client/petstore/ruby-faraday/docs
+
+# purge test files other than integration test
+# NOTE: spec/custom/*.rb and spec/petstore_helper.rb are not generated files
+echo "purge ruby petstore spec"
+find samples/openapi3/client/petstore/ruby-faraday/spec -type d -not -name spec -not -name custom | xargs rm -Rf
+find samples/openapi3/client/petstore/ruby-faraday/spec -type f -not -name petstore_helper.rb -not -iwholename '*/spec/custom/*' | xargs rm -Rf
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
+ags="generate -t modules/openapi-generator/src/main/resources/ruby-client -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ruby -c bin/openapi3/ruby-petstore-faraday.json -o samples/openapi3/client/petstore/ruby-faraday --additional-properties skipFormModel=true $@"
+
+java $JAVA_OPTS -jar $executable $ags
diff --git a/bin/openapi3/ruby-petstore-faraday.json b/bin/openapi3/ruby-petstore-faraday.json
new file mode 100644
index 00000000000..21974c307f2
--- /dev/null
+++ b/bin/openapi3/ruby-petstore-faraday.json
@@ -0,0 +1,6 @@
+{
+ "gemName": "petstore",
+ "moduleName": "Petstore",
+ "library": "faraday",
+ "gemVersion": "1.0.0"
+}
diff --git a/bin/ruby-client-petstore-faraday.sh b/bin/ruby-client-petstore-faraday.sh
new file mode 100755
index 00000000000..6782f410e46
--- /dev/null
+++ b/bin/ruby-client-petstore-faraday.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
+ags="generate -t modules/openapi-generator/src/main/resources/ruby-client -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ruby -c bin/ruby-petstore-faraday.json -o samples/client/petstore/ruby-faraday $@"
+
+java $JAVA_OPTS -jar $executable $ags
diff --git a/bin/ruby-petstore-faraday.json b/bin/ruby-petstore-faraday.json
new file mode 100644
index 00000000000..21974c307f2
--- /dev/null
+++ b/bin/ruby-petstore-faraday.json
@@ -0,0 +1,6 @@
+{
+ "gemName": "petstore",
+ "moduleName": "Petstore",
+ "library": "faraday",
+ "gemVersion": "1.0.0"
+}
diff --git a/bin/ruby-petstore.json b/bin/ruby-petstore.json
index ddb753471a1..47842a6be7a 100644
--- a/bin/ruby-petstore.json
+++ b/bin/ruby-petstore.json
@@ -1,5 +1,6 @@
{
"gemName": "petstore",
+ "library": "typhoeus",
"moduleName": "Petstore",
"gemVersion": "1.0.0"
}
diff --git a/bin/spring-all-petstore.sh b/bin/spring-all-petstore.sh
index e3060626f7b..3f3536cf1ab 100755
--- a/bin/spring-all-petstore.sh
+++ b/bin/spring-all-petstore.sh
@@ -2,6 +2,7 @@
# Generate clients:
./bin/spring-cloud-feign-petstore.sh
+./bin/spring-cloud-feign-async-petstore.sh
./bin/spring-stubs.sh
# Generate spring-mvc servers:
diff --git a/bin/spring-cloud-feign-async-petstore.sh b/bin/spring-cloud-feign-async-petstore.sh
new file mode 100755
index 00000000000..ec2df408974
--- /dev/null
+++ b/bin/spring-cloud-feign-async-petstore.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
+ags="generate -t modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g spring -c bin/spring-cloud-feign-petstore.json -o samples/client/petstore/spring-cloud-async --additional-properties hideGenerationTimestamp=true,java8=true,async=true $@"
+
+echo "Removing files and folders under samples/client/petstore/spring-cloud-async/src/main"
+rm -rf samples/client/petstore/spring-cloud-async/src/main
+find samples/client/petstore/spring-cloud-async -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
+java $JAVA_OPTS -jar $executable $ags
diff --git a/bin/typescript-angular-v7-petstore-not-provided-in-root-with-npm.json b/bin/typescript-angular-v7-petstore-not-provided-in-root-with-npm.json
index 535bffbd45e..9c939c67ae4 100644
--- a/bin/typescript-angular-v7-petstore-not-provided-in-root-with-npm.json
+++ b/bin/typescript-angular-v7-petstore-not-provided-in-root-with-npm.json
@@ -1,6 +1,7 @@
{
"npmName": "@openapitools/typescript-angular-petstore",
"npmVersion": "1.0.0",
- "npmRepository" : "https://skimdb.npmjs.com/registry",
- "snapshot" : false
+ "stringEnums": true,
+ "npmRepository": "https://skimdb.npmjs.com/registry",
+ "snapshot": false
}
diff --git a/bin/typescript-axios-petstore-all.sh b/bin/typescript-axios-petstore-all.sh
index de66b03904f..58d13d10f62 100755
--- a/bin/typescript-axios-petstore-all.sh
+++ b/bin/typescript-axios-petstore-all.sh
@@ -3,5 +3,6 @@
./bin/typescript-axios-petstore-target-es6.sh
./bin/typescript-axios-petstore-with-npm-version.sh
./bin/typescript-axios-petstore-with-npm-version-and-separate-models-and-api.sh
+./bin/typescript-axios-petstore-with-complex-headers.sh
./bin/typescript-axios-petstore-interfaces.sh
./bin/typescript-axios-petstore.sh
diff --git a/bin/typescript-axios-petstore-with-complex-headers.sh b/bin/typescript-axios-petstore-with-complex-headers.sh
new file mode 100755
index 00000000000..385f9684c1a
--- /dev/null
+++ b/bin/typescript-axios-petstore-with-complex-headers.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
+ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-complex-headers.yaml -g typescript-axios -o samples/client/petstore/typescript-axios/builds/with-complex-headers $@"
+
+java $JAVA_OPTS -jar $executable $ags
diff --git a/bin/utils/ensure-up-to-date b/bin/utils/ensure-up-to-date
index 166c8c60bd1..799e7dc2005 100755
--- a/bin/utils/ensure-up-to-date
+++ b/bin/utils/ensure-up-to-date
@@ -13,7 +13,7 @@ sleep 5
declare -a scripts=(
# SAMPLES
"./bin/openapi3/ruby-client-petstore.sh"
-"./bin/ruby-client-petstore.sh"
+"./bin/openapi3/ruby-client-faraday-petstore.sh"
"./bin/java-petstore-all.sh"
"./bin/java-jaxrs-petstore-server-all.sh"
"./bin/java-msf4j-petstore-server.sh"
diff --git a/bin/windows/ocaml-petstore.bat b/bin/windows/ocaml-petstore.bat
new file mode 100755
index 00000000000..aa59c18b827
--- /dev/null
+++ b/bin/windows/ocaml-petstore.bat
@@ -0,0 +1,10 @@
+set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
+
+If Not Exist %executable% (
+ mvn clean package
+)
+
+REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
+set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g ocaml -o samples\client\petstore\ocaml
+
+java %JAVA_OPTS% -jar %executable% %ags%
diff --git a/bin/windows/python-experimental-petstore.bat b/bin/windows/python-experimental-petstore.bat
new file mode 100644
index 00000000000..50df98535f4
--- /dev/null
+++ b/bin/windows/python-experimental-petstore.bat
@@ -0,0 +1,10 @@
+set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
+
+If Not Exist %executable% (
+ mvn clean package
+)
+
+REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
+set ags=generate -i modules\openapi-generator\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -g python-experimental -o samples\client\petstore\python-experimental -DpackageName=petstore_api
+
+java %JAVA_OPTS% -jar %executable% %ags%
diff --git a/bin/windows/typescript-axios-petstore-all.bat b/bin/windows/typescript-axios-petstore-all.bat
index 8f243f3def6..a5e4e732a1d 100644
--- a/bin/windows/typescript-axios-petstore-all.bat
+++ b/bin/windows/typescript-axios-petstore-all.bat
@@ -2,6 +2,7 @@
call bin\windows\typescript-axios-petstore.bat
call bin\windows\typescript-axios-petstore-target-es6.bat
+call bin\windows\typescript-axios-petstore-with-complex-headers.bat
call bin\windows\typescript-axios-petstore-with-npm-version.bat
call bin\windows\typescript-axios-petstore-interfaces.bat
call bin\windows\typescript-axios-petstore-with-npm-version-and-separate-models-and-api.bat
\ No newline at end of file
diff --git a/bin/windows/typescript-axios-petstore-with-complex-headers.bat b/bin/windows/typescript-axios-petstore-with-complex-headers.bat
new file mode 100755
index 00000000000..9cf113587ea
--- /dev/null
+++ b/bin/windows/typescript-axios-petstore-with-complex-headers.bat
@@ -0,0 +1,12 @@
+@ECHO OFF
+
+set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
+
+If Not Exist %executable% (
+ mvn clean package
+)
+
+REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
+set ags=generate -i modules\openapi-generator\src\test\resources\3_0\petstore-with-complex-headers.yaml -g typescript-axios -o samples\client\petstore\typescript-axios\builds\with-complex-headers
+
+java %JAVA_OPTS% -jar %executable% %ags%
diff --git a/docs/generators.md b/docs/generators.md
index ecb4edfd40c..77f0a887afb 100644
--- a/docs/generators.md
+++ b/docs/generators.md
@@ -39,6 +39,7 @@ The following generators are available:
- [kotlin](generators/kotlin.md)
- [lua](generators/lua.md)
- [objc](generators/objc.md)
+ - [ocaml](generators/ocaml.md)
- [perl](generators/perl.md)
- [php](generators/php.md)
- [powershell](generators/powershell.md)
@@ -93,6 +94,7 @@ The following generators are available:
- [jaxrs-spec](generators/jaxrs-spec.md)
- [kotlin-server](generators/kotlin-server.md)
- [kotlin-spring](generators/kotlin-spring.md)
+ - [nodejs-express-server](generators/nodejs-express-server.md) (beta)
- [nodejs-server-deprecated](generators/nodejs-server-deprecated.md) (deprecated)
- [php-laravel](generators/php-laravel.md)
- [php-lumen](generators/php-lumen.md)
diff --git a/docs/generators/nodejs-express-server.md b/docs/generators/nodejs-express-server.md
new file mode 100644
index 00000000000..25a84db36d6
--- /dev/null
+++ b/docs/generators/nodejs-express-server.md
@@ -0,0 +1,14 @@
+
+---
+id: generator-opts-server-nodejs-express-server
+title: Config Options for nodejs-express-server
+sidebar_label: nodejs-express-server
+---
+
+| Option | Description | Values | Default |
+| ------ | ----------- | ------ | ------- |
+|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
+|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
+|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
+|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
+|serverPort|TCP port to listen on.| |null|
diff --git a/docs/generators/ocaml-client.md b/docs/generators/ocaml-client.md
new file mode 100644
index 00000000000..52874232c1e
--- /dev/null
+++ b/docs/generators/ocaml-client.md
@@ -0,0 +1,13 @@
+
+---
+id: generator-opts-client-ocaml-client
+title: Config Options for ocaml-client
+sidebar_label: ocaml-client
+---
+
+| Option | Description | Values | Default |
+| ------ | ----------- | ------ | ------- |
+|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
+|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
+|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
+|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
diff --git a/docs/generators/ocaml.md b/docs/generators/ocaml.md
new file mode 100644
index 00000000000..7397b1c31bf
--- /dev/null
+++ b/docs/generators/ocaml.md
@@ -0,0 +1,13 @@
+
+---
+id: generator-opts-client-ocaml
+title: Config Options for ocaml
+sidebar_label: ocaml
+---
+
+| Option | Description | Values | Default |
+| ------ | ----------- | ------ | ------- |
+|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
+|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
+|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
+|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
diff --git a/docs/generators/openapi-yaml.md b/docs/generators/openapi-yaml.md
index 1dfe1b9f481..5bc5c746885 100644
--- a/docs/generators/openapi-yaml.md
+++ b/docs/generators/openapi-yaml.md
@@ -11,4 +11,4 @@ sidebar_label: openapi-yaml
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
-|outputFile|output filename| |null|
+|outputFile|Output filename| |openapi/openapi.yaml|
diff --git a/docs/generators/ruby.md b/docs/generators/ruby.md
index e8a5a56b227..a6af465e75f 100644
--- a/docs/generators/ruby.md
+++ b/docs/generators/ruby.md
@@ -22,3 +22,4 @@ sidebar_label: ruby
|gemAuthor|gem author (only one is supported).| |null|
|gemAuthorEmail|gem author email (only one is supported).| |null|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
+|library|HTTP library template (sub-template) to use|
**faraday** Faraday (https://github.com/lostisland/faraday) (Beta support) **typhoeus** Typhoeus >= 1.0.1 (https://github.com/typhoeus/typhoeus) |typhoeus|
diff --git a/docs/generators/typescript-angular.md b/docs/generators/typescript-angular.md
index 0090d5472bc..c9b6786ea87 100644
--- a/docs/generators/typescript-angular.md
+++ b/docs/generators/typescript-angular.md
@@ -26,3 +26,4 @@ sidebar_label: typescript-angular
|modelSuffix|The suffix of the generated model.| |null|
|modelFileSuffix|The suffix of the file of the generated model (model<suffix>.ts).| |null|
|fileNaming|Naming convention for the output files: 'camelCase', 'kebab-case'.| |camelCase|
+|stringEnums|Generate string enums instead of objects for enum values.| |false|
diff --git a/docs/templating.md b/docs/templating.md
index 6452a58c6db..287f8060c99 100644
--- a/docs/templating.md
+++ b/docs/templating.md
@@ -16,7 +16,7 @@ The transform logic needs to implement [CodegenConfig.java](https://github.com/o
> OpenAPI Generator applies user-defined templates via options:
> * CLI: `-t/--template` CLI options
> * Maven Plugin: `templateDirectory`
-> * Gradle Plugin: `templateDir`
+> * Gradle Plugin: `templateDir`
Built-in templates are written in Mustache and processed by [jmustache](https://github.com/samskivert/jmustache). Beginning with version 4.0.0, we support experimental Handlebars and user-defined template engines via plugins.
@@ -26,7 +26,7 @@ OpenAPI Generator supports user-defined templates. This approach is often the ea
### Custom Logic
-For this example, let's modify a Java client to use AOP via [jcabi/jcabi-aspects](https://github.com/jcabi/jcabi-aspects). We'll log API method execution at the `INFO` level. The jcabi-aspects project could also be used to implement method retries on failures; this would be a great exercise to further play around with templating.
+For this example, let's modify a Java client to use AOP via [jcabi/jcabi-aspects](https://github.com/jcabi/jcabi-aspects). We'll log API method execution at the `INFO` level. The jcabi-aspects project could also be used to implement method retries on failures; this would be a great exercise to further play around with templating.
The Java generator supports a `library` option. This option works by defining base templates, then applying library-specific template overrides. This allows for template reuse for libraries sharing the same programming language. Templates defined as a library need only modify or extend the templates concerning the library, and generation falls back to the root templates (the "defaults") when not extended by the library. Generators which support the `library` option will only support the libraries known by the generator at compile time, and will throw a runtime error if you try to provide a custom library name.
@@ -77,7 +77,7 @@ index 3b40702..a6d12e0 100644
+++ b/libraries/resteasy/build.gradle.mustache
@@ -134,6 +134,7 @@ ext {
}
-
+
dependencies {
+ compile "com.jcabi:jcabi-aspects:0.22.6"
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
@@ -95,7 +95,7 @@ index a4d0f9f..49b17c7 100644
+++ b/libraries/resteasy/api.mustache
@@ -1,5 +1,6 @@
package {{package}};
-
+
+import com.jcabi.aspects.Loggable;
import {{invokerPackage}}.ApiException;
import {{invokerPackage}}.ApiClient;
@@ -134,7 +134,7 @@ index 04a9d55..7a93c50 100644
apply plugin: 'idea'
apply plugin: 'eclipse'
+apply plugin: 'aspectj'
-
+
group = '{{groupId}}'
version = '{{artifactVersion}}'
@@ -12,6 +13,7 @@ buildscript {
@@ -144,14 +144,14 @@ index 04a9d55..7a93c50 100644
+ classpath "net.uberfoo.gradle:gradle-aspectj:2.2"
}
}
-
+
@@ -140,9 +142,18 @@ ext {
jersey_version = "1.19.4"
jodatime_version = "2.9.9"
junit_version = "4.12"
+ aspectjVersion = '1.9.0'
}
-
+
+sourceCompatibility = '1.8'
+targetCompatibility = '1.8'
+
@@ -199,7 +199,7 @@ Make sure your custom template compiles:
```bash
cd ~/.openapi-generator/example
gradle assemble
-# or, regenerate the wrapper
+# or, regenerate the wrapper
gradle wrapper --gradle-version 4.8 --distribution-type all
./gradlew assemble
```
@@ -291,7 +291,7 @@ Modifications to the new project's `build.gradle` should be made in the `plugins
id 'org.jetbrains.kotlin.jvm' version '1.3.11'
id "com.github.johnrengelman.shadow" version "5.0.0"
}
-
+
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
compile "org.openapitools:openapi-generator-core:4.0.0-SNAPSHOT"
@@ -301,7 +301,7 @@ Modifications to the new project's `build.gradle` should be made in the `plugins
The above configuration for the `shadow` plugin is strictly optional. It is not needed, for instance, if you plan to publish your adapter and consume it via the Maven or Gradle plugins.
-Next, create a new class file called `PebbleTemplateEngineAdapter` under `src/kotlin`. We'll define the template adapter's name as `pebble` and we'll also list this as the only supported file extension. We'll implement the adapter by extending `AbstractTemplatingEngineAdapter`, which includes reusable logic, such as retrieving a list of all possible template names for our provided template extensions(s).
+Next, create a new class file called `PebbleTemplateEngineAdapter` under `src/kotlin`. We'll define the template adapter's name as `pebble` and we'll also list this as the only supported file extension. We'll implement the adapter by extending `AbstractTemplatingEngineAdapter`, which includes reusable logic, such as retrieving a list of all possible template names for our provided template extensions(s).
The class in its simplest form looks like this (with inline comments):
@@ -374,7 +374,7 @@ import (
{% endfor %}
)
-type Generated{{classname}}Servicer
+type Generated{{classname}}Servicer
// etc
```
@@ -402,7 +402,7 @@ type {{item.classname}} struct {
> Find object structures passed to templates later in this document's **Structures** section.
-Finally, we can compile some code by explicitly defining our classpath and jar entrypoint for CLI (be sure to modify `/your/path` below)
+Finally, we can compile some code by explicitly defining our classpath and jar entrypoint for CLI (be sure to modify `/your/path` below)
```bash
java $JAVA_OPTS -cp /your/path/build/libs/pebble-template-adapter-1.0-SNAPSHOT-all.jar:modules/openapi-generator-cli/target/openapi-generator-cli.jar \
@@ -428,49 +428,49 @@ Examples for the following structures will be presented using the following spec
```yaml
swagger: "2.0"
- info:
+ info:
version: "1.0.0"
title: "Swagger Petstore"
description: "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification"
termsOfService: "http://swagger.io/terms/"
- contact:
+ contact:
name: "Swagger API Team"
- license:
+ license:
name: "MIT"
host: "petstore.swagger.io"
basePath: "/api"
- schemes:
+ schemes:
- "http"
- consumes:
+ consumes:
- "application/json"
- produces:
+ produces:
- "application/json"
- paths:
- /pets:
- get:
+ paths:
+ /pets:
+ get:
description: "Returns all pets from the system that the user has access to"
- produces:
+ produces:
- "application/json"
- responses:
+ responses:
"200":
description: "A list of pets."
- schema:
+ schema:
type: "array"
- items:
+ items:
$ref: "#/definitions/Pet"
- definitions:
- Pet:
+ definitions:
+ Pet:
type: "object"
- required:
+ required:
- "id"
- "name"
- properties:
- id:
+ properties:
+ id:
type: "integer"
format: "int64"
- name:
+ name:
type: "string"
- tag:
+ tag:
type: "string"
```
@@ -478,9 +478,9 @@ Examples for the following structures will be presented using the following spec
### Operations
> Inspect operation structures passed to templates with system property `-DdebugOpenAPI`
->
+>
> Example:
->
+>
> ```bash
> openapi-generator generate -g go \
> -o out \
@@ -510,9 +510,9 @@ Here, an Operation with tag `Pet` will generate two files: `SWGPetApi.h` and `SW
### Models
> Inspect models passed to templates with system property `-DdebugModels`
->
+>
> Execute:
->
+>
> ```bash
> openapi-generator generate -g go \
> -o out \
@@ -730,14 +730,14 @@ Templates are passed redundant properties, depending on the semantics of the arr
* `readOnlyVars` lists all model properties marked with `readonly` in the spec document
* `allVars` lists all model properties. This may include the same set as `vars`, but may also include generator-defined properties
-We expose the same properties in multiple sets because this allows us to conditionally iterate over properties based on some condition ("is it required" or "is it readonly"). This is driven by the use of the logic-less Mustache templates. It is possible that models passed to the templating engine may be cleaned up as we support more template engines, but such an effort will go through a deprecation phase and would be communicated at runtime through log messages.
+We expose the same properties in multiple sets because this allows us to conditionally iterate over properties based on some condition ("is it required" or "is it readonly"). This is driven by the use of the logic-less Mustache templates. It is possible that models passed to the templating engine may be cleaned up as we support more template engines, but such an effort will go through a deprecation phase and would be communicated at runtime through log messages.
### supportingFiles
> Inspect supportingFiles passed to templates with system property `-DdebugSupportingFiles`
->
+>
> Execute:
->
+>
> ```bash
> openapi-generator generate -g go \
> -o out \
@@ -755,10 +755,25 @@ Supporting files can either be processed through the templating engine or copied
> This is a very limited list of variable name explanations. Feel free to [open a pull request](https://github.com/OpenAPITools/openapi-generator/pull/new/master) to add to this documentation!
-- **complexType**: stores the name of the model (e.g. Pet)
+- **complexType**: stores the name of the model (e.g. Pet)
- **isContainer**: true if the parameter or property is an array or a map.
- **isPrimitiveType**: true if the parameter or property type is a primitive type (e.g. string, integer, etc) as defined in the spec.
+## Mustache Lambdas
+
+Many generators (*those extending DefaultCodegen*) come with a small set of lambda functions available under the key `lambda`:
+
+- `lowercase` - Converts all of the characters in this fragment to lower case using the rules of the `ROOT` locale.
+- `uppercase` - Converts all of the characters in this fragment to upper case using the rules of the `ROOT` locale.
+- `titlecase` - Converts text in a fragment to title case. For example `once upon a time` to `Once Upon A Time`.
+- `camelcase` - Converts text in a fragment to camelCase. For example `Input-text` to `inputText`.
+- `indented` - Prepends 4 spaces indention from second line of a fragment on. First line will be indented by Mustache.
+- `indented_8` - Prepends 8 spaces indention from second line of a fragment on. First line will be indented by Mustache.
+- `indented_12` - Prepends 12 spaces indention from second line of a fragment on. First line will be indented by Mustache.
+- `indented_16` -Prepends 16 spaces indention from second line of a fragment on. First line will be indented by Mustache.
+
+Lambda is invoked by `lambda.[lambda name]` expression. For example: `{{#lambda.lowercase}}FRAGMENT TO LOWERCASE{{/lambda.lowercase}}` to lower case text between `lambda.lowercase`.
+
## Extensions
OpenAPI supports a concept called "Extensions". These are called "Specification Extensions" [in 3.x](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#specificationExtensions) and "Vendor Extensions" [in 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#vendorExtensions).
@@ -861,7 +876,7 @@ paths:
#### x-mysqlSchema
-MySQL schema generator creates vendor extensions based on openapi `dataType` and `dataFormat`. When user defined extensions with same key already exists codegen accepts those as is. It means it won't validate properties or correct it for you. Every model in `definitions` can contain table related and column related extensions like in example below:
+MySQL schema generator creates vendor extensions based on openapi `dataType` and `dataFormat`. When user defined extensions with same key already exists codegen accepts those as is. It means it won't validate properties or correct it for you. Every model in `definitions` can contain table related and column related extensions like in example below:
```yaml
definitions:
diff --git a/modules/openapi-generator-gradle-plugin/README.adoc b/modules/openapi-generator-gradle-plugin/README.adoc
index 3ed40ed1ea0..d35c7240ed8 100644
--- a/modules/openapi-generator-gradle-plugin/README.adoc
+++ b/modules/openapi-generator-gradle-plugin/README.adoc
@@ -45,7 +45,7 @@ compileJava.dependsOn tasks.openApiGenerate
[source,group]
----
plugins {
- id "org.openapi.generator" version "4.0.3"
+ id "org.openapi.generator" version "4.1.0"
}
----
@@ -61,7 +61,7 @@ buildscript {
// url "https://plugins.gradle.org/m2/"
}
dependencies {
- classpath "org.openapitools:openapi-generator-gradle-plugin:4.0.3"
+ classpath "org.openapitools:openapi-generator-gradle-plugin:4.1.0"
}
}
@@ -609,7 +609,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
- classpath('org.openapitools:openapi-generator-gradle-plugin:4.0.3') {
+ classpath('org.openapitools:openapi-generator-gradle-plugin:4.1.0') {
exclude group: 'com.google.guava'
}
}
diff --git a/modules/openapi-generator-gradle-plugin/samples/local-spec/README.md b/modules/openapi-generator-gradle-plugin/samples/local-spec/README.md
index 178b02089a2..33dc2591229 100644
--- a/modules/openapi-generator-gradle-plugin/samples/local-spec/README.md
+++ b/modules/openapi-generator-gradle-plugin/samples/local-spec/README.md
@@ -17,5 +17,5 @@ gradle generateGoWithInvalidSpec
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
```bash
-gradle -PopenApiGeneratorVersion=4.0.3 openApiValidate
+gradle -PopenApiGeneratorVersion=4.1.0 openApiValidate
```
diff --git a/modules/openapi-generator-gradle-plugin/samples/local-spec/gradle.properties b/modules/openapi-generator-gradle-plugin/samples/local-spec/gradle.properties
index 00abde066a2..149e1997c3d 100644
--- a/modules/openapi-generator-gradle-plugin/samples/local-spec/gradle.properties
+++ b/modules/openapi-generator-gradle-plugin/samples/local-spec/gradle.properties
@@ -1,3 +1,3 @@
# RELEASE_VERSION
-openApiGeneratorVersion=4.0.3
+openApiGeneratorVersion=4.1.0
# /RELEASE_VERSION
diff --git a/modules/openapi-generator-maven-plugin/README.md b/modules/openapi-generator-maven-plugin/README.md
index 20015bddf01..2161502a97b 100644
--- a/modules/openapi-generator-maven-plugin/README.md
+++ b/modules/openapi-generator-maven-plugin/README.md
@@ -12,7 +12,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
org.openapitools
openapi-generator-maven-plugin
- 4.0.3
+ 4.1.0
diff --git a/modules/openapi-generator-maven-plugin/examples/java-client.xml b/modules/openapi-generator-maven-plugin/examples/java-client.xml
index e8f0bc88d6b..f7f5df89de0 100644
--- a/modules/openapi-generator-maven-plugin/examples/java-client.xml
+++ b/modules/openapi-generator-maven-plugin/examples/java-client.xml
@@ -13,7 +13,7 @@
org.openapitools
openapi-generator-maven-plugin
- 4.0.3
+ 4.1.1-SNAPSHOT
@@ -88,6 +88,13 @@
${jersey-version}
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.2
+
+
com.fasterxml.jackson.jaxrs
diff --git a/modules/openapi-generator-maven-plugin/examples/multi-module/java-client/pom.xml b/modules/openapi-generator-maven-plugin/examples/multi-module/java-client/pom.xml
index d7dcdbd7dfa..4bb2f19f343 100644
--- a/modules/openapi-generator-maven-plugin/examples/multi-module/java-client/pom.xml
+++ b/modules/openapi-generator-maven-plugin/examples/multi-module/java-client/pom.xml
@@ -19,7 +19,7 @@
org.openapitools
openapi-generator-maven-plugin
- 4.0.3
+ 5.0.0-SNAPSHOT
@@ -101,6 +101,13 @@
${jersey-version}
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.2
+
+
com.fasterxml.jackson.jaxrs
diff --git a/modules/openapi-generator-maven-plugin/examples/non-java-invalid-spec.xml b/modules/openapi-generator-maven-plugin/examples/non-java-invalid-spec.xml
index 8ea704877f8..95dc5c71679 100644
--- a/modules/openapi-generator-maven-plugin/examples/non-java-invalid-spec.xml
+++ b/modules/openapi-generator-maven-plugin/examples/non-java-invalid-spec.xml
@@ -13,7 +13,7 @@
org.openapitools
openapi-generator-maven-plugin
- 4.0.3
+ 4.1.0
diff --git a/modules/openapi-generator-maven-plugin/examples/non-java.xml b/modules/openapi-generator-maven-plugin/examples/non-java.xml
index ccace5a9933..df0297f8149 100644
--- a/modules/openapi-generator-maven-plugin/examples/non-java.xml
+++ b/modules/openapi-generator-maven-plugin/examples/non-java.xml
@@ -13,7 +13,7 @@
org.openapitools
openapi-generator-maven-plugin
- 4.0.3
+ 4.1.0
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
index 39415e2698d..94b29ee1bac 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
@@ -240,13 +240,10 @@ public class DefaultCodegen implements CodegenConfig {
}
if (additionalProperties.containsKey("lambda")) {
- LOGGER.warn("A property named 'lambda' already exists. Mustache lambdas renamed from 'lambda' to '_lambda'. " +
- "You'll likely need to use a custom template, " +
- "see https://github.com/OpenAPITools/openapi-generator/blob/master/docs/templating.md. ");
- additionalProperties.put("_lambda", lambdas);
- } else {
- additionalProperties.put("lambda", lambdas);
+ LOGGER.error("A property called 'lambda' already exists in additionalProperties");
+ throw new RuntimeException("A property called 'lambda' already exists in additionalProperties");
}
+ additionalProperties.put("lambda", lambdas);
}
// override with any special post-processing for all models
@@ -1870,6 +1867,9 @@ public class DefaultCodegen implements CodegenConfig {
}
}
+ if(composed.getRequired() != null) {
+ required.addAll(composed.getRequired());
+ }
addVars(m, unaliasPropertySchema(properties), required, unaliasPropertySchema(allProperties), allRequired);
// end of code block for composed schema
@@ -1975,6 +1975,10 @@ public class DefaultCodegen implements CodegenConfig {
addProperties(properties, required, component);
}
+ if(schema.getRequired() != null) {
+ required.addAll(schema.getRequired());
+ }
+
if (composedSchema.getOneOf() != null) {
throw new RuntimeException("Please report the issue: Cannot process oneOf (Composed Scheme) in addProperties: " + schema);
}
@@ -4017,6 +4021,19 @@ public class DefaultCodegen implements CodegenConfig {
* @return sanitized string
*/
public String sanitizeName(String name, String removeCharRegEx) {
+ return sanitizeName(name, removeCharRegEx, new ArrayList());
+ }
+
+ /**
+ * Sanitize name (parameter, property, method, etc)
+ *
+ * @param name string to be sanitize
+ * @param removeCharRegEx a regex containing all char that will be removed
+ * @param exceptionList a list of matches which should not be sanitized (i.e expections)
+ * @return sanitized string
+ */
+ @SuppressWarnings("static-method")
+ public String sanitizeName(String name, String removeCharRegEx, ArrayList exceptionList) {
// NOTE: performance wise, we should have written with 2 replaceAll to replace desired
// character with _ or empty character. Below aims to spell out different cases we've
// encountered so far and hopefully make it easier for others to add more special
@@ -4034,27 +4051,27 @@ public class DefaultCodegen implements CodegenConfig {
}
// input[] => input
- name = name.replaceAll("\\[\\]", ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
+ name = this.sanitizeValue(name, "\\[\\]", "", exceptionList);
// input[a][b] => input_a_b
- name = name.replaceAll("\\[", "_");
- name = name.replaceAll("\\]", "");
+ name = this.sanitizeValue(name, "\\[", "_", exceptionList);
+ name = this.sanitizeValue(name, "\\]", "", exceptionList);
// input(a)(b) => input_a_b
- name = name.replaceAll("\\(", "_");
- name = name.replaceAll("\\)", "");
+ name = this.sanitizeValue(name, "\\(", "_", exceptionList);
+ name = this.sanitizeValue(name, "\\)", "", exceptionList);
// input.name => input_name
- name = name.replaceAll("\\.", "_");
+ name = this.sanitizeValue(name, "\\.", "_", exceptionList);
// input-name => input_name
- name = name.replaceAll("-", "_");
+ name = this.sanitizeValue(name, "-", "_", exceptionList);
// a|b => a_b
- name = name.replace("|", "_");
+ name = this.sanitizeValue(name, "\\|", "_", exceptionList);
// input name and age => input_name_and_age
- name = name.replaceAll(" ", "_");
+ name = this.sanitizeValue(name, " ", "_", exceptionList);
// /api/films/get => _api_films_get
// \api\films\get => _api_films_get
@@ -4072,6 +4089,13 @@ public class DefaultCodegen implements CodegenConfig {
return name;
}
+ private String sanitizeValue(String value, String replaceMatch, String replaceValue, ArrayList exceptionList) {
+ if (exceptionList.size() == 0 || !exceptionList.contains(replaceMatch)) {
+ return value.replaceAll(replaceMatch, replaceValue);
+ }
+ return value;
+ }
+
/**
* Sanitize tag
*
@@ -4908,6 +4932,15 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.dataType = codegenProperty.dataType;
codegenParameter.description = codegenProperty.description;
codegenParameter.paramName = toParamName(codegenParameter.baseName);
+ codegenParameter.minimum = codegenProperty.minimum;
+ codegenParameter.maximum = codegenProperty.maximum;
+ codegenParameter.exclusiveMinimum = codegenProperty.exclusiveMinimum;
+ codegenParameter.exclusiveMaximum = codegenProperty.exclusiveMaximum;
+ codegenParameter.minLength = codegenProperty.minLength;
+ codegenParameter.maxLength = codegenProperty.maxLength;
+ codegenParameter.pattern = codegenProperty.pattern;
+
+
if (codegenProperty.complexType != null) {
imports.add(codegenProperty.complexType);
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java
index 5ea4a08a1a3..4ed482f4b8f 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/InlineModelResolver.java
@@ -407,9 +407,19 @@ public class InlineModelResolver {
}
}
+ /**
+ * Generates a unique model name. Non-alphanumeric characters will be replaced
+ * with underscores
+ *
+ * @param title String title field in the schema if present
+ * @param key String model name
+ */
private String resolveModelName(String title, String key) {
if (title == null) {
- return uniqueName(key);
+ // for auto-generated schema name, replace non-alphanumeric characters with underscore
+ // to avoid bugs with schema look up with inline schema created on the fly
+ // e.g. io.schema.User_name => io_schema_User_name
+ return uniqueName(key).replaceAll("[^A-Za-z0-9]", "_");
} else {
return uniqueName(title);
}
@@ -589,4 +599,4 @@ public class InlineModelResolver {
target.addExtension(extName, vendorExtensions.get(extName));
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java
index d39c6c07ab4..912b172fcd0 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java
@@ -153,13 +153,14 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
"DateTime?",
"DateTime",
"DateTimeOffset?",
- "DataTimeOffset",
+ "DateTimeOffset",
"Boolean",
"Double",
"Int32",
"Int64",
"Float",
"Guid?",
+ "Guid",
"System.IO.Stream", // not really a primitive, we include it to avoid model import
"Object")
);
@@ -192,7 +193,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
// nullable type
nullableType = new HashSet(
- Arrays.asList("decimal", "bool", "int", "float", "long", "double", "DateTime", "Guid")
+ Arrays.asList("decimal", "bool", "int", "float", "long", "double", "DateTime", "DateTimeOffset", "Guid")
);
// value Types
valueTypes = new HashSet(
@@ -226,9 +227,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
public void useDateTimeOffset(boolean flag) {
this.useDateTimeOffsetFlag = flag;
if (flag) {
- typeMapping.put("DateTime", "DateTimeOffset?");
+ typeMapping.put("DateTime", "DateTimeOffset");
} else {
- typeMapping.put("DateTime", "DateTime?");
+ typeMapping.put("DateTime", "DateTime");
}
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java
index 9e5e01123df..1500a1405ce 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java
@@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ArraySchema;
+import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import org.apache.commons.io.FilenameUtils;
@@ -54,6 +55,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
protected String npmName = null;
protected String npmVersion = "1.0.0";
+ protected String enumSuffix = "Enum";
+ protected String classEnumSeparator = ".";
+
public AbstractTypeScriptClientCodegen() {
super();
@@ -94,7 +98,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
"object"
));
- languageGenericTypes = new HashSet<>(Arrays.asList(
+ languageGenericTypes = new HashSet<>(Collections.singletonList(
"Array"
));
@@ -144,8 +148,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
if (StringUtils.isEmpty(System.getenv("TS_POST_PROCESS_FILE"))) {
LOGGER.info("Hint: Environment variable 'TS_POST_PROCESS_FILE' (optional) not defined. E.g. to format the source code, please try 'export TS_POST_PROCESS_FILE=\"/usr/local/bin/prettier --write\"' (Linux/Mac)");
LOGGER.info("Note: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
- }
- else if (!this.isEnablePostProcessFile()) {
+ } else if (!this.isEnablePostProcessFile()) {
LOGGER.info("Warning: Environment variable 'TS_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
@@ -177,7 +180,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
this.setNpmVersion(openAPI.getInfo().getVersion());
}
- if (additionalProperties.containsKey(SNAPSHOT) && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) {
+ if (additionalProperties.containsKey(SNAPSHOT) && Boolean.parseBoolean(additionalProperties.get(SNAPSHOT).toString())) {
if (npmVersion.toUpperCase(Locale.ROOT).matches("^.*-SNAPSHOT$")) {
this.setNpmVersion(npmVersion + "." + SNAPSHOT_SUFFIX_FORMAT.format(new Date()));
} else {
@@ -260,45 +263,45 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
final String regex = "^.*[+*:;,.()-]+.*$";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(str);
- boolean matches = matcher.matches();
- return matches;
+ return matcher.matches();
}
@Override
- public String toModelName(String name) {
- name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
+ public String toModelName(final String name) {
+ ArrayList exceptions = new ArrayList(Arrays.asList("\\|", " "));
+ String sanName = sanitizeName(name, "(?![| ])\\W", exceptions);
if (!StringUtils.isEmpty(modelNamePrefix)) {
- name = modelNamePrefix + "_" + name;
+ sanName = modelNamePrefix + "_" + sanName;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
- name = name + "_" + modelNameSuffix;
+ sanName = sanName + "_" + modelNameSuffix;
}
// model name cannot use reserved keyword, e.g. return
- if (isReservedWord(name)) {
- String modelName = camelize("model_" + name);
- LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
+ if (isReservedWord(sanName)) {
+ String modelName = camelize("model_" + sanName);
+ LOGGER.warn(sanName + " (reserved word) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
// model name starts with number
- if (name.matches("^\\d.*")) {
- String modelName = camelize("model_" + name); // e.g. 200Response => Model200Response (after camelize)
- LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
+ if (sanName.matches("^\\d.*")) {
+ String modelName = camelize("model_" + sanName); // e.g. 200Response => Model200Response (after camelize)
+ LOGGER.warn(sanName + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
return modelName;
}
- if (languageSpecificPrimitives.contains(name)) {
- String modelName = camelize("model_" + name);
- LOGGER.warn(name + " (model name matches existing language type) cannot be used as a model name. Renamed to " + modelName);
+ if (languageSpecificPrimitives.contains(sanName)) {
+ String modelName = camelize("model_" + sanName);
+ LOGGER.warn(sanName + " (model name matches existing language type) cannot be used as a model name. Renamed to " + modelName);
return modelName;
}
// camelize the model name
// phone_number => PhoneNumber
- return camelize(name);
+ return camelize(sanName);
}
@Override
@@ -549,8 +552,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override
public String toEnumName(CodegenProperty property) {
- String enumName = toModelName(property.name) + "Enum";
-
+ String enumName = toModelName(property.name) + enumSuffix;
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
@@ -569,14 +571,14 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
// name enum with model name, e.g. StatusEnum => Pet.StatusEnum
for (CodegenProperty var : cm.vars) {
if (Boolean.TRUE.equals(var.isEnum)) {
- var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + "." + var.enumName);
+ var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + classEnumSeparator + var.enumName);
}
}
if (cm.parent != null) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum
- .replace(var.enumName, cm.classname + "." + var.enumName);
+ .replace(var.enumName, cm.classname + classEnumSeparator + var.enumName);
}
}
}
@@ -696,4 +698,14 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
}
}
}
+
+ @Override
+ public String toAnyOfName(List names, ComposedSchema composedSchema) {
+ return String.join(" | ", names);
+ }
+
+ @Override
+ public String toOneOfName(List names, ComposedSchema composedSchema) {
+ return String.join(" | ", names);
+ }
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java
index ae3ed7e12da..a1d0889b25c 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AspNetCoreServerCodegen.java
@@ -22,6 +22,7 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.*;
+import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -326,6 +327,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
supportingFiles.add(new SupportingFile("Solution.mustache", "", packageName + ".sln"));
supportingFiles.add(new SupportingFile("gitignore", packageFolder, ".gitignore"));
supportingFiles.add(new SupportingFile("validateModel.mustache", packageFolder + File.separator + "Attributes", "ValidateModelStateAttribute.cs"));
+ supportingFiles.add(new SupportingFile("typeConverter.mustache", packageFolder + File.separator + "Converters", "CustomEnumConverter.cs"));
supportingFiles.add(new SupportingFile("Project.csproj.mustache", packageFolder, packageName + ".csproj"));
if (!isLibrary) {
supportingFiles.add(new SupportingFile("Dockerfile.mustache", packageFolder, "Dockerfile"));
@@ -353,7 +355,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
supportingFiles.add(new SupportingFile("Filters" + File.separator + "GeneratePathParamsValidationFilter.mustache",
packageFolder + File.separator + "Filters", "GeneratePathParamsValidationFilter.cs"));
}
-
+
supportingFiles.add(new SupportingFile("Authentication" + File.separator + "ApiAuthentication.mustache",packageFolder + File.separator + "Authentication", "ApiAuthentication.cs"));
}
@@ -407,12 +409,12 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
@Override
public String getNullableType(Schema p, String type) {
- boolean isNullableExpected = p.getNullable() == null || (p.getNullable() != null && p.getNullable());
-
- if (isNullableExpected && languageSpecificPrimitives.contains(type + "?")) {
- return type + "?";
- } else if (languageSpecificPrimitives.contains(type)) {
- return type;
+ if (languageSpecificPrimitives.contains(type)) {
+ if (isSupportNullable() && ModelUtils.isNullable(p) && nullableType.contains(type)) {
+ return type + "?";
+ } else {
+ return type;
+ }
} else {
return null;
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
index 8ef2fde34a2..6617dbe14cd 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
@@ -879,15 +879,15 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
return null;
}
}
-
+
@Override
public String getNullableType(Schema p, String type) {
- boolean isNullableExpected = p.getNullable() == null || (p.getNullable() != null && p.getNullable());
-
- if (isNullableExpected && languageSpecificPrimitives.contains(type + "?")) {
- return type + "?";
- } else if (languageSpecificPrimitives.contains(type)) {
- return type;
+ if (languageSpecificPrimitives.contains(type)) {
+ if (isSupportNullable() && ModelUtils.isNullable(p) && nullableType.contains(type)) {
+ return type + "?";
+ } else {
+ return type;
+ }
} else {
return null;
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppRestSdkClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppRestSdkClientCodegen.java
index aabac7f7a38..ddfdcbb0e0b 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppRestSdkClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppRestSdkClientCodegen.java
@@ -359,7 +359,10 @@ public class CppRestSdkClientCodegen extends AbstractCppCodegen {
return "new " + toModelName(ModelUtils.getSimpleRef(p.get$ref())) + "()";
} else if (ModelUtils.isStringSchema(p)) {
return "utility::conversions::to_string_t(\"\")";
+ } else if (ModelUtils.isFreeFormObject(p)) {
+ return "new Object()";
}
+
return "nullptr";
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSExpressServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSExpressServerCodegen.java
new file mode 100644
index 00000000000..14f305f654c
--- /dev/null
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSExpressServerCodegen.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openapitools.codegen.languages;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.PathItem.HttpMethod;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.info.Info;
+import org.openapitools.codegen.*;
+import org.openapitools.codegen.meta.GeneratorMetadata;
+import org.openapitools.codegen.meta.Stability;
+import org.openapitools.codegen.utils.URLPathUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.net.URL;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+
+import static org.openapitools.codegen.utils.StringUtils.*;
+
+public class NodeJSExpressServerCodegen extends DefaultCodegen implements CodegenConfig {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NodeJSExpressServerCodegen.class);
+ public static final String EXPORTED_NAME = "exportedName";
+ public static final String SERVER_PORT = "serverPort";
+
+ protected String apiVersion = "1.0.0";
+ protected String defaultServerPort = "8080";
+ protected String implFolder = "services";
+ protected String projectName = "openapi-server";
+ protected String exportedName;
+
+ public NodeJSExpressServerCodegen() {
+ super();
+
+ generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
+ .stability(Stability.BETA)
+ .build();
+
+ outputFolder = "generated-code/nodejs-express-server";
+ embeddedTemplateDir = templateDir = "nodejs-express-server";
+
+ setReservedWordsLowerCase(
+ Arrays.asList(
+ "break", "case", "class", "catch", "const", "continue", "debugger",
+ "default", "delete", "do", "else", "export", "extends", "finally",
+ "for", "function", "if", "import", "in", "instanceof", "let", "new",
+ "return", "super", "switch", "this", "throw", "try", "typeof", "var",
+ "void", "while", "with", "yield")
+ );
+
+ additionalProperties.put("apiVersion", apiVersion);
+ additionalProperties.put("implFolder", implFolder);
+
+ // no model file
+ modelTemplateFiles.clear();
+
+ apiTemplateFiles.put("controller.mustache", ".js");
+ apiTemplateFiles.put("service.mustache", ".js");
+
+ supportingFiles.add(new SupportingFile("openapi.mustache", "api", "openapi.yaml"));
+ supportingFiles.add(new SupportingFile("config.mustache", "", "config.js"));
+ supportingFiles.add(new SupportingFile("expressServer.mustache", "", "expressServer.js"));
+ supportingFiles.add(new SupportingFile("index.mustache", "", "index.js"));
+ supportingFiles.add(new SupportingFile("logger.mustache", "", "logger.js"));
+ supportingFiles.add(new SupportingFile("eslintrc.mustache", "", ".eslintrc.json"));
+
+ // utils folder
+ supportingFiles.add(new SupportingFile("utils" + File.separator + "openapiRouter.mustache", "utils", "openapiRouter.js"));
+
+ // controllers folder
+ supportingFiles.add(new SupportingFile("controllers" + File.separator + "index.mustache", "controllers", "index.js"));
+ supportingFiles.add(new SupportingFile("controllers" + File.separator + "Controller.mustache", "controllers", "Controller.js"));
+ // service folder
+ supportingFiles.add(new SupportingFile("services" + File.separator + "index.mustache", "services", "index.js"));
+ supportingFiles.add(new SupportingFile("services" + File.separator + "Service.mustache", "services", "Service.js"));
+
+ // do not overwrite if the file is already present
+ writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
+ writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
+
+ cliOptions.add(new CliOption(SERVER_PORT,
+ "TCP port to listen on."));
+ }
+
+ @Override
+ public String apiPackage() {
+ return "controllers";
+ }
+
+ /**
+ * Configures the type of generator.
+ *
+ * @return the CodegenType for this generator
+ * @see org.openapitools.codegen.CodegenType
+ */
+ @Override
+ public CodegenType getTag() {
+ return CodegenType.SERVER;
+ }
+
+ /**
+ * Configures a friendly name for the generator. This will be used by the generator
+ * to select the library with the -g flag.
+ *
+ * @return the friendly name for the generator
+ */
+ @Override
+ public String getName() {
+ return "nodejs-express-server";
+ }
+
+ /**
+ * Returns human-friendly help for the generator. Provide the consumer with help
+ * tips, parameters here
+ *
+ * @return A string value for the help message
+ */
+ @Override
+ public String getHelp() {
+ return "Generates a NodeJS Express server (alpha). IMPORTANT: this generator may subject to breaking changes without further notice).";
+ }
+
+ @Override
+ public String toApiName(String name) {
+ if (name.length() == 0) {
+ return "Default";
+ }
+ return camelize(name);
+ }
+
+ @Override
+ public String toApiFilename(String name) {
+ return toApiName(name) + "Controller";
+ }
+
+ @Override
+ public String apiFilename(String templateName, String tag) {
+ String result = super.apiFilename(templateName, tag);
+
+ if (templateName.equals("service.mustache")) {
+ String stringToMatch = File.separator + "controllers" + File.separator;
+ String replacement = File.separator + implFolder + File.separator;
+ result = result.replaceAll(Pattern.quote(stringToMatch), replacement);
+
+ stringToMatch = "Controller.js";
+ replacement = "Service.js";
+ result = result.replaceAll(Pattern.quote(stringToMatch), replacement);
+ }
+ return result;
+ }
+
+/*
+ @Override
+ protected String implFileFolder(String output) {
+ return outputFolder + File.separator + output + File.separator + apiPackage().replace('.', File.separatorChar);
+ }
+*/
+
+ /**
+ * Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
+ * those terms here. This logic is only called if a variable matches the reserved words
+ *
+ * @return the escaped term
+ */
+ @Override
+ public String escapeReservedWord(String name) {
+ if (this.reservedWordsMappings().containsKey(name)) {
+ return this.reservedWordsMappings().get(name);
+ }
+ return "_" + name;
+ }
+
+ /**
+ * Location to write api files. You can use the apiPackage() as defined when the class is
+ * instantiated
+ */
+ @Override
+ public String apiFileFolder() {
+ return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
+ }
+
+ public String getExportedName() {
+ return exportedName;
+ }
+
+ public void setExportedName(String name) {
+ exportedName = name;
+ }
+
+ @Override
+ public Map postProcessOperationsWithModels(Map objs, List allModels) {
+ @SuppressWarnings("unchecked")
+ Map objectMap = (Map) objs.get("operations");
+ @SuppressWarnings("unchecked")
+ List operations = (List) objectMap.get("operation");
+ for (CodegenOperation operation : operations) {
+ operation.httpMethod = operation.httpMethod.toLowerCase(Locale.ROOT);
+
+ List params = operation.allParams;
+ if (params != null && params.size() == 0) {
+ operation.allParams = null;
+ }
+ List responses = operation.responses;
+ if (responses != null) {
+ for (CodegenResponse resp : responses) {
+ if ("0".equals(resp.code)) {
+ resp.code = "default";
+ }
+ }
+ }
+ if (operation.examples != null && !operation.examples.isEmpty()) {
+ // Leave application/json* items only
+ for (Iterator> it = operation.examples.iterator(); it.hasNext(); ) {
+ final Map example = it.next();
+ final String contentType = example.get("contentType");
+ if (contentType == null || !contentType.startsWith("application/json")) {
+ it.remove();
+ }
+ }
+ }
+ }
+ return objs;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List> getOperations(Map objs) {
+ List> result = new ArrayList>();
+ Map apiInfo = (Map) objs.get("apiInfo");
+ List> apis = (List>) apiInfo.get("apis");
+ for (Map api : apis) {
+ result.add((Map) api.get("operations"));
+ }
+ return result;
+ }
+
+ private static List> sortOperationsByPath(List ops) {
+ Multimap opsByPath = ArrayListMultimap.create();
+
+ for (CodegenOperation op : ops) {
+ opsByPath.put(op.path, op);
+ }
+
+ List> opsByPathList = new ArrayList>();
+ for (Entry> entry : opsByPath.asMap().entrySet()) {
+ Map opsByPathEntry = new HashMap();
+ opsByPathList.add(opsByPathEntry);
+ opsByPathEntry.put("path", entry.getKey());
+ opsByPathEntry.put("operation", entry.getValue());
+ List operationsForThisPath = Lists.newArrayList(entry.getValue());
+ operationsForThisPath.get(operationsForThisPath.size() - 1).hasMore = false;
+ if (opsByPathList.size() < opsByPath.asMap().size()) {
+ opsByPathEntry.put("hasMore", "true");
+ }
+ }
+
+ return opsByPathList;
+ }
+
+ @Override
+ public void processOpts() {
+ super.processOpts();
+
+ if (additionalProperties.containsKey(EXPORTED_NAME)) {
+ setExportedName((String) additionalProperties.get(EXPORTED_NAME));
+ }
+
+ /*
+ * Supporting Files. You can write single files for the generator with the
+ * entire object tree available. If the input file has a suffix of `.mustache
+ * it will be processed by the template engine. Otherwise, it will be copied
+ */
+ // supportingFiles.add(new SupportingFile("controller.mustache",
+ // "controllers",
+ // "controller.js")
+ // );
+ }
+
+ @Override
+ public void preprocessOpenAPI(OpenAPI openAPI) {
+ URL url = URLPathUtils.getServerURL(openAPI);
+ String host = URLPathUtils.getProtocolAndHost(url);
+ String port = URLPathUtils.getPort(url, defaultServerPort) ;
+ String basePath = url.getPath();
+
+ if (additionalProperties.containsKey(SERVER_PORT)) {
+ port = additionalProperties.get(SERVER_PORT).toString();
+ }
+ this.additionalProperties.put(SERVER_PORT, port);
+
+ if (openAPI.getInfo() != null) {
+ Info info = openAPI.getInfo();
+ if (info.getTitle() != null) {
+ // when info.title is defined, use it for projectName
+ // used in package.json
+ projectName = info.getTitle()
+ .replaceAll("[^a-zA-Z0-9]", "-")
+ .replaceAll("^[-]*", "")
+ .replaceAll("[-]*$", "")
+ .replaceAll("[-]{2,}", "-")
+ .toLowerCase(Locale.ROOT);
+ this.additionalProperties.put("projectName", projectName);
+ }
+ }
+
+ // need vendor extensions
+ Paths paths = openAPI.getPaths();
+ if (paths != null) {
+ for (String pathname : paths.keySet()) {
+ PathItem path = paths.get(pathname);
+ Map operationMap = path.readOperationsMap();
+ if (operationMap != null) {
+ for (HttpMethod method : operationMap.keySet()) {
+ Operation operation = operationMap.get(method);
+ String tag = "default";
+ if (operation.getTags() != null && operation.getTags().size() > 0) {
+ tag = toApiName(operation.getTags().get(0));
+ }
+ if (operation.getOperationId() == null) {
+ operation.setOperationId(getOrGenerateOperationId(operation, pathname, method.toString()));
+ }
+ // add x-openapi-router-controller
+ if (operation.getExtensions() == null ||
+ operation.getExtensions().get("x-openapi-router-controller") == null) {
+ operation.addExtension("x-openapi-router-controller", sanitizeTag(tag) + "Controller");
+ }
+ // add x-openapi-router-service
+ if (operation.getExtensions() == null ||
+ operation.getExtensions().get("x-openapi-router-service") == null) {
+ operation.addExtension("x-openapi-router-service", sanitizeTag(tag) + "Service");
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public Map postProcessSupportingFileData(Map objs) {
+ generateYAMLSpecFile(objs);
+
+ for (Map operations : getOperations(objs)) {
+ @SuppressWarnings("unchecked")
+ List ops = (List) operations.get("operation");
+
+ List> opsByPathList = sortOperationsByPath(ops);
+ operations.put("operationsByPath", opsByPathList);
+ }
+ return super.postProcessSupportingFileData(objs);
+ }
+
+ @Override
+ public String removeNonNameElementToCamelCase(String name) {
+ return removeNonNameElementToCamelCase(name, "[-:;#]");
+ }
+
+ @Override
+ public String escapeUnsafeCharacters(String input) {
+ return input.replace("*/", "*_/").replace("/*", "/_*");
+ }
+
+ @Override
+ public String escapeQuotationMark(String input) {
+ // remove " to avoid code injection
+ return input.replace("\"", "");
+ }
+}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OCamlClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OCamlClientCodegen.java
new file mode 100644
index 00000000000..feffa95ddd1
--- /dev/null
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OCamlClientCodegen.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openapitools.codegen.languages;
+
+import com.google.common.base.Strings;
+import io.swagger.v3.oas.models.*;
+import io.swagger.v3.oas.models.headers.Header;
+import io.swagger.v3.oas.models.media.*;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openapitools.codegen.*;
+import org.openapitools.codegen.utils.ModelUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.apache.commons.lang3.StringUtils.capitalize;
+import static org.openapitools.codegen.utils.StringUtils.camelize;
+import static org.openapitools.codegen.utils.StringUtils.escape;
+import static org.openapitools.codegen.utils.StringUtils.underscore;
+
+public class OCamlClientCodegen extends DefaultCodegen implements CodegenConfig {
+ private static final Logger LOGGER = LoggerFactory.getLogger(OCamlClientCodegen.class);
+ public static final String PACKAGE_NAME = "packageName";
+ public static final String PACKAGE_VERSION = "packageVersion";
+
+ static final String X_MODEL_MODULE = "x-modelModule";
+
+ public static final String CO_HTTP = "cohttp";
+
+ protected String packageName = "openapi";
+ protected String packageVersion = "1.0.0";
+ protected String apiDocPath = "docs/";
+ protected String modelDocPath = "docs/";
+ protected String apiFolder = "src/apis";
+ protected String modelFolder = "src/models";
+
+ private Map> enumNames = new HashMap<>();
+ private Map enumHash = new HashMap<>();
+ private Map enumUniqNames;
+
+ public CodegenType getTag() {
+ return CodegenType.CLIENT;
+ }
+
+ public String getName() {
+ return "ocaml";
+ }
+
+ public String getHelp() {
+ return "Generates an OCaml client library (beta).";
+ }
+
+ public OCamlClientCodegen() {
+ super();
+ outputFolder = "generated-code/ocaml";
+ modelTemplateFiles.put("model.mustache", ".ml");
+
+ // default HIDE_GENERATION_TIMESTAMP to true
+ hideGenerationTimestamp = Boolean.TRUE;
+
+ embeddedTemplateDir = templateDir = "ocaml";
+
+ setReservedWordsLowerCase(
+ Arrays.asList(
+ "and", "as", "assert", "asr", "begin", "class",
+ "constraint", "do", "done", "downto", "else", "end",
+ "exception", "external", "false", "for ", "fun", "function",
+ "functor", "if", "in", "include", "inherit", "initializer",
+ "land", "lazy", "let", "lor", "lsl", "lsr",
+ "lxor", "match", "method", "mod", "module", "mutable",
+ "new", "nonrec", "object", "of", "open", "or",
+ "private", "rec", "sig", "struct", "then", "to",
+ "true", "try", "type", "val", "virtual", "when",
+ "while", "with",
+
+ "result"
+ )
+ );
+
+ importMapping.remove("File");
+
+ supportingFiles.add(new SupportingFile("dune.mustache", "", "dune"));
+ supportingFiles.add(new SupportingFile("dune-project.mustache", "", "dune-project"));
+ supportingFiles.add(new SupportingFile("readme.mustache", "", "README.md"));
+
+ defaultIncludes = new HashSet<>(
+ Arrays.asList(
+ "int",
+ "int32",
+ "int64",
+ "float",
+ "bool",
+ "char",
+ "string",
+ "list"
+ )
+ );
+
+ languageSpecificPrimitives = new HashSet<>(
+ Arrays.asList(
+ "int",
+ "int32",
+ "int64",
+ "float",
+ "bool",
+ "char",
+ "string",
+ "bytes",
+ "list",
+ "Yojson.Safe.t"
+ )
+ );
+
+ instantiationTypes.clear();
+
+ typeMapping.clear();
+ typeMapping.put("boolean", "bool");
+ typeMapping.put("int", "int32");
+ typeMapping.put("long", "int64");
+ typeMapping.put("short", "int");
+ typeMapping.put("char", "char");
+ typeMapping.put("float", "float");
+ typeMapping.put("double", "float");
+ typeMapping.put("integer", "int32");
+ typeMapping.put("number", "float");
+ typeMapping.put("date", "string");
+ typeMapping.put("object", "Yojson.Safe.t");
+ typeMapping.put("any", "Yojson.Safe.t");
+ typeMapping.put("file", "string");
+ typeMapping.put("ByteArray", "string");
+ // lib
+ typeMapping.put("string", "string");
+ typeMapping.put("UUID", "string");
+ typeMapping.put("URI", "string");
+ typeMapping.put("set", "`Set");
+ typeMapping.put("passsword", "string");
+ typeMapping.put("DateTime", "string");
+
+// supportedLibraries.put(CO_HTTP, "HTTP client: CoHttp.");
+//
+// CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use.");
+// libraryOption.setEnum(supportedLibraries);
+// // set hyper as the default
+// libraryOption.setDefault(CO_HTTP);
+// cliOptions.add(libraryOption);
+// setLibrary(CO_HTTP);
+ }
+
+ @Override
+ public Map postProcessAllModels(Map superobjs) {
+ List toRemove = new ArrayList<>();
+
+ for (Map.Entry modelEntry : superobjs.entrySet()) {
+ Map objs = (Map) modelEntry.getValue();
+ // process enum in models
+ List models = (List) objs.get("models");
+ for (Object _mo : models) {
+ Map mo = (Map) _mo;
+ CodegenModel cm = (CodegenModel) mo.get("model");
+
+ // for enum model
+ if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) {
+ toRemove.add(modelEntry.getKey());
+ } else {
+ enrichPropertiesWithEnumDefaultValues(cm.getAllVars());
+ enrichPropertiesWithEnumDefaultValues(cm.getReadOnlyVars());
+ enrichPropertiesWithEnumDefaultValues(cm.getReadWriteVars());
+ enrichPropertiesWithEnumDefaultValues(cm.getRequiredVars());
+ enrichPropertiesWithEnumDefaultValues(cm.getOptionalVars());
+ enrichPropertiesWithEnumDefaultValues(cm.getVars());
+ enrichPropertiesWithEnumDefaultValues(cm.getParentVars());
+ }
+ }
+ }
+
+ for (String keyToRemove : toRemove) {
+ superobjs.remove(keyToRemove);
+ }
+
+ return superobjs;
+
+ }
+
+ private void enrichPropertiesWithEnumDefaultValues(List properties) {
+ for (CodegenProperty property : properties) {
+ if (property.get_enum() != null && property.get_enum().size() == 1) {
+ String value = property.get_enum().get(0);
+ property.defaultValue = ocamlizeEnumValue(value);
+ }
+ }
+ }
+
+ @Override
+ protected void updateDataTypeWithEnumForMap(CodegenProperty property) {
+ CodegenProperty baseItem = property.items;
+ while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMapContainer)
+ || Boolean.TRUE.equals(baseItem.isListContainer))) {
+ baseItem = baseItem.items;
+ }
+
+ if (baseItem != null) {
+ // set default value for variable with inner enum
+ if (property.defaultValue != null) {
+ property.defaultValue = property.defaultValue.replace(", " + property.items.baseType, ", " + toEnumName(property.items));
+ }
+
+ updateCodegenPropertyEnum(property);
+ }
+ }
+
+ @Override
+ protected void updateDataTypeWithEnumForArray(CodegenProperty property) {
+ CodegenProperty baseItem = property.items;
+ while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMapContainer)
+ || Boolean.TRUE.equals(baseItem.isListContainer))) {
+ baseItem = baseItem.items;
+ }
+ if (baseItem != null) {
+ // set default value for variable with inner enum
+ if (property.defaultValue != null) {
+ property.defaultValue = property.defaultValue.replace(baseItem.baseType, toEnumName(baseItem));
+ }
+
+ updateCodegenPropertyEnum(property);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private String hashEnum(Schema schema) {
+ return ((List) schema.getEnum()).stream().map(String::valueOf).collect(Collectors.joining(","));
+ }
+
+ private boolean isEnumSchema(Schema schema) {
+ return schema != null && schema.getEnum() != null && !schema.getEnum().isEmpty();
+ }
+
+ private void collectEnumSchemas(String parentName, String sName, Schema schema) {
+ if (schema instanceof ArraySchema) {
+ collectEnumSchemas(parentName, sName, ((ArraySchema) schema).getItems());
+ } else if (schema instanceof MapSchema && schema.getAdditionalProperties() instanceof Schema) {
+ collectEnumSchemas(parentName, sName, (Schema) schema.getAdditionalProperties());
+ } else if (isEnumSchema(schema)) {
+ String h = hashEnum(schema);
+ if (!enumHash.containsKey(h)) {
+ enumHash.put(h, schema);
+ enumNames.computeIfAbsent(h, k -> new ArrayList<>()).add(sName.toLowerCase(Locale.ROOT));
+ if (parentName != null) {
+ enumNames.get(h).add((parentName + "_" + sName).toLowerCase(Locale.ROOT));
+ }
+ }
+ }
+ }
+
+ private void collectEnumSchemas(String sName, Schema schema) {
+ collectEnumSchemas(null, sName, schema);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void collectEnumSchemas(String parentName, Map schemas) {
+ for (String sName : schemas.keySet()) {
+ Schema schema = schemas.get(sName);
+
+ collectEnumSchemas(parentName, sName, schema);
+
+ if (schema.getProperties() != null) {
+ String pName = parentName != null ? parentName + "_" + sName : sName;
+ collectEnumSchemas(pName, schema.getProperties());
+ }
+
+ if (schema.getAdditionalProperties() != null && schema.getAdditionalProperties() instanceof Schema) {
+ String pName = parentName != null ? parentName + "_" + sName : sName;
+ collectEnumSchemas(pName, (Schema) schema.getAdditionalProperties());
+ }
+
+ if (schema instanceof ArraySchema) {
+ ArraySchema s = (ArraySchema) schema;
+ if (s.getItems() != null) {
+ String pName = parentName != null ? parentName + "_" + sName : sName;
+ collectEnumSchemas(pName, s.getItems());
+ }
+ }
+ }
+ }
+
+ private void collectEnumSchemas(Operation operation) {
+ if (operation != null) {
+ if (operation.getParameters() != null) {
+ for (Parameter parameter : operation.getParameters()) {
+ collectEnumSchemas(parameter.getName(), parameter.getSchema());
+ }
+ }
+ if (operation.getRequestBody() != null && operation.getRequestBody().getContent() != null) {
+ Content content = operation.getRequestBody().getContent();
+ for (String p : content.keySet()) {
+ collectEnumSchemas(p, content.get(p).getSchema());
+ }
+ }
+ if (operation.getResponses() != null) {
+ for (String s : operation.getResponses().keySet()) {
+ ApiResponse apiResponse = operation.getResponses().get(s);
+ if (apiResponse.getContent() != null) {
+ Content content = apiResponse.getContent();
+ for (String p : content.keySet()) {
+ collectEnumSchemas(p, content.get(p).getSchema());
+ }
+ }
+ if (apiResponse.getHeaders() != null) {
+ Map headers = apiResponse.getHeaders();
+ for (String h : headers.keySet()) {
+ Header header = headers.get(h);
+ collectEnumSchemas(h, header.getSchema());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private String sanitizeOCamlTypeName(String name) {
+ String typeName = name.replace("-", "_").replace(" ", "_").trim();
+ int i = 0;
+ char c;
+ while (i < typeName.length() && (Character.isDigit(c = typeName.charAt(i)) || c == '_')) {
+ i++;
+ }
+
+ return typeName.substring(i);
+ }
+
+ private void computeEnumUniqNames() {
+ Map definitiveNames = new HashMap<>();
+ for (String h : enumNames.keySet()) {
+ boolean hasDefName = false;
+ List nameCandidates = enumNames.get(h);
+ for (String name : nameCandidates) {
+ String candidate = sanitizeOCamlTypeName(name);
+ if (!definitiveNames.containsKey(candidate) && !reservedWords.contains(candidate)) {
+ definitiveNames.put(candidate, h);
+ hasDefName = true;
+ break;
+ }
+ }
+ if (!hasDefName) {
+ int i = 0;
+ String candidate;
+ while (definitiveNames.containsKey(candidate = sanitizeOCamlTypeName(nameCandidates.get(0) + "_" + i))) {
+ i++;
+ }
+ definitiveNames.put(candidate, h);
+ }
+ }
+
+ enumUniqNames = definitiveNames.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
+ }
+
+ private void collectEnumSchemas(OpenAPI openAPI) {
+ Components components = openAPI.getComponents();
+ if (components != null && components.getSchemas() != null && !components.getSchemas().isEmpty()) {
+ collectEnumSchemas(null, components.getSchemas());
+ }
+
+ Paths paths = openAPI.getPaths();
+ if (paths != null && !paths.isEmpty()) {
+ for (String path : paths.keySet()) {
+ PathItem item = paths.get(path);
+ collectEnumSchemas(item.getGet());
+ collectEnumSchemas(item.getPost());
+ collectEnumSchemas(item.getPut());
+ collectEnumSchemas(item.getDelete());
+ collectEnumSchemas(item.getPatch());
+ collectEnumSchemas(item.getOptions());
+ collectEnumSchemas(item.getHead());
+ collectEnumSchemas(item.getTrace());
+ }
+ }
+
+ computeEnumUniqNames();
+ }
+
+ @Override
+ public void preprocessOpenAPI(OpenAPI openAPI) {
+ collectEnumSchemas(openAPI);
+
+ supportingFiles.add(new SupportingFile("lib.mustache", "", packageName + ".opam"));
+ supportingFiles.add(new SupportingFile("support.mustache", "src/support", "request.ml"));
+ supportingFiles.add(new SupportingFile("json.mustache", "src/support", "jsonSupport.ml"));
+ supportingFiles.add(new SupportingFile("enums.mustache", "src/support", "enums.ml"));
+ }
+
+ @Override
+ public void processOpts() {
+ super.processOpts();
+
+ if (StringUtils.isEmpty(System.getenv("OCAML_POST_PROCESS_FILE"))) {
+ LOGGER.info("Hint: Environment variable 'OCAML_POST_PROCESS_FILE' (optional) not defined. E.g. to format the source code, please try 'export OCAML_POST_PROCESS_FILE=\"ocamlformat -i --enable-outside-detected-project\"' (Linux/Mac)");
+ LOGGER.info("Note: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
+ } else if (!this.isEnablePostProcessFile()) {
+ LOGGER.info("Warning: Environment variable 'OCAML_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
+ }
+
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
+ setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
+ } else {
+ setPackageName("openapi");
+ }
+
+ if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
+ setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
+ } else {
+ setPackageVersion("1.0.0");
+ }
+
+ additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
+ additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
+
+ additionalProperties.put("apiDocPath", apiDocPath);
+ additionalProperties.put("modelDocPath", modelDocPath);
+
+ apiTemplateFiles.put("api-impl.mustache", ".ml");
+ apiTemplateFiles.put("api-intf.mustache", ".mli");
+
+ modelPackage = packageName;
+ apiPackage = packageName;
+ }
+
+ @Override
+ public String escapeReservedWord(String name) {
+ if (this.reservedWordsMappings().containsKey(name)) {
+ return this.reservedWordsMappings().get(name);
+ }
+ return '_' + name;
+ }
+
+ @Override
+ public String apiFileFolder() {
+ return (outputFolder + File.separator + apiFolder).replace("/", File.separator);
+ }
+
+ @Override
+ public String modelFileFolder() {
+ return (outputFolder + File.separator + modelFolder).replace("/", File.separator);
+ }
+
+ @Override
+ public String toVarName(String name) {
+ // replace - with _ e.g. created-at => created_at
+ name = sanitizeName(name.replaceAll("-", "_"));
+
+ // snake_case, e.g. PetId => pet_id
+ name = underscore(name);
+
+ // for reserved word or word starting with number, append _
+ if (isReservedWord(name))
+ name = escapeReservedWord(name);
+
+ // for reserved word or word starting with number, append _
+ if (name.matches("^\\d.*"))
+ name = "var_" + name;
+
+ return name;
+ }
+
+ @Override
+ public String toParamName(String name) {
+ return toVarName(name);
+ }
+
+ @Override
+ public String toModelName(String name) {
+ // camelize the model name
+ // phone_number => PhoneNumber
+ return capitalize(toModelFilename(name)) + ".t";
+ }
+
+ @Override
+ public String toModelFilename(String name) {
+
+ if (!Strings.isNullOrEmpty(modelNamePrefix)) {
+ name = modelNamePrefix + "_" + name;
+ }
+
+ if (!Strings.isNullOrEmpty(modelNameSuffix)) {
+ name = name + "_" + modelNameSuffix;
+ }
+
+ name = sanitizeName(name);
+
+ // model name cannot use reserved keyword, e.g. return
+ if (isReservedWord(name)) {
+ LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + ("model_" + name));
+ name = "model_" + name; // e.g. return => ModelReturn (after camelize)
+ }
+
+ // model name starts with number or _
+ if (name.matches("^\\d.*|^_.*")) {
+ LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + ("model_" + name));
+ name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
+ }
+
+ return underscore(name);
+ }
+
+ @Override
+ public String toApiFilename(final String name) {
+ // replace - with _ e.g. created-at => created_at
+ final String _name = name.replaceAll("-", "_");
+
+ // e.g. PetApi.ml => pet_api.ml
+ return underscore(_name) + "_api";
+ }
+
+ @Override
+ public String apiDocFileFolder() {
+ return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
+ }
+
+ @Override
+ public String modelDocFileFolder() {
+ return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar);
+ }
+
+ @Override
+ public String toModelDocFilename(String name) {
+ return toModelName(name);
+ }
+
+ @Override
+ public String toApiDocFilename(String name) {
+ return toApiName(name);
+ }
+
+ @Override
+ public String getTypeDeclaration(Schema p) {
+ if (ModelUtils.isArraySchema(p)) {
+ ArraySchema ap = (ArraySchema) p;
+ Schema inner = ap.getItems();
+ if (inner == null) {
+ LOGGER.warn(ap.getName() + "(array property) does not have a proper inner type defined.Default to string");
+ inner = new StringSchema().description("TODO default missing array inner type to string");
+ }
+ return getTypeDeclaration(inner) + " list";
+ } else if (ModelUtils.isMapSchema(p)) {
+ Schema inner = ModelUtils.getAdditionalProperties(p);
+ if (inner == null) {
+ LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined. Default to string");
+ inner = new StringSchema().description("TODO default missing map inner type to string");
+ }
+ String prefix = inner.getEnum() != null ? "Enums." : "";
+ return "(string * " + prefix + getTypeDeclaration(inner) + ") list";
+ } else if (p.getEnum() != null) {
+ String h = hashEnum(p);
+ return enumUniqNames.get(h);
+ }
+
+ Schema referencedSchema = ModelUtils.getReferencedSchema(openAPI, p);
+ if (referencedSchema != null && referencedSchema.getEnum() != null) {
+ String h = hashEnum(referencedSchema);
+ return "Enums." + enumUniqNames.get(h);
+ }
+
+ // Not using the supertype invocation, because we want to UpperCamelize
+ // the type.
+ String schemaType = getSchemaType(p);
+ if (typeMapping.containsKey(schemaType)) {
+ return typeMapping.get(schemaType);
+ }
+
+ if (typeMapping.containsValue(schemaType)) {
+ return schemaType;
+ }
+
+ if (languageSpecificPrimitives.contains(schemaType)) {
+ return schemaType;
+ }
+
+ return toModelName(schemaType);
+ }
+
+ @Override
+ public String getSchemaType(Schema p) {
+ String schemaType = super.getSchemaType(p);
+ if (typeMapping.containsKey(schemaType)) {
+ String type = typeMapping.get(schemaType);
+ if (languageSpecificPrimitives.contains(type)) {
+ return type;
+ }
+ }
+ return capitalize(toModelFilename(schemaType));
+ }
+
+ @Override
+ public String toOperationId(String operationId) {
+ String sanitizedOperationId = sanitizeName(operationId);
+
+ // method name cannot use reserved keyword, e.g. return
+ if (isReservedWord(sanitizedOperationId) || sanitizedOperationId.matches("^[0-9].*")) {
+ LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + underscore("call_" + operationId));
+ sanitizedOperationId = "call_" + sanitizedOperationId;
+ }
+
+ return underscore(sanitizedOperationId);
+ }
+
+ private Map allowableValues(String valueString) {
+ Map result = new HashMap<>();
+ result.put("values", buildEnumValues(valueString));
+ return result;
+ }
+
+ private List> buildEnumValues(String valueString) {
+ List> result = new ArrayList<>();
+
+ for (String v : valueString.split(",")) {
+ Map m = new HashMap<>();
+ String value = v.isEmpty() ? "empty" : v;
+ m.put("name", value);
+ m.put("camlEnumValueName", ocamlizeEnumValue(value));
+ result.add(m);
+ }
+
+ return result;
+ }
+
+ public String toEnumValueName(String name) {
+ if (reservedWords.contains(name)) {
+ return escapeReservedWord(name);
+ } else if (((CharSequence) name).chars().anyMatch(character -> specialCharReplacements.keySet().contains("" + ((char) character)))) {
+ return escape(name, specialCharReplacements, Collections.singletonList("_"), null);
+ } else {
+ return name;
+ }
+ }
+
+ private String ocamlizeEnumValue(String value) {
+ String sanitizedValue =
+ toEnumValueName(value.isEmpty() ? "empty" : value)
+ .replace(" ", "_");
+
+ if (!sanitizedValue.matches("^[a-zA-Z_].*")) {
+ sanitizedValue = "_" + sanitizedValue;
+ }
+ return "`" + capitalize(sanitizedValue);
+ }
+
+ private CodegenModel buildEnumModel(String enumName, String values) {
+ CodegenModel m = new CodegenModel();
+ m.setAllowableValues(allowableValues(values));
+ m.setName(enumName);
+ m.setClassname(enumName);
+ m.setDataType(enumName);
+ String[] vals = values.split(",");
+ if (vals.length == 1) {
+ m.setDefaultValue(ocamlizeEnumValue(vals[0]));
+ }
+ m.isEnum = true;
+
+ return m;
+ }
+
+ private Map buildEnumModelWrapper(String enumName, String values) {
+ Map m = new HashMap<>();
+ m.put("importPath", packageName + "." + enumName);
+ m.put("model", buildEnumModel(enumName, values));
+ return m;
+ }
+
+ @Override
+ public Map postProcessOperationsWithModels(Map objs, List allModels) {
+ @SuppressWarnings("unchecked")
+ Map objectMap = (Map) objs.get("operations");
+ @SuppressWarnings("unchecked")
+ List operations = (List) objectMap.get("operation");
+ for (CodegenOperation operation : operations) {
+ // http method verb conversion, depending on client library (e.g. Hyper: PUT => Put, Reqwest: PUT => put)
+ //if (CO_HTTP.equals(getLibrary())) {
+ for (CodegenParameter param : operation.bodyParams) {
+ if (param.isModel && param.dataType.endsWith(".t")) {
+ param.vendorExtensions.put(X_MODEL_MODULE, param.dataType.substring(0, param.dataType.lastIndexOf('.')));
+ }
+ }
+
+ if ("Yojson.Safe.t".equals(operation.returnBaseType)) {
+ operation.vendorExtensions.put("x-returnFreeFormObject", true);
+ }
+ }
+
+ for (Map.Entry e : enumUniqNames.entrySet()) {
+ allModels.add(buildEnumModelWrapper(e.getValue(), e.getKey()));
+ }
+
+ enumUniqNames.clear();
+
+ return objs;
+ }
+
+ @Override
+ protected boolean needToImport(String type) {
+ return !defaultIncludes.contains(type)
+ && !languageSpecificPrimitives.contains(type);
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public void setPackageVersion(String packageVersion) {
+ this.packageVersion = packageVersion;
+ }
+
+ @Override
+ public String escapeQuotationMark(String input) {
+ // remove " to avoid code injection
+ return input.replace("\"", "");
+ }
+
+ @Override
+ public String escapeUnsafeCharacters(String input) {
+ return input
+ .replace("*)", "*_)")
+ .replace("(*", "(_*")
+ .replace("\"", "''");
+ }
+
+ @Override
+ public String toEnumName(CodegenProperty property) {
+ String hash = String.join(",", property.get_enum());
+
+ if (enumUniqNames.containsKey(hash)) {
+ return enumUniqNames.get(hash);
+ }
+
+ throw new IllegalArgumentException("Unreferenced enum " + hash);
+ }
+
+ @Override
+ public String toDefaultValue(Schema p) {
+ if (p.getDefault() != null) {
+ if (p.getEnum() != null) {
+ return ocamlizeEnumValue(p.getDefault().toString());
+ }
+ return p.getDefault().toString();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void postProcessFile(File file, String fileType) {
+ super.postProcessFile(file, fileType);
+
+ if (file == null) {
+ return;
+ }
+ String ocamlPostProcessFile = System.getenv("OCAML_POST_PROCESS_FILE");
+ if (StringUtils.isEmpty(ocamlPostProcessFile)) {
+ return; // skip if OCAML_POST_PROCESS_FILE env variable is not defined
+ }
+ // only process files with ml or mli extension
+ if ("ml".equals(FilenameUtils.getExtension(file.toString())) || "mli".equals(FilenameUtils.getExtension(file.toString()))) {
+ String command = ocamlPostProcessFile + " " + file.toString();
+ try {
+ Process p = Runtime.getRuntime().exec(command);
+ int exitValue = p.waitFor();
+ if (exitValue != 0) {
+ LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
+ } else {
+ LOGGER.info("Successfully executed: " + command);
+ }
+ } catch (Exception e) {
+ LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
+ }
+ }
+ }
+}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OpenAPIYamlGenerator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OpenAPIYamlGenerator.java
index ca1e9102664..02481665a55 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OpenAPIYamlGenerator.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/OpenAPIYamlGenerator.java
@@ -42,7 +42,7 @@ public class OpenAPIYamlGenerator extends DefaultCodegen implements CodegenConfi
super();
embeddedTemplateDir = templateDir = "openapi-yaml";
outputFolder = "generated-code/openapi-yaml";
- cliOptions.add(new CliOption(OUTPUT_NAME, "output filename"));
+ cliOptions.add(CliOption.newString(OUTPUT_NAME, "Output filename").defaultValue(outputFile));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpSymfonyServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpSymfonyServerCodegen.java
index 4a58052af4b..d6025d2bb2f 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpSymfonyServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpSymfonyServerCodegen.java
@@ -406,7 +406,7 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
// Create a variable to display the correct return type in comments for interfaces
if (op.returnType != null) {
op.vendorExtensions.put("x-commentType", op.returnType);
- if (!op.returnTypeIsPrimitive) {
+ if (op.returnContainer != null && op.returnContainer.equals("array")) {
op.vendorExtensions.put("x-commentType", op.returnType + "[]");
}
} else {
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java
index ba468d47ded..ffbad6f5d23 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientExperimentalCodegen.java
@@ -16,14 +16,29 @@
package org.openapitools.codegen.languages;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.swagger.v3.oas.models.media.Schema;
+import org.openapitools.codegen.*;
+import org.openapitools.codegen.utils.ModelUtils;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
public class PythonClientExperimentalCodegen extends PythonClientCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(PythonClientExperimentalCodegen.class);
public PythonClientExperimentalCodegen() {
super();
+
+ supportingFiles.add(new SupportingFile("python-experimental/api_client.mustache", packagePath(), "api_client.py"));
+ apiDocTemplateFiles.put("python-experimental/api_doc.mustache", ".md");
+ apiTemplateFiles.put("python-experimental/api.mustache", ".py");
+ modelDocTemplateFiles.put("python-experimental/model_doc.mustache", ".md");
+ modelTemplateFiles.put("python-experimental/model.mustache", ".py");
}
/**
@@ -36,4 +51,108 @@ public class PythonClientExperimentalCodegen extends PythonClientCodegen {
public String getName() {
return "python-experimental";
}
+
+ public String dateToString(Schema p, Date date, DateFormat dateFormatter, DateFormat dateTimeFormatter) {
+ // converts a date into a date or date-time python string
+ if (!(ModelUtils.isDateSchema(p) || ModelUtils.isDateTimeSchema(p))) {
+ throw new RuntimeException("passed schema must be of type Date or DateTime");
+ }
+ if (ModelUtils.isDateSchema(p)) {
+ return "dateutil_parser('" + dateFormatter.format(date) + "').date()";
+ }
+ return "dateutil_parser('" + dateTimeFormatter.format(date) + "')";
+ }
+
+ /**
+ * Return the default value of the property
+ * @param p OpenAPI property object
+ * @return string presentation of the default value of the property
+ */
+ @Override
+ public String toDefaultValue(Schema p) {
+ // if a variable has no default set and only has one allowed value
+ // using enum of length == 1 we use that value. Server/client usage:
+ // python servers: should only use default values for optional params
+ // python clients: should only use default values for required params
+ Object defaultObject = null;
+ Boolean enumLengthOne = (p.getEnum() != null && p.getEnum().size() == 1);
+ if (p.getDefault() != null) {
+ defaultObject = p.getDefault();
+ } else if (enumLengthOne) {
+ defaultObject = p.getEnum().get(0);
+ }
+
+ // convert datetime and date enums if they exist
+ DateFormat iso8601Date = new SimpleDateFormat("yyyy-MM-dd", Locale.ROOT);
+ DateFormat iso8601DateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ROOT);
+ TimeZone utc = TimeZone.getTimeZone("UTC");
+ iso8601Date.setTimeZone(utc);
+ iso8601DateTime.setTimeZone(utc);
+
+ if (ModelUtils.isDateSchema(p) || ModelUtils.isDateTimeSchema(p)) {
+ List currentEnum = p.getEnum();
+ List fixedEnum = new ArrayList();
+ String fixedValue = null;
+ Date date = null;
+ if (currentEnum != null && !currentEnum.isEmpty()) {
+ for (Object enumItem : currentEnum) {
+ date = (Date) enumItem;
+ fixedValue = dateToString(p, date, iso8601Date, iso8601DateTime);
+ fixedEnum.add(fixedValue);
+ }
+ p.setEnum(fixedEnum);
+ }
+
+ // convert the example if it exists
+ Object currentExample = p.getExample();
+ if (currentExample != null) {
+ date = (Date) currentExample;
+ fixedValue = dateToString(p, date, iso8601Date, iso8601DateTime);
+ fixedEnum.add(fixedValue);
+ p.setExample(fixedValue);
+ }
+
+ // fix defaultObject
+ if (defaultObject != null) {
+ date = (Date) defaultObject;
+ fixedValue = dateToString(p, date, iso8601Date, iso8601DateTime);
+ p.setDefault(fixedValue);
+ defaultObject = fixedValue;
+ }
+ }
+
+ if (defaultObject == null) {
+ return null;
+ }
+
+ String defaultValue = null;
+ if (ModelUtils.isStringSchema(p)) {
+ defaultValue = defaultObject.toString();
+ if (ModelUtils.isDateSchema(p) || ModelUtils.isDateTimeSchema(p)) {
+ return defaultValue;
+ }
+
+ if (!ModelUtils.isByteArraySchema(p) && !ModelUtils.isBinarySchema(p) && !ModelUtils.isFileSchema(p) && !ModelUtils.isUUIDSchema(p) && !ModelUtils.isEmailSchema(p) && !ModelUtils.isDateTimeSchema(p) && !ModelUtils.isDateSchema(p)) {
+ if (Pattern.compile("\r\n|\r|\n").matcher((String) defaultValue).find()) {
+ defaultValue = "'''" + defaultValue + "'''";
+ } else {
+ defaultValue = "'" + defaultValue + "'";
+ }
+ }
+ return defaultValue;
+ } else if (ModelUtils.isIntegerSchema(p) || ModelUtils.isNumberSchema(p) || ModelUtils.isBooleanSchema(p)) {
+ defaultValue = String.valueOf(defaultObject);
+ if (ModelUtils.isBooleanSchema(p)) {
+ if (Boolean.valueOf(defaultValue) == false) {
+ return "False";
+ } else {
+ return "True";
+ }
+ }
+ return defaultValue;
+ } else {
+ return defaultObject.toString();
+ }
+ }
+
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java
index e7af53297f3..fc23117e458 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java
@@ -46,6 +46,8 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
public static final String GEM_DESCRIPTION = "gemDescription";
public static final String GEM_AUTHOR = "gemAuthor";
public static final String GEM_AUTHOR_EMAIL = "gemAuthorEmail";
+ public static final String FARADAY = "faraday";
+ public static final String TYPHOEUS = "typhoeus";
protected String gemName;
protected String moduleName;
@@ -54,8 +56,8 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
protected String libFolder = "lib";
protected String gemLicense = "unlicense";
protected String gemRequiredRubyVersion = ">= 1.9";
- protected String gemHomepage = "http://org.openapitools";
- protected String gemSummary = "A ruby wrapper for the REST APIs";
+ protected String gemHomepage = "https://openapitools.org";
+ protected String gemSummary = "A Ruby SDK for the REST API";
protected String gemDescription = "This gem maps to a REST API";
protected String gemAuthor = "";
protected String gemAuthorEmail = "";
@@ -141,6 +143,15 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC).
defaultValue(Boolean.TRUE.toString()));
+ supportedLibraries.put(FARADAY, "Faraday (https://github.com/lostisland/faraday) (Beta support)");
+ supportedLibraries.put(TYPHOEUS, "Typhoeus >= 1.0.1 (https://github.com/typhoeus/typhoeus)");
+
+ CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "HTTP library template (sub-template) to use");
+ libraryOption.setEnum(supportedLibraries);
+ // set TYPHOEUS as the default
+ libraryOption.setDefault(TYPHOEUS);
+ cliOptions.add(libraryOption);
+ setLibrary(TYPHOEUS);
}
@Override
@@ -209,10 +220,8 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
setModelPackage("models");
setApiPackage("api");
- supportingFiles.add(new SupportingFile("gemspec.mustache", "", gemName + ".gemspec"));
supportingFiles.add(new SupportingFile("gem.mustache", libFolder, gemName + ".rb"));
String gemFolder = libFolder + File.separator + gemName;
- supportingFiles.add(new SupportingFile("api_client.mustache", gemFolder, "api_client.rb"));
supportingFiles.add(new SupportingFile("api_error.mustache", gemFolder, "api_error.rb"));
supportingFiles.add(new SupportingFile("configuration.mustache", gemFolder, "configuration.rb"));
supportingFiles.add(new SupportingFile("version.mustache", gemFolder, "version.rb"));
@@ -221,9 +230,20 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
supportingFiles.add(new SupportingFile("Rakefile.mustache", "", "Rakefile"));
supportingFiles.add(new SupportingFile("Gemfile.mustache", "", "Gemfile"));
- supportingFiles.add(new SupportingFile("Gemfile.lock.mustache", "", "Gemfile.lock"));
supportingFiles.add(new SupportingFile("rubocop.mustache", "", ".rubocop.yml"));
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
+ supportingFiles.add(new SupportingFile("gemspec.mustache", "", gemName + ".gemspec"));
+ supportingFiles.add(new SupportingFile("configuration.mustache", gemFolder, "configuration.rb"));
+ supportingFiles.add(new SupportingFile("api_client.mustache", gemFolder, "api_client.rb"));
+
+ if (TYPHOEUS.equals(getLibrary())) {
+ // for Typhoeus
+ } else if (FARADAY.equals(getLibrary())) {
+ // for Faraday
+ additionalProperties.put("isFaraday", Boolean.TRUE);
+ } else {
+ throw new RuntimeException("Invalid HTTP library " + getLibrary() + ". Only faraday, typhoeus are supported.");
+ }
// test files should not be overwritten
writeOptional(outputFolder, new SupportingFile("rspec.mustache", "", ".rspec"));
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java
index dfbb7eab35d..9f8e61ead37 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java
@@ -709,6 +709,9 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
consumesPlainText = true;
} else if (isMimetypeWwwFormUrlEncoded(mediaType)) {
additionalProperties.put("usesUrlEncodedForm", true);
+ } else if (isMimetypeMultipartFormData(mediaType)) {
+ op.vendorExtensions.put("consumesMultipart", true);
+ additionalProperties.put("apiUsesMultipart", true);
}
}
}
@@ -724,8 +727,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
} else {
op.bodyParam.vendorExtensions.put("consumesJson", true);
}
-
}
+
for (CodegenParameter param : op.bodyParams) {
processParam(param, op);
@@ -789,6 +792,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
codegenParameter.isPrimitiveType = false;
codegenParameter.isListContainer = false;
codegenParameter.isString = false;
+ codegenParameter.isByteArray = ModelUtils.isByteArraySchema(original_schema);
+
// This is a model, so should only have an example if explicitly
// defined.
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
index 4b8373004f7..1629e35d5ce 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
@@ -69,6 +69,9 @@ public class SpringCodegen extends AbstractJavaCodegen
public static final String RETURN_SUCCESS_CODE = "returnSuccessCode";
public static final String UNHANDLED_EXCEPTION_HANDLING = "unhandledException";
+ public static final String OPEN_BRACE = "{";
+ public static final String CLOSE_BRACE = "}";
+
protected String title = "OpenAPI Spring";
protected String configPackage = "org.openapitools.configuration";
protected String basePackage = "org.openapitools";
@@ -103,7 +106,7 @@ public class SpringCodegen extends AbstractJavaCodegen
invokerPackage = "org.openapitools.api";
artifactId = "openapi-spring";
- // clioOptions default redifinition need to be updated
+ // clioOptions default redefinition need to be updated
updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage());
updateOption(CodegenConstants.ARTIFACT_ID, this.getArtifactId());
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
@@ -113,6 +116,8 @@ public class SpringCodegen extends AbstractJavaCodegen
// spring uses the jackson lib
additionalProperties.put("jackson", "true");
+ additionalProperties.put("openbrace", OPEN_BRACE);
+ additionalProperties.put("closebrace", CLOSE_BRACE);
cliOptions.add(new CliOption(TITLE, "server title name or client service name").defaultValue(title));
cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code").defaultValue(this.getConfigPackage()));
@@ -132,7 +137,7 @@ public class SpringCodegen extends AbstractJavaCodegen
cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Skip header parameters in the generated API methods using @ApiImplicitParams annotation.", implicitHeaders));
cliOptions.add(CliOption.newBoolean(OPENAPI_DOCKET_CONFIG, "Generate Spring OpenAPI Docket configuration class.", openapiDocketConfig));
cliOptions.add(CliOption.newBoolean(API_FIRST, "Generate the API from the OAI spec at server compile time (API first approach)", apiFirst));
- cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,"Use Optional container for optional parameters", useOptional));
+ cliOptions.add(CliOption.newBoolean(USE_OPTIONAL, "Use Optional container for optional parameters", useOptional));
cliOptions.add(CliOption.newBoolean(HATEOAS, "Use Spring HATEOAS library to allow adding HATEOAS links", hateoas));
cliOptions.add(CliOption.newBoolean(RETURN_SUCCESS_CODE, "Generated server returns 2xx code", returnSuccessCode));
cliOptions.add(CliOption.newBoolean(UNHANDLED_EXCEPTION_HANDLING, "Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).", unhandledException));
@@ -172,7 +177,7 @@ public class SpringCodegen extends AbstractJavaCodegen
@Override
public void processOpts() {
- List> configOptions = additionalProperties.entrySet().stream()
+ List> configOptions = additionalProperties.entrySet().stream()
.filter(e -> !Arrays.asList(API_FIRST, "hideGenerationTimestamp").contains(e.getKey()))
.filter(e -> cliOptions.stream().map(CliOption::getOpt).anyMatch(opt -> opt.equals(e.getKey())))
.map(e -> Pair.of(e.getKey(), e.getValue().toString()))
@@ -220,7 +225,7 @@ public class SpringCodegen extends AbstractJavaCodegen
} else {
additionalProperties.put(BASE_PACKAGE, basePackage);
}
-
+
if (additionalProperties.containsKey(VIRTUAL_SERVICE)) {
this.setVirtualService(Boolean.valueOf(additionalProperties.get(VIRTUAL_SERVICE).toString()));
}
@@ -248,7 +253,7 @@ public class SpringCodegen extends AbstractJavaCodegen
}
if (additionalProperties.containsKey(REACTIVE)) {
- if (!library.equals(SPRING_BOOT)) {
+ if (!SPRING_BOOT.equals(library)) {
throw new IllegalArgumentException("Currently, reactive option is only supported with Spring-boot");
}
this.setReactive(Boolean.valueOf(additionalProperties.get(REACTIVE).toString()));
@@ -287,7 +292,7 @@ public class SpringCodegen extends AbstractJavaCodegen
if (additionalProperties.containsKey(API_FIRST)) {
this.setApiFirst(Boolean.valueOf(additionalProperties.get(API_FIRST).toString()));
}
-
+
if (additionalProperties.containsKey(HATEOAS)) {
this.setHateoas(Boolean.valueOf(additionalProperties.get(HATEOAS).toString()));
}
@@ -398,12 +403,15 @@ public class SpringCodegen extends AbstractJavaCodegen
apiTemplateFiles.put("apiDelegate.mustache", "Delegate.java");
}
+
if (this.java8) {
additionalProperties.put("javaVersion", "1.8");
- additionalProperties.put("jdk8-default-interface", !this.skipDefaultInterface);
- if (!SPRING_CLOUD_LIBRARY.equals(library)) {
- additionalProperties.put("jdk8", true);
+ if (SPRING_CLOUD_LIBRARY.equals(library)) {
+ additionalProperties.put("jdk8-default-interface", false);
+ } else {
+ additionalProperties.put("jdk8-default-interface", !this.skipDefaultInterface);
}
+ additionalProperties.put("jdk8", true);
if (this.async) {
additionalProperties.put(RESPONSE_WRAPPER, "CompletableFuture");
}
@@ -414,7 +422,8 @@ public class SpringCodegen extends AbstractJavaCodegen
additionalProperties.put(RESPONSE_WRAPPER, "Callable");
}
- if(!this.apiFirst && !this.reactive) {
+
+ if (!this.apiFirst && !this.reactive) {
additionalProperties.put("useSpringfox", true);
}
@@ -458,7 +467,7 @@ public class SpringCodegen extends AbstractJavaCodegen
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) {
- if((library.equals(SPRING_BOOT) || library.equals(SPRING_MVC_LIBRARY)) && !useTags) {
+ if ((library.equals(SPRING_BOOT) || library.equals(SPRING_MVC_LIBRARY)) && !useTags) {
String basePath = resourcePath;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
@@ -490,7 +499,7 @@ public class SpringCodegen extends AbstractJavaCodegen
}
*/
- if(!additionalProperties.containsKey(TITLE)) {
+ if (!additionalProperties.containsKey(TITLE)) {
// From the title, compute a reasonable name for the package and the API
String title = openAPI.getInfo().getTitle();
@@ -506,7 +515,7 @@ public class SpringCodegen extends AbstractJavaCodegen
additionalProperties.put(TITLE, this.title);
}
- if(!additionalProperties.containsKey(SERVER_PORT)) {
+ if (!additionalProperties.containsKey(SERVER_PORT)) {
URL url = URLPathUtils.getServerURL(openAPI);
this.additionalProperties.put(SERVER_PORT, URLPathUtils.getPort(url, 8080));
}
@@ -578,7 +587,7 @@ public class SpringCodegen extends AbstractJavaCodegen
}
});
- if(implicitHeaders){
+ if (implicitHeaders) {
removeHeadersFromAllParams(operation.allParams);
}
}
@@ -589,12 +598,12 @@ public class SpringCodegen extends AbstractJavaCodegen
private interface DataTypeAssigner {
void setReturnType(String returnType);
+
void setReturnContainer(String returnContainer);
}
/**
- *
- * @param returnType The return type that needs to be converted
+ * @param returnType The return type that needs to be converted
* @param dataTypeAssigner An object that will assign the data to the respective fields in the model.
*/
private void doDataTypeAssignment(String returnType, DataTypeAssigner dataTypeAssigner) {
@@ -625,29 +634,30 @@ public class SpringCodegen extends AbstractJavaCodegen
/**
* This method removes header parameters from the list of parameters and also
* corrects last allParams hasMore state.
+ *
* @param allParams list of all parameters
*/
private void removeHeadersFromAllParams(List allParams) {
- if(allParams.isEmpty()){
+ if (allParams.isEmpty()) {
return;
}
final ArrayList copy = new ArrayList<>(allParams);
allParams.clear();
- for(CodegenParameter p : copy){
- if(!p.isHeaderParam){
+ for (CodegenParameter p : copy) {
+ if (!p.isHeaderParam) {
allParams.add(p);
}
}
if (!allParams.isEmpty()) {
- allParams.get(allParams.size()-1).hasMore =false;
+ allParams.get(allParams.size() - 1).hasMore = false;
}
}
@Override
public Map postProcessSupportingFileData(Map objs) {
generateYAMLSpecFile(objs);
- if(library.equals(SPRING_CLOUD_LIBRARY)) {
+ if (library.equals(SPRING_CLOUD_LIBRARY)) {
List authMethods = (List) objs.get("authMethods");
if (authMethods != null) {
for (CodegenSecurity authMethod : authMethods) {
@@ -717,9 +727,13 @@ public class SpringCodegen extends AbstractJavaCodegen
return this.basePackage;
}
- public void setInterfaceOnly(boolean interfaceOnly) { this.interfaceOnly = interfaceOnly; }
+ public void setInterfaceOnly(boolean interfaceOnly) {
+ this.interfaceOnly = interfaceOnly;
+ }
- public void setDelegatePattern(boolean delegatePattern) { this.delegatePattern = delegatePattern; }
+ public void setDelegatePattern(boolean delegatePattern) {
+ this.delegatePattern = delegatePattern;
+ }
public void setSingleContentTypes(boolean singleContentTypes) {
this.singleContentTypes = singleContentTypes;
@@ -729,13 +743,21 @@ public class SpringCodegen extends AbstractJavaCodegen
public void setJava8(boolean java8) { this.java8 = java8; }
- public void setVirtualService(boolean virtualService) { this.virtualService = virtualService; }
+ public void setVirtualService(boolean virtualService) {
+ this.virtualService = virtualService;
+ }
- public void setAsync(boolean async) { this.async = async; }
+ public void setAsync(boolean async) {
+ this.async = async;
+ }
- public void setReactive(boolean reactive) { this.reactive = reactive; }
+ public void setReactive(boolean reactive) {
+ this.reactive = reactive;
+ }
- public void setResponseWrapper(String responseWrapper) { this.responseWrapper = responseWrapper; }
+ public void setResponseWrapper(String responseWrapper) {
+ this.responseWrapper = responseWrapper;
+ }
public void setUseTags(boolean useTags) {
this.useTags = useTags;
@@ -752,7 +774,7 @@ public class SpringCodegen extends AbstractJavaCodegen
public void setApiFirst(boolean apiFirst) {
this.apiFirst = apiFirst;
}
-
+
public void setHateoas(boolean hateoas) {
this.hateoas = hateoas;
}
@@ -793,7 +815,7 @@ public class SpringCodegen extends AbstractJavaCodegen
objs = super.postProcessModelsEnum(objs);
//Add imports for Jackson
- List> imports = (List>)objs.get("imports");
+ List> imports = (List>) objs.get("imports");
List models = (List) objs.get("models");
for (Object _mo : models) {
Map mo = (Map) _mo;
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java
index 745e9747b2c..87850355e90 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularClientCodegen.java
@@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
+import java.util.regex.Pattern;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.openapitools.codegen.utils.StringUtils.*;
@@ -48,6 +49,8 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
public static final String MODEL_SUFFIX = "modelSuffix";
public static final String MODEL_FILE_SUFFIX = "modelFileSuffix";
public static final String FILE_NAMING = "fileNaming";
+ public static final String STRING_ENUMS = "stringEnums";
+ public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
protected String ngVersion = "7.0.0";
protected String npmRepository = null;
@@ -56,6 +59,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
protected String modelSuffix = "";
protected String modelFileSuffix = "";
protected String fileNaming = "camelCase";
+ protected Boolean stringEnums = false;
private boolean taggedUnions = false;
@@ -88,6 +92,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model."));
this.cliOptions.add(new CliOption(MODEL_FILE_SUFFIX, "The suffix of the file of the generated model (model.ts)."));
this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
+ this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums)));
}
@Override
@@ -136,6 +141,15 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
addNpmPackageGeneration(ngVersion);
}
+ if (additionalProperties.containsKey(STRING_ENUMS)) {
+ setStringEnums(Boolean.valueOf(additionalProperties.get(STRING_ENUMS).toString()));
+ additionalProperties.put("stringEnums", getStringEnums());
+ if (getStringEnums()) {
+ enumSuffix = "";
+ classEnumSeparator = "";
+ }
+ }
+
if (additionalProperties.containsKey(WITH_INTERFACES)) {
boolean withInterfaces = Boolean.parseBoolean(additionalProperties.get(WITH_INTERFACES).toString());
if (withInterfaces) {
@@ -151,8 +165,9 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
if (!additionalProperties.containsKey(PROVIDED_IN_ROOT)) {
additionalProperties.put(PROVIDED_IN_ROOT, true);
} else {
- additionalProperties.put(PROVIDED_IN_ROOT, Boolean.valueOf(
- (String) additionalProperties.get(PROVIDED_IN_ROOT)));
+ additionalProperties.put(PROVIDED_IN_ROOT, Boolean.parseBoolean(
+ additionalProperties.get(PROVIDED_IN_ROOT).toString()
+ ));
}
} else {
additionalProperties.put(PROVIDED_IN_ROOT, false);
@@ -271,6 +286,14 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
return indexPackage.replace('.', File.separatorChar);
}
+ public void setStringEnums(boolean value) {
+ stringEnums = value;
+ }
+
+ public Boolean getStringEnums() {
+ return stringEnums;
+ }
+
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && dataType.equals("Blob");
@@ -330,7 +353,11 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
objs.put("apiFilename", getApiFilenameFromClassname(objs.get("classname").toString()));
List ops = (List) objs.get("operation");
+ boolean hasSomeFormParams = false;
for (CodegenOperation op : ops) {
+ if (op.getHasFormParams()) {
+ hasSomeFormParams = true;
+ }
if ((boolean) additionalProperties.get("useHttpClient")) {
op.httpMethod = op.httpMethod.toLowerCase(Locale.ENGLISH);
} else {
@@ -406,6 +433,8 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
op.path = pathBuffer.toString();
}
+ operations.put("hasSomeFormParams", hasSomeFormParams);
+
// Add additional filename information for model imports in the services
List> imports = (List>) operations.get("imports");
for (Map im : imports) {
@@ -458,12 +487,33 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
}
}
// Add additional filename information for imports
- mo.put("tsImports", toTsImports(cm, cm.imports));
+ Set parsedImports = parseImports(cm);
+ mo.put("tsImports", toTsImports(cm, parsedImports));
}
}
return result;
}
+ /**
+ * Parse imports
+ */
+ private Set parseImports(CodegenModel cm) {
+ Set newImports = new HashSet();
+ if (cm.imports.size() > 0) {
+ for (String name : cm.imports) {
+ if (name.indexOf(" | ") >= 0) {
+ String[] parts = name.split(" \\| ");
+ for (String s : parts) {
+ newImports.add(s);
+ }
+ } else {
+ newImports.add(name);
+ }
+ }
+ }
+ return newImports;
+ }
+
private List> toTsImports(CodegenModel cm, Set imports) {
List> tsImports = new ArrayList<>();
for (String im : imports) {
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java
index f6634095610..41986aa24fc 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java
@@ -50,9 +50,9 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
outputFolder = "generated-code/typescript-fetch";
embeddedTemplateDir = templateDir = "typescript-fetch";
- this.apiPackage = "apis";
+ this.apiPackage = "src" + File.separator +"apis";
+ this.modelPackage = "src" + File.separator + "models";
this.apiTemplateFiles.put("apis.mustache", ".ts");
- this.modelPackage = "models";
this.modelTemplateFiles.put("models.mustache", ".ts");
this.addExtraReservedWords();
@@ -84,8 +84,8 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
super.processOpts();
additionalProperties.put("isOriginalModelPropertyNaming", getModelPropertyNaming().equals("original"));
additionalProperties.put("modelPropertyNaming", getModelPropertyNaming());
- supportingFiles.add(new SupportingFile("index.mustache", "", "index.ts"));
- supportingFiles.add(new SupportingFile("runtime.mustache", "", "runtime.ts"));
+ supportingFiles.add(new SupportingFile("index.mustache", "src", "index.ts"));
+ supportingFiles.add(new SupportingFile("runtime.mustache", "src", "runtime.ts"));
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
@@ -188,6 +188,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
//Files for building our lib
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
+ supportingFiles.add(new SupportingFile("npmignore.mustache", "", ".npmignore"));
}
@Override
@@ -216,7 +217,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
// models for a given operation.
List> imports = (List>) operations.get("imports");
for (Map im : imports) {
- im.put("className", im.get("import").toString().replace("models.", ""));
+ im.put("className", im.get("import").toString().replace(modelPackage() + ".", ""));
}
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java
index bcad8aa989c..c1b0d618d0b 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNodeClientCodegen.java
@@ -18,7 +18,6 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
-import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
@@ -33,6 +32,7 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen
private static final Logger LOGGER = LoggerFactory.getLogger(TypeScriptNodeClientCodegen.class);
public static final String NPM_REPOSITORY = "npmRepository";
+ private static final String DEFAULT_IMPORT_PREFIX = "./";
protected String npmRepository = null;
protected String apiSuffix = "Api";
@@ -96,22 +96,37 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen
if (name.length() == 0) {
return "default" + apiSuffix;
}
+ if (importMapping.containsKey(name)) {
+ return importMapping.get(name);
+ }
return camelize(name, true) + apiSuffix;
}
@Override
public String toApiImport(String name) {
+ if (importMapping.containsKey(name)) {
+ return importMapping.get(name);
+ }
+
return apiPackage() + "/" + toApiFilename(name);
}
@Override
public String toModelFilename(String name) {
- return camelize(toModelName(name), true);
+ if (importMapping.containsKey(name)) {
+ return importMapping.get(name);
+ }
+
+ return DEFAULT_IMPORT_PREFIX + camelize(toModelName(name), true);
}
@Override
public String toModelImport(String name) {
- return modelPackage() + "/" + toModelFilename(name);
+ if (importMapping.containsKey(name)) {
+ return importMapping.get(name);
+ }
+
+ return modelPackage() + "/" + camelize(toModelName(name), true);
}
@Override
diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache
index cd173326c10..682bf945069 100644
--- a/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/ApiClient.mustache
@@ -187,24 +187,14 @@ public class ApiClient {
}
/**
- * Set HTTP client
+ * Set HTTP client, which must never be null.
*
* @param newHttpClient An instance of OkHttpClient
* @return Api Client
+ * @throws NullPointerException when newHttpClient is null
*/
public ApiClient setHttpClient(OkHttpClient newHttpClient) {
- if(!httpClient.equals(newHttpClient)) {
- OkHttpClient.Builder builder = newHttpClient.newBuilder();
- Iterator networkInterceptorIterator = httpClient.networkInterceptors().iterator();
- while(networkInterceptorIterator.hasNext()) {
- builder.addNetworkInterceptor(networkInterceptorIterator.next());
- }
- Iterator interceptorIterator = httpClient.interceptors().iterator();
- while(interceptorIterator.hasNext()) {
- builder.addInterceptor(interceptorIterator.next());
- }
- this.httpClient = builder.build();
- }
+ this.httpClient = Objects.requireNonNull(newHttpClient, "HttpClient must not be null!");
return this;
}
diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache
index 3f8f6a0f4de..52e5f96e994 100644
--- a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache
@@ -555,6 +555,16 @@ public class ApiClient {
return isForm ? formParams : obj;
}
+ /**
+ * Expand path template with variables
+ * @param pathTemplate path template with placeholders
+ * @param variables variables to replace
+ * @return path with placeholders replaced by variables
+ */
+ public String expandPath(String pathTemplate, Map variables) {
+ return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString();
+ }
+
/**
* Invoke API by sending HTTP request with the given options.
*
@@ -619,9 +629,6 @@ public class ApiClient {
if (responseEntity.getStatusCode() == HttpStatus.NO_CONTENT) {
return null;
} else if (responseEntity.getStatusCode().is2xxSuccessful()) {
- if (returnType == null) {
- return null;
- }
return responseEntity.getBody();
} else {
// The error handler built into the RestTemplate should handle 400 and 500 series errors.
diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/api.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/api.mustache
index 040d776efe9..79cdcd51ac1 100644
--- a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/api.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/api.mustache
@@ -6,6 +6,7 @@ import {{invokerPackage}}.ApiClient;
{{/imports}}
{{^fullJavaUtil}}import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -72,7 +73,7 @@ public class {{classname}} {
// create path and map variables
final Map uriVariables = new HashMap();{{#pathParams}}
uriVariables.put("{{baseName}}", {{#collectionFormat}}apiClient.collectionPathParameterToString(ApiClient.CollectionFormat.valueOf("{{{collectionFormat}}}".toUpperCase()), {{{paramName}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}});{{/pathParams}}{{/hasPathParams}}
- String path = UriComponentsBuilder.fromPath("{{{path}}}"){{#hasPathParams}}.buildAndExpand(uriVariables){{/hasPathParams}}{{^hasPathParams}}.build(){{/hasPathParams}}.toUriString();
+ String path = apiClient.expandPath("{{{path}}}", {{#hasPathParams}}uriVariables{{/hasPathParams}}{{^hasPathParams}}Collections.emptyMap(){{/hasPathParams}});
final MultiValueMap queryParams = new LinkedMultiValueMap();
final HttpHeaders headerParams = new HttpHeaders();
diff --git a/modules/openapi-generator/src/main/resources/Java/pojo.mustache b/modules/openapi-generator/src/main/resources/Java/pojo.mustache
index afd1ebf4098..240190fa11b 100644
--- a/modules/openapi-generator/src/main/resources/Java/pojo.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/pojo.mustache
@@ -20,7 +20,8 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
{{/isContainer}}
{{/isEnum}}
{{#jackson}}
- @JsonProperty("{{baseName}}")
+ public static final String JSON_PROPERTY_{{nameInSnakeCase}} = "{{baseName}}";
+ @JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
{{#withXml}}
{{^isContainer}}
@JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/pojo.mustache
index 18c5aa4db40..8e3abbae6a7 100644
--- a/modules/openapi-generator/src/main/resources/JavaJaxRS/pojo.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/pojo.mustache
@@ -16,10 +16,12 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
{{/isContainer}}
{{/isEnum}}
{{#jackson}}
- @JsonProperty("{{baseName}}")
+ public static final String JSON_PROPERTY_{{nameInSnakeCase}} = "{{baseName}}";
+ @JsonProperty(JSON_PROPERTY_{{nameInSnakeCase}})
{{/jackson}}
{{#gson}}
- @SerializedName("{{baseName}}")
+ public static final String SERIALIZED_NAME_{{nameInSnakeCase}} = "{{baseName}}";
+ @SerializedName(SERIALIZED_NAME_{{nameInSnakeCase}})
{{/gson}}
{{#isContainer}}
private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}};
diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/clientConfiguration.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/clientConfiguration.mustache
index 3e86330c91b..99d82b2c7d5 100644
--- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/clientConfiguration.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/clientConfiguration.mustache
@@ -24,25 +24,25 @@ public class ClientConfiguration {
{{#authMethods}}
{{#isBasic}}
- {{=<% %>=}}@Value("${<%title%>.security.<%name%>.username:}")<%={{ }}=%>
+ @Value("${{openbrace}}{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.username:{{closebrace}}")
private String {{{name}}}Username;
- {{=<% %>=}}@Value("${<%title%>.security.<%name%>.password:}")<%={{ }}=%>
+ @Value("${{openbrace}}{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.password:{{closebrace}}")
private String {{{name}}}Password;
@Bean
- @ConditionalOnProperty(name = "{{{title}}}.security.{{{name}}}.username")
+ @ConditionalOnProperty(name = "{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.username")
public BasicAuthRequestInterceptor {{{name}}}RequestInterceptor() {
return new BasicAuthRequestInterceptor(this.{{{name}}}Username, this.{{{name}}}Password);
}
{{/isBasic}}
{{#isApiKey}}
- {{=<% %>=}}@Value("${<%title%>.security.<%name%>.key:}")<%={{ }}=%>
+ @Value("${{openbrace}}{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.key:{{closebrace}}")
private String {{{name}}}Key;
@Bean
- @ConditionalOnProperty(name = "{{{title}}}.security.{{{name}}}.key")
+ @ConditionalOnProperty(name = "{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.key")
public ApiKeyRequestInterceptor {{{name}}}RequestInterceptor() {
return new ApiKeyRequestInterceptor({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{{keyParamName}}}", this.{{{name}}}Key);
}
@@ -50,15 +50,15 @@ public class ClientConfiguration {
{{/isApiKey}}
{{#isOAuth}}
@Bean
- @ConditionalOnProperty("{{{title}}}.security.{{{name}}}.client-id")
+ @ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
public OAuth2FeignRequestInterceptor {{{name}}}RequestInterceptor() {
return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), {{{name}}}ResourceDetails());
}
{{#isCode}}
@Bean
- @ConditionalOnProperty("{{{title}}}.security.{{{name}}}.client-id")
- @ConfigurationProperties("{{{title}}}.security.{{{name}}}")
+ @ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
+ @ConfigurationProperties("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}")
public AuthorizationCodeResourceDetails {{{name}}}ResourceDetails() {
AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
details.setAccessTokenUri("{{{tokenUrl}}}");
@@ -69,8 +69,8 @@ public class ClientConfiguration {
{{/isCode}}
{{#isPassword}}
@Bean
- @ConditionalOnProperty("{{{title}}}.security.{{{name}}}.client-id")
- @ConfigurationProperties("{{{title}}}.security.{{{name}}}")
+ @ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
+ @ConfigurationProperties("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}")
public ResourceOwnerPasswordResourceDetails {{{name}}}ResourceDetails() {
ResourceOwnerPasswordResourceDetails details = new ResourceOwnerPasswordResourceDetails();
details.setAccessTokenUri("{{{tokenUrl}}}");
@@ -80,8 +80,8 @@ public class ClientConfiguration {
{{/isPassword}}
{{#isApplication}}
@Bean
- @ConditionalOnProperty("{{{title}}}.security.{{{name}}}.client-id")
- @ConfigurationProperties("{{{title}}}.security.{{{name}}}")
+ @ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
+ @ConfigurationProperties("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}")
public ClientCredentialsResourceDetails {{{name}}}ResourceDetails() {
ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
details.setAccessTokenUri("{{{tokenUrl}}}");
@@ -91,8 +91,8 @@ public class ClientConfiguration {
{{/isApplication}}
{{#isImplicit}}
@Bean
- @ConditionalOnProperty("{{{title}}}.security.{{{name}}}.client-id")
- @ConfigurationProperties("{{{title}}}.security.{{{name}}}")
+ @ConditionalOnProperty("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}.client-id")
+ @ConfigurationProperties("{{#lambda.lowercase}}{{{title}}}{{/lambda.lowercase}}.security.{{{name}}}")
public ImplicitResourceDetails {{{name}}}ResourceDetails() {
ImplicitResourceDetails details = new ImplicitResourceDetails();
details.setUserAuthorizationUri("{{{authorizationUrl}}}");
diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache
index 1ba3588ac5a..6421924b76d 100644
--- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/pom.mustache
@@ -29,6 +29,7 @@
src/main/java
+{{^parentOverridden}}
@@ -41,11 +42,14 @@
+{{/parentOverridden}}
io.swagger
swagger-annotations
+{{^parentOverridden}}
${swagger-core-version}
+{{/parentOverridden}}
@@ -84,13 +88,17 @@
com.github.joschi.jackson
jackson-datatype-threetenbp
+ {{^parentOverridden}}
2.6.4
+ {{/parentOverridden}}
{{/threetenbp}}
org.openapitools
jackson-databind-nullable
+{{^parentOverridden}}
0.1.0
+{{/parentOverridden}}
org.springframework.boot
@@ -104,5 +112,14 @@
spring-boot-starter-hateoas
{{/hateoas}}
+{{#useBeanValidation}}
+
+ org.hibernate.validator
+ hibernate-validator
+ {{^parentOverridden}}
+ 6.0.16.Final
+ {{/parentOverridden}}
+
+{{/useBeanValidation}}
diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
index ac693c68c87..9a8fba9fc43 100644
--- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
+++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
@@ -61,7 +61,9 @@ org.openapitools.codegen.languages.JMeterClientCodegen
org.openapitools.codegen.languages.LuaClientCodegen
org.openapitools.codegen.languages.MysqlSchemaCodegen
org.openapitools.codegen.languages.NodeJSServerCodegen
+org.openapitools.codegen.languages.NodeJSExpressServerCodegen
org.openapitools.codegen.languages.ObjcClientCodegen
+org.openapitools.codegen.languages.OCamlClientCodegen
org.openapitools.codegen.languages.OpenAPIGenerator
org.openapitools.codegen.languages.OpenAPIYamlGenerator
org.openapitools.codegen.languages.PerlClientCodegen
diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache
index 98fb1fe23e6..744a282fee1 100644
--- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache
+++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/Startup.mustache
@@ -60,7 +60,7 @@ namespace {{packageName}}
// Add framework services.
services
- .AddMvc({{^useDefaultRoutng}}opts => opts.EnableEndpointRouting = false{{/useDefaultRoutng}})
+ .AddMvc({{^useDefaultRouting}}opts => opts.EnableEndpointRouting = false{{/useDefaultRouting}})
{{#compatibilityVersion}}
.SetCompatibilityVersion(CompatibilityVersion.{{compatibilityVersion}})
{{/compatibilityVersion}}
@@ -127,12 +127,12 @@ namespace {{packageName}}
//TODO: Or alternatively use the original Swagger contract that's included in the static files
// c.SwaggerEndpoint("/openapi-original.json", "{{#appName}}{{{appName}}}{{/appName}}{{^appName}}{{packageName}}{{/appName}} Original");
- }){{/useSwashbuckle}};{{^useDefaultRoutng}}
+ }){{/useSwashbuckle}};{{^useDefaultRouting}}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
- });{{/useDefaultRoutng}}
+ });{{/useDefaultRouting}}
if (env.IsDevelopment())
{
diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache
index 0c136c8a8b8..99492c9a604 100644
--- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache
+++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/controller.mustache
@@ -40,9 +40,14 @@ namespace {{apiPackage}}
[SwaggerOperation("{{operationId}}")]{{#responses}}{{#dataType}}
[SwaggerResponse(statusCode: {{code}}, type: typeof({{&dataType}}), description: "{{message}}")]{{/dataType}}{{^dataType}}{{/dataType}}{{/responses}}{{/useSwashbuckle}}{{^useSwashbuckle}}{{#responses}}{{#dataType}}
[ProducesResponseType(statusCode: {{code}}, type: typeof({{&dataType}}))]{{/dataType}}{{^dataType}}{{/dataType}}{{/responses}}{{/useSwashbuckle}}
- public {{operationModifier}} {{#operationResultTask}}{{#operationIsAsync}}async {{/operationIsAsync}}Task<{{/operationResultTask}}IActionResult{{#operationResultTask}}>{{/operationResultTask}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{^generateBody}};{{/generateBody}}
+ public {{operationModifier}} {{#operationResultTask}}{{#operationIsAsync}}async {{/operationIsAsync}}Task<{{/operationResultTask}}IActionResult{{#operationResultTask}}>{{/operationResultTask}} {{operationId}}({{#allParams}}{{>pathParam}}{{>queryParam}}{{>bodyParam}}{{>formParam}}{{>headerParam}}{{#hasMore}}{{^isCookieParam}}, {{/isCookieParam}}{{/hasMore}}{{/allParams}}){{^generateBody}};{{/generateBody}}
{{#generateBody}}
- { {{#responses}}
+ {
+ {{#cookieParams}}
+ var {{paramName}} = Request.Cookies["{{paramName}}"];
+ {{/cookieParams}}
+
+{{#responses}}
{{#dataType}}
//TODO: Uncomment the next line to return response {{code}} or use other options such as return this.NotFound(), return this.BadRequest(..), ...
// return StatusCode({{code}}, default({{&dataType}}));
@@ -50,7 +55,8 @@ namespace {{apiPackage}}
{{^dataType}}
//TODO: Uncomment the next line to return response {{code}} or use other options such as return this.NotFound(), return this.BadRequest(..), ...
// return StatusCode({{code}});
-{{/dataType}}{{/responses}}
+{{/dataType}}
+{{/responses}}
{{#returnType}}
string exampleJson = null;
{{#examples}}
diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/enumClass.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/enumClass.mustache
index a8a68b99844..8a932b5ade6 100644
--- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/enumClass.mustache
+++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/enumClass.mustache
@@ -5,7 +5,8 @@
{{#description}}
/// {{{description}}}
{{/description}}
- {{#allowableValues}}{{#enumVars}}{{#-first}}{{#isString}}[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]{{/isString}}{{/-first}}{{/enumVars}}{{/allowableValues}}
+ {{#allowableValues}}{{#enumVars}}{{#-first}}{{#isString}}[TypeConverter(typeof(CustomEnumConverter<{{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}>))]
+ [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]{{/isString}}{{/-first}}{{/enumVars}}{{/allowableValues}}
public enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}
{
{{#allowableValues}}{{#enumVars}}
diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/model.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/model.mustache
index e198e2447e7..bf1cb3902fc 100644
--- a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/model.mustache
+++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/model.mustache
@@ -3,9 +3,11 @@ using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
+using {{packageName}}.Converters;
{{#models}}
{{#model}}
diff --git a/modules/openapi-generator/src/main/resources/aspnetcore/2.1/typeConverter.mustache b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/typeConverter.mustache
new file mode 100644
index 00000000000..dadf3a0260d
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/aspnetcore/2.1/typeConverter.mustache
@@ -0,0 +1,33 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using Newtonsoft.Json;
+
+namespace {{packageName}}.Converters
+{
+ ///
+ /// Custom string to enum converter
+ ///
+ public class CustomEnumConverter : TypeConverter
+ {
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ {
+ return true;
+ }
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ var s = value as string;
+ if (string.IsNullOrEmpty(s))
+ {
+ return null;
+ }
+
+ return JsonConvert.DeserializeObject(@"""" + value.ToString() + @"""");
+ }
+ }
+}
diff --git a/modules/openapi-generator/src/main/resources/bash/client.mustache b/modules/openapi-generator/src/main/resources/bash/client.mustache
index e59d63b3f77..d53e1a937d5 100644
--- a/modules/openapi-generator/src/main/resources/bash/client.mustache
+++ b/modules/openapi-generator/src/main/resources/bash/client.mustache
@@ -416,18 +416,16 @@ build_request_path() {
local query_request_part=""
- local count=0
for qparam in "${query_params[@]}"; do
+ if [[ "${operation_parameters[$qparam]}" == "" ]]; then
+ continue
+ fi
+
# Get the array of parameter values
local parameter_value=""
local parameter_values
mapfile -t parameter_values < <(sed -e 's/'":::"'/\n/g' <<<"${operation_parameters[$qparam]}")
- if [[ -n "${parameter_values[*]}" ]]; then
- if [[ $((count++)) -gt 0 ]]; then
- query_request_part+="&"
- fi
- fi
{{#hasAuthMethods}}{{#authMethods}}{{#isApiKey}}{{#isKeyInQuery}}
if [[ ${qparam} == "{{keyParamName}}" ]]; then
if [[ -n "${parameter_values[*]}" ]]; then
@@ -508,6 +506,9 @@ build_request_path() {
fi
if [[ -n "${parameter_value}" ]]; then
+ if [[ -n "${query_request_part}" ]]; then
+ query_request_part+="&"
+ fi
query_request_part+="${parameter_value}"
fi
diff --git a/modules/openapi-generator/src/main/resources/cpp-pistache-server/api-source.mustache b/modules/openapi-generator/src/main/resources/cpp-pistache-server/api-source.mustache
index 4e35d5f863e..31afee650ff 100644
--- a/modules/openapi-generator/src/main/resources/cpp-pistache-server/api-source.mustache
+++ b/modules/openapi-generator/src/main/resources/cpp-pistache-server/api-source.mustache
@@ -70,7 +70,12 @@ void {{classname}}::{{operationIdSnakeCase}}_handler(const Pistache::Rest::Reque
try {
{{#hasBodyParam}}
{{#bodyParam}}
+ {{^isPrimitiveType}}
nlohmann::json::parse(request.body()).get_to({{paramName}});
+ {{/isPrimitiveType}}
+ {{#isPrimitiveType}}
+ {{paramName}} = request.body();
+ {{/isPrimitiveType}}
{{/bodyParam}}
{{/hasBodyParam}}
this->{{operationIdSnakeCase}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{#hasParams}}, {{/hasParams}}response);
diff --git a/modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/modelbase-source.mustache b/modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/modelbase-source.mustache
index 97f8aea1090..91446e73a33 100644
--- a/modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/modelbase-source.mustache
+++ b/modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/modelbase-source.mustache
@@ -265,16 +265,19 @@ std::shared_ptr ModelBase::fromBase64( const utility::string_t& en
int64_t ModelBase::int64_tFromJson(const web::json::value& val)
{
- return val.as_number().to_int64();
+ return val.is_null() ? std::numeric_limits::quiet_NaN() : val.as_number().to_int64();
}
+
int32_t ModelBase::int32_tFromJson(const web::json::value& val)
{
- return val.as_integer();
+ return val.is_null() ? std::numeric_limits::quiet_NaN() : val.as_integer();
}
+
float ModelBase::floatFromJson(const web::json::value& val)
{
- return static_cast(val.as_double());
+ return val.is_null() ? std::numeric_limits::quiet_NaN() : static_cast(val.as_double());
}
+
utility::string_t ModelBase::stringFromJson(const web::json::value& val)
{
return val.is_string() ? val.as_string() : utility::conversions::to_string_t("");
@@ -282,15 +285,15 @@ utility::string_t ModelBase::stringFromJson(const web::json::value& val)
utility::datetime ModelBase::dateFromJson(const web::json::value& val)
{
- return utility::datetime::from_string(val.as_string(), utility::datetime::ISO_8601);
+ return val.is_null() ? utility::datetime::from_string(L"NULL", utility::datetime::ISO_8601) : utility::datetime::from_string(val.as_string(), utility::datetime::ISO_8601);
}
bool ModelBase::boolFromJson(const web::json::value& val)
{
- return val.as_bool();
+ return val.is_null() ? false : val.as_bool();
}
double ModelBase::doubleFromJson(const web::json::value& val)
{
- return val.as_double();
+ return val.is_null() ? std::numeric_limits::quiet_NaN(): val.as_double();
}
int64_t ModelBase::int64_tFromHttpContent(std::shared_ptr val)
diff --git a/modules/openapi-generator/src/main/resources/csharp-netcore/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp-netcore/ApiClient.mustache
index f3232ec5f16..55b3e96c4c7 100644
--- a/modules/openapi-generator/src/main/resources/csharp-netcore/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp-netcore/ApiClient.mustache
@@ -270,6 +270,14 @@ namespace {{packageName}}.Client
}
}
+ if (configuration.DefaultHeaders != null)
+ {
+ foreach (var headerParam in configuration.DefaultHeaders)
+ {
+ request.AddHeader(headerParam.Key, headerParam.Value);
+ }
+ }
+
if (options.HeaderParameters != null)
{
foreach (var headerParam in options.HeaderParameters)
diff --git a/modules/openapi-generator/src/main/resources/csharp-netcore/Configuration.mustache b/modules/openapi-generator/src/main/resources/csharp-netcore/Configuration.mustache
index 7f70ee4c5e6..f9a29c90aa3 100644
--- a/modules/openapi-generator/src/main/resources/csharp-netcore/Configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp-netcore/Configuration.mustache
@@ -35,7 +35,7 @@ namespace {{packageName}}.Client
#endregion Constants
#region Static Members
-
+
///
/// Default creation of exceptions for a given method name and response object
///
@@ -65,7 +65,7 @@ namespace {{packageName}}.Client
/// Example: http://localhost:3000/v1/
///
private String _basePath;
-
+
///
/// Gets or sets the API key based on the authentication name.
/// This is the key and value comprising the "secret" for acessing an API.
@@ -94,7 +94,7 @@ namespace {{packageName}}.Client
{
UserAgent = "{{#httpUserAgent}}{{.}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{packageVersion}}/csharp{{/httpUserAgent}}";
BasePath = "{{{basePath}}}";
- DefaultHeader = new {{^net35}}Concurrent{{/net35}}Dictionary();
+ DefaultHeaders = new {{^net35}}Concurrent{{/net35}}Dictionary();
ApiKey = new {{^net35}}Concurrent{{/net35}}Dictionary();
ApiKeyPrefix = new {{^net35}}Concurrent{{/net35}}Dictionary();
@@ -107,15 +107,15 @@ namespace {{packageName}}.Client
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")]
public Configuration(
- IDictionary defaultHeader,
+ IDictionary defaultHeaders,
IDictionary apiKey,
IDictionary apiKeyPrefix,
string basePath = "{{{basePath}}}") : this()
{
if (string.{{^net35}}IsNullOrWhiteSpace{{/net35}}{{#net35}}IsNullOrEmpty{{/net35}}(basePath))
throw new ArgumentException("The provided basePath is invalid.", "basePath");
- if (defaultHeader == null)
- throw new ArgumentNullException("defaultHeader");
+ if (defaultHeaders == null)
+ throw new ArgumentNullException("defaultHeaders");
if (apiKey == null)
throw new ArgumentNullException("apiKey");
if (apiKeyPrefix == null)
@@ -123,9 +123,9 @@ namespace {{packageName}}.Client
BasePath = basePath;
- foreach (var keyValuePair in defaultHeader)
+ foreach (var keyValuePair in defaultHeaders)
{
- DefaultHeader.Add(keyValuePair);
+ DefaultHeaders.Add(keyValuePair);
}
foreach (var keyValuePair in apiKey)
@@ -156,7 +156,23 @@ namespace {{packageName}}.Client
///
/// Gets or sets the default header.
///
- public virtual IDictionary DefaultHeader { get; set; }
+ [Obsolete("Use DefaultHeaders instead.")]
+ public virtual IDictionary DefaultHeader
+ {
+ get
+ {
+ return DefaultHeaders;
+ }
+ set
+ {
+ DefaultHeaders = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the default headers.
+ ///
+ public virtual IDictionary DefaultHeaders { get; set; }
///
/// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds.
@@ -374,17 +390,17 @@ namespace {{packageName}}.Client
Dictionary apiKey = first.ApiKey.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
Dictionary apiKeyPrefix = first.ApiKeyPrefix.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
- Dictionary defaultHeader = first.DefaultHeader.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
+ Dictionary defaultHeaders = first.DefaultHeaders.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
foreach (var kvp in second.ApiKey) apiKey[kvp.Key] = kvp.Value;
foreach (var kvp in second.ApiKeyPrefix) apiKeyPrefix[kvp.Key] = kvp.Value;
- foreach (var kvp in second.DefaultHeader) defaultHeader[kvp.Key] = kvp.Value;
+ foreach (var kvp in second.DefaultHeaders) defaultHeaders[kvp.Key] = kvp.Value;
var config = new Configuration
{
ApiKey = apiKey,
ApiKeyPrefix = apiKeyPrefix,
- DefaultHeader = defaultHeader,
+ DefaultHeader = defaultHeaders,
BasePath = second.BasePath ?? first.BasePath,
Timeout = second.Timeout,
UserAgent = second.UserAgent ?? first.UserAgent,
diff --git a/modules/openapi-generator/src/main/resources/csharp-netcore/IReadableConfiguration.mustache b/modules/openapi-generator/src/main/resources/csharp-netcore/IReadableConfiguration.mustache
index ce165e0c81d..0acef255d6c 100644
--- a/modules/openapi-generator/src/main/resources/csharp-netcore/IReadableConfiguration.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp-netcore/IReadableConfiguration.mustache
@@ -1,5 +1,6 @@
{{>partial_header}}
+using System;
using System.Collections.Generic;
namespace {{packageName}}.Client
@@ -43,8 +44,15 @@ namespace {{packageName}}.Client
/// Gets the default header.
///
/// Default header.
+ [Obsolete("Use DefaultHeaders instead.")]
IDictionary DefaultHeader { get; }
+ ///
+ /// Gets the default headers.
+ ///
+ /// Default headers.
+ IDictionary DefaultHeaders { get; }
+
///
/// Gets the temp folder path.
///
diff --git a/modules/openapi-generator/src/main/resources/csharp/api.mustache b/modules/openapi-generator/src/main/resources/csharp/api.mustache
index f3f3f7e578d..9e68b292591 100644
--- a/modules/openapi-generator/src/main/resources/csharp/api.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp/api.mustache
@@ -32,7 +32,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// {{#returnType}}{{returnType}}{{/returnType}}
- {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+ {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
///
/// {{summary}}
@@ -43,7 +43,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}
- ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+ ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
#endregion Synchronous Operations
{{#supportsAsync}}
@@ -58,7 +58,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}
- {{#returnType}}System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+ {{#returnType}}System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
///
/// {{summary}}
@@ -69,7 +69,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}
- System.Threading.Tasks.Task> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+ System.Threading.Tasks.Task> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}
#endregion Asynchronous Operations
{{/supportsAsync}}
@@ -190,7 +190,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// {{#returnType}}{{returnType}}{{/returnType}}
- public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
+ public {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{operationId}} ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#returnType}}ApiResponse<{{{returnType}}}> localVarResponse = {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
return localVarResponse.Data;{{/returnType}}{{^returnType}}{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{/returnType}}
@@ -202,7 +202,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// ApiResponse of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object(void){{/returnType}}
- public ApiResponse<{{#returnType}} {{{returnType}}} {{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
+ public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}WithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}
{{#required}}
@@ -325,7 +325,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// Task of {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}void{{/returnType}}
- {{#returnType}}public async System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}public async System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
+ {{#returnType}}public async System.Threading.Tasks.Task<{{{returnType}}}>{{/returnType}}{{^returnType}}public async System.Threading.Tasks.Task{{/returnType}} {{operationId}}Async ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#returnType}}ApiResponse<{{{returnType}}}> localVarResponse = await {{operationId}}AsyncWithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
return localVarResponse.Data;{{/returnType}}{{^returnType}}await {{operationId}}AsyncWithHttpInfo({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{/returnType}}
@@ -338,7 +338,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Thrown when fails to make API call
{{#allParams}}/// {{description}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}/// Task of ApiResponse{{#returnType}} ({{returnType}}){{/returnType}}
- public async System.Threading.Tasks.Task> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = null{{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
+ public async System.Threading.Tasks.Task> {{operationId}}AsyncWithHttpInfo ({{#allParams}}{{{dataType}}} {{paramName}}{{^required}}{{#optionalMethodArgument}} = default({{{dataType}}}){{/optionalMethodArgument}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
{
{{#allParams}}
{{#required}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/README.mustache b/modules/openapi-generator/src/main/resources/dart2/README.mustache
index 83c7a21222c..eab8ee0ea7a 100644
--- a/modules/openapi-generator/src/main/resources/dart2/README.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/README.mustache
@@ -74,9 +74,9 @@ import 'package:{{pubName}}/api.dart';
{{/authMethods}}
{{/hasAuthMethods}}
-var api_instance = new {{classname}}();
+var api_instance = {{classname}}();
{{#allParams}}
-var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}new {{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
+var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}{{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
{{/allParams}}
try {
diff --git a/modules/openapi-generator/src/main/resources/dart2/api.mustache b/modules/openapi-generator/src/main/resources/dart2/api.mustache
index 394ae1073a0..9ecac421b67 100644
--- a/modules/openapi-generator/src/main/resources/dart2/api.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/api.mustache
@@ -19,7 +19,7 @@ class {{classname}} {
{{#allParams}}
{{#required}}
if({{paramName}} == null) {
- throw new ApiException(400, "Missing required param: {{paramName}}");
+ throw ApiException(400, "Missing required param: {{paramName}}");
}
{{/required}}
{{/allParams}}
@@ -51,7 +51,7 @@ class {{classname}} {
if(contentType.startsWith("multipart/form-data")) {
bool hasFields = false;
- MultipartRequest mp = new MultipartRequest(null, null);
+ MultipartRequest mp = MultipartRequest(null, null);
{{#formParams}}
{{^isFile}}
if ({{paramName}} != null) {
@@ -89,7 +89,7 @@ class {{classname}} {
authNames);
if(response.statusCode >= 400) {
- throw new ApiException(response.statusCode, _decodeBodyBytes(response));
+ throw ApiException(response.statusCode, _decodeBodyBytes(response));
} else if(response.body != null) {
{{#isListContainer}}
{{#returnType}}
@@ -99,7 +99,7 @@ class {{classname}} {
{{^isListContainer}}
{{#isMapContainer}}
{{#returnType}}
- return new {{{returnType}}}.from(apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}'));
+ return {{{returnType}}}.from(apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}'));
{{/returnType}};
{{/isMapContainer}}
{{^isMapContainer}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache b/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache
index 773ee0d562e..7ef24590d16 100644
--- a/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache
@@ -45,9 +45,9 @@ import 'package:{{pubName}}/api.dart';
{{/authMethods}}
{{/hasAuthMethods}}
-var api_instance = new {{classname}}();
+var api_instance = {{classname}}();
{{#allParams}}
-var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}new {{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
+var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}{{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
{{/allParams}}
try {
diff --git a/modules/openapi-generator/src/main/resources/dart2/api_test.mustache b/modules/openapi-generator/src/main/resources/dart2/api_test.mustache
index 951aaf86d85..07459b09938 100644
--- a/modules/openapi-generator/src/main/resources/dart2/api_test.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/api_test.mustache
@@ -5,7 +5,7 @@ import 'package:test/test.dart';
/// tests for {{classname}}
void main() {
- var instance = new {{classname}}();
+ var instance = {{classname}}();
group('tests for {{classname}}', () {
{{#operation}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/class.mustache b/modules/openapi-generator/src/main/resources/dart2/class.mustache
index 5c2c2e8d8cf..9f9af4e51a7 100644
--- a/modules/openapi-generator/src/main/resources/dart2/class.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/class.mustache
@@ -36,7 +36,7 @@ class {{classname}} {
{{name}} = {{complexType}}.mapFromJson(json['{{baseName}}']);
{{/isMapContainer}}
{{^isMapContainer}}
- {{name}} = new {{complexType}}.fromJson(json['{{baseName}}']);
+ {{name}} = {{complexType}}.fromJson(json['{{baseName}}']);
{{/isMapContainer}}
{{/isListContainer}}
{{/complexType}}
@@ -49,7 +49,12 @@ class {{classname}} {
{{name}} = (json['{{baseName}}'] as Map).cast();
{{/isMapContainer}}
{{^isMapContainer}}
+ {{#isDouble}}
+ {{name}} = json['{{baseName}}'].toDouble();
+ {{/isDouble}}
+ {{^isDouble}}
{{name}} = json['{{baseName}}'];
+ {{/isDouble}}
{{/isMapContainer}}
{{/isListContainer}}
{{/complexType}}
@@ -81,13 +86,13 @@ class {{classname}} {
}
static List<{{classname}}> listFromJson(List json) {
- return json == null ? new List<{{classname}}>() : json.map((value) => new {{classname}}.fromJson(value)).toList();
+ return json == null ? List<{{classname}}>() : json.map((value) => {{classname}}.fromJson(value)).toList();
}
static Map mapFromJson(Map json) {
- var map = new Map();
+ var map = Map();
if (json != null && json.isNotEmpty) {
- json.forEach((String key, dynamic value) => map[key] = new {{classname}}.fromJson(value));
+ json.forEach((String key, dynamic value) => map[key] = {{classname}}.fromJson(value));
}
return map;
}
diff --git a/modules/openapi-generator/src/main/resources/dart2/model_test.mustache b/modules/openapi-generator/src/main/resources/dart2/model_test.mustache
index 89300fed75d..49f403ef695 100644
--- a/modules/openapi-generator/src/main/resources/dart2/model_test.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/model_test.mustache
@@ -5,7 +5,7 @@ import 'package:test/test.dart';
// tests for {{classname}}
void main() {
- var instance = new Pet();
+ var instance = {{classname}}();
group('test {{classname}}', () {
{{#vars}}
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/README.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/README.mustache
new file mode 100644
index 00000000000..2bc0198b4a2
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/README.mustache
@@ -0,0 +1,72 @@
+{{=<% %>=}}
+# OpenAPI Generated JavaScript/Express Server
+
+## Overview
+This server was generated using the [OpenAPI Generator](https://openapi-generator.tech) project. The code generator, and it's generated code allows you to develop your system with an API-First attitude, where the API contract is the anchor and definer of your project, and your code and business-logic aims to complete and comply to the terms in the API contract.
+
+### prerequisites
+- NodeJS >= 10.4
+- NPM >= 6.10.0
+
+The code was written on a mac, so assuming all should work smoothly on Linux-based computers. However, there is no reason not to run this library on Windows-based machines. If you find an OS-related problem, please open an issue and it will be resolved.
+
+### Running the server
+To run the server, run:
+
+```
+npm start
+```
+### View and test the API
+You can see the API documentation, and check the available endpoints by going to http://localhost:3000/api-docs/. Endpoints that require security need to have security handlers configured before they can return a successful response. At this point they will return [ a response code of 401](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401).
+##### At this stage the server does not support document body sent in xml format. Forms will be supported in the near future.
+
+### Node version and guidelines
+The code was written using Node version 10.6, and complies to the [Airbnb .eslint guiding rules](https://github.com/airbnb/javascript).
+
+### Project Files
+#### Root Directory:
+In the root directory we have (besides package.json, config.js, and log files):
+- **logger.js** - where we define the logger for the project. The project uses winston, but the purpose of this file is to enable users to change and modify their own logger behavior.
+- **index.js** - This is the project's 'main' file, and from here we launch the application. This is a very short and concise file, and the idea behind launching from this short file is to allow use-cases of launching the server with different parameters (changing config and/or logger) without affecting the rest of the code.
+- **expressServer.js** - The core of the Express.js server. This is where the express server is initialized, together with the OpenAPI validator, OpenAPI UI, and other libraries needed to start our server. If we want to add external links, that's where they would go. Our project uses the [express-openapi-validator](https://www.npmjs.com/package/express-openapi-validator) library that acts as a first step in the routing process - requests that are directed to paths defined in the `openapi.yaml` file are caught by this process, and it's parameters and bodyContent are validated against the schema. A successful result of this validation will be a new 'openapi' object added to the request. If the path requested is not part of the openapi.yaml file, the validator ignores the request and passes it on, as is, down the flow of the Express server.
+
+#### api/
+- **openapi.yaml** - This is the OpenAPI contract to which this server will comply. The file was generated using the codegen, and should contain everything needed to run the API Gateway - no references to external models/schemas.
+
+#### utils/
+Currently a single file:
+
+- **openapiRouter.js** - This is where the routing to our back-end code happens. If the request object includes an ```openapi``` object, it picks up the following values (that are part of the ```openapi.yaml``` file): 'x-openapi-router-controller', and 'x-openapi-router-service'. These variables are names of files/classes in the controllers and services directories respectively. The operationId of the request is also extracted. The operationId is a method in the controller and the service that was generated as part of the codegen process. The routing process sends the request and response objects to the controller, which will extract the expected variables from the request, and send it to be processed by the service, returning the response from the service to the caller.
+
+#### controllers/
+After validating the request, and ensuring this belongs to our API gateway, we send the request to a `controller`, where the variables and parameters are extracted from the request and sent to the relevant `service` for processing. The `controller` handles the response from the `service` and builds the appropriate HTTP response to be sent back to the user.
+
+- **index.js** - load all the controllers that were generated for this project, and export them to be used dynamically by the `openapiRouter.js`. If you would like to customize your controller, it is advised that you link to your controller here, and ensure that the codegen does not rewrite this file.
+
+- **Controller.js** - The core processor of the generated controllers. The generated controllers are designed to be as slim and generic as possible, referencing to the `Controller.js` for the business logic of parsing the needed variables and arguments from the request, and for building the HTTP response which will be sent back. The `Controller.js` is a class with static methods.
+
+- **{{x-openapi-router-controller}}.js** - auto-generated code, processing all the operations. The Controller is a class that is constructed with the service class it will be sending the request to. Every request defined by the `openapi.yaml` has an operationId. The operationId is the name of the method that will be called. Every method receives the request and response, and calls the `Controller.js` to process the request and response, adding the service method that should be called for the actual business-logic processing.
+
+#### services/
+This is where the API Gateway ends, and the unique business-logic of your application kicks in. Every endpoint in the `openapi.yaml` has a variable 'x-openapi-router-service', which is the name of the service class that is generated. The operationID of the endpoint is the name of the method that will be called. The generated code provides a simple promise with a try/catch clause. A successful operation ends with a call to the generic `Service.js` to build a successful response (payload and response code), and a failure will call the generic `Service.js` to build a response with an error object and the relevant response code. It is recommended to have the services be generated automatically once, and after the initial build add methods manually.
+
+- **index.js** - load all the services that were generated for this project, and export them to be used dynamically by the `openapiRouter.js`. If you would like to customize your service, it is advised that you link to your controller here, and ensure that the codegen does not rewrite this file.
+
+- **Service.js** - A utility class, very simple and thin at this point, with two static methods for building a response object for successful and failed results in the service operation. The default response code is 200 for success and 500 for failure. It is recommended to send more accurate response codes and override these defaults when relevant.
+
+- **{{x-openapi-router-service}}.js** - auto-generated code, providing a stub Promise for each operationId defined in the `openapi.yaml`. Each method receives the variables that were defined in the `openapi.yaml` file, and wraps a Promise in a try/catch clause. The Promise resolves both success and failure in a call to the `Service.js` utility class for building the appropriate response that will be sent back to the Controller and then to the caller of this endpoint.
+
+#### tests/
+- **serverTests.js** - basic server validation tests, checking that the server is up, that a call to an endpoint within the scope of the `openapi.yaml` file returns 200, that a call to a path outside that scope returns 200 if it exists and a 404 if not.
+- **routingTests.js** - Runs through all the endpoints defined in the `openapi.yaml`, and constructs a dummy request to send to the server. Confirms that the response code is 200. At this point requests containing xml or formData fail - currently they are not supported in the router.
+- **additionalEndpointsTests.js** - A test file for all the endpoints that are defined outside the openapi.yaml scope. Confirms that these endpoints return a successful 200 response.
+
+
+Future tests should be written to ensure that the response of every request sent should conform to the structure defined in the `openapi.yaml`. This test will fail 100% initially, and the job of the development team will be to clear these tests.
+
+
+#### models/
+Currently a concept awaiting feedback. The idea is to have the objects defined in the openapi.yaml act as models which are passed between the different modules. This will conform the programmers to interact using defined objects, rather than loosley-defined JSON objects. Given the nature of JavaScript progrmmers, who want to work with their own bootstrapped parameters, this concept might not work. Keeping this here for future discussion and feedback.
+
+
+
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/app.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/app.mustache
new file mode 100644
index 00000000000..34d7c9c1636
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/app.mustache
@@ -0,0 +1,30 @@
+const ExpressServer = require('./expressServer');
+const logger = require('./logger');
+// const swaggerRouter = require('./utils/swaggerRouter');
+
+class App {
+ constructor(config) {
+ this.config = config;
+ }
+
+ async launch() {
+ try {
+ this.expressServer = new ExpressServer(this.config.URL_PORT, this.config.OPENAPI_YAML);
+ // this.expressServer.app.use(swaggerRouter());
+ await this.expressServer.launch();
+ logger.info('Express server running');
+ } catch (error) {
+ logger.error(error);
+ await this.close();
+ }
+ }
+
+ async close() {
+ if (this.expressServer !== undefined) {
+ await this.expressServer.close();
+ logger.info(`Server shut down on port ${this.config.URL_PORT}`);
+ }
+ }
+}
+
+module.exports = App;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/config.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/config.mustache
new file mode 100644
index 00000000000..80f568992bd
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/config.mustache
@@ -0,0 +1,12 @@
+const path = require('path');
+
+const config = {
+ ROOT_DIR: __dirname,
+ URL_PORT: 3000,
+ URL_PATH: 'http://localhost',
+ BASE_VERSION: 'v2',
+ CONTROLLER_DIRECTORY: path.join(__dirname, 'controllers'),
+};
+config.OPENAPI_YAML = path.join(config.ROOT_DIR, 'api', 'openapi.yaml');
+config.FULL_PATH = `${config.URL_PATH}:${config.URL_PORT}/${config.BASE_VERSION}`;
+module.exports = config;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/controller.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/controller.mustache
new file mode 100644
index 00000000000..61d7290a3ed
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/controller.mustache
@@ -0,0 +1,18 @@
+const Controller = require('./Controller');
+
+class {{{classname}}}Controller {
+ constructor(Service) {
+ this.service = Service;
+ }
+
+{{#operations}}
+{{#operation}}
+ async {{operationId}}(request, response) {
+ await Controller.handleRequest(request, response, this.service.{{operationId}});
+ }
+
+{{/operation}}
+}
+
+module.exports = {{classname}}Controller;
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/Controller.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/Controller.mustache
new file mode 100644
index 00000000000..bdf8776c0e4
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/Controller.mustache
@@ -0,0 +1,72 @@
+const logger = require('../logger');
+
+class Controller {
+ static sendResponse(response, payload) {
+ /**
+ * The default response-code is 200. We want to allow to change that. in That case,
+ * payload will be an object consisting of a code and a payload. If not customized
+ * send 200 and the payload as received in this method.
+ */
+ response.status(payload.code || 200);
+ const responsePayload = payload.payload !== undefined ? payload.payload : payload;
+ if (responsePayload instanceof Object) {
+ response.json(responsePayload);
+ } else {
+ response.end(responsePayload);
+ }
+ }
+
+ static sendError(response, error) {
+ response.status(error.code || 500);
+ if (error.error instanceof Object) {
+ response.json(error.error);
+ } else {
+ response.end(error.error || error.message);
+ }
+ }
+
+ static collectFiles(request) {
+ logger.info('Checking if files are expected in schema');
+ if (request.openapi.schema.requestBody !== undefined) {
+ const [contentType] = request.headers['content-type'].split(';');
+ if (contentType === 'multipart/form-data') {
+ const contentSchema = request.openapi.schema.requestBody.content[contentType].schema;
+ Object.entries(contentSchema.properties).forEach(([name, property]) => {
+ if (property.type === 'string' && ['binary', 'base64'].indexOf(property.format) > -1) {
+ request.body[name] = request.files.find(file => file.fieldname === name);
+ }
+ });
+ } else if (request.openapi.schema.requestBody.content[contentType] !== undefined
+ && request.files !== undefined) {
+ [request.body] = request.files;
+ }
+ }
+ }
+
+ static collectRequestParams(request) {
+ this.collectFiles(request);
+ const requestParams = {};
+ if (request.openapi.schema.requestBody !== undefined) {
+ requestParams.body = request.body;
+ }
+ request.openapi.schema.parameters.forEach((param) => {
+ if (param.in === 'path') {
+ requestParams[param.name] = request.openapi.pathParams[param.name];
+ } else if (param.in === 'query') {
+ requestParams[param.name] = request.query[param.name];
+ }
+ });
+ return requestParams;
+ }
+
+ static async handleRequest(request, response, serviceOperation) {
+ try {
+ const serviceResponse = await serviceOperation(this.collectRequestParams(request));
+ Controller.sendResponse(response, serviceResponse);
+ } catch (error) {
+ Controller.sendError(response, error);
+ }
+ }
+}
+
+module.exports = Controller;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/index.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/index.mustache
new file mode 100644
index 00000000000..439b7d8f025
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/index.mustache
@@ -0,0 +1,25 @@
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+{{#operation}}
+{{#-first}}
+const {{classname}}Controller = require('./{{classname}}Controller');
+{{/-first}}
+{{/operation}}
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
+
+module.exports = {
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+{{#operation}}
+ {{#-first}}
+ {{classname}}Controller,
+ {{/-first}}
+{{/operation}}
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
+};
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/test.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/test.mustache
new file mode 100644
index 00000000000..516c135b45b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/controllers/test.mustache
@@ -0,0 +1,72 @@
+const Service = require('../services/Service');
+
+const testItems = require('../tests/testFiles/testItems.json');
+
+class TestService {
+ static testGetController() {
+ return new Promise(
+ async (resolve, reject) => {
+ try {
+ resolve(Service.successResponse(
+ testItems,
+ 200,
+ ));
+ } catch (e) {
+ const message = e.getMessage() || 'Could not get items. Server error';
+ reject(Service.rejectResponse(message, 500));
+ }
+ },
+ );
+
+ sendResponse(request, response) {
+ response.status(200);
+ const objectToReturn = {};
+ Object.keys(request.swagger.paramValues).forEach((key) => {
+ const val = request.swagger.paramValues[key];
+ if (val instanceof Object) {
+ objectToReturn[key] = val.originalname || val.name || val;
+ } else {
+ objectToReturn[key] = request.swagger.paramValues[key];
+ }
+ });
+ response.json(objectToReturn);
+ }
+
+ confirmRouteGetSingle(request, response) {
+ this.sendResponse(request, response);
+ }
+
+ confirmRouteGetMany(request, response) {
+ this.sendResponse(request, response);
+ }
+
+ confirmRoutePost(request, response) {
+ this.sendResponse(request, response);
+ }
+
+ confirmRoutePut(request, response) {
+ this.sendResponse(request, response);
+ }
+
+ async testGetController(request, response) {
+ await Controller.handleRequest(request, response, this.service.testGetController);
+ }
+
+ async testPostController(request, response) {
+ await Controller.handleRequest(request, response, this.service.testPostController);
+ }
+
+ async testPutController(request, response) {
+ await Controller.handleRequest(request, response, this.service.testPutController);
+ }
+
+ async testDeleteController(request, response) {
+ await Controller.handleRequest(request, response, this.service.testDeleteController);
+ }
+
+ async testFindByIdController(request, response) {
+ await Controller.handleRequest(request, response, this.service.testFindByIdController);
+ }
+}
+
+module.exports = TestController;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/eslintrc.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/eslintrc.mustache
new file mode 100644
index 00000000000..6d8abec4c52
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/eslintrc.mustache
@@ -0,0 +1,8 @@
+// Use this file as a starting point for your project's .eslintrc.
+// Copy this file, and add rule overrides as needed.
+{
+ "extends": "airbnb",
+ "rules": {
+ "no-console": "off"
+ }
+}
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/expressServer.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/expressServer.mustache
new file mode 100644
index 00000000000..64998cf2563
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/expressServer.mustache
@@ -0,0 +1,93 @@
+// const { Middleware } = require('swagger-express-middleware');
+const path = require('path');
+const swaggerUI = require('swagger-ui-express');
+const yamljs = require('yamljs');
+const express = require('express');
+const cors = require('cors');
+const cookieParser = require('cookie-parser');
+const bodyParser = require('body-parser');
+const { OpenApiValidator } = require('express-openapi-validator');
+const openapiRouter = require('./utils/openapiRouter');
+const logger = require('./logger');
+
+class ExpressServer {
+ constructor(port, openApiYaml) {
+ this.port = port;
+ this.app = express();
+ this.openApiPath = openApiYaml;
+ this.schema = yamljs.load(openApiYaml);
+ this.setupMiddleware();
+ }
+
+ setupMiddleware() {
+ // this.setupAllowedMedia();
+ this.app.use(cors());
+ this.app.use(bodyParser.json());
+ this.app.use(express.json());
+ this.app.use(express.urlencoded({ extended: false }));
+ this.app.use(cookieParser());
+ this.app.use('/spec', express.static(path.join(__dirname, 'api')));
+ this.app.get('/hello', (req, res) => res.send('Hello World. path: '+this.openApiPath));
+ // this.app.get('/spec', express.static(this.openApiPath));
+ this.app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(this.schema));
+ this.app.get('/login-redirect', (req, res) => {
+ res.status(200);
+ res.json(req.query);
+ });
+ this.app.get('/oauth2-redirect.html', (req, res) => {
+ res.status(200);
+ res.json(req.query);
+ });
+ new OpenApiValidator({
+ apiSpecPath: this.openApiPath,
+ }).install(this.app);
+ this.app.use(openapiRouter());
+ this.app.get('/', (req, res) => {
+ res.status(200);
+ res.end('Hello World');
+ });
+ }
+
+ addErrorHandler() {
+ this.app.use('*', (req, res) => {
+ res.status(404);
+ res.send(JSON.stringify({ error: `path ${req.baseUrl} doesn't exist` }));
+ });
+ /**
+ * suppressed eslint rule: The next variable is required here, even though it's not used.
+ *
+ ** */
+ // eslint-disable-next-line no-unused-vars
+ this.app.use((error, req, res, next) => {
+ const errorResponse = error.error || error.errors || error.message || 'Unknown error';
+ res.status(error.status || 500);
+ res.type('json');
+ res.json({ error: errorResponse });
+ });
+ }
+
+ async launch() {
+ return new Promise(
+ async (resolve, reject) => {
+ try {
+ this.addErrorHandler();
+ this.server = await this.app.listen(this.port, () => {
+ console.log(`server running on port ${this.port}`);
+ resolve(this.server);
+ });
+ } catch (error) {
+ reject(error);
+ }
+ },
+ );
+ }
+
+ async close() {
+ if (this.server !== undefined) {
+ await this.server.close();
+ console.log(`Server on port ${this.port} shut down`);
+ }
+ }
+}
+
+module.exports = ExpressServer;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/index.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/index.mustache
new file mode 100644
index 00000000000..cc9dbc7e54b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/index.mustache
@@ -0,0 +1,28 @@
+const config = require('./config');
+const logger = require('./logger');
+const ExpressServer = require('./expressServer');
+// const App = require('./app');
+
+// const app = new App(config);
+// app.launch()
+// .then(() => {
+// logger.info('Server launched');
+// })
+// .catch((error) => {
+// logger.error('found error, shutting down server');
+// app.close()
+// .catch(closeError => logger.error(closeError))
+// .finally(() => logger.error(error));
+// });
+const launchServer = async () => {
+ try {
+ this.expressServer = new ExpressServer(config.URL_PORT, config.OPENAPI_YAML);
+ await this.expressServer.launch();
+ logger.info('Express server running');
+ } catch (error) {
+ logger.error(error);
+ await this.close();
+ }
+};
+
+launchServer().catch(e => logger.error(e));
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/logger.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/logger.mustache
new file mode 100644
index 00000000000..27134586f8e
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/logger.mustache
@@ -0,0 +1,17 @@
+const winston = require('winston');
+
+const logger = winston.createLogger({
+ level: 'info',
+ format: winston.format.json(),
+ defaultMeta: { service: 'user-service' },
+ transports: [
+ new winston.transports.File({ filename: 'error.log', level: 'error' }),
+ new winston.transports.File({ filename: 'combined.log' }),
+ ],
+});
+
+if (process.env.NODE_ENV !== 'production') {
+ logger.add(new winston.transports.Console({ format: winston.format.simple() }));
+}
+
+module.exports = logger;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/openapi.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/openapi.mustache
new file mode 100644
index 00000000000..51ebafb0187
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/openapi.mustache
@@ -0,0 +1 @@
+{{{openapi-yaml}}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/package.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/package.mustache
new file mode 100644
index 00000000000..e4bdc09d99b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/package.mustache
@@ -0,0 +1,46 @@
+{
+ "name": "openapi-petstore",
+ "version": "1.0.0",
+ "description": "This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.",
+ "main": "index.js",
+ "scripts": {
+ "prestart": "npm install",
+ "start": "node index.js"
+ },
+ "keywords": [
+ "openapi-generator",
+ "openapi"
+ ],
+ "license": "Unlicense",
+ "private": true,
+ "dependencies": {
+ "body-parser": "^1.19.0",
+ "connect": "^3.2.0",
+ "cookie-parser": "^1.4.4",
+ "cors": "^2.8.5",
+ "express": "^4.16.4",
+ "express-openapi-validator": "^1.0.0",
+ "js-yaml": "^3.3.0",
+ "jstoxml": "^1.5.0",
+ "ono": "^5.0.1",
+ "openapi-sampler": "^1.0.0-beta.15",
+ "swagger-express-middleware": "^2.0.2",
+ "swagger-tools": "^0.10.4",
+ "swagger-ui-express": "^4.0.2",
+ "winston": "^3.2.1",
+ "yamljs": "^0.3.0",
+ "mocha": "^6.1.4",
+ "axios": "^0.19.0",
+ "chai": "^4.2.0",
+ "chai-as-promised": "^7.1.1",
+ "eslint": "^5.16.0",
+ "eslint-config-airbnb-base": "^13.1.0",
+ "eslint-plugin-import": "^2.17.2",
+ "form-data": "^2.3.3"
+ },
+ "eslintConfig": {
+ "env": {
+ "node": true
+ }
+ }
+}
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/service.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/service.mustache
new file mode 100644
index 00000000000..b5f39b4577f
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/service.mustache
@@ -0,0 +1,45 @@
+/* eslint-disable no-unused-vars */
+const Service = require('./Service');
+
+class {{{classname}}}Service {
+
+{{#operations}}
+{{#operation}}
+ /**
+ {{#summary}}
+ * {{{summary}}}
+ {{/summary}}
+ {{#notes}}
+ * {{{notes}}}
+ {{/notes}}
+ *
+ {{#allParams}}
+ * {{paramName}} {{{dataType}}} {{{description}}}{{^required}} (optional){{/required}}
+ {{/allParams}}
+ {{^returnType}}
+ * no response value expected for this operation
+ {{/returnType}}
+ {{#returnType}}
+ * returns {{{returnType}}}
+ {{/returnType}}
+ **/
+ static {{{operationId}}}({{#allParams}}{{#-first}}{ {{/-first}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{#-last}} }{{/-last}}{{/allParams}}) {
+ return new Promise(
+ async (resolve) => {
+ try {
+ resolve(Service.successResponse(''));
+ } catch (e) {
+ resolve(Service.rejectResponse(
+ e.message || 'Invalid input',
+ e.status || 405,
+ ));
+ }
+ },
+ );
+ }
+
+{{/operation}}
+}
+
+module.exports = {{{classname}}}Service;
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/services/Service.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/services/Service.mustache
new file mode 100644
index 00000000000..11f8c9a1c3a
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/services/Service.mustache
@@ -0,0 +1,11 @@
+class Service {
+ static rejectResponse(error, code = 500) {
+ return { error, code };
+ }
+
+ static successResponse(payload, code = 200) {
+ return { payload, code };
+ }
+}
+
+module.exports = Service;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/services/index.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/services/index.mustache
new file mode 100644
index 00000000000..19478453fa8
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/services/index.mustache
@@ -0,0 +1,25 @@
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+{{#operation}}
+{{#-first}}
+const {{classname}}Service = require('./{{classname}}Service');
+{{/-first}}
+{{/operation}}
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
+
+module.exports = {
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+{{#operation}}
+{{#-first}}
+ {{classname}}Service,
+{{/-first}}
+{{/operation}}
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
+};
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/utils/openapiRouter.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/utils/openapiRouter.mustache
new file mode 100644
index 00000000000..1a77fec7b61
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/utils/openapiRouter.mustache
@@ -0,0 +1,67 @@
+const logger = require('../logger');
+const controllers = require('../controllers');
+const Services = require('../services');
+
+function handleError(err, request, response, next) {
+ logger.error(err);
+ const code = err.code || 400;
+ response.status(code);
+ response.error = err;
+ next(JSON.stringify({
+ code,
+ error: err,
+ }));
+}
+
+/**
+ * The purpose of this route is to collect the request variables as defined in the
+ * OpenAPI document and pass them to the handling controller as another Express
+ * middleware. All parameters are collected in the requet.swagger.values key-value object
+ *
+ * The assumption is that security handlers have already verified and allowed access
+ * to this path. If the business-logic of a particular path is dependant on authentication
+ * parameters (e.g. scope checking) - it is recommended to define the authentication header
+ * as one of the parameters expected in the OpenAPI/Swagger document.
+ *
+ * Requests made to paths that are not in the OpernAPI scope
+ * are passed on to the next middleware handler.
+ * @returns {Function}
+ */
+function openApiRouter() {
+ return async (request, response, next) => {
+ try {
+ /**
+ * This middleware runs after a previous process have applied an openapi object
+ * to the request.
+ * If none was applied This is because the path requested is not in the schema.
+ * If there's no openapi object, we have nothing to do, and pass on to next middleware.
+ */
+ if (request.openapi === undefined
+ || request.openapi.schema === undefined
+ ) {
+ next();
+ return;
+ }
+ // request.swagger.paramValues = {};
+ // request.swagger.params.forEach((param) => {
+ // request.swagger.paramValues[param.name] = getValueFromRequest(request, param);
+ // });
+ const controllerName = request.openapi.schema['x-openapi-router-controller'];
+ const serviceName = request.openapi.schema['x-openapi-router-service'];
+ if (!controllers[controllerName] || controllers[controllerName] === undefined) {
+ handleError(`request sent to controller '${controllerName}' which has not been defined`,
+ request, response, next);
+ } else {
+ const apiController = new controllers[controllerName](Services[serviceName]);
+ const controllerOperation = request.openapi.schema.operationId;
+ await apiController[controllerOperation](request, response, next);
+ }
+ } catch (error) {
+ console.error(error);
+ const err = { code: 500, error: error.message };
+ handleError(err, request, response, next);
+ }
+ };
+}
+
+module.exports = openApiRouter;
diff --git a/modules/openapi-generator/src/main/resources/nodejs-express-server/utils/writer.mustache b/modules/openapi-generator/src/main/resources/nodejs-express-server/utils/writer.mustache
new file mode 100644
index 00000000000..d79f6e1a526
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/nodejs-express-server/utils/writer.mustache
@@ -0,0 +1,43 @@
+var ResponsePayload = function(code, payload) {
+ this.code = code;
+ this.payload = payload;
+}
+
+exports.respondWithCode = function(code, payload) {
+ return new ResponsePayload(code, payload);
+}
+
+var writeJson = exports.writeJson = function(response, arg1, arg2) {
+ var code;
+ var payload;
+
+ if(arg1 && arg1 instanceof ResponsePayload) {
+ writeJson(response, arg1.payload, arg1.code);
+ return;
+ }
+
+ if(arg2 && Number.isInteger(arg2)) {
+ code = arg2;
+ }
+ else {
+ if(arg1 && Number.isInteger(arg1)) {
+ code = arg1;
+ }
+ }
+ if(code && arg1) {
+ payload = arg1;
+ }
+ else if(arg1) {
+ payload = arg1;
+ }
+
+ if(!code) {
+ // if no response code given, we default to 200
+ code = 200;
+ }
+ if(typeof payload === 'object') {
+ payload = JSON.stringify(payload, null, 2);
+ }
+ response.writeHead(code, {'Content-Type': 'application/json'});
+ response.end(payload);
+}
diff --git a/modules/openapi-generator/src/main/resources/ocaml/api-impl.mustache b/modules/openapi-generator/src/main/resources/ocaml/api-impl.mustache
new file mode 100644
index 00000000000..8e86eeb45ab
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/api-impl.mustache
@@ -0,0 +1,67 @@
+{{>partial_header}}
+{{#operations}}
+{{#operation}}
+{{#description}}
+ * Schema {{{classname}}} : {{{description}}}
+{{/description}}
+{{/operation}}
+{{/operations}}
+ *)
+
+{{#operations}}
+{{#operation}}
+let {{{operationId}}} {{^hasParams}}(){{/hasParams}}{{#allParams}}{{> to_param}}{{#hasMore}} {{/hasMore}}{{#-last}}{{^required}} (){{/required}}{{/-last}}{{/allParams}} =
+ let open Lwt in
+ let uri = Request.build_uri "{{{path}}}" in
+ let headers = Request.default_headers in
+{{#hasAuthMethods}}
+ {{#authMethods}}
+ {{#isApiKey}}
+ {{#isKeyInHeader}}
+ let headers = Cohttp.Header.add headers "{{{keyParamName}}}" Request.api_key in
+ {{/isKeyInHeader}}
+ {{/isApiKey}}
+ {{/authMethods}}
+{{/hasAuthMethods}}
+{{#headerParams}}
+ let headers = Request.{{> to_optional_prefix}}add_header{{#isContainer}}_multi{{/isContainer}} headers "{{baseName}}" {{> to_string}} {{{paramName}}} in
+{{/headerParams}}
+{{#pathParams}}
+ let uri = Request.{{> to_optional_prefix}}replace_path_param uri "{{{baseName}}}" {{> to_string}} {{{paramName}}} in
+{{/pathParams}}
+{{#queryParams}}
+ let uri = Request.{{> to_optional_prefix}}add_query_param{{#isListContainer}}_list{{/isListContainer}} uri "{{{baseName}}}" {{> to_string}} {{{paramName}}} in
+{{/queryParams}}
+{{#hasAuthMethods}}
+ {{#authMethods}}
+ {{#isApiKey}}
+ {{#isKeyInQuery}}
+ let uri = Uri.add_query_param' uri ("{{{keyParamName}}}", Request.api_key) in
+ {{/isKeyInQuery}}
+ {{/isApiKey}}
+ {{/authMethods}}
+{{/hasAuthMethods}}
+{{#bodyParams}}
+ let body = Request.{{#isFreeFormObject}}write_json_body{{/isFreeFormObject}}{{#isByteArray}}write_string_body{{/isByteArray}}{{^isFreeFormObject}}{{^isByteArray}}write_as_json_body{{/isByteArray}}{{/isFreeFormObject}} {{> to_json}} {{{paramName}}} in
+{{/bodyParams}}
+{{^hasBodyParam}}
+ {{#hasFormParams}}
+ let body = Request.init_form_encoded_body () in
+ {{/hasFormParams}}
+ {{#formParams}}
+ let body = Request.{{> to_optional_prefix}}add_form_encoded_body_param{{#isContainer}}_list{{/isContainer}} body "{{{paramName}}}" {{> to_string}} {{{paramName}}} in
+ {{/formParams}}
+ {{#hasFormParams}}
+ let body = Request.finalize_form_encoded_body body in
+ {{/hasFormParams}}
+{{/hasBodyParam}}
+ Cohttp_lwt_unix.Client.call `{{{httpMethod}}} uri ~headers {{#hasBodyParam}}~body {{/hasBodyParam}}{{^hasBodyParam}}{{#hasFormParams}}~body {{/hasFormParams}}{{/hasBodyParam}}>>= fun (resp, body) ->
+{{^returnType}}
+ Request.handle_unit_response resp
+{{/returnType}}
+{{#returnType}}
+ Request.read_json_body{{#returnContainer}}{{#isListContainer}}_as_list{{/isListContainer}}{{#isMapContainer}}_as_map{{/isMapContainer}}{{#returnBaseType}}{{^vendorExtensions.x-returnFreeFormObject}}_of{{/vendorExtensions.x-returnFreeFormObject}}{{/returnBaseType}}{{/returnContainer}}{{^returnContainer}}{{#returnBaseType}}{{^vendorExtensions.x-returnFreeFormObject}}_as{{/vendorExtensions.x-returnFreeFormObject}}{{/returnBaseType}}{{/returnContainer}} {{#returnType}}{{^vendorExtensions.x-returnFreeFormObject}}({{> of_json}}){{/vendorExtensions.x-returnFreeFormObject}}{{/returnType}} resp body
+{{/returnType}}
+
+{{/operation}}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/ocaml/api-intf.mustache b/modules/openapi-generator/src/main/resources/ocaml/api-intf.mustache
new file mode 100644
index 00000000000..42525de317c
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/api-intf.mustache
@@ -0,0 +1,15 @@
+{{>partial_header}}
+{{#operations}}
+{{#operation}}
+{{#description}}
+ * Schema {{{classname}}} : {{{description}}}
+{{/description}}
+{{/operation}}
+{{/operations}}
+ *)
+
+{{#operations}}
+{{#operation}}
+val {{{operationId}}} : {{^hasParams}}unit{{/hasParams}}{{#allParams}}{{#required}}{{{paramName}}}{{/required}}{{^required}}{{^isBodyParam}}?{{/isBodyParam}}{{{paramName}}}{{/required}}:{{#isEnum}}Enums.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#hasMore}} -> {{/hasMore}}{{#-last}}{{^required}} -> unit{{/required}}{{/-last}}{{/allParams}} -> {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}unit{{/returnType}} Lwt.t
+{{/operation}}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/ocaml/dune-project.mustache b/modules/openapi-generator/src/main/resources/ocaml/dune-project.mustache
new file mode 100644
index 00000000000..8e48d839f68
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/dune-project.mustache
@@ -0,0 +1,2 @@
+(lang dune 1.10)
+(name {{{packageName}}})
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/dune.mustache b/modules/openapi-generator/src/main/resources/ocaml/dune.mustache
new file mode 100644
index 00000000000..e7a9352401d
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/dune.mustache
@@ -0,0 +1,9 @@
+(include_subdirs unqualified)
+(library
+ (name {{{packageName}}})
+ (public_name {{{packageName}}})
+ (flags (:standard -w -27))
+ (libraries str cohttp-lwt-unix lwt yojson ppx_deriving_yojson.runtime)
+ (preprocess (pps ppx_deriving_yojson ppx_deriving.std))
+ (wrapped true)
+)
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/enums.mustache b/modules/openapi-generator/src/main/resources/ocaml/enums.mustache
new file mode 100644
index 00000000000..a9aed87db27
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/enums.mustache
@@ -0,0 +1,25 @@
+{{>partial_header}}
+{{#description}}
+ * Schema {{{classname}}} : {{{description}}}
+{{/description}}
+ *)
+{{#models}}
+{{#model}}
+{{#isEnum}}
+
+type {{name}} = [
+{{#allowableValues}}
+{{#values}}
+| {{{camlEnumValueName}}} [@printer fun fmt _ -> Format.pp_print_string fmt "{{{name}}}"] [@name "{{{name}}}"]
+{{/values}}
+{{/allowableValues}}
+] [@@deriving yojson, show { with_path = false }];;
+
+let {{name}}_of_yojson json = {{name}}_of_yojson (`List [json])
+let {{name}}_to_yojson e =
+ match {{name}}_to_yojson e with
+ | `List [json] -> json
+ | json -> json
+{{/isEnum}}
+{{/model}}
+{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/ocaml/json.mustache b/modules/openapi-generator/src/main/resources/ocaml/json.mustache
new file mode 100644
index 00000000000..4b0fac77545
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/json.mustache
@@ -0,0 +1,55 @@
+open Ppx_deriving_yojson_runtime
+
+let unwrap to_json json =
+ match to_json json with
+ | Result.Ok json -> json
+ | Result.Error s -> failwith s
+
+let to_int json =
+ match json with
+ | `Int x -> x
+ | `Intlit s -> int_of_string s
+ | _ -> failwith "JsonSupport.to_int"
+
+let to_bool json =
+ match json with
+ | `Bool x -> x
+ | _ -> failwith "JsonSupport.to_bool"
+
+let to_float json =
+ match json with
+ | `Float x -> x
+ | _ -> failwith "JsonSupport.to_float"
+
+let to_string json =
+ match json with
+ | `String s -> s
+ | _ -> failwith "JsonSupport.to_string"
+
+let to_int32 json : int32 =
+ match json with
+ | `Int x -> Int32.of_int x
+ | `Intlit s -> Int32.of_string s
+ | _ -> failwith "JsonSupport.to_int32"
+
+let to_int64 json : int64 =
+ match json with
+ | `Int x -> Int64.of_int x
+ | `Intlit s -> Int64.of_string s
+ | _ -> failwith "JsonSupport.to_int64"
+
+let of_int x = `Int x
+
+let of_bool b = `Bool b
+
+let of_float x = `Float x
+
+let of_string s = `String s
+
+let of_int32 x = `Intlit (Int32.to_string x)
+
+let of_int64 x = `Intlit (Int64.to_string x)
+
+let of_list_of of_f l = `List (List.map of_f l)
+
+let of_map_of of_f l = `Assoc (List.map (fun (k, v) -> (k, of_f v)) l)
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/lib.mustache b/modules/openapi-generator/src/main/resources/ocaml/lib.mustache
new file mode 100644
index 00000000000..627f3227880
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/lib.mustache
@@ -0,0 +1,15 @@
+opam-version: "2.0"
+name: "{{{packageName}}}"
+version: "{{{packageVersion}}}"
+synopsis: "{{{packageDescription}}}"
+description: """
+Longer description
+"""
+maintainer: "Name "
+authors: "Name "
+license: ""
+homepage: ""
+bug-reports: ""
+dev-repo: ""
+depends: [ "ocaml" "ocamlfind" ]
+build: ["dune" "build" "-p" name]
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/model.mustache b/modules/openapi-generator/src/main/resources/ocaml/model.mustache
new file mode 100644
index 00000000000..dd45db1915b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/model.mustache
@@ -0,0 +1,38 @@
+{{>partial_header}}
+{{#models}}
+{{#model}}
+{{#description}}
+ * Schema {{{classname}}} : {{{description}}}
+ *)
+{{/description}}
+{{^description}}
+ *)
+{{/description}}
+
+{{^isEnum}}
+type t = {
+{{#vars}}
+ {{#description}}
+ (* {{{description}}} *)
+ {{/description}}
+ {{#isEnum}}
+ {{{name}}}: {{^isMapContainer}}Enums.{{/isMapContainer}}{{{datatypeWithEnum}}}{{^isContainer}}{{#required}}{{#defaultValue}}[@default {{{defaultValue}}}]{{/defaultValue}}{{/required}}{{/isContainer}}{{^isContainer}}{{#required}}{{#isNullable}} option [@default {{#defaultValue}}Some({{{defaultValue}}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}]{{/isNullable}}{{/required}}{{/isContainer}}{{^isContainer}}{{^required}} option [@default {{#defaultValue}}Some({{{defaultValue}}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}]{{/required}}{{/isContainer}};
+ {{/isEnum}}
+ {{^isEnum}}
+ {{{name}}}: {{{datatypeWithEnum}}}{{^isContainer}}{{#required}}{{#isNullable}} option{{/isNullable}}{{/required}}{{/isContainer}}{{^isContainer}}{{^required}} option [@default None]{{/required}}{{/isContainer}};
+ {{/isEnum}}
+{{/vars}}
+} [@@deriving yojson { strict = false }, show ];;
+
+{{#description}}
+(** {{{description}}} *)
+{{/description}}
+let create {{#requiredVars}}({{{name}}} : {{#isEnum}}Enums.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}option{{/isNullable}}){{^-last}} {{/-last}}{{/requiredVars}}{{^hasRequired}}(){{/hasRequired}} : t = {
+ {{#vars}}
+ {{{name}}} = {{#required}}{{{name}}}{{/required}}{{^required}}{{#isContainer}}[]{{/isContainer}}{{^isContainer}}None{{/isContainer}}{{/required}};
+ {{/vars}}
+}
+{{/isEnum}}
+
+{{/model}}
+{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/ocaml/of_json.mustache b/modules/openapi-generator/src/main/resources/ocaml/of_json.mustache
new file mode 100644
index 00000000000..a7be3d4d7ca
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/of_json.mustache
@@ -0,0 +1 @@
+{{#isEnum}}JsonSupport.unwrap Enums.{{{datatypeWithEnum}}}_of_yojson{{/isEnum}}{{^isEnum}}{{#returnType}}{{#returnTypeIsPrimitive}}JsonSupport.to_{{{returnBaseType}}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#vendorExtensions.x-modelModule}}JsonSupport.unwrap {{{vendorExtensions.x-modelModule}}}.of_yojson{{/vendorExtensions.x-modelModule}}{{^vendorExtensions.x-modelModule}}JsonSupport.unwrap {{{returnBaseType}}}.of_yojson{{/vendorExtensions.x-modelModule}}{{/returnTypeIsPrimitive}}{{/returnType}}{{/isEnum}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/partial_header.mustache b/modules/openapi-generator/src/main/resources/ocaml/partial_header.mustache
new file mode 100644
index 00000000000..c4bbcd913c4
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/partial_header.mustache
@@ -0,0 +1,5 @@
+(*
+ * This file has been generated by the OCamlClientCodegen generator for openapi-generator.
+ *
+ * Generated by: https://openapi-generator.tech
+ *
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/readme.mustache b/modules/openapi-generator/src/main/resources/ocaml/readme.mustache
new file mode 100644
index 00000000000..2ecff7daa88
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/readme.mustache
@@ -0,0 +1,35 @@
+# {{{projectName}}}
+{{#appDescription}}
+{{{appDescription}}}
+{{/appDescription}}
+
+This OCaml package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: {{appVersion}}
+- Package version: {{packageVersion}}
+{{^hideGenerationTimestamp}}
+- Build date: {{generatedDate}}
+{{/hideGenerationTimestamp}}
+- Build package: {{generatorClass}}
+{{#infoUrl}}
+For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
+{{/infoUrl}}
+
+## Requirements.
+
+OCaml 4.x
+
+## Installation
+
+Please run the following commands to build the package `{{{packageName}}}`:
+
+```sh
+opam install ppx_deriving_yojson cohttp ppx_deriving cohttp-lwt-unix
+eval $(opam env)
+dune build
+```
+
+## Getting Started
+
+TODO
+
diff --git a/modules/openapi-generator/src/main/resources/ocaml/support.mustache b/modules/openapi-generator/src/main/resources/ocaml/support.mustache
new file mode 100644
index 00000000000..bc6d7a86f98
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/support.mustache
@@ -0,0 +1,97 @@
+let api_key = ""
+let base_url = "{{{basePath}}}"
+let default_headers = Cohttp.Header.init_with "Content-Type" "application/json"
+
+let option_fold f default o =
+ match o with
+ | Some v -> f v
+ | None -> default
+
+let build_uri operation_path = Uri.of_string (base_url ^ operation_path)
+
+let add_string_header headers key value =
+ Cohttp.Header.add headers key value
+
+let add_string_header_multi headers key values =
+ Cohttp.Header.add_multi headers key values
+
+let add_header headers key to_string value =
+ Cohttp.Header.add headers key (to_string value)
+
+let add_header_multi headers key to_string value =
+ Cohttp.Header.add_multi headers key (to_string value)
+
+let maybe_add_header headers key to_string value =
+ option_fold (add_header headers key to_string) headers value
+
+let maybe_add_header_multi headers key to_string value =
+ option_fold (add_header_multi headers key to_string) headers value
+
+let write_string_body s = Cohttp_lwt.Body.of_string s
+
+let write_json_body payload =
+ Cohttp_lwt.Body.of_string (Yojson.Safe.to_string payload ~std:true)
+
+let write_as_json_body to_json payload = write_json_body (to_json payload)
+
+let handle_response resp on_success_handler =
+ match Cohttp_lwt.Response.status resp with
+ | #Cohttp.Code.success_status -> on_success_handler ()
+ | s -> failwith ("Server responded with status " ^ Cohttp.Code.(reason_phrase_of_code (code_of_status s)))
+
+let handle_unit_response resp = handle_response resp (fun () -> Lwt.return ())
+
+let read_json_body resp body =
+ handle_response resp (fun () ->
+ (Lwt.(Cohttp_lwt.Body.to_string body >|= Yojson.Safe.from_string)))
+
+let read_json_body_as of_json resp body =
+ Lwt.(read_json_body resp body >|= of_json)
+
+let read_json_body_as_list resp body =
+ Lwt.(read_json_body resp body >|= Yojson.Safe.Util.to_list)
+
+let read_json_body_as_list_of of_json resp body =
+ Lwt.(read_json_body_as_list resp body >|= List.map of_json)
+
+let read_json_body_as_map resp body =
+ Lwt.(read_json_body resp body >|= Yojson.Safe.Util.to_assoc)
+
+let read_json_body_as_map_of of_json resp body =
+ Lwt.(read_json_body_as_map resp body >|= List.map (fun (s, v) -> (s, of_json v)))
+
+let replace_string_path_param uri param_name param_value =
+ let regexp = Str.regexp (Str.quote ("{" ^ param_name ^ "}")) in
+ let path = Str.global_replace regexp param_value (Uri.pct_decode (Uri.path uri)) in
+ Uri.with_path uri path
+
+let replace_path_param uri param_name to_string param_value =
+ replace_string_path_param uri param_name (to_string param_value)
+
+let maybe_replace_path_param uri param_name to_string param_value =
+ option_fold (replace_path_param uri param_name to_string) uri param_value
+
+let add_query_param uri param_name to_string param_value =
+ Uri.add_query_param' uri (param_name, to_string param_value)
+
+let add_query_param_list uri param_name to_string param_value =
+ Uri.add_query_param uri (param_name, to_string param_value)
+
+let maybe_add_query_param uri param_name to_string param_value =
+ option_fold (add_query_param uri param_name to_string) uri param_value
+
+let init_form_encoded_body () = ""
+
+let add_form_encoded_body_param params param_name to_string param_value =
+ let new_param_enc = Printf.sprintf {|%s=%s|} (Uri.pct_encode param_name) (Uri.pct_encode (to_string param_value)) in
+ if params = ""
+ then new_param_enc
+ else Printf.sprintf {|%s&%s|} params new_param_enc
+
+let add_form_encoded_body_param_list params param_name to_string new_params =
+ add_form_encoded_body_param params param_name (String.concat ",") (to_string new_params)
+
+let maybe_add_form_encoded_body_param params param_name to_string param_value =
+ option_fold (add_form_encoded_body_param params param_name to_string) params param_value
+
+let finalize_form_encoded_body body = Cohttp_lwt.Body.of_string body
diff --git a/modules/openapi-generator/src/main/resources/ocaml/to_json.mustache b/modules/openapi-generator/src/main/resources/ocaml/to_json.mustache
new file mode 100644
index 00000000000..6b8fea90fdc
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/to_json.mustache
@@ -0,0 +1 @@
+{{#isListContainer}}{{#items}}(JsonSupport.of_list_of {{> to_json}}){{/items}}{{/isListContainer}}{{#isMapContainer}}{{#items}}(JsonSupport.of_map_of {{> to_json}}){{/items}}{{/isMapContainer}}{{#isString}}JsonSupport.of_string{{/isString}}{{#isLong}}JsonSupport.of_int64{{/isLong}}{{#isInteger}}JsonSupport.of_int32{{/isInteger}}{{#isFloat}}JsonSupport.of_float{{/isFloat}}{{#isNumber}}JsonSupport.of_float{{/isNumber}}{{#isDouble}}JsonSupport.of_float{{/isDouble}}{{#isBoolean}}JsonSupport.of_bool{{/isBoolean}}{{^isEnum}}{{#isModel}}{{#vendorExtensions.x-modelModule}}{{{vendorExtensions.x-modelModule}}}.to_yojson{{/vendorExtensions.x-modelModule}}{{^vendorExtensions.x-modelModule}}{{{baseType}}}.to_yojson{{/vendorExtensions.x-modelModule}}{{/isModel}}{{/isEnum}}{{^isModel}}{{^isContainer}}{{#isEnum}}Enums.{{{datatypeWithEnum}}}_to_yojson{{/isEnum}}{{/isContainer}}{{/isModel}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/to_optional_prefix.mustache b/modules/openapi-generator/src/main/resources/ocaml/to_optional_prefix.mustache
new file mode 100644
index 00000000000..aa35be7da04
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/to_optional_prefix.mustache
@@ -0,0 +1 @@
+{{^required}}{{^defaultValue}}{{^isContainer}}maybe_{{/isContainer}}{{/defaultValue}}{{/required}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/to_param.mustache b/modules/openapi-generator/src/main/resources/ocaml/to_param.mustache
new file mode 100644
index 00000000000..59bd7672b9c
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/to_param.mustache
@@ -0,0 +1 @@
+{{^isBodyParam}}{{^required}}?{{#defaultValue}}({{{paramName}}} = {{^isEnum}}{{#isString}}"{{{defaultValue}}}"{{/isString}}{{#isBoolean}}{{{defaultValue}}}{{/isBoolean}}{{#isShort}}{{{defaultValue}}}{{/isShort}}{{#isInteger}}{{{defaultValue}}}l{{/isInteger}}{{#isLong}}{{{defaultValue}}}L{{/isLong}}{{#isFloat}}{{{defaultValue}}}.{{/isFloat}}{{#isNumber}}{{{defaultValue}}}.{{/isNumber}}{{/isEnum}}{{#isEnum}}{{#isContainer}}[{{{defaultValue}}}]{{/isContainer}}{{^isContainer}}{{{defaultValue}}}{{/isContainer}}{{/isEnum}}){{/defaultValue}}{{^defaultValue}}{{^isContainer}}{{{paramName}}}{{/isContainer}}{{#isContainer}}({{{paramName}}} = []){{/isContainer}}{{/defaultValue}}{{/required}}{{#required}}~{{{paramName}}}{{/required}}{{/isBodyParam}}{{#isBodyParam}}~{{{paramName}}}{{/isBodyParam}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/ocaml/to_string.mustache b/modules/openapi-generator/src/main/resources/ocaml/to_string.mustache
new file mode 100644
index 00000000000..0588ac5ab4f
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ocaml/to_string.mustache
@@ -0,0 +1 @@
+{{#isContainer}}{{#items}}(List.map {{> to_string}}){{/items}}{{/isContainer}}{{^isEnum}}{{#isLong}}Int64.to_string{{/isLong}}{{#isInteger}}Int32.to_string{{/isInteger}}{{#isFloat}}string_of_float{{/isFloat}}{{#isNumber}}string_of_float{{/isNumber}}{{#isDouble}}string_of_float{{/isDouble}}{{#isBoolean}}string_of_bool{{/isBoolean}}{{#isFile}}(fun x -> x){{/isFile}}{{#isDate}}(fun x -> x){{/isDate}}{{#isDateTime}}(fun x -> x){{/isDateTime}}{{#isString}}(fun x -> x){{/isString}}{{#isByteArray}}(fun x -> x){{/isByteArray}}{{#isModel}}{{{vendorExtensions.x-modelModule}}}.show{{/isModel}}{{/isEnum}}{{^isModel}}{{^isContainer}}{{#isEnum}}Enums.show_{{{datatypeWithEnum}}}{{/isEnum}}{{/isContainer}}{{/isModel}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/python-flask/requirements.mustache b/modules/openapi-generator/src/main/resources/python-flask/requirements.mustache
index 8d4d653bfd7..b5a702d5de8 100644
--- a/modules/openapi-generator/src/main/resources/python-flask/requirements.mustache
+++ b/modules/openapi-generator/src/main/resources/python-flask/requirements.mustache
@@ -1,7 +1,7 @@
-connexion == 2.0.2
-swagger-ui-bundle == 0.0.2
-python_dateutil == 2.6.0
+connexion >= 2.0.2
+swagger-ui-bundle >= 0.0.2
+python_dateutil >= 2.6.0
{{#supportPython2}}
-typing == 3.5.2.2
+typing >= 3.5.2.2
{{/supportPython2}}
setuptools >= 21.0.0
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache
new file mode 100644
index 00000000000..edf76be03bb
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api.mustache
@@ -0,0 +1,294 @@
+# coding: utf-8
+
+{{>partial_header}}
+
+from __future__ import absolute_import
+
+import re # noqa: F401
+
+# python 2 and python 3 compatibility library
+import six
+
+from {{packageName}}.api_client import ApiClient
+from {{packageName}}.exceptions import ( # noqa: F401
+ ApiTypeError,
+ ApiValueError
+)
+
+
+{{#operations}}
+class {{classname}}(object):
+ """NOTE: This class is auto generated by OpenAPI Generator
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """
+
+ def __init__(self, api_client=None):
+ if api_client is None:
+ api_client = ApiClient()
+ self.api_client = api_client
+{{#operation}}
+
+ def {{operationId}}(self{{#requiredParams}}{{^defaultValue}}, {{paramName}}{{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}, {{paramName}}={{{defaultValue}}}{{/defaultValue}}{{/requiredParams}}, **kwargs): # noqa: E501
+ """{{#summary}}{{{.}}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
+
+{{#notes}}
+ {{{notes}}} # noqa: E501
+{{/notes}}
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.{{operationId}}({{#requiredParams}}{{^defaultValue}}{{paramName}}, {{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}{{paramName}}={{{defaultValue}}}, {{/defaultValue}}{{/requiredParams}}async_req=True)
+ >>> result = thread.get()
+
+{{#requiredParams}}
+{{^hasMore}}
+ Args:
+{{/hasMore}}
+{{/requiredParams}}
+{{#requiredParams}}
+{{^defaultValue}}
+ {{paramName}} ({{dataType}}):{{#description}} {{description}}{{/description}}{{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}
+ {{paramName}} ({{dataType}}):{{#description}} {{description}}.{{/description}} defaults to {{{defaultValue}}}, must be one of [{{{defaultValue}}}]{{/defaultValue}}{{/requiredParams}}
+
+ Keyword Args:{{#optionalParams}}
+ {{paramName}} ({{dataType}}):{{#description}} {{description}}.{{/description}} [optional]{{#defaultValue}} if omitted the server will use the default value of {{{defaultValue}}}{{/defaultValue}}{{/optionalParams}}
+ async_req (bool): execute request asynchronously
+ param _preload_content (bool): if False, the urllib3.HTTPResponse
+ object will be returned without reading/decoding response data.
+ Default is True.
+ param _request_timeout (float/tuple): timeout setting for this
+ request. If one number provided, it will be total request
+ timeout. It can also be a pair (tuple) of (connection, read)
+ timeouts.
+
+ Returns:
+ {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}:
+ """
+ kwargs['_return_http_data_only'] = True
+ if kwargs.get('async_req'):
+ return self.{{operationId}}_with_http_info({{#requiredParams}}{{^defaultValue}}{{paramName}}, {{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}{{paramName}}={{paramName}}, {{/defaultValue}}{{/requiredParams}}**kwargs) # noqa: E501
+ else:
+ (data) = self.{{operationId}}_with_http_info({{#requiredParams}}{{^defaultValue}}{{paramName}}, {{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}{{paramName}}={{paramName}}, {{/defaultValue}}{{/requiredParams}}**kwargs) # noqa: E501
+ return data
+
+ def {{operationId}}_with_http_info(self{{#requiredParams}}{{^defaultValue}}, {{paramName}}{{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}, {{paramName}}=None{{/defaultValue}}{{/requiredParams}}, **kwargs): # noqa: E501
+ """{{#summary}}{{{.}}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
+
+{{#notes}}
+ {{{notes}}} # noqa: E501
+{{/notes}}
+ This method makes a synchronous HTTP request by default. To make an
+ asynchronous HTTP request, please pass async_req=True
+ >>> thread = api.{{operationId}}_with_http_info({{#requiredParams}}{{^defaultValue}}{{paramName}}, {{/defaultValue}}{{/requiredParams}}async_req=True)
+ >>> result = thread.get()
+
+{{#requiredParams}}
+{{^hasMore}}
+ Args:
+{{/hasMore}}
+{{/requiredParams}}
+{{#requiredParams}}
+{{^defaultValue}}
+ {{paramName}} ({{dataType}}):{{#description}} {{description}}{{/description}}{{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}}
+ {{paramName}} ({{dataType}}):{{#description}} {{description}}.{{/description}} defaults to {{{defaultValue}}}, must be one of [{{{defaultValue}}}]{{/defaultValue}}{{/requiredParams}}
+
+ Keyword Args:{{#optionalParams}}
+ {{paramName}} ({{dataType}}):{{#description}} {{description}}.{{/description}} [optional]{{#defaultValue}} if omitted the server will use the default value of {{{defaultValue}}}{{/defaultValue}}{{/optionalParams}}
+ async_req (bool): execute request asynchronously
+ param _preload_content (bool): if False, the urllib3.HTTPResponse
+ object will be returned without reading/decoding response data.
+ Default is True.
+ param _request_timeout (float/tuple): timeout setting for this
+ request. If one number provided, it will be total request
+ timeout. It can also be a pair (tuple) of (connection, read)
+ timeouts.
+
+ Returns:
+ {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}None{{/returnType}}:
+ """
+
+ {{#servers.0}}
+ local_var_hosts = [{{#servers}}
+ '{{{url}}}'{{^-last}},{{/-last}}{{/servers}}
+ ]
+ local_var_host = local_var_hosts[0]
+ if kwargs.get('_host_index'):
+ if (int(kwargs.get('_host_index')) < 0 or
+ int(kwargs.get('_host_index')) >= len(local_var_hosts)):
+ raise ApiValueError(
+ "Invalid host index. Must be 0 <= index < %s" %
+ len(local_var_host)
+ )
+ local_var_host = local_var_hosts[int(kwargs.get('_host_index'))]
+ {{/servers.0}}
+ local_var_params = locals()
+
+ all_params = [{{#allParams}}'{{paramName}}'{{#hasMore}}, {{/hasMore}}{{/allParams}}] # noqa: E501
+ all_params.append('async_req')
+ all_params.append('_return_http_data_only')
+ all_params.append('_preload_content')
+ all_params.append('_request_timeout')
+
+ for key, val in six.iteritems(local_var_params['kwargs']):
+ if key not in all_params{{#servers.0}} and key != "_host_index"{{/servers.0}}:
+ raise ApiTypeError(
+ "Got an unexpected keyword argument '%s'"
+ " to method {{operationId}}" % key
+ )
+ local_var_params[key] = val
+ del local_var_params['kwargs']
+{{#allParams}}
+{{^isNullable}}
+{{#required}}
+ # verify the required parameter '{{paramName}}' is set
+ if ('{{paramName}}' not in local_var_params or
+ local_var_params['{{paramName}}'] is None):
+ raise ApiValueError("Missing the required parameter `{{paramName}}` when calling `{{operationId}}`") # noqa: E501
+{{/required}}
+{{/isNullable}}
+{{#-last}}
+{{/-last}}
+{{/allParams}}
+{{#allParams}}
+{{#isEnum}}
+{{#isContainer}}
+ allowed_values = [{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
+{{#isListContainer}}
+ if ('{{{paramName}}}' in local_var_params and
+ not set(local_var_params['{{{paramName}}}']).issubset(set(allowed_values))): # noqa: E501
+ raise ValueError(
+ "Invalid values for `{{{paramName}}}` [{0}], must be a subset of [{1}]" # noqa: E501
+ .format(", ".join(map(str, set(local_var_params['{{{paramName}}}']) - set(allowed_values))), # noqa: E501
+ ", ".join(map(str, allowed_values)))
+ )
+{{/isListContainer}}
+{{#isMapContainer}}
+ if ('{{{paramName}}}' in local_var_params and
+ not set(local_var_params['{{{paramName}}}'].keys()).issubset(set(allowed_values))):
+ raise ValueError(
+ "Invalid keys in `{{{paramName}}}` [{0}], must be a subset of [{1}]" # noqa: E501
+ .format(", ".join(map(str, set(local_var_params['{{{paramName}}}'].keys()) - set(allowed_values))), # noqa: E501
+ ", ".join(map(str, allowed_values)))
+ )
+{{/isMapContainer}}
+{{/isContainer}}
+{{^isContainer}}
+ allowed_values = [{{#allowableValues}}{{#values}}{{#isString}}"{{/isString}}{{{this}}}{{#isString}}"{{/isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
+ if ('{{{paramName}}}' in local_var_params and
+ local_var_params['{{{paramName}}}'] not in allowed_values):
+ raise ValueError(
+ "Invalid value for `{{{paramName}}}` ({0}), must be one of {1}" # noqa: E501
+ .format(local_var_params['{{{paramName}}}'], allowed_values)
+ )
+{{/isContainer}}
+{{/isEnum}}
+{{/allParams}}
+{{#allParams}}
+{{#hasValidation}}
+ {{#maxLength}}
+ if ('{{paramName}}' in local_var_params and
+ len(local_var_params['{{paramName}}']) > {{maxLength}}):
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
+ {{/maxLength}}
+ {{#minLength}}
+ if ('{{paramName}}' in local_var_params and
+ len(local_var_params['{{paramName}}']) < {{minLength}}):
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
+ {{/minLength}}
+ {{#maximum}}
+ if '{{paramName}}' in local_var_params and local_var_params['{{paramName}}'] >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
+ {{/maximum}}
+ {{#minimum}}
+ if '{{paramName}}' in local_var_params and local_var_params['{{paramName}}'] <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
+ {{/minimum}}
+ {{#pattern}}
+ if '{{paramName}}' in local_var_params and not re.search(r'{{{vendorExtensions.x-regex}}}', local_var_params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must conform to the pattern `{{{pattern}}}`") # noqa: E501
+ {{/pattern}}
+ {{#maxItems}}
+ if ('{{paramName}}' in local_var_params and
+ len(local_var_params['{{paramName}}']) > {{maxItems}}):
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
+ {{/maxItems}}
+ {{#minItems}}
+ if ('{{paramName}}' in local_var_params and
+ len(local_var_params['{{paramName}}']) < {{minItems}}):
+ raise ApiValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
+ {{/minItems}}
+{{/hasValidation}}
+{{/allParams}}
+
+ collection_formats = {}
+
+ path_params = {}
+{{#pathParams}}
+ if '{{paramName}}' in local_var_params:
+ path_params['{{baseName}}'] = local_var_params['{{paramName}}']{{#isListContainer}} # noqa: E501
+ collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
+{{/pathParams}}
+
+ query_params = []
+{{#queryParams}}
+ if '{{paramName}}' in local_var_params:
+ query_params.append(('{{baseName}}', local_var_params['{{paramName}}'])){{#isListContainer}} # noqa: E501
+ collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
+{{/queryParams}}
+
+ header_params = {}
+{{#headerParams}}
+ if '{{paramName}}' in local_var_params:
+ header_params['{{baseName}}'] = local_var_params['{{paramName}}']{{#isListContainer}} # noqa: E501
+ collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
+{{/headerParams}}
+
+ form_params = []
+ local_var_files = {}
+{{#formParams}}
+ if '{{paramName}}' in local_var_params:
+ {{^isFile}}form_params.append(('{{baseName}}', local_var_params['{{paramName}}'])){{/isFile}}{{#isFile}}local_var_files['{{baseName}}'] = local_var_params['{{paramName}}']{{/isFile}}{{#isListContainer}} # noqa: E501
+ collection_formats['{{baseName}}'] = '{{collectionFormat}}'{{/isListContainer}} # noqa: E501
+{{/formParams}}
+
+ body_params = None
+{{#bodyParam}}
+ if '{{paramName}}' in local_var_params:
+ body_params = local_var_params['{{paramName}}']
+{{/bodyParam}}
+ {{#hasProduces}}
+ # HTTP header `Accept`
+ header_params['Accept'] = self.api_client.select_header_accept(
+ [{{#produces}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/produces}}]) # noqa: E501
+
+ {{/hasProduces}}
+ {{#hasConsumes}}
+ # HTTP header `Content-Type`
+ header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
+ [{{#consumes}}'{{{mediaType}}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]) # noqa: E501
+
+ {{/hasConsumes}}
+ # Authentication setting
+ auth_settings = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] # noqa: E501
+
+ return self.api_client.call_api(
+ '{{{path}}}', '{{httpMethod}}',
+ path_params,
+ query_params,
+ header_params,
+ body=body_params,
+ post_params=form_params,
+ files=local_var_files,
+ response_type={{#returnType}}'{{returnType}}'{{/returnType}}{{^returnType}}None{{/returnType}}, # noqa: E501
+ auth_settings=auth_settings,
+ async_req=local_var_params.get('async_req'),
+ _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501
+ _preload_content=local_var_params.get('_preload_content', True),
+ _request_timeout=local_var_params.get('_request_timeout'),
+ {{#servers.0}}
+ _host=local_var_host,
+ {{/servers.0}}
+ collection_formats=collection_formats)
+{{/operation}}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache
new file mode 100644
index 00000000000..e955eb05707
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api_client.mustache
@@ -0,0 +1,665 @@
+# coding: utf-8
+{{>partial_header}}
+from __future__ import absolute_import
+
+import datetime
+import inspect
+import json
+import mimetypes
+from multiprocessing.pool import ThreadPool
+import os
+import re
+import tempfile
+
+# python 2 and python 3 compatibility library
+import six
+from six.moves.urllib.parse import quote
+{{#tornado}}
+import tornado.gen
+{{/tornado}}
+
+from {{packageName}}.configuration import Configuration
+import {{modelPackage}}
+from {{packageName}} import rest
+from {{packageName}}.exceptions import ApiValueError
+
+
+class ApiClient(object):
+ """Generic API client for OpenAPI client library builds.
+
+ OpenAPI generic API client. This client handles the client-
+ server communication, and is invariant across implementations. Specifics of
+ the methods and models for each application are generated from the OpenAPI
+ templates.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
+ Do not edit the class manually.
+
+ :param configuration: .Configuration object for this client
+ :param header_name: a header to pass when making calls to the API.
+ :param header_value: a header value to pass when making calls to
+ the API.
+ :param cookie: a cookie to include in the header when making calls
+ to the API
+ :param pool_threads: The number of threads to use for async requests
+ to the API. More threads means more concurrent API requests.
+ """
+
+ PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types
+ NATIVE_TYPES_MAPPING = {
+ 'int': int,
+ 'long': int if six.PY3 else long, # noqa: F821
+ 'float': float,
+ 'str': str,
+ 'bool': bool,
+ 'date': datetime.date,
+ 'datetime': datetime.datetime,
+ 'object': object,
+ }
+ _pool = None
+
+ def __init__(self, configuration=None, header_name=None, header_value=None,
+ cookie=None, pool_threads=1):
+ if configuration is None:
+ configuration = Configuration()
+ self.configuration = configuration
+ self.pool_threads = pool_threads
+
+ self.rest_client = rest.RESTClientObject(configuration)
+ self.default_headers = {}
+ if header_name is not None:
+ self.default_headers[header_name] = header_value
+ self.cookie = cookie
+ # Set default User-Agent.
+ self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
+
+ def __del__(self):
+ if self._pool:
+ self._pool.close()
+ self._pool.join()
+ self._pool = None
+
+ @property
+ def pool(self):
+ """Create thread pool on first request
+ avoids instantiating unused threadpool for blocking clients.
+ """
+ if self._pool is None:
+ self._pool = ThreadPool(self.pool_threads)
+ return self._pool
+
+ @property
+ def user_agent(self):
+ """User agent for this API client"""
+ return self.default_headers['User-Agent']
+
+ @user_agent.setter
+ def user_agent(self, value):
+ self.default_headers['User-Agent'] = value
+
+ def set_default_header(self, header_name, header_value):
+ self.default_headers[header_name] = header_value
+
+ {{#tornado}}
+ @tornado.gen.coroutine
+ {{/tornado}}
+ {{#asyncio}}async {{/asyncio}}def __call_api(
+ self, resource_path, method, path_params=None,
+ query_params=None, header_params=None, body=None, post_params=None,
+ files=None, response_type=None, auth_settings=None,
+ _return_http_data_only=None, collection_formats=None,
+ _preload_content=True, _request_timeout=None, _host=None):
+
+ config = self.configuration
+
+ # header parameters
+ header_params = header_params or {}
+ header_params.update(self.default_headers)
+ if self.cookie:
+ header_params['Cookie'] = self.cookie
+ if header_params:
+ header_params = self.sanitize_for_serialization(header_params)
+ header_params = dict(self.parameters_to_tuples(header_params,
+ collection_formats))
+
+ # path parameters
+ if path_params:
+ path_params = self.sanitize_for_serialization(path_params)
+ path_params = self.parameters_to_tuples(path_params,
+ collection_formats)
+ for k, v in path_params:
+ # specified safe chars, encode everything
+ resource_path = resource_path.replace(
+ '{%s}' % k,
+ quote(str(v), safe=config.safe_chars_for_path_param)
+ )
+
+ # query parameters
+ if query_params:
+ query_params = self.sanitize_for_serialization(query_params)
+ query_params = self.parameters_to_tuples(query_params,
+ collection_formats)
+
+ # post parameters
+ if post_params or files:
+ post_params = post_params if post_params else []
+ post_params = self.sanitize_for_serialization(post_params)
+ post_params = self.parameters_to_tuples(post_params,
+ collection_formats)
+ post_params.extend(self.files_parameters(files))
+
+ # auth setting
+ self.update_params_for_auth(header_params, query_params, auth_settings)
+
+ # body
+ if body:
+ body = self.sanitize_for_serialization(body)
+
+ # request url
+ if _host is None:
+ url = self.configuration.host + resource_path
+ else:
+ # use server/host defined in path or operation instead
+ url = _host + resource_path
+
+ # perform request and return response
+ response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request(
+ method, url, query_params=query_params, headers=header_params,
+ post_params=post_params, body=body,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout)
+
+ self.last_response = response_data
+
+ return_data = response_data
+ if _preload_content:
+ # deserialize response data
+ if response_type:
+ return_data = self.deserialize(response_data, response_type)
+ else:
+ return_data = None
+
+{{^tornado}}
+ if _return_http_data_only:
+ return (return_data)
+ else:
+ return (return_data, response_data.status,
+ response_data.getheaders())
+{{/tornado}}
+{{#tornado}}
+ if _return_http_data_only:
+ raise tornado.gen.Return(return_data)
+ else:
+ raise tornado.gen.Return((return_data, response_data.status,
+ response_data.getheaders()))
+{{/tornado}}
+
+ def sanitize_for_serialization(self, obj):
+ """Builds a JSON POST object.
+
+ If obj is None, return None.
+ If obj is str, int, long, float, bool, return directly.
+ If obj is datetime.datetime, datetime.date
+ convert to string in iso8601 format.
+ If obj is list, sanitize each element in the list.
+ If obj is dict, return the dict.
+ If obj is OpenAPI model, return the properties dict.
+
+ :param obj: The data to serialize.
+ :return: The serialized form of data.
+ """
+ if obj is None:
+ return None
+ elif isinstance(obj, self.PRIMITIVE_TYPES):
+ return obj
+ elif isinstance(obj, list):
+ return [self.sanitize_for_serialization(sub_obj)
+ for sub_obj in obj]
+ elif isinstance(obj, tuple):
+ return tuple(self.sanitize_for_serialization(sub_obj)
+ for sub_obj in obj)
+ elif isinstance(obj, (datetime.datetime, datetime.date)):
+ return obj.isoformat()
+
+ if isinstance(obj, dict):
+ obj_dict = obj
+ else:
+ # Convert model obj to dict except
+ # attributes `openapi_types`, `attribute_map`
+ # and attributes which value is not None.
+ # Convert attribute name to json key in
+ # model definition for request.
+ obj_dict = {obj.attribute_map[attr]: getattr(obj, attr)
+ for attr, _ in six.iteritems(obj.openapi_types)
+ if getattr(obj, attr) is not None}
+
+ return {key: self.sanitize_for_serialization(val)
+ for key, val in six.iteritems(obj_dict)}
+
+ def deserialize(self, response, response_type):
+ """Deserializes response into an object.
+
+ :param response: RESTResponse object to be deserialized.
+ :param response_type: class literal for
+ deserialized object, or string of class name.
+
+ :return: deserialized object.
+ """
+ # handle file downloading
+ # save response body into a tmp file and return the instance
+ if response_type == "file":
+ return self.__deserialize_file(response)
+
+ # fetch data from response object
+ try:
+ data = json.loads(response.data)
+ except ValueError:
+ data = response.data
+
+ return self.__deserialize(data, response_type)
+
+ def __deserialize(self, data, klass):
+ """Deserializes dict, list, str into an object.
+
+ :param data: dict, list or str.
+ :param klass: class literal, or string of class name.
+
+ :return: object.
+ """
+ if data is None:
+ return None
+
+ if type(klass) == str:
+ if klass.startswith('list['):
+ sub_kls = re.match(r'list\[(.*)\]', klass).group(1)
+ return [self.__deserialize(sub_data, sub_kls)
+ for sub_data in data]
+
+ if klass.startswith('dict('):
+ sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2)
+ return {k: self.__deserialize(v, sub_kls)
+ for k, v in six.iteritems(data)}
+
+ # convert str to class
+ if klass in self.NATIVE_TYPES_MAPPING:
+ klass = self.NATIVE_TYPES_MAPPING[klass]
+ else:
+ klass = getattr({{modelPackage}}, klass)
+
+ if klass in self.PRIMITIVE_TYPES:
+ return self.__deserialize_primitive(data, klass)
+ elif klass == object:
+ return self.__deserialize_object(data)
+ elif klass == datetime.date:
+ return self.__deserialize_date(data)
+ elif klass == datetime.datetime:
+ return self.__deserialize_datatime(data)
+ else:
+ return self.__deserialize_model(data, klass)
+
+ def call_api(self, resource_path, method,
+ path_params=None, query_params=None, header_params=None,
+ body=None, post_params=None, files=None,
+ response_type=None, auth_settings=None, async_req=None,
+ _return_http_data_only=None, collection_formats=None,
+ _preload_content=True, _request_timeout=None, _host=None):
+ """Makes the HTTP request (synchronous) and returns deserialized data.
+
+ To make an async_req request, set the async_req parameter.
+
+ :param resource_path: Path to method endpoint.
+ :param method: Method to call.
+ :param path_params: Path parameters in the url.
+ :param query_params: Query parameters in the url.
+ :param header_params: Header parameters to be
+ placed in the request header.
+ :param body: Request body.
+ :param post_params dict: Request post form parameters,
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
+ :param auth_settings list: Auth Settings names for the request.
+ :param response: Response data type.
+ :param files dict: key -> filename, value -> filepath,
+ for `multipart/form-data`.
+ :param async_req bool: execute request asynchronously
+ :param _return_http_data_only: response data without head status code
+ and headers
+ :param collection_formats: dict of collection formats for path, query,
+ header, and post parameters.
+ :param _preload_content: if False, the urllib3.HTTPResponse object will
+ be returned without reading/decoding response
+ data. Default is True.
+ :param _request_timeout: timeout setting for this request. If one
+ number provided, it will be total request
+ timeout. It can also be a pair (tuple) of
+ (connection, read) timeouts.
+ :return:
+ If async_req parameter is True,
+ the request will be called asynchronously.
+ The method will return the request thread.
+ If parameter async_req is False or missing,
+ then the method will return the response directly.
+ """
+ if not async_req:
+ return self.__call_api(resource_path, method,
+ path_params, query_params, header_params,
+ body, post_params, files,
+ response_type, auth_settings,
+ _return_http_data_only, collection_formats,
+ _preload_content, _request_timeout, _host)
+ else:
+ thread = self.pool.apply_async(self.__call_api, (resource_path,
+ method, path_params, query_params,
+ header_params, body,
+ post_params, files,
+ response_type, auth_settings,
+ _return_http_data_only,
+ collection_formats,
+ _preload_content,
+ _request_timeout,
+ _host))
+ return thread
+
+ def request(self, method, url, query_params=None, headers=None,
+ post_params=None, body=None, _preload_content=True,
+ _request_timeout=None):
+ """Makes the HTTP request using RESTClient."""
+ if method == "GET":
+ return self.rest_client.GET(url,
+ query_params=query_params,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ headers=headers)
+ elif method == "HEAD":
+ return self.rest_client.HEAD(url,
+ query_params=query_params,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ headers=headers)
+ elif method == "OPTIONS":
+ return self.rest_client.OPTIONS(url,
+ query_params=query_params,
+ headers=headers,
+ post_params=post_params,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ body=body)
+ elif method == "POST":
+ return self.rest_client.POST(url,
+ query_params=query_params,
+ headers=headers,
+ post_params=post_params,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ body=body)
+ elif method == "PUT":
+ return self.rest_client.PUT(url,
+ query_params=query_params,
+ headers=headers,
+ post_params=post_params,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ body=body)
+ elif method == "PATCH":
+ return self.rest_client.PATCH(url,
+ query_params=query_params,
+ headers=headers,
+ post_params=post_params,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ body=body)
+ elif method == "DELETE":
+ return self.rest_client.DELETE(url,
+ query_params=query_params,
+ headers=headers,
+ _preload_content=_preload_content,
+ _request_timeout=_request_timeout,
+ body=body)
+ else:
+ raise ApiValueError(
+ "http method must be `GET`, `HEAD`, `OPTIONS`,"
+ " `POST`, `PATCH`, `PUT` or `DELETE`."
+ )
+
+ def parameters_to_tuples(self, params, collection_formats):
+ """Get parameters as list of tuples, formatting collections.
+
+ :param params: Parameters as dict or list of two-tuples
+ :param dict collection_formats: Parameter collection formats
+ :return: Parameters as list of tuples, collections formatted
+ """
+ new_params = []
+ if collection_formats is None:
+ collection_formats = {}
+ for k, v in six.iteritems(params) if isinstance(params, dict) else params: # noqa: E501
+ if k in collection_formats:
+ collection_format = collection_formats[k]
+ if collection_format == 'multi':
+ new_params.extend((k, value) for value in v)
+ else:
+ if collection_format == 'ssv':
+ delimiter = ' '
+ elif collection_format == 'tsv':
+ delimiter = '\t'
+ elif collection_format == 'pipes':
+ delimiter = '|'
+ else: # csv is the default
+ delimiter = ','
+ new_params.append(
+ (k, delimiter.join(str(value) for value in v)))
+ else:
+ new_params.append((k, v))
+ return new_params
+
+ def files_parameters(self, files=None):
+ """Builds form parameters.
+
+ :param files: File parameters.
+ :return: Form parameters with files.
+ """
+ params = []
+
+ if files:
+ for k, v in six.iteritems(files):
+ if not v:
+ continue
+ file_names = v if type(v) is list else [v]
+ for n in file_names:
+ with open(n, 'rb') as f:
+ filename = os.path.basename(f.name)
+ filedata = f.read()
+ mimetype = (mimetypes.guess_type(filename)[0] or
+ 'application/octet-stream')
+ params.append(
+ tuple([k, tuple([filename, filedata, mimetype])]))
+
+ return params
+
+ def select_header_accept(self, accepts):
+ """Returns `Accept` based on an array of accepts provided.
+
+ :param accepts: List of headers.
+ :return: Accept (e.g. application/json).
+ """
+ if not accepts:
+ return
+
+ accepts = [x.lower() for x in accepts]
+
+ if 'application/json' in accepts:
+ return 'application/json'
+ else:
+ return ', '.join(accepts)
+
+ def select_header_content_type(self, content_types):
+ """Returns `Content-Type` based on an array of content_types provided.
+
+ :param content_types: List of content-types.
+ :return: Content-Type (e.g. application/json).
+ """
+ if not content_types:
+ return 'application/json'
+
+ content_types = [x.lower() for x in content_types]
+
+ if 'application/json' in content_types or '*/*' in content_types:
+ return 'application/json'
+ else:
+ return content_types[0]
+
+ def update_params_for_auth(self, headers, querys, auth_settings):
+ """Updates header and query params based on authentication setting.
+
+ :param headers: Header parameters dict to be updated.
+ :param querys: Query parameters tuple list to be updated.
+ :param auth_settings: Authentication setting identifiers list.
+ """
+ if not auth_settings:
+ return
+
+ for auth in auth_settings:
+ auth_setting = self.configuration.auth_settings().get(auth)
+ if auth_setting:
+ if not auth_setting['value']:
+ continue
+ elif auth_setting['in'] == 'cookie':
+ headers['Cookie'] = auth_setting['value']
+ elif auth_setting['in'] == 'header':
+ headers[auth_setting['key']] = auth_setting['value']
+ elif auth_setting['in'] == 'query':
+ querys.append((auth_setting['key'], auth_setting['value']))
+ else:
+ raise ApiValueError(
+ 'Authentication token must be in `query` or `header`'
+ )
+
+ def __deserialize_file(self, response):
+ """Deserializes body to file
+
+ Saves response body into a file in a temporary folder,
+ using the filename from the `Content-Disposition` header if provided.
+
+ :param response: RESTResponse.
+ :return: file path.
+ """
+ fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
+ os.close(fd)
+ os.remove(path)
+
+ content_disposition = response.getheader("Content-Disposition")
+ if content_disposition:
+ filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?',
+ content_disposition).group(1)
+ path = os.path.join(os.path.dirname(path), filename)
+
+ with open(path, "wb") as f:
+ f.write(response.data)
+
+ return path
+
+ def __deserialize_primitive(self, data, klass):
+ """Deserializes string to primitive type.
+
+ :param data: str.
+ :param klass: class literal.
+
+ :return: int, long, float, str, bool.
+ """
+ try:
+ return klass(data)
+ except UnicodeEncodeError:
+ return six.text_type(data)
+ except TypeError:
+ return data
+
+ def __deserialize_object(self, value):
+ """Return an original value.
+
+ :return: object.
+ """
+ return value
+
+ def __deserialize_date(self, string):
+ """Deserializes string to date.
+
+ :param string: str.
+ :return: date.
+ """
+ try:
+ from dateutil.parser import parse
+ return parse(string).date()
+ except ImportError:
+ return string
+ except ValueError:
+ raise rest.ApiException(
+ status=0,
+ reason="Failed to parse `{0}` as date object".format(string)
+ )
+
+ def __deserialize_datatime(self, string):
+ """Deserializes string to datetime.
+
+ The string should be in iso8601 datetime format.
+
+ :param string: str.
+ :return: datetime.
+ """
+ try:
+ from dateutil.parser import parse
+ return parse(string)
+ except ImportError:
+ return string
+ except ValueError:
+ raise rest.ApiException(
+ status=0,
+ reason=(
+ "Failed to parse `{0}` as datetime object"
+ .format(string)
+ )
+ )
+
+ def __deserialize_model(self, data, klass):
+ """Deserializes list or dict to model.
+
+ :param data: dict, list.
+ :param klass: class literal.
+ :return: model object.
+ """
+
+ if not klass.openapi_types and not hasattr(klass,
+ 'get_real_child_model'):
+ return data
+
+ used_data = data
+ if not isinstance(data, (list, dict)):
+ used_data = [data]
+ keyword_args = {}
+ positional_args = []
+ if klass.openapi_types is not None:
+ for attr, attr_type in six.iteritems(klass.openapi_types):
+ if (data is not None and
+ klass.attribute_map[attr] in used_data):
+ value = used_data[klass.attribute_map[attr]]
+ keyword_args[attr] = self.__deserialize(value, attr_type)
+
+ end_index = None
+ argspec = inspect.getargspec(getattr(klass, '__init__'))
+ if argspec.defaults:
+ end_index = -len(argspec.defaults)
+ required_positional_args = argspec.args[1:end_index]
+
+ for index, req_positional_arg in enumerate(required_positional_args):
+ if keyword_args and req_positional_arg in keyword_args:
+ positional_args.append(keyword_args[req_positional_arg])
+ del keyword_args[req_positional_arg]
+ elif (not keyword_args and index < len(used_data) and
+ isinstance(used_data, list)):
+ positional_args.append(used_data[index])
+
+ instance = klass(*positional_args, **keyword_args)
+
+ if hasattr(instance, 'get_real_child_model'):
+ klass_name = instance.get_real_child_model(data)
+ if klass_name:
+ instance = self.__deserialize(data, klass_name)
+ return instance
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api_doc.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api_doc.mustache
new file mode 100644
index 00000000000..5cc638a2eb6
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api_doc.mustache
@@ -0,0 +1,78 @@
+# {{packageName}}.{{classname}}{{#description}}
+{{description}}{{/description}}
+
+All URIs are relative to *{{basePath}}*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
+{{/operation}}{{/operations}}
+
+{{#operations}}
+{{#operation}}
+# **{{{operationId}}}**
+> {{#returnType}}{{{returnType}}} {{/returnType}}{{{operationId}}}({{#requiredParams}}{{^defaultValue}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/defaultValue}}{{/requiredParams}})
+
+{{{summary}}}{{#notes}}
+
+{{{notes}}}{{/notes}}
+
+### Example
+
+{{#hasAuthMethods}}
+{{#authMethods}}
+{{#isBasic}}
+{{^isBasicBearer}}
+* Basic Authentication ({{name}}):
+{{/isBasicBearer}}
+{{#isBasicBearer}}
+* Bearer{{#bearerFormat}} ({{{.}}}){{/bearerFormat}} Authentication ({{name}}):
+{{/isBasicBearer}}
+{{/isBasic}}
+{{#isApiKey}}
+* Api Key Authentication ({{name}}):
+{{/isApiKey }}
+{{#isOAuth}}
+* OAuth Authentication ({{name}}):
+{{/isOAuth }}
+{{> api_doc_example }}
+{{/authMethods}}
+{{/hasAuthMethods}}
+{{^hasAuthMethods}}
+{{> api_doc_example }}
+{{/hasAuthMethods}}
+### Parameters
+{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
+{{#requiredParams}}{{^defaultValue}} **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{baseType}}.md){{/isPrimitiveType}}{{/isFile}}| {{description}} |
+{{/defaultValue}}{{/requiredParams}}{{#requiredParams}}{{#defaultValue}} **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{baseType}}.md){{/isPrimitiveType}}{{/isFile}}| {{description}} | defaults to {{{.}}}
+{{/defaultValue}}{{/requiredParams}}{{#optionalParams}} **{{paramName}}** | {{#isFile}}**{{dataType}}**{{/isFile}}{{^isFile}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{baseType}}.md){{/isPrimitiveType}}{{/isFile}}| {{description}} | [optional]{{#defaultValue}} if omitted the server will use the default value of {{{.}}}{{/defaultValue}}
+{{/optionalParams}}
+
+### Return type
+
+{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void (empty response body){{/returnType}}
+
+### Authorization
+
+{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}
+
+### HTTP request headers
+
+ - **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
+ - **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
+
+{{#responses.0}}
+### HTTP response details
+| Status code | Description | Response headers |
+|-------------|-------------|------------------|
+{{#responses}}
+**{{code}}** | {{message}} | {{#headers}} * {{baseName}} - {{description}} {{/headers}}{{^headers.0}} - {{/headers.0}} |
+{{/responses}}
+{{/responses.0}}
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+{{/operation}}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/api_doc_example.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/api_doc_example.mustache
new file mode 100644
index 00000000000..e5eeee6b0ef
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/api_doc_example.mustache
@@ -0,0 +1,58 @@
+```python
+from __future__ import print_function
+import time
+import {{{packageName}}}
+from {{{packageName}}}.rest import ApiException
+from pprint import pprint
+{{> python_doc_auth_partial}}
+{{#hasAuthMethods}}
+# Defining host is optional and default to {{{basePath}}}
+configuration.host = "{{{basePath}}}"
+# Create an instance of the API class
+api_instance = {{{packageName}}}.{{{classname}}}({{{packageName}}}.ApiClient(configuration))
+{{/hasAuthMethods}}
+{{^hasAuthMethods}}
+# Create an instance of the API class
+api_instance = {{{packageName}}}.{{{classname}}}()
+{{/hasAuthMethods}}
+{{#requiredParams}}{{^defaultValue}}{{paramName}} = {{{example}}} # {{{dataType}}} | {{{description}}}
+{{/defaultValue}}{{/requiredParams}}{{#optionalParams}}{{paramName}} = {{{example}}} # {{{dataType}}} | {{{description}}}{{^required}} (optional){{/required}}{{#defaultValue}} if omitted the server will use the default value of {{{defaultValue}}}{{/defaultValue}}
+{{/optionalParams}}
+
+{{#requiredParams}}
+{{^hasMore}}
+# example passing only required values which don't have defaults set
+try:
+{{#summary}} # {{{.}}}
+{{/summary}} {{#returnType}}api_response = {{/returnType}}api_instance.{{{operationId}}}({{#requiredParams}}{{^defaultValue}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/defaultValue}}{{/requiredParams}}){{#returnType}}
+ pprint(api_response){{/returnType}}
+except ApiException as e:
+ print("Exception when calling {{classname}}->{{operationId}}: %s\n" % e)
+{{/hasMore}}
+{{/requiredParams}}
+
+{{#optionalParams}}
+{{^hasMore}}
+# example passing only required values which don't have defaults set
+# and optional values
+try:
+{{#summary}} # {{{.}}}
+{{/summary}} {{#returnType}}api_response = {{/returnType}}api_instance.{{{operationId}}}({{#requiredParams}}{{^defaultValue}}{{paramName}}, {{/defaultValue}}{{/requiredParams}}{{#optionalParams}}{{paramName}}={{paramName}}{{#hasMore}}, {{/hasMore}}{{/optionalParams}}){{#returnType}}
+ pprint(api_response){{/returnType}}
+except ApiException as e:
+ print("Exception when calling {{classname}}->{{operationId}}: %s\n" % e)
+{{/hasMore}}
+{{/optionalParams}}
+
+{{^requiredParams}}
+{{^optionalParams}}
+# example, this endpoint has no required or optional parameters
+try:
+{{#summary}} # {{{.}}}
+{{/summary}} {{#returnType}}api_response = {{/returnType}}api_instance.{{{operationId}}}(){{#returnType}}
+ pprint(api_response){{/returnType}}
+except ApiException as e:
+ print("Exception when calling {{classname}}->{{operationId}}: %s\n" % e)
+{{/optionalParams}}
+{{/requiredParams}}
+```
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache
new file mode 100644
index 00000000000..7dc8e01fa62
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model.mustache
@@ -0,0 +1,241 @@
+# coding: utf-8
+
+{{>partial_header}}
+
+import pprint
+import re # noqa: F401
+
+import six
+
+
+{{#models}}
+{{#model}}
+class {{classname}}(object):
+ """NOTE: This class is auto generated by OpenAPI Generator.
+ Ref: https://openapi-generator.tech
+
+ Do not edit the class manually.
+ """{{#allowableValues}}
+
+ """
+ allowed enum values
+ """
+{{#enumVars}}
+ {{name}} = {{{value}}}{{^-last}}
+{{/-last}}
+{{/enumVars}}{{/allowableValues}}
+
+ """
+ Attributes:
+ openapi_types (dict): The key is attribute name
+ and the value is attribute type.
+ attribute_map (dict): The key is attribute name
+ and the value is json key in definition.
+ """
+ openapi_types = {
+{{#requiredVars}}
+ '{{name}}': '{{{dataType}}}',
+{{/requiredVars}}
+{{#optionalVars}}
+ '{{name}}': '{{{dataType}}}',
+{{/optionalVars}}
+ }
+
+ attribute_map = {
+{{#requiredVars}}
+ '{{name}}': '{{baseName}}', # noqa: E501
+{{/requiredVars}}
+{{#optionalVars}}
+ '{{name}}': '{{baseName}}', # noqa: E501
+{{/optionalVars}}
+ }
+{{#discriminator}}
+
+ discriminator_value_class_map = {
+ {{#children}}'{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}': '{{{classname}}}'{{^-last}},
+ {{/-last}}{{/children}}
+ }
+{{/discriminator}}
+
+ def __init__(self{{#requiredVars}}{{^defaultValue}}, {{name}}{{/defaultValue}}{{/requiredVars}}{{#requiredVars}}{{#defaultValue}}, {{name}}={{{defaultValue}}}{{/defaultValue}}{{/requiredVars}}{{#optionalVars}}, {{name}}=None{{/optionalVars}}): # noqa: E501
+ """{{classname}} - a model defined in OpenAPI
+
+{{#requiredVars}}{{^hasMore}} Args:{{/hasMore}}{{/requiredVars}}{{#requiredVars}}{{^defaultValue}}
+ {{name}} ({{dataType}}):{{#description}} {{description}}{{/description}}{{/defaultValue}}{{/requiredVars}}
+
+ Keyword Args:{{#requiredVars}}{{#defaultValue}}
+ {{name}} ({{dataType}}):{{#description}} {{description}}.{{/description}} defaults to {{{defaultValue}}}, must be one of [{{{defaultValue}}}]{{/defaultValue}} # noqa: E501{{/requiredVars}}{{#optionalVars}}
+ {{name}} ({{dataType}}):{{#description}} {{description}}.{{/description}} [optional]{{#defaultValue}} if omitted the server will use the default value of {{{defaultValue}}}{{/defaultValue}} # noqa: E501{{/optionalVars}}
+ """
+{{#vars}}{{#-first}}
+{{/-first}}
+ self._{{name}} = None
+{{/vars}}
+ self.discriminator = {{#discriminator}}'{{{discriminatorName}}}'{{/discriminator}}{{^discriminator}}None{{/discriminator}}
+{{#vars}}{{#-first}}
+{{/-first}}
+{{#required}}
+ self.{{name}} = {{name}}
+{{/required}}
+{{^required}}
+{{#isNullable}}
+ self.{{name}} = {{name}}
+{{/isNullable}}
+{{^isNullable}}
+ if {{name}} is not None:
+ self.{{name}} = {{name}} # noqa: E501
+{{/isNullable}}
+{{/required}}
+{{/vars}}
+
+{{#vars}}
+ @property
+ def {{name}}(self):
+ """Gets the {{name}} of this {{classname}}. # noqa: E501
+
+{{#description}}
+ {{{description}}} # noqa: E501
+{{/description}}
+
+ :return: The {{name}} of this {{classname}}. # noqa: E501
+ :rtype: {{dataType}}
+ """
+ return self._{{name}}
+
+ @{{name}}.setter
+ def {{name}}(
+ self,
+ {{name}}):
+ """Sets the {{name}} of this {{classname}}.
+
+{{#description}}
+ {{{description}}} # noqa: E501
+{{/description}}
+
+ :param {{name}}: The {{name}} of this {{classname}}. # noqa: E501
+ :type: {{dataType}}
+ """
+{{^isNullable}}
+{{#required}}
+ if {{name}} is None:
+ raise ValueError("Invalid value for `{{name}}`, must not be `None`") # noqa: E501
+{{/required}}
+{{/isNullable}}
+{{#isEnum}}
+{{#isContainer}}
+ allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#items.isString}}"{{/items.isString}}{{{this}}}{{#items.isString}}"{{/items.isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
+{{#isListContainer}}
+ if not set({{{name}}}).issubset(set(allowed_values)):
+ raise ValueError(
+ "Invalid values for `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
+ .format(", ".join(map(str, set({{{name}}}) - set(allowed_values))), # noqa: E501
+ ", ".join(map(str, allowed_values)))
+ )
+{{/isListContainer}}
+{{#isMapContainer}}
+ if not set({{{name}}}.keys()).issubset(set(allowed_values)):
+ raise ValueError(
+ "Invalid keys in `{{{name}}}` [{0}], must be a subset of [{1}]" # noqa: E501
+ .format(", ".join(map(str, set({{{name}}}.keys()) - set(allowed_values))), # noqa: E501
+ ", ".join(map(str, allowed_values)))
+ )
+{{/isMapContainer}}
+{{/isContainer}}
+{{^isContainer}}
+ allowed_values = [{{#isNullable}}None,{{/isNullable}}{{#allowableValues}}{{#values}}{{#isString}}"{{/isString}}{{{this}}}{{#isString}}"{{/isString}}{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}] # noqa: E501
+ if {{{name}}} not in allowed_values:
+ raise ValueError(
+ "Invalid value for `{{{name}}}` ({0}), must be one of {1}" # noqa: E501
+ .format({{{name}}}, allowed_values)
+ )
+{{/isContainer}}
+{{/isEnum}}
+{{^isEnum}}
+{{#hasValidation}}
+{{#maxLength}}
+ if {{name}} is not None and len({{name}}) > {{maxLength}}:
+ raise ValueError("Invalid value for `{{name}}`, length must be less than or equal to `{{maxLength}}`") # noqa: E501
+{{/maxLength}}
+{{#minLength}}
+ if {{name}} is not None and len({{name}}) < {{minLength}}:
+ raise ValueError("Invalid value for `{{name}}`, length must be greater than or equal to `{{minLength}}`") # noqa: E501
+{{/minLength}}
+{{#maximum}}
+ if {{name}} is not None and {{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}: # noqa: E501
+ raise ValueError("Invalid value for `{{name}}`, must be a value less than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}`{{maximum}}`") # noqa: E501
+{{/maximum}}
+{{#minimum}}
+ if {{name}} is not None and {{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}: # noqa: E501
+ raise ValueError("Invalid value for `{{name}}`, must be a value greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}`{{minimum}}`") # noqa: E501
+{{/minimum}}
+{{#pattern}}
+ if {{name}} is not None and not re.search(r'{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
+ raise ValueError(r"Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501
+{{/pattern}}
+{{#maxItems}}
+ if {{name}} is not None and len({{name}}) > {{maxItems}}:
+ raise ValueError("Invalid value for `{{name}}`, number of items must be less than or equal to `{{maxItems}}`") # noqa: E501
+{{/maxItems}}
+{{#minItems}}
+ if {{name}} is not None and len({{name}}) < {{minItems}}:
+ raise ValueError("Invalid value for `{{name}}`, number of items must be greater than or equal to `{{minItems}}`") # noqa: E501
+{{/minItems}}
+{{/hasValidation}}
+{{/isEnum}}
+
+ self._{{name}} = (
+ {{name}})
+
+{{/vars}}
+{{#discriminator}}
+ def get_real_child_model(self, data):
+ """Returns the real base class specified by the discriminator"""
+ discriminator_key = self.attribute_map[self.discriminator]
+ discriminator_value = data[discriminator_key]
+ return self.discriminator_value_class_map.get(discriminator_value)
+
+{{/discriminator}}
+ def to_dict(self):
+ """Returns the model properties as a dict"""
+ result = {}
+
+ for attr, _ in six.iteritems(self.openapi_types):
+ value = getattr(self, attr)
+ if isinstance(value, list):
+ result[attr] = list(map(
+ lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
+ value
+ ))
+ elif hasattr(value, "to_dict"):
+ result[attr] = value.to_dict()
+ elif isinstance(value, dict):
+ result[attr] = dict(map(
+ lambda item: (item[0], item[1].to_dict())
+ if hasattr(item[1], "to_dict") else item,
+ value.items()
+ ))
+ else:
+ result[attr] = value
+
+ return result
+
+ def to_str(self):
+ """Returns the string representation of the model"""
+ return pprint.pformat(self.to_dict())
+
+ def __repr__(self):
+ """For `print` and `pprint`"""
+ return self.to_str()
+
+ def __eq__(self, other):
+ """Returns true if both objects are equal"""
+ if not isinstance(other, {{classname}}):
+ return False
+
+ return self.__dict__ == other.__dict__
+
+ def __ne__(self, other):
+ """Returns true if both objects are not equal"""
+ return not self == other
+{{/model}}
+{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache b/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache
new file mode 100644
index 00000000000..b6e1b263fcd
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/python/python-experimental/model_doc.mustache
@@ -0,0 +1,13 @@
+{{#models}}{{#model}}# {{classname}}
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+{{#requiredVars}}{{^defaultValue}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{#readOnly}}[readonly] {{/readOnly}}
+{{/defaultValue}}{{/requiredVars}}{{#requiredVars}}{{#defaultValue}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}defaults to {{{.}}}{{/defaultValue}}
+{{/defaultValue}}{{/requiredVars}}{{#optionalVars}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | [optional] {{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}} if omitted the server will use the default value of {{{.}}}{{/defaultValue}}
+{{/optionalVars}}
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+{{/model}}{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/Gemfile.lock.mustache b/modules/openapi-generator/src/main/resources/ruby-client/Gemfile.lock.mustache
deleted file mode 100644
index bf18a06ea83..00000000000
--- a/modules/openapi-generator/src/main/resources/ruby-client/Gemfile.lock.mustache
+++ /dev/null
@@ -1,79 +0,0 @@
-PATH
- remote: .
- specs:
- {{gemName}}{{^gemName}}{{{appName}}}{{/gemName}} ({{gemVersion}})
- json (~> 2.1, >= 2.1.0)
- typhoeus (~> 1.0, >= 1.0.1)
-
-GEM
- remote: https://rubygems.org/
- specs:
- ZenTest (4.11.2)
- addressable (2.5.2)
- public_suffix (>= 2.0.2, < 4.0)
- autotest (4.4.6)
- ZenTest (>= 4.4.1)
- autotest-fsevent (0.2.14)
- sys-uname
- autotest-growl (0.2.16)
- autotest-rails-pure (4.1.2)
- byebug (10.0.2)
- coderay (1.1.2)
- crack (0.4.3)
- safe_yaml (~> 1.0.0)
- diff-lcs (1.3)
- ethon (0.11.0)
- ffi (>= 1.3.0)
- ffi (1.9.25)
- hashdiff (0.3.7)
- json (2.1.0)
- method_source (0.9.0)
- pry (0.11.3)
- coderay (~> 1.1.0)
- method_source (~> 0.9.0)
- pry-byebug (3.6.0)
- byebug (~> 10.0)
- pry (~> 0.10)
- public_suffix (3.0.3)
- rake (12.0.0)
- rspec (3.8.0)
- rspec-core (~> 3.8.0)
- rspec-expectations (~> 3.8.0)
- rspec-mocks (~> 3.8.0)
- rspec-core (3.8.0)
- rspec-support (~> 3.8.0)
- rspec-expectations (3.8.1)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-mocks (3.8.0)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-support (3.8.0)
- safe_yaml (1.0.4)
- sys-uname (1.0.3)
- ffi (>= 1.0.0)
- typhoeus (1.3.0)
- ethon (>= 0.9.0)
- vcr (3.0.3)
- webmock (1.24.6)
- addressable (>= 2.3.6)
- crack (>= 0.3.2)
- hashdiff
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- autotest (~> 4.4, >= 4.4.6)
- autotest-fsevent (~> 0.2, >= 0.2.12)
- autotest-growl (~> 0.2, >= 0.2.16)
- autotest-rails-pure (~> 4.1, >= 4.1.2)
- {{gemName}}{{^gemName}}{{{appName}}}{{/gemName}}!
- pry-byebug
- rake (~> 12.0.0)
- rspec (~> 3.6, >= 3.6.0)
- vcr (~> 3.0, >= 3.0.1)
- webmock (~> 1.24, >= 1.24.3)
-
-BUNDLED WITH
- 1.16.1
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache
index 28c76241620..5d263ece7e3 100644
--- a/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache
+++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache
@@ -6,7 +6,12 @@ require 'date'
require 'json'
require 'logger'
require 'tempfile'
+{{^isFaraday}}
require 'typhoeus'
+{{/isFaraday}}
+{{#isFaraday}}
+require 'faraday'
+{{/isFaraday}}
module {{moduleName}}
class ApiClient
@@ -33,94 +38,12 @@ module {{moduleName}}
@@default ||= ApiClient.new
end
- # Call an API with given options.
- #
- # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
- # the data deserialized from response body (could be nil), response status code and response headers.
- def call_api(http_method, path, opts = {})
- request = build_request(http_method, path, opts)
- response = request.run
-
- if @config.debugging
- @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
- end
-
- unless response.success?
- if response.timed_out?
- fail ApiError.new('Connection timed out')
- elsif response.code == 0
- # Errors from libcurl will be made visible here
- fail ApiError.new(:code => 0,
- :message => response.return_message)
- else
- fail ApiError.new(:code => response.code,
- :response_headers => response.headers,
- :response_body => response.body),
- response.status_message
- end
- end
-
- if opts[:return_type]
- data = deserialize(response, opts[:return_type])
- else
- data = nil
- end
- return data, response.code, response.headers
- end
-
- # Builds the HTTP request
- #
- # @param [String] http_method HTTP method/verb (e.g. POST)
- # @param [String] path URL path (e.g. /account/new)
- # @option opts [Hash] :header_params Header parameters
- # @option opts [Hash] :query_params Query parameters
- # @option opts [Hash] :form_params Query parameters
- # @option opts [Object] :body HTTP body (JSON/XML)
- # @return [Typhoeus::Request] A Typhoeus Request
- def build_request(http_method, path, opts = {})
- url = build_request_url(path)
- http_method = http_method.to_sym.downcase
-
- header_params = @default_headers.merge(opts[:header_params] || {})
- query_params = opts[:query_params] || {}
- form_params = opts[:form_params] || {}
-
- {{#hasAuthMethods}}
- update_params_for_auth! header_params, query_params, opts[:auth_names]
- {{/hasAuthMethods}}
-
- # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
- _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
-
- req_opts = {
- :method => http_method,
- :headers => header_params,
- :params => query_params,
- :params_encoding => @config.params_encoding,
- :timeout => @config.timeout,
- :ssl_verifypeer => @config.verify_ssl,
- :ssl_verifyhost => _verify_ssl_host,
- :sslcert => @config.cert_file,
- :sslkey => @config.key_file,
- :verbose => @config.debugging
- }
-
- # set custom cert, if provided
- req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
-
- if [:post, :patch, :put, :delete].include?(http_method)
- req_body = build_request_body(header_params, form_params, opts[:body])
- req_opts.update :body => req_body
- if @config.debugging
- @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
- end
- end
-
- request = Typhoeus::Request.new(url, req_opts)
- download_file(request) if opts[:return_type] == 'File'
- request
- end
-
+{{^isFaraday}}
+{{> api_client_typhoeus_partial}}
+{{/isFaraday}}
+{{#isFaraday}}
+{{> api_client_faraday_partial}}
+{{/isFaraday}}
# Check if the given MIME is a JSON MIME.
# JSON MIME examples:
# application/json
@@ -258,34 +181,6 @@ module {{moduleName}}
@config.base_url + path
end
- # Builds the HTTP request body
- #
- # @param [Hash] header_params Header parameters
- # @param [Hash] form_params Query parameters
- # @param [Object] body HTTP body (JSON/XML)
- # @return [String] HTTP body data in the form of string
- def build_request_body(header_params, form_params, body)
- # http form
- if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
- header_params['Content-Type'] == 'multipart/form-data'
- data = {}
- form_params.each do |key, value|
- case value
- when ::File, ::Array, nil
- # let typhoeus handle File, Array and nil parameters
- data[key] = value
- else
- data[key] = value.to_s
- end
- end
- elsif body
- data = body.is_a?(String) ? body : body.to_json
- else
- data = nil
- end
- data
- end
-
# Update hearder and query params based on authentication settings.
#
# @param [Hash] header_params Header parameters
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache
new file mode 100644
index 00000000000..7fc08ee0fce
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client_faraday_partial.mustache
@@ -0,0 +1,129 @@
+ # Call an API with given options.
+ #
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
+ # the data deserialized from response body (could be nil), response status code and response headers.
+ def call_api(http_method, path, opts = {})
+ ssl_options = {
+ :ca_file => @config.ssl_ca_file,
+ :verify => @config.ssl_verify,
+ :verify => @config.ssl_verify_mode,
+ :client_cert => @config.ssl_client_cert,
+ :client_key => @config.ssl_client_key
+ }
+
+ connection = Faraday.new(:url => config.base_url, :ssl => ssl_options) do |conn|
+ conn.basic_auth(config.username, config.password)
+ if opts[:header_params]["Content-Type"] == "multipart/form-data"
+ conn.request :multipart
+ conn.request :url_encoded
+ end
+ conn.adapter(Faraday.default_adapter)
+ end
+
+ begin
+ response = connection.public_send(http_method.to_sym.downcase) do |req|
+ build_request(http_method, path, req, opts)
+ end
+
+ if @config.debugging
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
+ end
+
+ unless response.success?
+ if response.status == 0
+ # Errors from libcurl will be made visible here
+ fail ApiError.new(:code => 0,
+ :message => response.return_message)
+ else
+ fail ApiError.new(:code => response.status,
+ :response_headers => response.headers,
+ :response_body => response.body),
+ response.reason_phrase
+ end
+ end
+ rescue Faraday::TimeoutError
+ fail ApiError.new('Connection timed out')
+ end
+
+ if opts[:return_type]
+ data = deserialize(response, opts[:return_type])
+ else
+ data = nil
+ end
+ return data, response.status, response.headers
+ end
+
+ # Builds the HTTP request
+ #
+ # @param [String] http_method HTTP method/verb (e.g. POST)
+ # @param [String] path URL path (e.g. /account/new)
+ # @option opts [Hash] :header_params Header parameters
+ # @option opts [Hash] :query_params Query parameters
+ # @option opts [Hash] :form_params Query parameters
+ # @option opts [Object] :body HTTP body (JSON/XML)
+ # @return [Typhoeus::Request] A Typhoeus Request
+ def build_request(http_method, path, request, opts = {})
+ url = build_request_url(path)
+ http_method = http_method.to_sym.downcase
+
+ header_params = @default_headers.merge(opts[:header_params] || {})
+ query_params = opts[:query_params] || {}
+ form_params = opts[:form_params] || {}
+
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
+
+ req_opts = {
+ :method => http_method,
+ :headers => header_params,
+ :params => query_params,
+ :params_encoding => @config.params_encoding,
+ :timeout => @config.timeout,
+ :verbose => @config.debugging
+ }
+
+ if [:post, :patch, :put, :delete].include?(http_method)
+ req_body = build_request_body(header_params, form_params, opts[:body])
+ req_opts.update :body => req_body
+ if @config.debugging
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
+ end
+ end
+ request.headers = header_params
+ request.body = req_body
+ request.url url
+ request.params = query_params
+ download_file(request) if opts[:return_type] == 'File'
+ request
+ end
+
+ # Builds the HTTP request body
+ #
+ # @param [Hash] header_params Header parameters
+ # @param [Hash] form_params Query parameters
+ # @param [Object] body HTTP body (JSON/XML)
+ # @return [String] HTTP body data in the form of string
+ def build_request_body(header_params, form_params, body)
+ # http form
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
+ data = URI.encode_www_form(form_params)
+ elsif header_params['Content-Type'] == 'multipart/form-data'
+ data = {}
+ form_params.each do |key, value|
+ case value
+ when ::File, ::Tempfile
+ # TODO hardcode to application/octet-stream, need better way to detect content type
+ data[key] = Faraday::UploadIO.new(value.path, 'application/octet-stream', value.path)
+ when ::Array, nil
+ # let Faraday handle Array and nil parameters
+ data[key] = value
+ else
+ data[key] = value.to_s
+ end
+ end
+ elsif body
+ data = body.is_a?(String) ? body : body.to_json
+ else
+ data = nil
+ end
+ data
+ end
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client_spec.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client_spec.mustache
index b887b92f31a..3e8d070ef9f 100644
--- a/modules/openapi-generator/src/main/resources/ruby-client/api_client_spec.mustache
+++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client_spec.mustache
@@ -43,6 +43,7 @@ describe {{moduleName}}::ApiClient do
end
end
+{{^isFaraday}}
describe 'params_encoding in #build_request' do
let(:config) { {{moduleName}}::Configuration.new }
let(:api_client) { {{moduleName}}::ApiClient.new(config) }
@@ -81,6 +82,7 @@ describe {{moduleName}}::ApiClient do
end
end
+{{/isFaraday}}
describe '#deserialize' do
it "handles Array" do
api_client = {{moduleName}}::ApiClient.new
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache
new file mode 100644
index 00000000000..bd554afc006
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache
@@ -0,0 +1,115 @@
+ # Call an API with given options.
+ #
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
+ # the data deserialized from response body (could be nil), response status code and response headers.
+ def call_api(http_method, path, opts = {})
+ request = build_request(http_method, path, opts)
+ response = request.run
+
+ if @config.debugging
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
+ end
+
+ unless response.success?
+ if response.timed_out?
+ fail ApiError.new('Connection timed out')
+ elsif response.code == 0
+ # Errors from libcurl will be made visible here
+ fail ApiError.new(:code => 0,
+ :message => response.return_message)
+ else
+ fail ApiError.new(:code => response.code,
+ :response_headers => response.headers,
+ :response_body => response.body),
+ response.status_message
+ end
+ end
+
+ if opts[:return_type]
+ data = deserialize(response, opts[:return_type])
+ else
+ data = nil
+ end
+ return data, response.code, response.headers
+ end
+
+ # Builds the HTTP request
+ #
+ # @param [String] http_method HTTP method/verb (e.g. POST)
+ # @param [String] path URL path (e.g. /account/new)
+ # @option opts [Hash] :header_params Header parameters
+ # @option opts [Hash] :query_params Query parameters
+ # @option opts [Hash] :form_params Query parameters
+ # @option opts [Object] :body HTTP body (JSON/XML)
+ # @return [Typhoeus::Request] A Typhoeus Request
+ def build_request(http_method, path, opts = {})
+ url = build_request_url(path)
+ http_method = http_method.to_sym.downcase
+
+ header_params = @default_headers.merge(opts[:header_params] || {})
+ query_params = opts[:query_params] || {}
+ form_params = opts[:form_params] || {}
+
+ {{#hasAuthMethods}}
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
+ {{/hasAuthMethods}}
+
+ # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
+ _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
+
+ req_opts = {
+ :method => http_method,
+ :headers => header_params,
+ :params => query_params,
+ :params_encoding => @config.params_encoding,
+ :timeout => @config.timeout,
+ :ssl_verifypeer => @config.verify_ssl,
+ :ssl_verifyhost => _verify_ssl_host,
+ :sslcert => @config.cert_file,
+ :sslkey => @config.key_file,
+ :verbose => @config.debugging
+ }
+
+ # set custom cert, if provided
+ req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
+
+ if [:post, :patch, :put, :delete].include?(http_method)
+ req_body = build_request_body(header_params, form_params, opts[:body])
+ req_opts.update :body => req_body
+ if @config.debugging
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
+ end
+ end
+
+ request = Typhoeus::Request.new(url, req_opts)
+ download_file(request) if opts[:return_type] == 'File'
+ request
+ end
+
+ # Builds the HTTP request body
+ #
+ # @param [Hash] header_params Header parameters
+ # @param [Hash] form_params Query parameters
+ # @param [Object] body HTTP body (JSON/XML)
+ # @return [String] HTTP body data in the form of string
+ def build_request_body(header_params, form_params, body)
+ # http form
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
+ header_params['Content-Type'] == 'multipart/form-data'
+ data = {}
+ form_params.each do |key, value|
+ case value
+ when ::File, ::Array, nil
+ # let typhoeus handle File, Array and nil parameters
+ data[key] = value
+ else
+ data[key] = value.to_s
+ end
+ end
+ elsif body
+ data = body.is_a?(String) ? body : body.to_json
+ else
+ data = nil
+ end
+ data
+ end
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/configuration.mustache b/modules/openapi-generator/src/main/resources/ruby-client/configuration.mustache
index 3c0148fbd4d..72f6fe90e28 100644
--- a/modules/openapi-generator/src/main/resources/ruby-client/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/ruby-client/configuration.mustache
@@ -71,41 +71,12 @@ module {{moduleName}}
# @return [true, false]
attr_accessor :client_side_validation
- ### TLS/SSL setting
- # Set this to false to skip verifying SSL certificate when calling API from https server.
- # Default to true.
- #
- # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
- #
- # @return [true, false]
- attr_accessor :verify_ssl
-
- ### TLS/SSL setting
- # Set this to false to skip verifying SSL host name
- # Default to true.
- #
- # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
- #
- # @return [true, false]
- attr_accessor :verify_ssl_host
-
- ### TLS/SSL setting
- # Set this to customize the certificate file to verify the peer.
- #
- # @return [String] the path to the certificate file
- #
- # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code:
- # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145
- attr_accessor :ssl_ca_cert
-
- ### TLS/SSL setting
- # Client certificate file (for client certificate)
- attr_accessor :cert_file
-
- ### TLS/SSL setting
- # Client private key file (for client certificate)
- attr_accessor :key_file
-
+{{^isFaraday}}
+{{> configuration_tls_typhoeus_partial}}
+{{/isFaraday}}
+{{#isFaraday}}
+{{> configuration_tls_faraday_partial}}
+{{/isFaraday}}
# Set this to customize parameters encoding of array parameter with multi collectionFormat.
# Default to nil.
#
@@ -125,11 +96,20 @@ module {{moduleName}}
@api_key_prefix = {}
@timeout = 0
@client_side_validation = true
+ {{#isFaraday}}
+ @ssl_verify = true
+ @ssl_verify_mode = nil
+ @ssl_ca_file = nil
+ @ssl_client_cert = nil
+ @ssl_client_key = nil
+ {{/isFaraday}}
+ {{^isFaraday}}
@verify_ssl = true
@verify_ssl_host = true
@params_encoding = nil
@cert_file = nil
@key_file = nil
+ {{/isFaraday}}
@debugging = false
@inject_format = false
@force_ending_format = false
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/configuration_tls_faraday_partial.mustache b/modules/openapi-generator/src/main/resources/ruby-client/configuration_tls_faraday_partial.mustache
new file mode 100644
index 00000000000..e5f4085cda2
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ruby-client/configuration_tls_faraday_partial.mustache
@@ -0,0 +1,29 @@
+ ### TLS/SSL setting
+ # Set this to false to skip verifying SSL certificate when calling API from https server.
+ # Default to true.
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ # @return [true, false]
+ attr_accessor :ssl_verify
+
+ ### TLS/SSL setting
+ # Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ attr_accessor :ssl_verify_mode
+
+ ### TLS/SSL setting
+ # Set this to customize the certificate file to verify the peer.
+ #
+ # @return [String] the path to the certificate file
+ attr_accessor :ssl_ca_file
+
+ ### TLS/SSL setting
+ # Client certificate file (for client certificate)
+ attr_accessor :ssl_client_cert
+
+ ### TLS/SSL setting
+ # Client private key file (for client certificate)
+ attr_accessor :ssl_client_key
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/configuration_tls_typhoeus_partial.mustache b/modules/openapi-generator/src/main/resources/ruby-client/configuration_tls_typhoeus_partial.mustache
new file mode 100644
index 00000000000..b75954c254a
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ruby-client/configuration_tls_typhoeus_partial.mustache
@@ -0,0 +1,34 @@
+ ### TLS/SSL setting
+ # Set this to false to skip verifying SSL certificate when calling API from https server.
+ # Default to true.
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ # @return [true, false]
+ attr_accessor :verify_ssl
+
+ ### TLS/SSL setting
+ # Set this to false to skip verifying SSL host name
+ # Default to true.
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ # @return [true, false]
+ attr_accessor :verify_ssl_host
+
+ ### TLS/SSL setting
+ # Set this to customize the certificate file to verify the peer.
+ #
+ # @return [String] the path to the certificate file
+ #
+ # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code:
+ # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145
+ attr_accessor :ssl_ca_cert
+
+ ### TLS/SSL setting
+ # Client certificate file (for client certificate)
+ attr_accessor :cert_file
+
+ ### TLS/SSL setting
+ # Client private key file (for client certificate)
+ attr_accessor :key_file
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/faraday_configuration.mustache b/modules/openapi-generator/src/main/resources/ruby-client/faraday_configuration.mustache
new file mode 100644
index 00000000000..67aaaf4f00f
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/ruby-client/faraday_configuration.mustache
@@ -0,0 +1,300 @@
+=begin
+{{> api_info}}
+=end
+
+module {{moduleName}}
+ class Configuration
+ # Defines url scheme
+ attr_accessor :scheme
+
+ # Defines url host
+ attr_accessor :host
+
+ # Defines url base path
+ attr_accessor :base_path
+
+ # Defines API keys used with API Key authentications.
+ #
+ # @return [Hash] key: parameter name, value: parameter value (API key)
+ #
+ # @example parameter name is "api_key", API key is "xxx" (e.g. "api_key=xxx" in query string)
+ # config.api_key['api_key'] = 'xxx'
+ attr_accessor :api_key
+
+ # Defines API key prefixes used with API Key authentications.
+ #
+ # @return [Hash] key: parameter name, value: API key prefix
+ #
+ # @example parameter name is "Authorization", API key prefix is "Token" (e.g. "Authorization: Token xxx" in headers)
+ # config.api_key_prefix['api_key'] = 'Token'
+ attr_accessor :api_key_prefix
+
+ # Defines the username used with HTTP basic authentication.
+ #
+ # @return [String]
+ attr_accessor :username
+
+ # Defines the password used with HTTP basic authentication.
+ #
+ # @return [String]
+ attr_accessor :password
+
+ # Defines the access token (Bearer) used with OAuth2.
+ attr_accessor :access_token
+
+ # Set this to enable/disable debugging. When enabled (set to true), HTTP request/response
+ # details will be logged with `logger.debug` (see the `logger` attribute).
+ # Default to false.
+ #
+ # @return [true, false]
+ attr_accessor :debugging
+
+ # Defines the logger used for debugging.
+ # Default to `Rails.logger` (when in Rails) or logging to STDOUT.
+ #
+ # @return [#debug]
+ attr_accessor :logger
+
+ # Defines the temporary folder to store downloaded files
+ # (for API endpoints that have file response).
+ # Default to use `Tempfile`.
+ #
+ # @return [String]
+ attr_accessor :temp_folder_path
+
+ # The time limit for HTTP request in seconds.
+ # Default to 0 (never times out).
+ attr_accessor :timeout
+
+ # Set this to false to skip client side validation in the operation.
+ # Default to true.
+ # @return [true, false]
+ attr_accessor :client_side_validation
+
+ # Set this to false to skip client side validation in the operation.
+ # Default to true.
+ # @return [true, false]
+ attr_accessor :client_side_validation
+
+ ### TLS/SSL setting
+ # Set this to false to skip verifying SSL certificate when calling API from https server.
+ # Default to true.
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ # @return [true, false]
+ attr_accessor :ssl_verify
+
+ ### TLS/SSL setting
+ # Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
+ #
+ # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ #
+ attr_accessor :ssl_verify_mode
+
+ ### TLS/SSL setting
+ # Set this to customize the certificate file to verify the peer.
+ #
+ # @return [String] the path to the certificate file
+ attr_accessor :ssl_ca_file
+
+ ### TLS/SSL setting
+ # Client certificate file (for client certificate)
+ attr_accessor :ssl_client_cert
+
+ ### TLS/SSL setting
+ # Client private key file (for client certificate)
+ attr_accessor :ssl_client_key
+
+ # Set this to customize parameters encoding of array parameter with multi collectionFormat.
+ # Default to nil.
+ #
+ # @see The params_encoding option of Ethon. Related source code:
+ # https://github.com/typhoeus/ethon/blob/master/lib/ethon/easy/queryable.rb#L96
+ attr_accessor :params_encoding
+
+ attr_accessor :inject_format
+
+ attr_accessor :force_ending_format
+
+ def initialize
+ @scheme = 'http'
+ @host = 'localhost'
+ @base_path = ''
+ @api_key = {}
+ @api_key_prefix = {}
+ @params_encoding = nil
+ @timeout = 0
+ @client_side_validation = true
+ @ssl_verify = true
+ @ssl_verify_mode = nil
+ @ssl_ca_file = nil
+ @ssl_client_cert = nil
+ @ssl_client_key = nil
+ @debugging = false
+ @inject_format = false
+ @force_ending_format = false
+ @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
+
+ yield(self) if block_given?
+ end
+
+ # The default Configuration object.
+ def self.default
+ @@default ||= Configuration.new
+ end
+
+ def configure
+ yield(self) if block_given?
+ end
+
+ def scheme=(scheme)
+ # remove :// from scheme
+ @scheme = scheme.sub(/:\/\//, '')
+ end
+
+ def host=(host)
+ # remove http(s):// and anything after a slash
+ @host = host.sub(/https?:\/\//, '').split('/').first
+ end
+
+ def base_path=(base_path)
+ # Add leading and trailing slashes to base_path
+ @base_path = "/#{base_path}".gsub(/\/+/, '/')
+ @base_path = '' if @base_path == '/'
+ end
+
+ def base_url
+ "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '')
+ end
+
+ # Gets API key (with prefix if set).
+ # @param [String] param_name the parameter name of API key auth
+ def api_key_with_prefix(param_name)
+ if @api_key_prefix[param_name]
+ "#{@api_key_prefix[param_name]} #{@api_key[param_name]}"
+ else
+ @api_key[param_name]
+ end
+ end
+
+ # Gets Basic Auth token string
+ def basic_auth_token
+ 'Basic ' + ["#{username}:#{password}"].pack('m').delete("\r\n")
+ end
+
+ # Returns Auth Settings hash for api client.
+ def auth_settings
+ {
+{{#authMethods}}
+{{#isApiKey}}
+ '{{name}}' =>
+ {
+ type: 'api_key',
+ in: {{#isKeyInHeader}}'header'{{/isKeyInHeader}}{{#isKeyInQuery}}'query'{{/isKeyInQuery}},
+ key: '{{keyParamName}}',
+ value: api_key_with_prefix('{{keyParamName}}')
+ },
+{{/isApiKey}}
+{{#isBasic}}
+{{^isBasicBearer}}
+ '{{name}}' =>
+ {
+ type: 'basic',
+ in: 'header',
+ key: 'Authorization',
+ value: basic_auth_token
+ },
+{{/isBasicBearer}}
+{{#isBasicBearer}}
+ '{{name}}' =>
+ {
+ type: 'bearer',
+ in: 'header',
+ {{#bearerFormat}}
+ format: '{{{.}}}',
+ {{/bearerFormat}}
+ key: 'Authorization',
+ value: "Bearer #{access_token}"
+ },
+{{/isBasicBearer}}
+{{/isBasic}}
+{{#isOAuth}}
+ '{{name}}' =>
+ {
+ type: 'oauth2',
+ in: 'header',
+ key: 'Authorization',
+ value: "Bearer #{access_token}"
+ },
+{{/isOAuth}}
+{{/authMethods}}
+ }
+ end
+
+ # Returns an array of Server setting
+ def server_settings
+ [
+ {{#servers}}
+ {
+ url: "{{{url}}}",
+ description: "{{{description}}}{{^description}}No descriptoin provided{{/description}}",
+ {{#variables}}
+ {{#-first}}
+ variables: {
+ {{/-first}}
+ {{{name}}}: {
+ description: "{{{description}}}{{^description}}No descriptoin provided{{/description}}",
+ default_value: "{{{defaultValue}}}",
+ {{#enumValues}}
+ {{#-first}}
+ enum_values: [
+ {{/-first}}
+ "{{{.}}}"{{^-last}},{{/-last}}
+ {{#-last}}
+ ]
+ {{/-last}}
+ {{/enumValues}}
+ }{{^-last}},{{/-last}}
+ {{#-last}}
+ }
+ {{/-last}}
+ {{/variables}}
+ }{{^-last}},{{/-last}}
+ {{/servers}}
+ ]
+ end
+
+ # Returns URL based on server settings
+ #
+ # @param index array index of the server settings
+ # @param variables hash of variable and the corresponding value
+ def server_url(index, variables = {})
+ servers = server_settings
+
+ # check array index out of bound
+ if (index < 0 || index >= servers.size)
+ fail ArgumentError, "Invalid index #{index} when selecting the server. Must be less than #{servers.size}"
+ end
+
+ server = servers[index]
+ url = server[:url]
+
+ # go through variable and assign a value
+ server[:variables].each do |name, variable|
+ if variables.key?(name)
+ if (server[:variables][name][:enum_values].include? variables[name])
+ url.gsub! "{" + name.to_s + "}", variables[name]
+ else
+ fail ArgumentError, "The variable `#{name}` in the server URL has invalid value #{variables[name]}. Must be #{server[:variables][name][:enum_values]}."
+ end
+ else
+ # use default value
+ url.gsub! "{" + name.to_s + "}", server[:variables][name][:default_value]
+ end
+ end
+
+ url
+ end
+ end
+end
diff --git a/modules/openapi-generator/src/main/resources/ruby-client/gemspec.mustache b/modules/openapi-generator/src/main/resources/ruby-client/gemspec.mustache
index b77bbb50367..0fe63c2e47b 100644
--- a/modules/openapi-generator/src/main/resources/ruby-client/gemspec.mustache
+++ b/modules/openapi-generator/src/main/resources/ruby-client/gemspec.mustache
@@ -24,16 +24,15 @@ Gem::Specification.new do |s|
{{/gemLicense}}
s.required_ruby_version = "{{{gemRequiredRubyVersion}}}{{^gemRequiredRubyVersion}}>= 1.9{{/gemRequiredRubyVersion}}"
+ {{#isFaraday}}
+ s.add_runtime_dependency 'faraday', '>= 0.14.0'
+ {{/isFaraday}}
+ {{^isFaraday}}
s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
+ {{/isFaraday}}
s.add_runtime_dependency 'json', '~> 2.1', '>= 2.1.0'
s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0'
- s.add_development_dependency 'vcr', '~> 3.0', '>= 3.0.1'
- s.add_development_dependency 'webmock', '~> 1.24', '>= 1.24.3'
- s.add_development_dependency 'autotest', '~> 4.4', '>= 4.4.6'
- s.add_development_dependency 'autotest-rails-pure', '~> 4.1', '>= 4.1.2'
- s.add_development_dependency 'autotest-growl', '~> 0.2', '>= 0.2.16'
- s.add_development_dependency 'autotest-fsevent', '~> 0.2', '>= 0.2.12'
s.files = `find *`.split("\n").uniq.sort.select { |f| !f.empty? }
s.test_files = `find spec/*`.split("\n")
diff --git a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache
index bf43a520c29..2bd053e1b69 100644
--- a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache
+++ b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache
@@ -25,8 +25,8 @@ swagger = "2"
#
lazy_static = "0.2"
log = "0.3.0"
-mime = "0.3.3"
-multipart = {version = "0.13.3", optional = true}
+mime = "0.2.6"
+multipart = {version = "0.13.3"}
native-tls = {version = "0.1.4", optional = true}
openssl = {version = "0.9.14", optional = true}
percent-encoding = {version = "1.0.0", optional = true}
diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache
index aea03b15c6d..f09a9c09a6e 100644
--- a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache
+++ b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache
@@ -6,9 +6,16 @@ extern crate openssl;
extern crate mime;
extern crate chrono;
extern crate url;
-{{#usesUrlEncodedForm}}extern crate serde_urlencoded;{{/usesUrlEncodedForm}}
+{{#usesUrlEncodedForm}}
+extern crate serde_urlencoded;
+{{/usesUrlEncodedForm}}
+{{#apiUsesMultipart}}
+extern crate multipart;
+{{/apiUsesMultipart}}
-{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
+{{#apiUsesUuid}}
+use uuid;
+{{/apiUsesUuid}}
use hyper;
use hyper::header::{Headers, ContentType};
use hyper::Uri;
@@ -26,11 +33,16 @@ use std::sync::Arc;
use std::str;
use std::str::FromStr;
use std::string::ToString;
-
+{{#apiUsesMultipart}}
+use hyper::mime::Mime;
+use std::io::Cursor;
+use client::multipart::client::lazy::Multipart;
+{{/apiUsesMultipart}}
use mimetypes;
-
use serde_json;
-{{#usesXml}}use serde_xml_rs;{{/usesXml}}
+{{#usesXml}}
+use serde_xml_rs;
+{{/usesXml}}
#[allow(unused_imports)]
use std::collections::{HashMap, BTreeMap};
@@ -275,15 +287,93 @@ impl Api for Client where
let mut request = hyper::Request::new(hyper::Method::{{#vendorExtensions}}{{{HttpMethod}}}{{/vendorExtensions}}, uri);
-{{#vendorExtensions}}{{#formParams}}{{#-first}} let params = &[{{/-first}}
- ("{{{baseName}}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}format!("{:?}", param_{{{paramName}}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}param_{{{paramName}}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}),{{/vendorExtensions}}{{#-last}}
+{{#vendorExtensions}}
+ {{#consumesMultipart}}
+ let mut multipart = Multipart::new();
+
+ {{#vendorExtensions}}
+ {{#formParams}}
+ {{#-first}}
+ // For each parameter, encode as appropriate and add to the multipart body as a stream.
+ {{/-first}}
+ {{^isByteArray}}
+ {{#jsonSchema}}
+
+ let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) {
+ Ok(str) => str,
+ Err(e) => return Box::new(futures::done(Err(ApiError(format!("Unable to parse {{{paramName}}} to string: {}", e))))),
+ };
+
+ let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec();
+
+ let {{{paramName}}}_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse");
+
+ let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec);
+
+ multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime));
+
+ {{/jsonSchema}}
+ {{/isByteArray}}
+ {{#isByteArray}}
+
+ let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec();
+
+ let {{{paramName}}}_mime = match mime::Mime::from_str("application/octet-stream") {
+ Ok(mime) => mime,
+ Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to get mime type: {:?}", err))))),
+ };
+
+ let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec);
+
+ let filename = None as Option<&str> ;
+ multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime));
+
+ {{/isByteArray}}
+ {{#-last}}
+ {{/-last}}
+ {{/formParams}}
+ {{/vendorExtensions}}
+
+ let mut fields = match multipart.prepare() {
+ Ok(fields) => fields,
+ Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))),
+ };
+
+ let mut body_string = String::new();
+ fields.to_body().read_to_string(&mut body_string).unwrap();
+ let boundary = fields.boundary();
+
+ let multipart_header = match Mime::from_str(&format!("multipart/form-data;boundary={}", boundary)) {
+ Ok(multipart_header) => multipart_header,
+ Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build multipart header: {:?}", err))))),
+ };
+
+ request.set_body(body_string.into_bytes());
+ request.headers_mut().set(ContentType(multipart_header));
+
+ {{/consumesMultipart}}
+{{/vendorExtensions}}
+{{#vendorExtensions}}
+ {{^consumesMultipart}}
+ {{#vendorExtensions}}
+ {{#formParams}}
+ {{#-first}}
+ let params = &[
+ {{/-first}}
+ ("{{{baseName}}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}format!("{:?}", param_{{{paramName}}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}param_{{{paramName}}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}),{{/vendorExtensions}}
+ {{#-last}}
];
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}.clone()));
- request.set_body(body.into_bytes());{{/-last}}{{/formParams}}{{/vendorExtensions}}{{#bodyParam}}{{#-first}}
+ request.set_body(body.into_bytes());
+ {{/-last}}
+ {{/formParams}}
+ {{/vendorExtensions}}
+ {{#bodyParam}}
+ {{#-first}}
// Body parameter
- {{/-first}}
+ {{/-first}}
{{#vendorExtensions}}
{{#consumesPlainText}}
{{#isByteArray}}
@@ -312,34 +402,51 @@ impl Api for Client where
});
{{/required}}
{{/vendorExtensions}}
- {{/bodyParam}}
+ {{^required}}
-{{#bodyParam}}{{^required}}if let Some(body) = body {
- {{/required}} request.set_body(body);
-{{^required}} }{{/required}}
+ if let Some(body) = body {
+{{/required}}
+ request.set_body(body);
+{{^required}}
+ }
+{{/required}}
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}.clone()));
-{{/bodyParam}}
+ {{/bodyParam}}
+ {{/consumesMultipart}}
+{{/vendorExtensions}}
+
request.headers_mut().set(XSpanId((context as &Has).get().0.clone()));
-{{#authMethods}}{{#isBasic}} if let Some(auth_data) = (context as &Has>).get().as_ref() {
+{{#authMethods}}
+ {{#isBasic}}
+ if let Some(auth_data) = (context as &Has >).get().as_ref() {
if let AuthData::Basic(ref basic_header) = *auth_data {
request.headers_mut().set(hyper::header::Authorization(
basic_header.clone(),
))
}
- }{{/isBasic}}{{#isApiKey}}{{#isKeyInHeader}} header! { ({{#vendorExtensions}}{{x-apiKeyName}}{{/vendorExtensions}}, "{{keyParamName}}") => [String] }
+ }
+ {{/isBasic}}
+ {{#isApiKey}}
+ {{#isKeyInHeader}}
+ header! { ({{#vendorExtensions}}{{x-apiKeyName}}{{/vendorExtensions}}, "{{keyParamName}}") => [String] }
if let Some(auth_data) = (context as &Has >).get().as_ref() {
if let AuthData::ApiKey(ref api_key) = *auth_data {
request.headers_mut().set({{#vendorExtensions}}{{x-apiKeyName}}{{/vendorExtensions}}(api_key.to_string()));
}
- }{{/isKeyInHeader}}{{/isApiKey}}{{/authMethods}}{{#headerParams}}{{#-first}}
+ }
+ {{/isKeyInHeader}}
+ {{/isApiKey}}
+{{/authMethods}}
+{{#headerParams}}
+{{#-first}}
// Header parameters
{{/-first}}{{^isMapContainer}} header! { (Request{{vendorExtensions.typeName}}, "{{{baseName}}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
{{#required}} request.headers_mut().set(Request{{vendorExtensions.typeName}}(param_{{{paramName}}}{{#isListContainer}}.clone(){{/isListContainer}}));
{{/required}}{{^required}} param_{{{paramName}}}.map(|header| request.headers_mut().set(Request{{vendorExtensions.typeName}}(header{{#isListContainer}}.clone(){{/isListContainer}})));
{{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{{paramName}}}: Option<{{{dataType}}}> = None;
-{{/isMapContainer}}{{/headerParams}}
-
+{{/isMapContainer}}
+{{/headerParams}}
Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| {
diff --git a/modules/openapi-generator/src/main/resources/rust-server/lib.mustache b/modules/openapi-generator/src/main/resources/rust-server/lib.mustache
index c163280799e..b1c055176ff 100644
--- a/modules/openapi-generator/src/main/resources/rust-server/lib.mustache
+++ b/modules/openapi-generator/src/main/resources/rust-server/lib.mustache
@@ -11,6 +11,7 @@ extern crate chrono;
extern crate lazy_static;
#[macro_use]
extern crate log;
+extern crate mime;
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
#[cfg(any(feature = "client", feature = "server"))]
diff --git a/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache b/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache
index d0acd71dc0a..b8492bebf98 100644
--- a/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache
+++ b/modules/openapi-generator/src/main/resources/rust-server/mimetypes.mustache
@@ -4,8 +4,9 @@ pub mod responses {
use hyper::mime::*;
// The macro is called per-operation to beat the recursion limit
-{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} /// Create Mime objects for the response content types for {{{operationId}}}
+{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}}
lazy_static! {
+ /// Create Mime objects for the response content types for {{{operationId}}}
pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}: Mime = "{{{mediaType}}}".parse().unwrap();
}
{{/dataType}}{{/-first}}{{/produces}}{{/responses}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
@@ -13,12 +14,14 @@ pub mod responses {
pub mod requests {
use hyper::mime::*;
-{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{{operationId}}}
+{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}}
lazy_static! {
+ /// Create Mime objects for the request content types for {{{operationId}}}
pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}".parse().unwrap();
}
-{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}} /// Create Mime objects for the request content types for {{{operationId}}}
+{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}}
lazy_static! {
+ /// Create Mime objects for the request content types for {{{operationId}}}
pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}".parse().unwrap();
}
{{/-first}}{{/formParams}}{{/vendorExtensions}}{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache
index 2aea9c00ae8..afe2744e04d 100644
--- a/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache
+++ b/modules/openapi-generator/src/main/resources/rust-server/server-mod.mustache
@@ -5,12 +5,16 @@ extern crate native_tls;
extern crate hyper_tls;
extern crate openssl;
extern crate mime;
-{{^apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}}
extern crate chrono;
extern crate percent_encoding;
extern crate url;
+{{^apiUsesUuid}}
+extern crate uuid;
+{{/apiUsesUuid}}
+{{#apiUsesMultipart}}
+extern crate multipart;
+{{/apiUsesMultipart}}
-{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
use std::sync::Arc;
use std::marker::PhantomData;
use futures::{Future, future, Stream, stream};
@@ -19,9 +23,18 @@ use hyper::{Request, Response, Error, StatusCode};
use hyper::header::{Headers, ContentType};
use self::url::form_urlencoded;
use mimetypes;
-
+{{#apiUsesMultipart}}
+use self::multipart::server::Multipart;
+use self::multipart::server::save::SaveResult;
+use std::fs;
+{{/apiUsesMultipart}}
use serde_json;
-{{#usesXml}}use serde_xml_rs;{{/usesXml}}
+{{#usesXml}}
+use serde_xml_rs;
+{{/usesXml}}
+{{#apiUsesUuid}}
+use uuid;
+{{/apiUsesUuid}}
#[allow(unused_imports)]
use std::collections::{HashMap, BTreeMap};
@@ -50,7 +63,7 @@ mod paths {
extern crate regex;
lazy_static! {
- pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[
+ pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![
{{#pathSet}}
r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}"{{^-last}},{{/-last}}
{{/pathSet}}
@@ -165,8 +178,14 @@ where
{{/authMethods}}
}
{{/hasAuthMethods}}
-
-{{#vendorExtensions}}{{#hasPathParams}}
+{{#vendorExtensions}}
+ {{#consumesMultipart}}
+ let boundary = match multipart_boundary(&headers) {
+ Some(boundary) => boundary.to_string(),
+ None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Couldn't find valid multipart body"))),
+ };
+ {{/consumesMultipart}}
+ {{#hasPathParams}}
// Path parameters
let path = uri.path().to_string();
let path_params =
@@ -175,7 +194,8 @@ where
.unwrap_or_else(||
panic!("Path {} matched RE {{{PATH_ID}}} in set but failed match against \"{}\"", path, paths::REGEX_{{{PATH_ID}}}.as_str())
);
-{{/hasPathParams}}{{/vendorExtensions}}
+ {{/hasPathParams}}
+{{/vendorExtensions}}
{{#pathParams}}
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{baseName}}}"].as_bytes()).decode_utf8() {
Ok(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
@@ -185,36 +205,39 @@ where
Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))))
};
{{/pathParams}}
-{{#headerParams}}{{#-first}}
+{{#headerParams}}
+ {{#-first}}
// Header parameters
-{{/-first}}
+ {{/-first}}
header! { (Request{{vendorExtensions.typeName}}, "{{{baseName}}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
-{{#required}}
+ {{#required}}
let param_{{{paramName}}} = match headers.get::() {
Some(param_{{{paramName}}}) => param_{{{paramName}}}.0.clone(),
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing or invalid required header {{{baseName}}}"))),
};
-{{/required}}
-{{^required}}
+ {{/required}}
+ {{^required}}
let param_{{{paramName}}} = headers.get::().map(|header| header.0.clone());
-{{/required}}{{/headerParams}}
-
-{{#queryParams}}{{#-first}}
+ {{/required}}
+{{/headerParams}}
+{{#queryParams}}
+ {{#-first}}
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>();
-{{/-first}}
+ {{/-first}}
let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.to_owned())
-{{#isListContainer}}
+ {{#isListContainer}}
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok())
.collect::>();
-{{^required}}
+ {{^required}}
let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() {
Some(param_{{{paramName}}})
} else {
None
};
-{{/required}}
-{{/isListContainer}}{{^isListContainer}}
+ {{/required}}
+{{/isListContainer}}
+{{^isListContainer}}
.nth(0);
{{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
@@ -229,8 +252,10 @@ where
{{/required}}
{{/isListContainer}}
{{/queryParams}}
-
-{{#bodyParams}}{{#-first}}
+{{#vendorExtensions}}
+ {{^consumesMultipart}}
+ {{#bodyParams}}
+ {{#-first}}
// Body parameters (note that non-required body parameters will ignore garbage
// values, rather than causing a 400 response). Produce warning header and logs for
// any unused fields.
@@ -238,53 +263,147 @@ where
.then(move |result| -> Box> {
match result {
Ok(body) => {
-{{#vendorExtensions}}{{^consumesPlainText}}
+ {{#vendorExtensions}}
+ {{^consumesPlainText}}
let mut unused_elements = Vec::new();
-{{/consumesPlainText}}
+ {{/consumesPlainText}}
let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() {
-{{#consumesXml}}
+ {{#consumesXml}}
let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body);
-{{/consumesXml}}{{#consumesJson}}
+ {{/consumesXml}}
+ {{#consumesJson}}
let deserializer = &mut serde_json::Deserializer::from_slice(&*body);
-{{/consumesJson}}{{^consumesPlainText}}
+ {{/consumesJson}}
+ {{^consumesPlainText}}
match serde_ignored::deserialize(deserializer, |path| {
warn!("Ignoring unknown field in body: {}", path);
unused_elements.push(path.to_string());
}) {
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
-{{#required}}
+ {{#required}}
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e)))),
-{{/required}}{{^required}}
+ {{/required}}
+ {{^required}}
Err(_) => None,
-{{/required}}
+ {{/required}}
}
-{{/consumesPlainText}}{{#consumesPlainText}}
-{{#isByteArray}}
+ {{/consumesPlainText}}
+ {{#consumesPlainText}}
+ {{#isByteArray}}
Some(swagger::ByteArray(body.to_vec()))
-{{/isByteArray}}
-{{#isString}}
+ {{/isByteArray}}
+ {{#isString}}
Some(String::from_utf8(body.to_vec()).unwrap())
-{{/isString}}
-{{/consumesPlainText}}{{/vendorExtensions}}
+ {{/isString}}
+ {{/consumesPlainText}}
+ {{/vendorExtensions}}
} else {
None
};
-{{#required}}
+ {{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => param_{{{paramName}}},
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter {{{baseName}}}"))),
};
-{{/required}}
-{{/-first}}{{/bodyParams}}
-{{^bodyParams}}{{#vendorExtensions}}
+ {{/required}}
+ {{/-first}}
+ {{/bodyParams}}
+ {{/consumesMultipart}}
+ {{#consumesMultipart}}
+ {{^bodyParams}}
+ {{#vendorExtensions}}
+ // Form Body parameters (note that non-required body parameters will ignore garbage
+ // values, rather than causing a 400 response). Produce warning header and logs for
+ // any unused fields.
+ Box::new(body.concat2()
+ .then(move |result| -> Box> {
+ match result {
+ Ok(body) => {
+ // Read Form Parameters from body
+ let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
+ SaveResult::Full(entries) => {
+ entries
+ },
+ _ => {
+ return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Unable to process all message parts"))))
+ },
+ };
+ {{#formParams}}{{#-first}}{{/-first}}
+ {{#isByteArray}}
+ let file_{{{paramName}}} = entries.files.remove("{{{paramName}}}");
+ {{#required}}
+ let param_{{{paramName}}} = match file_{{{paramName}}} {
+ Some(file) => {
+ let path = &file[0].path;
+ let {{{paramName}}}_str = fs::read_to_string(path).unwrap();
+ swagger::ByteArray({{{paramName}}}_str.as_bytes().to_vec())
+ }
+ None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter {{{paramName}}}")))),
+ };
+ {{/required}}
+ {{^required}}
+ let param_{{{paramName}}} = match file_{{{paramName}}} {
+ Some(file) => {
+ let path = &file[0].path;
+ let {{{paramName}}}_str = fs::read_to_string(path).unwrap();
+ Some(swagger::ByteArray({{{paramName}}}_str.as_bytes().to_vec()))
+ }
+ None => None,
+ };
+ {{/required}}
+ {{/isByteArray}}
+ {{^isByteArray}}{{#jsonSchema}}
+ let file_{{{paramName}}} = entries.files.remove("{{{paramName}}}");
+ {{#required}}
+ let param_{{{paramName}}} = match file_{{{paramName}}} {
+ Some(file) => {
+ let path = &file[0].path;
+ let {{{paramName}}}_str = fs::read_to_string(path).expect("Reading saved String should never fail");
+ let {{{paramName}}}_model: {{{dataType}}} = match serde_json::from_str(&{{{paramName}}}_str) {
+ Ok(model) => model,
+ Err(e) => {
+ return Box::new(future::ok(
+ Response::new()
+ .with_status(StatusCode::BadRequest)
+ .with_body(format!("{{{paramName}}} data does not match API definition: {}", e))))
+ }
+ };
+ {{{paramName}}}_model
+ }
+ None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter {{{paramName}}}")))),
+ };
+ {{/required}}
+ {{^required}}
+ let param_{{{paramName}}} = match file_{{{paramName}}} {
+ Some(file) => {
+ let path = &file[0].path;
+ let {{{paramName}}}_str = fs::read_to_string(path).unwrap();
+ let {{{paramName}}}_model: {{{dataType}}} = serde_json::from_str(&{{{paramName}}}_str).expect("Impossible to fail to serialise");
+ Some({{{paramName}}}_model)
+ }
+ None => None,
+ };
+ {{/required}}
+ {{/jsonSchema}}{{/isByteArray}}
+ {{/formParams}}
+ {{/vendorExtensions}}
+ {{/bodyParams}}
+ {{/consumesMultipart}}
+ {{^consumesMultipart}}
+ {{^bodyParams}}
+ {{#vendorExtensions}}
Box::new({
{{
-{{#formParams}}{{#-first}}
+ {{#formParams}}
+ {{#-first}}
// Form parameters
-{{/-first}}
+ {{/-first}}
let param_{{{paramName}}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}}
-{{/formParams}}
-{{/vendorExtensions}}{{/bodyParams}}
+ {{/formParams}}
+ {{/vendorExtensions}}
+ {{/bodyParams}}
+ {{/consumesMultipart}}
+{{/vendorExtensions}}
Box::new(api_impl.{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}param_{{{paramName}}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}&context)
.then(move |result| {
let mut response = Response::new();
@@ -356,19 +475,36 @@ where
future::ok(response)
}
))
-{{^bodyParams}}{{#vendorExtensions}}
+{{#vendorExtensions}}
+ {{^consumesMultipart}}
+ {{^bodyParams}}
}}
}) as Box>
-{{/vendorExtensions}}{{/bodyParams}}
-{{#bodyParams}}{{#-first}}
+ {{/bodyParams}}
+ {{/consumesMultipart}}
+{{/vendorExtensions}}
+{{#bodyParams}}
+ {{#-first}}
},
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))),
}
})
) as Box>
-{{/-first}}{{/bodyParams}}
+ {{/-first}}
+{{/bodyParams}}
+{{#vendorExtensions}}
+ {{#consumesMultipart}}
+ {{^bodyParams}}
+ as Box>
+ },
+ Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read multipart body")))),
+ }
+ })
+ )
+ {{/bodyParams}}
+ {{/consumesMultipart}}
+{{/vendorExtensions}}
},
-
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
_ => Box::new(future::ok(Response::new().with_status(StatusCode::NotFound))) as Box>,
}
@@ -385,6 +521,20 @@ impl Clone for Service
}
}
+{{#apiUsesMultipart}}
+/// Utility function to get the multipart boundary marker (if any) from the Headers.
+fn multipart_boundary<'a>(headers: &'a Headers) -> Option<&'a str> {
+ headers.get::().and_then(|content_type| {
+ let ContentType(ref mime) = *content_type;
+ if mime.type_() == hyper::mime::MULTIPART && mime.subtype() == hyper::mime::FORM_DATA {
+ mime.get_param(hyper::mime::BOUNDARY).map(|x| x.as_str())
+ } else {
+ None
+ }
+ })
+}
+{{/apiUsesMultipart}}
+
/// Request parser for `Api`.
pub struct ApiRequestParser;
impl RequestParser for ApiRequestParser {
diff --git a/modules/openapi-generator/src/main/resources/rust/model.mustache b/modules/openapi-generator/src/main/resources/rust/model.mustache
index f371e0e703c..1572a1a8718 100644
--- a/modules/openapi-generator/src/main/resources/rust/model.mustache
+++ b/modules/openapi-generator/src/main/resources/rust/model.mustache
@@ -20,7 +20,7 @@ pub enum {{classname}} {
{{!-- for non-enum schemas --}}
{{^isEnum}}
-#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct {{{classname}}} {
{{#vars}}
{{#description}}
@@ -49,7 +49,7 @@ impl {{{classname}}} {
{{#vars}}
{{#isEnum}}
/// {{{description}}}
-#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum {{enumName}} {
{{#allowableValues}}
{{#enumVars}}
diff --git a/modules/openapi-generator/src/main/resources/scala-finch/sbt b/modules/openapi-generator/src/main/resources/scala-finch/sbt
old mode 100644
new mode 100755
diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache
index 85573aa8b13..96c92290b4e 100644
--- a/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-angular/api.service.mustache
@@ -82,6 +82,7 @@ export class {{classname}} {
{{/useHttpClient}}
}
+{{#hasSomeFormParams}}
/**
* @param consumes string[] mime-types
* @return true: consumes contains 'multipart/form-data', false: otherwise
@@ -95,6 +96,7 @@ export class {{classname}} {
}
return false;
}
+{{/hasSomeFormParams}}
{{^useHttpClient}}
{{! Before HttpClient implementation or method overloading we relied on 2 functions, 1 to return the straight body as json
@@ -129,8 +131,12 @@ export class {{classname}} {
{{#operation}}
/**
+{{#summary}}
* {{summary}}
+{{/summary}}
+{{#notes}}
* {{notes}}
+{{/notes}}
{{#allParams}}* @param {{paramName}} {{description}}
{{/allParams}}{{#useHttpClient}}* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.{{/useHttpClient}}
@@ -256,12 +262,25 @@ export class {{classname}} {
{{/useHttpClient}}
}
+{{#bodyParam}}
+{{- duplicated below, don't forget to change}}
// to determine the Content-Type header
const consumes: string[] = [
{{#consumes}}
'{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
{{/consumes}}
];
+{{/bodyParam}}
+{{#hasFormParams}}
+{{^bodyParam}}
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ {{#consumes}}
+ '{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
+ {{/consumes}}
+ ];
+{{/bodyParam}}
+{{/hasFormParams}}
{{#bodyParam}}
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/encoder.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/encoder.mustache
index b3685b0bd92..c7e5f3cc8da 100644
--- a/modules/openapi-generator/src/main/resources/typescript-angular/encoder.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-angular/encoder.mustache
@@ -7,9 +7,9 @@ import { QueryEncoder } from '@angular/http';
{{#useHttpClient}}
/**
-* Custom HttpParameterCodec
-* Workaround for https://github.com/angular/angular/issues/18261
-*/
+ * Custom HttpParameterCodec
+ * Workaround for https://github.com/angular/angular/issues/18261
+ */
export class CustomHttpParameterCodec implements HttpParameterCodec {
encodeKey(k: string): string {
return encodeURIComponent(k);
@@ -27,10 +27,10 @@ export class CustomHttpParameterCodec implements HttpParameterCodec {
{{/useHttpClient}}
{{^useHttpClient}}
/**
-* Custom QueryEncoder
-* Fix plus sign (+) not encoding, so sent as blank space
-* See: https://github.com/angular/angular/issues/11058#issuecomment-247367318
-*/
+ * Custom QueryEncoder
+ * Fix plus sign (+) not encoding, so sent as blank space
+ * See: https://github.com/angular/angular/issues/11058#issuecomment-247367318
+ */
export class CustomQueryEncoderHelper extends QueryEncoder {
encodeKey(k: string): string {
k = super.encodeKey(k);
diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/modelEnum.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/modelEnum.mustache
index 7ad77ac62a2..4695a611e79 100644
--- a/modules/openapi-generator/src/main/resources/typescript-angular/modelEnum.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-angular/modelEnum.mustache
@@ -1,3 +1,13 @@
+{{#stringEnums}}
+export enum {{classname}} {
+{{#allowableValues}}
+{{#enumVars}}
+ {{name}} = {{{value}}}{{^-last}},{{/-last}}
+{{/enumVars}}
+{{/allowableValues}}
+};
+{{/stringEnums}}
+{{^stringEnums}}
export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{classname}} = {
@@ -6,4 +16,5 @@ export const {{classname}} = {
{{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
-};
\ No newline at end of file
+};
+{{/stringEnums}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/typescript-angular/modelGenericEnums.mustache b/modules/openapi-generator/src/main/resources/typescript-angular/modelGenericEnums.mustache
index eb450b57fcc..a824e55ec53 100644
--- a/modules/openapi-generator/src/main/resources/typescript-angular/modelGenericEnums.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-angular/modelGenericEnums.mustache
@@ -1,8 +1,20 @@
{{#hasEnums}}
+{{^stringEnums}}
export namespace {{classname}} {
+{{/stringEnums}}
{{#vars}}
{{#isEnum}}
+{{#stringEnums}}
+export enum {{classname}}{{enumName}} {
+{{#allowableValues}}
+{{#enumVars}}
+ {{name}} = {{{value}}}{{^-last}},{{/-last}}
+{{/enumVars}}
+{{/allowableValues}}
+};
+{{/stringEnums}}
+{{^stringEnums}}
export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{enumName}} = {
{{#allowableValues}}
@@ -11,6 +23,8 @@ export namespace {{classname}} {
{{/enumVars}}
{{/allowableValues}}
};
+{{/stringEnums}}
{{/isEnum}}
{{/vars}}
-}{{/hasEnums}}
\ No newline at end of file
+{{^stringEnums}}}{{/stringEnums}}
+{{/hasEnums}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache b/modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache
index 52c5354446c..62103f4c7db 100644
--- a/modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache
@@ -133,12 +133,18 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
{{#headerParams}}
{{#isListContainer}}
if ({{paramName}}) {
- localVarHeaderParameter['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}});
+ let mapped = {{paramName}}.map(value => ("{{{dataType}}}" !== "Array") ? JSON.stringify(value) : (value || ""));
+ localVarHeaderParameter['{{baseName}}'] = mapped.join(COLLECTION_FORMATS["{{collectionFormat}}"]);
}
{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined && {{paramName}} !== null) {
+ {{#isString}}
localVarHeaderParameter['{{baseName}}'] = String({{paramName}});
+ {{/isString}}
+ {{^isString}}
+ localVarHeaderParameter['{{baseName}}'] = String(JSON.stringify({{paramName}}));
+ {{/isString}}
}
{{/isListContainer}}
@@ -164,10 +170,10 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
}
{{/isListContainer}}
{{/formParams}}{{/vendorExtensions}}
- {{#hasFormParams}}{{#multipartFormData}}
+ {{#vendorExtensions}}{{#hasFormParams}}{{^multipartFormData}}
localVarHeaderParameter['Content-Type'] = 'application/x-www-form-urlencoded';{{/multipartFormData}}{{#multipartFormData}}
localVarHeaderParameter['Content-Type'] = 'multipart/form-data';{{/multipartFormData}}
- {{/hasFormParams}}
+ {{/hasFormParams}}{{/vendorExtensions}}
{{#bodyParam}}
{{^consumes}}
localVarHeaderParameter['Content-Type'] = 'application/json';
diff --git a/modules/openapi-generator/src/main/resources/typescript-axios/configuration.mustache b/modules/openapi-generator/src/main/resources/typescript-axios/configuration.mustache
index 98585d783f4..575a42c020f 100644
--- a/modules/openapi-generator/src/main/resources/typescript-axios/configuration.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-axios/configuration.mustache
@@ -5,7 +5,7 @@ export interface ConfigurationParameters {
apiKey?: string | ((name: string) => string);
username?: string;
password?: string;
- accessToken?: string | ((name: string, scopes?: string[]) => string);
+ accessToken?: string | ((name?: string, scopes?: string[]) => string);
basePath?: string;
baseOptions?: any;
}
@@ -37,7 +37,7 @@ export class Configuration {
* @param scopes oauth2 scope
* @memberof Configuration
*/
- accessToken?: string | ((name: string, scopes?: string[]) => string);
+ accessToken?: string | ((name?: string, scopes?: string[]) => string);
/**
* override base path
*
diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache
index 662ec63b5b8..d1751f7135d 100644
--- a/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache
@@ -181,7 +181,7 @@ export class {{classname}} extends runtime.BaseAPI {
{{#hasBodyParam}}
{{#bodyParam}}
{{#isContainer}}
- body: requestParameters.{{paramName}}.map({{#items}}{{datatype}}{{/items}}ToJSON),
+ body: requestParameters.{{paramName}}{{#isListContainer}}{{#items}}{{^isPrimitiveType}}.map({{datatype}}ToJSON){{/isPrimitiveType}}{{/items}}{{/isListContainer}},
{{/isContainer}}
{{^isContainer}}
{{^isPrimitiveType}}
diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/npmignore.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/npmignore.mustache
new file mode 100644
index 00000000000..42061c01a1c
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/typescript-fetch/npmignore.mustache
@@ -0,0 +1 @@
+README.md
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/package.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/package.mustache
index 5bfbc1a9236..1c9d9e55bbf 100644
--- a/modules/openapi-generator/src/main/resources/typescript-fetch/package.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-fetch/package.mustache
@@ -6,7 +6,7 @@
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"scripts" : {
- "build": "tsc --outDir dist/",
+ "build": "tsc",
"prepare": "npm run build"
},
"devDependencies": {
diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache
index 6878fd84958..0b42e5e8629 100644
--- a/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache
@@ -52,10 +52,13 @@ export class BaseAPI {
const body = (context.body instanceof FormData || isBlob(context.body))
? context.body
: JSON.stringify(context.body);
+
+ const headers = Object.assign({}, this.configuration.headers, context.headers);
const init = {
method: context.method,
- headers: context.headers,
+ headers: headers,
body,
+ credentials: this.configuration.credentials
};
return { url, init };
}
@@ -120,7 +123,9 @@ export interface ConfigurationParameters {
username?: string; // parameter for basic security
password?: string; // parameter for basic security
apiKey?: string | ((name: string) => string); // parameter for apiKey security
- accessToken?: string | ((name: string, scopes?: string[]) => string); // parameter for oauth2 security
+ accessToken?: string | ((name?: string, scopes?: string[]) => string); // parameter for oauth2 security
+ headers?: HTTPHeaders; //header params we want to use on every request
+ credentials?: RequestCredentials; //value for the credentials param we want to use on each request
}
export class Configuration {
@@ -165,6 +170,14 @@ export class Configuration {
}
return undefined;
}
+
+ get headers(): HTTPHeaders | undefined {
+ return this.configuration.headers;
+ }
+
+ get credentials(): RequestCredentials | undefined {
+ return this.configuration.credentials;
+ }
}
export type Json = any;
diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/tsconfig.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/tsconfig.mustache
index 328c7d4e141..420c3a44f88 100644
--- a/modules/openapi-generator/src/main/resources/typescript-fetch/tsconfig.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-fetch/tsconfig.mustache
@@ -5,7 +5,6 @@
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
- "rootDir": ".",
{{^supportsES6}}
"lib": [
"es6",
diff --git a/modules/openapi-generator/src/main/resources/typescript-node/model.mustache b/modules/openapi-generator/src/main/resources/typescript-node/model.mustache
index c9ef8ebbc06..3559593a50c 100644
--- a/modules/openapi-generator/src/main/resources/typescript-node/model.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-node/model.mustache
@@ -2,7 +2,7 @@
{{#models}}
{{#model}}
{{#tsImports}}
-import { {{classname}} } from './{{filename}}';
+import { {{classname}} } from '{{filename}}';
{{/tsImports}}
{{#description}}
diff --git a/modules/openapi-generator/src/main/resources/typescript-node/models.mustache b/modules/openapi-generator/src/main/resources/typescript-node/models.mustache
index 0bd709c2dda..59e86fe445d 100644
--- a/modules/openapi-generator/src/main/resources/typescript-node/models.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-node/models.mustache
@@ -1,6 +1,6 @@
{{#models}}
{{#model}}
-export * from './{{{ classFilename }}}';
+export * from '{{{ classFilename }}}';
{{/model}}
{{/models}}
@@ -8,7 +8,7 @@ import localVarRequest = require('request');
{{#models}}
{{#model}}
-import { {{classname}} } from './{{{ classFilename }}}';
+import { {{classname}} } from '{{{ classFilename }}}';
{{/model}}
{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/typescript-rxjs/runtime.mustache b/modules/openapi-generator/src/main/resources/typescript-rxjs/runtime.mustache
index 429584b64c3..27f466a6650 100644
--- a/modules/openapi-generator/src/main/resources/typescript-rxjs/runtime.mustache
+++ b/modules/openapi-generator/src/main/resources/typescript-rxjs/runtime.mustache
@@ -12,7 +12,7 @@ export interface ConfigurationParameters {
username?: string; // parameter for basic security
password?: string; // parameter for basic security
apiKey?: string | ((name: string) => string); // parameter for apiKey security
- accessToken?: string | ((name: string, scopes?: string[]) => string); // parameter for oauth2 security
+ accessToken?: string | ((name?: string, scopes?: string[]) => string); // parameter for oauth2 security
}
export class Configuration {
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
index 871958108e8..9dbb5bb5c13 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
@@ -18,6 +18,8 @@
package org.openapitools.codegen;
import com.google.common.collect.Sets;
+import com.samskivert.mustache.Mustache.Lambda;
+
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
@@ -30,14 +32,19 @@ import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.parser.core.models.ParseOptions;
-import org.openapitools.codegen.languages.features.CXFServerFeatures;
+
+import org.openapitools.codegen.templating.mustache.CamelCaseLambda;
+import org.openapitools.codegen.templating.mustache.IndentedLambda;
+import org.openapitools.codegen.templating.mustache.LowercaseLambda;
+import org.openapitools.codegen.templating.mustache.TitlecaseLambda;
+import org.openapitools.codegen.templating.mustache.UppercaseLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.testng.Assert;
import org.testng.annotations.Test;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
import java.util.*;
import java.util.stream.Collectors;
@@ -477,6 +484,44 @@ public class DefaultCodegenTest {
Assert.assertEquals(childModel.parentSchema, "Person");
}
+ @Test
+ public void testAllOfRequired() {
+ final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/allOf-required.yaml");
+ DefaultCodegen codegen = new DefaultCodegen();
+
+ Schema child = openAPI.getComponents().getSchemas().get("clubForCreation");
+ codegen.setOpenAPI(openAPI);
+ CodegenModel childModel = codegen.fromModel("clubForCreation", child);
+ showVars(childModel);
+ }
+
+ @Test
+ public void testAllOfParent() {
+ final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/allOf-required-parent.yaml");
+ DefaultCodegen codegen = new DefaultCodegen();
+ codegen.setOpenAPI(openAPI);
+
+ Schema person = openAPI.getComponents().getSchemas().get("person");
+ CodegenModel personModel = codegen.fromModel("person", person);
+ showVars(personModel);
+
+ Schema personForCreation = openAPI.getComponents().getSchemas().get("personForCreation");
+ CodegenModel personForCreationModel = codegen.fromModel("personForCreation", personForCreation);
+ showVars(personForCreationModel);
+
+ Schema personForUpdate = openAPI.getComponents().getSchemas().get("personForUpdate");
+ CodegenModel personForUpdateModel = codegen.fromModel("personForUpdate", personForUpdate);
+ showVars(personForUpdateModel);
+ }
+
+ private void showVars(CodegenModel model) {
+ if(model.getRequiredVars() != null) {
+
+ System.out.println(model.getRequiredVars().stream().map(v -> v.name).collect(Collectors.toList()));
+ }
+ }
+
+
@Test
public void testCallbacks() {
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/callbacks.yaml");
@@ -850,6 +895,7 @@ public class DefaultCodegenTest {
Assert.assertEquals(codegenModel.vars.size(), 1);
}
+
@Test
public void modelWithSuffixDoNotContainInheritedVars() {
DefaultCodegen codegen = new DefaultCodegen();
@@ -865,4 +911,25 @@ public class DefaultCodegenTest {
Assert.assertEquals(codegenModel.vars.size(), 1);
}
+ @Test
+ @SuppressWarnings("unchecked")
+ public void commonLambdasRegistrationTest() {
+
+ DefaultCodegen codegen = new DefaultCodegen();
+ Object lambdasObj = codegen.additionalProperties.get("lambda");
+
+ assertNotNull(lambdasObj, "Expecting lambda in additionalProperties");
+
+ Map lambdas = (Map) lambdasObj;
+
+ assertTrue(lambdas.get("lowercase") instanceof LowercaseLambda, "Expecting LowercaseLambda class");
+ assertTrue(lambdas.get("uppercase") instanceof UppercaseLambda, "Expecting UppercaseLambda class");
+ assertTrue(lambdas.get("titlecase") instanceof TitlecaseLambda, "Expecting TitlecaseLambda class");
+ assertTrue(lambdas.get("camelcase") instanceof CamelCaseLambda, "Expecting CamelCaseLambda class");
+ assertTrue(lambdas.get("indented") instanceof IndentedLambda, "Expecting IndentedLambda class");
+ assertTrue(lambdas.get("indented_8") instanceof IndentedLambda, "Expecting IndentedLambda class");
+ assertTrue(lambdas.get("indented_12") instanceof IndentedLambda, "Expecting IndentedLambda class");
+ assertTrue(lambdas.get("indented_16") instanceof IndentedLambda, "Expecting IndentedLambda class");
+ }
+
}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CSharpModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CSharpModelTest.java
index 7134fe37978..91600d2ac10 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CSharpModelTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CSharpModelTest.java
@@ -141,10 +141,10 @@ public class CSharpModelTest {
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "id");
- Assert.assertEquals(property1.dataType, "long?");
+ Assert.assertEquals(property1.dataType, "long");
Assert.assertEquals(property1.name, "Id");
Assert.assertNull(property1.defaultValue);
- Assert.assertEquals(property1.baseType, "long?");
+ Assert.assertEquals(property1.baseType, "long");
Assert.assertTrue(property1.hasMore);
Assert.assertTrue(property1.required);
Assert.assertTrue(property1.isPrimitiveType);
@@ -161,10 +161,10 @@ public class CSharpModelTest {
final CodegenProperty property3 = cm.vars.get(2);
Assert.assertEquals(property3.baseName, "createdAt");
- Assert.assertEquals(property3.dataType, "DateTime?");
+ Assert.assertEquals(property3.dataType, "DateTime");
Assert.assertEquals(property3.name, "CreatedAt");
Assert.assertNull(property3.defaultValue);
- Assert.assertEquals(property3.baseType, "DateTime?");
+ Assert.assertEquals(property3.baseType, "DateTime");
Assert.assertFalse(property3.hasMore);
Assert.assertFalse(property3.required);
}
@@ -209,7 +209,59 @@ public class CSharpModelTest {
Assert.assertFalse(property2.required);
Assert.assertTrue(property2.isPrimitiveType);
Assert.assertTrue(property2.isContainer);
-
+
+ final CodegenProperty property3 = cm.vars.get(2);
+ Assert.assertEquals(property3.baseName, "name");
+ Assert.assertEquals(property3.dataType, "string");
+ Assert.assertEquals(property3.name, "Name");
+ Assert.assertNull(property3.defaultValue);
+ Assert.assertEquals(property3.baseType, "string");
+ Assert.assertFalse(property3.hasMore);
+ Assert.assertFalse(property3.required);
+ Assert.assertTrue(property3.isPrimitiveType);
+ }
+
+ @Test(description = "convert a model with a nullable property")
+ public void nullablePropertyTest() {
+ final Schema model = new Schema()
+ .description("a sample model")
+ .addProperties("id", new IntegerSchema().format(SchemaTypeUtil.INTEGER64_FORMAT).nullable(true))
+ .addProperties("urls", new ArraySchema()
+ .items(new StringSchema()))
+ .addProperties("name", new StringSchema().nullable(true))
+ .addRequiredItem("id");
+ final DefaultCodegen codegen = new CSharpClientCodegen();
+ OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model);
+ codegen.setOpenAPI(openAPI);
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 3);
+
+ final CodegenProperty property1 = cm.vars.get(0);
+ Assert.assertEquals(property1.baseName, "id");
+ Assert.assertEquals(property1.dataType, "long?");
+ Assert.assertEquals(property1.name, "Id");
+ Assert.assertNull(property1.defaultValue);
+ Assert.assertEquals(property1.baseType, "long?");
+ Assert.assertTrue(property1.hasMore);
+ Assert.assertTrue(property1.required);
+ Assert.assertTrue(property1.isPrimitiveType);
+
+ final CodegenProperty property2 = cm.vars.get(1);
+ Assert.assertEquals(property2.baseName, "urls");
+ Assert.assertEquals(property2.dataType, "List");
+ Assert.assertEquals(property2.name, "Urls");
+ Assert.assertNull(property2.defaultValue);
+ Assert.assertEquals(property2.baseType, "List");
+ Assert.assertTrue(property2.hasMore);
+ Assert.assertEquals(property2.containerType, "array");
+ Assert.assertFalse(property2.required);
+ Assert.assertTrue(property2.isPrimitiveType);
+ Assert.assertTrue(property2.isContainer);
+
final CodegenProperty property3 = cm.vars.get(2);
Assert.assertEquals(property3.baseName, "name");
Assert.assertEquals(property3.dataType, "string");
@@ -241,10 +293,10 @@ public class CSharpModelTest {
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "id");
- Assert.assertEquals(property1.dataType, "long?");
+ Assert.assertEquals(property1.dataType, "long");
Assert.assertEquals(property1.name, "Id");
Assert.assertNull(property1.defaultValue);
- Assert.assertEquals(property1.baseType, "long?");
+ Assert.assertEquals(property1.baseType, "long");
Assert.assertTrue(property1.hasMore);
Assert.assertTrue(property1.required);
Assert.assertTrue(property1.isPrimitiveType);
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java
index 4fa35f9675a..578b485e8d1 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java
@@ -41,6 +41,9 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
+import static org.openapitools.codegen.languages.SpringCodegen.RESPONSE_WRAPPER;
+import static org.testng.Assert.assertTrue;
+
public class SpringCodegenTest {
@Test
@@ -103,10 +106,10 @@ public class SpringCodegenTest {
codegen.additionalProperties().put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true");
codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.yyyyy.mmmmm.model");
codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "xyz.yyyyy.aaaaa.api");
- codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE,"xyz.yyyyy.iiii.invoker");
- codegen.additionalProperties().put(SpringCodegen.BASE_PACKAGE,"xyz.yyyyy.bbbb.base");
- codegen.additionalProperties().put(SpringCodegen.CONFIG_PACKAGE,"xyz.yyyyy.cccc.config");
- codegen.additionalProperties().put(SpringCodegen.SERVER_PORT,"8088");
+ codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE, "xyz.yyyyy.iiii.invoker");
+ codegen.additionalProperties().put(SpringCodegen.BASE_PACKAGE, "xyz.yyyyy.bbbb.base");
+ codegen.additionalProperties().put(SpringCodegen.CONFIG_PACKAGE, "xyz.yyyyy.cccc.config");
+ codegen.additionalProperties().put(SpringCodegen.SERVER_PORT, "8088");
codegen.processOpts();
OpenAPI openAPI = new OpenAPI();
@@ -179,4 +182,46 @@ public class SpringCodegenTest {
.collect(groupingBy(CliOption::getOpt))
.forEach((k,v) -> assertEquals(v.size(), 1, k + " is described multiple times"));
}
+
+ @Test
+ public void springcloudWithJava8DisabeJdk8() {
+ final SpringCodegen codegen = new SpringCodegen();
+ codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
+ codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
+ codegen.processOpts();
+
+ Assert.assertEquals(codegen.additionalProperties().get("jdk8-default-interface"), false);
+ }
+
+ @Test
+ public void springcloudWithAsyncHasResponseWrapperCallable() {
+ final SpringCodegen codegen = new SpringCodegen();
+ codegen.additionalProperties().put(SpringCodegen.JAVA_8, false);
+ codegen.additionalProperties().put(SpringCodegen.ASYNC, true);
+ codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
+ codegen.processOpts();
+
+ Assert.assertNull(codegen.additionalProperties().get("jdk8-default-interface"));
+ Assert.assertEquals(codegen.additionalProperties().get(RESPONSE_WRAPPER), "Callable");
+ }
+
+ @Test
+ public void springcloudWithAsyncAndJava8HasResponseWrapperCompletableFuture() {
+ final SpringCodegen codegen = new SpringCodegen();
+ codegen.additionalProperties().put(SpringCodegen.JAVA_8, true);
+ codegen.additionalProperties().put(SpringCodegen.ASYNC, true);
+ codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
+ codegen.processOpts();
+
+ Assert.assertEquals(codegen.additionalProperties().get("jdk8-default-interface"), false);
+ Assert.assertEquals(codegen.additionalProperties().get(RESPONSE_WRAPPER), "CompletableFuture");
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void reactiveRequiredSpringBoot() {
+ final SpringCodegen codegen = new SpringCodegen();
+ codegen.additionalProperties().put(SpringCodegen.REACTIVE, true);
+ codegen.additionalProperties().put(CodegenConstants.LIBRARY, "spring-cloud");
+ codegen.processOpts();
+ }
}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/RubyClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/RubyClientOptionsProvider.java
index a42bbb22f09..61c914163c3 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/RubyClientOptionsProvider.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/RubyClientOptionsProvider.java
@@ -38,6 +38,7 @@ public class RubyClientOptionsProvider implements OptionsProvider {
public static final String GEM_AUTHOR_EMAIL_VALUE = "foo";
public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false";
public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true";
+ public static final String LIBRARY = "typhoeus";
@Override
public String getLanguage() {
@@ -62,6 +63,7 @@ public class RubyClientOptionsProvider implements OptionsProvider {
.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "true")
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
.put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
+ .put(CodegenConstants.LIBRARY, LIBRARY)
.build();
}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java
index 6100c2d4692..d464a532a0e 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/TypeScriptAngularClientOptionsProvider.java
@@ -25,6 +25,7 @@ import java.util.Map;
public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
public static final String SUPPORTS_ES6_VALUE = "false";
+ public static final String STRING_ENUMS_VALUE = "false";
public static final String SORT_PARAMS_VALUE = "false";
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase";
@@ -52,6 +53,7 @@ public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
.put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE)
.put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE)
+ .put(TypeScriptAngularClientCodegen.STRING_ENUMS, STRING_ENUMS_VALUE)
.put(TypeScriptAngularClientCodegen.NPM_NAME, NMP_NAME)
.put(TypeScriptAngularClientCodegen.NPM_VERSION, NMP_VERSION)
.put(TypeScriptAngularClientCodegen.SNAPSHOT, Boolean.FALSE.toString())
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CamelCaseLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CamelCaseLambdaTest.java
new file mode 100644
index 00000000000..f984adcb0f8
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CamelCaseLambdaTest.java
@@ -0,0 +1,63 @@
+package org.openapitools.codegen.templating.mustache;
+
+import static org.mockito.AdditionalAnswers.returnsFirstArg;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.openapitools.codegen.CodegenConfig;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class CamelCaseLambdaTest extends LambdaTest {
+
+ @Mock
+ CodegenConfig generator;
+
+ @BeforeMethod
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void camelCaseTest() {
+ // Given
+ Map ctx = context("camelcase", new CamelCaseLambda());
+
+ // When & Then
+ test("inputText", "{{#camelcase}}Input-text{{/camelcase}}", ctx);
+ }
+
+ @Test
+ public void camelCaseReservedWordTest() {
+ // Given
+ Map ctx = context("camelcase", new CamelCaseLambda().generator(generator));
+
+ when(generator.sanitizeName(anyString())).then(returnsFirstArg());
+ when(generator.reservedWords()).thenReturn(new HashSet(Arrays.asList("reservedWord")));
+ when(generator.escapeReservedWord("reservedWord")).thenReturn("escapedReservedWord");
+
+ // When & Then
+ test("escapedReservedWord", "{{#camelcase}}reserved-word{{/camelcase}}", ctx);
+ }
+
+ @Test
+ public void camelCaseEscapeParamTest() {
+ // Given
+ Map ctx = context("camelcase", new CamelCaseLambda()
+ .generator(generator).escapeAsParamName(true));
+
+ when(generator.sanitizeName(anyString())).then(returnsFirstArg());
+ when(generator.reservedWords()).thenReturn(new HashSet());
+ when(generator.toParamName("inputText")).thenReturn("inputTextAsParam");
+
+ // When & Then
+ test("inputTextAsParam", "{{#camelcase}}Input_text{{/camelcase}}", ctx);
+ }
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/IndentedLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/IndentedLambdaTest.java
new file mode 100644
index 00000000000..51a4eeda0a3
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/IndentedLambdaTest.java
@@ -0,0 +1,35 @@
+package org.openapitools.codegen.templating.mustache;
+
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class IndentedLambdaTest extends LambdaTest {
+
+ String lineSeparator = System.lineSeparator();
+
+ @Test
+ public void defaultIndentTest() {
+ // Given
+ Map ctx = context("indented", new IndentedLambda());
+ String lineSeparator = System.lineSeparator();
+
+ // When & Then
+ // IndentedLambda applies indentation from second line on of a template.
+ test("first line" + lineSeparator + " second line",
+ "{{#indented}}first line" + lineSeparator +"second line{{/indented}}", ctx);
+ }
+
+ @Test
+ public void indentedCountTest() {
+ // Given
+ Map ctx = context("indented", new IndentedLambda(8, " "));
+
+ // When & Then
+ // IndentedLambda applies indentation from second line on of a template.
+ test("first line" + lineSeparator + " second line",
+ "{{#indented}}first line" + lineSeparator +"second line{{/indented}}", ctx);
+ }
+
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/LambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/LambdaTest.java
new file mode 100644
index 00000000000..fbaed952eff
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/LambdaTest.java
@@ -0,0 +1,44 @@
+package org.openapitools.codegen.templating.mustache;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.samskivert.mustache.Mustache;
+
+/**
+ * Simple framework to test Mustache Lambdas. It avoids
+ * compiler->compile->execute->assert
+ * boilerplate code.
+ *
+ * Inspired by Jmustache SharedTests.java
+ *
+ */
+public abstract class LambdaTest {
+
+ protected String execute(String template, Object ctx) {
+ return execute(Mustache.compiler(), template, ctx);
+ }
+
+ protected String execute(Mustache.Compiler compiler, String template, Object ctx) {
+ return compiler.compile(template).execute(ctx);
+ }
+
+ protected void test(String expected, String template, Map ctx) {
+ test(Mustache.compiler(), expected, template, ctx);
+ }
+
+ protected void test(Mustache.Compiler compiler, String expected,String template, Map ctx) {
+ assertEquals(execute(compiler, template, ctx), expected);
+ }
+
+ protected static Map context(Object... data) {
+ Map ctx = new HashMap();
+ for (int ii = 0; ii < data.length; ii += 2) {
+ ctx.put(data[ii].toString(), data[ii + 1]);
+ }
+ return ctx;
+ }
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/LowercaseLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/LowercaseLambdaTest.java
new file mode 100644
index 00000000000..87ade0caa70
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/LowercaseLambdaTest.java
@@ -0,0 +1,49 @@
+package org.openapitools.codegen.templating.mustache;
+
+import static org.mockito.AdditionalAnswers.returnsFirstArg;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.openapitools.codegen.CodegenConfig;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class LowercaseLambdaTest extends LambdaTest {
+
+ @Mock
+ CodegenConfig generator;
+
+ @BeforeMethod
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void lowercaseTest() {
+ // Given
+ Map ctx = context("lowercase", new LowercaseLambda());
+
+ // When & Then
+ test("input text", "{{#lowercase}}InPut Text{{/lowercase}}", ctx);
+ }
+
+ @Test
+ public void lowercaseReservedWordTest() {
+ // Given
+ Map ctx = context("lowercase", new LowercaseLambda().generator(generator));
+
+ when(generator.sanitizeName(anyString())).then(returnsFirstArg());
+ when(generator.reservedWords()).thenReturn(new HashSet(Arrays.asList("reserved")));
+ when(generator.escapeReservedWord("reserved")).thenReturn("escaped-reserved");
+
+ // When & Then
+ test("escaped-reserved", "{{#lowercase}}rEservEd{{/lowercase}}", ctx);
+ }
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/OnChangeLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/OnChangeLambdaTest.java
new file mode 100644
index 00000000000..175524c0d28
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/OnChangeLambdaTest.java
@@ -0,0 +1,42 @@
+package org.openapitools.codegen.templating.mustache;
+
+import java.util.Map;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class OnChangeLambdaTest extends LambdaTest {
+
+ private Map ctx;
+
+ // OnChangeLambda holds internal state it is important that context is
+ // reinitialize before each test.
+ @BeforeMethod
+ public void setup() {
+ ctx = context("onchange", new OnChangeLambda());
+ }
+
+ @Test
+ public void firstValueIsReturnedTest() {
+ // Given
+
+ // When & Then
+ test("first", "{{#onchange}}first{{/onchange}}", ctx);
+ }
+
+ @Test
+ public void repeatingValueReturnedOnFirstOccurrenceTest() {
+ // Given
+
+ // When & Then
+ test("First", "{{#onchange}}First{{/onchange}}", ctx);
+ test("", "{{#onchange}}First{{/onchange}}", ctx);
+
+ test("Another", "{{#onchange}}Another{{/onchange}}", ctx);
+ test("", "{{#onchange}}Another{{/onchange}}", ctx);
+ test("", "{{#onchange}}Another{{/onchange}}", ctx);
+
+ test("First", "{{#onchange}}First{{/onchange}}", ctx);
+ }
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/TitlecaseLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/TitlecaseLambdaTest.java
new file mode 100644
index 00000000000..2b3f632e9dd
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/TitlecaseLambdaTest.java
@@ -0,0 +1,28 @@
+package org.openapitools.codegen.templating.mustache;
+
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class TitlecaseLambdaTest extends LambdaTest {
+
+ @Test
+ public void titlecaseTest() {
+ // Given
+ Map ctx = context("titlecase", new TitlecaseLambda());
+
+ // When & Then
+ test("Once Upon A Time", "{{#titlecase}}once upon a time{{/titlecase}}", ctx);
+ }
+
+ @Test
+ public void titlecaseWithDelimiterTest() {
+ // Given
+ Map ctx = context("titlecase", new TitlecaseLambda("-"));
+
+ // When & Then
+ test("Once-Upon-A-Time", "{{#titlecase}}once-upon-a-time{{/titlecase}}", ctx);
+ }
+
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/UppercaseLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/UppercaseLambdaTest.java
new file mode 100644
index 00000000000..ebd12454ce6
--- /dev/null
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/UppercaseLambdaTest.java
@@ -0,0 +1,18 @@
+package org.openapitools.codegen.templating.mustache;
+
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class UppercaseLambdaTest extends LambdaTest {
+
+ @Test
+ public void uppercaseTest() {
+ // Given
+ Map ctx = context("uppercase", new UppercaseLambda());
+
+ // When & Then
+ test("INPUT TEXT", "{{#uppercase}}InPut Text{{/uppercase}}", ctx);
+ }
+
+}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java
index 21cb66f7767..8adc9328ec5 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientCodegenTest.java
@@ -3,6 +3,8 @@ package org.openapitools.codegen.typescript.typescriptangular;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.media.ComposedSchema;
+import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.CodegenOperation;
@@ -109,4 +111,25 @@ public class TypeScriptAngularClientCodegenTest {
Assert.assertEquals("TestName", codegen.removeModelPrefixSuffix("TestNameDefGhi"));
}
+ @Test
+ public void testSchema() {
+ TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
+
+ ComposedSchema composedSchema = new ComposedSchema();
+
+ Schema schema1 = new Schema<>();
+ schema1.set$ref("SchemaOne");
+ Schema schema2 = new Schema<>();
+ schema2.set$ref("SchemaTwo");
+ Schema schema3 = new Schema<>();
+ schema3.set$ref("SchemaThree");
+
+ composedSchema.addAnyOfItem(schema1);
+ composedSchema.addAnyOfItem(schema2);
+ composedSchema.addAnyOfItem(schema3);
+
+ String schemaType = codegen.getSchemaType(composedSchema);
+ Assert.assertEquals(schemaType, "SchemaOne | SchemaTwo | SchemaThree");
+ }
+
}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java
index 91f24924159..e7ab479a537 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypeScriptAngularClientOptionsTest.java
@@ -48,6 +48,8 @@ public class TypeScriptAngularClientOptionsTest extends AbstractOptionsTest {
times = 1;
clientCodegen.setSupportsES6(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.SUPPORTS_ES6_VALUE));
times = 1;
+ clientCodegen.setStringEnums(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.STRING_ENUMS_VALUE));
+ times = 1;
clientCodegen.setPrependFormOrBodyParameters(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.PREPEND_FORM_OR_BODY_PARAMETERS_VALUE));
times = 1;
}};
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java
index 93fb08719d7..5cce4a425ea 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeClientCodegenTest.java
@@ -4,68 +4,134 @@ import io.swagger.v3.oas.models.OpenAPI;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.languages.TypeScriptNodeClientCodegen;
import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class TypeScriptNodeClientCodegenTest {
+ private TypeScriptNodeClientCodegen codegen;
+
+ @BeforeMethod
+ public void setUp() {
+ codegen = new TypeScriptNodeClientCodegen();
+ }
+
@Test
public void convertVarName() throws Exception {
- TypeScriptNodeClientCodegen codegen = new TypeScriptNodeClientCodegen();
- Assert.assertEquals(codegen.toVarName("name"), "name");
- Assert.assertEquals(codegen.toVarName("$name"), "$name");
- Assert.assertEquals(codegen.toVarName("nam$$e"), "nam$$e");
- Assert.assertEquals(codegen.toVarName("user-name"), "userName");
- Assert.assertEquals(codegen.toVarName("user_name"), "userName");
- Assert.assertEquals(codegen.toVarName("user|name"), "userName");
- Assert.assertEquals(codegen.toVarName("user !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~name"), "user$Name");
- }
+ TypeScriptNodeClientCodegen codegen = new TypeScriptNodeClientCodegen();
+ Assert.assertEquals(codegen.toVarName("name"), "name");
+ Assert.assertEquals(codegen.toVarName("$name"), "$name");
+ Assert.assertEquals(codegen.toVarName("nam$$e"), "nam$$e");
+ Assert.assertEquals(codegen.toVarName("user-name"), "userName");
+ Assert.assertEquals(codegen.toVarName("user_name"), "userName");
+ Assert.assertEquals(codegen.toVarName("user|name"), "userName");
+ Assert.assertEquals(codegen.toVarName("user !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~name"), "user$Name");
+ }
- @Test
- public void testSnapshotVersion() {
- OpenAPI api = TestUtils.createOpenAPI();
- TypeScriptNodeClientCodegen codegen = new TypeScriptNodeClientCodegen();
+ @Test
+ public void testSnapshotVersion() {
+ OpenAPI api = TestUtils.createOpenAPI();
+ TypeScriptNodeClientCodegen codegen = new TypeScriptNodeClientCodegen();
- codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
- codegen.additionalProperties().put("snapshot", true);
- codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
- codegen.processOpts();
- codegen.preprocessOpenAPI(api);
+ codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
+ codegen.additionalProperties().put("snapshot", true);
+ codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
+ codegen.processOpts();
+ codegen.preprocessOpenAPI(api);
- Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT.[0-9]{12}$"));
+ Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT.[0-9]{12}$"));
- codegen = new TypeScriptNodeClientCodegen();
- codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
- codegen.additionalProperties().put("snapshot", true);
- codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
- codegen.processOpts();
- codegen.preprocessOpenAPI(api);
+ codegen = new TypeScriptNodeClientCodegen();
+ codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
+ codegen.additionalProperties().put("snapshot", true);
+ codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
+ codegen.processOpts();
+ codegen.preprocessOpenAPI(api);
- Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1-SNAPSHOT.[0-9]{12}$"));
+ Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1-SNAPSHOT.[0-9]{12}$"));
+ }
- }
+ @Test
+ public void testWithoutSnapshotVersion() {
+ OpenAPI api = TestUtils.createOpenAPI();
+ TypeScriptNodeClientCodegen codegen = new TypeScriptNodeClientCodegen();
- @Test
- public void testWithoutSnapshotVersion() {
- OpenAPI api = TestUtils.createOpenAPI();
- TypeScriptNodeClientCodegen codegen = new TypeScriptNodeClientCodegen();
+ codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
+ codegen.additionalProperties().put("snapshot", false);
+ codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
+ codegen.processOpts();
+ codegen.preprocessOpenAPI(api);
- codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
- codegen.additionalProperties().put("snapshot", false);
- codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
- codegen.processOpts();
- codegen.preprocessOpenAPI(api);
+ Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT$"));
- Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT$"));
+ codegen = new TypeScriptNodeClientCodegen();
+ codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
+ codegen.additionalProperties().put("snapshot", false);
+ codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
+ codegen.processOpts();
+ codegen.preprocessOpenAPI(api);
- codegen = new TypeScriptNodeClientCodegen();
- codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
- codegen.additionalProperties().put("snapshot", false);
- codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
- codegen.processOpts();
- codegen.preprocessOpenAPI(api);
+ Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1$"));
+ }
- Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1$"));
+ @Test(description = "prepend model filename with ./ by default")
+ public void defaultModelFilenameTest() {
+ Assert.assertEquals(codegen.toModelFilename("ApiResponse"), "./apiResponse");
+ }
- }
+ @Test(description = "use mapped name for model filename when provided")
+ public void modelFilenameWithMappingTest() {
+ final String mappedName = "@namespace/dir/response";
+ codegen.importMapping().put("ApiResponse", mappedName);
+
+ Assert.assertEquals(codegen.toModelFilename("ApiResponse"), mappedName);
+ }
+
+ @Test(description = "prepend model import with ./ by default")
+ public void defaultModelImportTest() {
+ Assert.assertEquals(codegen.toModelImport("ApiResponse"), "model/apiResponse");
+ }
+
+ @Test(description = "use mapped name for model import when provided")
+ public void modelImportWithMappingTest() {
+ final String mappedName = "@namespace/dir/response";
+ codegen.importMapping().put("ApiResponse", mappedName);
+
+ Assert.assertEquals(codegen.toModelImport("ApiResponse"), mappedName);
+ }
+
+ @Test(description = "append api suffix to default api filename")
+ public void emptyApiFilenameTest() {
+ Assert.assertEquals(codegen.toApiFilename(""), "defaultApi");
+ }
+
+ @Test(description = "appends api suffix to api filename")
+ public void defaultApiFilenameTest() {
+ Assert.assertEquals(codegen.toApiFilename("Category"), "categoryApi");
+ }
+
+ @Test(description = "appends api suffix to mapped api filename")
+ public void mappedApiFilenameTest() {
+ final String mappedName = "@namespace/dir/category";
+ codegen.importMapping().put("Category", mappedName);
+ Assert.assertEquals(codegen.toApiFilename("Category"), mappedName);
+ }
+
+ @Test(description = "append api suffix to default api import")
+ public void emptyApiImportTest() {
+ Assert.assertEquals(codegen.toApiImport(""), "api/defaultApi");
+ }
+
+ @Test(description = "appends api suffix to api import")
+ public void defaultApiImportTest() {
+ Assert.assertEquals(codegen.toApiImport("Category"), "api/categoryApi");
+ }
+
+ @Test(description = "appends api suffix to mapped api filename")
+ public void mappedApiImportTest() {
+ final String mappedName = "@namespace/dir/category";
+ codegen.importMapping().put("Category", mappedName);
+ Assert.assertEquals(codegen.toApiImport("Category"), mappedName);
+ }
}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java
index 0f6a8a9647a..d3a11b970c0 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptnode/TypeScriptNodeModelTest.java
@@ -205,4 +205,30 @@ public class TypeScriptNodeModelTest {
Assert.assertEquals(cm.imports.size(), 1);
Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
}
+
+ @Test(description = "prepend imports with ./ by default")
+ public void defaultFromModelTest() {
+ final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
+ final DefaultCodegen codegen = new TypeScriptNodeClientCodegen();
+ codegen.setOpenAPI(openAPI);
+ final Schema categorySchema = openAPI.getComponents().getSchemas().get("ApiResponse");
+ final CodegenModel cm = codegen.fromModel("ApiResponse", categorySchema);
+
+ Assert.assertEquals(cm.name, "ApiResponse");
+ Assert.assertEquals(cm.classFilename, "./apiResponse");
+ }
+
+ @Test(description = "use mapped imports for type")
+ public void mappedFromModelTest() {
+ final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
+ final DefaultCodegen codegen = new TypeScriptNodeClientCodegen();
+ final String mappedName = "@namespace/dir/response";
+ codegen.importMapping().put("ApiResponse", mappedName);
+ codegen.setOpenAPI(openAPI);
+ final Schema categorySchema = openAPI.getComponents().getSchemas().get("ApiResponse");
+ final CodegenModel cm = codegen.fromModel("ApiResponse", categorySchema);
+
+ Assert.assertEquals(cm.name, "ApiResponse");
+ Assert.assertEquals(cm.classFilename, mappedName);
+ }
}
diff --git a/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml b/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
index ed907f27854..d424cd93e96 100644
--- a/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
+++ b/modules/openapi-generator/src/test/resources/2_0/python-client-experimental/petstore-with-fake-endpoints-models-for-testing.yaml
@@ -1041,6 +1041,50 @@ paths:
responses:
'200':
description: Success
+ /fake/enums-of-length-one/{path_string}/{path_integer}:
+ put:
+ tags:
+ - fake
+ description: 'This route has required values with enums of 1'
+ operationId: testEndpointEnumsLengthOne
+ parameters:
+ - in: query
+ name: query_integer
+ required: true
+ type: integer
+ format: int32
+ enum:
+ - 3
+ - in: query
+ name: query_string
+ required: true
+ type: string
+ enum:
+ - brillig
+ - in: path
+ name: path_string
+ required: true
+ type: string
+ enum:
+ - hello
+ - in: path
+ name: path_integer
+ required: true
+ type: integer
+ enum:
+ - 34
+ - in: header
+ name: header_number
+ required: true
+ type: number
+ format: double
+ enum:
+ - 1.234
+ consumes:
+ - application/json
+ responses:
+ '200':
+ description: Success
'/fake/{petId}/uploadImageWithRequiredFile':
post:
tags:
@@ -1703,6 +1747,7 @@ definitions:
type: string
TypeHolderDefault:
type: object
+ description: a model to test optional properties with server defaults
required:
- string_item
- number_item
@@ -1716,12 +1761,25 @@ definitions:
number_item:
type: number
default: 1.234
+ format: double
integer_item:
type: integer
+ format: int32
default: -2
bool_item:
type: boolean
default: true
+ # swagger-parser does not see date defaults yet: https://github.com/swagger-api/swagger-parser/issues/971
+ date_item:
+ type: string
+ format: date
+ default: 2017-07-21
+ # swagger-parser does not see date-time defaults yet: https://github.com/swagger-api/swagger-parser/issues/971
+ datetime_item:
+ type: string
+ format: date-time
+ default: 2017-07-21T17:32:28Z
+ # swagger-parser does not see array defaults yet: https://github.com/swagger-api/swagger-parser/issues/971
array_item:
type: array
items:
@@ -1733,22 +1791,30 @@ definitions:
- 3
TypeHolderExample:
type: object
+ description: a model to test required properties with an example and length one enum
required:
- string_item
- number_item
- integer_item
- bool_item
- array_item
+ # - date_item/datetime_item adding date and datetime enums will be a future task, this does not yet work in many languages
properties:
string_item:
type: string
example: what
+ enum: [what]
number_item:
type: number
+ format: double
example: 1.234
+ enum: [1.234]
integer_item:
type: integer
+ format: int32
+ enum: [-2]
example: -2
+ # swagger-parser does not see bool enums yet https://github.com/swagger-api/swagger-parser/issues/985
bool_item:
type: boolean
example: true
@@ -1757,10 +1823,17 @@ definitions:
items:
type: integer
example:
- - 0
- - 1
- - 2
- - 3
+ -
+ - 0
+ - 1
+ - 2
+ - 3
+ enum:
+ -
+ - 0
+ - 1
+ - 2
+ - 3
XmlItem:
type: object
xml:
@@ -1939,4 +2012,4 @@ definitions:
type: integer
xml:
namespace: http://g.com/schema
- prefix: g
+ prefix: g
\ No newline at end of file
diff --git a/modules/openapi-generator/src/test/resources/3_0/allOf-required-parent.yaml b/modules/openapi-generator/src/test/resources/3_0/allOf-required-parent.yaml
new file mode 100644
index 00000000000..d6a24e2aef7
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/allOf-required-parent.yaml
@@ -0,0 +1,75 @@
+openapi: 3.0.1
+info:
+ version: 1.0.0
+ title: Example
+ license:
+ name: MIT
+servers:
+ - url: http://api.example.xyz/v1
+paths:
+ /person/display/{personId}:
+ get:
+ parameters:
+ - name: personId
+ in: path
+ required: true
+ description: The id of the person to retrieve
+ schema:
+ type: string
+ operationId: list
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/person"
+components:
+ schemas:
+ person:
+ allOf:
+ - $ref: '#/components/schemas/personForCreation'
+ - properties:
+ id:
+ type: integer
+ format: int32
+ required:
+ - id
+
+ personForCreation:
+ allOf:
+ - $ref: '#/components/schemas/personForUpdate'
+ required:
+ - firstName
+ - name
+ - email
+
+ personForUpdate:
+ properties:
+ firstName:
+ type: string
+ maxLength: 255
+ name:
+ type: string
+ maxLength: 255
+ birthDate:
+ type: string
+ format: date
+ address:
+ type: string
+ maxLength: 255
+ postalCode:
+ type: string
+ maxLength: 255
+ city:
+ type: string
+ maxLength: 255
+ phoneNumber:
+ type: string
+ pattern: ^((\+)33|0)[1-9](\d{2}){4}$
+ email:
+ type: string
+ format: email
+ nationality:
+ type: string
+ maxLength: 255
\ No newline at end of file
diff --git a/modules/openapi-generator/src/test/resources/3_0/allOf-required.yaml b/modules/openapi-generator/src/test/resources/3_0/allOf-required.yaml
new file mode 100644
index 00000000000..adf10632952
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/allOf-required.yaml
@@ -0,0 +1,42 @@
+openapi: 3.0.1
+info:
+ version: 1.0.0
+ title: Example
+ license:
+ name: MIT
+servers:
+ - url: http://api.example.xyz/v1
+paths:
+ /person/display/{personId}:
+ get:
+ parameters:
+ - name: personId
+ in: path
+ required: true
+ description: The id of the person to retrieve
+ schema:
+ type: string
+ operationId: list
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/clubForCreation"
+components:
+ schemas:
+ clubForCreation:
+ allOf:
+ - $ref: '#/components/schemas/clubForUpdate'
+ required:
+ - name
+
+ clubForUpdate:
+ properties:
+ name:
+ type: string
+ maxLength: 255
+ shortName:
+ type: string
+ maxLength: 255
\ No newline at end of file
diff --git a/modules/openapi-generator/src/test/resources/3_0/petstore-with-complex-headers.yaml b/modules/openapi-generator/src/test/resources/3_0/petstore-with-complex-headers.yaml
new file mode 100644
index 00000000000..adee68bcd0b
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/petstore-with-complex-headers.yaml
@@ -0,0 +1,710 @@
+openapi: 3.0.0
+servers:
+ - url: 'http://petstore.swagger.io/v2'
+info:
+ description: >-
+ This is a sample server Petstore server. For this sample, you can use the api key
+ `special-key` to test the authorization filters.
+ version: 1.0.0
+ title: OpenAPI Petstore
+ license:
+ name: Apache-2.0
+ url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
+tags:
+ - name: pet
+ description: Everything about your Pets
+ - name: store
+ description: Access to Petstore orders
+ - name: user
+ description: Operations about user
+paths:
+ /pet:
+ post:
+ tags:
+ - pet
+ summary: Add a new pet to the store
+ description: ''
+ operationId: addPet
+ responses:
+ '405':
+ description: Invalid input
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ parameters:
+ - name: header1
+ in: header
+ schema:
+ $ref: '#/components/requestBodies/Pet'
+ - name: header2
+ in: header
+ schema:
+ type: array
+ items:
+ $ref: '#/components/requestBodies/Pet'
+ requestBody:
+ $ref: '#/components/requestBodies/Pet'
+ put:
+ tags:
+ - pet
+ summary: Update an existing pet
+ description: ''
+ operationId: updatePet
+ responses:
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Pet not found
+ '405':
+ description: Validation exception
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ $ref: '#/components/requestBodies/Pet'
+ /pet/findByStatus:
+ get:
+ tags:
+ - pet
+ summary: Finds Pets by status
+ description: Multiple status values can be provided with comma separated strings
+ operationId: findPetsByStatus
+ parameters:
+ - name: status
+ in: query
+ description: Status values that need to be considered for filter
+ required: true
+ style: form
+ explode: false
+ schema:
+ type: array
+ items:
+ type: string
+ enum:
+ - available
+ - pending
+ - sold
+ default: available
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid status value
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ /pet/findByTags:
+ get:
+ tags:
+ - pet
+ summary: Finds Pets by tags
+ description: >-
+ Multiple tags can be provided with comma separated strings. Use tag1,
+ tag2, tag3 for testing.
+ operationId: findPetsByTags
+ parameters:
+ - name: tags
+ in: query
+ description: Tags to filter by
+ required: true
+ style: form
+ explode: false
+ schema:
+ type: array
+ items:
+ type: string
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid tag value
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ deprecated: true
+ '/pet/{petId}':
+ get:
+ tags:
+ - pet
+ summary: Find pet by ID
+ description: Returns a single pet
+ operationId: getPetById
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet to return
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Pet not found
+ security:
+ - api_key: []
+ post:
+ tags:
+ - pet
+ summary: Updates a pet in the store with form data
+ description: ''
+ operationId: updatePetWithForm
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet that needs to be updated
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '405':
+ description: Invalid input
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ type: object
+ properties:
+ name:
+ description: Updated name of the pet
+ type: string
+ status:
+ description: Updated status of the pet
+ type: string
+ delete:
+ tags:
+ - pet
+ summary: Deletes a pet
+ description: ''
+ operationId: deletePet
+ parameters:
+ - name: api_key
+ in: header
+ required: false
+ schema:
+ type: string
+ - name: petId
+ in: path
+ description: Pet id to delete
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '400':
+ description: Invalid pet value
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ '/pet/{petId}/uploadImage':
+ post:
+ tags:
+ - pet
+ summary: uploads an image
+ description: ''
+ operationId: uploadFile
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet to update
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApiResponse'
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ additionalMetadata:
+ description: Additional data to pass to server
+ type: string
+ file:
+ description: file to upload
+ type: string
+ format: binary
+ /store/inventory:
+ get:
+ tags:
+ - store
+ summary: Returns pet inventories by status
+ description: Returns a map of status codes to quantities
+ operationId: getInventory
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ type: object
+ additionalProperties:
+ type: integer
+ format: int32
+ security:
+ - api_key: []
+ /store/order:
+ post:
+ tags:
+ - store
+ summary: Place an order for a pet
+ description: ''
+ operationId: placeOrder
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Order'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Order'
+ '400':
+ description: Invalid Order
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Order'
+ description: order placed for purchasing the pet
+ required: true
+ '/store/order/{orderId}':
+ get:
+ tags:
+ - store
+ summary: Find purchase order by ID
+ description: >-
+ For valid response try integer IDs with value <= 5 or > 10. Other values
+ will generated exceptions
+ operationId: getOrderById
+ parameters:
+ - name: orderId
+ in: path
+ description: ID of pet that needs to be fetched
+ required: true
+ schema:
+ type: integer
+ format: int64
+ minimum: 1
+ maximum: 5
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Order'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Order'
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Order not found
+ delete:
+ tags:
+ - store
+ summary: Delete purchase order by ID
+ description: >-
+ For valid response try integer IDs with value < 1000. Anything above
+ 1000 or nonintegers will generate API errors
+ operationId: deleteOrder
+ parameters:
+ - name: orderId
+ in: path
+ description: ID of the order that needs to be deleted
+ required: true
+ schema:
+ type: string
+ responses:
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Order not found
+ /user:
+ post:
+ tags:
+ - user
+ summary: Create user
+ description: This can only be done by the logged in user.
+ operationId: createUser
+ responses:
+ default:
+ description: successful operation
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ description: Created user object
+ required: true
+ /user/createWithArray:
+ post:
+ tags:
+ - user
+ summary: Creates list of users with given input array
+ description: ''
+ operationId: createUsersWithArrayInput
+ responses:
+ default:
+ description: successful operation
+ requestBody:
+ $ref: '#/components/requestBodies/UserArray'
+ /user/createWithList:
+ post:
+ tags:
+ - user
+ summary: Creates list of users with given input array
+ description: ''
+ operationId: createUsersWithListInput
+ responses:
+ default:
+ description: successful operation
+ requestBody:
+ $ref: '#/components/requestBodies/UserArray'
+ /user/login:
+ get:
+ tags:
+ - user
+ summary: Logs user into the system
+ description: ''
+ operationId: loginUser
+ parameters:
+ - name: username
+ in: query
+ description: The user name for login
+ required: true
+ schema:
+ type: string
+ - name: password
+ in: query
+ description: The password for login in clear text
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: successful operation
+ headers:
+ X-Rate-Limit:
+ description: calls per hour allowed by the user
+ schema:
+ type: integer
+ format: int32
+ X-Expires-After:
+ description: date in UTC when toekn expires
+ schema:
+ type: string
+ format: date-time
+ content:
+ application/xml:
+ schema:
+ type: string
+ application/json:
+ schema:
+ type: string
+ '400':
+ description: Invalid username/password supplied
+ /user/logout:
+ get:
+ tags:
+ - user
+ summary: Logs out current logged in user session
+ description: ''
+ operationId: logoutUser
+ responses:
+ default:
+ description: successful operation
+ '/user/{username}':
+ get:
+ tags:
+ - user
+ summary: Get user by user name
+ description: ''
+ operationId: getUserByName
+ parameters:
+ - name: username
+ in: path
+ description: The name that needs to be fetched. Use user1 for testing.
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/User'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ '400':
+ description: Invalid username supplied
+ '404':
+ description: User not found
+ put:
+ tags:
+ - user
+ summary: Updated user
+ description: This can only be done by the logged in user.
+ operationId: updateUser
+ parameters:
+ - name: username
+ in: path
+ description: name that need to be deleted
+ required: true
+ schema:
+ type: string
+ responses:
+ '400':
+ description: Invalid user supplied
+ '404':
+ description: User not found
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ description: Updated user object
+ required: true
+ delete:
+ tags:
+ - user
+ summary: Delete user
+ description: This can only be done by the logged in user.
+ operationId: deleteUser
+ parameters:
+ - name: username
+ in: path
+ description: The name that needs to be deleted
+ required: true
+ schema:
+ type: string
+ responses:
+ '400':
+ description: Invalid username supplied
+ '404':
+ description: User not found
+externalDocs:
+ description: Find out more about Swagger
+ url: 'http://swagger.io'
+components:
+ requestBodies:
+ UserArray:
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ description: List of user object
+ required: true
+ Pet:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ description: Pet object that needs to be added to the store
+ required: true
+ securitySchemes:
+ petstore_auth:
+ type: oauth2
+ flows:
+ implicit:
+ authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
+ scopes:
+ 'write:pets': modify pets in your account
+ 'read:pets': read your pets
+ api_key:
+ type: apiKey
+ name: api_key
+ in: header
+ schemas:
+ Order:
+ title: Pet Order
+ description: An order for a pets from the pet store
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ petId:
+ type: integer
+ format: int64
+ quantity:
+ type: integer
+ format: int32
+ shipDate:
+ type: string
+ format: date-time
+ status:
+ type: string
+ description: Order Status
+ enum:
+ - placed
+ - approved
+ - delivered
+ complete:
+ type: boolean
+ default: false
+ xml:
+ name: Order
+ Category:
+ title: Pet category
+ description: A category for a pet
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ xml:
+ name: Category
+ User:
+ title: a User
+ description: A User who is purchasing from the pet store
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ username:
+ type: string
+ firstName:
+ type: string
+ lastName:
+ type: string
+ email:
+ type: string
+ password:
+ type: string
+ phone:
+ type: string
+ userStatus:
+ type: integer
+ format: int32
+ description: User Status
+ xml:
+ name: User
+ Tag:
+ title: Pet Tag
+ description: A tag for a pet
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ xml:
+ name: Tag
+ Pet:
+ title: a Pet
+ description: A pet for sale in the pet store
+ type: object
+ required:
+ - name
+ - photoUrls
+ properties:
+ id:
+ type: integer
+ format: int64
+ category:
+ $ref: '#/components/schemas/Category'
+ name:
+ type: string
+ example: doggie
+ photoUrls:
+ type: array
+ xml:
+ name: photoUrl
+ wrapped: true
+ items:
+ type: string
+ tags:
+ type: array
+ xml:
+ name: tag
+ wrapped: true
+ items:
+ $ref: '#/components/schemas/Tag'
+ status:
+ type: string
+ description: pet status in the store
+ enum:
+ - available
+ - pending
+ - sold
+ xml:
+ name: Pet
+ ApiResponse:
+ title: An uploaded response
+ description: Describes the result of uploading an image resource
+ type: object
+ properties:
+ code:
+ type: integer
+ format: int32
+ type:
+ type: string
+ message:
+ type: string
diff --git a/modules/openapi-generator/src/test/resources/3_0/petstore.yaml b/modules/openapi-generator/src/test/resources/3_0/petstore.yaml
index 5cddb68050e..c424e27cd39 100644
--- a/modules/openapi-generator/src/test/resources/3_0/petstore.yaml
+++ b/modules/openapi-generator/src/test/resources/3_0/petstore.yaml
@@ -115,13 +115,6 @@ paths:
type: array
items:
type: string
- - name: maxCount
- in: query
- description: Maximum number of items to return
- required: false
- schema:
- type: integer
- format: int32
responses:
'200':
description: successful operation
diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/multipart-v3.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/multipart-v3.yaml
new file mode 100644
index 00000000000..70c4e5d4602
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/multipart-v3.yaml
@@ -0,0 +1,51 @@
+# Test the multipart function of the OpenAPI specification
+#
+# Specifically, these tests include
+# - multipart/form data including
+# - binary data
+# - string data
+# - objects
+
+openapi: 3.0.1
+info:
+ title: Multipart OpenAPI V3 Rust Server Test
+ description: API under test
+ version: 1.0.7
+paths:
+ /multipart_request:
+ post:
+ requestBody:
+ required: true
+ content:
+ multipart/form-data:
+ schema:
+ $ref: '#/components/schemas/multipart_request'
+ responses:
+ '201':
+ description: 'OK'
+components:
+ schemas:
+ multipart_request:
+ type: object
+ required:
+ - string_field
+ - binary_field
+ properties:
+ string_field:
+ type: string
+ optional_string_field:
+ type: string
+ object_field:
+ type: object
+ required:
+ - field_a
+ properties:
+ field_a:
+ type: string
+ field_b:
+ type: array
+ items:
+ type: string
+ binary_field:
+ type: string
+ format: byte
diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml
index 677a439f041..cef3e746ba0 100644
--- a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml
+++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml
@@ -1,5 +1,7 @@
-# Test the mainline function of the XML part of the OpenAPI specification,
-# as found here : https://swagger.io/docs/specification/data-models/representing-xml/
+# Test the mainline function of OpenAPI v3 specification.
+#
+# This includes the XML part of the OpenAPI specification, as found at
+# https://swagger.io/docs/specification/data-models/representing-xml/
#
# Specifically, these tests are intended to include:
# - namespaces
@@ -9,6 +11,8 @@
# - wrapping and renaming to and from camelCase and snake_case
# - objects
# - renaming to and from camelCase and snake_case
+# - UUIDs
+# - Octet Streams
openapi: 3.0.1
info:
@@ -76,6 +80,15 @@ paths:
description: 'OK'
'400':
description: Bad Request
+ /uuid:
+ get:
+ responses:
+ 200:
+ description: Duplicate Response long text. One.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UuidObject"
/required_octet_stream:
put:
requestBody:
diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/ops-v3.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/ops-v3.yaml
new file mode 100644
index 00000000000..bd2addb34e9
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/ops-v3.yaml
@@ -0,0 +1,192 @@
+# Test large number of configured operations
+
+openapi: 3.0.1
+info:
+ title: Regression test for large number of operations
+ version: 0.0.1
+paths:
+ /op1:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op2:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op3:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op4:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op5:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op6:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op7:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op8:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op9:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op10:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op11:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op12:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op13:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op14:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op15:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op16:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op17:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op18:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op19:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op20:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op21:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op22:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op23:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op24:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op25:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op26:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op27:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op28:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op29:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op30:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op31:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op32:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op33:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op34:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op35:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op36:
+ get:
+ responses:
+ '200':
+ description: 'OK'
+ /op37:
+ get:
+ responses:
+ '200':
+ description: 'OK'
diff --git a/pom.xml b/pom.xml
index 7cb07df2f11..21e3c4b0b65 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1024,6 +1024,7 @@
samples/client/petstore/c
+ samples/client/petstore/cpp-qt5
diff --git a/samples/client/petstore/bash/.openapi-generator/VERSION b/samples/client/petstore/bash/.openapi-generator/VERSION
index 096bf47efe3..83a328a9227 100644
--- a/samples/client/petstore/bash/.openapi-generator/VERSION
+++ b/samples/client/petstore/bash/.openapi-generator/VERSION
@@ -1 +1 @@
-3.0.0-SNAPSHOT
\ No newline at end of file
+4.1.0-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/bash/README.md b/samples/client/petstore/bash/README.md
index a543b69de1b..9e6a8c0dac3 100644
--- a/samples/client/petstore/bash/README.md
+++ b/samples/client/petstore/bash/README.md
@@ -1,6 +1,7 @@
# OpenAPI Petstore Bash client
## Overview
+
This is a Bash client script for accessing OpenAPI Petstore service.
The script uses cURL underneath for making all REST calls.
@@ -43,6 +44,7 @@ $ petstore-cli --host http://: --dry-run
```
## Docker image
+
You can easily create a Docker image containing a preconfigured environment
for using the REST Bash client including working autocompletion and short
welcome message with basic instructions, using the generated Dockerfile:
@@ -59,6 +61,7 @@ is also available.
## Shell completion
### Bash
+
The generated bash-completion script can be either directly loaded to the current Bash session using:
```shell
@@ -72,10 +75,13 @@ sudo cp petstore-cli.bash-completion /etc/bash-completion.d/petstore-cli
```
#### OS X
+
On OSX you might need to install bash-completion using Homebrew:
+
```shell
brew install bash-completion
```
+
and add the following to the `~/.bashrc`:
```shell
@@ -85,8 +91,8 @@ fi
```
### Zsh
-In Zsh, the generated `_petstore-cli` Zsh completion file must be copied to one of the folders under `$FPATH` variable.
+In Zsh, the generated `_petstore-cli` Zsh completion file must be copied to one of the folders under `$FPATH` variable.
## Documentation for API Endpoints
@@ -94,11 +100,13 @@ All URIs are relative to */v2*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
-*AnotherFakeApi* | [**testSpecialTags**](docs/AnotherFakeApi.md#testspecialtags) | **PATCH** /another-fake/dummy | To test special tags
+*AnotherFakeApi* | [**123Test@$%SpecialTags**](docs/AnotherFakeApi.md#123test@$%specialtags) | **PATCH** /another-fake/dummy | To test special tags
+*FakeApi* | [**createXmlItem**](docs/FakeApi.md#createxmlitem) | **POST** /fake/create_xml_item | creates an XmlItem
*FakeApi* | [**fakeOuterBooleanSerialize**](docs/FakeApi.md#fakeouterbooleanserialize) | **POST** /fake/outer/boolean |
*FakeApi* | [**fakeOuterCompositeSerialize**](docs/FakeApi.md#fakeoutercompositeserialize) | **POST** /fake/outer/composite |
*FakeApi* | [**fakeOuterNumberSerialize**](docs/FakeApi.md#fakeouternumberserialize) | **POST** /fake/outer/number |
*FakeApi* | [**fakeOuterStringSerialize**](docs/FakeApi.md#fakeouterstringserialize) | **POST** /fake/outer/string |
+*FakeApi* | [**testBodyWithFileSchema**](docs/FakeApi.md#testbodywithfileschema) | **PUT** /fake/body-with-file-schema |
*FakeApi* | [**testBodyWithQueryParams**](docs/FakeApi.md#testbodywithqueryparams) | **PUT** /fake/body-with-query-params |
*FakeApi* | [**testClientModel**](docs/FakeApi.md#testclientmodel) | **PATCH** /fake | To test \"client\" model
*FakeApi* | [**testEndpointParameters**](docs/FakeApi.md#testendpointparameters) | **POST** /fake | Fake endpoint for testing various parameters
@@ -106,6 +114,7 @@ Class | Method | HTTP request | Description
偽のエンドポイント
가짜 엔드 포인트
*FakeApi* | [**testEnumParameters**](docs/FakeApi.md#testenumparameters) | **GET** /fake | To test enum parameters
+*FakeApi* | [**testGroupParameters**](docs/FakeApi.md#testgroupparameters) | **DELETE** /fake | Fake endpoint to test group parameters (optional)
*FakeApi* | [**testInlineAdditionalProperties**](docs/FakeApi.md#testinlineadditionalproperties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties
*FakeApi* | [**testJsonFormData**](docs/FakeApi.md#testjsonformdata) | **GET** /fake/jsonFormData | test json serialization of form data
*FakeClassnameTags123Api* | [**testClassname**](docs/FakeClassnameTags123Api.md#testclassname) | **PATCH** /fake_classname_test | To test class name in snake case
@@ -117,6 +126,7 @@ Class | Method | HTTP request | Description
*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet
*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data
*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image
+*PetApi* | [**uploadFileWithRequiredFile**](docs/PetApi.md#uploadfilewithrequiredfile) | **POST** /fake/{petId}/uploadImageWithRequiredFile | uploads an image (required)
*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{order_id} | Delete purchase order by ID
*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status
*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{order_id} | Find purchase order by ID
@@ -133,25 +143,34 @@ Class | Method | HTTP request | Description
## Documentation For Models
- - [$special[model.name]](docs/$special[model.name].md)
- - [200_response](docs/200_response.md)
+ - [$special[modelName]](docs/$special[modelName].md)
+ - [200Response](docs/200Response.md)
+ - [AdditionalPropertiesAnyType](docs/AdditionalPropertiesAnyType.md)
+ - [AdditionalPropertiesArray](docs/AdditionalPropertiesArray.md)
+ - [AdditionalPropertiesBoolean](docs/AdditionalPropertiesBoolean.md)
- [AdditionalPropertiesClass](docs/AdditionalPropertiesClass.md)
+ - [AdditionalPropertiesInteger](docs/AdditionalPropertiesInteger.md)
+ - [AdditionalPropertiesNumber](docs/AdditionalPropertiesNumber.md)
+ - [AdditionalPropertiesObject](docs/AdditionalPropertiesObject.md)
+ - [AdditionalPropertiesString](docs/AdditionalPropertiesString.md)
- [Animal](docs/Animal.md)
- - [AnimalFarm](docs/AnimalFarm.md)
- [ApiResponse](docs/ApiResponse.md)
- [ArrayOfArrayOfNumberOnly](docs/ArrayOfArrayOfNumberOnly.md)
- [ArrayOfNumberOnly](docs/ArrayOfNumberOnly.md)
- [ArrayTest](docs/ArrayTest.md)
- [Capitalization](docs/Capitalization.md)
- [Cat](docs/Cat.md)
+ - [CatAllOf](docs/CatAllOf.md)
- [Category](docs/Category.md)
- [ClassModel](docs/ClassModel.md)
- [Client](docs/Client.md)
- [Dog](docs/Dog.md)
+ - [DogAllOf](docs/DogAllOf.md)
- [EnumArrays](docs/EnumArrays.md)
- [EnumClass](docs/EnumClass.md)
- - [Enum_Test](docs/Enum_Test.md)
- - [Format_test](docs/Format_test.md)
+ - [EnumTest](docs/EnumTest.md)
+ - [FileSchemaTestClass](docs/FileSchemaTestClass.md)
+ - [FormatTest](docs/FormatTest.md)
- [HasOnlyReadOnly](docs/HasOnlyReadOnly.md)
- [MapTest](docs/MapTest.md)
- [MixedPropertiesAndAdditionalPropertiesClass](docs/MixedPropertiesAndAdditionalPropertiesClass.md)
@@ -164,7 +183,10 @@ Class | Method | HTTP request | Description
- [ReadOnlyFirst](docs/ReadOnlyFirst.md)
- [Return](docs/Return.md)
- [Tag](docs/Tag.md)
+ - [TypeHolderDefault](docs/TypeHolderDefault.md)
+ - [TypeHolderExample](docs/TypeHolderExample.md)
- [User](docs/User.md)
+ - [XmlItem](docs/XmlItem.md)
## Documentation For Authorization
@@ -172,12 +194,14 @@ Class | Method | HTTP request | Description
## api_key
+
- **Type**: API key
- **API key parameter name**: api_key
- **Location**: HTTP header
## api_key_query
+
- **Type**: API key
- **API key parameter name**: api_key_query
- **Location**: URL query string
@@ -188,6 +212,7 @@ Class | Method | HTTP request | Description
## petstore_auth
+
- **Type**: OAuth
- **Flow**: implicit
- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
diff --git a/samples/client/petstore/bash/_client.sh b/samples/client/petstore/bash/_client.sh
new file mode 100644
index 00000000000..8be68229c3d
--- /dev/null
+++ b/samples/client/petstore/bash/_client.sh
@@ -0,0 +1,594 @@
+#compdef
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# !
+# ! Note:
+# !
+# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
+# ! openapi-generator (https://openapi-generator.tech)
+# ! FROM OPENAPI SPECIFICATION IN JSON.
+# !
+# ! Based on: https://github.com/Valodim/zsh-curl-completion/blob/master/_curl
+# !
+# !
+# !
+# ! Installation:
+# !
+# ! Copy the _ file to any directory under FPATH
+# ! environment variable (echo $FPATH)
+# !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+local curcontext="$curcontext" state line ret=1
+typeset -A opt_args
+
+typeset -A mime_type_abbreviations
+# text/*
+mime_type_abbreviations[text]="text/plain"
+mime_type_abbreviations[html]="text/html"
+mime_type_abbreviations[md]="text/x-markdown"
+mime_type_abbreviations[csv]="text/csv"
+mime_type_abbreviations[css]="text/css"
+mime_type_abbreviations[rtf]="text/rtf"
+# application/*
+mime_type_abbreviations[json]="application/json"
+mime_type_abbreviations[xml]="application/xml"
+mime_type_abbreviations[yaml]="application/yaml"
+mime_type_abbreviations[js]="application/javascript"
+mime_type_abbreviations[bin]="application/octet-stream"
+mime_type_abbreviations[rdf]="application/rdf+xml"
+# image/*
+mime_type_abbreviations[jpg]="image/jpeg"
+mime_type_abbreviations[png]="image/png"
+mime_type_abbreviations[gif]="image/gif"
+mime_type_abbreviations[bmp]="image/bmp"
+mime_type_abbreviations[tiff]="image/tiff"
+
+#
+# Generate zsh completion string list for abbreviated mime types
+#
+get_mime_type_completions() {
+ typeset -a result
+ result=()
+ for k in "${(@k)mime_type_abbreviations}"; do
+ value=$mime_type_abbreviations[${k}]
+ #echo $value
+ result+=( "${k}[${value}]" )
+ #echo $result
+ done
+ echo "$result"
+}
+
+#
+# cURL crypto engines completion function
+#
+_curl_crypto_engine() {
+ local vals
+ vals=( ${${(f)"$(curl --engine list)":gs/ /}[2,$]} )
+ _describe -t outputs 'engines' vals && return 0
+}
+
+#
+# cURL post data completion functions=
+#
+_curl_post_data() {
+
+ # don't do anything further if this is raw content
+ compset -P '=' && _message 'raw content' && return 0
+
+ # complete filename or stdin for @ syntax
+ compset -P '*@' && {
+ local expl
+ _description files expl stdin
+ compadd "$expl[@]" - "-"
+ _files
+ return 0
+ }
+
+ # got a name already? expecting data.
+ compset -P '*=' && _message 'data value' && return 0
+
+ # otherwise, name (or @ or =) should be specified
+ _message 'data name' && return 0
+
+}
+
+
+local arg_http arg_ftp arg_other arg_proxy arg_crypto arg_connection arg_auth arg_input arg_output
+
+# HTTP Arguments
+arg_http=(''\
+ {-0,--http1.0}'[force use of use http 1.0 instead of 1.1]' \
+ {-b,--cookie}'[pass data to http server as cookie]:data or file' \
+ {-c,--cookie-jar}'[specify cookie file]:file name:_files' \
+ {-d,--data}'[send specified data as HTTP POST data]:data:{_curl_post_data}' \
+ '--data-binary[post HTTP POST data without any processing]:data:{_curl_post_data}' \
+ '--data-urlencode[post HTTP POST data, with url encoding]:data:{_curl_post_data}' \
+ {-f,--fail}'[enable failfast behavior for server errors]' \
+ '*'{-F,--form}'[add POST form data]:name=content' \
+ {-G,--get}'[use HTTP GET even with data (-d, --data, --data-binary)]' \
+ '*'{-H,--header}'[specify an extra header]:header' \
+ '--ignore-content-length[ignore Content-Length header]' \
+ {-i,--include}'[include HTTP header in the output]' \
+ {-j,--junk-session-cookies}'[discard all session cookies]' \
+ {-e,--referer}'[send url as referer]:referer url:_urls' \
+ {-L,--location}'[follow Location headers on http 3XX response]' \
+ '--location-trusted[like --location, but allows sending of auth data to redirected hosts]' \
+ '--max-redirs[set maximum number of redirection followings allowed]:number' \
+ {-J,--remote-header-name}'[use Content-Disposition for output file name]' \
+ {-O,--remote-name}'[write to filename parsed from url instead of stdout]' \
+ '--post301[do not convert POST to GET after following 301 Location response (follow RFC 2616/10.3.2)]' \
+ '--post302[do not convert POST to GET after following 302 Location response (follow RFC 2616/10.3.2)]' \
+ )
+
+# FTP arguments
+arg_ftp=(\
+ {-a,--append}'[append to target file instead of overwriting (FTP/SFTP)]' \
+ '--crlf[convert LF to CRLF in upload]' \
+ '--disable-eprt[disable use of EPRT and LPRT for active FTP transfers]' \
+ '--disable-epsv[disable use of EPSV for passive FTP transfers]' \
+ '--ftp-account[account data (FTP)]:data' \
+ '--ftp-alternative-to-user[command to send when USER and PASS commands fail (FTP)]:command' \
+ '--ftp-create-dirs[create paths remotely if it does not exist]' \
+ '--ftp-method[ftp method to use to reach a file (FTP)]:method:(multicwd ocwd singlecwd)' \
+ '--ftp-pasv[use passive mode for the data connection (FTP)]' \
+ '--ftp-skip-pasv-ip[do not use the ip the server suggests for PASV]' \
+ '--form-string[like --form, but do not parse content]:name=string' \
+ '--ftp-pret[send PRET before PASV]' \
+ '--ftp-ssl-ccc[use clear command channel (CCC) after authentication (FTP)]' \
+ '--ftp-ssl-ccc-mode[sets the CCC mode (FTP)]:mode:(active passive)' \
+ '--ftp-ssl-control[require SSL/TLS for FTP login, clear for transfer]' \
+ {-l,--list-only}'[list names only when listing directories (FTP)]' \
+ {-P,--ftp-port}'[use active mode, tell server to connect to specified address or interface (FTP]:address' \
+ '*'{-Q,--quote}'[send arbitrary command to the remote server before transfer (FTP/SFTP)]:command' \
+ )
+
+# Other Protocol arguments
+arg_other=(\
+ '--mail-from[specify From: address]:address' \
+ '--mail-rcpt[specify email recipient for SMTP, may be given multiple times]:address' \
+ {-t,--telnet-option}'[pass options to telnet protocol]:opt=val' \
+ '--tftp-blksize[set tftp BLKSIZE option]:value' \
+ )
+
+# Proxy arguments
+arg_proxy=(\
+ '--noproxy[list of hosts to connect directly to instead of through proxy]:no-proxy-list' \
+ {-p,--proxytunnel}'[tunnel non-http protocols through http proxy]' \
+ {-U,--proxy-user}'[specify the user name and password to use for proxy authentication]:user:password' \
+ '--proxy-anyauth[use any authentication method for proxy, default to most secure]' \
+ '--proxy-basic[use HTTP Basic authentication for proxy]' \
+ '--proxy-digest[use http digest authentication for proxy]' \
+ '--proxy-negotiate[enable GSS-Negotiate authentication for proxy]' \
+ '--proxy-ntlm[enable ntlm authentication for proxy]' \
+ '--proxy1.0[use http 1.0 proxy]:proxy url' \
+ {-x,--proxy}'[use specified proxy]:proxy url' \
+ '--socks5-gssapi-service[change service name for socks server]:servicename' \
+ '--socks5-gssapi-nec[allow unprotected exchange of protection mode negotiation]' \
+ )
+
+# Crypto arguments
+arg_crypto=(\
+ {-1,--tlsv1}'[Forces curl to use TLS version 1 when negotiating with a remote TLS server.]' \
+ {-2,--sslv2}'[Forces curl to use SSL version 2 when negotiating with a remote SSL server.]' \
+ {-3,--sslv3}'[Forces curl to use SSL version 3 when negotiating with a remote SSL server.]' \
+ '--ciphers[specifies which cipher to use for the ssl connection]:list of ciphers' \
+ '--crlfile[specify file with revoked certificates]:file' \
+ '--delegation[set delegation policy to use with GSS/kerberos]:delegation policy:(none policy always)' \
+ {-E,--cert}'[use specified client certificate]:certificate file:_files' \
+ '--engine[use selected OpenSSL crypto engine]:ssl crypto engine:{_curl_crypto_engine}' \
+ '--egd-file[set ssl entropy gathering daemon socket]:entropy socket:_files' \
+ '--cert-type[specify certificate type (PEM, DER, ENG)]:certificate type:(PEM DER ENG)' \
+ '--cacert[specify certificate file to verify the peer with]:CA certificate:_files' \
+ '--capath[specify a search path for certificate files]:CA certificate directory:_directories' \
+ '--hostpubmd5[check remote hosts public key]:md5 hash' \
+ {-k,--insecure}'[allow ssl to perform insecure ssl connections (ie, ignore certificate)]' \
+ '--key[ssl/ssh private key file name]:key file:_files' \
+ '--key-type[ssl/ssh private key file type]:file type:(PEM DER ENG)' \
+ '--pubkey[ssh public key file]:pubkey file:_files' \
+ '--random-file[set source of random data for ssl]:random source:_files' \
+ '--no-sessionid[disable caching of ssl session ids]' \
+ '--pass:phrase[passphrase for ssl/ssh private key]' \
+ '--ssl[try to use ssl/tls for connection, if available]' \
+ '--ssl-reqd[try to use ssl/tls for connection, fail if unavailable]' \
+ '--tlsauthtype[set TLS authentication type (only SRP supported!)]:authtype' \
+ '--tlsuser[set username for TLS authentication]:user' \
+ '--tlspassword[set password for TLS authentication]:password' \
+ )
+
+# Connection arguments
+arg_connection=(\
+ {-4,--ipv4}'[prefer ipv4]' \
+ {-6,--ipv6}'[prefer ipv6, if available]' \
+ {-B,--use-ascii}'[use ascii mode]' \
+ '--compressed[request a compressed transfer]' \
+ '--connect-timeout[timeout for connection phase]:seconds' \
+ {-I,--head}'[fetch http HEAD only (HTTP/FTP/FILE]' \
+ '--interface[work on a specific interface]:name' \
+ '--keepalive-time[set time to wait before sending keepalive probes]:seconds' \
+ '--limit-rate[specify maximum transfer rate]:speed' \
+ '--local-port[set preferred number or range of local ports to use]:num' \
+ {-N,--no-buffer}'[disable buffering of the output stream]' \
+ '--no-keepalive[disable use of keepalive messages in TCP connections]' \
+ '--raw[disable all http decoding and pass raw data]' \
+ '--resolve[provide a custom address for a specific host and port pair]:host\:port\:address' \
+ '--retry[specify maximum number of retries for transient errors]:num' \
+ '--retry-delay[specify delay between retries]:seconds' \
+ '--retry-max-time[maximum time to spend on retries]:seconds' \
+ '--tcp-nodelay[turn on TCP_NODELAY option]' \
+ {-y,--speed-time}'[specify time to abort after if download is slower than speed-limit]:time' \
+ {-Y,--speed-limit}'[specify minimum speed for --speed-time]:speed' \
+ )
+
+# Authentication arguments
+arg_auth=(\
+ '--anyauth[use any authentication method, default to most secure]' \
+ '--basic[use HTTP Basic authentication]' \
+ '--ntlm[enable ntlm authentication]' \
+ '--digest[use http digest authentication]' \
+ '--krb[use kerberos authentication]:auth:(clear safe confidential private)' \
+ '--negotiate[enable GSS-Negotiate authentication]' \
+ {-n,--netrc}'[scan ~/.netrc for login data]' \
+ '--netrc-optional[like --netrc, but does not make .netrc usage mandatory]' \
+ '--netrc-file[like --netrc, but specify file to use]:netrc file:_files' \
+ '--tr-encoding[request compressed transfer-encoding]' \
+ {-u,--user}'[specify user name and password for server authentication]:user\:password' \
+ )
+
+# Input arguments
+arg_input=(\
+ {-C,--continue-at}'[resume at offset ]:offset' \
+ {-g,--globoff}'[do not glob {}\[\] letters]' \
+ '--max-filesize[maximum filesize to download, fail for bigger files]:bytes' \
+ '--proto[specify allowed protocols for transfer]:protocols' \
+ '--proto-redir[specify allowed protocols for transfer after a redirect]:protocols' \
+ {-r,--range}'[set range of bytes to request (HTTP/FTP/SFTP/FILE)]:range' \
+ {-R,--remote-time}'[use timestamp of remote file for local file]' \
+ {-T,--upload-file}'[transfer file to remote url (using PUT for HTTP)]:file to upload:_files' \
+ '--url[specify a URL to fetch (multi)]:url:_urls' \
+ {-z,--time-cond}'[request downloaded file to be newer than date or given reference file]:date expression' \
+ )
+
+# Output arguments
+arg_output=(\
+ '--create-dirs[create local directory hierarchy as needed]' \
+ {-D,--dump-header}'[write protocol headers to file]:dump file:_files' \
+ {-o,--output}'[write to specified file instead of stdout]:output file:_files' \
+ {--progress-bar,-\#}'[display progress as a simple progress bar]' \
+ {-\#,--progress-bar}'[Make curl display progress as a simple progress bar instead of the standard, more informational, meter.]' \
+ {-R,--remote-time}'[use timestamp of remote file for local file]' \
+ '--raw[disable all http decoding and pass raw data]' \
+ {-s,--silent}'[silent mode, do not show progress meter or error messages]' \
+ {-S,--show-error}'[show errors in silent mode]' \
+ '--stderr[redirect stderr to specified file]:output file:_files' \
+ '--trace[enable full trace dump of all incoming and outgoing data]:trace file:_files' \
+ '--trace-ascii[enable full trace dump of all incoming and outgoing data, without hex data]:trace file:_files' \
+ '--trace-time[prepends a time stamp to each trace or verbose line that curl displays]' \
+ {-v,--verbose}'[output debug info]' \
+ {-w,--write-out}'[specify message to output on successful operation]:format string' \
+ '--xattr[store some file metadata in extended file attributes]' \
+ {-X,--request}'[specifies request method for HTTP server]:method:(GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH LINK UNLINK)' \
+ )
+
+_arguments -C -s $arg_http $arg_ftp $arg_other $arg_crypto $arg_connection $arg_auth $arg_input $arg_output \
+ {-M,--manual}'[Print manual]' \
+ '*'{-K,--config}'[Use other config file to read arguments from]:config file:_files' \
+ '--libcurl[output libcurl code for the operation to file]:output file:_files' \
+ {-m,--max-time}'[Limit total time of operation]:seconds' \
+ {-s,--silent}'[Silent mode, do not show progress meter or error messages]' \
+ {-S,--show-error}'[Show errors in silent mode]' \
+ '--stderr[Redirect stderr to specified file]:output file:_files' \
+ '-q[Do not read settings from .curlrc (must be first option)]' \
+ {-h,--help}'[Print help and list of operations]' \
+ {-V,--version}'[Print service API version]' \
+ '--about[Print the information about service]' \
+ '--host[Specify the host URL]':URL:_urls \
+ '--dry-run[Print out the cURL command without executing it]' \
+ {-ac,--accept}'[Set the Accept header in the request]: :{_values "Accept mime type" $(get_mime_type_completions)}' \
+ {-ct,--content-type}'[Set the Content-type header in request]: :{_values "Content mime type" $(get_mime_type_completions)}' \
+ '1: :->ops' \
+ '*:: :->args' \
+ && ret=0
+
+
+case $state in
+ ops)
+ # Operations
+ _values "Operations" \
+ "123Test@$%SpecialTags[To test special tags]" "fooGet[]" "fakeHealthGet[Health check endpoint]" \
+ "fakeOuterBooleanSerialize[]" \
+ "fakeOuterCompositeSerialize[]" \
+ "fakeOuterNumberSerialize[]" \
+ "fakeOuterStringSerialize[]" \
+ "testBodyWithFileSchema[]" \
+ "testBodyWithQueryParams[]" \
+ "testClientModel[To test \"client\" model]" \
+ "testEndpointParameters[Fake endpoint for testing various parameters
+假端點
+偽のエンドポイント
+가짜 엔드 포인트]" \
+ "testEnumParameters[To test enum parameters]" \
+ "testGroupParameters[Fake endpoint to test group parameters (optional)]" \
+ "testInlineAdditionalProperties[test inline additionalProperties]" \
+ "testJsonFormData[test json serialization of form data]" "testClassname[To test class name in snake case]" "addPet[Add a new pet to the store]" \
+ "deletePet[Deletes a pet]" \
+ "findPetsByStatus[Finds Pets by status]" \
+ "findPetsByTags[Finds Pets by tags]" \
+ "getPetById[Find pet by ID]" \
+ "updatePet[Update an existing pet]" \
+ "updatePetWithForm[Updates a pet in the store with form data]" \
+ "uploadFile[uploads an image]" \
+ "uploadFileWithRequiredFile[uploads an image (required)]" "deleteOrder[Delete purchase order by ID]" \
+ "getInventory[Returns pet inventories by status]" \
+ "getOrderById[Find purchase order by ID]" \
+ "placeOrder[Place an order for a pet]" "createUser[Create user]" \
+ "createUsersWithArrayInput[Creates list of users with given input array]" \
+ "createUsersWithListInput[Creates list of users with given input array]" \
+ "deleteUser[Delete user]" \
+ "getUserByName[Get user by user name]" \
+ "loginUser[Logs user into the system]" \
+ "logoutUser[Logs out current logged in user session]" \
+ "updateUser[Updated user]"
+ _arguments "(--help)--help[Print information about operation]"
+
+ ret=0
+ ;;
+ args)
+ case $line[1] in
+ 123Test@$%SpecialTags)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ fooGet)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ fakeHealthGet)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ fakeOuterBooleanSerialize)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ fakeOuterCompositeSerialize)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ fakeOuterNumberSerialize)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ fakeOuterStringSerialize)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testBodyWithFileSchema)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testBodyWithQueryParams)
+ local -a _op_arguments
+ _op_arguments=(
+ "query=:[QUERY] "
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testClientModel)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testEndpointParameters)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testEnumParameters)
+ local -a _op_arguments
+ _op_arguments=(
+ "enum_query_string_array=:[QUERY] Query parameter enum test (string array)"
+"enum_query_string=:[QUERY] Query parameter enum test (string)"
+"enum_query_integer=:[QUERY] Query parameter enum test (double)"
+"enum_query_double=:[QUERY] Query parameter enum test (double)"
+ "enum_header_string_array\::[HEADER] Header parameter enum test (string array)"
+"enum_header_string\::[HEADER] Header parameter enum test (string)"
+)
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testGroupParameters)
+ local -a _op_arguments
+ _op_arguments=(
+ "required_string_group=:[QUERY] Required String in group parameters"
+"required_int64_group=:[QUERY] Required Integer in group parameters"
+"string_group=:[QUERY] String in group parameters"
+"int64_group=:[QUERY] Integer in group parameters"
+ "required_boolean_group\::[HEADER] Required Boolean in group parameters"
+"boolean_group\::[HEADER] Boolean in group parameters"
+)
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testInlineAdditionalProperties)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testJsonFormData)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testClassname)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ addPet)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ deletePet)
+ local -a _op_arguments
+ _op_arguments=(
+ "petId=:[PATH] Pet id to delete"
+ "api_key\::[HEADER] "
+)
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ findPetsByStatus)
+ local -a _op_arguments
+ _op_arguments=(
+ "status=:[QUERY] Status values that need to be considered for filter"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ findPetsByTags)
+ local -a _op_arguments
+ _op_arguments=(
+ "tags=:[QUERY] Tags to filter by"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ getPetById)
+ local -a _op_arguments
+ _op_arguments=(
+ "petId=:[PATH] ID of pet to return"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ updatePet)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ updatePetWithForm)
+ local -a _op_arguments
+ _op_arguments=(
+ "petId=:[PATH] ID of pet that needs to be updated"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ uploadFile)
+ local -a _op_arguments
+ _op_arguments=(
+ "petId=:[PATH] ID of pet to update"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ uploadFileWithRequiredFile)
+ local -a _op_arguments
+ _op_arguments=(
+ "petId=:[PATH] ID of pet to update"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ deleteOrder)
+ local -a _op_arguments
+ _op_arguments=(
+ "order_id=:[PATH] ID of the order that needs to be deleted"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ getInventory)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ getOrderById)
+ local -a _op_arguments
+ _op_arguments=(
+ "order_id=:[PATH] ID of pet that needs to be fetched"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ placeOrder)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ createUser)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ createUsersWithArrayInput)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ createUsersWithListInput)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ deleteUser)
+ local -a _op_arguments
+ _op_arguments=(
+ "username=:[PATH] The name that needs to be deleted"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ getUserByName)
+ local -a _op_arguments
+ _op_arguments=(
+ "username=:[PATH] The name that needs to be fetched. Use user1 for testing."
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ loginUser)
+ local -a _op_arguments
+ _op_arguments=(
+ "username=:[QUERY] The user name for login"
+"password=:[QUERY] The password for login in clear text"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ logoutUser)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ updateUser)
+ local -a _op_arguments
+ _op_arguments=(
+ "username=:[PATH] name that need to be deleted"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ esac
+ ;;
+
+esac
+
+return ret
diff --git a/samples/client/petstore/bash/_petstore-cli b/samples/client/petstore/bash/_petstore-cli
index 3141c8ccd87..22d7eaf982d 100644
--- a/samples/client/petstore/bash/_petstore-cli
+++ b/samples/client/petstore/bash/_petstore-cli
@@ -296,10 +296,12 @@ case $state in
ops)
# Operations
_values "Operations" \
- "testSpecialTags[To test special tags]" "fakeOuterBooleanSerialize[]" \
+ "123Test@$%SpecialTags[To test special tags]" "createXmlItem[creates an XmlItem]" \
+ "fakeOuterBooleanSerialize[]" \
"fakeOuterCompositeSerialize[]" \
"fakeOuterNumberSerialize[]" \
"fakeOuterStringSerialize[]" \
+ "testBodyWithFileSchema[]" \
"testBodyWithQueryParams[]" \
"testClientModel[To test \"client\" model]" \
"testEndpointParameters[Fake endpoint for testing various parameters
@@ -307,6 +309,7 @@ case $state in
偽のエンドポイント
가짜 엔드 포인트]" \
"testEnumParameters[To test enum parameters]" \
+ "testGroupParameters[Fake endpoint to test group parameters (optional)]" \
"testInlineAdditionalProperties[test inline additionalProperties]" \
"testJsonFormData[test json serialization of form data]" "testClassname[To test class name in snake case]" "addPet[Add a new pet to the store]" \
"deletePet[Deletes a pet]" \
@@ -315,7 +318,8 @@ case $state in
"getPetById[Find pet by ID]" \
"updatePet[Update an existing pet]" \
"updatePetWithForm[Updates a pet in the store with form data]" \
- "uploadFile[uploads an image]" "deleteOrder[Delete purchase order by ID]" \
+ "uploadFile[uploads an image]" \
+ "uploadFileWithRequiredFile[uploads an image (required)]" "deleteOrder[Delete purchase order by ID]" \
"getInventory[Returns pet inventories by status]" \
"getOrderById[Find purchase order by ID]" \
"placeOrder[Place an order for a pet]" "createUser[Create user]" \
@@ -332,7 +336,13 @@ case $state in
;;
args)
case $line[1] in
- testSpecialTags)
+ 123Test@$%SpecialTags)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ createXmlItem)
local -a _op_arguments
_op_arguments=(
)
@@ -362,6 +372,12 @@ case $state in
)
_describe -t actions 'operations' _op_arguments -S '' && ret=0
;;
+ testBodyWithFileSchema)
+ local -a _op_arguments
+ _op_arguments=(
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
testBodyWithQueryParams)
local -a _op_arguments
_op_arguments=(
@@ -390,6 +406,18 @@ case $state in
"enum_query_double=:[QUERY] Query parameter enum test (double)"
"enum_header_string_array\::[HEADER] Header parameter enum test (string array)"
"enum_header_string\::[HEADER] Header parameter enum test (string)"
+)
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
+ testGroupParameters)
+ local -a _op_arguments
+ _op_arguments=(
+ "required_string_group=:[QUERY] Required String in group parameters"
+"required_int64_group=:[QUERY] Required Integer in group parameters"
+"string_group=:[QUERY] String in group parameters"
+"int64_group=:[QUERY] Integer in group parameters"
+ "required_boolean_group\::[HEADER] Required Boolean in group parameters"
+"boolean_group\::[HEADER] Boolean in group parameters"
)
_describe -t actions 'operations' _op_arguments -S '' && ret=0
;;
@@ -466,6 +494,13 @@ case $state in
)
_describe -t actions 'operations' _op_arguments -S '' && ret=0
;;
+ uploadFileWithRequiredFile)
+ local -a _op_arguments
+ _op_arguments=(
+ "petId=:[PATH] ID of pet to update"
+ )
+ _describe -t actions 'operations' _op_arguments -S '' && ret=0
+ ;;
deleteOrder)
local -a _op_arguments
_op_arguments=(
diff --git a/samples/client/petstore/bash/client.sh b/samples/client/petstore/bash/client.sh
new file mode 100644
index 00000000000..c43fb5804e6
--- /dev/null
+++ b/samples/client/petstore/bash/client.sh
@@ -0,0 +1,4003 @@
+#!/usr/bin/env bash
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# !
+# ! Note:
+# !
+# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
+# ! openapi-generator (https://openapi-generator.tech)
+# ! FROM OPENAPI SPECIFICATION IN JSON.
+# !
+# !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#
+# This is a Bash client for OpenAPI Petstore.
+#
+# LICENSE:
+# http://www.apache.org/licenses/LICENSE-2.0.html
+#
+# CONTACT:
+#
+#
+# MORE INFORMATION:
+#
+#
+
+# For improved pattern matching in case statemets
+shopt -s extglob
+
+###############################################################################
+#
+# Make sure Bash is at least in version 4.3
+#
+###############################################################################
+if ! ( (("${BASH_VERSION:0:1}" == "4")) && (("${BASH_VERSION:2:1}" >= "3")) ) \
+ && ! (("${BASH_VERSION:0:1}" >= "5")); then
+ echo ""
+ echo "Sorry - your Bash version is ${BASH_VERSION}"
+ echo ""
+ echo "You need at least Bash 4.3 to run this script."
+ echo ""
+ exit 1
+fi
+
+###############################################################################
+#
+# Global variables
+#
+###############################################################################
+
+##
+# The filename of this script for help messages
+script_name=$(basename "$0")
+
+##
+# Map for headers passed after operation as KEY:VALUE
+declare -A header_arguments
+
+
+##
+# Map for operation parameters passed after operation as PARAMETER=VALUE
+# These will be mapped to appropriate path or query parameters
+# The values in operation_parameters are arrays, so that multiple values
+# can be provided for the same parameter if allowed by API specification
+declare -A operation_parameters
+
+##
+# Declare colors with autodection if output is terminal
+if [ -t 1 ]; then
+ RED="$(tput setaf 1)"
+ GREEN="$(tput setaf 2)"
+ YELLOW="$(tput setaf 3)"
+ BLUE="$(tput setaf 4)"
+ MAGENTA="$(tput setaf 5)"
+ CYAN="$(tput setaf 6)"
+ WHITE="$(tput setaf 7)"
+ BOLD="$(tput bold)"
+ OFF="$(tput sgr0)"
+else
+ RED=""
+ GREEN=""
+ YELLOW=""
+ BLUE=""
+ MAGENTA=""
+ CYAN=""
+ WHITE=""
+ BOLD=""
+ OFF=""
+fi
+
+declare -a result_color_table=( "$WHITE" "$WHITE" "$GREEN" "$YELLOW" "$WHITE" "$MAGENTA" "$WHITE" )
+
+##
+# This array stores the minimum number of required occurrences for parameter
+# 0 - optional
+# 1 - required
+declare -A operation_parameters_minimum_occurrences
+operation_parameters_minimum_occurrences["123Test@$%SpecialTags:::Client"]=1
+operation_parameters_minimum_occurrences["fakeOuterBooleanSerialize:::body"]=0
+operation_parameters_minimum_occurrences["fakeOuterCompositeSerialize:::OuterComposite"]=0
+operation_parameters_minimum_occurrences["fakeOuterNumberSerialize:::body"]=0
+operation_parameters_minimum_occurrences["fakeOuterStringSerialize:::body"]=0
+operation_parameters_minimum_occurrences["testBodyWithFileSchema:::FileSchemaTestClass"]=1
+operation_parameters_minimum_occurrences["testBodyWithQueryParams:::query"]=1
+operation_parameters_minimum_occurrences["testBodyWithQueryParams:::User"]=1
+operation_parameters_minimum_occurrences["testClientModel:::Client"]=1
+operation_parameters_minimum_occurrences["testEndpointParameters:::number"]=1
+operation_parameters_minimum_occurrences["testEndpointParameters:::double"]=1
+operation_parameters_minimum_occurrences["testEndpointParameters:::pattern_without_delimiter"]=1
+operation_parameters_minimum_occurrences["testEndpointParameters:::byte"]=1
+operation_parameters_minimum_occurrences["testEndpointParameters:::integer"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::int32"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::int64"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::float"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::string"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::binary"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::date"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::dateTime"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::password"]=0
+operation_parameters_minimum_occurrences["testEndpointParameters:::callback"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_header_string_array"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_header_string"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_query_string_array"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_query_string"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_query_integer"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_query_double"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_form_string_array"]=0
+operation_parameters_minimum_occurrences["testEnumParameters:::enum_form_string"]=0
+operation_parameters_minimum_occurrences["testGroupParameters:::required_string_group"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::required_boolean_group"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::required_int64_group"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::string_group"]=0
+operation_parameters_minimum_occurrences["testGroupParameters:::boolean_group"]=0
+operation_parameters_minimum_occurrences["testGroupParameters:::int64_group"]=0
+operation_parameters_minimum_occurrences["testInlineAdditionalProperties:::request_body"]=1
+operation_parameters_minimum_occurrences["testJsonFormData:::param"]=1
+operation_parameters_minimum_occurrences["testJsonFormData:::param2"]=1
+operation_parameters_minimum_occurrences["testClassname:::Client"]=1
+operation_parameters_minimum_occurrences["addPet:::Pet"]=1
+operation_parameters_minimum_occurrences["deletePet:::petId"]=1
+operation_parameters_minimum_occurrences["deletePet:::api_key"]=0
+operation_parameters_minimum_occurrences["findPetsByStatus:::status"]=1
+operation_parameters_minimum_occurrences["findPetsByTags:::tags"]=1
+operation_parameters_minimum_occurrences["getPetById:::petId"]=1
+operation_parameters_minimum_occurrences["updatePet:::Pet"]=1
+operation_parameters_minimum_occurrences["updatePetWithForm:::petId"]=1
+operation_parameters_minimum_occurrences["updatePetWithForm:::name"]=0
+operation_parameters_minimum_occurrences["updatePetWithForm:::status"]=0
+operation_parameters_minimum_occurrences["uploadFile:::petId"]=1
+operation_parameters_minimum_occurrences["uploadFile:::additionalMetadata"]=0
+operation_parameters_minimum_occurrences["uploadFile:::file"]=0
+operation_parameters_minimum_occurrences["uploadFileWithRequiredFile:::petId"]=1
+operation_parameters_minimum_occurrences["uploadFileWithRequiredFile:::requiredFile"]=1
+operation_parameters_minimum_occurrences["uploadFileWithRequiredFile:::additionalMetadata"]=0
+operation_parameters_minimum_occurrences["deleteOrder:::order_id"]=1
+operation_parameters_minimum_occurrences["getOrderById:::order_id"]=1
+operation_parameters_minimum_occurrences["placeOrder:::Order"]=1
+operation_parameters_minimum_occurrences["createUser:::User"]=1
+operation_parameters_minimum_occurrences["createUsersWithArrayInput:::User"]=1
+operation_parameters_minimum_occurrences["createUsersWithListInput:::User"]=1
+operation_parameters_minimum_occurrences["deleteUser:::username"]=1
+operation_parameters_minimum_occurrences["getUserByName:::username"]=1
+operation_parameters_minimum_occurrences["loginUser:::username"]=1
+operation_parameters_minimum_occurrences["loginUser:::password"]=1
+operation_parameters_minimum_occurrences["updateUser:::username"]=1
+operation_parameters_minimum_occurrences["updateUser:::User"]=1
+
+##
+# This array stores the maximum number of allowed occurrences for parameter
+# 1 - single value
+# 2 - 2 values
+# N - N values
+# 0 - unlimited
+declare -A operation_parameters_maximum_occurrences
+operation_parameters_maximum_occurrences["123Test@$%SpecialTags:::Client"]=0
+operation_parameters_maximum_occurrences["fakeOuterBooleanSerialize:::body"]=0
+operation_parameters_maximum_occurrences["fakeOuterCompositeSerialize:::OuterComposite"]=0
+operation_parameters_maximum_occurrences["fakeOuterNumberSerialize:::body"]=0
+operation_parameters_maximum_occurrences["fakeOuterStringSerialize:::body"]=0
+operation_parameters_maximum_occurrences["testBodyWithFileSchema:::FileSchemaTestClass"]=0
+operation_parameters_maximum_occurrences["testBodyWithQueryParams:::query"]=0
+operation_parameters_maximum_occurrences["testBodyWithQueryParams:::User"]=0
+operation_parameters_maximum_occurrences["testClientModel:::Client"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::number"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::double"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::pattern_without_delimiter"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::byte"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::integer"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::int32"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::int64"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::float"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::string"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::binary"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::date"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::dateTime"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::password"]=0
+operation_parameters_maximum_occurrences["testEndpointParameters:::callback"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_header_string_array"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_header_string"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_query_string_array"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_query_string"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_query_integer"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_query_double"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_form_string_array"]=0
+operation_parameters_maximum_occurrences["testEnumParameters:::enum_form_string"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::required_string_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::required_boolean_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::required_int64_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::string_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::boolean_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::int64_group"]=0
+operation_parameters_maximum_occurrences["testInlineAdditionalProperties:::request_body"]=0
+operation_parameters_maximum_occurrences["testJsonFormData:::param"]=0
+operation_parameters_maximum_occurrences["testJsonFormData:::param2"]=0
+operation_parameters_maximum_occurrences["testClassname:::Client"]=0
+operation_parameters_maximum_occurrences["addPet:::Pet"]=0
+operation_parameters_maximum_occurrences["deletePet:::petId"]=0
+operation_parameters_maximum_occurrences["deletePet:::api_key"]=0
+operation_parameters_maximum_occurrences["findPetsByStatus:::status"]=0
+operation_parameters_maximum_occurrences["findPetsByTags:::tags"]=0
+operation_parameters_maximum_occurrences["getPetById:::petId"]=0
+operation_parameters_maximum_occurrences["updatePet:::Pet"]=0
+operation_parameters_maximum_occurrences["updatePetWithForm:::petId"]=0
+operation_parameters_maximum_occurrences["updatePetWithForm:::name"]=0
+operation_parameters_maximum_occurrences["updatePetWithForm:::status"]=0
+operation_parameters_maximum_occurrences["uploadFile:::petId"]=0
+operation_parameters_maximum_occurrences["uploadFile:::additionalMetadata"]=0
+operation_parameters_maximum_occurrences["uploadFile:::file"]=0
+operation_parameters_maximum_occurrences["uploadFileWithRequiredFile:::petId"]=0
+operation_parameters_maximum_occurrences["uploadFileWithRequiredFile:::requiredFile"]=0
+operation_parameters_maximum_occurrences["uploadFileWithRequiredFile:::additionalMetadata"]=0
+operation_parameters_maximum_occurrences["deleteOrder:::order_id"]=0
+operation_parameters_maximum_occurrences["getOrderById:::order_id"]=0
+operation_parameters_maximum_occurrences["placeOrder:::Order"]=0
+operation_parameters_maximum_occurrences["createUser:::User"]=0
+operation_parameters_maximum_occurrences["createUsersWithArrayInput:::User"]=0
+operation_parameters_maximum_occurrences["createUsersWithListInput:::User"]=0
+operation_parameters_maximum_occurrences["deleteUser:::username"]=0
+operation_parameters_maximum_occurrences["getUserByName:::username"]=0
+operation_parameters_maximum_occurrences["loginUser:::username"]=0
+operation_parameters_maximum_occurrences["loginUser:::password"]=0
+operation_parameters_maximum_occurrences["updateUser:::username"]=0
+operation_parameters_maximum_occurrences["updateUser:::User"]=0
+
+##
+# The type of collection for specifying multiple values for parameter:
+# - multi, csv, ssv, tsv
+declare -A operation_parameters_collection_type
+operation_parameters_collection_type["123Test@$%SpecialTags:::Client"]=""
+operation_parameters_collection_type["fakeOuterBooleanSerialize:::body"]=""
+operation_parameters_collection_type["fakeOuterCompositeSerialize:::OuterComposite"]=""
+operation_parameters_collection_type["fakeOuterNumberSerialize:::body"]=""
+operation_parameters_collection_type["fakeOuterStringSerialize:::body"]=""
+operation_parameters_collection_type["testBodyWithFileSchema:::FileSchemaTestClass"]=""
+operation_parameters_collection_type["testBodyWithQueryParams:::query"]=""
+operation_parameters_collection_type["testBodyWithQueryParams:::User"]=""
+operation_parameters_collection_type["testClientModel:::Client"]=""
+operation_parameters_collection_type["testEndpointParameters:::number"]=""
+operation_parameters_collection_type["testEndpointParameters:::double"]=""
+operation_parameters_collection_type["testEndpointParameters:::pattern_without_delimiter"]=""
+operation_parameters_collection_type["testEndpointParameters:::byte"]=""
+operation_parameters_collection_type["testEndpointParameters:::integer"]=""
+operation_parameters_collection_type["testEndpointParameters:::int32"]=""
+operation_parameters_collection_type["testEndpointParameters:::int64"]=""
+operation_parameters_collection_type["testEndpointParameters:::float"]=""
+operation_parameters_collection_type["testEndpointParameters:::string"]=""
+operation_parameters_collection_type["testEndpointParameters:::binary"]=""
+operation_parameters_collection_type["testEndpointParameters:::date"]=""
+operation_parameters_collection_type["testEndpointParameters:::dateTime"]=""
+operation_parameters_collection_type["testEndpointParameters:::password"]=""
+operation_parameters_collection_type["testEndpointParameters:::callback"]=""
+operation_parameters_collection_type["testEnumParameters:::enum_header_string_array"]="csv"
+operation_parameters_collection_type["testEnumParameters:::enum_header_string"]=""
+operation_parameters_collection_type["testEnumParameters:::enum_query_string_array"]="multi"
+operation_parameters_collection_type["testEnumParameters:::enum_query_string"]=""
+operation_parameters_collection_type["testEnumParameters:::enum_query_integer"]=""
+operation_parameters_collection_type["testEnumParameters:::enum_query_double"]=""
+operation_parameters_collection_type["testEnumParameters:::enum_form_string_array"]=
+operation_parameters_collection_type["testEnumParameters:::enum_form_string"]=""
+operation_parameters_collection_type["testGroupParameters:::required_string_group"]=""
+operation_parameters_collection_type["testGroupParameters:::required_boolean_group"]=""
+operation_parameters_collection_type["testGroupParameters:::required_int64_group"]=""
+operation_parameters_collection_type["testGroupParameters:::string_group"]=""
+operation_parameters_collection_type["testGroupParameters:::boolean_group"]=""
+operation_parameters_collection_type["testGroupParameters:::int64_group"]=""
+operation_parameters_collection_type["testInlineAdditionalProperties:::request_body"]=
+operation_parameters_collection_type["testJsonFormData:::param"]=""
+operation_parameters_collection_type["testJsonFormData:::param2"]=""
+operation_parameters_collection_type["testClassname:::Client"]=""
+operation_parameters_collection_type["addPet:::Pet"]=""
+operation_parameters_collection_type["deletePet:::petId"]=""
+operation_parameters_collection_type["deletePet:::api_key"]=""
+operation_parameters_collection_type["findPetsByStatus:::status"]="csv"
+operation_parameters_collection_type["findPetsByTags:::tags"]="csv"
+operation_parameters_collection_type["getPetById:::petId"]=""
+operation_parameters_collection_type["updatePet:::Pet"]=""
+operation_parameters_collection_type["updatePetWithForm:::petId"]=""
+operation_parameters_collection_type["updatePetWithForm:::name"]=""
+operation_parameters_collection_type["updatePetWithForm:::status"]=""
+operation_parameters_collection_type["uploadFile:::petId"]=""
+operation_parameters_collection_type["uploadFile:::additionalMetadata"]=""
+operation_parameters_collection_type["uploadFile:::file"]=""
+operation_parameters_collection_type["uploadFileWithRequiredFile:::petId"]=""
+operation_parameters_collection_type["uploadFileWithRequiredFile:::requiredFile"]=""
+operation_parameters_collection_type["uploadFileWithRequiredFile:::additionalMetadata"]=""
+operation_parameters_collection_type["deleteOrder:::order_id"]=""
+operation_parameters_collection_type["getOrderById:::order_id"]=""
+operation_parameters_collection_type["placeOrder:::Order"]=""
+operation_parameters_collection_type["createUser:::User"]=""
+operation_parameters_collection_type["createUsersWithArrayInput:::User"]=
+operation_parameters_collection_type["createUsersWithListInput:::User"]=
+operation_parameters_collection_type["deleteUser:::username"]=""
+operation_parameters_collection_type["getUserByName:::username"]=""
+operation_parameters_collection_type["loginUser:::username"]=""
+operation_parameters_collection_type["loginUser:::password"]=""
+operation_parameters_collection_type["updateUser:::username"]=""
+operation_parameters_collection_type["updateUser:::User"]=""
+
+
+##
+# Map for body parameters passed after operation as
+# PARAMETER==STRING_VALUE or PARAMETER:=NUMERIC_VALUE
+# These will be mapped to top level json keys ( { "PARAMETER": "VALUE" })
+declare -A body_parameters
+
+##
+# These arguments will be directly passed to cURL
+curl_arguments=""
+
+##
+# The host for making the request
+host=""
+
+##
+# The user credentials for basic authentication
+basic_auth_credential=""
+
+##
+# The user API key
+apikey_auth_credential=""
+
+##
+# If true, the script will only output the actual cURL command that would be
+# used
+print_curl=false
+
+##
+# The operation ID passed on the command line
+operation=""
+
+##
+# The provided Accept header value
+header_accept=""
+
+##
+# The provided Content-type header value
+header_content_type=""
+
+##
+# If there is any body content on the stdin pass it to the body of the request
+body_content_temp_file=""
+
+##
+# If this variable is set to true, the request will be performed even
+# if parameters for required query, header or body values are not provided
+# (path parameters are still required).
+force=false
+
+##
+# Declare some mime types abbreviations for easier content-type and accepts
+# headers specification
+declare -A mime_type_abbreviations
+# text/*
+mime_type_abbreviations["text"]="text/plain"
+mime_type_abbreviations["html"]="text/html"
+mime_type_abbreviations["md"]="text/x-markdown"
+mime_type_abbreviations["csv"]="text/csv"
+mime_type_abbreviations["css"]="text/css"
+mime_type_abbreviations["rtf"]="text/rtf"
+# application/*
+mime_type_abbreviations["json"]="application/json"
+mime_type_abbreviations["xml"]="application/xml"
+mime_type_abbreviations["yaml"]="application/yaml"
+mime_type_abbreviations["js"]="application/javascript"
+mime_type_abbreviations["bin"]="application/octet-stream"
+mime_type_abbreviations["rdf"]="application/rdf+xml"
+# image/*
+mime_type_abbreviations["jpg"]="image/jpeg"
+mime_type_abbreviations["png"]="image/png"
+mime_type_abbreviations["gif"]="image/gif"
+mime_type_abbreviations["bmp"]="image/bmp"
+mime_type_abbreviations["tiff"]="image/tiff"
+
+
+##############################################################################
+#
+# Escape special URL characters
+# Based on table at http://www.w3schools.com/tags/ref_urlencode.asp
+#
+##############################################################################
+url_escape() {
+ local raw_url="$1"
+
+ value=$(sed -e 's/ /%20/g' \
+ -e 's/!/%21/g' \
+ -e 's/"/%22/g' \
+ -e 's/#/%23/g' \
+ -e 's/\&/%26/g' \
+ -e 's/'\''/%28/g' \
+ -e 's/(/%28/g' \
+ -e 's/)/%29/g' \
+ -e 's/:/%3A/g' \
+ -e 's/\t/%09/g' \
+ -e 's/?/%3F/g' <<<"$raw_url");
+
+ echo "$value"
+}
+
+##############################################################################
+#
+# Lookup the mime type abbreviation in the mime_type_abbreviations array.
+# If not present assume the user provided a valid mime type
+#
+##############################################################################
+lookup_mime_type() {
+ local mime_type="$1"
+
+ if [[ ${mime_type_abbreviations[$mime_type]} ]]; then
+ echo "${mime_type_abbreviations[$mime_type]}"
+ else
+ echo "$mime_type"
+ fi
+}
+
+##############################################################################
+#
+# Converts an associative array into a list of cURL header
+# arguments (-H "KEY: VALUE")
+#
+##############################################################################
+header_arguments_to_curl() {
+ local headers_curl=""
+ local api_key_header=""
+ local api_key_header_in_cli=""
+ api_key_header="api_key"
+
+ for key in "${!header_arguments[@]}"; do
+ headers_curl+="-H \"${key}: ${header_arguments[${key}]}\" "
+ if [[ "${key}XX" == "${api_key_header}XX" ]]; then
+ api_key_header_in_cli="YES"
+ fi
+ done
+ #
+ # If the api_key was not provided in the header, try one from the
+ # environment variable
+ #
+ if [[ -z $api_key_header_in_cli && -n $apikey_auth_credential ]]; then
+ headers_curl+="-H \"${api_key_header}: ${apikey_auth_credential}\""
+ fi
+ headers_curl+=" "
+
+ echo "${headers_curl}"
+}
+
+##############################################################################
+#
+# Converts an associative array into a simple JSON with keys as top
+# level object attributes
+#
+# \todo Add conversion of more complex attributes using paths
+#
+##############################################################################
+body_parameters_to_json() {
+ local body_json="-d '{"
+ local count=0
+ for key in "${!body_parameters[@]}"; do
+ if [[ $((count++)) -gt 0 ]]; then
+ body_json+=", "
+ fi
+ body_json+="\"${key}\": ${body_parameters[${key}]}"
+ done
+ body_json+="}'"
+
+ if [[ "${#body_parameters[@]}" -eq 0 ]]; then
+ echo ""
+ else
+ echo "${body_json}"
+ fi
+}
+
+##############################################################################
+#
+# Helper method for showing error because for example echo in
+# build_request_path() is evaluated as part of command line not printed on
+# output. Anyway better idea for resource clean up ;-).
+#
+##############################################################################
+ERROR_MSG=""
+function finish {
+ if [[ -n "$ERROR_MSG" ]]; then
+ echo >&2 "${OFF}${RED}$ERROR_MSG"
+ echo >&2 "${OFF}Check usage: '${script_name} --help'"
+ fi
+}
+trap finish EXIT
+
+
+##############################################################################
+#
+# Validate and build request path including query parameters
+#
+##############################################################################
+build_request_path() {
+ local path_template=$1
+ local -n path_params=$2
+ local -n query_params=$3
+
+
+ #
+ # Check input parameters count against minimum and maximum required
+ #
+ if [[ "$force" = false ]]; then
+ local was_error=""
+ for qparam in "${query_params[@]}" "${path_params[@]}"; do
+ local parameter_values
+ mapfile -t parameter_values < <(sed -e 's/'":::"'/\n/g' <<<"${operation_parameters[$qparam]}")
+
+ #
+ # Check if the number of provided values is not less than minimum required
+ #
+ if [[ ${#parameter_values[@]} -lt ${operation_parameters_minimum_occurrences["${operation}:::${qparam}"]} ]]; then
+ echo "ERROR: Too few values provided for '${qparam}' parameter."
+ was_error=true
+ fi
+
+ #
+ # Check if the number of provided values is not more than maximum
+ #
+ if [[ ${operation_parameters_maximum_occurrences["${operation}:::${qparam}"]} -gt 0 \
+ && ${#parameter_values[@]} -gt ${operation_parameters_maximum_occurrences["${operation}:::${qparam}"]} ]]; then
+ echo "ERROR: Too many values provided for '${qparam}' parameter"
+ was_error=true
+ fi
+ done
+ if [[ -n "$was_error" ]]; then
+ exit 1
+ fi
+ fi
+
+ # First replace all path parameters in the path
+ for pparam in "${path_params[@]}"; do
+ local path_regex="(.*)(\\{$pparam\\})(.*)"
+ if [[ $path_template =~ $path_regex ]]; then
+ path_template=${BASH_REMATCH[1]}${operation_parameters[$pparam]}${BASH_REMATCH[3]}
+ fi
+ done
+
+ local query_request_part=""
+
+ for qparam in "${query_params[@]}"; do
+ if [[ "${operation_parameters[$qparam]}" == "" ]]; then
+ continue
+ fi
+
+ # Get the array of parameter values
+ local parameter_value=""
+ local parameter_values
+ mapfile -t parameter_values < <(sed -e 's/'":::"'/\n/g' <<<"${operation_parameters[$qparam]}")
+
+
+ if [[ ${qparam} == "api_key_query" ]]; then
+ if [[ -n "${parameter_values[*]}" ]]; then
+ parameter_value+="${qparam}=${parameter_values}"
+ else
+ echo "Missing ApiKey!!! You have to provide on command line option 'api_key_query=...'"
+ exit 1
+ fi
+ continue
+ fi
+
+ #
+ # Append parameters without specific cardinality
+ #
+ local collection_type="${operation_parameters_collection_type["${operation}:::${qparam}"]}"
+ if [[ "${collection_type}" == "" ]]; then
+ local vcount=0
+ for qvalue in "${parameter_values[@]}"; do
+ if [[ $((vcount++)) -gt 0 ]]; then
+ parameter_value+="&"
+ fi
+ parameter_value+="${qparam}=${qvalue}"
+ done
+ #
+ # Append parameters specified as 'mutli' collections i.e. param=value1¶m=value2&...
+ #
+ elif [[ "${collection_type}" == "multi" ]]; then
+ local vcount=0
+ for qvalue in "${parameter_values[@]}"; do
+ if [[ $((vcount++)) -gt 0 ]]; then
+ parameter_value+="&"
+ fi
+ parameter_value+="${qparam}=${qvalue}"
+ done
+ #
+ # Append parameters specified as 'csv' collections i.e. param=value1,value2,...
+ #
+ elif [[ "${collection_type}" == "csv" ]]; then
+ parameter_value+="${qparam}="
+ local vcount=0
+ for qvalue in "${parameter_values[@]}"; do
+ if [[ $((vcount++)) -gt 0 ]]; then
+ parameter_value+=","
+ fi
+ parameter_value+="${qvalue}"
+ done
+ #
+ # Append parameters specified as 'ssv' collections i.e. param="value1 value2 ..."
+ #
+ elif [[ "${collection_type}" == "ssv" ]]; then
+ parameter_value+="${qparam}="
+ local vcount=0
+ for qvalue in "${parameter_values[@]}"; do
+ if [[ $((vcount++)) -gt 0 ]]; then
+ parameter_value+=" "
+ fi
+ parameter_value+="${qvalue}"
+ done
+ #
+ # Append parameters specified as 'tsv' collections i.e. param="value1\tvalue2\t..."
+ #
+ elif [[ "${collection_type}" == "tsv" ]]; then
+ parameter_value+="${qparam}="
+ local vcount=0
+ for qvalue in "${parameter_values[@]}"; do
+ if [[ $((vcount++)) -gt 0 ]]; then
+ parameter_value+="\\t"
+ fi
+ parameter_value+="${qvalue}"
+ done
+ else
+ echo "Unsupported collection format \"${collection_type}\""
+ exit 1
+ fi
+
+ if [[ -n "${parameter_value}" ]]; then
+ if [[ -n "${query_request_part}" ]]; then
+ query_request_part+="&"
+ fi
+ query_request_part+="${parameter_value}"
+ fi
+
+ done
+
+
+ # Now append query parameters - if any
+ if [[ -n "${query_request_part}" ]]; then
+ path_template+="?${query_request_part}"
+ fi
+
+ echo "$path_template"
+}
+
+
+
+###############################################################################
+#
+# Print main help message
+#
+###############################################################################
+print_help() {
+cat <${OFF}]
+ [-ac|--accept ${GREEN}${OFF}] [-ct,--content-type ${GREEN}${OFF}]
+ [--host ${CYAN}${OFF}] [--dry-run] [-nc|--no-colors] ${YELLOW}${OFF} [-h|--help]
+ [${BLUE}${OFF}] [${MAGENTA}${OFF}] [${MAGENTA}${OFF}]
+
+ - ${CYAN}${OFF} - endpoint of the REST service without basepath
+
+ - ${RED}${OFF} - any valid cURL options can be passed before ${YELLOW}${OFF}
+ - ${GREEN}${OFF} - either full mime-type or one of supported abbreviations:
+ (text, html, md, csv, css, rtf, json, xml, yaml, js, bin,
+ rdf, jpg, png, gif, bmp, tiff)
+ - ${BLUE}${OFF} - HTTP headers can be passed in the form ${YELLOW}HEADER${OFF}:${BLUE}VALUE${OFF}
+ - ${MAGENTA}${OFF} - REST operation parameters can be passed in the following
+ forms:
+ * ${YELLOW}KEY${OFF}=${BLUE}VALUE${OFF} - path or query parameters
+ - ${MAGENTA}${OFF} - simple JSON body content (first level only) can be build
+ using the following arguments:
+ * ${YELLOW}KEY${OFF}==${BLUE}VALUE${OFF} - body parameters which will be added to body
+ JSON as '{ ..., "${YELLOW}KEY${OFF}": "${BLUE}VALUE${OFF}", ... }'
+ * ${YELLOW}KEY${OFF}:=${BLUE}VALUE${OFF} - body parameters which will be added to body
+ JSON as '{ ..., "${YELLOW}KEY${OFF}": ${BLUE}VALUE${OFF}, ... }'
+
+EOF
+ echo -e "${BOLD}${WHITE}Authentication methods${OFF}"
+ echo -e ""
+ echo -e " - ${BLUE}Api-key${OFF} - add '${RED}api_key:${OFF}' after ${YELLOW}${OFF}"
+
+ echo -e " - ${BLUE}Api-key${OFF} - add '${RED}api_key_query=${OFF}' after ${YELLOW}${OFF}"
+
+ echo -e " - ${BLUE}Basic AUTH${OFF} - add '-u :' before ${YELLOW}${OFF}"
+
+ echo -e " - ${BLUE}Basic AUTH${OFF} - add '-u :' before ${YELLOW}${OFF}"
+
+ echo -e " - ${MAGENTA}OAuth2 (flow: implicit)${OFF}"
+ echo -e " Authorization URL: "
+ echo -e " * http://petstore.swagger.io/api/oauth/dialog"
+ echo -e " Scopes:"
+ echo -e " * write:pets - modify pets in your account"
+ echo -e " * read:pets - read your pets"
+ echo ""
+ echo -e "${BOLD}${WHITE}Operations (grouped by tags)${OFF}"
+ echo ""
+ echo -e "${BOLD}${WHITE}[anotherFake]${OFF}"
+read -r -d '' ops <${OFF}\\t\\t\\t\\tSpecify the host URL "
+echo -e " \\t\\t\\t\\t(e.g. 'https://petstore.swagger.io')"
+
+ echo -e " --force\\t\\t\\t\\tForce command invocation in spite of missing"
+ echo -e " \\t\\t\\t\\trequired parameters or wrong content type"
+ echo -e " --dry-run\\t\\t\\t\\tPrint out the cURL command without"
+ echo -e " \\t\\t\\t\\texecuting it"
+ echo -e " -nc,--no-colors\\t\\t\\tEnforce print without colors, otherwise autodected"
+ echo -e " -ac,--accept ${YELLOW}${OFF}\\t\\tSet the 'Accept' header in the request"
+ echo -e " -ct,--content-type ${YELLOW}${OFF}\\tSet the 'Content-type' header in "
+ echo -e " \\tthe request"
+ echo ""
+}
+
+
+##############################################################################
+#
+# Print REST service description
+#
+##############################################################################
+print_about() {
+ echo ""
+ echo -e "${BOLD}${WHITE}OpenAPI Petstore command line client (API version 1.0.0)${OFF}"
+ echo ""
+ echo -e "License: Apache-2.0"
+ echo -e "Contact: "
+ echo ""
+read -r -d '' appdescription < 10. Other values will generated exceptions" | paste -sd' ' | fold -sw 80
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}order_id${OFF} ${BLUE}[integer]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - ID of pet that needs to be fetched ${YELLOW}Specify as: order_id=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=200
+ echo -e "${result_color_table[${code:0:1}]} 200;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=400
+ echo -e "${result_color_table[${code:0:1}]} 400;Invalid ID supplied${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=404
+ echo -e "${result_color_table[${code:0:1}]} 404;Order not found${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for placeOrder operation
+#
+##############################################################################
+print_placeOrder_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}placeOrder - Place an order for a pet${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}body${OFF} ${BLUE}[application/json]${OFF} ${RED}(required)${OFF}${OFF} - order placed for purchasing the pet" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=200
+ echo -e "${result_color_table[${code:0:1}]} 200;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=400
+ echo -e "${result_color_table[${code:0:1}]} 400;Invalid Order${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for createUser operation
+#
+##############################################################################
+print_createUser_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}createUser - Create user${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "This can only be done by the logged in user." | paste -sd' ' | fold -sw 80
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}body${OFF} ${BLUE}[application/json]${OFF} ${RED}(required)${OFF}${OFF} - Created user object" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=0
+ echo -e "${result_color_table[${code:0:1}]} 0;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for createUsersWithArrayInput operation
+#
+##############################################################################
+print_createUsersWithArrayInput_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}createUsersWithArrayInput - Creates list of users with given input array${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}body${OFF} ${BLUE}[application/json]${OFF} ${RED}(required)${OFF}${OFF} - List of user object" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=0
+ echo -e "${result_color_table[${code:0:1}]} 0;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for createUsersWithListInput operation
+#
+##############################################################################
+print_createUsersWithListInput_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}createUsersWithListInput - Creates list of users with given input array${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}body${OFF} ${BLUE}[application/json]${OFF} ${RED}(required)${OFF}${OFF} - List of user object" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=0
+ echo -e "${result_color_table[${code:0:1}]} 0;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for deleteUser operation
+#
+##############################################################################
+print_deleteUser_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}deleteUser - Delete user${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "This can only be done by the logged in user." | paste -sd' ' | fold -sw 80
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The name that needs to be deleted ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=400
+ echo -e "${result_color_table[${code:0:1}]} 400;Invalid username supplied${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=404
+ echo -e "${result_color_table[${code:0:1}]} 404;User not found${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for getUserByName operation
+#
+##############################################################################
+print_getUserByName_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}getUserByName - Get user by user name${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The name that needs to be fetched. Use user1 for testing. ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=200
+ echo -e "${result_color_table[${code:0:1}]} 200;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=400
+ echo -e "${result_color_table[${code:0:1}]} 400;Invalid username supplied${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=404
+ echo -e "${result_color_table[${code:0:1}]} 404;User not found${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for loginUser operation
+#
+##############################################################################
+print_loginUser_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}loginUser - Logs user into the system${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The user name for login${YELLOW} Specify as: username=value${OFF}" \
+ | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " * ${GREEN}password${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The password for login in clear text${YELLOW} Specify as: password=value${OFF}" \
+ | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=200
+ echo -e "${result_color_table[${code:0:1}]} 200;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " ${BOLD}${WHITE}Response headers${OFF}"
+ echo -e " ${BLUE}X-Rate-Limit${OFF} - calls per hour allowed by the user" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " ${BLUE}X-Expires-After${OFF} - date in UTC when token expires" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ code=400
+ echo -e "${result_color_table[${code:0:1}]} 400;Invalid username/password supplied${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for logoutUser operation
+#
+##############################################################################
+print_logoutUser_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}logoutUser - Logs out current logged in user session${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=0
+ echo -e "${result_color_table[${code:0:1}]} 0;successful operation${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+##############################################################################
+#
+# Print help for updateUser operation
+#
+##############################################################################
+print_updateUser_help() {
+ echo ""
+ echo -e "${BOLD}${WHITE}updateUser - Updated user${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo -e "This can only be done by the logged in user." | paste -sd' ' | fold -sw 80
+ echo -e ""
+ echo -e "${BOLD}${WHITE}Parameters${OFF}"
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - name that need to be deleted ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " * ${GREEN}body${OFF} ${BLUE}[application/json]${OFF} ${RED}(required)${OFF}${OFF} - Updated user object" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e ""
+ echo ""
+ echo -e "${BOLD}${WHITE}Responses${OFF}"
+ code=400
+ echo -e "${result_color_table[${code:0:1}]} 400;Invalid user supplied${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+ code=404
+ echo -e "${result_color_table[${code:0:1}]} 404;User not found${OFF}" | paste -sd' ' | column -t -s ';' | fold -sw 80 | sed '2,$s/^/ /'
+}
+
+
+##############################################################################
+#
+# Call 123Test@$%SpecialTags operation
+#
+##############################################################################
+call_123Test@$%SpecialTags() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/another-fake/dummy" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PATCH"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call fooGet operation
+#
+##############################################################################
+call_fooGet() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/foo" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call fakeHealthGet operation
+#
+##############################################################################
+call_fakeHealthGet() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/health" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call fakeOuterBooleanSerialize operation
+#
+##############################################################################
+call_fakeOuterBooleanSerialize() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/outer/boolean" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call fakeOuterCompositeSerialize operation
+#
+##############################################################################
+call_fakeOuterCompositeSerialize() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/outer/composite" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call fakeOuterNumberSerialize operation
+#
+##############################################################################
+call_fakeOuterNumberSerialize() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/outer/number" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call fakeOuterStringSerialize operation
+#
+##############################################################################
+call_fakeOuterStringSerialize() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/outer/string" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call testBodyWithFileSchema operation
+#
+##############################################################################
+call_testBodyWithFileSchema() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/body-with-file-schema" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PUT"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call testBodyWithQueryParams operation
+#
+##############################################################################
+call_testBodyWithQueryParams() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(query)
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/body-with-query-params" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PUT"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call testClientModel operation
+#
+##############################################################################
+call_testClientModel() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PATCH"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call testEndpointParameters operation
+#
+##############################################################################
+call_testEndpointParameters() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call testEnumParameters operation
+#
+##############################################################################
+call_testEnumParameters() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(enum_query_string_array enum_query_string enum_query_integer enum_query_double)
+ local path
+
+ if ! path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call testGroupParameters operation
+#
+##############################################################################
+call_testGroupParameters() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(required_string_group required_int64_group string_group int64_group )
+ local path
+
+ if ! path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="DELETE"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call testInlineAdditionalProperties operation
+#
+##############################################################################
+call_testInlineAdditionalProperties() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/inline-additionalProperties" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call testJsonFormData operation
+#
+##############################################################################
+call_testJsonFormData() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/jsonFormData" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call testClassname operation
+#
+##############################################################################
+call_testClassname() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( api_key_query )
+ local path
+
+ if ! path=$(build_request_path "/v2/fake_classname_test" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PATCH"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call addPet operation
+#
+##############################################################################
+call_addPet() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo -e "\\t- application/xml"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call deletePet operation
+#
+##############################################################################
+call_deletePet() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(petId)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet/{petId}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="DELETE"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call findPetsByStatus operation
+#
+##############################################################################
+call_findPetsByStatus() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(status )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet/findByStatus" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call findPetsByTags operation
+#
+##############################################################################
+call_findPetsByTags() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(tags )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet/findByTags" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call getPetById operation
+#
+##############################################################################
+call_getPetById() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(petId)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet/{petId}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call updatePet operation
+#
+##############################################################################
+call_updatePet() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PUT"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo -e "\\t- application/xml"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call updatePetWithForm operation
+#
+##############################################################################
+call_updatePetWithForm() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(petId)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet/{petId}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call uploadFile operation
+#
+##############################################################################
+call_uploadFile() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(petId)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/pet/{petId}/uploadImage" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call uploadFileWithRequiredFile operation
+#
+##############################################################################
+call_uploadFileWithRequiredFile() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(petId)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/{petId}/uploadImageWithRequiredFile" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call deleteOrder operation
+#
+##############################################################################
+call_deleteOrder() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(order_id)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/store/order/{order_id}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="DELETE"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call getInventory operation
+#
+##############################################################################
+call_getInventory() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/store/inventory" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call getOrderById operation
+#
+##############################################################################
+call_getOrderById() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(order_id)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/store/order/{order_id}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call placeOrder operation
+#
+##############################################################################
+call_placeOrder() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/store/order" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call createUser operation
+#
+##############################################################################
+call_createUser() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call createUsersWithArrayInput operation
+#
+##############################################################################
+call_createUsersWithArrayInput() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user/createWithArray" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call createUsersWithListInput operation
+#
+##############################################################################
+call_createUsersWithListInput() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user/createWithList" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+##############################################################################
+#
+# Call deleteUser operation
+#
+##############################################################################
+call_deleteUser() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(username)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user/{username}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="DELETE"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call getUserByName operation
+#
+##############################################################################
+call_getUserByName() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(username)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user/{username}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call loginUser operation
+#
+##############################################################################
+call_loginUser() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(username password)
+ local path
+
+ if ! path=$(build_request_path "/v2/user/login" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call logoutUser operation
+#
+##############################################################################
+call_logoutUser() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user/logout" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="GET"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
+##############################################################################
+#
+# Call updateUser operation
+#
+##############################################################################
+call_updateUser() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(username)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/user/{username}" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PUT"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
+
+
+##############################################################################
+#
+# Main
+#
+##############################################################################
+
+
+# Check dependencies
+type curl >/dev/null 2>&1 || { echo >&2 "ERROR: You do not have 'cURL' installed."; exit 1; }
+type sed >/dev/null 2>&1 || { echo >&2 "ERROR: You do not have 'sed' installed."; exit 1; }
+type column >/dev/null 2>&1 || { echo >&2 "ERROR: You do not have 'bsdmainutils' installed."; exit 1; }
+
+#
+# Process command line
+#
+# Pass all arguments before 'operation' to cURL except the ones we override
+#
+take_user=false
+take_host=false
+take_accept_header=false
+take_contenttype_header=false
+
+for key in "$@"; do
+# Take the value of -u|--user argument
+if [[ "$take_user" = true ]]; then
+ basic_auth_credential="$key"
+ take_user=false
+ continue
+fi
+# Take the value of --host argument
+if [[ "$take_host" = true ]]; then
+ host="$key"
+ take_host=false
+ continue
+fi
+# Take the value of --accept argument
+if [[ "$take_accept_header" = true ]]; then
+ header_accept=$(lookup_mime_type "$key")
+ take_accept_header=false
+ continue
+fi
+# Take the value of --content-type argument
+if [[ "$take_contenttype_header" = true ]]; then
+ header_content_type=$(lookup_mime_type "$key")
+ take_contenttype_header=false
+ continue
+fi
+case $key in
+ -h|--help)
+ if [[ "x$operation" == "x" ]]; then
+ print_help
+ exit 0
+ else
+ eval "print_${operation}_help"
+ exit 0
+ fi
+ ;;
+ -V|--version)
+ print_version
+ exit 0
+ ;;
+ --about)
+ print_about
+ exit 0
+ ;;
+ -u|--user)
+ take_user=true
+ ;;
+ --host)
+ take_host=true
+ ;;
+ --force)
+ force=true
+ ;;
+ -ac|--accept)
+ take_accept_header=true
+ ;;
+ -ct|--content-type)
+ take_contenttype_header=true
+ ;;
+ --dry-run)
+ print_curl=true
+ ;;
+ -nc|--no-colors)
+ RED=""
+ GREEN=""
+ YELLOW=""
+ BLUE=""
+ MAGENTA=""
+ CYAN=""
+ WHITE=""
+ BOLD=""
+ OFF=""
+ result_color_table=( "" "" "" "" "" "" "" )
+ ;;
+ 123Test@$%SpecialTags)
+ operation="123Test@$%SpecialTags"
+ ;;
+ fooGet)
+ operation="fooGet"
+ ;;
+ fakeHealthGet)
+ operation="fakeHealthGet"
+ ;;
+ fakeOuterBooleanSerialize)
+ operation="fakeOuterBooleanSerialize"
+ ;;
+ fakeOuterCompositeSerialize)
+ operation="fakeOuterCompositeSerialize"
+ ;;
+ fakeOuterNumberSerialize)
+ operation="fakeOuterNumberSerialize"
+ ;;
+ fakeOuterStringSerialize)
+ operation="fakeOuterStringSerialize"
+ ;;
+ testBodyWithFileSchema)
+ operation="testBodyWithFileSchema"
+ ;;
+ testBodyWithQueryParams)
+ operation="testBodyWithQueryParams"
+ ;;
+ testClientModel)
+ operation="testClientModel"
+ ;;
+ testEndpointParameters)
+ operation="testEndpointParameters"
+ ;;
+ testEnumParameters)
+ operation="testEnumParameters"
+ ;;
+ testGroupParameters)
+ operation="testGroupParameters"
+ ;;
+ testInlineAdditionalProperties)
+ operation="testInlineAdditionalProperties"
+ ;;
+ testJsonFormData)
+ operation="testJsonFormData"
+ ;;
+ testClassname)
+ operation="testClassname"
+ ;;
+ addPet)
+ operation="addPet"
+ ;;
+ deletePet)
+ operation="deletePet"
+ ;;
+ findPetsByStatus)
+ operation="findPetsByStatus"
+ ;;
+ findPetsByTags)
+ operation="findPetsByTags"
+ ;;
+ getPetById)
+ operation="getPetById"
+ ;;
+ updatePet)
+ operation="updatePet"
+ ;;
+ updatePetWithForm)
+ operation="updatePetWithForm"
+ ;;
+ uploadFile)
+ operation="uploadFile"
+ ;;
+ uploadFileWithRequiredFile)
+ operation="uploadFileWithRequiredFile"
+ ;;
+ deleteOrder)
+ operation="deleteOrder"
+ ;;
+ getInventory)
+ operation="getInventory"
+ ;;
+ getOrderById)
+ operation="getOrderById"
+ ;;
+ placeOrder)
+ operation="placeOrder"
+ ;;
+ createUser)
+ operation="createUser"
+ ;;
+ createUsersWithArrayInput)
+ operation="createUsersWithArrayInput"
+ ;;
+ createUsersWithListInput)
+ operation="createUsersWithListInput"
+ ;;
+ deleteUser)
+ operation="deleteUser"
+ ;;
+ getUserByName)
+ operation="getUserByName"
+ ;;
+ loginUser)
+ operation="loginUser"
+ ;;
+ logoutUser)
+ operation="logoutUser"
+ ;;
+ updateUser)
+ operation="updateUser"
+ ;;
+ *==*)
+ # Parse body arguments and convert them into top level
+ # JSON properties passed in the body content as strings
+ if [[ "$operation" ]]; then
+ IFS='==' read -r body_key sep body_value <<< "$key"
+ body_parameters[${body_key}]="\"${body_value}\""
+ fi
+ ;;
+ *:=*)
+ # Parse body arguments and convert them into top level
+ # JSON properties passed in the body content without qoutes
+ if [[ "$operation" ]]; then
+ # ignore error about 'sep' being unused
+ # shellcheck disable=SC2034
+ IFS=':=' read -r body_key sep body_value <<< "$key"
+ body_parameters[${body_key}]=${body_value}
+ fi
+ ;;
+ +\([^=]\):*)
+ # Parse header arguments and convert them into curl
+ # only after the operation argument
+ if [[ "$operation" ]]; then
+ IFS=':' read -r header_name header_value <<< "$key"
+ #
+ # If the header key is the same as the api_key expected by API in the
+ # header, override the ${apikey_auth_credential} variable
+ #
+ if [[ $header_name == "api_key" ]]; then
+ apikey_auth_credential=$header_value
+ fi
+ header_arguments[$header_name]=$header_value
+ else
+ curl_arguments+=" $key"
+ fi
+ ;;
+ -)
+ body_content_temp_file=$(mktemp)
+ cat - > "$body_content_temp_file"
+ ;;
+ *=*)
+ # Parse operation arguments and convert them into curl
+ # only after the operation argument
+ if [[ "$operation" ]]; then
+ IFS='=' read -r parameter_name parameter_value <<< "$key"
+ if [[ -z "${operation_parameters[$parameter_name]+foo}" ]]; then
+ operation_parameters[$parameter_name]=$(url_escape "${parameter_value}")
+ else
+ operation_parameters[$parameter_name]+=":::"$(url_escape "${parameter_value}")
+ fi
+ else
+ curl_arguments+=" $key"
+ fi
+ ;;
+ *)
+ # If we are before the operation, treat the arguments as cURL arguments
+ if [[ "x$operation" == "x" ]]; then
+ # Maintain quotes around cURL arguments if necessary
+ space_regexp="[[:space:]]"
+ if [[ $key =~ $space_regexp ]]; then
+ curl_arguments+=" \"$key\""
+ else
+ curl_arguments+=" $key"
+ fi
+ fi
+ ;;
+esac
+done
+
+
+# Check if user provided host name
+if [[ -z "$host" ]]; then
+ ERROR_MSG="ERROR: No hostname provided!!! You have to provide on command line option '--host ...'"
+ exit 1
+fi
+
+# Check if user specified operation ID
+if [[ -z "$operation" ]]; then
+ ERROR_MSG="ERROR: No operation specified!!!"
+ exit 1
+fi
+
+
+# Run cURL command based on the operation ID
+case $operation in
+ 123Test@$%SpecialTags)
+ call_123Test@$%SpecialTags
+ ;;
+ fooGet)
+ call_fooGet
+ ;;
+ fakeHealthGet)
+ call_fakeHealthGet
+ ;;
+ fakeOuterBooleanSerialize)
+ call_fakeOuterBooleanSerialize
+ ;;
+ fakeOuterCompositeSerialize)
+ call_fakeOuterCompositeSerialize
+ ;;
+ fakeOuterNumberSerialize)
+ call_fakeOuterNumberSerialize
+ ;;
+ fakeOuterStringSerialize)
+ call_fakeOuterStringSerialize
+ ;;
+ testBodyWithFileSchema)
+ call_testBodyWithFileSchema
+ ;;
+ testBodyWithQueryParams)
+ call_testBodyWithQueryParams
+ ;;
+ testClientModel)
+ call_testClientModel
+ ;;
+ testEndpointParameters)
+ call_testEndpointParameters
+ ;;
+ testEnumParameters)
+ call_testEnumParameters
+ ;;
+ testGroupParameters)
+ call_testGroupParameters
+ ;;
+ testInlineAdditionalProperties)
+ call_testInlineAdditionalProperties
+ ;;
+ testJsonFormData)
+ call_testJsonFormData
+ ;;
+ testClassname)
+ call_testClassname
+ ;;
+ addPet)
+ call_addPet
+ ;;
+ deletePet)
+ call_deletePet
+ ;;
+ findPetsByStatus)
+ call_findPetsByStatus
+ ;;
+ findPetsByTags)
+ call_findPetsByTags
+ ;;
+ getPetById)
+ call_getPetById
+ ;;
+ updatePet)
+ call_updatePet
+ ;;
+ updatePetWithForm)
+ call_updatePetWithForm
+ ;;
+ uploadFile)
+ call_uploadFile
+ ;;
+ uploadFileWithRequiredFile)
+ call_uploadFileWithRequiredFile
+ ;;
+ deleteOrder)
+ call_deleteOrder
+ ;;
+ getInventory)
+ call_getInventory
+ ;;
+ getOrderById)
+ call_getOrderById
+ ;;
+ placeOrder)
+ call_placeOrder
+ ;;
+ createUser)
+ call_createUser
+ ;;
+ createUsersWithArrayInput)
+ call_createUsersWithArrayInput
+ ;;
+ createUsersWithListInput)
+ call_createUsersWithListInput
+ ;;
+ deleteUser)
+ call_deleteUser
+ ;;
+ getUserByName)
+ call_getUserByName
+ ;;
+ loginUser)
+ call_loginUser
+ ;;
+ logoutUser)
+ call_logoutUser
+ ;;
+ updateUser)
+ call_updateUser
+ ;;
+ *)
+ ERROR_MSG="ERROR: Unknown operation: $operation"
+ exit 1
+esac
diff --git a/samples/client/petstore/bash/client.sh.bash-completion b/samples/client/petstore/bash/client.sh.bash-completion
new file mode 100644
index 00000000000..f099fa5897a
--- /dev/null
+++ b/samples/client/petstore/bash/client.sh.bash-completion
@@ -0,0 +1,326 @@
+# completion -*- shell-script -*-
+
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# !
+# ! Note:
+# !
+# ! THIS SCRIPT HAS BEEN AUTOMATICALLY GENERATED USING
+# ! openapi-generator (https://openapi-generator.tech)
+# ! FROM OPENAPI SPECIFICATION IN JSON.
+# !
+# !
+# !
+# ! System wide installation:
+# !
+# ! $ sudo cp .bash-completion /etc/bash-completion.d/
+# !
+# !
+# ! User home installation (add this line to .bash_profile):
+# !
+# ! [ -r ~/.bash-completion ] && source ~/.bash-completion
+# !
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+declare -A mime_type_abbreviations
+# text/*
+mime_type_abbreviations["text"]="text/plain"
+mime_type_abbreviations["html"]="text/html"
+mime_type_abbreviations["md"]="text/x-markdown"
+mime_type_abbreviations["csv"]="text/csv"
+mime_type_abbreviations["css"]="text/css"
+mime_type_abbreviations["rtf"]="text/rtf"
+# application/*
+mime_type_abbreviations["json"]="application/json"
+mime_type_abbreviations["xml"]="application/xml"
+mime_type_abbreviations["yaml"]="application/yaml"
+mime_type_abbreviations["js"]="application/javascript"
+mime_type_abbreviations["bin"]="application/octet-stream"
+mime_type_abbreviations["rdf"]="application/rdf+xml"
+# image/*
+mime_type_abbreviations["jpg"]="image/jpeg"
+mime_type_abbreviations["png"]="image/png"
+mime_type_abbreviations["gif"]="image/gif"
+mime_type_abbreviations["bmp"]="image/bmp"
+mime_type_abbreviations["tiff"]="image/tiff"
+
+
+#
+# Check if this is OSX, if so defined custom init_completion
+#
+if [[ `uname` =~ "Darwin" ]]; then
+ __osx_init_completion()
+ {
+ COMPREPLY=()
+ _get_comp_words_by_ref cur prev words cword
+ }
+fi
+
+_()
+{
+ local cur
+ local prev
+ local words
+ local cword
+
+ # The reference of currently selected REST operation
+ local operation=""
+
+ # The list of available operation in the REST service
+ # It's modelled as an associative array for efficient key lookup
+ declare -A operations
+ operations["123Test@$%SpecialTags"]=1
+ operations["fooGet"]=1
+ operations["fakeHealthGet"]=1
+ operations["fakeOuterBooleanSerialize"]=1
+ operations["fakeOuterCompositeSerialize"]=1
+ operations["fakeOuterNumberSerialize"]=1
+ operations["fakeOuterStringSerialize"]=1
+ operations["testBodyWithFileSchema"]=1
+ operations["testBodyWithQueryParams"]=1
+ operations["testClientModel"]=1
+ operations["testEndpointParameters"]=1
+ operations["testEnumParameters"]=1
+ operations["testGroupParameters"]=1
+ operations["testInlineAdditionalProperties"]=1
+ operations["testJsonFormData"]=1
+ operations["testClassname"]=1
+ operations["addPet"]=1
+ operations["deletePet"]=1
+ operations["findPetsByStatus"]=1
+ operations["findPetsByTags"]=1
+ operations["getPetById"]=1
+ operations["updatePet"]=1
+ operations["updatePetWithForm"]=1
+ operations["uploadFile"]=1
+ operations["uploadFileWithRequiredFile"]=1
+ operations["deleteOrder"]=1
+ operations["getInventory"]=1
+ operations["getOrderById"]=1
+ operations["placeOrder"]=1
+ operations["createUser"]=1
+ operations["createUsersWithArrayInput"]=1
+ operations["createUsersWithListInput"]=1
+ operations["deleteUser"]=1
+ operations["getUserByName"]=1
+ operations["loginUser"]=1
+ operations["logoutUser"]=1
+ operations["updateUser"]=1
+
+ # An associative array of operations to their parameters
+ # Only include path, query and header parameters
+ declare -A operation_parameters
+ operation_parameters["123Test@$%SpecialTags"]=""
+ operation_parameters["fooGet"]=""
+ operation_parameters["fakeHealthGet"]=""
+ operation_parameters["fakeOuterBooleanSerialize"]=""
+ operation_parameters["fakeOuterCompositeSerialize"]=""
+ operation_parameters["fakeOuterNumberSerialize"]=""
+ operation_parameters["fakeOuterStringSerialize"]=""
+ operation_parameters["testBodyWithFileSchema"]=""
+ operation_parameters["testBodyWithQueryParams"]="query= "
+ operation_parameters["testClientModel"]=""
+ operation_parameters["testEndpointParameters"]=""
+ operation_parameters["testEnumParameters"]="enum_query_string_array= enum_query_string= enum_query_integer= enum_query_double= enum_header_string_array: enum_header_string: "
+ operation_parameters["testGroupParameters"]="required_string_group= required_int64_group= string_group= int64_group= required_boolean_group: boolean_group: "
+ operation_parameters["testInlineAdditionalProperties"]=""
+ operation_parameters["testJsonFormData"]=""
+ operation_parameters["testClassname"]=""
+ operation_parameters["addPet"]=""
+ operation_parameters["deletePet"]="petId= api_key: "
+ operation_parameters["findPetsByStatus"]="status= "
+ operation_parameters["findPetsByTags"]="tags= "
+ operation_parameters["getPetById"]="petId= "
+ operation_parameters["updatePet"]=""
+ operation_parameters["updatePetWithForm"]="petId= "
+ operation_parameters["uploadFile"]="petId= "
+ operation_parameters["uploadFileWithRequiredFile"]="petId= "
+ operation_parameters["deleteOrder"]="order_id= "
+ operation_parameters["getInventory"]=""
+ operation_parameters["getOrderById"]="order_id= "
+ operation_parameters["placeOrder"]=""
+ operation_parameters["createUser"]=""
+ operation_parameters["createUsersWithArrayInput"]=""
+ operation_parameters["createUsersWithListInput"]=""
+ operation_parameters["deleteUser"]="username= "
+ operation_parameters["getUserByName"]="username= "
+ operation_parameters["loginUser"]="username= password= "
+ operation_parameters["logoutUser"]=""
+ operation_parameters["updateUser"]="username= "
+
+ # An associative array of possible values for enum parameters
+ declare -A operation_parameters_enum_values
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+
+ #
+ # Check if this is OSX and use special __osx_init_completion function
+ #
+ if [[ `uname` =~ "Darwin" ]]; then
+ __osx_init_completion || return
+ else
+ _init_completion -s || return
+ fi
+
+
+ # Check if operation is already in the command line provided
+ for word in "${words[@]}"; do
+ if [[ -n $word && ${operations[$word]} ]]; then
+ operation="${word}"
+ fi
+ done
+
+ if [[ -z $operation ]]; then
+ case $prev in
+ --ciphers|--connect-timeout|-C|--continue-at|-F|--form|--form-string|\
+ --ftp-account|--ftp-alternative-to-user|-P|--ftp-port|-H|--header|-h|\
+ --help|--hostpubmd5|--keepalive-time|--krb|--limit-rate|--local-port|\
+ --mail-from|--mail-rcpt|--max-filesize|--max-redirs|-m|--max-time|\
+ --pass|--proto|--proto-redir|--proxy-user|--proxy1.0|-Q|--quote|-r|\
+ --range|-X|--request|--retry|--retry-delay|--retry-max-time|\
+ --socks5-gssapi-service|-t|--telnet-option|--tftp-blksize|-z|\
+ --time-cond|--url|-u|--user|-A|--user-agent|-V|--version|-w|\
+ --write-out|--resolve|--tlsuser|--tlspassword|--about)
+ return
+ ;;
+ -K|--config|-b|--cookie|-c|--cookie-jar|-D|--dump-header|--egd-file|\
+ --key|--libcurl|-o|--output|--random-file|-T|--upload-file|--trace|\
+ --trace-ascii|--netrc-file)
+ _filedir
+ return
+ ;;
+ --cacert|-E|--cert)
+ _filedir '@(c?(e)rt|cer|pem|der)'
+ return
+ ;;
+ --capath)
+ _filedir -d
+ return
+ ;;
+ --cert-type|--key-type)
+ COMPREPLY=( $( compgen -W 'DER PEM ENG' -- "$cur" ) )
+ return
+ ;;
+ --crlfile)
+ _filedir crl
+ return
+ ;;
+ -d|--data|--data-ascii|--data-binary|--data-urlencode)
+ if [[ $cur == \@* ]]; then
+ cur=${cur:1}
+ _filedir
+ COMPREPLY=( "${COMPREPLY[@]/#/@}" )
+ fi
+ return
+ ;;
+ --delegation)
+ COMPREPLY=( $( compgen -W 'none policy always' -- "$cur" ) )
+ return
+ ;;
+ --engine)
+ COMPREPLY=( $( compgen -W 'list' -- "$cur" ) )
+ return
+ ;;
+ --ftp-method)
+ COMPREPLY=( $( compgen -W 'multicwd nocwd singlecwd' -- "$cur" ) )
+ return
+ ;;
+ --ftp-ssl-ccc-mode)
+ COMPREPLY=( $( compgen -W 'active passive' -- "$cur" ) )
+ return
+ ;;
+ --interface)
+ _available_interfaces -a
+ return
+ ;;
+ -x|--proxy|--socks4|--socks4a|--socks5|--socks5-hostname)
+ _known_hosts_real
+ return
+ ;;
+ --pubkey)
+ _filedir pub
+ return
+ ;;
+ --stderr)
+ COMPREPLY=( $( compgen -W '-' -- "$cur" ) )
+ _filedir
+ return
+ ;;
+ --tlsauthtype)
+ COMPREPLY=( $( compgen -W 'SRP' -- "$cur" ) )
+ return
+ ;;
+ --host)
+ COMPREPLY=( $( compgen -W 'http:// https://' -- "$cur" ) )
+ return
+ ;;
+ -ct|--content-type|-ac|--accept)
+ COMPREPLY=( $( compgen -W '${!mime_type_abbreviations[*]}' -- "$cur" ) )
+ return
+ ;;
+ esac
+ fi
+
+ #
+ # Complete the server address based on ~/.ssh/known_hosts
+ # and ~/.ssh/config
+ #
+ local prefix=${COMP_WORDS[COMP_CWORD-2]}
+ local colon=${COMP_WORDS[COMP_CWORD-1]}
+ if [[ "$colon" == ":" && ( $prefix == "https" || $prefix == "http" ) ]]; then
+ COMPREPLY=()
+ local comp_ssh_hosts=`[[ -f ~/.ssh/known_hosts ]] && \
+ ( cat ~/.ssh/known_hosts | \
+ grep '^[a-zA-Z0-9]' | \
+ cut -f 1 -d ' ' | \
+ sed -e s/,.*//g | \
+ grep -v ^# | \
+ uniq | \
+ grep -v "\[" ) ;
+ [[ -f ~/.ssh/config ]] && \
+ ( cat ~/.ssh/config | \
+ grep "^Host " | \
+ awk '{print $2}' )`
+ COMPREPLY=( $( compgen -P '//' -W '${comp_ssh_hosts}' -- "${cur:2}") )
+ return
+ fi
+
+ #
+ # Complete the and cURL's arguments
+ #
+ if [[ $cur == -* ]]; then
+ COMPREPLY=( $( compgen -W '$(_parse_help curl) $(_parse_help $1)' -- "$cur" ) )
+ return
+ fi
+
+ #
+ # If the argument starts with a letter this could be either an operation
+ # or an operation parameter
+ # When $cur is empty, suggest the list of operations by default
+ #
+ if [[ $cur =~ ^[A-Za-z_0-9]* ]]; then
+ # If operation has not been yet selected, suggest the list of operations
+ # otherwise suggest arguments of this operation as declared in the
+ # OpenAPI specification
+ if [[ -z $operation ]]; then
+ COMPREPLY=( $(compgen -W '${!operations[*]}' -- ${cur}) )
+ else
+ COMPREPLY=( $(compgen -W '${operation_parameters[$operation]}' -- ${cur}) )
+ compopt -o nospace
+ fi
+ return
+ fi
+
+} &&
+complete -F _
+
+# ex: ts=4 sw=4 et filetype=sh
diff --git a/samples/client/petstore/bash/docs/$special[modelName].md b/samples/client/petstore/bash/docs/$special[modelName].md
new file mode 100644
index 00000000000..884128c8b39
--- /dev/null
+++ b/samples/client/petstore/bash/docs/$special[modelName].md
@@ -0,0 +1,10 @@
+# $special[model.name]
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**DollarspecialLeft_Square_BracketpropertyPeriodnameRight_Square_Bracket** | **integer** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/200Response.md b/samples/client/petstore/bash/docs/200Response.md
new file mode 100644
index 00000000000..b575df6f2eb
--- /dev/null
+++ b/samples/client/petstore/bash/docs/200Response.md
@@ -0,0 +1,11 @@
+# 200_response
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **integer** | | [optional] [default to null]
+**class** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesAnyType.md b/samples/client/petstore/bash/docs/AdditionalPropertiesAnyType.md
new file mode 100644
index 00000000000..dfb55fb51b4
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesAnyType.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesAnyType
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesArray.md b/samples/client/petstore/bash/docs/AdditionalPropertiesArray.md
new file mode 100644
index 00000000000..5edd62c9050
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesArray.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesArray
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesBoolean.md b/samples/client/petstore/bash/docs/AdditionalPropertiesBoolean.md
new file mode 100644
index 00000000000..3223701aa4c
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesBoolean.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesBoolean
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesClass.md b/samples/client/petstore/bash/docs/AdditionalPropertiesClass.md
index 70fe49c1edf..5b1ed2dce63 100644
--- a/samples/client/petstore/bash/docs/AdditionalPropertiesClass.md
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesClass.md
@@ -3,8 +3,17 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**map_property** | **map[String, string]** | | [optional] [default to null]
-**map_of_map_property** | **map[String, map[String, string]]** | | [optional] [default to null]
+**mapUnderscorestring** | **map[String, string]** | | [optional] [default to null]
+**mapUnderscorenumber** | **map[String, integer]** | | [optional] [default to null]
+**mapUnderscoreinteger** | **map[String, integer]** | | [optional] [default to null]
+**mapUnderscoreboolean** | **map[String, boolean]** | | [optional] [default to null]
+**mapUnderscorearrayUnderscoreinteger** | **map[String, array[integer]]** | | [optional] [default to null]
+**mapUnderscorearrayUnderscoreanytype** | **map[String, array[map]]** | | [optional] [default to null]
+**mapUnderscoremapUnderscorestring** | **map[String, map[String, string]]** | | [optional] [default to null]
+**mapUnderscoremapUnderscoreanytype** | **map[String, map[String, map]]** | | [optional] [default to null]
+**anytypeUnderscore1** | [**map**](.md) | | [optional] [default to null]
+**anytypeUnderscore2** | [**map**](.md) | | [optional] [default to null]
+**anytypeUnderscore3** | [**map**](.md) | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesInteger.md b/samples/client/petstore/bash/docs/AdditionalPropertiesInteger.md
new file mode 100644
index 00000000000..c95116042e2
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesInteger.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesInteger
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesNumber.md b/samples/client/petstore/bash/docs/AdditionalPropertiesNumber.md
new file mode 100644
index 00000000000..5ba50ecfe5e
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesNumber.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesNumber
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesObject.md b/samples/client/petstore/bash/docs/AdditionalPropertiesObject.md
new file mode 100644
index 00000000000..5694b15649a
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesObject.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesObject
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AdditionalPropertiesString.md b/samples/client/petstore/bash/docs/AdditionalPropertiesString.md
new file mode 100644
index 00000000000..f39e11d88e5
--- /dev/null
+++ b/samples/client/petstore/bash/docs/AdditionalPropertiesString.md
@@ -0,0 +1,10 @@
+# AdditionalPropertiesString
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/AnotherFakeApi.md b/samples/client/petstore/bash/docs/AnotherFakeApi.md
index f5b70880abc..f93603717d2 100644
--- a/samples/client/petstore/bash/docs/AnotherFakeApi.md
+++ b/samples/client/petstore/bash/docs/AnotherFakeApi.md
@@ -4,25 +4,28 @@ All URIs are relative to */v2*
Method | HTTP request | Description
------------- | ------------- | -------------
-[**testSpecialTags**](AnotherFakeApi.md#testSpecialTags) | **PATCH** /another-fake/dummy | To test special tags
+[**123Test@$%SpecialTags**](AnotherFakeApi.md#123Test@$%SpecialTags) | **PATCH** /another-fake/dummy | To test special tags
-## **testSpecialTags**
+
+## 123Test@$%SpecialTags
To test special tags
-To test special tags
+To test special tags and operation ID starting with number
### Example
+
```bash
-petstore-cli testSpecialTags
+petstore-cli 123Test@$%SpecialTags
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **client** | [**Client**](Client.md) | client model |
+ **body** | [**Client**](Client.md) | client model |
### Return type
@@ -34,8 +37,8 @@ No authorization required
### HTTP request headers
- - **Content-Type**: application/json
- - **Accept**: application/json
+- **Content-Type**: application/json
+- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/ArrayTest.md b/samples/client/petstore/bash/docs/ArrayTest.md
index 6c86d88f309..ee047cb7370 100644
--- a/samples/client/petstore/bash/docs/ArrayTest.md
+++ b/samples/client/petstore/bash/docs/ArrayTest.md
@@ -3,9 +3,9 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**array_of_string** | **array[string]** | | [optional] [default to null]
-**array_array_of_integer** | **array[array[integer]]** | | [optional] [default to null]
-**array_array_of_model** | **array[array[ReadOnlyFirst]]** | | [optional] [default to null]
+**arrayUnderscoreofUnderscorestring** | **array[string]** | | [optional] [default to null]
+**arrayUnderscorearrayUnderscoreofUnderscoreinteger** | **array[array[integer]]** | | [optional] [default to null]
+**arrayUnderscorearrayUnderscoreofUnderscoremodel** | **array[array[ReadOnlyFirst]]** | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/Capitalization.md b/samples/client/petstore/bash/docs/Capitalization.md
index 362258aa0d4..3a6e754d44d 100644
--- a/samples/client/petstore/bash/docs/Capitalization.md
+++ b/samples/client/petstore/bash/docs/Capitalization.md
@@ -5,10 +5,10 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**smallCamel** | **string** | | [optional] [default to null]
**CapitalCamel** | **string** | | [optional] [default to null]
-**small_Snake** | **string** | | [optional] [default to null]
-**Capital_Snake** | **string** | | [optional] [default to null]
-**SCA_ETH_Flow_Points** | **string** | | [optional] [default to null]
-**ATT_NAME** | **string** | | [optional] [default to null]
+**smallUnderscoreSnake** | **string** | | [optional] [default to null]
+**CapitalUnderscoreSnake** | **string** | | [optional] [default to null]
+**SCAUnderscoreETHUnderscoreFlowUnderscorePoints** | **string** | | [optional] [default to null]
+**ATTUnderscoreNAME** | **string** | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/CatAllOf.md b/samples/client/petstore/bash/docs/CatAllOf.md
new file mode 100644
index 00000000000..99ba1bec860
--- /dev/null
+++ b/samples/client/petstore/bash/docs/CatAllOf.md
@@ -0,0 +1,10 @@
+# Cat_allOf
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**declawed** | **boolean** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/Category.md b/samples/client/petstore/bash/docs/Category.md
index 5af29e81851..25078d7ad51 100644
--- a/samples/client/petstore/bash/docs/Category.md
+++ b/samples/client/petstore/bash/docs/Category.md
@@ -4,7 +4,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **integer** | | [optional] [default to null]
-**name** | **string** | | [optional] [default to null]
+**name** | **string** | | [default to default-name]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/ClassModel.md b/samples/client/petstore/bash/docs/ClassModel.md
index 7979502a642..2e1cda38387 100644
--- a/samples/client/petstore/bash/docs/ClassModel.md
+++ b/samples/client/petstore/bash/docs/ClassModel.md
@@ -3,7 +3,7 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**_class** | **string** | | [optional] [default to null]
+**Underscoreclass** | **string** | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/DefaultApi.md b/samples/client/petstore/bash/docs/DefaultApi.md
new file mode 100644
index 00000000000..5ef9511145b
--- /dev/null
+++ b/samples/client/petstore/bash/docs/DefaultApi.md
@@ -0,0 +1,39 @@
+# DefaultApi
+
+All URIs are relative to */v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**fooGet**](DefaultApi.md#fooGet) | **GET** /foo |
+
+
+
+## fooGet
+
+
+
+### Example
+
+```bash
+ fooGet
+```
+
+### Parameters
+
+This endpoint does not need any parameter.
+
+### Return type
+
+[**InlineResponseDefault**](InlineResponseDefault.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: Not Applicable
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/bash/docs/DogAllOf.md b/samples/client/petstore/bash/docs/DogAllOf.md
new file mode 100644
index 00000000000..2bf2fdd3478
--- /dev/null
+++ b/samples/client/petstore/bash/docs/DogAllOf.md
@@ -0,0 +1,10 @@
+# Dog_allOf
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**breed** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/EnumArrays.md b/samples/client/petstore/bash/docs/EnumArrays.md
index 70798f4be67..965ac8323cc 100644
--- a/samples/client/petstore/bash/docs/EnumArrays.md
+++ b/samples/client/petstore/bash/docs/EnumArrays.md
@@ -3,8 +3,8 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**just_symbol** | **string** | | [optional] [default to null]
-**array_enum** | **array[string]** | | [optional] [default to null]
+**justUnderscoresymbol** | **string** | | [optional] [default to null]
+**arrayUnderscoreenum** | **array[string]** | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/EnumTest.md b/samples/client/petstore/bash/docs/EnumTest.md
new file mode 100644
index 00000000000..30b30efa730
--- /dev/null
+++ b/samples/client/petstore/bash/docs/EnumTest.md
@@ -0,0 +1,14 @@
+# Enum_Test
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**enumUnderscorestring** | **string** | | [optional] [default to null]
+**enumUnderscorestringUnderscorerequired** | **string** | | [default to null]
+**enumUnderscoreinteger** | **integer** | | [optional] [default to null]
+**enumUnderscorenumber** | **float** | | [optional] [default to null]
+**outerEnum** | [**OuterEnum**](OuterEnum.md) | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/FakeApi.md b/samples/client/petstore/bash/docs/FakeApi.md
index 458397e6727..0f9bf109d34 100644
--- a/samples/client/petstore/bash/docs/FakeApi.md
+++ b/samples/client/petstore/bash/docs/FakeApi.md
@@ -4,10 +4,12 @@ All URIs are relative to */v2*
Method | HTTP request | Description
------------- | ------------- | -------------
+[**createXmlItem**](FakeApi.md#createXmlItem) | **POST** /fake/create_xml_item | creates an XmlItem
[**fakeOuterBooleanSerialize**](FakeApi.md#fakeOuterBooleanSerialize) | **POST** /fake/outer/boolean |
[**fakeOuterCompositeSerialize**](FakeApi.md#fakeOuterCompositeSerialize) | **POST** /fake/outer/composite |
[**fakeOuterNumberSerialize**](FakeApi.md#fakeOuterNumberSerialize) | **POST** /fake/outer/number |
[**fakeOuterStringSerialize**](FakeApi.md#fakeOuterStringSerialize) | **POST** /fake/outer/string |
+[**testBodyWithFileSchema**](FakeApi.md#testBodyWithFileSchema) | **PUT** /fake/body-with-file-schema |
[**testBodyWithQueryParams**](FakeApi.md#testBodyWithQueryParams) | **PUT** /fake/body-with-query-params |
[**testClientModel**](FakeApi.md#testClientModel) | **PATCH** /fake | To test \"client\" model
[**testEndpointParameters**](FakeApi.md#testEndpointParameters) | **POST** /fake | Fake endpoint for testing various parameters
@@ -15,23 +17,62 @@ Method | HTTP request | Description
偽のエンドポイント
가짜 엔드 포인트
[**testEnumParameters**](FakeApi.md#testEnumParameters) | **GET** /fake | To test enum parameters
+[**testGroupParameters**](FakeApi.md#testGroupParameters) | **DELETE** /fake | Fake endpoint to test group parameters (optional)
[**testInlineAdditionalProperties**](FakeApi.md#testInlineAdditionalProperties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties
[**testJsonFormData**](FakeApi.md#testJsonFormData) | **GET** /fake/jsonFormData | test json serialization of form data
-## **fakeOuterBooleanSerialize**
+
+## createXmlItem
+
+creates an XmlItem
+
+this route creates an XmlItem
+
+### Example
+
+```bash
+petstore-cli createXmlItem
+```
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **xmlItem** | [**XmlItem**](XmlItem.md) | XmlItem Body |
+
+### Return type
+
+(empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/xml, application/xml; charset=utf-8, application/xml; charset=utf-16, text/xml, text/xml; charset=utf-8, text/xml; charset=utf-16
+- **Accept**: Not Applicable
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## fakeOuterBooleanSerialize
Test serialization of outer boolean types
### Example
+
```bash
petstore-cli fakeOuterBooleanSerialize
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | **boolean** | Input boolean as post body | [optional]
@@ -46,27 +87,30 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: */*
+- **Content-Type**: Not Applicable
+- **Accept**: */*
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **fakeOuterCompositeSerialize**
+
+## fakeOuterCompositeSerialize
Test serialization of object with outer number type
### Example
+
```bash
petstore-cli fakeOuterCompositeSerialize
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **outerComposite** | [**OuterComposite**](OuterComposite.md) | Input composite as post body | [optional]
+ **body** | [**OuterComposite**](OuterComposite.md) | Input composite as post body | [optional]
### Return type
@@ -78,24 +122,27 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: */*
+- **Content-Type**: Not Applicable
+- **Accept**: */*
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **fakeOuterNumberSerialize**
+
+## fakeOuterNumberSerialize
Test serialization of outer number types
### Example
+
```bash
petstore-cli fakeOuterNumberSerialize
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | **integer** | Input number as post body | [optional]
@@ -110,24 +157,27 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: */*
+- **Content-Type**: Not Applicable
+- **Accept**: */*
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **fakeOuterStringSerialize**
+
+## fakeOuterStringSerialize
Test serialization of outer string types
### Example
+
```bash
petstore-cli fakeOuterStringSerialize
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | **string** | Input string as post body | [optional]
@@ -142,26 +192,30 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: */*
+- **Content-Type**: Not Applicable
+- **Accept**: */*
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **testBodyWithQueryParams**
+
+## testBodyWithFileSchema
+For this test, the body for this request much reference a schema named 'File'.
+
### Example
+
```bash
-petstore-cli testBodyWithQueryParams query=value
+petstore-cli testBodyWithFileSchema
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **query** | **string** | |
- **user** | [**User**](User.md) | |
+ **body** | [**FileSchemaTestClass**](FileSchemaTestClass.md) | |
### Return type
@@ -173,27 +227,64 @@ No authorization required
### HTTP request headers
- - **Content-Type**: application/json
- - **Accept**: Not Applicable
+- **Content-Type**: application/json
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **testClientModel**
+
+## testBodyWithQueryParams
+
+
+
+### Example
+
+```bash
+petstore-cli testBodyWithQueryParams query=value
+```
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **query** | **string** | | [default to null]
+ **body** | [**User**](User.md) | |
+
+### Return type
+
+(empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: Not Applicable
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## testClientModel
To test \"client\" model
To test \"client\" model
### Example
+
```bash
petstore-cli testClientModel
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **client** | [**Client**](Client.md) | client model |
+ **body** | [**Client**](Client.md) | client model |
### Return type
@@ -205,12 +296,13 @@ No authorization required
### HTTP request headers
- - **Content-Type**: application/json
- - **Accept**: application/json
+- **Content-Type**: application/json
+- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **testEndpointParameters**
+
+## testEndpointParameters
Fake endpoint for testing various parameters
假端點
@@ -223,12 +315,14 @@ Fake endpoint for testing various parameters
가짜 엔드 포인트
### Example
+
```bash
petstore-cli testEndpointParameters
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**number** | **integer** | None | [default to null]
@@ -256,33 +350,36 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: application/x-www-form-urlencoded
- - **Accept**: Not Applicable
+- **Content-Type**: application/x-www-form-urlencoded
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **testEnumParameters**
+
+## testEnumParameters
To test enum parameters
To test enum parameters
### Example
+
```bash
petstore-cli testEnumParameters enum_header_string_array:value enum_header_string:value Specify as: enum_query_string_array="value1,value2,..." enum_query_string=value enum_query_integer=value enum_query_double=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **enumHeaderStringArray** | [**array[string]**](string.md) | Header parameter enum test (string array) | [optional]
+ **enumHeaderStringArray** | [**array[string]**](string.md) | Header parameter enum test (string array) | [optional] [default to null]
**enumHeaderString** | **string** | Header parameter enum test (string) | [optional] [default to -efg]
- **enumQueryStringArray** | [**array[string]**](string.md) | Query parameter enum test (string array) | [optional]
+ **enumQueryStringArray** | [**array[string]**](string.md) | Query parameter enum test (string array) | [optional] [default to null]
**enumQueryString** | **string** | Query parameter enum test (string) | [optional] [default to -efg]
- **enumQueryInteger** | **integer** | Query parameter enum test (double) | [optional]
- **enumQueryDouble** | **float** | Query parameter enum test (double) | [optional]
- **enumFormStringArray** | **array[string]** | Form parameter enum test (string array) | [optional] [default to $]
+ **enumQueryInteger** | **integer** | Query parameter enum test (double) | [optional] [default to null]
+ **enumQueryDouble** | **float** | Query parameter enum test (double) | [optional] [default to null]
+ **enumFormStringArray** | [**array[string]**](string.md) | Form parameter enum test (string array) | [optional] [default to $]
**enumFormString** | **string** | Form parameter enum test (string) | [optional] [default to -efg]
### Return type
@@ -295,25 +392,35 @@ No authorization required
### HTTP request headers
- - **Content-Type**: application/x-www-form-urlencoded
- - **Accept**: Not Applicable
+- **Content-Type**: application/x-www-form-urlencoded
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **testInlineAdditionalProperties**
-test inline additionalProperties
+## testGroupParameters
+
+Fake endpoint to test group parameters (optional)
+
+Fake endpoint to test group parameters (optional)
### Example
+
```bash
-petstore-cli testInlineAdditionalProperties
+petstore-cli testGroupParameters required_string_group=value required_boolean_group:value required_int64_group=value string_group=value boolean_group:value int64_group=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **requestBody** | [**map[String, string]**](string.md) | request body |
+ **requiredStringGroup** | **integer** | Required String in group parameters | [default to null]
+ **requiredBooleanGroup** | **boolean** | Required Boolean in group parameters | [default to null]
+ **requiredInt64Group** | **integer** | Required Integer in group parameters | [default to null]
+ **stringGroup** | **integer** | String in group parameters | [optional] [default to null]
+ **booleanGroup** | **boolean** | Boolean in group parameters | [optional] [default to null]
+ **int64Group** | **integer** | Integer in group parameters | [optional] [default to null]
### Return type
@@ -325,22 +432,58 @@ No authorization required
### HTTP request headers
- - **Content-Type**: application/json
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **testJsonFormData**
+
+## testInlineAdditionalProperties
+
+test inline additionalProperties
+
+### Example
+
+```bash
+petstore-cli testInlineAdditionalProperties
+```
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **param** | [**map[String, string]**](string.md) | request body |
+
+### Return type
+
+(empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+- **Content-Type**: application/json
+- **Accept**: Not Applicable
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## testJsonFormData
test json serialization of form data
### Example
+
```bash
petstore-cli testJsonFormData
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**param** | **string** | field1 | [default to null]
@@ -356,8 +499,8 @@ No authorization required
### HTTP request headers
- - **Content-Type**: application/x-www-form-urlencoded
- - **Accept**: Not Applicable
+- **Content-Type**: application/x-www-form-urlencoded
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/FakeClassnameTags123Api.md b/samples/client/petstore/bash/docs/FakeClassnameTags123Api.md
index 6499a704868..19b3d386d38 100644
--- a/samples/client/petstore/bash/docs/FakeClassnameTags123Api.md
+++ b/samples/client/petstore/bash/docs/FakeClassnameTags123Api.md
@@ -7,22 +7,25 @@ Method | HTTP request | Description
[**testClassname**](FakeClassnameTags123Api.md#testClassname) | **PATCH** /fake_classname_test | To test class name in snake case
-## **testClassname**
+
+## testClassname
To test class name in snake case
To test class name in snake case
### Example
+
```bash
petstore-cli testClassname
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **client** | [**Client**](Client.md) | client model |
+ **body** | [**Client**](Client.md) | client model |
### Return type
@@ -34,8 +37,8 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: application/json
- - **Accept**: application/json
+- **Content-Type**: application/json
+- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/FileSchemaTestClass.md b/samples/client/petstore/bash/docs/FileSchemaTestClass.md
new file mode 100644
index 00000000000..47de5903a44
--- /dev/null
+++ b/samples/client/petstore/bash/docs/FileSchemaTestClass.md
@@ -0,0 +1,11 @@
+# FileSchemaTestClass
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**file** | [**File**](File.md) | | [optional] [default to null]
+**files** | [**array[File]**](File.md) | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/Foo.md b/samples/client/petstore/bash/docs/Foo.md
new file mode 100644
index 00000000000..69ef867a797
--- /dev/null
+++ b/samples/client/petstore/bash/docs/Foo.md
@@ -0,0 +1,10 @@
+# Foo
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**bar** | **string** | | [optional] [default to bar]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/FormatTest.md b/samples/client/petstore/bash/docs/FormatTest.md
new file mode 100644
index 00000000000..8f73bb59bbc
--- /dev/null
+++ b/samples/client/petstore/bash/docs/FormatTest.md
@@ -0,0 +1,22 @@
+# format_test
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**integer** | **integer** | | [optional] [default to null]
+**int32** | **integer** | | [optional] [default to null]
+**int64** | **integer** | | [optional] [default to null]
+**number** | **integer** | | [default to null]
+**float** | **float** | | [optional] [default to null]
+**double** | **float** | | [optional] [default to null]
+**string** | **string** | | [optional] [default to null]
+**byte** | **string** | | [default to null]
+**binary** | **binary** | | [optional] [default to null]
+**date** | **string** | | [default to null]
+**dateTime** | **string** | | [optional] [default to null]
+**uuid** | **string** | | [optional] [default to null]
+**password** | **string** | | [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/HealthCheckResult.md b/samples/client/petstore/bash/docs/HealthCheckResult.md
new file mode 100644
index 00000000000..fcfa835d21e
--- /dev/null
+++ b/samples/client/petstore/bash/docs/HealthCheckResult.md
@@ -0,0 +1,10 @@
+# HealthCheckResult
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**NullableMessage** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineObject.md b/samples/client/petstore/bash/docs/InlineObject.md
new file mode 100644
index 00000000000..4606c548920
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineObject.md
@@ -0,0 +1,11 @@
+# inline_object
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **string** | | [optional] [default to null]
+**status** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineObject1.md b/samples/client/petstore/bash/docs/InlineObject1.md
new file mode 100644
index 00000000000..13ab3ed546d
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineObject1.md
@@ -0,0 +1,11 @@
+# inline_object_1
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**additionalMetadata** | **string** | | [optional] [default to null]
+**file** | **binary** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineObject2.md b/samples/client/petstore/bash/docs/InlineObject2.md
new file mode 100644
index 00000000000..3ad0a1d2e0c
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineObject2.md
@@ -0,0 +1,11 @@
+# inline_object_2
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**enumUnderscoreformUnderscorestringUnderscorearray** | **array[string]** | | [optional] [default to null]
+**enumUnderscoreformUnderscorestring** | **string** | | [optional] [default to -efg]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineObject3.md b/samples/client/petstore/bash/docs/InlineObject3.md
new file mode 100644
index 00000000000..080c4051cc4
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineObject3.md
@@ -0,0 +1,23 @@
+# inline_object_3
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**integer** | **integer** | | [optional] [default to null]
+**int32** | **integer** | | [optional] [default to null]
+**int64** | **integer** | | [optional] [default to null]
+**number** | **integer** | | [default to null]
+**float** | **float** | | [optional] [default to null]
+**double** | **float** | | [default to null]
+**string** | **string** | | [optional] [default to null]
+**patternUnderscorewithoutUnderscoredelimiter** | **string** | | [default to null]
+**byte** | **string** | | [default to null]
+**binary** | **binary** | | [optional] [default to null]
+**date** | **string** | | [optional] [default to null]
+**dateTime** | **string** | | [optional] [default to null]
+**password** | **string** | | [optional] [default to null]
+**callback** | **string** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineObject4.md b/samples/client/petstore/bash/docs/InlineObject4.md
new file mode 100644
index 00000000000..a75f87f5fef
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineObject4.md
@@ -0,0 +1,11 @@
+# inline_object_4
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**param** | **string** | | [default to null]
+**param2** | **string** | | [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineObject5.md b/samples/client/petstore/bash/docs/InlineObject5.md
new file mode 100644
index 00000000000..89121b040e2
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineObject5.md
@@ -0,0 +1,11 @@
+# inline_object_5
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**additionalMetadata** | **string** | | [optional] [default to null]
+**requiredFile** | **binary** | | [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/InlineResponseDefault.md b/samples/client/petstore/bash/docs/InlineResponseDefault.md
new file mode 100644
index 00000000000..ef6d219bac4
--- /dev/null
+++ b/samples/client/petstore/bash/docs/InlineResponseDefault.md
@@ -0,0 +1,10 @@
+# inline_response_default
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**string** | [**Foo**](Foo.md) | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/MapTest.md b/samples/client/petstore/bash/docs/MapTest.md
index 31ca86b91c1..e4ed4a23382 100644
--- a/samples/client/petstore/bash/docs/MapTest.md
+++ b/samples/client/petstore/bash/docs/MapTest.md
@@ -3,8 +3,10 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**map_map_of_string** | **map[String, map[String, string]]** | | [optional] [default to null]
-**map_of_enum_string** | **map[String, string]** | | [optional] [default to null]
+**mapUnderscoremapUnderscoreofUnderscorestring** | **map[String, map[String, string]]** | | [optional] [default to null]
+**mapUnderscoreofUnderscoreenumUnderscorestring** | **map[String, string]** | | [optional] [default to null]
+**directUnderscoremap** | **map[String, boolean]** | | [optional] [default to null]
+**indirectUnderscoremap** | **map[String, boolean]** | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/Name.md b/samples/client/petstore/bash/docs/Name.md
index 8f59de26d01..5c3afc21594 100644
--- a/samples/client/petstore/bash/docs/Name.md
+++ b/samples/client/petstore/bash/docs/Name.md
@@ -4,7 +4,7 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**name** | **integer** | | [default to null]
-**snake_case** | **integer** | | [optional] [default to null]
+**snakeUnderscorecase** | **integer** | | [optional] [default to null]
**property** | **string** | | [optional] [default to null]
**123Number** | **integer** | | [optional] [default to null]
diff --git a/samples/client/petstore/bash/docs/NullableClass.md b/samples/client/petstore/bash/docs/NullableClass.md
new file mode 100644
index 00000000000..8b85103f58f
--- /dev/null
+++ b/samples/client/petstore/bash/docs/NullableClass.md
@@ -0,0 +1,21 @@
+# NullableClass
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**integerUnderscoreprop** | **integer** | | [optional] [default to null]
+**numberUnderscoreprop** | **integer** | | [optional] [default to null]
+**booleanUnderscoreprop** | **boolean** | | [optional] [default to null]
+**stringUnderscoreprop** | **string** | | [optional] [default to null]
+**dateUnderscoreprop** | **string** | | [optional] [default to null]
+**datetimeUnderscoreprop** | **string** | | [optional] [default to null]
+**arrayUnderscorenullableUnderscoreprop** | **array[map]** | | [optional] [default to null]
+**arrayUnderscoreandUnderscoreitemsUnderscorenullableUnderscoreprop** | **array[map]** | | [optional] [default to null]
+**arrayUnderscoreitemsUnderscorenullable** | **array[map]** | | [optional] [default to null]
+**objectUnderscorenullableUnderscoreprop** | **map[String, map]** | | [optional] [default to null]
+**objectUnderscoreandUnderscoreitemsUnderscorenullableUnderscoreprop** | **map[String, map]** | | [optional] [default to null]
+**objectUnderscoreitemsUnderscorenullable** | **map[String, map]** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/OuterComposite.md b/samples/client/petstore/bash/docs/OuterComposite.md
index 2a4eb8388e8..afe7b21b8d7 100644
--- a/samples/client/petstore/bash/docs/OuterComposite.md
+++ b/samples/client/petstore/bash/docs/OuterComposite.md
@@ -3,9 +3,9 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**my_number** | **integer** | | [optional] [default to null]
-**my_string** | **string** | | [optional] [default to null]
-**my_boolean** | **boolean** | | [optional] [default to null]
+**myUnderscorenumber** | **integer** | | [optional] [default to null]
+**myUnderscorestring** | **string** | | [optional] [default to null]
+**myUnderscoreboolean** | **boolean** | | [optional] [default to null]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/OuterEnumDefaultValue.md b/samples/client/petstore/bash/docs/OuterEnumDefaultValue.md
new file mode 100644
index 00000000000..1487a710393
--- /dev/null
+++ b/samples/client/petstore/bash/docs/OuterEnumDefaultValue.md
@@ -0,0 +1,9 @@
+# OuterEnumDefaultValue
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/OuterEnumInteger.md b/samples/client/petstore/bash/docs/OuterEnumInteger.md
new file mode 100644
index 00000000000..8be15eee6a2
--- /dev/null
+++ b/samples/client/petstore/bash/docs/OuterEnumInteger.md
@@ -0,0 +1,9 @@
+# OuterEnumInteger
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/OuterEnumIntegerDefaultValue.md b/samples/client/petstore/bash/docs/OuterEnumIntegerDefaultValue.md
new file mode 100644
index 00000000000..27d962f106e
--- /dev/null
+++ b/samples/client/petstore/bash/docs/OuterEnumIntegerDefaultValue.md
@@ -0,0 +1,9 @@
+# OuterEnumIntegerDefaultValue
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/PetApi.md b/samples/client/petstore/bash/docs/PetApi.md
index d9728a14ac7..32086308206 100644
--- a/samples/client/petstore/bash/docs/PetApi.md
+++ b/samples/client/petstore/bash/docs/PetApi.md
@@ -12,22 +12,26 @@ Method | HTTP request | Description
[**updatePet**](PetApi.md#updatePet) | **PUT** /pet | Update an existing pet
[**updatePetWithForm**](PetApi.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data
[**uploadFile**](PetApi.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image
+[**uploadFileWithRequiredFile**](PetApi.md#uploadFileWithRequiredFile) | **POST** /fake/{petId}/uploadImageWithRequiredFile | uploads an image (required)
-## **addPet**
+
+## addPet
Add a new pet to the store
### Example
+
```bash
petstore-cli addPet
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **pet** | [**Pet**](Pet.md) | Pet object that needs to be added to the store |
+ **body** | [**Pet**](Pet.md) | Pet object that needs to be added to the store |
### Return type
@@ -39,26 +43,29 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: application/json, application/xml
- - **Accept**: Not Applicable
+- **Content-Type**: application/json, application/xml
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **deletePet**
+
+## deletePet
Deletes a pet
### Example
+
```bash
petstore-cli deletePet petId=value api_key:value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **petId** | **integer** | Pet id to delete |
- **apiKey** | **string** | | [optional]
+ **petId** | **integer** | Pet id to delete | [default to null]
+ **apiKey** | **string** | | [optional] [default to null]
### Return type
@@ -70,27 +77,30 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **findPetsByStatus**
+
+## findPetsByStatus
Finds Pets by status
Multiple status values can be provided with comma separated strings
### Example
+
```bash
petstore-cli findPetsByStatus Specify as: status="value1,value2,..."
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **status** | [**array[string]**](string.md) | Status values that need to be considered for filter |
+ **status** | [**array[string]**](string.md) | Status values that need to be considered for filter | [default to null]
### Return type
@@ -102,27 +112,30 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **findPetsByTags**
+
+## findPetsByTags
Finds Pets by tags
Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
### Example
+
```bash
petstore-cli findPetsByTags Specify as: tags="value1,value2,..."
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **tags** | [**array[string]**](string.md) | Tags to filter by |
+ **tags** | [**array[string]**](string.md) | Tags to filter by | [default to null]
### Return type
@@ -134,27 +147,30 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **getPetById**
+
+## getPetById
Find pet by ID
Returns a single pet
### Example
+
```bash
petstore-cli getPetById petId=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **petId** | **integer** | ID of pet to return |
+ **petId** | **integer** | ID of pet to return | [default to null]
### Return type
@@ -166,25 +182,28 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **updatePet**
+
+## updatePet
Update an existing pet
### Example
+
```bash
petstore-cli updatePet
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **pet** | [**Pet**](Pet.md) | Pet object that needs to be added to the store |
+ **body** | [**Pet**](Pet.md) | Pet object that needs to be added to the store |
### Return type
@@ -196,25 +215,28 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: application/json, application/xml
- - **Accept**: Not Applicable
+- **Content-Type**: application/json, application/xml
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **updatePetWithForm**
+
+## updatePetWithForm
Updates a pet in the store with form data
### Example
+
```bash
petstore-cli updatePetWithForm petId=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **petId** | **integer** | ID of pet that needs to be updated |
+ **petId** | **integer** | ID of pet that needs to be updated | [default to null]
**name** | **string** | Updated name of the pet | [optional] [default to null]
**status** | **string** | Updated status of the pet | [optional] [default to null]
@@ -228,25 +250,28 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: application/x-www-form-urlencoded
- - **Accept**: Not Applicable
+- **Content-Type**: application/x-www-form-urlencoded
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **uploadFile**
+
+## uploadFile
uploads an image
### Example
+
```bash
petstore-cli uploadFile petId=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **petId** | **integer** | ID of pet to update |
+ **petId** | **integer** | ID of pet to update | [default to null]
**additionalMetadata** | **string** | Additional data to pass to server | [optional] [default to null]
**file** | **binary** | file to upload | [optional] [default to null]
@@ -260,8 +285,43 @@ Name | Type | Description | Notes
### HTTP request headers
- - **Content-Type**: multipart/form-data
- - **Accept**: application/json
+- **Content-Type**: multipart/form-data
+- **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+
+## uploadFileWithRequiredFile
+
+uploads an image (required)
+
+### Example
+
+```bash
+petstore-cli uploadFileWithRequiredFile petId=value
+```
+
+### Parameters
+
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **integer** | ID of pet to update | [default to null]
+ **requiredFile** | **binary** | file to upload | [default to null]
+ **additionalMetadata** | **string** | Additional data to pass to server | [optional] [default to null]
+
+### Return type
+
+[**ApiResponse**](ApiResponse.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+- **Content-Type**: multipart/form-data
+- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/SpecialModelName.md b/samples/client/petstore/bash/docs/SpecialModelName.md
new file mode 100644
index 00000000000..0ba2b4da02d
--- /dev/null
+++ b/samples/client/petstore/bash/docs/SpecialModelName.md
@@ -0,0 +1,10 @@
+# _special_model.name_
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**DollarspecialLeft_Square_BracketpropertyPeriodnameRight_Square_Bracket** | **integer** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/StoreApi.md b/samples/client/petstore/bash/docs/StoreApi.md
index f7f5c324b05..56b2934562b 100644
--- a/samples/client/petstore/bash/docs/StoreApi.md
+++ b/samples/client/petstore/bash/docs/StoreApi.md
@@ -10,22 +10,25 @@ Method | HTTP request | Description
[**placeOrder**](StoreApi.md#placeOrder) | **POST** /store/order | Place an order for a pet
-## **deleteOrder**
+
+## deleteOrder
Delete purchase order by ID
For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
### Example
+
```bash
petstore-cli deleteOrder order_id=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **orderId** | **string** | ID of the order that needs to be deleted |
+ **orderId** | **string** | ID of the order that needs to be deleted | [default to null]
### Return type
@@ -37,23 +40,26 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **getInventory**
+
+## getInventory
Returns pet inventories by status
Returns a map of status codes to quantities
### Example
+
```bash
petstore-cli getInventory
```
### Parameters
+
This endpoint does not need any parameter.
### Return type
@@ -66,27 +72,30 @@ This endpoint does not need any parameter.
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **getOrderById**
+
+## getOrderById
Find purchase order by ID
For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
### Example
+
```bash
petstore-cli getOrderById order_id=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **orderId** | **integer** | ID of pet that needs to be fetched |
+ **orderId** | **integer** | ID of pet that needs to be fetched | [default to null]
### Return type
@@ -98,25 +107,28 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **placeOrder**
+
+## placeOrder
Place an order for a pet
### Example
+
```bash
petstore-cli placeOrder
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **order** | [**Order**](Order.md) | order placed for purchasing the pet |
+ **body** | [**Order**](Order.md) | order placed for purchasing the pet |
### Return type
@@ -128,8 +140,8 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/TypeHolderDefault.md b/samples/client/petstore/bash/docs/TypeHolderDefault.md
new file mode 100644
index 00000000000..91c3f8fe015
--- /dev/null
+++ b/samples/client/petstore/bash/docs/TypeHolderDefault.md
@@ -0,0 +1,14 @@
+# TypeHolderDefault
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**stringUnderscoreitem** | **string** | | [default to what]
+**numberUnderscoreitem** | **integer** | | [default to null]
+**integerUnderscoreitem** | **integer** | | [default to null]
+**boolUnderscoreitem** | **boolean** | | [default to true]
+**arrayUnderscoreitem** | **array[integer]** | | [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/TypeHolderExample.md b/samples/client/petstore/bash/docs/TypeHolderExample.md
new file mode 100644
index 00000000000..411eda40870
--- /dev/null
+++ b/samples/client/petstore/bash/docs/TypeHolderExample.md
@@ -0,0 +1,14 @@
+# TypeHolderExample
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**stringUnderscoreitem** | **string** | | [default to null]
+**numberUnderscoreitem** | **integer** | | [default to null]
+**integerUnderscoreitem** | **integer** | | [default to null]
+**boolUnderscoreitem** | **boolean** | | [default to null]
+**arrayUnderscoreitem** | **array[integer]** | | [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/docs/UserApi.md b/samples/client/petstore/bash/docs/UserApi.md
index 54a393a46be..9663a425b73 100644
--- a/samples/client/petstore/bash/docs/UserApi.md
+++ b/samples/client/petstore/bash/docs/UserApi.md
@@ -14,22 +14,25 @@ Method | HTTP request | Description
[**updateUser**](UserApi.md#updateUser) | **PUT** /user/{username} | Updated user
-## **createUser**
+
+## createUser
Create user
This can only be done by the logged in user.
### Example
+
```bash
petstore-cli createUser
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **user** | [**User**](User.md) | Created user object |
+ **body** | [**User**](User.md) | Created user object |
### Return type
@@ -41,25 +44,28 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **createUsersWithArrayInput**
+
+## createUsersWithArrayInput
Creates list of users with given input array
### Example
+
```bash
petstore-cli createUsersWithArrayInput
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **user** | [**array[User]**](array.md) | List of user object |
+ **body** | [**array[User]**](User.md) | List of user object |
### Return type
@@ -71,25 +77,28 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **createUsersWithListInput**
+
+## createUsersWithListInput
Creates list of users with given input array
### Example
+
```bash
petstore-cli createUsersWithListInput
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **user** | [**array[User]**](array.md) | List of user object |
+ **body** | [**array[User]**](User.md) | List of user object |
### Return type
@@ -101,27 +110,30 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **deleteUser**
+
+## deleteUser
Delete user
This can only be done by the logged in user.
### Example
+
```bash
petstore-cli deleteUser username=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **username** | **string** | The name that needs to be deleted |
+ **username** | **string** | The name that needs to be deleted | [default to null]
### Return type
@@ -133,25 +145,28 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **getUserByName**
+
+## getUserByName
Get user by user name
### Example
+
```bash
petstore-cli getUserByName username=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **username** | **string** | The name that needs to be fetched. Use user1 for testing. |
+ **username** | **string** | The name that needs to be fetched. Use user1 for testing. | [default to null]
### Return type
@@ -163,26 +178,29 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **loginUser**
+
+## loginUser
Logs user into the system
### Example
+
```bash
petstore-cli loginUser username=value password=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **username** | **string** | The user name for login |
- **password** | **string** | The password for login in clear text |
+ **username** | **string** | The user name for login | [default to null]
+ **password** | **string** | The password for login in clear text | [default to null]
### Return type
@@ -194,21 +212,24 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: application/xml, application/json
+- **Content-Type**: Not Applicable
+- **Accept**: application/xml, application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **logoutUser**
+
+## logoutUser
Logs out current logged in user session
### Example
+
```bash
petstore-cli logoutUser
```
### Parameters
+
This endpoint does not need any parameter.
### Return type
@@ -221,28 +242,31 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
-## **updateUser**
+
+## updateUser
Updated user
This can only be done by the logged in user.
### Example
+
```bash
petstore-cli updateUser username=value
```
### Parameters
+
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **username** | **string** | name that need to be deleted |
- **user** | [**User**](User.md) | Updated user object |
+ **username** | **string** | name that need to be deleted | [default to null]
+ **body** | [**User**](User.md) | Updated user object |
### Return type
@@ -254,8 +278,8 @@ No authorization required
### HTTP request headers
- - **Content-Type**: Not Applicable
- - **Accept**: Not Applicable
+- **Content-Type**: Not Applicable
+- **Accept**: Not Applicable
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/samples/client/petstore/bash/docs/XmlItem.md b/samples/client/petstore/bash/docs/XmlItem.md
new file mode 100644
index 00000000000..7f60d6cd52e
--- /dev/null
+++ b/samples/client/petstore/bash/docs/XmlItem.md
@@ -0,0 +1,38 @@
+# XmlItem
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**attributeUnderscorestring** | **string** | | [optional] [default to null]
+**attributeUnderscorenumber** | **integer** | | [optional] [default to null]
+**attributeUnderscoreinteger** | **integer** | | [optional] [default to null]
+**attributeUnderscoreboolean** | **boolean** | | [optional] [default to null]
+**wrappedUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**nameUnderscorestring** | **string** | | [optional] [default to null]
+**nameUnderscorenumber** | **integer** | | [optional] [default to null]
+**nameUnderscoreinteger** | **integer** | | [optional] [default to null]
+**nameUnderscoreboolean** | **boolean** | | [optional] [default to null]
+**nameUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**nameUnderscorewrappedUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**prefixUnderscorestring** | **string** | | [optional] [default to null]
+**prefixUnderscorenumber** | **integer** | | [optional] [default to null]
+**prefixUnderscoreinteger** | **integer** | | [optional] [default to null]
+**prefixUnderscoreboolean** | **boolean** | | [optional] [default to null]
+**prefixUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**prefixUnderscorewrappedUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**namespaceUnderscorestring** | **string** | | [optional] [default to null]
+**namespaceUnderscorenumber** | **integer** | | [optional] [default to null]
+**namespaceUnderscoreinteger** | **integer** | | [optional] [default to null]
+**namespaceUnderscoreboolean** | **boolean** | | [optional] [default to null]
+**namespaceUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**namespaceUnderscorewrappedUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**prefixUnderscorensUnderscorestring** | **string** | | [optional] [default to null]
+**prefixUnderscorensUnderscorenumber** | **integer** | | [optional] [default to null]
+**prefixUnderscorensUnderscoreinteger** | **integer** | | [optional] [default to null]
+**prefixUnderscorensUnderscoreboolean** | **boolean** | | [optional] [default to null]
+**prefixUnderscorensUnderscorearray** | **array[integer]** | | [optional] [default to null]
+**prefixUnderscorensUnderscorewrappedUnderscorearray** | **array[integer]** | | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/bash/petstore-cli b/samples/client/petstore/bash/petstore-cli
index b74ebf8b204..dabf7c50485 100755
--- a/samples/client/petstore/bash/petstore-cli
+++ b/samples/client/petstore/bash/petstore-cli
@@ -95,14 +95,16 @@ declare -a result_color_table=( "$WHITE" "$WHITE" "$GREEN" "$YELLOW" "$WHITE" "$
# 0 - optional
# 1 - required
declare -A operation_parameters_minimum_occurrences
-operation_parameters_minimum_occurrences["testSpecialTags:::Client"]=1
+operation_parameters_minimum_occurrences["123Test@$%SpecialTags:::body"]=1
+operation_parameters_minimum_occurrences["createXmlItem:::XmlItem"]=1
operation_parameters_minimum_occurrences["fakeOuterBooleanSerialize:::body"]=0
-operation_parameters_minimum_occurrences["fakeOuterCompositeSerialize:::OuterComposite"]=0
+operation_parameters_minimum_occurrences["fakeOuterCompositeSerialize:::body"]=0
operation_parameters_minimum_occurrences["fakeOuterNumberSerialize:::body"]=0
operation_parameters_minimum_occurrences["fakeOuterStringSerialize:::body"]=0
+operation_parameters_minimum_occurrences["testBodyWithFileSchema:::body"]=1
operation_parameters_minimum_occurrences["testBodyWithQueryParams:::query"]=1
-operation_parameters_minimum_occurrences["testBodyWithQueryParams:::User"]=1
-operation_parameters_minimum_occurrences["testClientModel:::Client"]=1
+operation_parameters_minimum_occurrences["testBodyWithQueryParams:::body"]=1
+operation_parameters_minimum_occurrences["testClientModel:::body"]=1
operation_parameters_minimum_occurrences["testEndpointParameters:::number"]=1
operation_parameters_minimum_occurrences["testEndpointParameters:::double"]=1
operation_parameters_minimum_occurrences["testEndpointParameters:::pattern_without_delimiter"]=1
@@ -125,35 +127,44 @@ operation_parameters_minimum_occurrences["testEnumParameters:::enum_query_intege
operation_parameters_minimum_occurrences["testEnumParameters:::enum_query_double"]=0
operation_parameters_minimum_occurrences["testEnumParameters:::enum_form_string_array"]=0
operation_parameters_minimum_occurrences["testEnumParameters:::enum_form_string"]=0
-operation_parameters_minimum_occurrences["testInlineAdditionalProperties:::request_body"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::required_string_group"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::required_boolean_group"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::required_int64_group"]=1
+operation_parameters_minimum_occurrences["testGroupParameters:::string_group"]=0
+operation_parameters_minimum_occurrences["testGroupParameters:::boolean_group"]=0
+operation_parameters_minimum_occurrences["testGroupParameters:::int64_group"]=0
+operation_parameters_minimum_occurrences["testInlineAdditionalProperties:::param"]=1
operation_parameters_minimum_occurrences["testJsonFormData:::param"]=1
operation_parameters_minimum_occurrences["testJsonFormData:::param2"]=1
-operation_parameters_minimum_occurrences["testClassname:::Client"]=1
-operation_parameters_minimum_occurrences["addPet:::Pet"]=1
+operation_parameters_minimum_occurrences["testClassname:::body"]=1
+operation_parameters_minimum_occurrences["addPet:::body"]=1
operation_parameters_minimum_occurrences["deletePet:::petId"]=1
operation_parameters_minimum_occurrences["deletePet:::api_key"]=0
operation_parameters_minimum_occurrences["findPetsByStatus:::status"]=1
operation_parameters_minimum_occurrences["findPetsByTags:::tags"]=1
operation_parameters_minimum_occurrences["getPetById:::petId"]=1
-operation_parameters_minimum_occurrences["updatePet:::Pet"]=1
+operation_parameters_minimum_occurrences["updatePet:::body"]=1
operation_parameters_minimum_occurrences["updatePetWithForm:::petId"]=1
operation_parameters_minimum_occurrences["updatePetWithForm:::name"]=0
operation_parameters_minimum_occurrences["updatePetWithForm:::status"]=0
operation_parameters_minimum_occurrences["uploadFile:::petId"]=1
operation_parameters_minimum_occurrences["uploadFile:::additionalMetadata"]=0
operation_parameters_minimum_occurrences["uploadFile:::file"]=0
+operation_parameters_minimum_occurrences["uploadFileWithRequiredFile:::petId"]=1
+operation_parameters_minimum_occurrences["uploadFileWithRequiredFile:::requiredFile"]=1
+operation_parameters_minimum_occurrences["uploadFileWithRequiredFile:::additionalMetadata"]=0
operation_parameters_minimum_occurrences["deleteOrder:::order_id"]=1
operation_parameters_minimum_occurrences["getOrderById:::order_id"]=1
-operation_parameters_minimum_occurrences["placeOrder:::Order"]=1
-operation_parameters_minimum_occurrences["createUser:::User"]=1
-operation_parameters_minimum_occurrences["createUsersWithArrayInput:::User"]=1
-operation_parameters_minimum_occurrences["createUsersWithListInput:::User"]=1
+operation_parameters_minimum_occurrences["placeOrder:::body"]=1
+operation_parameters_minimum_occurrences["createUser:::body"]=1
+operation_parameters_minimum_occurrences["createUsersWithArrayInput:::body"]=1
+operation_parameters_minimum_occurrences["createUsersWithListInput:::body"]=1
operation_parameters_minimum_occurrences["deleteUser:::username"]=1
operation_parameters_minimum_occurrences["getUserByName:::username"]=1
operation_parameters_minimum_occurrences["loginUser:::username"]=1
operation_parameters_minimum_occurrences["loginUser:::password"]=1
operation_parameters_minimum_occurrences["updateUser:::username"]=1
-operation_parameters_minimum_occurrences["updateUser:::User"]=1
+operation_parameters_minimum_occurrences["updateUser:::body"]=1
##
# This array stores the maximum number of allowed occurrences for parameter
@@ -162,14 +173,16 @@ operation_parameters_minimum_occurrences["updateUser:::User"]=1
# N - N values
# 0 - unlimited
declare -A operation_parameters_maximum_occurrences
-operation_parameters_maximum_occurrences["testSpecialTags:::Client"]=0
+operation_parameters_maximum_occurrences["123Test@$%SpecialTags:::body"]=0
+operation_parameters_maximum_occurrences["createXmlItem:::XmlItem"]=0
operation_parameters_maximum_occurrences["fakeOuterBooleanSerialize:::body"]=0
-operation_parameters_maximum_occurrences["fakeOuterCompositeSerialize:::OuterComposite"]=0
+operation_parameters_maximum_occurrences["fakeOuterCompositeSerialize:::body"]=0
operation_parameters_maximum_occurrences["fakeOuterNumberSerialize:::body"]=0
operation_parameters_maximum_occurrences["fakeOuterStringSerialize:::body"]=0
+operation_parameters_maximum_occurrences["testBodyWithFileSchema:::body"]=0
operation_parameters_maximum_occurrences["testBodyWithQueryParams:::query"]=0
-operation_parameters_maximum_occurrences["testBodyWithQueryParams:::User"]=0
-operation_parameters_maximum_occurrences["testClientModel:::Client"]=0
+operation_parameters_maximum_occurrences["testBodyWithQueryParams:::body"]=0
+operation_parameters_maximum_occurrences["testClientModel:::body"]=0
operation_parameters_maximum_occurrences["testEndpointParameters:::number"]=0
operation_parameters_maximum_occurrences["testEndpointParameters:::double"]=0
operation_parameters_maximum_occurrences["testEndpointParameters:::pattern_without_delimiter"]=0
@@ -192,48 +205,59 @@ operation_parameters_maximum_occurrences["testEnumParameters:::enum_query_intege
operation_parameters_maximum_occurrences["testEnumParameters:::enum_query_double"]=0
operation_parameters_maximum_occurrences["testEnumParameters:::enum_form_string_array"]=0
operation_parameters_maximum_occurrences["testEnumParameters:::enum_form_string"]=0
-operation_parameters_maximum_occurrences["testInlineAdditionalProperties:::request_body"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::required_string_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::required_boolean_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::required_int64_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::string_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::boolean_group"]=0
+operation_parameters_maximum_occurrences["testGroupParameters:::int64_group"]=0
+operation_parameters_maximum_occurrences["testInlineAdditionalProperties:::param"]=0
operation_parameters_maximum_occurrences["testJsonFormData:::param"]=0
operation_parameters_maximum_occurrences["testJsonFormData:::param2"]=0
-operation_parameters_maximum_occurrences["testClassname:::Client"]=0
-operation_parameters_maximum_occurrences["addPet:::Pet"]=0
+operation_parameters_maximum_occurrences["testClassname:::body"]=0
+operation_parameters_maximum_occurrences["addPet:::body"]=0
operation_parameters_maximum_occurrences["deletePet:::petId"]=0
operation_parameters_maximum_occurrences["deletePet:::api_key"]=0
operation_parameters_maximum_occurrences["findPetsByStatus:::status"]=0
operation_parameters_maximum_occurrences["findPetsByTags:::tags"]=0
operation_parameters_maximum_occurrences["getPetById:::petId"]=0
-operation_parameters_maximum_occurrences["updatePet:::Pet"]=0
+operation_parameters_maximum_occurrences["updatePet:::body"]=0
operation_parameters_maximum_occurrences["updatePetWithForm:::petId"]=0
operation_parameters_maximum_occurrences["updatePetWithForm:::name"]=0
operation_parameters_maximum_occurrences["updatePetWithForm:::status"]=0
operation_parameters_maximum_occurrences["uploadFile:::petId"]=0
operation_parameters_maximum_occurrences["uploadFile:::additionalMetadata"]=0
operation_parameters_maximum_occurrences["uploadFile:::file"]=0
+operation_parameters_maximum_occurrences["uploadFileWithRequiredFile:::petId"]=0
+operation_parameters_maximum_occurrences["uploadFileWithRequiredFile:::requiredFile"]=0
+operation_parameters_maximum_occurrences["uploadFileWithRequiredFile:::additionalMetadata"]=0
operation_parameters_maximum_occurrences["deleteOrder:::order_id"]=0
operation_parameters_maximum_occurrences["getOrderById:::order_id"]=0
-operation_parameters_maximum_occurrences["placeOrder:::Order"]=0
-operation_parameters_maximum_occurrences["createUser:::User"]=0
-operation_parameters_maximum_occurrences["createUsersWithArrayInput:::User"]=0
-operation_parameters_maximum_occurrences["createUsersWithListInput:::User"]=0
+operation_parameters_maximum_occurrences["placeOrder:::body"]=0
+operation_parameters_maximum_occurrences["createUser:::body"]=0
+operation_parameters_maximum_occurrences["createUsersWithArrayInput:::body"]=0
+operation_parameters_maximum_occurrences["createUsersWithListInput:::body"]=0
operation_parameters_maximum_occurrences["deleteUser:::username"]=0
operation_parameters_maximum_occurrences["getUserByName:::username"]=0
operation_parameters_maximum_occurrences["loginUser:::username"]=0
operation_parameters_maximum_occurrences["loginUser:::password"]=0
operation_parameters_maximum_occurrences["updateUser:::username"]=0
-operation_parameters_maximum_occurrences["updateUser:::User"]=0
+operation_parameters_maximum_occurrences["updateUser:::body"]=0
##
# The type of collection for specifying multiple values for parameter:
# - multi, csv, ssv, tsv
declare -A operation_parameters_collection_type
-operation_parameters_collection_type["testSpecialTags:::Client"]=""
+operation_parameters_collection_type["123Test@$%SpecialTags:::body"]=""
+operation_parameters_collection_type["createXmlItem:::XmlItem"]=""
operation_parameters_collection_type["fakeOuterBooleanSerialize:::body"]=""
-operation_parameters_collection_type["fakeOuterCompositeSerialize:::OuterComposite"]=""
+operation_parameters_collection_type["fakeOuterCompositeSerialize:::body"]=""
operation_parameters_collection_type["fakeOuterNumberSerialize:::body"]=""
operation_parameters_collection_type["fakeOuterStringSerialize:::body"]=""
+operation_parameters_collection_type["testBodyWithFileSchema:::body"]=""
operation_parameters_collection_type["testBodyWithQueryParams:::query"]=""
-operation_parameters_collection_type["testBodyWithQueryParams:::User"]=""
-operation_parameters_collection_type["testClientModel:::Client"]=""
+operation_parameters_collection_type["testBodyWithQueryParams:::body"]=""
+operation_parameters_collection_type["testClientModel:::body"]=""
operation_parameters_collection_type["testEndpointParameters:::number"]=""
operation_parameters_collection_type["testEndpointParameters:::double"]=""
operation_parameters_collection_type["testEndpointParameters:::pattern_without_delimiter"]=""
@@ -256,35 +280,44 @@ operation_parameters_collection_type["testEnumParameters:::enum_query_integer"]=
operation_parameters_collection_type["testEnumParameters:::enum_query_double"]=""
operation_parameters_collection_type["testEnumParameters:::enum_form_string_array"]=
operation_parameters_collection_type["testEnumParameters:::enum_form_string"]=""
-operation_parameters_collection_type["testInlineAdditionalProperties:::request_body"]=
+operation_parameters_collection_type["testGroupParameters:::required_string_group"]=""
+operation_parameters_collection_type["testGroupParameters:::required_boolean_group"]=""
+operation_parameters_collection_type["testGroupParameters:::required_int64_group"]=""
+operation_parameters_collection_type["testGroupParameters:::string_group"]=""
+operation_parameters_collection_type["testGroupParameters:::boolean_group"]=""
+operation_parameters_collection_type["testGroupParameters:::int64_group"]=""
+operation_parameters_collection_type["testInlineAdditionalProperties:::param"]=
operation_parameters_collection_type["testJsonFormData:::param"]=""
operation_parameters_collection_type["testJsonFormData:::param2"]=""
-operation_parameters_collection_type["testClassname:::Client"]=""
-operation_parameters_collection_type["addPet:::Pet"]=""
+operation_parameters_collection_type["testClassname:::body"]=""
+operation_parameters_collection_type["addPet:::body"]=""
operation_parameters_collection_type["deletePet:::petId"]=""
operation_parameters_collection_type["deletePet:::api_key"]=""
operation_parameters_collection_type["findPetsByStatus:::status"]="csv"
operation_parameters_collection_type["findPetsByTags:::tags"]="csv"
operation_parameters_collection_type["getPetById:::petId"]=""
-operation_parameters_collection_type["updatePet:::Pet"]=""
+operation_parameters_collection_type["updatePet:::body"]=""
operation_parameters_collection_type["updatePetWithForm:::petId"]=""
operation_parameters_collection_type["updatePetWithForm:::name"]=""
operation_parameters_collection_type["updatePetWithForm:::status"]=""
operation_parameters_collection_type["uploadFile:::petId"]=""
operation_parameters_collection_type["uploadFile:::additionalMetadata"]=""
operation_parameters_collection_type["uploadFile:::file"]=""
+operation_parameters_collection_type["uploadFileWithRequiredFile:::petId"]=""
+operation_parameters_collection_type["uploadFileWithRequiredFile:::requiredFile"]=""
+operation_parameters_collection_type["uploadFileWithRequiredFile:::additionalMetadata"]=""
operation_parameters_collection_type["deleteOrder:::order_id"]=""
operation_parameters_collection_type["getOrderById:::order_id"]=""
-operation_parameters_collection_type["placeOrder:::Order"]=""
-operation_parameters_collection_type["createUser:::User"]=""
-operation_parameters_collection_type["createUsersWithArrayInput:::User"]=
-operation_parameters_collection_type["createUsersWithListInput:::User"]=
+operation_parameters_collection_type["placeOrder:::body"]=""
+operation_parameters_collection_type["createUser:::body"]=""
+operation_parameters_collection_type["createUsersWithArrayInput:::body"]=
+operation_parameters_collection_type["createUsersWithListInput:::body"]=
operation_parameters_collection_type["deleteUser:::username"]=""
operation_parameters_collection_type["getUserByName:::username"]=""
operation_parameters_collection_type["loginUser:::username"]=""
operation_parameters_collection_type["loginUser:::password"]=""
operation_parameters_collection_type["updateUser:::username"]=""
-operation_parameters_collection_type["updateUser:::User"]=""
+operation_parameters_collection_type["updateUser:::body"]=""
##
@@ -527,18 +560,16 @@ build_request_path() {
local query_request_part=""
- local count=0
for qparam in "${query_params[@]}"; do
+ if [[ "${operation_parameters[$qparam]}" == "" ]]; then
+ continue
+ fi
+
# Get the array of parameter values
local parameter_value=""
local parameter_values
mapfile -t parameter_values < <(sed -e 's/'":::"'/\n/g' <<<"${operation_parameters[$qparam]}")
- if [[ -n "${parameter_values[*]}" ]]; then
- if [[ $((count++)) -gt 0 ]]; then
- query_request_part+="&"
- fi
- fi
if [[ ${qparam} == "api_key_query" ]]; then
if [[ -n "${parameter_values[*]}" ]]; then
@@ -617,6 +648,9 @@ build_request_path() {
fi
if [[ -n "${parameter_value}" ]]; then
+ if [[ -n "${query_request_part}" ]]; then
+ query_request_part+="&"
+ fi
query_request_part+="${parameter_value}"
fi
@@ -687,16 +721,18 @@ EOF
echo ""
echo -e "${BOLD}${WHITE}[anotherFake]${OFF}"
read -r -d '' ops < 10. Other values will generated exceptions" | paste -sd' ' | fold -sw 80
echo -e ""
echo -e "${BOLD}${WHITE}Parameters${OFF}"
- echo -e " * ${GREEN}order_id${OFF} ${BLUE}[integer]${OFF} ${RED}(required)${OFF}${OFF} - ID of pet that needs to be fetched ${YELLOW}Specify as: order_id=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " * ${GREEN}order_id${OFF} ${BLUE}[integer]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - ID of pet that needs to be fetched ${YELLOW}Specify as: order_id=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo ""
echo -e "${BOLD}${WHITE}Responses${OFF}"
code=200
@@ -1331,7 +1456,7 @@ print_deleteUser_help() {
echo -e "This can only be done by the logged in user." | paste -sd' ' | fold -sw 80
echo -e ""
echo -e "${BOLD}${WHITE}Parameters${OFF}"
- echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF}${OFF} - The name that needs to be deleted ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The name that needs to be deleted ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo ""
echo -e "${BOLD}${WHITE}Responses${OFF}"
code=400
@@ -1349,7 +1474,7 @@ print_getUserByName_help() {
echo -e "${BOLD}${WHITE}getUserByName - Get user by user name${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo -e ""
echo -e "${BOLD}${WHITE}Parameters${OFF}"
- echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF}${OFF} - The name that needs to be fetched. Use user1 for testing. ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The name that needs to be fetched. Use user1 for testing. ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo ""
echo -e "${BOLD}${WHITE}Responses${OFF}"
code=200
@@ -1369,9 +1494,9 @@ print_loginUser_help() {
echo -e "${BOLD}${WHITE}loginUser - Logs user into the system${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo -e ""
echo -e "${BOLD}${WHITE}Parameters${OFF}"
- echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF}${OFF} - The user name for login${YELLOW} Specify as: username=value${OFF}" \
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The user name for login${YELLOW} Specify as: username=value${OFF}" \
| paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
- echo -e " * ${GREEN}password${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF}${OFF} - The password for login in clear text${YELLOW} Specify as: password=value${OFF}" \
+ echo -e " * ${GREEN}password${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - The password for login in clear text${YELLOW} Specify as: password=value${OFF}" \
| paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo ""
echo -e "${BOLD}${WHITE}Responses${OFF}"
@@ -1409,7 +1534,7 @@ print_updateUser_help() {
echo -e "This can only be done by the logged in user." | paste -sd' ' | fold -sw 80
echo -e ""
echo -e "${BOLD}${WHITE}Parameters${OFF}"
- echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF}${OFF} - name that need to be deleted ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
+ echo -e " * ${GREEN}username${OFF} ${BLUE}[string]${OFF} ${RED}(required)${OFF} ${CYAN}(default: null)${OFF} - name that need to be deleted ${YELLOW}Specify as: username=value${OFF}" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo -e " * ${GREEN}body${OFF} ${BLUE}[]${OFF} ${RED}(required)${OFF}${OFF} - Updated user object" | paste -sd' ' | fold -sw 80 | sed '2,$s/^/ /'
echo -e ""
echo ""
@@ -1423,10 +1548,10 @@ print_updateUser_help() {
##############################################################################
#
-# Call testSpecialTags operation
+# Call 123Test@$%SpecialTags operation
#
##############################################################################
-call_testSpecialTags() {
+call_123Test@$%SpecialTags() {
# ignore error about 'path_parameter_names' being unused; passed by reference
# shellcheck disable=SC2034
local path_parameter_names=()
@@ -1499,6 +1624,86 @@ call_testSpecialTags() {
fi
}
+##############################################################################
+#
+# Call createXmlItem operation
+#
+##############################################################################
+call_createXmlItem() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/create_xml_item" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/xml"
+ echo -e "\\t- application/xml; charset=utf-8"
+ echo -e "\\t- application/xml; charset=utf-16"
+ echo -e "\\t- text/xml"
+ echo -e "\\t- text/xml; charset=utf-8"
+ echo -e "\\t- text/xml; charset=utf-16"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
##############################################################################
#
# Call fakeOuterBooleanSerialize operation
@@ -1775,6 +1980,84 @@ call_fakeOuterStringSerialize() {
fi
}
+##############################################################################
+#
+# Call testBodyWithFileSchema operation
+#
+##############################################################################
+call_testBodyWithFileSchema() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=()
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/body-with-file-schema" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="PUT"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ local body_json_curl=""
+
+ #
+ # Check if the user provided 'Content-type' headers in the
+ # command line. If not try to set them based on the OpenAPI specification
+ # if values produces and consumes are defined unambigously
+ #
+ if [[ -z $header_content_type ]]; then
+ header_content_type="application/json"
+ fi
+
+
+ if [[ -z $header_content_type && "$force" = false ]]; then
+ :
+ echo "ERROR: Request's content-type not specified!!!"
+ echo "This operation expects content-type in one of the following formats:"
+ echo -e "\\t- application/json"
+ echo ""
+ echo "Use '--content-type' to set proper content type"
+ exit 1
+ else
+ headers_curl="${headers_curl} -H 'Content-type: ${header_content_type}'"
+ fi
+
+
+ #
+ # If we have received some body content over pipe, pass it from the
+ # temporary file to cURL
+ #
+ if [[ -n $body_content_temp_file ]]; then
+ if [[ "$print_curl" = true ]]; then
+ echo "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ else
+ eval "cat ${body_content_temp_file} | curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\" -d @-"
+ fi
+ rm "${body_content_temp_file}"
+ #
+ # If not, try to build the content body from arguments KEY==VALUE and KEY:=VALUE
+ #
+ else
+ body_json_curl=$(body_parameters_to_json)
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} ${body_json_curl} \"${host}${path}\""
+ fi
+ fi
+}
+
##############################################################################
#
# Call testBodyWithQueryParams operation
@@ -2003,6 +2286,42 @@ call_testEnumParameters() {
fi
}
+##############################################################################
+#
+# Call testGroupParameters operation
+#
+##############################################################################
+call_testGroupParameters() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=()
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=(required_string_group required_int64_group string_group int64_group)
+ local path
+
+ if ! path=$(build_request_path "/v2/fake" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="DELETE"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
##############################################################################
#
# Call testInlineAdditionalProperties operation
@@ -2563,6 +2882,42 @@ call_uploadFile() {
fi
}
+##############################################################################
+#
+# Call uploadFileWithRequiredFile operation
+#
+##############################################################################
+call_uploadFileWithRequiredFile() {
+ # ignore error about 'path_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local path_parameter_names=(petId)
+ # ignore error about 'query_parameter_names' being unused; passed by reference
+ # shellcheck disable=SC2034
+ local query_parameter_names=( )
+ local path
+
+ if ! path=$(build_request_path "/v2/fake/{petId}/uploadImageWithRequiredFile" path_parameter_names query_parameter_names); then
+ ERROR_MSG=$path
+ exit 1
+ fi
+ local method="POST"
+ local headers_curl
+ headers_curl=$(header_arguments_to_curl)
+ if [[ -n $header_accept ]]; then
+ headers_curl="${headers_curl} -H 'Accept: ${header_accept}'"
+ fi
+
+ local basic_auth_option=""
+ if [[ -n $basic_auth_credential ]]; then
+ basic_auth_option="-u ${basic_auth_credential}"
+ fi
+ if [[ "$print_curl" = true ]]; then
+ echo "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ else
+ eval "curl ${basic_auth_option} ${curl_arguments} ${headers_curl} -X ${method} \"${host}${path}\""
+ fi
+}
+
##############################################################################
#
# Call deleteOrder operation
@@ -3257,8 +3612,11 @@ case $key in
OFF=""
result_color_table=( "" "" "" "" "" "" "" )
;;
- testSpecialTags)
- operation="testSpecialTags"
+ 123Test@$%SpecialTags)
+ operation="123Test@$%SpecialTags"
+ ;;
+ createXmlItem)
+ operation="createXmlItem"
;;
fakeOuterBooleanSerialize)
operation="fakeOuterBooleanSerialize"
@@ -3272,6 +3630,9 @@ case $key in
fakeOuterStringSerialize)
operation="fakeOuterStringSerialize"
;;
+ testBodyWithFileSchema)
+ operation="testBodyWithFileSchema"
+ ;;
testBodyWithQueryParams)
operation="testBodyWithQueryParams"
;;
@@ -3284,6 +3645,9 @@ case $key in
testEnumParameters)
operation="testEnumParameters"
;;
+ testGroupParameters)
+ operation="testGroupParameters"
+ ;;
testInlineAdditionalProperties)
operation="testInlineAdditionalProperties"
;;
@@ -3317,6 +3681,9 @@ case $key in
uploadFile)
operation="uploadFile"
;;
+ uploadFileWithRequiredFile)
+ operation="uploadFileWithRequiredFile"
+ ;;
deleteOrder)
operation="deleteOrder"
;;
@@ -3437,8 +3804,11 @@ fi
# Run cURL command based on the operation ID
case $operation in
- testSpecialTags)
- call_testSpecialTags
+ 123Test@$%SpecialTags)
+ call_123Test@$%SpecialTags
+ ;;
+ createXmlItem)
+ call_createXmlItem
;;
fakeOuterBooleanSerialize)
call_fakeOuterBooleanSerialize
@@ -3452,6 +3822,9 @@ case $operation in
fakeOuterStringSerialize)
call_fakeOuterStringSerialize
;;
+ testBodyWithFileSchema)
+ call_testBodyWithFileSchema
+ ;;
testBodyWithQueryParams)
call_testBodyWithQueryParams
;;
@@ -3464,6 +3837,9 @@ case $operation in
testEnumParameters)
call_testEnumParameters
;;
+ testGroupParameters)
+ call_testGroupParameters
+ ;;
testInlineAdditionalProperties)
call_testInlineAdditionalProperties
;;
@@ -3497,6 +3873,9 @@ case $operation in
uploadFile)
call_uploadFile
;;
+ uploadFileWithRequiredFile)
+ call_uploadFileWithRequiredFile
+ ;;
deleteOrder)
call_deleteOrder
;;
diff --git a/samples/client/petstore/bash/petstore-cli.bash-completion b/samples/client/petstore/bash/petstore-cli.bash-completion
index 872c13b683c..d65b8a8efff 100644
--- a/samples/client/petstore/bash/petstore-cli.bash-completion
+++ b/samples/client/petstore/bash/petstore-cli.bash-completion
@@ -68,15 +68,18 @@ _petstore-cli()
# The list of available operation in the REST service
# It's modelled as an associative array for efficient key lookup
declare -A operations
- operations["testSpecialTags"]=1
+ operations["123Test@$%SpecialTags"]=1
+ operations["createXmlItem"]=1
operations["fakeOuterBooleanSerialize"]=1
operations["fakeOuterCompositeSerialize"]=1
operations["fakeOuterNumberSerialize"]=1
operations["fakeOuterStringSerialize"]=1
+ operations["testBodyWithFileSchema"]=1
operations["testBodyWithQueryParams"]=1
operations["testClientModel"]=1
operations["testEndpointParameters"]=1
operations["testEnumParameters"]=1
+ operations["testGroupParameters"]=1
operations["testInlineAdditionalProperties"]=1
operations["testJsonFormData"]=1
operations["testClassname"]=1
@@ -88,6 +91,7 @@ _petstore-cli()
operations["updatePet"]=1
operations["updatePetWithForm"]=1
operations["uploadFile"]=1
+ operations["uploadFileWithRequiredFile"]=1
operations["deleteOrder"]=1
operations["getInventory"]=1
operations["getOrderById"]=1
@@ -104,15 +108,18 @@ _petstore-cli()
# An associative array of operations to their parameters
# Only include path, query and header parameters
declare -A operation_parameters
- operation_parameters["testSpecialTags"]=""
+ operation_parameters["123Test@$%SpecialTags"]=""
+ operation_parameters["createXmlItem"]=""
operation_parameters["fakeOuterBooleanSerialize"]=""
operation_parameters["fakeOuterCompositeSerialize"]=""
operation_parameters["fakeOuterNumberSerialize"]=""
operation_parameters["fakeOuterStringSerialize"]=""
+ operation_parameters["testBodyWithFileSchema"]=""
operation_parameters["testBodyWithQueryParams"]="query= "
operation_parameters["testClientModel"]=""
operation_parameters["testEndpointParameters"]=""
operation_parameters["testEnumParameters"]="enum_query_string_array= enum_query_string= enum_query_integer= enum_query_double= enum_header_string_array: enum_header_string: "
+ operation_parameters["testGroupParameters"]="required_string_group= required_int64_group= string_group= int64_group= required_boolean_group: boolean_group: "
operation_parameters["testInlineAdditionalProperties"]=""
operation_parameters["testJsonFormData"]=""
operation_parameters["testClassname"]=""
@@ -124,6 +131,7 @@ _petstore-cli()
operation_parameters["updatePet"]=""
operation_parameters["updatePetWithForm"]="petId= "
operation_parameters["uploadFile"]="petId= "
+ operation_parameters["uploadFileWithRequiredFile"]="petId= "
operation_parameters["deleteOrder"]="order_id= "
operation_parameters["getInventory"]=""
operation_parameters["getOrderById"]="order_id= "
@@ -139,6 +147,18 @@ _petstore-cli()
# An associative array of possible values for enum parameters
declare -A operation_parameters_enum_values
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::required_boolean_group"]="true false"
+ operation_parameters_enum_values["testGroupParameters::boolean_group"]="true false"
#
# Check if this is OSX and use special __osx_init_completion function
diff --git a/samples/client/petstore/cpp-qt5/.gitignore b/samples/client/petstore/cpp-qt5/.gitignore
new file mode 100644
index 00000000000..378eac25d31
--- /dev/null
+++ b/samples/client/petstore/cpp-qt5/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/samples/client/petstore/cpp-qt5/PetStore/UserApiTests.cpp b/samples/client/petstore/cpp-qt5/PetStore/UserApiTests.cpp
index 9dc641b8592..3634efc81f8 100644
--- a/samples/client/petstore/cpp-qt5/PetStore/UserApiTests.cpp
+++ b/samples/client/petstore/cpp-qt5/PetStore/UserApiTests.cpp
@@ -1,10 +1,11 @@
#include "UserApiTests.h"
+#include