Merge remote-tracking branch 'origin/master' into 3.4.x

This commit is contained in:
William Cheng 2018-11-08 18:17:29 +08:00
commit a186efed35
683 changed files with 9676 additions and 2142 deletions

View File

@ -2,7 +2,7 @@
<div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.1`): [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`3.3.2`): [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.org/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Run Status](https://api.shippable.com/projects/5af6bf74e790f4070084a115/badge?branch=master)](https://app.shippable.com/github/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator-wh2wu)
@ -47,7 +47,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
| | Languages/Frameworks |
|-|-|
**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, 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** (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 - 6.x), Aurelia, Axios, Fetch, Inversify, jQuery, Node)
**API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, 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** (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)
**Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **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), **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), Scalatra)
**API documentation generators** | **HTML**, **Confluence Wiki**
**Configuration files** | [**Apache2**](https://httpd.apache.org/)
@ -65,6 +65,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
- [1.4 - Build Projects](#14---build-projects)
- [1.5 - Homebrew](#15---homebrew)
- [1.6 - Docker](#16---docker)
- [1.7 - NPM](#17---npm)
- [2 - Getting Started](#2---getting-started)
- [3 - Usage](#3---usage)
- [3.1 - Customization](#31---customization)
@ -89,8 +90,8 @@ OpenAPI Generator Version | Release Date | Notes
---------------------------- | ------------ | -----
4.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/)| TBD | Major release with breaking changes (no fallback)
3.4.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.4.0-SNAPSHOT/)| 01.11.2018 | Minor release (breaking changes with fallbacks)
3.3.2 (current master, upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.3.2-SNAPSHOT/) | 29.10.2018 | Bugfix release
[3.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.3.1) (latest stable release) | 15.10.2018 | Bugfix release
3.3.3 (current master, upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/3.3.3-SNAPSHOT/) | 15.11.2018 | Bugfix release
[3.3.2](https://github.com/OpenAPITools/openapi-generator/releases/tag/v3.3.2) (latest stable release) | 31.10.2018 | Bugfix release
OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0
@ -146,16 +147,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/3.3.1/openapi-generator-cli-3.3.1.jar`
JAR location: `http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar`
For **Mac/Linux** users:
```sh
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.1/openapi-generator-cli-3.3.1.jar -O openapi-generator-cli.jar
wget http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.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/3.3.1/openapi-generator-cli-3.3.1.jar
Invoke-WebRequest -OutFile openapi-generator-cli.jar http://central.maven.org/maven2/org/openapitools/openapi-generator-cli/3.3.2/openapi-generator-cli-3.3.2.jar
```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@ -346,6 +347,24 @@ cd /vagrant
./run-in-docker.sh mvn package
```
### [1.7 - NPM](#table-of-contents)
There is also an [NPM package wrapper](https://github.com/HarmoWatch/openapi-generator-cli), available.
Please see the [docs](https://github.com/HarmoWatch/openapi-generator-cli) there for more information.
Install it globally to get the CLI available on the command line:
```sh
npm install @harmowatch/openapi-generator-cli -g
openapi-generator version
```
Or you install it as dev-dependency like this:
```sh
npm install @harmowatch/openapi-generator-cli -D
```
## [2 - Getting Started](#table-of-contents)
To generate a PHP client for [petstore.yaml](https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml), please run the following
@ -482,6 +501,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Boxever](https://www.boxever.com/)
- [GMO Pepabo](https://pepabo.com/en/)
- [JustStar](https://www.juststarinfo.com)
- [Klarna](https://www.klarna.com/)
- [Myworkout](https://myworkout.com)
- [Raiffeisen Schweiz Genossenschaft](https://www.raiffeisen.ch)
- [RepreZen API Studio](https://www.reprezen.com/swagger-openapi-code-generation-api-first-microservices-enterprise-development)
@ -501,6 +521,9 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2018/06/27 - [Lessons Learned from Leading an Open-Source Project Supporting 30+ Programming Languages](https://speakerdeck.com/wing328/lessons-learned-from-leading-an-open-source-project-supporting-30-plus-programming-languages) - [William Cheng](https://github.com/wing328) at [LinuxCon + ContainerCon + CloudOpen China 2018](http://bit.ly/2waDKKX)
- 2018/07/19 - [OpenAPI Generator Contribution Quickstart - RingCentral Go SDK](https://medium.com/ringcentral-developers/openapi-generator-for-go-contribution-quickstart-8cc72bf37b53) by [John Wang](https://github.com/grokify)
- 2018/08/22 - [OpenAPI Generatorのプロジェクト構成などのメモ](https://yinm.info/20180822/) by [Yusuke Iinuma](https://github.com/yinm)
- 2018/10/31 - [A node package wrapper for openapi-generator](https://github.com/HarmoWatch/openapi-generator-cli)
- 2018/11/03 - [OpenAPI Generator + golang + Flutter でアプリ開発](http://ryuichi111std.hatenablog.com/entry/2018/11/03/214005) by [Ryuichi Daigo](https://github.com/ryuichi111)
## [6 - About Us](#table-of-contents)
@ -537,6 +560,7 @@ Here is a list of template creators:
* Elm: @trenneman
* Eiffel: @jvelilla
* Erlang: @tsloughter
* Erlang (PropEr): @jfacorro @robertoaloi
* Groovy: @victorgit
* Go: @wing328
* Go (rewritten in 2.3.0): @antihax
@ -568,8 +592,10 @@ Here is a list of template creators:
* Swift: @tkqubo
* Swift 3: @hexelon
* Swift 4: @ehyche
* TypeScript (Angular1): @mhardorf
* TypeScript (Angular1): @mhardorf
* TypeScript (Angular2): @roni-frantchi
* TypeScript (Angular6): @akehir
* TypeScript (Angular7): @topce
* TypeScript (Axios): @nicokoenig
* TypeScript (Fetch): @leonyu
* TypeScript (jQuery): @bherila
@ -656,7 +682,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Eiffel | @jvelilla (2017/09) |
| Elixir | |
| Elm | @trenneman (2018/09) |
| Erlang | @tsloughter (2017/11) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
| Go | @antihax (2017/11) @bvwells (2017/12) @grokify (2018/07) @kemokemo (2018/09 |
| Groovy | |
| Haskell | |
@ -674,7 +700,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Rust | @frol (2017/07) @farcaller (2017/08) @bjgill (2017/12) |
| Scala | @clasnake (2017/07) @jimschubert (2017/09) @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) |
| 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) |
### [6.3 - History of OpenAPI Generator](#table-of-contents)

32
bin/erlang-petstore-proper.sh Executable file
View File

@ -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/erlang-proper -DpackageName=petstore -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g erlang-proper -o samples/client/petstore/erlang-proper $@"
java $JAVA_OPTS -jar $executable $ags

0
bin/mysql-schema-petstore.sh Normal file → Executable file
View File

0
bin/springboot-virtualan-petstore-server.sh Normal file → Executable file
View File

View File

@ -10,34 +10,43 @@ echo "Please press CTRL+C to stop or the script will continue in 5 seconds."
sleep 5
# LIST OF SCRIPTS:
./bin/openapi3/ruby-client-petstore.sh > /dev/null 2>&1
./bin/java-petstore-all.sh > /dev/null 2>&1
./bin/java-jaxrs-petstore-server-all.sh > /dev/null 2>&1
./bin/openapi3/jaxrs-jersey-petstore.sh > /dev/null 2>&1
./bin/spring-all-pestore.sh > /dev/null 2>&1
./bin/kotlin-client-petstore.sh > /dev/null 2>&1
./bin/kotlin-client-string.sh > /dev/null 2>&1
./bin/kotlin-client-threetenbp.sh > /dev/null 2>&1
./bin/kotlin-server-petstore.sh > /dev/null 2>&1
./bin/mysql-schema-petstore.sh > /dev/null 2>&1
./bin/php-petstore.sh > /dev/null 2>&1
./bin/php-silex-petstore-server.sh > /dev/null 2>&1
./bin/php-symfony-petstore.sh > /dev/null 2>&1
./bin/php-lumen-petstore-server.sh > /dev/null 2>&1
./bin/php-slim-server-petstore.sh > /dev/null 2>&1
./bin/php-ze-ph-petstore-server.sh > /dev/null 2>&1
./bin/openapi3/php-petstore.sh > /dev/null 2>&1
./bin/typescript-angular-petstore-all.sh > /dev/null 2>&1
./bin/typescript-fetch-petstore-all.sh > /dev/null 2>&1
./bin/typescript-node-petstore-all.sh > /dev/null 2>&1
./bin/typescript-inversify-petstore.sh > /dev/null 2>&1
./bin/rust-server-petstore.sh > /dev/null 2>&1
./bin/haskell-http-client-petstore.sh > /dev/null 2>&1
./bin/csharp-petstore.sh > /dev/null 2>&1
./bin/meta-codegen.sh > /dev/null 2>&1
./bin/utils/export_docs_generators.sh > /dev/null 2>&1
./bin/go-petstore.sh > /dev/null 2>&1
./bin/go-gin-petstore-server.sh > /dev/null 2>&1
declare -a scripts=("./bin/openapi3/ruby-client-petstore.sh"
"./bin/java-petstore-all.sh"
"./bin/java-jaxrs-petstore-server-all.sh"
"./bin/openapi3/jaxrs-jersey-petstore.sh"
"./bin/spring-all-pestore.sh"
"./bin/kotlin-client-petstore.sh"
"./bin/kotlin-client-string.sh"
"./bin/kotlin-client-threetenbp.sh"
"./bin/kotlin-server-petstore.sh"
"./bin/mysql-schema-petstore.sh"
"./bin/php-petstore.sh"
"./bin/php-silex-petstore-server.sh"
"./bin/php-symfony-petstore.sh"
"./bin/php-lumen-petstore-server.sh"
"./bin/php-slim-server-petstore.sh"
"./bin/php-ze-ph-petstore-server.sh"
"./bin/openapi3/php-petstore.sh"
"./bin/typescript-angular-petstore-all.sh"
"./bin/typescript-fetch-petstore-all.sh"
"./bin/typescript-node-petstore-all.sh"
"./bin/typescript-inversify-petstore.sh"
"./bin/rust-server-petstore.sh"
"./bin/haskell-http-client-petstore.sh"
"./bin/csharp-petstore.sh"
"./bin/meta-codegen.sh"
"./bin/utils/export_docs_generators.sh"
"./bin/go-petstore.sh"
"./bin/go-gin-petstore-server.sh")
for script in "${scripts[@]}"; do
if eval $script > /dev/null 2>&1; then
echo "Executed $script successfully!"
else
echo "ERROR: Failed to run $script"
exit 1
fi
done
# Check:
if [ -n "$(git status --porcelain)" ]; then

View File

@ -41,7 +41,7 @@ jar=${artifactid}-${ver}.jar
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ ! -f ${DIR}/${jar} ]; then
repo="central::default::https://repo1.maven.apache.org/maven2"
repo="central::default::https://repo1.maven.org/maven2/"
if [[ ${ver} =~ ^.*-SNAPSHOT$ ]]; then
repo="central::default::https://oss.sonatype.org/content/repositories/snapshots"
fi

View File

@ -33,11 +33,7 @@ fi
echo "Release preparation: replacing $FROM with $TO in different files"
declare -a files=("CI/pom.xml.bash"
"CI/pom.xml.circleci"
"CI/pom.xml.circleci.java7"
"CI/pom.xml.ios"
"modules/openapi-generator-cli/pom.xml"
declare -a files=("modules/openapi-generator-cli/pom.xml"
"modules/openapi-generator-gradle-plugin/gradle.properties"
"modules/openapi-generator-gradle-plugin/pom.xml"
"modules/openapi-generator-maven-plugin/pom.xml"

View File

@ -5,6 +5,6 @@ CONFIG OPTIONS for rust-server
Rust crate name (convention: snake_case). (Default: openapi_client)
packageVersion
Rust crate version. (Default: 1.0.0)
Rust crate version.
Back to the [generators list](README.md)

View File

@ -48,7 +48,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.1"
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.2"
}
}
@ -278,6 +278,32 @@ in others being disabled. That is, OpenAPI Generator considers any one of these
For more control over generation of individual files, configure an ignore file and refer to it via `ignoreFileOverride`.
====
[NOTE]
====
When configuring `systemProperties` in order to perform selective generation you can disable generation of some parts by providing `"false"` value:
[source,groovy]
----
openApiGenerate {
// other settings omitted
systemProperties = [
modelDocs: "false",
apis: "false"
]
}
----
When enabling generation of only specific parts you either have to provide CSV list of what you particularly are generating or provide an empty string `""` to generate everything. If you provide `"true"` it will be treated as a specific name of model or api you want to generate.
[source,groovy]
----
openApiGenerate {
// other settings omitted
systemProperties = [
apis: "",
models: "User,Pet"
]
}
----
====
=== openApiValidate
.Options

View File

@ -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=3.3.1 openApiValidate
gradle -PopenApiGeneratorVersion=3.3.2 openApiValidate
```

View File

@ -1 +1 @@
openApiGeneratorVersion=3.3.1
openApiGeneratorVersion=3.3.2

View File

@ -11,7 +11,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
<executions>
<execution>
<goals>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
<executions>
<execution>
<goals>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
<executions>
<execution>
<goals>

View File

@ -12,7 +12,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
<executions>
<execution>
<goals>

View File

@ -15,6 +15,11 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-build-api</artifactId>
<version>0.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>

View File

@ -42,6 +42,7 @@ import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.project.MavenProject;
import org.openapitools.codegen.CliOption;
@ -50,6 +51,8 @@ import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.sonatype.plexus.build.incremental.DefaultBuildContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -61,6 +64,13 @@ public class CodeGenMojo extends AbstractMojo {
private static final Logger LOGGER = LoggerFactory.getLogger(CodeGenMojo.class);
/**
* The build context is only avail when running from within eclipse.
* It is used to update the eclipse-m2e-layer when the plugin is executed inside the IDE.
*/
@Component
private BuildContext buildContext = new DefaultBuildContext();
@Parameter(name="validateSpec", required = false, defaultValue = "true")
private Boolean validateSpec;
@ -329,274 +339,300 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(readonly = true, required = true, defaultValue = "${project}")
private MavenProject project;
public void setBuildContext(BuildContext buildContext) {
this.buildContext = buildContext;
}
@Override
public void execute() throws MojoExecutionException {
File inputSpecFile = new File(inputSpec);
addCompileSourceRootIfConfigured();
if (skip) {
getLog().info("Code generation is skipped.");
// Even when no new sources are generated, the existing ones should
// still be compiled if needed.
addCompileSourceRootIfConfigured();
return;
}
// attempt to read from config file
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile);
// if a config file wasn't specified or we were unable to read it
if (configurator == null) {
configurator = new CodegenConfigurator();
}
configurator.setVerbose(verbose);
// now override with any specified parameters
if (validateSpec != null) {
configurator.setValidateSpec(validateSpec);
}
if (skipOverwrite != null) {
configurator.setSkipOverwrite(skipOverwrite);
}
if (removeOperationIdPrefix != null) {
configurator.setRemoveOperationIdPrefix(removeOperationIdPrefix);
}
if (isNotEmpty(inputSpec)) {
configurator.setInputSpec(inputSpec);
}
if (isNotEmpty(gitUserId)) {
configurator.setGitUserId(gitUserId);
}
if (isNotEmpty(gitRepoId)) {
configurator.setGitRepoId(gitRepoId);
}
if (isNotEmpty(ignoreFileOverride)) {
configurator.setIgnoreFileOverride(ignoreFileOverride);
}
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
if (isNotEmpty(generatorName)) {
configurator.setGeneratorName(generatorName);
// check if generatorName & language are set together, inform user this needs to be updated to prevent future issues.
if (isNotEmpty(language)) {
LOGGER.warn("The 'language' option is deprecated and was replaced by 'generatorName'. Both can not be set together");
throw new MojoExecutionException("Illegal configuration: 'language' and 'generatorName' can not be set both, remove 'language' from your configuration");
}
} else if (isNotEmpty(language)) {
LOGGER.warn("The 'language' option is deprecated and may reference language names only in the next major release (4.0). Please use 'generatorName' instead.");
configurator.setGeneratorName(language);
} else {
LOGGER.error("A generator name (generatorName) is required.");
throw new MojoExecutionException("The generator requires 'generatorName'. Refer to documentation for a list of options.");
}
configurator.setOutputDir(output.getAbsolutePath());
if (isNotEmpty(auth)) {
configurator.setAuth(auth);
}
if (isNotEmpty(apiPackage)) {
configurator.setApiPackage(apiPackage);
}
if (isNotEmpty(modelPackage)) {
configurator.setModelPackage(modelPackage);
}
if (isNotEmpty(invokerPackage)) {
configurator.setInvokerPackage(invokerPackage);
}
if (isNotEmpty(groupId)) {
configurator.setGroupId(groupId);
}
if (isNotEmpty(artifactId)) {
configurator.setArtifactId(artifactId);
}
if (isNotEmpty(artifactVersion)) {
configurator.setArtifactVersion(artifactVersion);
}
if (isNotEmpty(library)) {
configurator.setLibrary(library);
}
if (isNotEmpty(modelNamePrefix)) {
configurator.setModelNamePrefix(modelNamePrefix);
}
if (isNotEmpty(modelNameSuffix)) {
configurator.setModelNameSuffix(modelNameSuffix);
}
if (null != templateDirectory) {
configurator.setTemplateDir(templateDirectory.getAbsolutePath());
}
// Set generation options
if (null != generateApis && generateApis) {
System.setProperty(CodegenConstants.APIS, "");
} else {
System.clearProperty(CodegenConstants.APIS);
}
if (null != generateModels && generateModels) {
System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
} else {
System.clearProperty(CodegenConstants.MODELS);
}
if (null != generateSupportingFiles && generateSupportingFiles) {
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
} else {
System.clearProperty(CodegenConstants.SUPPORTING_FILES);
}
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
if (configOptions != null) {
// Retained for backwards-compataibility with configOptions -> instantiation-types
if (instantiationTypes == null && configOptions.containsKey("instantiation-types")) {
applyInstantiationTypesKvp(configOptions.get("instantiation-types").toString(),
configurator);
}
// Retained for backwards-compataibility with configOptions -> import-mappings
if (importMappings == null && configOptions.containsKey("import-mappings")) {
applyImportMappingsKvp(configOptions.get("import-mappings").toString(),
configurator);
}
// Retained for backwards-compataibility with configOptions -> type-mappings
if (typeMappings == null && configOptions.containsKey("type-mappings")) {
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
}
// Retained for backwards-compataibility with configOptions -> language-specific-primitives
if (languageSpecificPrimitives == null && configOptions.containsKey("language-specific-primitives")) {
applyLanguageSpecificPrimitivesCsv(configOptions
.get("language-specific-primitives").toString(), configurator);
}
// Retained for backwards-compataibility with configOptions -> additional-properties
if (additionalProperties == null && configOptions.containsKey("additional-properties")) {
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(),
configurator);
}
// Retained for backwards-compataibility with configOptions -> reserved-words-mappings
if (reservedWordsMappings == null && configOptions.containsKey("reserved-words-mappings")) {
applyReservedWordsMappingsKvp(configOptions.get("reserved-words-mappings")
.toString(), configurator);
}
}
//Apply Instantiation Types
if (instantiationTypes != null && (configOptions == null || !configOptions.containsKey("instantiation-types"))) {
applyInstantiationTypesKvpList(instantiationTypes, configurator);
}
//Apply Import Mappings
if (importMappings != null && (configOptions == null || !configOptions.containsKey("import-mappings"))) {
applyImportMappingsKvpList(importMappings, configurator);
}
//Apply Type Mappings
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
applyTypeMappingsKvpList(typeMappings, configurator);
}
//Apply Language Specific Primitives
if (languageSpecificPrimitives != null && (configOptions == null || !configOptions.containsKey("language-specific-primitives"))) {
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
}
//Apply Additional Properties
if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) {
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
}
//Apply Reserved Words Mappings
if (reservedWordsMappings != null && (configOptions == null || !configOptions.containsKey("reserved-words-mappings"))) {
applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator);
}
if (environmentVariables != null) {
for (String key : environmentVariables.keySet()) {
originalEnvironmentVariables.put(key, System.getProperty(key));
String value = environmentVariables.get(key);
if (value == null) {
// don't put null values
value = "";
}
System.setProperty(key, value);
configurator.addSystemProperty(key, value);
}
}
final ClientOptInput input = configurator.toClientOptInput();
final CodegenConfig config = input.getConfig();
if (configOptions != null) {
for (CliOption langCliOption : config.cliOptions()) {
if (configOptions.containsKey(langCliOption.getOpt())) {
input.getConfig().additionalProperties()
.put(langCliOption.getOpt(), configOptions.get(langCliOption.getOpt()));
}
}
}
if (configHelp) {
for (CliOption langCliOption : config.cliOptions()) {
System.out.println("\t" + langCliOption.getOpt());
System.out.println("\t "
+ langCliOption.getOptionHelp().replaceAll("\n", "\n\t "));
System.out.println();
}
return;
}
adjustAdditionalProperties(config);
try {
if (skip) {
getLog().info("Code generation is skipped.");
return;
}
if (buildContext != null) {
if (buildContext.isIncremental()) {
if (inputSpec != null) {
if (inputSpecFile.exists()) {
if (!buildContext.hasDelta(inputSpecFile)) {
getLog().info(
"Code generation is skipped in delta-build because source-json was not modified.");
return;
}
}
}
}
}
// attempt to read from config file
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configurationFile);
// if a config file wasn't specified or we were unable to read it
if (configurator == null) {
configurator = new CodegenConfigurator();
}
configurator.setVerbose(verbose);
// now override with any specified parameters
if (validateSpec != null) {
configurator.setValidateSpec(validateSpec);
}
if (skipOverwrite != null) {
configurator.setSkipOverwrite(skipOverwrite);
}
if (removeOperationIdPrefix != null) {
configurator.setRemoveOperationIdPrefix(removeOperationIdPrefix);
}
if (isNotEmpty(inputSpec)) {
configurator.setInputSpec(inputSpec);
}
if (isNotEmpty(gitUserId)) {
configurator.setGitUserId(gitUserId);
}
if (isNotEmpty(gitRepoId)) {
configurator.setGitRepoId(gitRepoId);
}
if (isNotEmpty(ignoreFileOverride)) {
configurator.setIgnoreFileOverride(ignoreFileOverride);
}
// TODO: After 3.0.0 release (maybe for 3.1.0): Fully deprecate lang.
if (isNotEmpty(generatorName)) {
configurator.setGeneratorName(generatorName);
// check if generatorName & language are set together, inform user this needs to be updated to prevent future issues.
if (isNotEmpty(language)) {
LOGGER.warn("The 'language' option is deprecated and was replaced by 'generatorName'. Both can not be set together");
throw new MojoExecutionException(
"Illegal configuration: 'language' and 'generatorName' can not be set both, remove 'language' from your configuration");
}
} else if (isNotEmpty(language)) {
LOGGER.warn(
"The 'language' option is deprecated and may reference language names only in the next major release (4.0). Please use 'generatorName' instead.");
configurator.setGeneratorName(language);
} else {
LOGGER.error("A generator name (generatorName) is required.");
throw new MojoExecutionException("The generator requires 'generatorName'. Refer to documentation for a list of options.");
}
configurator.setOutputDir(output.getAbsolutePath());
if (isNotEmpty(auth)) {
configurator.setAuth(auth);
}
if (isNotEmpty(apiPackage)) {
configurator.setApiPackage(apiPackage);
}
if (isNotEmpty(modelPackage)) {
configurator.setModelPackage(modelPackage);
}
if (isNotEmpty(invokerPackage)) {
configurator.setInvokerPackage(invokerPackage);
}
if (isNotEmpty(groupId)) {
configurator.setGroupId(groupId);
}
if (isNotEmpty(artifactId)) {
configurator.setArtifactId(artifactId);
}
if (isNotEmpty(artifactVersion)) {
configurator.setArtifactVersion(artifactVersion);
}
if (isNotEmpty(library)) {
configurator.setLibrary(library);
}
if (isNotEmpty(modelNamePrefix)) {
configurator.setModelNamePrefix(modelNamePrefix);
}
if (isNotEmpty(modelNameSuffix)) {
configurator.setModelNameSuffix(modelNameSuffix);
}
if (null != templateDirectory) {
configurator.setTemplateDir(templateDirectory.getAbsolutePath());
}
// Set generation options
if (null != generateApis && generateApis) {
System.setProperty(CodegenConstants.APIS, "");
} else {
System.clearProperty(CodegenConstants.APIS);
}
if (null != generateModels && generateModels) {
System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
} else {
System.clearProperty(CodegenConstants.MODELS);
}
if (null != generateSupportingFiles && generateSupportingFiles) {
System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
} else {
System.clearProperty(CodegenConstants.SUPPORTING_FILES);
}
System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
if (configOptions != null) {
// Retained for backwards-compataibility with configOptions -> instantiation-types
if (instantiationTypes == null && configOptions.containsKey("instantiation-types")) {
applyInstantiationTypesKvp(configOptions.get("instantiation-types").toString(),
configurator);
}
// Retained for backwards-compataibility with configOptions -> import-mappings
if (importMappings == null && configOptions.containsKey("import-mappings")) {
applyImportMappingsKvp(configOptions.get("import-mappings").toString(),
configurator);
}
// Retained for backwards-compataibility with configOptions -> type-mappings
if (typeMappings == null && configOptions.containsKey("type-mappings")) {
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
}
// Retained for backwards-compataibility with configOptions -> language-specific-primitives
if (languageSpecificPrimitives == null && configOptions.containsKey("language-specific-primitives")) {
applyLanguageSpecificPrimitivesCsv(configOptions
.get("language-specific-primitives").toString(), configurator);
}
// Retained for backwards-compataibility with configOptions -> additional-properties
if (additionalProperties == null && configOptions.containsKey("additional-properties")) {
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(),
configurator);
}
// Retained for backwards-compataibility with configOptions -> reserved-words-mappings
if (reservedWordsMappings == null && configOptions.containsKey("reserved-words-mappings")) {
applyReservedWordsMappingsKvp(configOptions.get("reserved-words-mappings")
.toString(), configurator);
}
}
// Apply Instantiation Types
if (instantiationTypes != null && (configOptions == null || !configOptions.containsKey("instantiation-types"))) {
applyInstantiationTypesKvpList(instantiationTypes, configurator);
}
// Apply Import Mappings
if (importMappings != null && (configOptions == null || !configOptions.containsKey("import-mappings"))) {
applyImportMappingsKvpList(importMappings, configurator);
}
// Apply Type Mappings
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
applyTypeMappingsKvpList(typeMappings, configurator);
}
// Apply Language Specific Primitives
if (languageSpecificPrimitives != null
&& (configOptions == null || !configOptions.containsKey("language-specific-primitives"))) {
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);
}
// Apply Additional Properties
if (additionalProperties != null && (configOptions == null || !configOptions.containsKey("additional-properties"))) {
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
}
// Apply Reserved Words Mappings
if (reservedWordsMappings != null && (configOptions == null || !configOptions.containsKey("reserved-words-mappings"))) {
applyReservedWordsMappingsKvpList(reservedWordsMappings, configurator);
}
if (environmentVariables != null) {
for (String key : environmentVariables.keySet()) {
originalEnvironmentVariables.put(key, System.getProperty(key));
String value = environmentVariables.get(key);
if (value == null) {
// don't put null values
value = "";
}
System.setProperty(key, value);
configurator.addSystemProperty(key, value);
}
}
final ClientOptInput input = configurator.toClientOptInput();
final CodegenConfig config = input.getConfig();
if (configOptions != null) {
for (CliOption langCliOption : config.cliOptions()) {
if (configOptions.containsKey(langCliOption.getOpt())) {
input.getConfig().additionalProperties()
.put(langCliOption.getOpt(), configOptions.get(langCliOption.getOpt()));
}
}
}
if (configHelp) {
for (CliOption langCliOption : config.cliOptions()) {
System.out.println("\t" + langCliOption.getOpt());
System.out.println("\t "
+ langCliOption.getOptionHelp().replaceAll("\n", "\n\t "));
System.out.println();
}
return;
}
adjustAdditionalProperties(config);
new DefaultGenerator().opts(input).generate();
if (buildContext != null) {
buildContext.refresh(new File(getCompileSourceRoot()));
}
} catch (Exception e) {
// Maven logs exceptions thrown by plugins only if invoked with -e
// I find it annoying to jump through hoops to get basic diagnostic information,
// so let's log it in any case:
if (buildContext != null) {
buildContext.addError(inputSpecFile, 0, 0, "unexpected error in Open-API generation", e);
}
getLog().error(e);
throw new MojoExecutionException(
"Code generation failed. See above for the full exception.");
}
}
private String getCompileSourceRoot() {
final Object sourceFolderObject =
configOptions == null ? null : configOptions
.get(CodegenConstants.SOURCE_FOLDER);
final String sourceFolder =
sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString();
addCompileSourceRootIfConfigured();
String sourceJavaFolder = output.toString() + "/" + sourceFolder;
return sourceJavaFolder;
}
private void addCompileSourceRootIfConfigured() {
if (addCompileSourceRoot) {
final Object sourceFolderObject =
configOptions == null ? null : configOptions
.get(CodegenConstants.SOURCE_FOLDER);
final String sourceFolder =
sourceFolderObject == null ? "src/main/java" : sourceFolderObject.toString();
String sourceJavaFolder = output.toString() + "/" + sourceFolder;
project.addCompileSourceRoot(sourceJavaFolder);
project.addCompileSourceRoot(getCompileSourceRoot());
}
// Reset all environment variables to their original value. This prevents unexpected

View File

@ -0,0 +1,17 @@
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>

View File

@ -18,6 +18,7 @@
package org.openapitools.codegen.languages;
import java.util.*;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CodegenConfig;
@ -35,8 +36,6 @@ import io.swagger.v3.oas.models.responses.ApiResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractApexCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractApexCodegen.class);
@ -325,7 +324,7 @@ public abstract class AbstractApexCodegen extends DefaultCodegen implements Code
if (example.isEmpty()) {
example = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu";
}
((ByteArraySchema) p).setExample(example);
p.setExample(example);
example = "EncodingUtil.base64Decode('" + example + "')";
} else if (ModelUtils.isDateSchema(p)) {
if (example.matches("^\\d{4}(-\\d{2}){2}")) {

View File

@ -1397,7 +1397,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
return; // skip if JAVA_POST_PROCESS_FILE env variable is not defined
}
// only process files with hs extension
// only process files with java extension
if ("java".equals(FilenameUtils.getExtension(file.toString()))) {
String command = javaPostProcessFile + " " + file.toString();
try {

View File

@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConfig;
@ -308,6 +309,11 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
public void processOpts() {
super.processOpts();
if (StringUtils.isEmpty(System.getenv("KOTLIN_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable KOTLIN_POST_PROCESS_FILE not defined so the Kotlin code may not be properly formatted. To define it, try 'export KOTLIN_POST_PROCESS_FILE=\"/usr/local/bin/ktlint -F\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
if (additionalProperties.containsKey(CodegenConstants.ENUM_PROPERTY_NAMING)) {
setEnumPropertyNaming((String) additionalProperties.get(CodegenConstants.ENUM_PROPERTY_NAMING));
}
@ -684,4 +690,33 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
}
return startsWithTwoUppercaseLetters;
}
@Override
public void postProcessFile(File file, String fileType) {
if (file == null) {
return;
}
String kotlinPostProcessFile = System.getenv("KOTLIN_POST_PROCESS_FILE");
if (StringUtils.isEmpty(kotlinPostProcessFile)) {
return; // skip if KOTLIN_POST_PROCESS_FILE env variable is not defined
}
// only process files with kt extension
if ("kt".equals(FilenameUtils.getExtension(file.toString()))) {
String command = kotlinPostProcessFile + " " + file.toString();
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
int exitValue = p.exitValue();
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());
}
}
}
}

View File

@ -146,6 +146,23 @@ abstract class AbstractRubyCodegen extends DefaultCodegen implements CodegenConf
return name;
}
public String toRegularExpression(String pattern) {
if (StringUtils.isEmpty(pattern)) {
return pattern;
}
// We don't escape \ in string since Ruby doesn't like \ escaped in regex literal
String regexString = pattern;
if (!regexString.startsWith("/")) {
regexString = "/" + regexString;
}
if (StringUtils.countMatches(regexString, '/') == 1) {
// we only have forward slash inserted at start... adding one to end
regexString = regexString + "/";
}
return regexString;
}
@Override
public String toParamName(String name) {
// should be the same as variable name

View File

@ -26,6 +26,7 @@ import io.swagger.v3.oas.models.info.*;
import io.swagger.v3.oas.models.OpenAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
@ -224,7 +225,7 @@ public class ApexClientCodegen extends AbstractApexCodegen {
);
} else if (ModelUtils.isBooleanSchema(p)) {
// true => "true", false => "false", null => "null"
out = String.valueOf(((BooleanSchema) p).getDefault());
out = String.valueOf(p.getDefault());
} else if (ModelUtils.isLongSchema(p)) {
Long def = (Long) p.getDefault();
out = def == null ? out : def.toString() + "L";

View File

@ -251,4 +251,9 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
// To avoid unexpected behaviors when options are passed programmatically such as { "useCollection": "" }
return super.processCompiler(compiler).emptyStringIsFalse(true);
}
@Override
public String toRegularExpression(String pattern) {
return escapeText(pattern);
}
}

View File

@ -313,6 +313,9 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
}
if (schema.getDefault() != null) {
if (ModelUtils.isStringSchema(schema)) {
return "\"" + schema.getDefault().toString().replaceAll("\"", "\\\"") + "\"";
}
return schema.getDefault().toString();
} else {
return "null";

View File

@ -30,7 +30,6 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jws.WebParam;
import java.io.File;
import java.io.IOException;
import java.io.Writer;

View File

@ -0,0 +1,542 @@
/*
* 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.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ErlangProperCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ErlangProperCodegen.class);
protected String packageName = "openapi";
protected String packageVersion = "1.0.0";
protected String sourceFolder = "src";
protected String modelFolder = "model";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "erlang-proper";
}
public String getHelp() {
return "Generates an Erlang library with PropEr generators (beta).";
}
public ErlangProperCodegen() {
super();
outputFolder = "generated-code/erlang";
modelTemplateFiles.put("model.mustache", ".erl");
apiTemplateFiles.put("api.mustache", "_api.erl");
apiTemplateFiles.put("statem.mustache", "_statem.erl");
embeddedTemplateDir = templateDir = "erlang-proper";
setReservedWordsLowerCase(
Arrays.asList(
"after", "and", "andalso", "band", "begin", "bnot", "bor", "bsl", "bsr", "bxor", "case",
"catch", "cond", "div", "end", "fun", "if", "let", "not", "of", "or", "orelse", "receive",
"rem", "try", "when", "xor"
)
);
instantiationTypes.clear();
typeMapping.clear();
typeMapping.put("enum", "binary()");
typeMapping.put("date", "date()");
typeMapping.put("datetime", "datetime()");
typeMapping.put("DateTime", "datetime()");
typeMapping.put("boolean", "boolean()");
typeMapping.put("string", "binary()");
typeMapping.put("integer", "integer()");
typeMapping.put("int", "integer()");
typeMapping.put("float", "integer()");
typeMapping.put("long", "integer()");
typeMapping.put("double", "float()");
typeMapping.put("array", "list()");
typeMapping.put("map", "map()");
typeMapping.put("number", "integer()");
typeMapping.put("bigdecimal", "float()");
typeMapping.put("List", "list()");
typeMapping.put("object", "map()");
typeMapping.put("file", "binary()");
typeMapping.put("binary", "binary()");
typeMapping.put("bytearray", "binary()");
typeMapping.put("byte", "binary()");
typeMapping.put("uuid", "binary()");
typeMapping.put("password", "binary()");
cliOptions.clear();
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Erlang application name (convention: lowercase).")
.defaultValue(this.packageName));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Erlang application version")
.defaultValue(this.packageVersion));
}
@Override
public CodegenModel fromModel(String name, Schema model, Map<String, Schema> allDefinitions) {
CodegenModel cm = super.fromModel(name, model, allDefinitions);
if(ModelUtils.isArraySchema(model)) {
return new CodegenArrayModel(cm, (ArraySchema) model);
} else {
return cm;
}
}
@Override
public String getTypeDeclaration(String name) {
return name + ":" + name + "()";
}
@Override
public String getTypeDeclaration(Schema schema) {
String typeDeclaration = super.getSchemaType(schema);
if(ModelUtils.isArraySchema(schema)) {
ArraySchema arraySchema = (ArraySchema) schema;
String complexType = getSchemaType(arraySchema.getItems());
StringBuilder sb = new StringBuilder("list(");
sb.append(complexType);
return sb.append(")").toString();
} else if (typeMapping.containsKey(typeDeclaration)) {
return typeMapping.get(typeDeclaration);
} else {
return getTypeDeclaration(toModelName(snakeCase(typeDeclaration)));
}
}
@Override
public String getSchemaType(Schema schema) {
String schemaType = super.getSchemaType(schema);
if(ModelUtils.isArraySchema(schema)) {
ArraySchema arraySchema = (ArraySchema) schema;
String complexType = getSchemaType(arraySchema.getItems());
StringBuilder sb = new StringBuilder("list(");
sb.append(complexType);
Integer minItems = schema.getMinItems();
Integer maxItems = schema.getMaxItems();
if(minItems != null) sb.append(", ").append(minItems);
if(minItems != null && maxItems != null) sb.append(", ").append(maxItems);
return sb.append(")").toString();
} else if(ModelUtils.isIntegerSchema(schema)) {
StringBuilder sb = new StringBuilder("integer(");
BigDecimal min = schema.getMinimum();
BigDecimal max = schema.getMaximum();
if(min != null) sb.append(min);
if(min != null && max != null) sb.append(", ").append(max);
return sb.append(")").toString();
} else if(ModelUtils.isDateSchema(schema) || ModelUtils.isDateTimeSchema(schema)) {
return typeMapping.get(schemaType);
} else if(ModelUtils.isStringSchema(schema)) {
StringBuilder sb = new StringBuilder("binary(");
Integer min = schema.getMinLength();
Integer max = schema.getMaxLength();
if(min != null) sb.append(min);
if(min != null && max != null) sb.append(", ").append(max);
return sb.append(")").toString();
} else if (typeMapping.containsKey(schemaType)) {
return typeMapping.get(schemaType);
} else {
return getTypeDeclaration(toModelName(snakeCase(schemaType)));
}
}
@Override
public void processOpts() {
super.processOpts();
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("length", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(length(fragment.context()));
}
});
additionalProperties.put("qsEncode", new Mustache.Lambda() {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
writer.write(qsEncode(fragment.context()));
}
});
modelPackage = packageName;
apiPackage = packageName;
supportingFiles.add(new SupportingFile("rebar.config.mustache", "", "rebar.config"));
supportingFiles.add(new SupportingFile("app.src.mustache", "", "src" + File.separator +
this.packageName + ".app.src"));
supportingFiles.add(new SupportingFile("utils.mustache", "", "src" + File.separator +
this.packageName + "_utils.erl"));
supportingFiles.add(new SupportingFile("gen.mustache", "", "src" + File.separator + this
.packageName + "_gen.erl"));
supportingFiles.add(new SupportingFile("include.mustache", "", "src" + File.separator +
this.packageName + ".hrl"));
supportingFiles.add(new SupportingFile("statem.hrl.mustache", "", "src" + File.separator +
this.packageName + "_statem.hrl"));
supportingFiles.add(new SupportingFile("test.mustache", "", "test" + File.separator +
"prop_" + this.packageName + ".erl"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
private String qsEncode(Object o) {
String r = "";
CodegenParameter q = (CodegenParameter) o;
if (q.required) {
if (q.isListContainer) {
r += "[{<<\"" + q.baseName + "\">>, X} || X <- " + q.paramName + "]";
} else {
r += "{<<\"" + q.baseName + "\">>, " + q.paramName + "}";
}
}
return r;
}
@Override
public String escapeReservedWord(String name) {
// Can't start with an underscore, as our fields need to start with an
// UppercaseLetter so that Go treats them as public/visible.
// Options?
// - MyName
// - AName
// - TheName
// - XName
// - X_Name
// ... or maybe a suffix?
// - Name_ ... think this will work.
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return camelize(name) + '_';
}
@Override
public String apiFileFolder() {
return outputFolder + File.separator + sourceFolder + File.separator;
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator
+ sourceFolder + File.separator
+ modelFolder + File.separator;
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = sanitizeName(name.replaceAll("-", "_"));
// for reserved word or word starting with number, append _
if (isReservedWord(name))
name = escapeReservedWord(name);
return name;
}
@Override
public String toParamName(String name) {
return camelize(toVarName(name));
}
@Override
public String toArrayModelParamName(String name) {
if (name == null) {
LOGGER.warn("parameter name for array model is null. Default to 'array_model'.");
name = "array_model";
}
if (name.indexOf(":") > 0) {
name = name.substring(0, name.indexOf(":")) + "_array";
}
return toParamName(name);
}
@Override
public String toModelName(String name) {
return this.packageName + "_" + underscore(name.replaceAll("-", "_").replaceAll("\\.", "_"));
}
@Override
public String toApiName(String name) {
return this.packageName;
}
@Override
public String toModelFilename(String name) {
return this.packageName + "_" + underscore(name.replaceAll("\\.", "_"));
}
@Override
public String toApiFilename(String name) {
return toApiName(name);
}
@Override
public String toOperationId(String operationId) {
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + underscore(sanitizeName("call_" + operationId)).replaceAll("\\.", "_"));
operationId = "call_" + operationId;
}
return underscore(operationId.replaceAll("\\.", "_"));
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> os = (List<CodegenOperation>) operations.get("operation");
List<ExtendedCodegenOperation> newOs = new ArrayList<>();
Pattern pattern = Pattern.compile("\\{([^\\}]+)\\}");
for (CodegenOperation o : os) {
// force http method to lower case
o.httpMethod = o.httpMethod.toLowerCase(Locale.ROOT);
if (o.isListContainer) {
o.returnType = "[" + o.returnBaseType + "]";
}
Matcher matcher = pattern.matcher(o.path);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
String pathTemplateName = matcher.group(1);
matcher.appendReplacement(buffer, "\", " + camelize(pathTemplateName) + ", \"");
}
matcher.appendTail(buffer);
ExtendedCodegenOperation eco = new ExtendedCodegenOperation(o);
if (buffer.length() == 0) {
eco.setReplacedPathName(o.path);
} else {
eco.setReplacedPathName(buffer.toString());
}
newOs.add(eco);
}
operations.put("operation", newOs);
return objs;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
String length(Object os) {
int l = 1;
for (CodegenParameter o : ((ExtendedCodegenOperation) os).allParams) {
if (o.required)
l++;
}
return Integer.toString(l);
}
private int lengthRequired(List<CodegenParameter> allParams) {
int l = 0;
for (CodegenParameter o : allParams) {
if (o.required || o.isBodyParam)
l++;
}
return l;
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
class CodegenArrayModel extends CodegenModel {
Integer minItems;
Integer maxItems;
public CodegenArrayModel(CodegenModel cm, ArraySchema schema) {
super();
// Copy all fields of CodegenModel
this.parent = cm.parent;
this.parentSchema = cm.parentSchema;
this.parentModel = cm.parentModel;
this.interfaceModels = cm.interfaceModels;
this.children = cm.children;
this.name = cm.name;
this.classname = cm.classname;
this.title = cm.title;
this.description = cm.description;
this.classVarName = cm.classVarName;
this.modelJson = cm.modelJson;
this.dataType = cm.dataType;
this.xmlPrefix = cm.xmlPrefix;
this.xmlNamespace = cm.xmlNamespace;
this.xmlName = cm.xmlName;
this.classFilename = cm.classFilename;
this.unescapedDescription = cm.unescapedDescription;
this.discriminator = cm.discriminator;
this.defaultValue = cm.defaultValue;
this.arrayModelType = cm.arrayModelType;
this.isAlias = cm.isAlias;
this.vars = cm.vars;
this.requiredVars = cm.requiredVars;
this.optionalVars = cm.optionalVars;
this.readOnlyVars = cm.readOnlyVars;
this.readWriteVars = cm.readWriteVars;
this.allVars = cm.allVars;
this.parentVars = cm.parentVars;
this.allowableValues = cm.allowableValues;
this.mandatory = cm.mandatory;
this.allMandatory = cm.allMandatory;
this.imports = cm.imports;
this.hasVars = cm.hasVars;
this.emptyVars = cm.emptyVars;
this.hasMoreModels = cm.hasMoreModels;
this.hasEnums = cm.hasEnums;
this.isEnum = cm.isEnum;
this.hasRequired = cm.hasRequired;
this.hasOptional = cm.hasOptional;
this.isArrayModel = cm.isArrayModel;
this.hasChildren = cm.hasChildren;
this.hasOnlyReadOnly = cm.hasOnlyReadOnly;
this.externalDocumentation = cm.externalDocumentation;
this.vendorExtensions = cm.vendorExtensions;
this.additionalPropertiesType = cm.additionalPropertiesType;
this.minItems = schema.getMinItems();
this.maxItems = schema.getMaxItems();
}
}
class ExtendedCodegenOperation extends CodegenOperation {
private String replacedPathName;
String arity;
ExtendedCodegenOperation(CodegenOperation o) {
super();
// Copy all fields of CodegenOperation
this.responseHeaders.addAll(o.responseHeaders);
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
this.subresourceOperation = o.subresourceOperation;
this.isMapContainer = o.isMapContainer;
this.isListContainer = o.isListContainer;
this.isMultipart = o.isMultipart;
this.hasMore = o.hasMore;
this.isResponseBinary = o.isResponseBinary;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;
this.httpMethod = o.httpMethod;
this.returnBaseType = o.returnBaseType;
this.returnContainer = o.returnContainer;
this.summary = o.summary;
this.unescapedNotes = o.unescapedNotes;
this.notes = o.notes;
this.baseName = o.baseName;
this.defaultResponse = o.defaultResponse;
this.discriminator = o.discriminator;
this.consumes = o.consumes;
this.produces = o.produces;
this.bodyParam = o.bodyParam;
this.allParams = o.allParams;
this.arity = Integer.toString(lengthRequired(o.allParams));
this.bodyParams = o.bodyParams;
this.pathParams = o.pathParams;
this.queryParams = o.queryParams;
this.headerParams = o.headerParams;
this.formParams = o.formParams;
this.authMethods = o.authMethods;
this.tags = o.tags;
this.responses = o.responses;
this.imports = o.imports;
this.examples = o.examples;
this.externalDocs = o.externalDocs;
this.vendorExtensions = o.vendorExtensions;
this.nickname = o.nickname;
this.operationIdLowerCase = o.operationIdLowerCase;
this.operationIdCamelCase = o.operationIdCamelCase;
}
public String getReplacedPathName() {
return replacedPathName;
}
public void setReplacedPathName(String replacedPathName) {
this.replacedPathName = replacedPathName;
}
}
}

View File

@ -30,7 +30,7 @@ public class JavaJerseyServerCodegen extends AbstractJavaJAXRSServerCodegen {
protected static final String LIBRARY_JERSEY2 = "jersey2";
/**
* Default library template to use. (Default:{@value #DEFAULT_JERSEY_LIBRARY})
* Default library template to use. (Default: jersey2)
*/
public static final String DEFAULT_JERSEY_LIBRARY = LIBRARY_JERSEY2;
public static final String USE_TAGS = "useTags";

View File

@ -18,6 +18,8 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.examples.Example;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.slf4j.Logger;
@ -536,6 +538,34 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
p.example = example;
}
/**
* Return the example value of the parameter. Overrides the
* setParameterExampleValue(CodegenParameter, Parameter) method in
* DefaultCodegen to always call setParameterExampleValue(CodegenParameter)
* in this class, which adds single quotes around strings from the
* x-example property.
*
* @param codegenParameter Codegen parameter
* @param parameter Parameter
*/
public void setParameterExampleValue(CodegenParameter codegenParameter, Parameter parameter) {
if (parameter.getExample() != null) {
codegenParameter.example = parameter.getExample().toString();
} else if (parameter.getExamples() != null && !parameter.getExamples().isEmpty()) {
Example example = parameter.getExamples().values().iterator().next();
if (example.getValue() != null) {
codegenParameter.example = example.getValue().toString();
}
} else {
Schema schema = parameter.getSchema();
if (schema != null && schema.getExample() != null) {
codegenParameter.example = schema.getExample().toString();
}
}
setParameterExampleValue(codegenParameter);
}
public void setGemName(String gemName) {
this.gemName = gemName;
}

View File

@ -20,6 +20,7 @@ package org.openapitools.codegen.languages;
import com.google.common.base.Strings;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.StringUtils;
@ -310,9 +311,17 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
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 "Vec<" + getTypeDeclaration(inner) + ">";
} 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");
}
return "::std::collections::HashMap<String, " + getTypeDeclaration(inner) + ">";
}

View File

@ -177,8 +177,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
"Rust crate name (convention: snake_case).")
.defaultValue("openapi_client"));
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION,
"Rust crate version.")
.defaultValue("1.0.0"));
"Rust crate version."));
/*
* Additional Properties. These values can be passed to the templates and
@ -224,8 +223,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
} else {
setPackageVersion("1.0.0");
}
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
@ -477,6 +474,10 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
return mimetype.toLowerCase(Locale.ROOT).startsWith("text/plain");
}
boolean isMimetypeHtmlText(String mimetype) {
return mimetype.toLowerCase(Locale.ROOT).startsWith("text/html");
}
boolean isMimetypeWwwFormUrlEncoded(String mimetype) {
return mimetype.toLowerCase(Locale.ROOT).startsWith("application/x-www-form-urlencoded");
}
@ -547,6 +548,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
consumesXml = true;
} else if (isMimetypePlainText(mimeType)) {
consumesPlainText = true;
} else if (isMimetypeHtmlText(mimeType)) {
consumesPlainText = true;
} else if (isMimetypeWwwFormUrlEncoded(mimeType)) {
additionalProperties.put("usesUrlEncodedForm", true);
}
@ -573,6 +576,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
producesXml = true;
} else if (isMimetypePlainText(mimeType)) {
producesPlainText = true;
} else if (isMimetypeHtmlText(mimeType)) {
producesPlainText = true;
}
mediaType.put("mediaType", mimeType);
@ -665,7 +670,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
if (isMimetypeXml(mediaType)) {
additionalProperties.put("usesXml", true);
consumesXml = true;
} else if (isMimetypePlainText(mediaType)) {
} else if (isMimetypePlainText(mediaType) || isMimetypeHtmlText(mediaType)) {
consumesPlainText = true;
} else if (isMimetypeWwwFormUrlEncoded(mediaType)) {
additionalProperties.put("usesUrlEncodedForm", true);

View File

@ -472,7 +472,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
@Override
public String toModelFilename(String name) {
return this.sanitizeName(this.convertUsingFileNamingConvention(name) + modelFileSuffix);
return this.convertUsingFileNamingConvention(this.sanitizeName(name) + modelFileSuffix);
}
@Override

View File

@ -80,7 +80,7 @@ public class ApiClient {
private HttpLoggingInterceptor loggingInterceptor;
/*
* Constructor for ApiClient
* Basic constructor for ApiClient
*/
public ApiClient() {
init();
@ -94,13 +94,23 @@ public class ApiClient {
}
{{#authMethods}}{{#isOAuth}}
/*
* Constructor for ApiClient to support access token retry on 401/403
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID
*/
public ApiClient(
String clientId,
String clientSecret,
Map<String, String> parameters
) {
public ApiClient(String clientId) {
this(clientId, null, null);
}
/*
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID and additional parameters
*/
public ApiClient(String clientId, Map<String, String> parameters) {
this(clientId, null, parameters);
}
/*
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID, secret, and additional parameters
*/
public ApiClient(String clientId, String clientSecret, Map<String, String> parameters) {
init();
RetryingOAuth retryingOAuth = new RetryingOAuth("{{tokenUrl}}", clientId, OAuthFlow.{{flow}}, clientSecret, parameters);

View File

@ -206,8 +206,8 @@
{{#useBeanValidation}}
<beanvalidation-version>1.1.0.Final</beanvalidation-version>
{{/useBeanValidation}}
<cxf-version>3.2.5</cxf-version>
<jackson-jaxrs-version>2.9.6</jackson-jaxrs-version>
<cxf-version>3.2.7</cxf-version>
<jackson-jaxrs-version>2.9.7</jackson-jaxrs-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -263,8 +263,8 @@
{{#generateSpringBootApplication}}
<spring.boot-version>1.5.9.RELEASE</spring.boot-version>
{{/generateSpringBootApplication}}
<cxf-version>3.2.5</cxf-version>
<jackson-jaxrs-version>2.9.6</jackson-jaxrs-version>
<cxf-version>3.2.7</cxf-version>
<jackson-jaxrs-version>2.9.7</jackson-jaxrs-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -79,7 +79,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{^parent}}
* maximum: {{maximum}}
{{/maximum}}
* @return {{name}}
**/
*/
{{#vendorExtensions.extraAnnotation}}
{{{vendorExtensions.extraAnnotation}}}
{{/vendorExtensions.extraAnnotation}}

View File

@ -22,6 +22,7 @@ org.openapitools.codegen.languages.EiffelClientCodegen
org.openapitools.codegen.languages.ElixirClientCodegen
org.openapitools.codegen.languages.ElmClientCodegen
org.openapitools.codegen.languages.ErlangClientCodegen
org.openapitools.codegen.languages.ErlangProperCodegen
org.openapitools.codegen.languages.ErlangServerCodegen
org.openapitools.codegen.languages.FlashClientCodegen
org.openapitools.codegen.languages.FinchServerCodegen

View File

@ -73,7 +73,7 @@ void {{classname}}::{{operationIdSnakeCase}}_handler(const Pistache::Rest::Reque
nlohmann::json request_body = nlohmann::json::parse(request.body());
{{^isPrimitiveType}}{{^isContainer}}
{{paramName}}.fromJson(request_body);
{{/isContainer}}{{/isPrimitiveType}}{{#isContainer}} {{paramName}} = {{#isListContainer}} {{prefix}}ModelArrayHelper{{/isListContainer}}{{#isMapContainer}} {{prefix}}ModelMapHelper{{/isMapContainer}}::fromJson<{{items.baseType}}>(request_body);{{/isContainer}}
{{/isContainer}}{{/isPrimitiveType}}{{#isContainer}} {{paramName}} = {{#isListContainer}} {{prefix}}ArrayHelper{{/isListContainer}}{{#isMapContainer}} {{prefix}}MapHelper{{/isMapContainer}}::fromJson<{{items.baseType}}>(request_body);{{/isContainer}}
{{#isPrimitiveType}}
// The conversion is done automatically by the json library
{{paramName}} = request_body;

View File

@ -34,7 +34,7 @@ public:
void validate() override;
nlohmann::json toJson() const override;
void fromJson(nlohmann::json& json) override;
void fromJson(const nlohmann::json& json) override;
/////////////////////////////////////////////
/// {{classname}} members

View File

@ -45,20 +45,34 @@ nlohmann::json {{classname}}::toJson() const
if(jsonArray.size() > 0)
{
val["{{baseName}}"] = jsonArray;
}
{{/required}}
} {{/required}}
}
{{/isListContainer}}{{^isListContainer}}{{^isPrimitiveType}}{{^required}}if(m_{{name}}IsSet)
{{/isListContainer}}{{#isMapContainer}}{
nlohmann::json jsonObj;
for( auto const& item : m_{{name}} )
{ {{^items.isContainer}}
jsonObj[item.first] = {{prefix}}ModelBase::toJson(item.second);{{/items.isContainer}} {{#items.isListContainer}}
jsonObj[item.first] = {{prefix}}ArrayHelper::toJson<{{{items.items.datatype}}}>(item.second);
{{/items.isListContainer}} {{#items.isMapContainer}}
jsonObj[item.first] = {{prefix}}MapHelper::toJson<{{{items.items.datatype}}}>(item.second); {{/items.isMapContainer}}
}
{{#required}}val["{{baseName}}"] = jsonObj; {{/required}}{{^required}}
if(jsonObj.size() > 0)
{
val["{{baseName}}"] = jsonObj;
} {{/required}}
}
{{/isMapContainer}}{{^isContainer}}{{^isPrimitiveType}}{{^required}}if(m_{{name}}IsSet)
{
val["{{baseName}}"] = {{prefix}}ModelBase::toJson(m_{{name}});
}
{{/required}}{{#required}}val["{{baseName}}"] = {{prefix}}ModelBase::toJson(m_{{name}});
{{/required}}{{/isPrimitiveType}}{{/isListContainer}}{{/vars}}
{{/required}}{{/isPrimitiveType}}{{/isContainer}}{{/vars}}
return val;
}
void {{classname}}::fromJson(nlohmann::json& val)
void {{classname}}::fromJson(const nlohmann::json& val)
{
{{#vars}}{{#isPrimitiveType}}{{^isListContainer}}{{^required}}if(val.find("{{baseName}}") != val.end())
{
@ -67,33 +81,53 @@ void {{classname}}::fromJson(nlohmann::json& val)
{{/required}}{{#required}}{{setter}}(val.at("{{baseName}}"));
{{/required}}{{/isListContainer}}{{/isPrimitiveType}}{{#isListContainer}}{
m_{{name}}.clear();
nlohmann::json jsonArray;
{{^required}}if(val.find("{{baseName}}") != val.end())
{
{{/required}}
for( auto& item : val["{{baseName}}"] )
{
{{#isPrimitiveType}}m_{{name}}.push_back(item);
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#items.isString}}m_{{name}}.push_back(item);
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}m_{{name}}.push_back(item);
{{/items.isDateTime}}{{^items.isDateTime}}
if(item.is_null())
for( auto& item : val["{{baseName}}"] )
{
m_{{name}}.push_back( {{{items.datatype}}}() );
{{#isPrimitiveType}}m_{{name}}.push_back(item);
{{/isPrimitiveType}}{{^isPrimitiveType}}{{#items.isString}}m_{{name}}.push_back(item);
{{/items.isString}}{{^items.isString}}{{#items.isDateTime}}m_{{name}}.push_back(item);
{{/items.isDateTime}}{{^items.isDateTime}}
if(item.is_null())
{
m_{{name}}.push_back( {{{items.datatype}}}() );
}
else
{
{{{items.datatype}}} newItem;
newItem.fromJson(item);
m_{{name}}.push_back( newItem );
}
{{/items.isDateTime}}{{/items.isString}}{{/isPrimitiveType}}
}
else
{
{{{items.datatype}}} newItem;
newItem.fromJson(item);
m_{{name}}.push_back( newItem );
}
{{/items.isDateTime}}{{/items.isString}}{{/isPrimitiveType}}
}
{{^required}}
}
{{/required}}
}
{{/isListContainer}}{{^isListContainer}}{{^isPrimitiveType}}{{^required}}if(val.find("{{baseName}}") != val.end())
{{/isListContainer}}{{#isMapContainer}}{
m_{{name}}.clear();
{{^required}}if(val.find("{{baseName}}") != val.end())
{
{{/required}}
if(val["{{baseName}}"].is_object()) { {{^items.isContainer}}
m_{{name}} = {{prefix}}MapHelper::fromJson<{{{items.datatype}}}>(val["{{baseName}}"]);
{{/items.isContainer}} {{#items.isContainer}}
for( auto& item : val["{{baseName}}"].items() )
{ {{#items.isMapContainer}}
{{{items.datatype}}} newItem = {{prefix}}MapHelper::fromJson<{{{items.items.datatype}}}>(item.value());
{{/items.isMapContainer}}{{#items.isListContainer}}
{{{items.datatype}}} newItem = {{prefix}}ArrayHelper::fromJson<{{{items.items.datatype}}}>(item.value());
{{/items.isListContainer}}
m_{{name}}.insert(m_{{name}}.end(), std::pair< std::string, {{{items.datatype}}} >(item.key(), newItem));
} {{/items.isContainer}}
}
{{^required}}
}
{{/required}}
}
{{/isMapContainer}}{{^isContainer}}{{^isPrimitiveType}}{{^required}}if(val.find("{{baseName}}") != val.end())
{
{{#isString}}{{setter}}(val.at("{{baseName}}"));{{/isString}}{{#isByteArray}}{{setter}}(val.at("{{baseName}}"));{{/isByteArray}}{{#isBinary}}{{setter}}(val.at("{{baseName}}"));
{{/isBinary}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
@ -107,7 +141,7 @@ void {{classname}}::fromJson(nlohmann::json& val)
}
{{/required}}{{#required}}{{#isString}}{{setter}}(val.at("{{baseName}}"));
{{/isString}}{{^isString}}{{#isDateTime}}{{setter}}(val.at("{{baseName}}"));
{{/isDateTime}}{{/isString}}{{/required}}{{/isPrimitiveType}}{{/isListContainer}}{{/vars}}
{{/isDateTime}}{{/isString}}{{/required}}{{/isPrimitiveType}}{{/isContainer}}{{/vars}}
}

View File

@ -28,7 +28,7 @@ public:
virtual void validate() = 0;
virtual nlohmann::json toJson() const = 0;
virtual void fromJson(nlohmann::json& json) = 0;
virtual void fromJson(const nlohmann::json& json) = 0;
static std::string toJson( std::string const& value );
static std::string toJson( std::time_t const& value );
@ -39,100 +39,85 @@ public:
static nlohmann::json toJson({{prefix}}ModelBase const& content );
};
class {{prefix}}ModelArrayHelper {
public:
template<typename T>
static std::vector<T> fromJson(nlohmann::json& json) {
T *ptrTest;
std::vector<T> val;
if (dynamic_cast<{{prefix}}ModelBase*>(ptrTest) != nullptr) {
if (!json.empty()) {
for (auto &item : json.items()) {
T entry;
entry.fromJson(item.value());
val.push_back(entry);
}
}
}
return val;
}
template<typename T>
static nlohmann::json toJson(std::vector<T> val) {
nlohmann::json json;
for(auto item : val){
json.push_back(item.toJson());
}
return json;
}
};
class {{prefix}}ArrayHelper {
private:
template<typename T, typename std::enable_if<!std::is_base_of<ModelBase, T>::value>::value>
static void itemFromJson(T& item, const nlohmann::json& json){
item = json;
}
static void itemFromJson(ModelBase& item, const nlohmann::json& json){
item.fromJson(json);
}
template<typename T, typename std::enable_if<!std::is_base_of<ModelBase, T>::value>::value>
static nlohmann::json itemtoJson(const T& item){
return item;
}
static nlohmann::json itemtoJson(const ModelBase& item){
return item.toJson();
}
public:
template<typename T>
static std::vector<T> fromJson(nlohmann::json& json) {
std::vector<T> val;
nlohmann::from_json(json, val);
return val;
}
template<typename T>
static nlohmann::json toJson(std::vector<T> val) {
nlohmann::json json;
nlohmann::to_json(json, val);
return json;
}
};
class {{prefix}}ModelMapHelper {
public:
template<typename T>
static std::map<std::string, T> & fromJson(nlohmann::json& json) {
T *ptrTest;
std::map<std::string, T> val;
if (dynamic_cast<{{prefix}}ModelBase*>(ptrTest) != nullptr) {
if (!json.empty()) {
for (auto &item : json.items()) {
T entry;
entry.fromJson(item.value());
val.insert(val.end(),
std::pair<std::string, T>(item.key(), entry));
}
}
}
return val;
}
template<typename T>
static nlohmann::json toJson(std::map<std::string, T> val) {
nlohmann::json json;
for (auto const& item : val) {
json[item.first] = item.second.toJson();
}
return json;
}
template<typename T>
static std::vector<T> fromJson(const nlohmann::json& json) {
std::vector<T> val;
if (!json.empty()) {
for (const auto& item : json.items()) {
T entry;
itemFromJson(entry, item.value());
val.push_back(entry);
}
}
return val;
}
template<typename T>
static nlohmann::json toJson(const std::vector<T>& val) {
nlohmann::json json;
for(const auto& item : val){
json.push_back(itemtoJson(item));
}
return json;
}
};
class {{prefix}}MapHelper {
private:
template<typename T, typename std::enable_if<!std::is_base_of<ModelBase, T>::value>::value>
static void itemFromJson(T &item, const nlohmann::json& json){
item = json;
}
static void itemFromJson(ModelBase &item, const nlohmann::json& json){
item.fromJson(json);
}
template<typename T, typename std::enable_if<!std::is_base_of<ModelBase, T>::value>::value>
static nlohmann::json itemtoJson(const T& item){
return item;
}
static nlohmann::json itemtoJson(const ModelBase& item){
return item.toJson();
}
public:
template<typename T>
static std::map<std::string, T> & fromJson(nlohmann::json& json) {
std::map<std::string, T> val;
if (!json.empty()) {
for (auto &item : json.items()) {
T entry = item.value();
val.insert(val.end(),
std::pair<std::string, T>(item.key(), entry));
}
}
return val;
}
template<typename T>
static nlohmann::json toJson(std::map<std::string, T> val) {
nlohmann::json json;
for (auto const& item : val) {
nlohmann::json jitem = item.second;
json[item.first] = jitem;
}
return json;
}
template<typename T>
static std::map<std::string, T> fromJson(const nlohmann::json& json) {
std::map<std::string, T> val;
if (!json.empty()) {
for (const auto& item : json.items()) {
T entry;
itemfromJson(entry, item.value());
val.insert(val.end(),
std::pair<std::string, T>(item.key(), entry));
}
}
return val;
}
template<typename T>
static nlohmann::json toJson(const std::map<std::string, T>& val) {
nlohmann::json json;
for (const auto& item : val) {
nlohmann::json jitem = itemtoJson(item.second);
json[item.first] = jitem;
}
return json;
}
};
{{#modelNamespaceDeclarations}}

View File

@ -3,6 +3,18 @@
#include "MultipartFormData.h"
#include "ModelBase.h"
#include <sstream>
#include <limits>
#include <iomanip>
template <typename T>
utility::string_t toString(const T value)
{
std::ostringstream out;
out << std::setprecision(std::numeric_limits<T>::digits10) << std::fixed << value;
return out.str();
}
{{#apiNamespaceDeclarations}}
namespace {{this}} {
{{/apiNamespaceDeclarations}}
@ -46,12 +58,12 @@ utility::string_t ApiClient::parameterToString(int32_t value)
utility::string_t ApiClient::parameterToString(float value)
{
return utility::conversions::to_string_t(std::to_string(value));
return utility::conversions::to_string_t(toString(value));
}
utility::string_t ApiClient::parameterToString(double value)
{
return utility::conversions::to_string_t(std::to_string(value));
return utility::conversions::to_string_t(toString(value));
}
utility::string_t ApiClient::parameterToString(const utility::datetime &value)

View File

@ -36,7 +36,7 @@ public:
void validate() override;
web::json::value toJson() const override;
void fromJson(web::json::value& json) override;
void fromJson(const web::json::value& json) override;
void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const override;
void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) override;
@ -54,7 +54,14 @@ public:
{{/isNotContainer}}{{^required}}bool {{nameInCamelCase}}IsSet() const;
void unset{{name}}();
{{/required}}
{{#isPrimitiveType}}
void {{setter}}({{{dataType}}} value);
{{/isPrimitiveType}}
{{^isPrimitiveType}}
void {{setter}}(const {{{dataType}}}& value);
{{/isPrimitiveType}}
{{/isInherited}}
{{/vars}}

View File

@ -126,7 +126,7 @@ web::json::value {{classname}}::toJson() const
return val;
}
void {{classname}}::fromJson(web::json::value& val)
void {{classname}}::fromJson(const web::json::value& val)
{
{{#parent}}
this->{{{parent}}}::fromJson(val);
@ -140,7 +140,7 @@ void {{classname}}::fromJson(web::json::value& val)
{{^required}}
if(val.has_field(utility::conversions::to_string_t("{{baseName}}")))
{
web::json::value& fieldValue = val[utility::conversions::to_string_t("{{baseName}}")];
const web::json::value& fieldValue = val.at(utility::conversions::to_string_t("{{baseName}}"));
if(!fieldValue.is_null())
{
{{setter}}(ModelBase::{{baseType}}FromJson(fieldValue));
@ -148,7 +148,7 @@ void {{classname}}::fromJson(web::json::value& val)
}
{{/required}}
{{#required}}
{{setter}}(ModelBase::{{baseType}}FromJson(val[utility::conversions::to_string_t("{{baseName}}")]));
{{setter}}(ModelBase::{{baseType}}FromJson(val.at(utility::conversions::to_string_t("{{baseName}}"))));
{{/required}}
{{/isMapContainer}}
{{/isListContainer}}
@ -161,7 +161,7 @@ void {{classname}}::fromJson(web::json::value& val)
if(val.has_field(utility::conversions::to_string_t("{{baseName}}")))
{
{{/required}}
for( auto& item : val[utility::conversions::to_string_t("{{baseName}}")].as_array() )
for( auto& item : val.at(utility::conversions::to_string_t("{{baseName}}")).as_array() )
{
{{#items.isPrimitiveType}}
m_{{name}}.push_back(ModelBase::{{items.baseType}}FromJson(item));
@ -202,21 +202,21 @@ void {{classname}}::fromJson(web::json::value& val)
if(val.has_field(utility::conversions::to_string_t("{{baseName}}")))
{
{{/required}}
for( auto& item : val[utility::conversions::to_string_t("{{baseName}}")].as_array() )
for( const auto& item : val.at(utility::conversions::to_string_t("{{baseName}}")).as_array() )
{
if(item.has_field(utility::conversions::to_string_t("key")))
{
utility::string_t key = ModelBase::stringFromJson(item[utility::conversions::to_string_t("key")]);
utility::string_t key = ModelBase::stringFromJson(item.at(utility::conversions::to_string_t("key")));
{{#items.isPrimitiveType}}
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, ModelBase::{{items.baseType}}FromJson(item[utility::conversions::to_string_t("value")])));
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, ModelBase::{{items.baseType}}FromJson(item.at(utility::conversions::to_string_t("value")))));
{{/items.isPrimitiveType}}
{{^items.isPrimitiveType}}
{{#items.isString}}
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, ModelBase::stringFromJson(item[utility::conversions::to_string_t("value")])));
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, ModelBase::stringFromJson(item.at(utility::conversions::to_string_t("value")))));
{{/items.isString}}
{{^items.isString}}
{{#items.isDateTime}}
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, ModelBase::dateFromJson(item[utility::conversions::to_string_t("value")])));
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, ModelBase::dateFromJson(item.at(utility::conversions::to_string_t("value")))));
{{/items.isDateTime}}
{{^items.isDateTime}}
if(item.is_null())
@ -226,7 +226,7 @@ void {{classname}}::fromJson(web::json::value& val)
else
{
{{{items.datatype}}} newItem({{{items.defaultValue}}});
newItem->fromJson(item[utility::conversions::to_string_t("value")]);
newItem->fromJson(item.at(utility::conversions::to_string_t("value")));
m_{{name}}.insert(std::pair<utility::string_t,{{{items.datatype}}}>( key, newItem ));
}
{{/items.isDateTime}}
@ -245,7 +245,7 @@ void {{classname}}::fromJson(web::json::value& val)
{{^required}}
if(val.has_field(utility::conversions::to_string_t("{{baseName}}")))
{
web::json::value& fieldValue = val[utility::conversions::to_string_t("{{baseName}}")];
const web::json::value& fieldValue = val.at(utility::conversions::to_string_t("{{baseName}}"));
if(!fieldValue.is_null())
{
{{#isString}}
@ -271,7 +271,7 @@ void {{classname}}::fromJson(web::json::value& val)
{{/required}}
{{#required}}
{{#isString}}
{{setter}}(ModelBase::stringFromJson(val[utility::conversions::to_string_t("{{baseName}}")]));
{{setter}}(ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("{{baseName}}"))));
{{/isString}}
{{#isByteArray}}
{{setter}}(ModelBase::stringFromJson(val[utility::conversions::to_string_t("{{baseName}}")]));
@ -280,15 +280,15 @@ void {{classname}}::fromJson(web::json::value& val)
{{^isByteArray}}
{{#isDateTime}}
{{setter}}
(ModelBase::dateFromJson(val[utility::conversions::to_string_t("{{baseName}}")]));
(ModelBase::dateFromJson(val.at(utility::conversions::to_string_t("{{baseName}}"))));
{{/isDateTime}}
{{^isDateTime}}
{{#vendorExtensions.x-codegen-file}}
{{setter}}(ModelBase::fileFromJson(val[utility::conversions::to_string_t("{{baseName}}")]));
{{setter}}(ModelBase::fileFromJson(val.at(utility::conversions::to_string_t("{{baseName}}"))));
{{/vendorExtensions.x-codegen-file}}
{{^vendorExtensions.x-codegen-file}}
{{{dataType}}} new{{name}}({{{defaultValue}}});
new{{name}}->fromJson(val[utility::conversions::to_string_t("{{baseName}}")]);
new{{name}}->fromJson(val.at(utility::conversions::to_string_t("{{baseName}}")));
{{setter}}( new{{name}} );
{{/vendorExtensions.x-codegen-file}}
{{/isDateTime}}
@ -596,26 +596,25 @@ void {{classname}}::fromMultiPart(std::shared_ptr<MultipartFormData> multipart,
{
return m_{{name}};
}
void {{classname}}::{{setter}}({{{dataType}}} value)
{
m_{{name}} = value;
{{^required}}m_{{name}}IsSet = true;{{/required}}
}
{{/isNotContainer}}
{{#isNotContainer}}
{{{dataType}}} {{classname}}::{{getter}}() const
{
return m_{{name}};
}
{{/isNotContainer}}
{{#isPrimitiveType}}
void {{classname}}::{{setter}}({{{dataType}}} value)
{{/isPrimitiveType}}
{{^isPrimitiveType}}
void {{classname}}::{{setter}}(const {{{dataType}}}& value)
{{/isPrimitiveType}}
{
m_{{name}} = value;
{{^required}}m_{{name}}IsSet = true;{{/required}}
}
{{/isNotContainer}}
{{^required}}
bool {{classname}}::{{nameInCamelCase}}IsSet() const
{

View File

@ -30,7 +30,7 @@ public:
virtual void validate() = 0;
virtual web::json::value toJson() const = 0;
virtual void fromJson(web::json::value& json) = 0;
virtual void fromJson(const web::json::value& json) = 0;
virtual void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const = 0;
virtual void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) = 0;
@ -46,14 +46,14 @@ public:
template<class T>
static web::json::value toJson(const std::vector<T>& value);
static int64_t int64_tFromJson(web::json::value& val);
static int32_t int32_tFromJson(web::json::value& val);
static float floatFromJson(web::json::value& val);
static utility::string_t stringFromJson(web::json::value& val);
static utility::datetime dateFromJson(web::json::value& val);
static double doubleFromJson(web::json::value& val);
static bool boolFromJson(web::json::value& val);
static std::shared_ptr<HttpContent> fileFromJson(web::json::value& val);
static int64_t int64_tFromJson(const web::json::value& val);
static int32_t int32_tFromJson(const web::json::value& val);
static float floatFromJson(const web::json::value& val);
static utility::string_t stringFromJson(const web::json::value& val);
static utility::datetime dateFromJson(const web::json::value& val);
static double doubleFromJson(const web::json::value& val);
static bool boolFromJson(const web::json::value& val);
static std::shared_ptr<HttpContent> fileFromJson(const web::json::value& val);
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const utility::string_t& value, const utility::string_t& contentType = utility::conversions::to_string_t(""));
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const utility::datetime& value, const utility::string_t& contentType = utility::conversions::to_string_t(""));

View File

@ -46,25 +46,25 @@ web::json::value ModelBase::toJson( std::shared_ptr<HttpContent> content )
return value;
}
std::shared_ptr<HttpContent> ModelBase::fileFromJson(web::json::value& val)
std::shared_ptr<HttpContent> ModelBase::fileFromJson(const web::json::value& val)
{
std::shared_ptr<HttpContent> content(new HttpContent);
if(val.has_field(utility::conversions::to_string_t("ContentDisposition")))
{
content->setContentDisposition( ModelBase::stringFromJson(val[utility::conversions::to_string_t("ContentDisposition")]) );
content->setContentDisposition( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("ContentDisposition"))) );
}
if(val.has_field(utility::conversions::to_string_t("ContentType")))
{
content->setContentType( ModelBase::stringFromJson(val[utility::conversions::to_string_t("ContentType")]) );
content->setContentType( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("ContentType"))) );
}
if(val.has_field(utility::conversions::to_string_t("FileName")))
{
content->setFileName( ModelBase::stringFromJson(val[utility::conversions::to_string_t("FileName")]) );
content->setFileName( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("FileName"))) );
}
if(val.has_field(utility::conversions::to_string_t("InputStream")))
{
content->setData( ModelBase::fromBase64( ModelBase::stringFromJson(val[utility::conversions::to_string_t("InputStream")]) ) );
content->setData( ModelBase::fromBase64( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("InputStream")))) );
}
return content;
@ -263,32 +263,32 @@ std::shared_ptr<std::istream> ModelBase::fromBase64( const utility::string_t& en
return result;
}
int64_t ModelBase::int64_tFromJson(web::json::value& val)
int64_t ModelBase::int64_tFromJson(const web::json::value& val)
{
return val.as_number().to_int64();
}
int32_t ModelBase::int32_tFromJson(web::json::value& val)
int32_t ModelBase::int32_tFromJson(const web::json::value& val)
{
return val.as_integer();
}
float ModelBase::floatFromJson(web::json::value& val)
float ModelBase::floatFromJson(const web::json::value& val)
{
return static_cast<float>(val.as_double());
}
utility::string_t ModelBase::stringFromJson(web::json::value& val)
utility::string_t ModelBase::stringFromJson(const web::json::value& val)
{
return val.is_string() ? val.as_string() : utility::conversions::to_string_t("");
}
utility::datetime ModelBase::dateFromJson(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);
}
bool ModelBase::boolFromJson(web::json::value& val)
bool ModelBase::boolFromJson(const web::json::value& val)
{
return val.as_bool();
}
double ModelBase::doubleFromJson(web::json::value& val)
double ModelBase::doubleFromJson(const web::json::value& val)
{
return val.as_double();
}

View File

@ -29,7 +29,7 @@ public:
void validate() override;
web::json::value toJson() const override;
void fromJson(web::json::value& json) override;
void fromJson(const web::json::value& json) override;
void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const override;
void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) override;

View File

@ -24,7 +24,7 @@ web::json::value Object::toJson() const
return m_object;
}
void Object::fromJson(web::json::value& val)
void Object::fromJson(const web::json::value& val)
{
if (val.is_object())
{

View File

@ -0,0 +1,6 @@
# OpenAPI client library for Erlang with Erlang QuickCheck generators
## Overview
An Erlang client stub and Erlang QuickCheck generators, generated by
[OpenAPI Generator](https://openapi-generator.tech) given an OpenAPI spec.

View File

@ -0,0 +1,30 @@
-module({{classname}}_api).
-export([ {{#operations}}{{#operation}}{{^-first}}
, {{/-first}}{{operationId}}/{{arity}}{{/operation}}{{/operations}}
]).
-define(BASE_URL, "{{{basePathWithoutHost}}}").
{{#operations}}
{{#operation}}
%% @doc {{{summary}}}
{{^notes.isEmpty}}
%% {{{notes}}}
{{/notes.isEmpty}}
-spec {{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{{dataType}}}{{/required}}{{/allParams}}) ->
{{packageName}}_utils:response().
{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}) ->
Method = {{httpMethod}},
Host = application:get_env({{packageName}}, host, "http://localhost:8080"),
Path = ["{{{replacedPathName}}}"],
Body = {{^formParams.isEmpty}}{form, [{{#formParams}}{{#required}}{{^-first}}, {{/-first}}{<<"{{{baseName}}}">>, {{paramName}}{{/required}}{{/formParams}}]++{{packageName}}_utils:optional_params([{{#formParams}}{{^required}}{{^-first}}, {{/-first}}'{{{baseName}}}'{{/required}}{{/formParams}}], _OptionalParams)}{{/formParams.isEmpty}}{{#formParams.isEmpty}}{{#bodyParams.isEmpty}}[]{{/bodyParams.isEmpty}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/bodyParams.isEmpty}}{{/formParams.isEmpty}},
ContentType = {{#hasConsumes}}hd([{{#consumes}}{{^-first}}, {{/-first}}"{{mediaType}}"{{/consumes}}]){{/hasConsumes}}{{^hasConsumes}}<<"text/plain">>{{/hasConsumes}},
{{^queryParams.isEmpty}}
QueryString = [{{#queryParams}}{{^-first}}, {{/-first}}<<"{{{baseName}}}=">>, {{{paramName}}}, <<"&">>{{/queryParams}}],
{{/queryParams.isEmpty}}
{{packageName}}_utils:request(Method, [Host, ?BASE_URL, Path{{^queryParams.isEmpty}}, <<"?">>, QueryString{{/queryParams.isEmpty}}], jsx:encode(Body), ContentType).
{{/operation}}
{{/operations}}

View File

@ -0,0 +1,21 @@
{ application, {{packageName}}
, [ {description, {{#appDescription}}"{{appDescription}}"{{/appDescription}}{{^appDescription}}"OpenAPI client library for EQC testing"{{/appDescription}}}
, {vsn, "{{#apiVersion}}{{apiVersion}}{{/apiVersion}}{{^apiVersion}}0.1.0{{/apiVersion}}"}
, {registered, []}
, { applications
, [ kernel
, stdlib
, ssl
, jsx
]
}
, { env
, [ {host, "http://{{#host}}{{{host}}}{{/host}}{{^host}}localhost:8080{{/host}}"}
, {basic_auth, {"admin", "admin"}}
]
}
, {modules, []}
, {maintainers, []}
, {licenses, [{{#licenseInfo}}"{{licenseInfo}}"{{/licenseInfo}}]}
, {links, [{{#infoUrl}}"{{infoUrl}}"{{/infoUrl}}]}
]}.

View File

@ -0,0 +1,157 @@
-module({{packageName}}_gen).
-compile({no_auto_import,[date/0]}).
-include_lib("proper/include/proper_common.hrl").
%%==============================================================================
%% Exports
%%==============================================================================
-export([ binary/0
, binary/1
, binary/2
, integer/0
, integer/1
, integer/2
, boolean/0
, list/0
, list/1
, list/2
, list/3
, map/0
, date/0
, datetime/0
, any/0
, elements/1
]).
-define(CHARS, [$a, $b, $c]).
%%==============================================================================
%% Generators
%%==============================================================================
binary() -> binary(10).
binary(Min, Max) ->
?LET( {X, N}
, { proper_types:elements(?CHARS)
, proper_types:choose(Min, Max)
}
, iolist_to_binary(lists:duplicate(N, X))
).
binary(N) ->
?LET( X
, proper_types:elements(?CHARS)
, iolist_to_binary(lists:duplicate(N, X))
).
integer() -> proper_types:int().
integer(0) -> proper_types:nat();
integer(Min) ->
?LET( N
, proper_types:nat()
, proper_types:choose(Min, Min + N)
).
integer(Min, Max) -> proper_types:choose(Min, Max).
boolean() -> proper_types:bool().
list() -> list(any()).
list(Type) -> proper_types:list(Type).
list(Type, Min) ->
?LET( N
, integer(0)
, ?LET(X, list(Type, Min, Min + N), X)
).
list(Type, Min, Max) when Min =< Max ->
?LET( {X, Y}
, { proper_types:vector(Min, Type)
, proper_types:resize(Max - Min, proper_types:list(Type))
}
, X ++ Y
).
map() -> proper_types:map(any(), any()).
date() ->
?LET( X
, ?SUCHTHAT( X
, { year()
, proper_types:choose(1, 12)
, proper_types:choose(1, 31)
}
, calendar:valid_date(X)
)
, begin
{Year, Month, Day} = X,
YearBin = num_binary_format(Year, "4"),
MonthBin = num_binary_format(Month, "2"),
DayBin = num_binary_format(Day, "2"),
<<YearBin/binary, "-", MonthBin/binary, "-", DayBin/binary>>
end
).
datetime() ->
Date = date(),
Hour = hour(),
?LET( X
, {Date, Hour}
, begin
{D, H} = X,
<<D/binary, "T", H/binary, "+0000">>
end
).
any() ->
Any = [ binary()
, integer()
, boolean()
%% We don't include lists and maps to avoid huge values
%% , list()
%% , map()
, date()
, datetime()
],
proper_types:oneof(Any).
elements(Items) ->
proper_types:elements(Items).
%%==============================================================================
%% Internal
%%==============================================================================
year() ->
?LET( X
, proper_types:nat()
, 1970 + X
).
hour() ->
?LET( X
, { proper_types:choose(0, 23)
, proper_types:choose(0, 59)
, proper_types:choose(0, 59)
, proper_types:choose(0, 999)
}
, begin
{Hours, Mins, Secs, Millis} = X,
HoursBin = num_binary_format(Hours, "2"),
MinsBin = num_binary_format(Mins, "2"),
SecsBin = num_binary_format(Secs, "2"),
MillisBin = num_binary_format(Millis, "3"),
<<HoursBin/binary, ":", MinsBin/binary, ":",
SecsBin/binary, ".", MillisBin/binary>>
end
).
num_binary_format(X, N) ->
list_to_binary(io_lib:format("~" ++ N ++ "..0B", [X])).

View File

@ -0,0 +1,24 @@
-compile({no_auto_import,[date/0]}).
-import( {{packageName}}_gen
, [ binary/0
, binary/1
, binary/2
, integer/0
, integer/1
, integer/2
, boolean/0
, list/0
, list/1
, list/2
, list/3
, map/0
, date/0
, datetime/0
, any/0
, elements/1
]
).
-type date() :: calendar:date().
-type datetime() :: calendar:datetime().

View File

@ -0,0 +1,26 @@
{{#models}}
{{#model}}
-module({{classname}}).
-include("{{packageName}}.hrl").
-export([{{classname}}/0]).
-export_type([{{classname}}/0]).
-type {{classname}}() ::{{#isEnum}}
binary().{{/isEnum}}{{^isEnum}}{{#isArrayModel}}
list({{arrayModelType}}).{{/isArrayModel}}{{^isArrayModel}}
[ {{#vars}}{{^-first}}
| {{/-first}}{'{{name}}', {{dataType}} }{{/vars}}
].{{/isArrayModel}}{{/isEnum}}
{{classname}}() ->{{#isEnum}}
elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]).
{{/isEnum}}{{#isArrayModel}}
list({{arrayModelType}}{{#minItems}}, {{minItems}}{{#maxItems}}, {{maxItems}}{{/maxItems}}{{/minItems}}).{{/isArrayModel}}{{^isEnum}}{{^isArrayModel}}
[ {{#vars}}{{^-first}}
, {{/-first}}{'{{baseName}}', {{#isString}}{{#isEnum}}elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]){{/isEnum}}{{^isEnum}}binary({{#minLength}}{{minLength}}{{#maxLength}}, {{maxLength}}{{/maxLength}}{{/minLength}}){{/isEnum}}{{/isString}}{{^isString}}{{baseType}}{{/isString}} }{{/vars}}
].{{/isArrayModel}}{{/isEnum}}
{{/model}}
{{/models}}

View File

@ -0,0 +1,7 @@
{erl_opts, [debug_info, warnings_as_errors]}.
{deps, [{jsx, "2.9.0"}, {proper, "1.3.0"}]}.
{shell, [{apps, [{{packageName}}]}]}.
{plugins, [rebar3_proper]}.

View File

@ -0,0 +1,25 @@
%%==============================================================================
%% Setup
%%==============================================================================
setup() -> ok.
%%==============================================================================
%% Cleanup
%%==============================================================================
cleanup() -> ok.
%%==============================================================================
%% Initial State
%%==============================================================================
initial_state() -> #{}.
%%==============================================================================
%% State transitions callbacks
%%
%% operation_pre(State) -> true.
%% operation_next(State, Result, Args) -> State.
%% operation_post(State, Args, Result) -> true.
%%==============================================================================

View File

@ -0,0 +1,105 @@
-module({{classname}}_statem).
-behaviour(proper_statem).
-include("{{packageName}}.hrl").
-include_lib("proper/include/proper_common.hrl").
-include_lib("stdlib/include/assert.hrl").
-compile(export_all).
-compile(nowarn_export_all).
%%==============================================================================
%% PropEr callbacks
%%==============================================================================
command(State) ->
Funs0 = [ {F, list_to_atom(atom_to_list(F) ++ "_args")}
|| {F, _} <- ?MODULE:module_info(exports)
],
Funs1 = [ X || {_, FArgs} = X <- Funs0,
erlang:function_exported(?MODULE, FArgs, 1)
],
proper_types:oneof([ {call, ?MODULE, F, ?MODULE:FArgs(State)}
|| {F, FArgs} <- Funs1
]).
precondition(S, {call, M, F, Args}) ->
Pre = list_to_atom(atom_to_list(F) ++ "_pre"),
case erlang:function_exported(M, Pre, 1) of
true -> M:Pre(S);
false -> true
end
andalso
case erlang:function_exported(M, Pre, 2) of
true -> M:Pre(S, Args);
false -> true
end.
next_state(S, Res, {call, M, F, Args}) ->
Next = list_to_atom(atom_to_list(F) ++ "_next"),
case erlang:function_exported(M, Next, 3) of
true -> M:Next(S, Res, Args);
false -> S
end.
postcondition(S, {call, M, F, Args}, Res) ->
Post = list_to_atom(atom_to_list(F) ++ "_post"),
case erlang:function_exported(M, Post, 3) of
true -> M:Post(S, Args, Res);
false -> true
end.
{{#operations}}
{{#operation}}
%%==============================================================================
%% {{operationId}}
%%==============================================================================
{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}) ->
{{classname}}_api:{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}).
{{operationId}}_args(S) ->
Args = [{{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{dataType}}{{/required}}{{/allParams}}],
case erlang:function_exported(?MODULE, '{{operationId}}_args_custom', 2) of
true -> ?MODULE:{{operationId}}_args_custom(S, Args);
false -> Args
end.
{{/operation}}
{{/operations}}
%%==============================================================================
%% The statem's property
%%==============================================================================
prop_main() ->
setup(),
?FORALL( Cmds
, proper_statem:commands(?MODULE)
, begin
cleanup(),
{ History
, State
, Result
} = proper_statem:run_commands(?MODULE, Cmds),
?WHENFAIL(
io:format("History: ~p\nState: ~p\nResult: ~p\nCmds: ~p\n",
[ History
, State
, Result
, proper_statem:command_names(Cmds)
]),
proper:aggregate( proper_statem:command_names(Cmds)
, Result =:= ok
)
)
end
).
%%==============================================================================
%% Include file with setup, cleanup, initial_state
%% and state transitions callbacks
%%==============================================================================
-include("{{classname}}_statem.hrl").

View File

@ -0,0 +1,7 @@
-module(prop_{{packageName}}).
-export([prop_test/0]).
prop_test() ->
{ok, _} = application:ensure_all_started({{packageName}}),
{{packageName}}_statem:prop_main().

View File

@ -0,0 +1,66 @@
-module({{packageName}}_utils).
-export([ request/2
, request/4
]).
-type response() :: #{ status := integer()
, headers := map()
, body := iolist()
}.
-export_type([response/0]).
-spec request(atom(), string()) -> response().
request(Method, Url) ->
request(Method, Url, undefined, undefined).
-spec request(atom(), iolist(), iolist(), string()) -> response().
request(Method, Url0, Body, ContentType) ->
Url = binary_to_list(iolist_to_binary(Url0)),
Headers = headers(),
Request = case Body of
undefined -> {Url, Headers};
_ -> {Url, Headers, ContentType, Body}
end,
HTTPOptions = [{autoredirect, true}],
Options = [],
%% Disable pipelining to avoid the socket getting closed during long runs
ok = httpc:set_options([ {max_keep_alive_length, 0}
, {max_pipeline_length, 0}
, {max_sessions, 0}
]),
Result = httpc:request(Method, Request, HTTPOptions, Options),
{ok, {{=<% %>=}}{{_Ver, Status, _Phrase}, RespHeaders, RespBody}}<%={{ }}=%> = Result,
Response = #{ status => Status
, headers => maps:from_list(RespHeaders)
, body => RespBody
},
decode_body(Response).
-spec headers() -> [{string(), string()}].
headers() ->
[ {"Accept", "application/json"}
| basic_auth()
].
-spec basic_auth() -> [{string(), string()}].
basic_auth() ->
case application:get_env({{packageName}}, basic_auth, undefined) of
undefined -> [];
{Username, Password} ->
Credentials = base64:encode_to_string(Username ++ ":" ++ Password),
[{"Authorization", "Basic " ++ Credentials}]
end.
-spec decode_body(response()) -> response().
decode_body(#{ headers := #{"content-type" := "application/json"}
, body := Body
} = Response) ->
Json = jsx:decode( unicode:characters_to_binary(Body)
, [return_maps, {labels, atom}]
),
Response#{body_json => Json};
decode_body(Response) ->
Response.

View File

@ -136,7 +136,7 @@ class {{classname}}(Model):
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('{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
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("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501
{{/pattern}}
{{#maxItems}}

View File

@ -1,4 +1,4 @@
connexion == 2.0.0rc3
connexion == 2.0.0
swagger-ui-bundle == 0.0.2
python_dateutil == 2.6.0
{{#supportPython2}}

View File

@ -13,7 +13,12 @@ VERSION = "{{packageVersion}}"
# prerequisite: setuptools
# http://pypi.python.org/pypi/setuptools
REQUIRES = ["connexion"]
REQUIRES = [
"connexion==2.0.0",
"swagger-ui-bundle==0.0.2",
"python_dateutil==2.6.0"{{#supportPython2}},
"typing==3.5.2.2"{{/supportPython2}}
]
setup(
name=NAME,

View File

@ -89,6 +89,10 @@ use {{invokerPackage}}\ObjectSerializer;
* {{.}}
*
{{/description}}
{{#vendorExtensions.x-group-parameters}}
* Note: the input parameter is an associative array with the keys listed as the parameter name below
*
{{/vendorExtensions.x-group-parameters}}
{{#allParams}}
* @param {{dataType}} ${{paramName}}{{#description}} {{description}}{{/description}}{{^description}} {{paramName}}{{/description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
@ -97,9 +101,9 @@ use {{invokerPackage}}\ObjectSerializer;
* @throws \InvalidArgumentException
* @return {{#returnType}}{{#responses}}{{#dataType}}{{^-first}}|{{/-first}}{{/dataType}}{{{dataType}}}{{/responses}}{{/returnType}}{{^returnType}}void{{/returnType}}
*/
public function {{operationId}}({{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
public function {{operationId}}({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
{{#returnType}}list($response) = {{/returnType}}$this->{{operationId}}WithHttpInfo({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
{{#returnType}}list($response) = {{/returnType}}$this->{{operationId}}WithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});{{#returnType}}
return $response;{{/returnType}}
}
@ -114,6 +118,10 @@ use {{invokerPackage}}\ObjectSerializer;
* {{.}}
*
{{/description}}
{{#vendorExtensions.x-group-parameters}}
* Note: the inpput parameter is an associative array with the keys listed as the parameter name below
*
{{/vendorExtensions.x-group-parameters}}
{{#allParams}}
* @param {{dataType}} ${{paramName}}{{#description}} {{description}}{{/description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
@ -122,9 +130,9 @@ use {{invokerPackage}}\ObjectSerializer;
* @throws \InvalidArgumentException
* @return array of {{#returnType}}{{#responses}}{{#dataType}}{{^-first}}|{{/-first}}{{/dataType}}{{{dataType}}}{{/responses}}{{/returnType}}{{^returnType}}null{{/returnType}}, HTTP status code, HTTP response headers (array of strings)
*/
public function {{operationId}}WithHttpInfo({{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
public function {{operationId}}WithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
$request = $this->{{operationId}}Request({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
$request = $this->{{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}{{#allParams}}$associative_array['{{paramName}}']{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}});
try {
$options = $this->createHttpClientOption();
@ -226,6 +234,10 @@ use {{invokerPackage}}\ObjectSerializer;
* {{.}}
*
{{/description}}
{{#vendorExtensions.x-group-parameters}}
* Note: the inpput parameter is an associative array with the keys listed as the parameter name below
*
{{/vendorExtensions.x-group-parameters}}
{{#allParams}}
* @param {{dataType}} ${{paramName}}{{#description}} {{description}}{{/description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
@ -233,9 +245,9 @@ use {{invokerPackage}}\ObjectSerializer;
* @throws \InvalidArgumentException
* @return \GuzzleHttp\Promise\PromiseInterface
*/
public function {{operationId}}Async({{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
public function {{operationId}}Async({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
return $this->{{operationId}}AsyncWithHttpInfo({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
return $this->{{operationId}}AsyncWithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
->then(
function ($response) {
return $response[0];
@ -252,6 +264,10 @@ use {{invokerPackage}}\ObjectSerializer;
* {{.}}
*
{{/description}}
{{#vendorExtensions.x-group-parameters}}
* Note: the inpput parameter is an associative array with the keys listed as the parameter name below
*
{{/vendorExtensions.x-group-parameters}}
{{#allParams}}
* @param {{dataType}} ${{paramName}}{{#description}} {{description}}{{/description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
@ -259,10 +275,10 @@ use {{invokerPackage}}\ObjectSerializer;
* @throws \InvalidArgumentException
* @return \GuzzleHttp\Promise\PromiseInterface
*/
public function {{operationId}}AsyncWithHttpInfo({{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
public function {{operationId}}AsyncWithHttpInfo({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
$returnType = '{{returnType}}';
$request = $this->{{operationId}}Request({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
$request = $this->{{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}});
return $this->client
->sendAsync($request, $this->createHttpClientOption())
@ -306,6 +322,10 @@ use {{invokerPackage}}\ObjectSerializer;
/**
* Create request for operation '{{{operationId}}}'
*
{{#vendorExtensions.x-group-parameters}}
* Note: the input parameter is an associative array with the keys listed as the parameter name below
*
{{/vendorExtensions.x-group-parameters}}
{{#allParams}}
* @param {{dataType}} ${{paramName}}{{#description}} {{description}}{{/description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
@ -313,8 +333,15 @@ use {{invokerPackage}}\ObjectSerializer;
* @throws \InvalidArgumentException
* @return \GuzzleHttp\Psr7\Request
*/
protected function {{operationId}}Request({{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
protected function {{operationId}}Request({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associative_array{{/vendorExtensions.x-group-parameters}})
{
{{#vendorExtensions.x-group-parameters}}
// unbox the parameters from the associative array
{{#allParams}}
${{paramName}} = array_key_exists('{{paramName}}', $associative_array) ? $associative_array['{{paramName}}'] : {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}};
{{/allParams}}
{{/vendorExtensions.x-group-parameters}}
{{#allParams}}
{{#required}}
// verify the required parameter '{{paramName}}' is set

View File

@ -21,31 +21,45 @@ Method | HTTP request | Description
```php
<?php
require_once(__DIR__ . '/vendor/autoload.php');
{{#hasAuthMethods}}{{#authMethods}}{{#isBasic}}
{{#hasAuthMethods}}
{{#authMethods}}
{{#isBasic}}
// Configure HTTP basic authorization: {{{name}}}
$config = {{{invokerPackage}}}\Configuration::getDefaultConfiguration()
->setUsername('YOUR_USERNAME')
->setPassword('YOUR_PASSWORD');
{{/isBasic}}{{#isApiKey}}
{{/isBasic}}
{{#isApiKey}}
// Configure API key authorization: {{{name}}}
$config = {{{invokerPackage}}}\Configuration::getDefaultConfiguration()->setApiKey('{{{keyParamName}}}', 'YOUR_API_KEY');
// Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
// $config = {{{invokerPackage}}}\Configuration::getDefaultConfiguration()->setApiKeyPrefix('{{{keyParamName}}}', 'Bearer');{{/isApiKey}}{{#isOAuth}}
// $config = {{{invokerPackage}}}\Configuration::getDefaultConfiguration()->setApiKeyPrefix('{{{keyParamName}}}', 'Bearer');
{{/isApiKey}}
{{#isOAuth}}
// Configure OAuth2 access token for authorization: {{{name}}}
$config = {{{invokerPackage}}}\Configuration::getDefaultConfiguration()->setAccessToken('YOUR_ACCESS_TOKEN');{{/isOAuth}}{{/authMethods}}
{{/hasAuthMethods}}
$config = {{{invokerPackage}}}\Configuration::getDefaultConfiguration()->setAccessToken('YOUR_ACCESS_TOKEN');
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
$apiInstance = new {{invokerPackage}}\Api\{{classname}}(
// If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
// This is optional, `GuzzleHttp\Client` will be used as default.
new GuzzleHttp\Client(){{#hasAuthMethods}},
$config{{/hasAuthMethods}}
);
{{^vendorExtensions.x-group-parameters}}
{{#allParams}}${{paramName}} = {{{example}}}; // {{{dataType}}} | {{{description}}}
{{/allParams}}
{{/vendorExtensions.x-group-parameters}}
{{#vendorExtensions.x-group-parameters}}
{{#allParams}}$associate_array['{{paramName}}'] = {{{example}}}; // {{{dataType}}} | {{{description}}}
{{/allParams}}
{{/vendorExtensions.x-group-parameters}}
try {
{{#returnType}}$result = {{/returnType}}$apiInstance->{{{operationId}}}({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});{{#returnType}}
{{#returnType}}$result = {{/returnType}}$apiInstance->{{{operationId}}}({{^vendorExtensions.x-group-parameters}}{{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{/vendorExtensions.x-group-parameters}}{{#vendorExtensions.x-group-parameters}}$associate_array{{/vendorExtensions.x-group-parameters}});{{#returnType}}
print_r($result);{{/returnType}}
} catch (Exception $e) {
echo 'Exception when calling {{classname}}->{{operationId}}: ', $e->getMessage(), PHP_EOL;
@ -54,6 +68,10 @@ try {
```
### Parameters
{{#vendorExtensions.x-group-parameters}}
Note: the input parameter is an associative array with the keys listed as the parameter name below.
{{/vendorExtensions.x-group-parameters}}
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}

View File

@ -27,7 +27,7 @@ class {{classname}}(object):
{{#operation}}
def {{operationId}}(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs): # noqa: E501
"""{{#summary}}{{.}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
"""{{#summary}}{{{.}}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
{{#notes}}
{{{notes}}} # noqa: E501
@ -58,7 +58,7 @@ class {{classname}}(object):
return data
def {{operationId}}_with_http_info(self, {{#sortParamsByRequiredFlag}}{{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}}{{/sortParamsByRequiredFlag}}**kwargs): # noqa: E501
"""{{#summary}}{{.}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
"""{{#summary}}{{{.}}}{{/summary}}{{^summary}}{{operationId}}{{/summary}} # noqa: E501
{{#notes}}
{{{notes}}} # noqa: E501
@ -130,7 +130,7 @@ class {{classname}}(object):
raise ValueError("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('{{{vendorExtensions.x-regex}}}', local_var_params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
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 ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must conform to the pattern `{{{pattern}}}`") # noqa: E501
{{/pattern}}
{{#maxItems}}

View File

@ -40,6 +40,8 @@ class ApiClient(object):
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
@ -53,14 +55,15 @@ class ApiClient(object):
'datetime': datetime.datetime,
'object': object,
}
_pool = None
def __init__(self, configuration=None, header_name=None, header_value=None,
cookie=None):
cookie=None, pool_threads=None):
if configuration is None:
configuration = Configuration()
self.configuration = configuration
self.pool_threads = pool_threads
self.pool = ThreadPool()
self.rest_client = rest.RESTClientObject(configuration)
self.default_headers = {}
if header_name is not None:
@ -70,8 +73,19 @@ class ApiClient(object):
self.user_agent = '{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
def __del__(self):
self.pool.close()
self.pool.join()
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):
@ -251,12 +265,12 @@ class ApiClient(object):
if type(klass) == str:
if klass.startswith('list['):
sub_kls = re.match('list\[(.*)\]', klass).group(1)
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('dict\(([^,]*), (.*)\)', klass).group(2)
sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2)
return {k: self.__deserialize(v, sub_kls)
for k, v in six.iteritems(data)}

View File

@ -153,8 +153,8 @@ class {{classname}}(object):
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('{{{vendorExtensions.x-regex}}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): # noqa: E501
raise ValueError("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{{pattern}}}`") # noqa: E501
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}}:

View File

@ -13,7 +13,7 @@ GEM
public_suffix (>= 2.0.2, < 4.0)
autotest (4.4.6)
ZenTest (>= 4.4.1)
autotest-fsevent (0.2.13)
autotest-fsevent (0.2.14)
sys-uname
autotest-growl (0.2.16)
autotest-rails-pure (4.1.2)

View File

@ -1,6 +1,6 @@
[package]
name = "{{{packageName}}}"
version = "{{{appVersion}}}"
version = {{#packageVersion}}"{{{packageVersion}}}"{{/packageVersion}}{{^packageVersion}}"{{{appVersion}}}"{{/packageVersion}}{{! Fill in with packageVersion if defined, which can be passed via a command line argument, Else use appVersion from the Open API spec, which defaults to 1.0.0 if not present.}}
authors = [{{#infoEmail}}"{{{infoEmail}}}"{{/infoEmail}}]
{{#appDescription}}
description = "{{{appDescription}}}"

View File

@ -257,7 +257,7 @@ export class {{classname}} {
{{#hasFormParams}}
const canConsumeForm = this.canConsumeForm(consumes);
let formParams: { append(param: string, value: any): void; };
let formParams: { append(param: string, value: any): any; };
let useForm = false;
let convertFormParamsToString = false;
{{#formParams}}

View File

@ -271,4 +271,61 @@ public class RubyClientCodegenTest {
// TODO comment out the following until https://github.com/swagger-api/swagger-parser/issues/820 is solved
//Assert.assertTrue(status.isNullable);
}
@Test(description = "test example string imported from x-example parameterr (OAS2)")
public void exampleStringFromExampleParameterOAS2Test() {
final OpenAPI openAPI = new OpenAPIParser().readLocation("src/test/resources/2_0/petstore-nullable.yaml", null, new ParseOptions()).getOpenAPI();
final RubyClientCodegen codegen = new RubyClientCodegen();
codegen.setModuleName("OnlinePetstore");
final String path = "/store/order/{orderId}";
final Operation p = openAPI.getPaths().get(path).getDelete();
final CodegenOperation op = codegen.fromOperation(path, "delete", p, openAPI.getComponents().getSchemas());
CodegenParameter pp = op.pathParams.get(0);
Assert.assertEquals(pp.example, "'orderid123'");
}
@Test(description = "test example string imported from example in schema (OAS3)")
public void exampleStringFromXExampleParameterOAS3Test() {
final OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/petstore_oas3_test.yaml", null, new ParseOptions()).getOpenAPI();
final RubyClientCodegen codegen = new RubyClientCodegen();
codegen.setModuleName("OnlinePetstore");
final String path = "/store/order/{orderId}";
final Operation p = openAPI.getPaths().get(path).getDelete();
final CodegenOperation op = codegen.fromOperation(path, "delete", p, openAPI.getComponents().getSchemas());
CodegenParameter pp = op.pathParams.get(0);
Assert.assertEquals(pp.example, "'orderid123'");
}
/**
* We want to make sure that all Regex patterns:
* - Start with / so Ruby know this is a regex pattern
* - Have a second / that may be added to end if only 1 exists at start
* - If there are 2 / in pattern then don't add any more
*/
@Test(description = "test regex patterns")
public void exampleRegexParameterValidationOAS3Test() {
final OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/test_regex.yaml", null, new ParseOptions()).getOpenAPI();
final RubyClientCodegen codegen = new RubyClientCodegen();
final String path = "/ping";
final Operation p = openAPI.getPaths().get(path).getGet();
final CodegenOperation op = codegen.fromOperation(path, "get", p, openAPI.getComponents().getSchemas());
// pattern_no_forward_slashes '^pattern$'
Assert.assertEquals(op.allParams.get(0).pattern, "/^pattern$/");
// pattern_two_slashes '/^pattern$/i'
Assert.assertEquals(op.allParams.get(1).pattern, "/^pattern$/i");
// pattern_one_slash_start '/^pattern$'
Assert.assertEquals(op.allParams.get(2).pattern, "/^pattern$/");
// pattern_one_slash_end '^pattern$/'
Assert.assertEquals(op.allParams.get(3).pattern, "/^pattern$/");
// pattern_one_slash_near_end '^pattern$/im'
Assert.assertEquals(op.allParams.get(4).pattern, "/^pattern$/im");
// pattern_dont_escape_backslash '/^pattern\d{3}$/i' NOTE: the double \ is to escape \ in string but is read as single \
Assert.assertEquals(op.allParams.get(5).pattern, "/^pattern\\d{3}$/i");
}
}

View File

@ -361,6 +361,7 @@ paths:
description: ID of the order that needs to be deleted
required: true
type: string
x-example: orderid123
responses:
'400':
description: Invalid ID supplied

View File

@ -792,6 +792,30 @@ paths:
description: User not found
security:
- http_basic_test: []
delete:
tags:
- fake
summary: Fake endpoint to test group parameters (optional)
description: Fake endpoint to test group parameters (optional)
operationId: testGroupParameters
x-group-parameters: true
parameters:
- name: string_group
type: integer
in: query
description: String in group parameters
- name: boolean_group
type: boolean
in: header
description: Boolean in group parameters
- name: int64_group
type: integer
format: int64
in: query
description: Integer in group parameters
responses:
'400':
description: Someting wrong
/fake/outer/number:
post:
tags:

View File

@ -1,7 +1,7 @@
swagger: '2.0'
info:
description: "This spec is for testing rust-server-specific things"
version: 1.0.0
version: 2.3.4
title: rust-server-test
schemes:
- http
@ -12,6 +12,42 @@ paths:
responses:
'200':
description: Success
put:
parameters:
- $ref: '#/parameters/nested_response'
responses:
'200':
description: Success
/html:
post:
summary: Test HTML handling
consumes: [text/html]
produces: [text/html]
parameters:
- in: body
name: body
required: true
schema:
type: string
responses:
200:
description: Success
schema:
type: string
parameters:
nested_response:
name: nested_response
in: body
required: true
schema:
# Erroneously ends up as `Option<models::InlineObject>`
properties:
id:
type: string
password:
type: string
required:
- id
definitions:
additionalPropertiesObject:
description: An additionalPropertiesObject
@ -30,3 +66,31 @@ definitions:
x-nullable: true
required:
- RequiredNullableThing
ObjectOfObjects:
description: An object of objects
type: object
properties:
inner:
type: object
required:
- required_thing
properties:
required_thing:
type: string
optional_thing:
type: integer
# Currently broken - see https://github.com/OpenAPITools/openapi-generator/issues/8
# ArrayOfObjects:
# description: An array of objects
# type: array
# items:
# properties:
# filename:
# description: A non-required property
# type: string
# contents:
# description: A required property
# type: string
# required:
# - contents
# type: object

View File

@ -765,6 +765,33 @@ paths:
- double
- pattern_without_delimiter
- byte
delete:
tags:
- fake
summary: Fake endpoint to test group parameters (optional)
description: Fake endpoint to test group parameters (optional)
operationId: testGroupParameters
x-group-parameters: true
parameters:
- name: string_group
in: query
description: String in group parameters
schema:
type: integer
- name: boolean_group
in: header
description: Boolean in group parameters
schema:
type: boolean
- name: int64_group
in: query
description: Integer in group parameters
schema:
type: integer
format: int64
responses:
'400':
description: Someting wrong
/fake/outer/number:
post:
tags:
@ -911,7 +938,7 @@ paths:
- $another-fake?
summary: To test special tags
description: To test special tags and operation ID starting with number
operationId: 123_test_@#$%_special_tags
operationId: '123_test_@#$%_special_tags'
responses:
'200':
description: successful operation
@ -1311,6 +1338,14 @@ components:
format: password
maxLength: 64
minLength: 10
pattern_with_digits:
description: A string that is a 10 digit number. Can have leading zeros.
type: string
pattern: '^\d{10}$'
pattern_with_digits_and_delimiter:
description: A string starting with 'image_' (case insensitive) and one to three digits following i.e. Image_01.
type: string
pattern: '/^image_\d{1,3}$/i'
EnumClass:
type: string
default: '-efg'

View File

@ -360,6 +360,7 @@ paths:
required: true
schema:
type: string
example: orderid123
responses:
'400':
description: Invalid ID supplied

View File

@ -0,0 +1,51 @@
openapi: 3.0.1
info:
title: Test Regex generation for parameter validation
version: 1.0.0
components:
headers:
responses:
OK_200:
description: OK
paths:
/ping:
get:
summary: Get Payment Information
description: Returns the content of a payment object
parameters:
- name: pattern_no_forward_slashes
in: header
schema:
type: string
pattern: '^pattern$'
- name: pattern_two_slashes
in: header
schema:
type: string
pattern: '/^pattern$/i'
- name: pattern_one_slash_start
in: header
schema:
type: string
pattern: '/^pattern$'
- name: pattern_one_slash_end
in: header
schema:
type: string
pattern: '^pattern$/'
- name: pattern_one_slash_near_end
in: header
schema:
type: string
pattern: '^pattern$/im'
- name: pattern_dont_escape_backslash
in: header
schema:
type: string
pattern: '/^pattern\d{3}$/i'
responses:
'200':
$ref: "#/components/responses/OK_200"

View File

@ -1 +1 @@
3.3.1-SNAPSHOT
3.3.2-SNAPSHOT

View File

@ -79,7 +79,7 @@ public class ApiClient {
private HttpLoggingInterceptor loggingInterceptor;
/*
* Constructor for ApiClient
* Basic constructor for ApiClient
*/
public ApiClient() {
init();
@ -92,13 +92,23 @@ public class ApiClient {
}
/*
* Constructor for ApiClient to support access token retry on 401/403
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID
*/
public ApiClient(
String clientId,
String clientSecret,
Map<String, String> parameters
) {
public ApiClient(String clientId) {
this(clientId, null, null);
}
/*
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID and additional parameters
*/
public ApiClient(String clientId, Map<String, String> parameters) {
this(clientId, null, parameters);
}
/*
* Constructor for ApiClient to support access token retry on 401/403 configured with client ID, secret, and additional parameters
*/
public ApiClient(String clientId, String clientSecret, Map<String, String> parameters) {
init();
RetryingOAuth retryingOAuth = new RetryingOAuth("", clientId, OAuthFlow.implicit, clientSecret, parameters);

View File

@ -32,7 +32,7 @@ import java.io.IOException;
public class ModelReturn {
public static final String SERIALIZED_NAME_RETURN = "return";
@SerializedName(SERIALIZED_NAME_RETURN)
private Integer _return = null;
private Integer _return;
public ModelReturn _return(Integer _return) {
this._return = _return;

View File

@ -1 +1 @@
3.2.0-SNAPSHOT
3.3.3-SNAPSHOT

View File

@ -1 +1 @@
3.3.1-SNAPSHOT
3.3.0-SNAPSHOT

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/
@ -13,6 +13,18 @@
#include "MultipartFormData.h"
#include "ModelBase.h"
#include <sstream>
#include <limits>
#include <iomanip>
template <typename T>
utility::string_t toString(const T value)
{
std::ostringstream out;
out << std::setprecision(std::numeric_limits<T>::digits10) << std::fixed << value;
return out.str();
}
namespace org {
namespace openapitools {
namespace client {
@ -57,12 +69,12 @@ utility::string_t ApiClient::parameterToString(int32_t value)
utility::string_t ApiClient::parameterToString(float value)
{
return utility::conversions::to_string_t(std::to_string(value));
return utility::conversions::to_string_t(toString(value));
}
utility::string_t ApiClient::parameterToString(double value)
{
return utility::conversions::to_string_t(std::to_string(value));
return utility::conversions::to_string_t(toString(value));
}
utility::string_t ApiClient::parameterToString(const utility::datetime &value)

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/
@ -57,25 +57,25 @@ web::json::value ModelBase::toJson( std::shared_ptr<HttpContent> content )
return value;
}
std::shared_ptr<HttpContent> ModelBase::fileFromJson(web::json::value& val)
std::shared_ptr<HttpContent> ModelBase::fileFromJson(const web::json::value& val)
{
std::shared_ptr<HttpContent> content(new HttpContent);
if(val.has_field(utility::conversions::to_string_t("ContentDisposition")))
{
content->setContentDisposition( ModelBase::stringFromJson(val[utility::conversions::to_string_t("ContentDisposition")]) );
content->setContentDisposition( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("ContentDisposition"))) );
}
if(val.has_field(utility::conversions::to_string_t("ContentType")))
{
content->setContentType( ModelBase::stringFromJson(val[utility::conversions::to_string_t("ContentType")]) );
content->setContentType( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("ContentType"))) );
}
if(val.has_field(utility::conversions::to_string_t("FileName")))
{
content->setFileName( ModelBase::stringFromJson(val[utility::conversions::to_string_t("FileName")]) );
content->setFileName( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("FileName"))) );
}
if(val.has_field(utility::conversions::to_string_t("InputStream")))
{
content->setData( ModelBase::fromBase64( ModelBase::stringFromJson(val[utility::conversions::to_string_t("InputStream")]) ) );
content->setData( ModelBase::fromBase64( ModelBase::stringFromJson(val.at(utility::conversions::to_string_t("InputStream")))) );
}
return content;
@ -274,32 +274,32 @@ std::shared_ptr<std::istream> ModelBase::fromBase64( const utility::string_t& en
return result;
}
int64_t ModelBase::int64_tFromJson(web::json::value& val)
int64_t ModelBase::int64_tFromJson(const web::json::value& val)
{
return val.as_number().to_int64();
}
int32_t ModelBase::int32_tFromJson(web::json::value& val)
int32_t ModelBase::int32_tFromJson(const web::json::value& val)
{
return val.as_integer();
}
float ModelBase::floatFromJson(web::json::value& val)
float ModelBase::floatFromJson(const web::json::value& val)
{
return static_cast<float>(val.as_double());
}
utility::string_t ModelBase::stringFromJson(web::json::value& val)
utility::string_t ModelBase::stringFromJson(const web::json::value& val)
{
return val.is_string() ? val.as_string() : utility::conversions::to_string_t("");
}
utility::datetime ModelBase::dateFromJson(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);
}
bool ModelBase::boolFromJson(web::json::value& val)
bool ModelBase::boolFromJson(const web::json::value& val)
{
return val.as_bool();
}
double ModelBase::doubleFromJson(web::json::value& val)
double ModelBase::doubleFromJson(const web::json::value& val)
{
return val.as_double();
}

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/
@ -41,7 +41,7 @@ public:
virtual void validate() = 0;
virtual web::json::value toJson() const = 0;
virtual void fromJson(web::json::value& json) = 0;
virtual void fromJson(const web::json::value& json) = 0;
virtual void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const = 0;
virtual void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) = 0;
@ -57,14 +57,14 @@ public:
template<class T>
static web::json::value toJson(const std::vector<T>& value);
static int64_t int64_tFromJson(web::json::value& val);
static int32_t int32_tFromJson(web::json::value& val);
static float floatFromJson(web::json::value& val);
static utility::string_t stringFromJson(web::json::value& val);
static utility::datetime dateFromJson(web::json::value& val);
static double doubleFromJson(web::json::value& val);
static bool boolFromJson(web::json::value& val);
static std::shared_ptr<HttpContent> fileFromJson(web::json::value& val);
static int64_t int64_tFromJson(const web::json::value& val);
static int32_t int32_tFromJson(const web::json::value& val);
static float floatFromJson(const web::json::value& val);
static utility::string_t stringFromJson(const web::json::value& val);
static utility::datetime dateFromJson(const web::json::value& val);
static double doubleFromJson(const web::json::value& val);
static bool boolFromJson(const web::json::value& val);
static std::shared_ptr<HttpContent> fileFromJson(const web::json::value& val);
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const utility::string_t& value, const utility::string_t& contentType = utility::conversions::to_string_t(""));
static std::shared_ptr<HttpContent> toHttpContent( const utility::string_t& name, const utility::datetime& value, const utility::string_t& contentType = utility::conversions::to_string_t(""));

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/
@ -35,7 +35,7 @@ web::json::value Object::toJson() const
return m_object;
}
void Object::fromJson(web::json::value& val)
void Object::fromJson(const web::json::value& val)
{
if (val.is_object())
{

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/
@ -40,7 +40,7 @@ public:
void validate() override;
web::json::value toJson() const override;
void fromJson(web::json::value& json) override;
void fromJson(const web::json::value& json) override;
void toMultipart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) const override;
void fromMultiPart(std::shared_ptr<MultipartFormData> multipart, const utility::string_t& namePrefix) override;

View File

@ -4,7 +4,7 @@
*
* OpenAPI spec version: 1.0.0
*
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.1-SNAPSHOT.
* NOTE: This class is auto generated by OpenAPI-Generator 3.3.0-SNAPSHOT.
* https://openapi-generator.tech
* Do not edit the class manually.
*/

Some files were not shown because too many files have changed in this diff Show More