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

This commit is contained in:
William Cheng 2021-04-28 17:48:21 +08:00
commit 37eaf70755
1666 changed files with 42781 additions and 17405 deletions

View File

@ -24,18 +24,18 @@ jobs:
uses: actions/checkout@v2
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: ${{ matrix.java }}
- uses: actions/cache@v2.1.4
- uses: actions/cache@v2.1.5
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('pom.xml', 'modules/**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- uses: actions/cache@v2.1.4
- uses: actions/cache@v2.1.5
with:
path: |
~/.gradle/caches
@ -49,7 +49,7 @@ jobs:
run: mvn -nsu -B --quiet -Djacoco.skip=true -Dorg.slf4j.simpleLogger.defaultLogLevel=error --no-transfer-progress clean install --file pom.xml ${{ matrix.flags }}
- name: Upload Maven build artifact
uses: actions/upload-artifact@v2.2.2
uses: actions/upload-artifact@v2.2.3
if: matrix.java == '8' && matrix.os == 'ubuntu-latest'
with:
name: artifact

View File

@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Set up JDK 11
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: 11
- name: Compile with Maven

View File

@ -62,6 +62,14 @@ addons:
- petstore.swagger.io
before_install:
- sudo rm -rf /var/lib/apt/lists/*
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge"
- sudo apt-get update
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- mkdir -vp ~/.docker/cli-plugins/
- curl --silent -L "https://github.com/docker/buildx/releases/download/v0.3.0/buildx-v0.3.0.linux-amd64" > ~/.docker/cli-plugins/docker-buildx
- chmod a+x ~/.docker/cli-plugins/docker-buildx
# to run petstore server locally via docker
- echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin || true
- docker pull swaggerapi/petstore
@ -149,6 +157,8 @@ install:
script:
# fail fast
- set -e
# show docker buildx version
- docker buildx version
# fail if the template files contains tabs
- /bin/bash ./bin/utils/detect_tab_in_templates.sh
# fail if the test files have changes
@ -199,12 +209,14 @@ after_success:
echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin;
export cli_version=$(\mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\[');
export build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ");
docker build --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-online --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online;
docker buildx create --use;
if [ ! -z "$TRAVIS_TAG" ]; then
docker tag $DOCKER_GENERATOR_IMAGE_NAME:latest $DOCKER_GENERATOR_IMAGE_NAME:$TRAVIS_TAG;
docker buildx build --platform linux/amd64,linux/arm64 --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-online --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_GENERATOR_IMAGE_NAME:latest -t $DOCKER_GENERATOR_IMAGE_NAME:$TRAVIS_TAG -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online;
echo "Built and tagged $DOCKER_GENERATOR_IMAGE_NAME";
fi;
if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then
docker push $DOCKER_GENERATOR_IMAGE_NAME && echo "Pushed to $DOCKER_GENERATOR_IMAGE_NAME";
if [ -z "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
docker buildx build --push --platform linux/amd64,linux/arm64 --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-online --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online;
echo "Pushed to $DOCKER_GENERATOR_IMAGE_NAME for master";
fi;
fi;
## docker: build cli image and push to Docker Hub
@ -213,12 +225,14 @@ after_success:
cp docker-entrypoint.sh ./modules/openapi-generator-cli;
export cli_version=$(\mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\[');
export build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ");
docker build --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-cli --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli;
docker buildx create --use;
docker buildx build --platform linux/amd64,linux/arm64 --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-cli --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli;
if [ ! -z "$TRAVIS_TAG" ]; then
docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG;
docker buildx build --platform linux/amd64,linux/arm64 --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-cli --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest -t $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli;
echo "Built and tagged $DOCKER_GENERATOR_IMAGE_NAME";
fi;
if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then
docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME;
if [ -z "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
docker buildx build --push --platform linux/amd64,linux/arm64 --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-cli --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli;
echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME";
fi;
fi;

View File

@ -2,6 +2,22 @@ kind: pipeline
name: default
steps:
# test Java 11 HTTP client
- name: java11-test
image: openjdk:11.0
commands:
- ./mvnw --quiet clean install -Dorg.slf4j.simpleLogger.defaultLogLevel=error
- ./mvnw --quiet verify -Psamples.droneio -Dorg.slf4j.simpleLogger.defaultLogLevel=error
# run ensure up-to-date
- /bin/bash bin/utils/ensure-up-to-date
# test java native client
- ./mvnw clean test -f samples/client/petstore/java/native/pom.xml
- ./mvnw clean test -f samples/client/petstore/java/native-async/pom.xml
- ./mvnw clean test -f samples/openapi3/client/petstore/java/native/pom.xml
# test all generators with fake petstore spec (2.0, 3.0)
- /bin/bash bin/utils/test-fake-petstore-for-all.sh
# generate test scripts
- /bin/bash bin/tests/run-all-test
# test nim client
- name: nim-client-test
image: nimlang/nim
@ -38,21 +54,3 @@ steps:
image: haskell:8.6.5
commands:
- (cd samples/client/petstore/haskell-http-client/ && stack --install-ghc --no-haddock-deps haddock --fast && stack test --fast)
# test Java 11 HTTP client
- name: java11-test
image: openjdk:11.0
commands:
- ./mvnw --quiet clean install -Dorg.slf4j.simpleLogger.defaultLogLevel=error
- ./mvnw --quiet verify -Psamples.droneio -Dorg.slf4j.simpleLogger.defaultLogLevel=error
# test java native client
- ./mvnw clean test -f samples/client/petstore/java/native/pom.xml
- ./mvnw clean test -f samples/client/petstore/java/native-async/pom.xml
- ./mvnw clean test -f samples/openapi3/client/petstore/java/native/pom.xml
# test all generators with fake petstore spec (2.0, 3.0)
- /bin/bash bin/utils/test-fake-petstore-for-all.sh
# generate test scripts
- /bin/bash bin/tests/run-all-test
# generate all petstore samples (client, servers, doc)
- /bin/bash bin/generate-samples.sh
# generate all petstore samples (openapi3)
- /bin/bash bin/generate-samples.sh bin/configs/other/*.yaml

View File

@ -47,7 +47,8 @@ elif [ "$NODE_INDEX" = "2" ]; then
git checkout -- .
# look for outdated samples
./bin/utils/ensure-up-to-date
#./bin/utils/ensure-up-to-date
# UPDATE: moved to drone.io
fi
echo "Running node $NODE_INDEX to test haskell"
# install haskell

View File

@ -78,7 +78,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
| | Languages/Frameworks |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0, .NET 5.0. Libraries: RestSharp, HttpClient), **C++** (cpp-restsdk, Qt5, Tizen, Unreal Engine 4), **Clojure**, **Crystal**, **Dart**, **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, MicroProfile Rest Client), **k6**, **Kotlin**, **Lua**, **Nim**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types, Apollo GraphQL DataStore), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (hyper, reqwest, rust-server), **Scala** (akka, http4s, scalaz, sttp, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x, 5.x), **Typescript** (AngularJS, Angular (2.x - 11.x), Aurelia, Axios, Fetch, Inversify, jQuery, Nestjs, Node, redux-query, Rxjs) |
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/)), **Kotlin** (Spring Boot, Ktor, Vertx), **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** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) |
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/)), **Kotlin** (Spring Boot, Ktor, Vertx), **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** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) |
| **API documentation generators** | **HTML**, **Confluence Wiki**, **Asciidoc**, **Markdown**, **PlantUML** |
| **Configuration files** | [**Apache2**](https://httpd.apache.org/) |
| **Others** | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Protocol Buffer** |
@ -659,6 +659,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Stingray](http://www.stingray.com)
- [Suva](https://www.suva.ch/)
- [Telstra](https://dev.telstra.com)
- [The University of Aizu](https://www.u-aizu.ac.jp/en/)
- [TravelTime platform](https://www.traveltimeplatform.com/)
- [TribalScale](https://www.tribalscale.com)
- [TUI InfoTec GmbH](http://www.tui-infotec.com/)
@ -814,6 +815,14 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2021-01-18 - [「アプリ開発あるある」を疑うことから始まった、API Clientコードの自動生成【デブスト2020】](https://codezine.jp/article/detail/13406?p=2) by [CodeZine編集部](https://codezine.jp/author/1)
- 2021-02-05 - [REST-API-Roundtrip with SpringDoc and OpenAPI Generator](https://blog.viadee.de/en/rest-api-roundtrip) by [Benjamin Klatt](https://twitter.com/benklatt) at [viadee](https://www.viadee.de/en/)
- 2021-02-17 - [REST-API-Roundtrip with SpringDoc and OpenAPI Generator](https://medium.com/nerd-for-tech/rest-api-roundtrip-with-springdoc-and-openapi-generator-30bd27ccf698) by [cloud @viadee](https://cloud-viadee.medium.com/)
- 2021-03-08 - [OpenAPI Generator 工具的躺坑尝试](https://blog.csdn.net/u013019701/article/details/114531975) by [独家雨天](https://blog.csdn.net/u013019701) at [CSDN官方博客](https://blog.csdn.net/)
- 2021-03-16 - [如何基于 Swagger 使用 OpenAPI Generator 生成 JMeter 脚本?](https://cloud.tencent.com/developer/article/1802704) by [高楼Zee](https://cloud.tencent.com/developer/user/5836255) at [腾讯云专栏](https://cloud.tencent.com/developer/column)
- 2021-03-24 - [openapi-generator-cli による TypeScript 型定義](https://zenn.dev/takepepe/articles/openapi-generator-cli-ts) by [Takefumi Yoshii](https://zenn.dev/takepepe)
- 2021-03-28 - [Trying out NestJS part 4: Generate Typescript clients from OpenAPI documents](https://dev.to/arnaudcortisse/trying-out-nestjs-part-4-generate-typescript-clients-from-openapi-documents-28mk) by [Arnaud Cortisse](https://dev.to/arnaudcortisse)
- 2021-03-31 - [Open API Server Implementation Using OpenAPI Generator](https://www.baeldung.com/java-openapi-generator-server) at [Baeldung](https://www.baeldung.com/)
- 2021-03-31 - [使用OpenAPI Generator實現Open API Server](https://www.1ju.org/article/java-openapi-generator-server) at [億聚網](https://www.1ju.org/)
- 2022-04-19 - [Introducing Twilios OpenAPI Specification Beta](https://www.twilio.com/blog/introducing-twilio-open-api-specification-beta) by [GARETH PAUL JONES](https://www.twilio.com/blog/author/gpj) at [Twilio Blog](https://www.twilio.com/blog)
- 2022-04-22 - [Leveraging OpenApi strengths in a Micro-Service environment](https://medium.com/unibuddy-technology-blog/leveraging-openapi-strengths-in-a-micro-service-environment-3d7f9e7c26ff) by Nicolas Jellab at [Unibuddy Technology Blog](https://medium.com/unibuddy-technology-blog)
## [6 - About Us](#table-of-contents)
@ -926,6 +935,7 @@ Here is a list of template creators:
* Erlang Server: @galaxie
* F# (Giraffe) Server: @nmfisher
* Go Server: @guohuang
* Go (Echo) Server: @ph4r5h4d
* Go (Gin) Server: @kemokemo
* GraphQL Express Server: @renepardon
* Haskell Servant: @algas
@ -1018,7 +1028,7 @@ If you want to join the committee, please kindly apply by sending an email to te
| Elm | @eriktim (2018/09) |
| Erlang | @tsloughter (2017/11) @jfacorro (2018/10) @robertoaloi (2018/10) |
| F# | @nmfisher (2019/05) |
| Go | @antihax (2017/11) @grokify (2018/07) @kemokemo (2018/09) @jirikuncar (2021/01) |
| Go | @antihax (2017/11) @grokify (2018/07) @kemokemo (2018/09) @jirikuncar (2021/01) @ph4r5h4d (2021/04) |
| GraphQL | @renepardon (2018/12) |
| Groovy | |
| Haskell | |

View File

@ -43,6 +43,8 @@ build_script:
- dotnet build samples\server\petstore\aspnetcore-3.0\Org.OpenAPITools.sln
# build C# aspnetcore 2.2 server
- dotnet build samples\server\petstore\aspnetcore\Org.OpenAPITools.sln
# build C# API client (multiple frameworks)
- dotnet build samples\client\petstore\csharp-netcore\OpenAPIClientCoreAndNet47\Org.OpenAPITools.sln
# build C# API client (httpclient)
- dotnet build samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\Org.OpenAPITools.sln
# build C# API client (netcore)
@ -66,6 +68,8 @@ build_script:
# run the locally installed openapi-generator-gradle-plugin
- gradle -b modules\openapi-generator-gradle-plugin\samples\local-spec\build.gradle buildGoSdk --stacktrace
test_script:
# test c# API client (multiple frameworks)
- dotnet test samples\client\petstore\csharp-netcore\OpenAPIClientCoreAndNet47\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test c# API client (httpclient)
- dotnet test samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj
# test c# API client (netcore)

View File

@ -0,0 +1,8 @@
generatorName: csharp-netcore
outputDir: samples/client/petstore/csharp-netcore/OpenAPIClientCoreAndNet47
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/csharp-netcore
additionalProperties:
packageGuid: '{321C8C3F-0156-40C1-AE42-D59761FB9B6C}'
targetFramework: netstandard2.1;netcoreapp3.0
useCompareNetObjects: "true"

View File

@ -2,5 +2,9 @@ generatorName: dart-dio-next
outputDir: samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/dart/libraries/dio
typeMappings:
Client: "ModelClient"
File: "ModelFile"
EnumClass: "ModelEnumClass"
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -2,5 +2,9 @@ generatorName: dart-dio
outputDir: samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/dart-dio
typeMappings:
Client: "ModelClient"
File: "ModelFile"
EnumClass: "ModelEnumClass"
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -1,6 +0,0 @@
generatorName: dart-dio
outputDir: samples/client/petstore/dart-dio/petstore_client_lib
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/dart-dio
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -2,5 +2,8 @@ generatorName: dart
outputDir: samples/openapi3/client/petstore/dart2/petstore_client_lib_fake
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/dart2
typeMappings:
Client: "ModelClient"
File: "ModelFile"
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -1,6 +0,0 @@
generatorName: dart
outputDir: samples/client/petstore/dart2/petstore_client_lib
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/dart2
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -2,6 +2,9 @@ generatorName: dart
outputDir: samples/openapi3/client/petstore/dart2/petstore_json_serializable_client_lib_fake
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/dart2
typeMappings:
Client: "ModelClient"
File: "ModelFile"
additionalProperties:
hideGenerationTimestamp: "true"
serializationLibrary: json_serializable

View File

@ -0,0 +1,6 @@
generatorName: go-echo-server
outputDir: samples/server/petstore/go-echo-server
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/go-echo-server
additionalProperties:
hideGenerationTimestamp: "true"

View File

@ -5,3 +5,4 @@ templateDir: modules/openapi-generator/src/main/resources/go-server
additionalProperties:
hideGenerationTimestamp: "true"
packageName: petstoreserver
addResponseHeaders: true

View File

@ -1,4 +1,4 @@
generatorName: php-symfony
outputDir: samples/server/petstore/php-symfony/SymfonyBundle-php
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/php-symfony

View File

@ -1,6 +1,6 @@
generatorName: swift5
outputDir: samples/client/petstore/swift5/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/swift/petstore-with-fake-endpoints-models-for-testing.yaml
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/swift5
generateAliasAsModel: true
additionalProperties:

View File

@ -9,3 +9,4 @@ additionalProperties:
podSummary: PetstoreClient
projectName: PetstoreClient
podHomepage: https://github.com/openapitools/openapi-generator
useBacktickEscapes: true

View File

@ -9,3 +9,5 @@ additionalProperties:
podSummary: PetstoreClient
projectName: PetstoreClient
podHomepage: https://github.com/openapitools/openapi-generator
useSPMFileStructure: true
useClasses: true

View File

@ -0,0 +1,3 @@
generatorName: typescript-axios
outputDir: samples/client/petstore/typescript-axios/builds/with-fake-endpoints-models-for-testing-with-http-signature
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml

View File

@ -1,5 +1,7 @@
#!/usr/bin/env bash
set -e
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
@ -18,8 +20,8 @@ ags="meta -n myClientCodegen -t DOCUMENTATION -p com.my.company.codegen -o sampl
java $JAVA_OPTS -jar $executable $ags
(cd "$root"/samples/meta-codegen/ && mvn -B package -Djacoco.skip=true -DskipTests=true -f pom.xml)
(./mvnw -B package -Djacoco.skip=true -DskipTests=true -f "$root"/samples/meta-codegen/pom.xml)
ags2="generate -g myClientCodegen -i modules/openapi-generator/src/test/resources/2_0/petstore.json -o samples/meta-codegen/usage $@"
ags2="generate -g myClientCodegen -i modules/openapi-generator/src/test/resources/3_0/petstore.json -o samples/meta-codegen/usage $@"
java $JAVA_OPTS -cp ${root}/samples/meta-codegen/lib/target/myClientCodegen-openapi-generator-1.0.0.jar:$executable org.openapitools.codegen.OpenAPIGenerator $ags2

View File

@ -11,15 +11,16 @@ logfile="/tmp/generator-fake-petstore-output.log"
for GENERATOR in $(java -jar ${executable} list --short | sed -e 's/,/\'$'\n''/g')
do
if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR} > ${logfile} 2>&1; then
echo "[OAS 2.0] Executed ${GENERATOR} successfully!"
else
echo "ERROR: Failed to run '${GENERATOR}' generator. The command was:"
echo "java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR}"
echo "ERROR: The output of the command was:"
cat ${logfile}
exit 1
fi
# no longer test 2.0 spec as we migrated to 3.0 spec
#if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR} > ${logfile} 2>&1; then
# echo "[OAS 2.0] Executed ${GENERATOR} successfully!"
#else
# echo "ERROR: Failed to run '${GENERATOR}' generator. The command was:"
# echo "java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/2.0/${GENERATOR}"
# echo "ERROR: The output of the command was:"
# cat ${logfile}
# exit 1
#fi
if eval java -jar ${executable} generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -g ${GENERATOR} -o /tmp/openapi-generator-test-fake-petstore/3.0/${GENERATOR} > ${logfile} 2>&1; then
echo "[OAS 3.0] Executed ${GENERATOR} successfully!"

View File

@ -86,6 +86,7 @@ The following generators are available:
* [erlang-server](generators/erlang-server.md)
* [fsharp-functions (beta)](generators/fsharp-functions.md)
* [fsharp-giraffe-server (beta)](generators/fsharp-giraffe-server.md)
* [go-echo-server (beta)](generators/go-echo-server.md)
* [go-gin-server](generators/go-gin-server.md)
* [go-server](generators/go-server.md)
* [graphql-nodejs-express-server](generators/graphql-nodejs-express-server.md)

View File

@ -29,7 +29,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|returnICollection|Return ICollection<T> instead of the concrete type.| |false|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src|
|targetFramework|The target .NET framework version.|<dl><dt>**netstandard1.3**</dt><dd>.NET Standard 1.3 compatible</dd><dt>**netstandard1.4**</dt><dd>.NET Standard 1.4 compatible</dd><dt>**netstandard1.5**</dt><dd>.NET Standard 1.5 compatible</dd><dt>**netstandard1.6**</dt><dd>.NET Standard 1.6 compatible</dd><dt>**netstandard2.0**</dt><dd>.NET Standard 2.0 compatible</dd><dt>**netstandard2.1**</dt><dd>.NET Standard 2.1 compatible</dd><dt>**netcoreapp2.0**</dt><dd>.NET Core 2.0 compatible</dd><dt>**netcoreapp2.1**</dt><dd>.NET Core 2.1 compatible</dd><dt>**netcoreapp3.0**</dt><dd>.NET Core 3.0 compatible</dd><dt>**netcoreapp3.1**</dt><dd>.NET Core 3.1 compatible</dd><dt>**net47**</dt><dd>.NET Framework 4.7 compatible</dd><dt>**net5.0**</dt><dd>.NET 5.0 compatible</dd></dl>|netstandard2.0|
|targetFramework|The target .NET framework version. To target multiple frameworks, use `;` as the separator, e.g. `netstandard2.1;netcoreapp3.0`|<dl><dt>**netstandard1.3**</dt><dd>.NET Standard 1.3 compatible</dd><dt>**netstandard1.4**</dt><dd>.NET Standard 1.4 compatible</dd><dt>**netstandard1.5**</dt><dd>.NET Standard 1.5 compatible</dd><dt>**netstandard1.6**</dt><dd>.NET Standard 1.6 compatible</dd><dt>**netstandard2.0**</dt><dd>.NET Standard 2.0 compatible</dd><dt>**netstandard2.1**</dt><dd>.NET Standard 2.1 compatible</dd><dt>**netcoreapp2.0**</dt><dd>.NET Core 2.0 compatible</dd><dt>**netcoreapp2.1**</dt><dd>.NET Core 2.1 compatible</dd><dt>**netcoreapp3.0**</dt><dd>.NET Core 3.0 compatible</dd><dt>**netcoreapp3.1**</dt><dd>.NET Core 3.1 compatible</dd><dt>**net47**</dt><dd>.NET Framework 4.7 compatible</dd><dt>**net5.0**</dt><dd>.NET 5.0 compatible</dd></dl>|netstandard2.0|
|useCollection|Deserialize array types to Collection&lt;T&gt; instead of List&lt;T&gt;.| |false|
|useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped.| |false|

View File

@ -25,7 +25,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|returnICollection|Return ICollection&lt;T&gt; instead of the concrete type.| |false|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src|
|targetFramework|The target .NET framework version.|<dl><dt>**v3.5**</dt><dd>.NET Framework 3.5 compatible</dd><dt>**v4.0**</dt><dd>.NET Framework 4.0 compatible</dd><dt>**v4.5**</dt><dd>.NET Framework 4.5 compatible</dd><dt>**v4.5.2**</dt><dd>.NET Framework 4.5.2+ compatible</dd><dt>**netstandard1.3**</dt><dd>.NET Standard 1.3 compatible (DEPRECATED. Please use `csharp-netcore` generator instead)</dd><dt>**uwp**</dt><dd>Universal Windows Platform (DEPRECATED. Please use `csharp-netcore` generator instead)</dd></dl>|v4.5|
|targetFramework|The target .NET framework version. To target multiple frameworks, use `;` as the separator, e.g. `netstandard2.1;netcoreapp3.0`|<dl><dt>**v3.5**</dt><dd>.NET Framework 3.5 compatible</dd><dt>**v4.0**</dt><dd>.NET Framework 4.0 compatible</dd><dt>**v4.5**</dt><dd>.NET Framework 4.5 compatible</dd><dt>**v4.5.2**</dt><dd>.NET Framework 4.5.2+ compatible</dd><dt>**netstandard1.3**</dt><dd>.NET Standard 1.3 compatible (DEPRECATED. Please use `csharp-netcore` generator instead)</dd><dt>**uwp**</dt><dd>Universal Windows Platform (DEPRECATED. Please use `csharp-netcore` generator instead)</dd></dl>|v4.5|
|useCollection|Deserialize array types to Collection&lt;T&gt; instead of List&lt;T&gt;.| |false|
|useCompareNetObjects|Use KellermanSoftware.CompareNetObjects for deep recursive object comparison. WARNING: this option incurs potential performance impact.| |false|
|useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false|

View File

@ -44,7 +44,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>String</li>
<li>bool</li>
<li>double</li>
<li>dynamic</li>
<li>int</li>
<li>num</li>
</ul>

View File

@ -30,11 +30,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Imports |
| ---------- | ------- |
|BuiltList|package:built_collection/built_collection.dart|
|BuiltMap|package:built_collection/built_collection.dart|
|BuiltSet|package:built_collection/built_collection.dart|
|JsonObject|package:built_value/json_object.dart|
|Uint8List|dart:typed_data|
## INSTANTIATION TYPES
@ -49,7 +44,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>String</li>
<li>bool</li>
<li>double</li>
<li>dynamic</li>
<li>int</li>
<li>num</li>
</ul>

View File

@ -44,7 +44,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>String</li>
<li>bool</li>
<li>double</li>
<li>dynamic</li>
<li>int</li>
<li>num</li>
</ul>

View File

@ -43,7 +43,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>String</li>
<li>bool</li>
<li>double</li>
<li>dynamic</li>
<li>int</li>
<li>num</li>
</ul>

View File

@ -0,0 +1,206 @@
---
title: Config Options for go-echo-server
sidebar_label: go-echo-server
---
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|packageName|Go package name (convention: lowercase).| |openapi|
|packageVersion|Go package version.| |1.0.0|
|serverPort|The network port the generated server binds to| |8080|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>bool</li>
<li>byte</li>
<li>complex128</li>
<li>complex64</li>
<li>float32</li>
<li>float64</li>
<li>int</li>
<li>int32</li>
<li>int64</li>
<li>interface{}</li>
<li>map[string]interface{}</li>
<li>rune</li>
<li>string</li>
<li>uint</li>
<li>uint32</li>
<li>uint64</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>bool</li>
<li>break</li>
<li>byte</li>
<li>case</li>
<li>chan</li>
<li>complex128</li>
<li>complex64</li>
<li>const</li>
<li>continue</li>
<li>default</li>
<li>defer</li>
<li>else</li>
<li>error</li>
<li>fallthrough</li>
<li>float32</li>
<li>float64</li>
<li>for</li>
<li>func</li>
<li>go</li>
<li>goto</li>
<li>if</li>
<li>import</li>
<li>int</li>
<li>int16</li>
<li>int32</li>
<li>int64</li>
<li>int8</li>
<li>interface</li>
<li>map</li>
<li>nil</li>
<li>package</li>
<li>range</li>
<li>return</li>
<li>rune</li>
<li>select</li>
<li>string</li>
<li>struct</li>
<li>switch</li>
<li>type</li>
<li>uint</li>
<li>uint16</li>
<li>uint32</li>
<li>uint64</li>
<li>uint8</li>
<li>uintptr</li>
<li>var</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Array|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✓|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✗|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✗|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✗|OAS2,OAS3
|Union|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✗|OAS2,OAS3
|ApiKey|✗|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✗|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@ -7,6 +7,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|addResponseHeaders|To include response headers in ImplResponse| |false|
|enumClassPrefix|Prefix enum with class name| |false|
|featureCORS|Enable Cross-Origin Resource Sharing middleware| |false|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|

View File

@ -33,7 +33,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|responseAs|Optionally use libraries to manage response. Currently PromiseKit, RxSwift, Result, Combine are available.| |null|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|swiftPackagePath|Set a custom source path instead of OpenAPIClient/Classes/OpenAPIs.| |null|
|swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null|
|useBacktickEscapes|Escape reserved words using backticks (default: false)| |false|
|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null|
## IMPORT MAPPING

View File

@ -15,7 +15,9 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.0.0</version>
<!-- RELEASE_VERSION -->
<version>5.1.0</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
<goals>

View File

@ -910,9 +910,9 @@ x-content-type: application/json
### Rust-server
#### x-responseId
#### x-response-id
Each response may specify a unique `x-responseId`. `rust-server` will use this to name the corresponding enum variant in the code. e.g.
Each response may specify a unique `x-response-id`. `rust-server` will use this to name the corresponding enum variant in the code. e.g.
```yaml
paths:
@ -921,7 +921,7 @@ paths:
responses:
200:
description: OK
x-responseId: Pong
x-response-id: Pong
```
### MySQL Schema

View File

@ -10,12 +10,13 @@ This page demonstrates navigating the options via CLI. Commands are presented he
The `help` option lists all commands available to the CLI.
```bash
```text
openapi-generator-cli help
usage: openapi-generator-cli <command> [<args>]
The most commonly used openapi-generator-cli commands are:
author Utilities for authoring generators or customizing templates.
batch Generate code in batch via external configs.
config-help Config help for chosen lang
generate Generate code with the specified generator.
help Display help information about openapi-generator
@ -30,26 +31,28 @@ command.
## version
The version command provides version information, returning either the semver version by default or the git sha when passed `--sha`.
The version command provides version information, returning either the version by default, the git commit sha when passed `--sha`, or verbose output when passed `--full`.
```bash
```text
NAME
openapi-generator-cli version - Show version information
openapi-generator-cli version - Show version information used in tooling
SYNOPSIS
openapi-generator-cli version [--sha]
openapi-generator-cli version [--full] [--sha]
OPTIONS
--full
Full version details
--sha
Git commit SHA version
```
## list
The `list` command outputs a formatted list of every available generator. Pass the `-s/--short` option if you would like a CSV output for easy parsing.
```bash
```text
openapi-generator-cli help list
NAME
openapi-generator-cli list - Lists the available generators
@ -66,7 +69,6 @@ OPTIONS
-s, --short
shortened output (suitable for scripting)
```
Example:
@ -81,26 +83,49 @@ For the full list of generators, refer to the [Generators List](./generators.md)
The `config-help` option provides details about
```bash
```text
openapi-generator-cli help config-help
NAME
openapi-generator-cli config-help - Config help for chosen lang
SYNOPSIS
openapi-generator-cli config-help
[(-f <output format> | --format <output format>)]
[(-f <output format> | --format <output format>)] [--feature-set]
[--full-details]
[(-g <generator name> | --generator-name <generator name>)]
[--markdown-header] [--named-header]
[(-o <output location> | --output <output location>)]
[--import-mappings] [--instantiation-types]
[--language-specific-primitive] [--markdown-header] [--named-header]
[(-o <output location> | --output <output location>)] [--reserved-words]
OPTIONS
-f <output format>, --format <output format>
Write output files in the desired format. Options are 'text',
'markdown' or 'yamlsample'. Default is 'text'.
--feature-set
displays feature set as supported by the generator
--full-details
displays CLI options as well as other configs/mappings (implies
--instantiation-types, --reserved-words,
--language-specific-primitives, --import-mappings,
--supporting-files)
-g <generator name>, --generator-name <generator name>
generator to get config help for
--import-mappings
displays the default import mappings (types and aliases, and what
imports they will pull into the template)
--instantiation-types
displays types used to instantiate simple type/alias names
--language-specific-primitive
displays the language specific primitives (types which require no
additional imports, or which may conflict with user defined model
names)
--markdown-header
When format=markdown, include this option to write out markdown
headers (e.g. for docusaurus).
@ -112,6 +137,9 @@ OPTIONS
Optionally write help to this location, otherwise default is
standard output
--reserved-words
displays the reserved words which may result in renamed model or
property names
```
The option of note is `-g/--generator-name` (other options are exposed for tooling).
@ -153,7 +181,7 @@ To pass these go client generator-specific options to the `generate` command for
The `meta` command creates a new Java class and template files, used for creating your own custom templates.
```bash
```text
openapi-generator-cli help meta
NAME
openapi-generator-cli meta - MetaGenerator. Generator for creating a new
@ -161,11 +189,15 @@ NAME
the language you specify, and includes default templates to include.
SYNOPSIS
openapi-generator-cli meta [(-n <name> | --name <name>)]
openapi-generator-cli meta [(-l <language> | --language <language>)]
[(-n <name> | --name <name>)]
[(-o <output directory> | --output <output directory>)]
[(-p <package> | --package <package>)] [(-t <type> | --type <type>)]
OPTIONS
-l <language>, --language <language>
the implementation language for the generator class
-n <name>, --name <name>
the human-readable name of the generator
@ -186,7 +218,7 @@ For an in-depth example of using the `meta` command, see [Customization](./custo
The `validate` command allows you to validate an input specification, optionally providing recommendations for error fixes or other improvements (if available).
```bash
```text
openapi-generator-cli help validate
NAME
openapi-generator-cli validate - Validate specification
@ -200,7 +232,6 @@ OPTIONS
location of the OpenAPI spec, as URL or file (required)
--recommend
```
Valid Spec Example (using [petstore-v3.0.yaml](https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator-gradle-plugin/samples/local-spec/petstore-v3.0.yaml))
@ -250,7 +281,7 @@ An example bash completion script can be found in the repo at [scripts/openapi-g
The `generate` command is the workhorse of the generator toolset. As such, it has _many_ more options available than the previous commands. The abbreviated options are below, but you may expand the full descriptions.
```bash
```text
openapi-generator-cli help generate
NAME
openapi-generator-cli generate - Generate code with the specified
@ -269,23 +300,24 @@ SYNOPSIS
[--git-repo-id <git repo id>] [--git-user-id <git user id>]
[--global-property <global properties>...] [--group-id <group id>]
[--http-user-agent <http user agent>]
(-i <spec file> | --input-spec <spec file>)
[(-i <spec file> | --input-spec <spec file>)]
[--ignore-file-override <ignore file override location>]
[--import-mappings <import mappings>...]
[--instantiation-types <instantiation types>...]
[--invoker-package <invoker package>]
[--language-specific-primitives <language specific primitives>...]
[--library <library>] [--log-to-stderr] [--minimal-update]
[--legacy-discriminator-behavior] [--library <library>]
[--log-to-stderr] [--minimal-update]
[--model-name-prefix <model name prefix>]
[--model-name-suffix <model name suffix>]
[--model-package <model package>]
[(-o <output directory> | --output <output directory>)]
[(-p <additional properties> | --additional-properties <additional properties>)...]
[(-o <output directory> | --output <output directory>)] [(-p <additional properties> | --additional-properties <additional properties>)...]
[--package-name <package name>] [--release-note <release note>]
[--remove-operation-id-prefix]
[--reserved-words-mappings <reserved word mappings>...]
[(-s | --skip-overwrite)] [--server-variables <server variables>...]
[--skip-validate-spec] [--strict-spec <true/false strict behavior>]
[--skip-operation-example] [--skip-validate-spec]
[--strict-spec <true/false strict behavior>]
[(-t <template directory> | --template-dir <template directory>)]
[--type-mappings <type mappings>...] [(-v | --verbose)]
```
@ -293,7 +325,7 @@ SYNOPSIS
<details>
<summary>generate OPTIONS</summary>
```bash
```text
OPTIONS
-a <authorization>, --auth <authorization>
adds authorization headers when fetching the OpenAPI definitions
@ -303,7 +335,7 @@ OPTIONS
--api-name-suffix <api name suffix>
Suffix that will be appended to all API names ('tags'). Default:
Api. e.g. Pet => PetApi. Note: Only ruby, python, jaxrs generators
suppport this feature at the moment.
support this feature at the moment.
--api-package <api package>
package for generated api classes
@ -367,7 +399,8 @@ OPTIONS
'OpenAPI-Generator/{packageVersion}/{language}'
-i <spec file>, --input-spec <spec file>
location of the OpenAPI spec, as URL or file (required)
location of the OpenAPI spec, as URL or file (required if not loaded
via config using -c)
--ignore-file-override <ignore file override location>
Specifies an override location for the .openapi-generator-ignore
@ -394,13 +427,18 @@ OPTIONS
String,boolean,Boolean,Double. You can also have multiple
occurrences of this option.
--legacy-discriminator-behavior
Set to false for generators with better support for discriminators.
(Python, Java, Go, PowerShell, C#have this enabled by default).
--library <library>
library template (sub-template)
--log-to-stderr
write all log messages (not just errors) to STDOUT. Useful for
piping the JSON output of debug options (e.g. `--global-property debugOperations=true`)
to an external parser directly while testing a generator.
piping the JSON output of debug options (e.g. `--global-property
debugOperations`) to an external parser directly while testing a
generator.
--minimal-update
Only write output files that have changed.
@ -445,6 +483,9 @@ OPTIONS
sets server variables overrides for spec documents which support
variable templating of servers.
--skip-operation-example
Skip examples defined in operations to avoid out of memory errors.
--skip-validate-spec
Skips the default behavior of validating an input specification.
@ -464,7 +505,6 @@ OPTIONS
-v, --verbose
verbose mode
```
</details>
@ -604,19 +644,22 @@ The `batch` command allows you to move all CLI arguments supported by the `gener
*NOTE*: This command supports an additional `!include` property which may point to another "shared" file, the base path to which can be
modified by `--includes-base-dir`. Starting with 5.0.0, the `!batch` command supports multiple `!include` properties, either sequential or nested. In order to support multiple `!include` properties in a JSON file, the property name can have a suffix, e.g. `!include1`, `!include2`, etc. The suffix have no meaning other than providing unique property names.
```bash
```text
openapi-generator-cli help batch
NAME
openapi-generator-cli batch - Generate code in batch via external
configs.
SYNOPSIS
openapi-generator-cli batch [--fail-fast]
openapi-generator-cli batch [--clean] [--fail-fast]
[--includes-base-dir <includes>] [(-r <threads> | --threads <threads>)]
[--root-dir <root>] [--timeout <timeout>] [(-v | --verbose)] [--]
<configs>...
OPTIONS
--clean
clean output of previously written files before generation
--fail-fast
fail fast on any errors
@ -682,7 +725,7 @@ openapi-generator-cli batch *.yaml
This command group contains utilities for authoring generators or customizing templates.
```
```text
openapi-generator-cli help author
NAME
openapi-generator-cli author - Utilities for authoring generators or
@ -690,9 +733,9 @@ NAME
SYNOPSIS
openapi-generator-cli author
openapi-generator-cli author template [(-v | --verbose)]
openapi-generator-cli author template [--library <library>]
[(-v | --verbose)]
[(-o <output directory> | --output <output directory>)]
[--library <library>]
(-g <generator name> | --generator-name <generator name>)
OPTIONS
@ -708,13 +751,13 @@ COMMANDS
template
Retrieve templates for local modification
With --library option, library template (sub-template)
With --verbose option, verbose mode
With --output option, where to write the template files (defaults to
'out')
With --library option, library template (sub-template)
With --generator-name option, generator to use (see list command for
list)
```
@ -723,7 +766,8 @@ COMMANDS
This command allows user to extract templates from the CLI jar which simplifies customization efforts.
```
```text
openapi-generator-cli help author template
NAME
openapi-generator-cli author template - Retrieve templates for local
modification
@ -753,12 +797,12 @@ Example:
Extract Java templates, limiting to the `webclient` library.
```
```bash
openapi-generator-cli author template -g java --library webclient
```
Extract all Java templates:
```
```bash
openapi-generator-cli author template -g java
```

View File

@ -1,6 +1,4 @@
FROM java:8-jre-alpine
RUN apk add --no-cache bash
FROM openjdk:11.0-jre-buster
ADD target/openapi-generator-cli.jar /opt/openapi-generator/modules/openapi-generator-cli/target/openapi-generator-cli.jar

View File

@ -134,7 +134,8 @@ public class Generate extends OpenApiGeneratorCommand {
title = "type mappings",
description = "sets mappings between OpenAPI spec types and generated code types "
+ "in the format of OpenAPIType=generatedType,OpenAPIType=generatedType. For example: array=List,map=Map,string=String."
+ " You can also have multiple occurrences of this option.")
+ " You can also have multiple occurrences of this option."
+ " To map a specified format, use type+format, e.g. string+password=EncryptedString will map `type: string, format: password` to `EncryptedString`.")
private List<String> typeMappings = new ArrayList<>();
@Option(

View File

@ -212,7 +212,7 @@ apply plugin: 'org.openapi.generator'
|typeMappings
|Map(String,String)
|None
|Sets mappings between OpenAPI spec types and generated code types.
|Sets mappings between OpenAPI spec types and generated code types in the format of OpenAPIType=generatedType,OpenAPIType=generatedType. For example: `array=List,map=Map,string=String`. You can also have multiple occurrences of this option. To map a specified format, use type+format, e.g. string+password=EncryptedString will map `type: string, format: password` to `EncryptedString`.
|additionalProperties
|Map(String,Any)

View File

@ -81,9 +81,8 @@ open class GenerateTask : DefaultTask() {
val outputDir = project.objects.property<String>()
@Suppress("unused")
@get:Internal
@set:Option(option = "input", description = "The input specification.")
@Input
@Internal
var input: String? = null
set(value) {
inputSpec.set(value)

View File

@ -79,7 +79,7 @@ mvn clean compile
| `configOptions` | N/A | a **map** of language-specific parameters. To show a full list of generator-specified parameters (options), please use `configHelp` (explained below)
| `instantiationTypes` | `openapi.generator.maven.plugin.instantiationTypes` | sets instantiation type mappings in the format of type=instantiatedType,type=instantiatedType. For example (in Java): `array=ArrayList,map=HashMap`. In other words array types will get instantiated as ArrayList in generated code. You can also have multiple occurrences of this option
| `importMappings` | `openapi.generator.maven.plugin.importMappings` | specifies mappings between a given class and the import that should be used for that class in the format of type=import,type=import. You can also have multiple occurrences of this option
| `typeMappings` | `openapi.generator.maven.plugin.typeMappings` | sets mappings between OpenAPI spec types and generated code types in the format of OpenAPIType=generatedType,OpenAPIType=generatedType. For example: `array=List,map=Map,string=String`. You can also have multiple occurrences of this option
| `typeMappings` | `openapi.generator.maven.plugin.typeMappings` | sets mappings between OpenAPI spec types and generated code types in the format of OpenAPIType=generatedType,OpenAPIType=generatedType. For example: `array=List,map=Map,string=String`. You can also have multiple occurrences of this option. To map a specified format, use type+format, e.g. string+password=EncryptedString will map `type: string, format: password` to `EncryptedString`.
| `languageSpecificPrimitives` | `openapi.generator.maven.plugin.languageSpecificPrimitives` | specifies additional language specific primitive types in the format of type1,type2,type3,type3. For example: `String,boolean,Boolean,Double`. You can also have multiple occurrences of this option
| `additionalProperties` | `openapi.generator.maven.plugin.additionalProperties` | sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value. You can also have multiple occurrences of this option
| `serverVariableOverrides` | `openapi.generator.maven.plugin.serverVariableOverrides` | A map of server variable overrides for specs that support server URL templating

View File

@ -43,6 +43,7 @@ import com.google.common.io.CharSource;
import io.swagger.v3.parser.util.ClasspathHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
@ -423,6 +424,9 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(property = "codegen.configHelp")
private boolean configHelp = false;
@Parameter(defaultValue = "${mojoExecution}", readonly = true)
private MojoExecution mojo;
/**
* The project being built.
*/
@ -847,7 +851,7 @@ public class CodeGenMojo extends AbstractMojo {
name = Files.getNameWithoutExtension(segments[segments.length - 1]);
}
return new File(output.getPath() + File.separator + ".openapi-generator" + File.separator + name + ".sha256");
return new File(output.getPath() + File.separator + ".openapi-generator" + File.separator + name + "-" + mojo.getExecutionId() + ".sha256");
}
private String getCompileSourceRoot() {

View File

@ -16,9 +16,20 @@
package org.openapitools.codegen.plugin;
import org.apache.commons.io.FileUtils;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingRequest;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.openapitools.codegen.plugin.stubs.StubUtility;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
public class CodeGenMojoTest extends BaseTestCase {
@ -29,8 +40,8 @@ public class CodeGenMojoTest extends BaseTestCase {
@SuppressWarnings("unchecked")
public void testCommonConfiguration() throws Exception {
File testPom = StubUtility.basedPath(getUnitTestDir().toFile(), "common-maven", "common-maven.xml").toFile();
final CodeGenMojo mojo = (CodeGenMojo) lookupMojo("generate", testPom);
File folder = Files.createTempDirectory("test").toFile();
CodeGenMojo mojo = loadMojo(folder, "src/test/resources/default");
mojo.execute();
assertEquals("java", getVariableValueFromObject(mojo, "generatorName"));
assertEquals("jersey2", getVariableValueFromObject(mojo, "library"));
@ -42,4 +53,49 @@ public class CodeGenMojoTest extends BaseTestCase {
assertNotNull(configOptions);
assertEquals("joda", configOptions.get("dateLibrary"));
}
public void testHashGenerationFileContainsExecutionId() throws Exception {
// GIVEN
Path folder = Files.createTempDirectory("test");
CodeGenMojo mojo = loadMojo(folder.toFile(), "src/test/resources/default", "executionId");
// WHEN
mojo.execute();
// THEN
Path hashFolder = folder.resolve("target/generated-sources/common-maven/remote-openapi/.openapi-generator");
assertTrue(hashFolder.resolve("petstore.yaml-executionId.sha256").toFile().exists());
}
protected CodeGenMojo loadMojo(File temporaryFolder, String projectRoot) throws Exception {
return loadMojo(temporaryFolder, projectRoot, "default");
}
protected CodeGenMojo loadMojo(File temporaryFolder, String projectRoot, String executionId) throws Exception {
File file = new File(projectRoot);
FileUtils.copyDirectory(file, temporaryFolder);
MavenProject project = readMavenProject(temporaryFolder);
MavenSession session = newMavenSession(project);
MojoExecution execution = newMojoExecution("generate");
MojoExecution executionWithId = copyWithExecutionId(executionId, execution);
return (CodeGenMojo) lookupConfiguredMojo(session, executionWithId);
}
private MojoExecution copyWithExecutionId(String executionId, MojoExecution execution) {
MojoExecution executionWithId = new MojoExecution(execution.getMojoDescriptor(), executionId);
executionWithId.setConfiguration(execution.getConfiguration());
return executionWithId;
}
protected MavenProject readMavenProject(File basedir)
throws Exception {
File pom = new File(basedir, "pom.xml");
MavenExecutionRequest request = new DefaultMavenExecutionRequest();
request.setBaseDirectory(basedir);
ProjectBuildingRequest configuration = request.getProjectBuildingRequest();
configuration.setRepositorySession(new DefaultRepositorySystemSession());
MavenProject project = lookup(ProjectBuilder.class).build(pom, configuration).getProject();
assertNotNull(project);
return project;
}
}

View File

@ -29,8 +29,7 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<configuration>
<project implementation="org.openapitools.codegen.plugin.stubs.CommonMavenProjectStub"/>
<inputSpec>${basedir}/src/test/resources/unit/common-maven/petstore.yaml</inputSpec>
<inputSpec>${basedir}/petstore.yaml</inputSpec>
<generatorName>java</generatorName>
<configOptions>
<dateLibrary>joda</dateLibrary>
@ -43,7 +42,7 @@
</configuration>
<executions>
<execution>
<id>default</id>
<id>executionId</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>

View File

@ -206,7 +206,7 @@ public class CodegenConstants {
public static final String MODEL_PROPERTY_NAMING_DESC = "Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name";
public static final String DOTNET_FRAMEWORK = "targetFramework";
public static final String DOTNET_FRAMEWORK_DESC = "The target .NET framework version.";
public static final String DOTNET_FRAMEWORK_DESC = "The target .NET framework version. To target multiple frameworks, use `;` as the separator, e.g. `netstandard2.1;netcoreapp3.0`";
public static final String TEMPLATING_ENGINE = "templatingEngine";
public static final String TEMPLATING_ENGINE_DESC = "The templating engine plugin to use: \"mustache\" (default) or \"handlebars\" (beta)";

View File

@ -29,7 +29,7 @@ public class CodegenOperation {
isArray, isMultipart,
isResponseBinary = false, isResponseFile = false, hasReference = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems;
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public CodegenDiscriminator discriminator;
@ -168,6 +168,15 @@ public class CodegenOperation {
return nonempty(examples);
}
/**
* Check if there's a default response
*
* @return true if responses contain a default response, false otherwise
*/
public boolean getHasDefaultResponse() {
return responses.stream().filter(response -> response.isDefault).findFirst().isPresent();
}
/**
* Check if act as Restful index method
*
@ -270,6 +279,7 @@ public class CodegenOperation {
sb.append(", isResponseBinary=").append(isResponseBinary);
sb.append(", isResponseFile=").append(isResponseFile);
sb.append(", hasReference=").append(hasReference);
sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
sb.append(", isRestfulIndex=").append(isRestfulIndex);
sb.append(", isRestfulShow=").append(isRestfulShow);
sb.append(", isRestfulCreate=").append(isRestfulCreate);
@ -343,6 +353,7 @@ public class CodegenOperation {
isResponseBinary == that.isResponseBinary &&
isResponseFile == that.isResponseFile &&
hasReference == that.hasReference &&
hasDefaultResponse == that.hasDefaultResponse &&
isRestfulIndex == that.isRestfulIndex &&
isRestfulShow == that.isRestfulShow &&
isRestfulCreate == that.isRestfulCreate &&
@ -400,7 +411,7 @@ public class CodegenOperation {
return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
hasRequiredParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isResponseBinary, isResponseFile, hasReference, isRestfulIndex,
isArray, isMultipart, isResponseBinary, isResponseFile, hasReference, hasDefaultResponse, isRestfulIndex,
isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful, isDeprecated,
isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse, discriminator, consumes,

View File

@ -39,7 +39,7 @@ public class CodegenSecurity {
public String keyParamName;
public Boolean isKeyInQuery, isKeyInHeader, isKeyInCookie;
// Oauth specific
public String flow, authorizationUrl, tokenUrl;
public String flow, authorizationUrl, tokenUrl, refreshUrl;
public List<Map<String, Object>> scopes;
public Boolean isCode, isPassword, isApplication, isImplicit;
@ -66,6 +66,7 @@ public class CodegenSecurity {
filteredSecurity.flow = flow;
filteredSecurity.tokenUrl = tokenUrl;
filteredSecurity.authorizationUrl = authorizationUrl;
filteredSecurity.refreshUrl = refreshUrl;
// It is not possible to deep copy the extensions, as we have no idea what types they are.
// So the filtered method *will* refer to the original extensions, if any.
filteredSecurity.vendorExtensions = new HashMap<String, Object>(vendorExtensions);
@ -109,6 +110,7 @@ public class CodegenSecurity {
Objects.equals(flow, that.flow) &&
Objects.equals(authorizationUrl, that.authorizationUrl) &&
Objects.equals(tokenUrl, that.tokenUrl) &&
Objects.equals(refreshUrl, that.refreshUrl) &&
Objects.equals(scopes, that.scopes) &&
Objects.equals(isCode, that.isCode) &&
Objects.equals(isPassword, that.isPassword) &&
@ -122,7 +124,7 @@ public class CodegenSecurity {
return Objects.hash(name, type, scheme, isBasic, isOAuth, isApiKey,
isBasicBasic, isHttpSignature, isBasicBearer, bearerFormat, vendorExtensions,
keyParamName, isKeyInQuery, isKeyInHeader, isKeyInCookie, flow,
authorizationUrl, tokenUrl, scopes, isCode, isPassword, isApplication, isImplicit);
authorizationUrl, tokenUrl, refreshUrl, scopes, isCode, isPassword, isApplication, isImplicit);
}
@Override
@ -146,6 +148,7 @@ public class CodegenSecurity {
sb.append(", flow='").append(flow).append('\'');
sb.append(", authorizationUrl='").append(authorizationUrl).append('\'');
sb.append(", tokenUrl='").append(tokenUrl).append('\'');
sb.append(", refreshUrl='").append(refreshUrl).append('\'');
sb.append(", scopes=").append(scopes);
sb.append(", isCode=").append(isCode);
sb.append(", isPassword=").append(isPassword);

View File

@ -2043,6 +2043,10 @@ public class DefaultCodegen implements CodegenConfig {
private String getPrimitiveType(Schema schema) {
if (schema == null) {
throw new RuntimeException("schema cannot be null in getPrimitiveType");
} else if (typeMapping.containsKey(schema.getType() + "+" + schema.getFormat())) {
// allows custom type_format mapping.
// use {type}+{format}
return typeMapping.get(schema.getType() + "+" + schema.getFormat());
} else if (ModelUtils.isNullType(schema)) {
// The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x,
// though this tooling supports it.
@ -2702,14 +2706,14 @@ public class DefaultCodegen implements CodegenConfig {
String modelName = ModelUtils.getSimpleRef(oneOf.get$ref());
CodegenProperty thisCp = discriminatorFound(composedSchemaName, oneOf, discPropName, openAPI);
if (thisCp == null) {
throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced OneOf schema '" + modelName + "' is missing " + discPropName);
LOGGER.warn("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced OneOf schema '" + modelName + "' is missing " + discPropName);
}
if (cp.dataType == null) {
cp = thisCp;
continue;
}
if (cp != thisCp) {
throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the OneOf schema '" + modelName + "' has a different " + discPropName + " definition than the prior OneOf schema's. Make sure the " + discPropName + " type and required values are the same");
LOGGER.warn("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the OneOf schema '" + modelName + "' has a different " + discPropName + " definition than the prior OneOf schema's. Make sure the " + discPropName + " type and required values are the same");
}
}
return cp;
@ -2721,14 +2725,14 @@ public class DefaultCodegen implements CodegenConfig {
String modelName = ModelUtils.getSimpleRef(anyOf.get$ref());
CodegenProperty thisCp = discriminatorFound(composedSchemaName, anyOf, discPropName, openAPI);
if (thisCp == null) {
throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced AnyOf schema '" + modelName + "' is missing " + discPropName);
LOGGER.warn("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced AnyOf schema '" + modelName + "' is missing " + discPropName);
}
if (cp.dataType == null) {
cp = thisCp;
continue;
}
if (cp != thisCp) {
throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the AnyOf schema '" + modelName + "' has a different " + discPropName + " definition than the prior AnyOf schema's. Make sure the " + discPropName + " type and required values are the same");
LOGGER.warn("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the AnyOf schema '" + modelName + "' has a different " + discPropName + " definition than the prior AnyOf schema's. Make sure the " + discPropName + " type and required values are the same");
}
}
return cp;
@ -2787,7 +2791,7 @@ public class DefaultCodegen implements CodegenConfig {
}
}
if (discriminatorsPropNames.size() > 1) {
throw new RuntimeException("The oneOf schemas have conflicting discriminator property names. " +
LOGGER.warn("The oneOf schemas have conflicting discriminator property names. " +
"oneOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames));
}
if (foundDisc != null && (hasDiscriminatorCnt + hasNullTypeCnt) == composedSchema.getOneOf().size() && discriminatorsPropNames.size() == 1) {
@ -2816,7 +2820,7 @@ public class DefaultCodegen implements CodegenConfig {
}
}
if (discriminatorsPropNames.size() > 1) {
throw new RuntimeException("The anyOf schemas have conflicting discriminator property names. " +
LOGGER.warn("The anyOf schemas have conflicting discriminator property names. " +
"anyOf schemas must have the same property name, but found " + String.join(", ", discriminatorsPropNames));
}
if (foundDisc != null && (hasDiscriminatorCnt + hasNullTypeCnt) == composedSchema.getAnyOf().size() && discriminatorsPropNames.size() == 1) {
@ -2866,7 +2870,7 @@ public class DefaultCodegen implements CodegenConfig {
// schemas also has inline composed schemas
// Note: if it is only inline one level, then the inline model resolver will move it into its own
// schema and make it a $ref schema in the oneOf/anyOf location
throw new RuntimeException("Invalid inline schema defined in oneOf/anyOf in '" + composedSchemaName + "'. Per the OpenApi spec, for this case when a composed schema defines a discriminator, the oneOf/anyOf schemas must use $ref. Change this inline definition to a $ref definition");
LOGGER.warn("Invalid inline schema defined in oneOf/anyOf in '" + composedSchemaName + "'. Per the OpenApi spec, for this case when a composed schema defines a discriminator, the oneOf/anyOf schemas must use $ref. Change this inline definition to a $ref definition");
}
CodegenProperty df = discriminatorFound(composedSchemaName, sc, discPropName, openAPI);
String modelName = ModelUtils.getSimpleRef(ref);
@ -2886,7 +2890,7 @@ public class DefaultCodegen implements CodegenConfig {
msgSuffix += spacer + "invalid optional definition of " + discPropName + ", include it in required";
}
}
throw new RuntimeException("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced schema '" + modelName + "' is incorrect. " + msgSuffix);
LOGGER.warn("'" + composedSchemaName + "' defines discriminator '" + discPropName + "', but the referenced schema '" + modelName + "' is incorrect. " + msgSuffix);
}
MappedModel mm = new MappedModel(modelName, toModelName(modelName));
descendentSchemas.add(mm);
@ -5599,6 +5603,7 @@ public class DefaultCodegen implements CodegenConfig {
private void setOauth2Info(CodegenSecurity codegenSecurity, OAuthFlow flow) {
codegenSecurity.authorizationUrl = flow.getAuthorizationUrl();
codegenSecurity.tokenUrl = flow.getTokenUrl();
codegenSecurity.refreshUrl = flow.getRefreshUrl();
if (flow.getScopes() != null && !flow.getScopes().isEmpty()) {
List<Map<String, Object>> scopes = new ArrayList<>();

View File

@ -1,6 +1,7 @@
package org.openapitools.codegen.languages;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.ArraySchema;
@ -51,9 +52,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
protected String apiTestPath = "test" + File.separator;
protected String modelTestPath = "test" + File.separator;
// Names that must not be used as model names because they clash with existing
// default imports (dart:io, dart:async, package:http etc.) but are not basic dataTypes.
protected Set<String> additionalReservedWords;
protected Map<String, String> imports = new HashMap<>();
public AbstractDartCodegen() {
super();
@ -112,13 +111,13 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
}
setReservedWordsLowerCase(reservedWordsList);
// These types return isPrimitive=true in templates
languageSpecificPrimitives = Sets.newHashSet(
"String",
"bool",
"int",
"num",
"double",
"dynamic"
"double"
);
typeMapping = new HashMap<>();
@ -149,29 +148,31 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
typeMapping.put("object", "Object");
typeMapping.put("AnyType", "Object");
// DataTypes of the above values which are automatically imported.
// They are also not allowed to be model names.
// Data types of the above values which are automatically imported
defaultIncludes = Sets.newHashSet(
"String",
"bool",
"int",
"num",
"double",
"dynamic",
"List",
"Set",
"Map",
"DateTime",
"Object",
"MultipartFile"
"Object"
);
additionalReservedWords = Sets.newHashSet(
"File",
"Client",
"Future",
"Response"
);
imports.put("String", "dart:core");
imports.put("bool", "dart:core");
imports.put("int", "dart:core");
imports.put("num", "dart:core");
imports.put("double", "dart:core");
imports.put("List", "dart:core");
imports.put("Set", "dart:core");
imports.put("Map", "dart:core");
imports.put("DateTime", "dart:core");
imports.put("Object", "dart:core");
imports.put("MultipartFile", "package:http/http.dart");
cliOptions.add(new CliOption(PUB_LIBRARY, "Library name in generated code"));
cliOptions.add(new CliOption(PUB_NAME, "Name in generated pubspec"));
@ -182,7 +183,6 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
cliOptions.add(new CliOption(PUB_HOMEPAGE, "Homepage in generated pubspec"));
cliOptions.add(new CliOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums"));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "Source folder for generated code"));
}
@Override
@ -279,13 +279,17 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
}
}
@Override
protected boolean needToImport(String type) {
// Import everything, unless it is from dart:core.
return StringUtils.isNotBlank(type) && (!imports.containsKey(type) || !imports.get(type).equals("dart:core"));
}
@Override
protected boolean isReservedWord(String word) {
// consider everything as reserved that is either a keyword,
// a default included type, or a type include through some library
return super.isReservedWord(word) ||
defaultIncludes().contains(word) ||
additionalReservedWords.contains(word);
return super.isReservedWord(word) || defaultIncludes().contains(word);
}
@Override
@ -367,20 +371,34 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
@Override
public String toModelName(final String name) {
String nameWithPrefixSuffix = sanitizeName(name);
String sanitizedName = sanitizeName(name);
if (!StringUtils.isEmpty(modelNamePrefix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = modelNamePrefix + "_" + nameWithPrefixSuffix;
sanitizedName = modelNamePrefix + "_" + sanitizedName;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
// add '_' so that model name can be camelized correctly
nameWithPrefixSuffix = nameWithPrefixSuffix + "_" + modelNameSuffix;
sanitizedName = sanitizedName + "_" + modelNameSuffix;
}
// camelize the model name
// phone_number => PhoneNumber
final String camelizedName = camelize(nameWithPrefixSuffix);
final String camelizedName = camelize(sanitizedName);
// Check if there is a mapping that can be used
if (typeMapping().containsKey(camelizedName)) {
String typeName = typeMapping().get(camelizedName);
if (imports.containsKey(typeName)) {
// Anything with an import mapping is likely
// generator specific and can not be used as model name.
final String modelName = "Model" + camelizedName;
LOGGER.warn("{} (existing type) cannot be used as model name. Renamed to {}", camelizedName, modelName);
return modelName;
}
return typeName;
}
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
@ -473,11 +491,8 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
if (openAPIType == null) {
LOGGER.error("No Type defined for Schema {}", p);
}
if (typeMapping.containsKey(openAPIType)) {
return typeMapping.get(openAPIType);
}
if (languageSpecificPrimitives.contains(openAPIType)) {
return openAPIType;
if (typeMapping().containsKey(openAPIType)) {
return typeMapping().get(openAPIType);
}
return toModelName(openAPIType);
}
@ -607,8 +622,9 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
// operationId starts with a number
if (operationId.matches("^\\d.*")) {
LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId, camelize("call_" + operationId), true);
operationId = camelize("call_" + operationId, true);
String newOperationId = camelize("call_" + operationId, true);
LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId, newOperationId);
operationId = newOperationId;
}
return operationId;

View File

@ -311,16 +311,17 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override
public String toApiFilename(String name) {
final String apiName;
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
String api = name.replaceAll("-", "_");
// e.g. PetApi.go => pet_api.go
name = "api_" + underscore(name);
if (isReservedFilename(name)) {
LOGGER.warn(name + ".go with suffix (reserved word) cannot be used as filename. Renamed to " + name + "_.go");
name += "_";
api = "api_" + underscore(api);
if (isReservedFilename(api)) {
LOGGER.warn(name + ".go with suffix (reserved word) cannot be used as filename. Renamed to " + api + "_.go");
api += "_";
}
return name;
apiName = api;
return apiName;
}
/**
@ -807,7 +808,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
return; // skip if GO_POST_PROCESS_FILE env variable is not defined
}
// only procees the following type (or we can simply rely on the file extension to check if it's a Go file)
// only process the following type (or we can simply rely on the file extension to check if it's a Go file)
Set<String> supportedFileType = new HashSet<String>(
Arrays.asList(
"supporting-mustache",

View File

@ -590,38 +590,51 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
throw new RuntimeException("Invalid HTTP library " + getLibrary() + ". Only restsharp, httpclient are supported.");
}
String framework = (String) additionalProperties.getOrDefault(CodegenConstants.DOTNET_FRAMEWORK, defaultFramework.name);
boolean strategyMatched = false;
FrameworkStrategy strategy = defaultFramework;
for (FrameworkStrategy frameworkStrategy : frameworkStrategies) {
if (framework.equals(frameworkStrategy.name)) {
strategy = frameworkStrategy;
strategyMatched = true;
String inputFramework = (String) additionalProperties.getOrDefault(CodegenConstants.DOTNET_FRAMEWORK, defaultFramework.name);
String[] frameworks;
List<FrameworkStrategy> strategies = new ArrayList<>();
if (inputFramework.contains(";")) {
// multiple target framework
frameworks = inputFramework.split(";");
additionalProperties.put("multiTarget", true);
} else {
// just a single value
frameworks = new String [] {inputFramework};
}
for (String framework : frameworks) {
boolean strategyMatched = false;
for (FrameworkStrategy frameworkStrategy : frameworkStrategies) {
if (framework.equals(frameworkStrategy.name)) {
strategies.add(frameworkStrategy);
strategyMatched = true;
}
if (frameworkStrategy != FrameworkStrategy.NETSTANDARD_2_0 && "restsharp".equals(getLibrary())) {
LOGGER.warn("If using built-in templates, RestSharp only supports netstandard 2.0 or later.");
}
}
if (!strategyMatched) {
// throws exception if the input targetFramework is invalid
throw new IllegalArgumentException("The input (" + inputFramework + ") contains Invalid .NET framework version: " +
framework + ". List of supported versions: " +
frameworkStrategies.stream()
.map(p -> p.name)
.collect(Collectors.joining(", ")));
}
}
// throws exception if the input targetFramework is invalid
if (strategyMatched == false) {
throw new IllegalArgumentException("Invalid .NET framework version: " +
framework + ". List of supported versions: " +
frameworkStrategies.stream()
.map(p -> p.name)
.collect(Collectors.joining(", ")));
}
strategy.configureAdditionalProperties(additionalProperties);
setTargetFrameworkNuget(strategy.getNugetFrameworkIdentifier());
setTargetFramework(strategy.name);
setTestTargetFramework(strategy.testTargetFramework);
if (strategy != FrameworkStrategy.NETSTANDARD_2_0) {
LOGGER.warn("If using built-in templates-RestSharp only supports netstandard 2.0 or later.");
}
configureAdditionalPropertiesForFrameworks(additionalProperties, strategies);
setTargetFrameworkNuget(strategies);
setTargetFramework(strategies);
setTestTargetFramework(strategies);
setSupportsAsync(Boolean.TRUE);
setNetStandard(strategy.isNetStandard);
setNetStandard(strategies.stream().anyMatch(p -> Boolean.TRUE.equals(p.isNetStandard)));
if (!strategy.isNetStandard) {
if (!netStandard) {
setNetCoreProjectFileFlag(true);
}
@ -774,14 +787,39 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
LOGGER.info("Generating code for .NET Framework " + this.targetFramework);
}
public void setTargetFramework(List<FrameworkStrategy> strategies) {
for (FrameworkStrategy strategy : strategies) {
if (!frameworks.containsKey(strategy.name)) {
throw new IllegalArgumentException("Invalid .NET framework version: " +
strategy.name + ". List of supported versions: " +
frameworkStrategies.stream()
.map(p -> p.name)
.collect(Collectors.joining(", ")));
}
}
this.targetFramework = strategies.stream().map(p -> p.name)
.collect(Collectors.joining(";"));
LOGGER.info("Generating code for .NET Framework " + this.targetFramework);
}
public void setTestTargetFramework(String testTargetFramework) {
this.testTargetFramework = testTargetFramework;
}
public void setTestTargetFramework(List<FrameworkStrategy> strategies) {
this.testTargetFramework = strategies.stream().map(p -> p.testTargetFramework)
.collect(Collectors.joining(";"));
}
public void setTargetFrameworkNuget(String targetFrameworkNuget) {
this.targetFrameworkNuget = targetFrameworkNuget;
}
public void setTargetFrameworkNuget(List<FrameworkStrategy> strategies) {
this.targetFrameworkNuget = strategies.stream().map(p -> p.getNugetFrameworkIdentifier())
.collect(Collectors.joining(";"));
}
public void setValidatable(boolean validatable) {
this.validatable = validatable;
}
@ -1003,6 +1041,23 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
}
}
protected void configureAdditionalPropertiesForFrameworks(final Map<String, Object> properties, List<FrameworkStrategy> strategies) {
properties.putIfAbsent(CodegenConstants.DOTNET_FRAMEWORK, strategies.stream()
.map(p -> p.name)
.collect(Collectors.joining(";")));
// not intended to be user-settable
properties.put(TARGET_FRAMEWORK_IDENTIFIER, strategies.stream()
.map(p -> p.getTargetFrameworkIdentifier())
.collect(Collectors.joining(";")));
properties.put(TARGET_FRAMEWORK_VERSION, strategies.stream()
.map(p -> p.getTargetFrameworkVersion())
.collect(Collectors.joining(";")));
properties.putIfAbsent(MCS_NET_VERSION_KEY, "4.6-api");
properties.put(NET_STANDARD, strategies.stream().anyMatch(p -> Boolean.TRUE.equals(p.isNetStandard)));
}
/**
* Return the instantiation type of the property, especially for map and array
*

View File

@ -37,20 +37,6 @@ public class DartClientCodegen extends AbstractDartCodegen {
public DartClientCodegen() {
super();
additionalReservedWords.addAll(
Sets.newHashSet(
"StreamedRequest",
"ApiClient",
"QueryParam",
"Authentication",
"HttpBasicAuth",
"HttpBearerAuth",
"ApiKeyAuth",
"OAuth"
)
);
final CliOption serializationLibrary = CliOption.newString(CodegenConstants.SERIALIZATION_LIBRARY,
"Specify serialization library");
serializationLibrary.setDefault(SERIALIZATION_LIBRARY_NATIVE);

View File

@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -77,22 +78,11 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
typeMapping.put("object", "JsonObject");
typeMapping.put("AnyType", "JsonObject");
additionalReservedWords.addAll(Sets.newHashSet(
"EnumClass",
// The following are reserved dataTypes but can not be added to defaultIncludes
// as this would prevent them from being added to the imports.
"BuiltList",
"BuiltSet",
"BuiltMap",
"Uint8List",
"JsonObject"
));
importMapping.put("BuiltList", "package:built_collection/built_collection.dart");
importMapping.put("BuiltSet", "package:built_collection/built_collection.dart");
importMapping.put("BuiltMap", "package:built_collection/built_collection.dart");
importMapping.put("JsonObject", "package:built_value/json_object.dart");
importMapping.put("Uint8List", "dart:typed_data");
imports.put("BuiltList", "package:built_collection/built_collection.dart");
imports.put("BuiltSet", "package:built_collection/built_collection.dart");
imports.put("BuiltMap", "package:built_collection/built_collection.dart");
imports.put("JsonObject", "package:built_value/json_object.dart");
imports.put("Uint8List", "dart:typed_data");
}
public String getDateLibrary() {
@ -210,9 +200,8 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
typeMapping.put("Date", "OffsetDate");
typeMapping.put("DateTime", "OffsetDateTime");
typeMapping.put("datetime", "OffsetDateTime");
additionalReservedWords.addAll(Sets.newHashSet("OffsetDate", "OffsetDateTime"));
importMapping.put("OffsetDate", "package:time_machine/time_machine.dart");
importMapping.put("OffsetDateTime", "package:time_machine/time_machine.dart");
imports.put("OffsetDate", "package:time_machine/time_machine.dart");
imports.put("OffsetDateTime", "package:time_machine/time_machine.dart");
supportingFiles.add(new SupportingFile("local_date_serializer.mustache", libFolder, "local_date_serializer.dart"));
}
}
@ -225,21 +214,9 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
Set<String> modelImports = new HashSet<>();
CodegenModel cm = (CodegenModel) mo.get("model");
for (String modelImport : cm.imports) {
if (needToImport(modelImport)) {
if (importMapping().containsKey(modelImport)) {
modelImports.add(importMapping().get(modelImport));
} else {
modelImports.add("package:" + pubName + "/model/" + underscore(modelImport) + ".dart");
}
}
}
cm.imports = modelImports;
boolean hasVars = cm.vars.size() > 0;
cm.vendorExtensions.put("x-has-vars", hasVars);
cm.imports = rewriteImports(cm.imports);
cm.vendorExtensions.put("x-has-vars", !cm.vars.isEmpty());
}
return objs;
}
@ -292,8 +269,7 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
Set<Map<String, Object>> serializers = new HashSet<>();
Set<String> modelImports = new HashSet<>();
Set<String> fullImports = new HashSet<>();
Set<String> resultImports = new HashSet<>();
for (CodegenOperation op : operationList) {
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
@ -331,23 +307,11 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
op.vendorExtensions.put("x-is-form", isForm);
op.vendorExtensions.put("x-is-multipart", isMultipart);
resultImports.addAll(rewriteImports(op.imports));
if (op.getHasFormParams()) {
fullImports.add("package:" + pubName + "/api_util.dart");
resultImports.add("package:" + pubName + "/api_util.dart");
}
Set<String> imports = new HashSet<>();
for (String item : op.imports) {
if (needToImport(item)) {
if (importMapping().containsKey(item)) {
fullImports.add(importMapping().get(item));
} else {
imports.add(underscore(item));
}
}
}
modelImports.addAll(imports);
op.imports = imports;
if (op.returnContainer != null) {
final Map<String, Object> serializer = new HashMap<>();
serializer.put("isArray", Objects.equals("array", op.returnContainer) || Objects.equals("set", op.returnContainer));
@ -358,11 +322,21 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
}
}
objs.put("modelImports", modelImports);
objs.put("fullImports", fullImports);
objs.put("imports", resultImports.stream().sorted().collect(Collectors.toList()));
objs.put("serializers", serializers);
return objs;
}
private Set<String> rewriteImports(Set<String> originalImports) {
Set<String> resultImports = Sets.newHashSet();
for (String modelImport : originalImports) {
if (imports.containsKey(modelImport)) {
resultImports.add(imports.get(modelImport));
} else {
resultImports.add("package:" + pubName + "/model/" + underscore(modelImport) + ".dart");
}
}
return resultImports;
}
}

View File

@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -186,22 +187,11 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
typeMapping.put("object", "JsonObject");
typeMapping.put("AnyType", "JsonObject");
additionalReservedWords.addAll(Sets.newHashSet(
"EnumClass",
// The following are reserved dataTypes but can not be added to defaultIncludes
// as this would prevent them from being added to the imports.
"BuiltList",
"BuiltSet",
"BuiltMap",
"Uint8List",
"JsonObject"
));
importMapping.put("BuiltList", "package:built_collection/built_collection.dart");
importMapping.put("BuiltSet", "package:built_collection/built_collection.dart");
importMapping.put("BuiltMap", "package:built_collection/built_collection.dart");
importMapping.put("JsonObject", "package:built_value/json_object.dart");
importMapping.put("Uint8List", "dart:typed_data");
imports.put("BuiltList", "package:built_collection/built_collection.dart");
imports.put("BuiltSet", "package:built_collection/built_collection.dart");
imports.put("BuiltMap", "package:built_collection/built_collection.dart");
imports.put("JsonObject", "package:built_value/json_object.dart");
imports.put("Uint8List", "dart:typed_data");
}
private void configureDateLibrary(String srcFolder) {
@ -212,17 +202,22 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
typeMapping.put("Date", "OffsetDate");
typeMapping.put("DateTime", "OffsetDateTime");
typeMapping.put("datetime", "OffsetDateTime");
additionalReservedWords.addAll(Sets.newHashSet("OffsetDate", "OffsetDateTime"));
importMapping.put("OffsetDate", "package:time_machine/time_machine.dart");
importMapping.put("OffsetDateTime", "package:time_machine/time_machine.dart");
imports.put("OffsetDate", "package:time_machine/time_machine.dart");
imports.put("OffsetDateTime", "package:time_machine/time_machine.dart");
if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) {
supportingFiles.add(new SupportingFile("serialization/built_value/local_date_serializer.mustache", srcFolder, "local_date_serializer.dart"));
supportingFiles.add(new SupportingFile("serialization/built_value/offset_date_serializer.mustache", srcFolder, "local_date_serializer.dart"));
}
break;
default:
case DATE_LIBRARY_CORE:
// this option uses the dart core classes
additionalProperties.put("useDateLibCore", "true");
if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) {
typeMapping.put("date", "Date");
typeMapping.put("Date", "Date");
importMapping.put("Date", "package:" + pubName + "/src/model/date.dart");
supportingFiles.add(new SupportingFile("serialization/built_value/date.mustache", srcFolder + File.separator + "model", "date.dart"));
supportingFiles.add(new SupportingFile("serialization/built_value/date_serializer.mustache", srcFolder, "date_serializer.dart"));
}
break;
}
}
@ -261,21 +256,9 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
Set<String> modelImports = new HashSet<>();
CodegenModel cm = (CodegenModel) mo.get("model");
for (String modelImport : cm.imports) {
if (needToImport(modelImport)) {
if (importMapping().containsKey(modelImport)) {
modelImports.add(importMapping().get(modelImport));
} else {
modelImports.add("package:" + pubName + "/src/model/" + underscore(modelImport) + ".dart");
}
}
}
cm.imports = modelImports;
boolean hasVars = cm.vars.size() > 0;
cm.vendorExtensions.put("x-has-vars", hasVars);
cm.imports = rewriteImports(cm.imports);
cm.vendorExtensions.put("x-has-vars", !cm.vars.isEmpty());
}
return objs;
}
@ -319,6 +302,7 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
sb.append(")]");
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels);
@ -326,8 +310,7 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
Set<Map<String, Object>> serializers = new HashSet<>();
Set<String> modelImports = new HashSet<>();
Set<String> fullImports = new HashSet<>();
Set<String> resultImports = new HashSet<>();
for (CodegenOperation op : operationList) {
op.httpMethod = op.httpMethod.toLowerCase(Locale.ROOT);
@ -365,23 +348,11 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
op.vendorExtensions.put("x-is-form", isForm);
op.vendorExtensions.put("x-is-multipart", isMultipart);
resultImports.addAll(rewriteImports(op.imports));
if (op.getHasFormParams()) {
fullImports.add("package:" + pubName + "/src/api_util.dart");
resultImports.add("package:" + pubName + "/src/api_util.dart");
}
Set<String> imports = new HashSet<>();
for (String item : op.imports) {
if (needToImport(item)) {
if (importMapping().containsKey(item)) {
fullImports.add(importMapping().get(item));
} else {
imports.add(underscore(item));
}
}
}
modelImports.addAll(imports);
op.imports = imports;
if (op.returnContainer != null) {
final Map<String, Object> serializer = new HashMap<>();
serializer.put("isArray", Objects.equals("array", op.returnContainer) || Objects.equals("set", op.returnContainer));
@ -392,11 +363,21 @@ public class DartDioNextClientCodegen extends AbstractDartCodegen {
}
}
objs.put("modelImports", modelImports);
objs.put("fullImports", fullImports);
objs.put("imports", resultImports.stream().sorted().collect(Collectors.toList()));
objs.put("serializers", serializers);
return objs;
}
private Set<String> rewriteImports(Set<String> originalImports) {
Set<String> resultImports = Sets.newHashSet();
for (String modelImport : originalImports) {
if (imports.containsKey(modelImport)) {
resultImports.add(imports.get(modelImport));
} else {
resultImports.add("package:" + pubName + "/src/model/" + underscore(modelImport) + ".dart");
}
}
return resultImports;
}
}

View File

@ -280,4 +280,17 @@ public class FsharpGiraffeServerCodegen extends AbstractFSharpCodegen {
public String toRegularExpression(String pattern) {
return escapeText(pattern);
}
@Override
public void postProcess() {
System.out.println("################################################################################");
System.out.println("# Thanks for using OpenAPI Generator. #");
System.out.println("# Please consider donation to help us maintain this project \uD83D\uDE4F #");
System.out.println("# https://opencollective.com/openapi_generator/donate #");
System.out.println("# #");
System.out.println("# This generator's contributed by Nick Fisher (https://github.com/nmfisher) #");
System.out.println("# Please support his work directly via https://paypal.me/nickfisher1984 \uD83D\uDE4F #");
System.out.println("################################################################################");
}
}

View File

@ -0,0 +1,184 @@
/*
* 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
*
* https://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 org.openapitools.codegen.*;
import java.io.File;
import java.util.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoEchoServerCodegen extends AbstractGoCodegen {
static final Logger LOGGER = LoggerFactory.getLogger(GoEchoServerCodegen.class);
protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "openapi-go-echo-server";
protected String apiPath = "go";
private static final String MODEL_PACKAGE_NAME = "models";
private static final String API_PACKAGE_NAME = "handlers";
private static final String OUTPUT_PATH = "generated-code" + File.separator + "go-echo-server";
public CodegenType getTag() {
return CodegenType.SERVER;
}
public String getName() {
return "go-echo-server";
}
public String getHelp() {
return "Generates a go-echo server. (Beta)";
}
public GoEchoServerCodegen() {
super();
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.BETA)
.build();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
.securityFeatures(EnumSet.noneOf(
SecurityFeature.class
))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
.excludeParameterFeatures(
ParameterFeature.Cookie
)
);
outputFolder = OUTPUT_PATH;
modelTemplateFiles.put("model.mustache", ".go");
setModelPackage(MODEL_PACKAGE_NAME);
apiTemplateFiles.put("api.mustache", ".go");
embeddedTemplateDir = templateDir = "go-echo-server";
/*
* Reserved words. Override this with reserved words specific to your language
*/
setReservedWordsLowerCase(
Arrays.asList(
// data type
"string", "bool", "uint", "uint8", "uint16", "uint32", "uint64",
"int", "int8", "int16", "int32", "int64", "float32", "float64",
"complex64", "complex128", "rune", "byte", "uintptr",
"break", "default", "func", "interface", "select",
"case", "defer", "go", "map", "struct",
"chan", "else", "goto", "package", "switch",
"const", "fallthrough", "if", "range", "type",
"continue", "for", "import", "return", "var", "error", "nil")
// Added "error" as it's used so frequently that it may as well be a keyword
);
CliOption optServerPort = new CliOption("serverPort", "The network port the generated server binds to");
optServerPort.setType("int");
optServerPort.defaultValue(Integer.toString(serverPort));
cliOptions.add(optServerPort);
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels);
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
if (op.path != null) {
op.path = op.path.replaceAll("\\{(.*?)\\}", ":$1");
}
}
return objs;
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
} else {
setPackageName("openapi");
additionalProperties.put(CodegenConstants.PACKAGE_NAME, this.packageName);
}
/*
* Additional Properties. These values can be passed to the templates and
* are available in models, apis, and supporting files
*/
if (additionalProperties.containsKey("apiVersion")) {
this.apiVersion = (String) additionalProperties.get("apiVersion");
} else {
additionalProperties.put("apiVersion", apiVersion);
}
if (additionalProperties.containsKey("serverPort")) {
this.serverPort = Integer.parseInt((String) additionalProperties.get("serverPort"));
} else {
additionalProperties.put("serverPort", serverPort);
}
if (additionalProperties.containsKey("apiPath")) {
this.apiPath = (String) additionalProperties.get("apiPath");
} else {
additionalProperties.put("apiPath", apiPath);
}
if (additionalProperties.containsKey(CodegenConstants.ENUM_CLASS_PREFIX)) {
setEnumClassPrefix(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.ENUM_CLASS_PREFIX).toString()));
if (enumClassPrefix) {
additionalProperties.put(CodegenConstants.ENUM_CLASS_PREFIX, true);
}
}
/*
set model and package names, this is mainly used inside the templates.
*/
modelPackage = MODEL_PACKAGE_NAME;
apiPackage = API_PACKAGE_NAME;
/*
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
* it will be processed by the template engine. Otherwise, it will be copied
*/
supportingFiles.add(new SupportingFile("openapi.mustache", ".docs/api", "openapi.yaml"));
supportingFiles.add(new SupportingFile("hello-world.mustache", "models", "hello-world.go"));
supportingFiles.add(new SupportingFile("go-mod.mustache", "", "go.mod"));
supportingFiles.add(new SupportingFile("handler-container.mustache", "handlers", "container.go"));
supportingFiles.add(new SupportingFile("main.mustache", "", "main.go"));
supportingFiles.add(new SupportingFile("Dockerfile.mustache", "", "Dockerfile"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite());
}
}

View File

@ -37,6 +37,7 @@ public class GoServerCodegen extends AbstractGoCodegen {
protected String projectName = "openapi-server";
protected String sourceFolder = "go";
protected Boolean corsFeatureEnabled = false;
protected Boolean addResponseHeaders = false;
public GoServerCodegen() {
@ -80,6 +81,12 @@ public class GoServerCodegen extends AbstractGoCodegen {
cliOptions.add(CliOption.newBoolean(CodegenConstants.ENUM_CLASS_PREFIX, CodegenConstants.ENUM_CLASS_PREFIX_DESC));
// option to include headers in the response
CliOption optAddResponseHeaders = new CliOption("addResponseHeaders", "To include response headers in ImplResponse");
optAddResponseHeaders.setType("bool");
optAddResponseHeaders.defaultValue(addResponseHeaders.toString());
cliOptions.add(optAddResponseHeaders);
/*
* Models. You can write model files using the modelTemplateFiles map.
* if you want to create one template for file, you can do so here.
@ -172,12 +179,19 @@ public class GoServerCodegen extends AbstractGoCodegen {
} else {
additionalProperties.put("serverPort", serverPort);
}
if (additionalProperties.containsKey("featureCORS")) {
this.setFeatureCORS(convertPropertyToBooleanAndWriteBack("featureCORS"));
} else {
additionalProperties.put("featureCORS", corsFeatureEnabled);
}
if (additionalProperties.containsKey("addResponseHeaders")) {
this.setAddResponseHeaders(convertPropertyToBooleanAndWriteBack("addResponseHeaders"));
} else {
additionalProperties.put("addResponseHeaders", addResponseHeaders);
}
if (additionalProperties.containsKey(CodegenConstants.ENUM_CLASS_PREFIX)) {
setEnumClassPrefix(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.ENUM_CLASS_PREFIX).toString()));
if (enumClassPrefix) {
@ -221,10 +235,8 @@ public class GoServerCodegen extends AbstractGoCodegen {
// override imports to only include packages for interface parameters
imports.clear();
boolean addedOptionalImport = false;
boolean addedTimeImport = false;
boolean addedOSImport = false;
boolean addedReflectImport = false;
for (CodegenOperation operation : operations) {
for (CodegenParameter param : operation.allParams) {
// import "os" if the operation uses files
@ -233,7 +245,7 @@ public class GoServerCodegen extends AbstractGoCodegen {
addedOSImport = true;
}
// import "time" if the operation has a required time parameter.
// import "time" if the operation has a required time parameter
if (param.required) {
if (!addedTimeImport && "time.Time".equals(param.dataType)) {
imports.add(createMapping("import", "time"));
@ -314,4 +326,8 @@ public class GoServerCodegen extends AbstractGoCodegen {
public void setFeatureCORS(Boolean featureCORS) {
this.corsFeatureEnabled = featureCORS;
}
public void setAddResponseHeaders(Boolean addResponseHeaders) {
this.addResponseHeaders = addResponseHeaders;
}
}

View File

@ -17,6 +17,8 @@
package org.openapitools.codegen.languages;
import static java.util.Collections.sort;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants;
@ -463,6 +465,8 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/OffsetDateTimeAdapter.kt.mustache", infrastructureFolder, "OffsetDateTimeAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/BigDecimalAdapter.kt.mustache", infrastructureFolder, "BigDecimalAdapter.kt"));
supportingFiles.add(new SupportingFile("jvm-common/infrastructure/BigIntegerAdapter.kt.mustache", infrastructureFolder, "BigIntegerAdapter.kt"));
break;
case gson:
@ -654,6 +658,20 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
operation.path = operation.path.substring(1);
}
// sorting operation parameters to make sure path params are parsed before query params
if (operation.allParams != null) {
sort(operation.allParams, (one, another) -> {
if (one.isPathParam && another.isQueryParam) {
return -1;
}
if (one.isQueryParam && another.isPathParam){
return 1;
}
return 0;
});
}
// modify the data type of binary form parameters to a more friendly type for multiplatform builds
if (MULTIPLATFORM.equals(getLibrary()) && operation.allParams != null) {
for (CodegenParameter param : operation.allParams) {

View File

@ -540,8 +540,10 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
.filter(cm -> Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null)
.forEach(cm -> {
cm.imports.add(importMapping.get("JsonValue"));
cm.imports.add(importMapping.get("JsonProperty"));
Map<String, String> item = new HashMap<>();
item.put("import", importMapping.get("JsonValue"));
item.put("import", importMapping.get("JsonProperty"));
imports.add(item);
});

View File

@ -31,6 +31,8 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import static org.openapitools.codegen.utils.StringUtils.camelize;
public class NimClientCodegen extends DefaultCodegen implements CodegenConfig {
final Logger LOGGER = LoggerFactory.getLogger(NimClientCodegen.class);
@ -297,14 +299,32 @@ public class NimClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String toVarName(String name) {
if (isReservedWord(name)) {
name = escapeReservedWord(name);
// sanitize name
name = sanitizeName(name, "\\W-[\\$]"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if ("_".equals(name)) {
name = "_u";
}
// numbers are not allowed at the beginning
if (name.matches("^\\d.*")) {
name = "`" + name + "`";
}
// if it's all uppper case, do nothing
if (name.matches("^[A-Z0-9_]*$")) {
return name;
}
// camelize (lower first character) the variable name
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (isReservedWord(name)) {
name = escapeReservedWord(name);
}
return name;
}

View File

@ -416,20 +416,12 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
if (param.isContainer) {
param.vendorExtensions.put("x-comment-type", param.dataType + "[]");
}
// Quote default values for strings
// @todo: The default values for headers, forms and query params are handled
// in DefaultCodegen fromParameter with no real possibility to override
// the functionality. Thus we are handling quoting of string values here
if ("string".equals(param.dataType) && param.defaultValue != null && !param.defaultValue.isEmpty()) {
param.defaultValue = "'" + param.defaultValue + "'";
}
}
// Create a variable to display the correct return type in comments for interfaces
if (op.returnType != null) {
op.vendorExtensions.put("x-comment-type", op.returnType);
if (op.returnContainer != null && "array".equals(op.returnContainer)) {
if ("array".equals(op.returnContainer)) {
op.vendorExtensions.put("x-comment-type", op.returnType + "[]");
}
} else {

View File

@ -1323,6 +1323,23 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen {
for (Map.Entry<String, Schema> entry : requiredAndOptionalProps.entrySet()) {
String propName = entry.getKey();
Schema propSchema = entry.getValue();
boolean readOnly = false;
if (propSchema.getReadOnly() != null) {
readOnly = propSchema.getReadOnly();
}
if (readOnly) {
continue;
}
String ref = propSchema.get$ref();
if (ref != null) {
Schema refSchema = ModelUtils.getSchema(this.openAPI, ModelUtils.getSimpleRef(ref));
if (refSchema.getReadOnly() != null) {
readOnly = refSchema.getReadOnly();
}
if (readOnly) {
continue;
}
}
propName = toVarName(propName);
String propModelName = null;
Object propExample = null;

View File

@ -748,8 +748,14 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
return moduleName + "::" + codegenModel.classname + "::" + enumVars.get(0).get("name");
} else if (codegenModel.oneOf != null && !codegenModel.oneOf.isEmpty()) {
String subModel = (String) codegenModel.oneOf.toArray()[0];
String oneOf = constructExampleCode(modelMaps.get(subModel), modelMaps, processedModelMap);
return oneOf;
if (modelMaps.containsKey(subModel)) {
// oneOf models
return constructExampleCode(modelMaps.get(subModel), modelMaps, processedModelMap);
} else {
// TODO oneOf primitive type not supported at the moment
LOGGER.warn("oneOf example value not supported at the moment.");
return "nil";
}
} else {
processedModelMap.put(model, 1);
}

View File

@ -87,6 +87,7 @@ public class RubySinatraServerCodegen extends AbstractRubyCodegen {
supportingFiles.add(new SupportingFile("Gemfile", "", "Gemfile"));
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
supportingFiles.add(new SupportingFile("openapi.mustache", "", "openapi.yaml"));
supportingFiles.add(new SupportingFile("Dockerfile", "", "Dockerfile"));
}
@Override

View File

@ -1560,12 +1560,12 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
LOGGER.trace("Post processing model: {}", cm);
if (cm.dataType != null && "object".equals(cm.dataType)) {
if ("object".equals(cm.dataType)) {
// Object isn't a sensible default. Instead, we set it to
// 'null'. This ensures that we treat this model as a struct
// with multiple parameters.
cm.dataType = null;
} else if (cm.dataType != null && "map".equals(cm.dataType)) {
} else if ("map".equals(cm.dataType)) {
if (!cm.allVars.isEmpty() || cm.additionalPropertiesType == null) {
// We don't yet support `additionalProperties` that also have
// properties. If we see variables, we ignore the

View File

@ -336,8 +336,8 @@ public class SpringCodegen extends AbstractJavaCodegen
}
additionalProperties.put(UNHANDLED_EXCEPTION_HANDLING, this.isUnhandledException());
typeMapping.put("file", "org.springframework.core.io.Resource");
importMapping.put("org.springframework.core.io.Resource", "org.springframework.core.io.Resource");
typeMapping.put("file", "org.springframework.web.multipart.MultipartFile");
importMapping.put("org.springframework.web.multipart.MultipartFile", "org.springframework.web.multipart.MultipartFile");
if (useOptional) {
writePropertyBack(USE_OPTIONAL, useOptional);

View File

@ -534,12 +534,12 @@ public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
@Override
public boolean isDataTypeFile(String dataType) {
return dataType != null && "URL".equals(dataType);
return "URL".equals(dataType);
}
@Override
public boolean isDataTypeBinary(final String dataType) {
return dataType != null && "Data".equals(dataType);
return "Data".equals(dataType);
}
/**

View File

@ -61,6 +61,9 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
public static final String SWIFT_USE_API_NAMESPACE = "swiftUseApiNamespace";
public static final String DEFAULT_POD_AUTHORS = "OpenAPI Generator";
public static final String LENIENT_TYPE_CAST = "lenientTypeCast";
public static final String USE_SPM_FILE_STRUCTURE = "useSPMFileStructure";
public static final String SWIFT_PACKAGE_PATH = "swiftPackagePath";
public static final String USE_BACKTICK_ESCAPES = "useBacktickEscapes";
protected static final String LIBRARY_ALAMOFIRE = "alamofire";
protected static final String LIBRARY_URLSESSION = "urlsession";
protected static final String RESPONSE_LIBRARY_PROMISE_KIT = "PromiseKit";
@ -73,9 +76,12 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
protected boolean objcCompatible = false;
protected boolean lenientTypeCast = false;
protected boolean readonlyProperties = false;
protected boolean swiftUseApiNamespace;
protected boolean swiftUseApiNamespace = false;
protected boolean useSPMFileStructure = false;
protected String swiftPackagePath = "Classes" + File.separator + "OpenAPIs";
protected boolean useBacktickEscapes = false;
protected String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "OpenAPIs";
protected String sourceFolder = swiftPackagePath;
protected HashSet objcReservedWords;
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
@ -197,7 +203,6 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping = new HashMap<>();
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("map", "Dictionary");
typeMapping.put("set", "Set");
typeMapping.put("date", "Date");
@ -220,8 +225,8 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("UUID", "UUID");
typeMapping.put("URI", "String");
typeMapping.put("decimal", "Decimal");
typeMapping.put("object", "Any");
typeMapping.put("AnyType", "Any");
typeMapping.put("object", "AnyCodable");
typeMapping.put("AnyType", "AnyCodable");
importMapping = new HashMap<>();
@ -259,8 +264,15 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
"Accept and cast values for simple types (string->bool, "
+ "string->int, int->string)")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(USE_BACKTICK_ESCAPES,
"Escape reserved words using backticks (default: false)")
.defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(CodegenConstants.API_NAME_PREFIX, CodegenConstants.API_NAME_PREFIX_DESC));
cliOptions.add(new CliOption(USE_SPM_FILE_STRUCTURE, "Use SPM file structure"
+ " and set the source path to Sources" + File.separator + "{{projectName}} (default: false)."));
cliOptions.add(new CliOption(SWIFT_PACKAGE_PATH, "Set a custom source path instead of "
+ projectName + File.separator + "Classes" + File.separator + "OpenAPIs" + "."));
supportedLibraries.put(LIBRARY_URLSESSION, "[DEFAULT] HTTP client: URLSession");
supportedLibraries.put(LIBRARY_ALAMOFIRE, "HTTP client: Alamofire");
@ -334,7 +346,15 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
final Schema additionalProperties = getAdditionalProperties(schema);
if (additionalProperties != null) {
codegenModel.additionalPropertiesType = getSchemaType(additionalProperties);
Schema inner = null;
if (ModelUtils.isArraySchema(schema)) {
ArraySchema ap = (ArraySchema) schema;
inner = ap.getItems();
} else if (ModelUtils.isMapSchema(schema)) {
inner = getAdditionalProperties(schema);
}
codegenModel.additionalPropertiesType = inner != null ? getTypeDeclaration(inner) : getSchemaType(additionalProperties);
}
}
@ -414,6 +434,20 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
additionalProperties.put(POD_AUTHORS, DEFAULT_POD_AUTHORS);
}
if (additionalProperties.containsKey(USE_SPM_FILE_STRUCTURE)) {
setUseSPMFileStructure(convertPropertyToBooleanAndWriteBack(USE_SPM_FILE_STRUCTURE));
sourceFolder = "Sources" + File.separator + projectName;
}
if (additionalProperties.containsKey(SWIFT_PACKAGE_PATH) && ((String)additionalProperties.get(SWIFT_PACKAGE_PATH)).length() > 0) {
setSwiftPackagePath((String)additionalProperties.get(SWIFT_PACKAGE_PATH));
sourceFolder = swiftPackagePath;
}
if (additionalProperties.containsKey(USE_BACKTICK_ESCAPES)) {
setUseBacktickEscapes(convertPropertyToBooleanAndWriteBack(USE_BACKTICK_ESCAPES));
}
setLenientTypeCast(convertPropertyToBooleanAndWriteBack(LENIENT_TYPE_CAST));
// make api and model doc path available in mustache template
@ -501,7 +535,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
return useBacktickEscapes && !objcCompatible ? "`" + name + "`" : "_" + name;
}
@Override
@ -546,12 +580,12 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
@Override
public boolean isDataTypeFile(String dataType) {
return dataType != null && "URL".equals(dataType);
return "URL".equals(dataType);
}
@Override
public boolean isDataTypeBinary(final String dataType) {
return dataType != null && "Data".equals(dataType);
return "Data".equals(dataType);
}
/**
@ -720,11 +754,16 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
// for reserved words surround with `` or append _
if (isReservedWord(name)) {
name = escapeReservedWord(name);
}
// for words starting with number, append _
if (name.matches("^\\d.*")) {
name = "_" + name;
}
return name;
}
@ -745,11 +784,16 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
// pet_id => petId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (isReservedWord(name) || name.matches("^\\d.*")) {
// for reserved words surround with ``
if (isReservedWord(name)) {
name = escapeReservedWord(name);
}
// for words starting with number, append _
if (name.matches("^\\d.*")) {
name = "_" + name;
}
return name;
}
@ -806,6 +850,18 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
this.swiftUseApiNamespace = swiftUseApiNamespace;
}
public void setUseSPMFileStructure(boolean useSPMFileStructure) {
this.useSPMFileStructure = useSPMFileStructure;
}
public void setSwiftPackagePath(String swiftPackagePath) {
this.swiftPackagePath = swiftPackagePath;
}
public void setUseBacktickEscapes(boolean useBacktickEscapes) {
this.useBacktickEscapes = useBacktickEscapes;
}
@Override
public String toEnumValue(String value, String datatype) {
// for string, array of string

View File

@ -384,7 +384,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && "Blob".equals(dataType);
return "Blob".equals(dataType);
}
@Override

View File

@ -141,7 +141,7 @@ public class TypeScriptInversifyClientCodegen extends AbstractTypeScriptClientCo
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && "Blob".equals(dataType);
return "Blob".equals(dataType);
}
@Override

View File

@ -216,7 +216,7 @@ public class TypeScriptNestjsClientCodegen extends AbstractTypeScriptClientCodeg
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && "Blob".equals(dataType);
return "Blob".equals(dataType);
}
@Override

View File

@ -82,7 +82,7 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && "RequestFile".equals(dataType);
return "RequestFile".equals(dataType);
}
@Override

View File

@ -98,7 +98,7 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
@Override
public boolean isDataTypeFile(final String dataType) {
return dataType != null && "Blob".equals(dataType);
return "Blob".equals(dataType);
}
@Override

View File

@ -1,6 +1,6 @@
{{>licenseInfo}}
package {{invokerPackage}}.model;
package {{modelPackage}};
import {{invokerPackage}}.ApiException;
import java.util.Objects;

View File

@ -16,7 +16,6 @@ import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.Charset;
import java.time.Duration;
{{#java8}}
import java.time.OffsetDateTime;
@ -29,6 +28,8 @@ import java.util.StringJoiner;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Configuration and utility class for API clients.
*
@ -45,8 +46,6 @@ import java.util.stream.Collectors;
{{>generatedAnnotation}}
public class ApiClient {
private static final Charset UTF_8 = Charset.forName("UTF-8");
private HttpClient.Builder builder;
private ObjectMapper mapper;
private String scheme;
@ -171,7 +170,7 @@ public class ApiClient {
public ApiClient(HttpClient.Builder builder, ObjectMapper mapper, String baseUri) {
this.builder = builder;
this.mapper = mapper;
updateBaseUri(baseUri);
updateBaseUri(baseUri != null ? baseUri : getDefaultBaseUri());
interceptor = null;
readTimeout = null;
responseInterceptor = null;

View File

@ -65,6 +65,14 @@ public class {{classname}} {
}
{{/asyncNative}}
protected ApiException createApiException(HttpResponse<InputStream> response, String msgPrefix) throws IOException {
String body = response.body() == null ? null : new String(response.body().readAllBytes());
if (body != null) {
msgPrefix += ": " + body;
}
return new ApiException(response.statusCode(), msgPrefix, response.headers(), body);
}
{{#operation}}
{{#vendorExtensions.x-group-parameters}}
{{#hasParams}}
@ -207,10 +215,7 @@ public class {{classname}} {
memberVarResponseInterceptor.accept(localVarResponse);
}
if (localVarResponse.statusCode()/ 100 != 2) {
throw new ApiException(localVarResponse.statusCode(),
"{{operationId}} call received non-success response",
localVarResponse.headers(),
localVarResponse.body() == null ? null : new String(localVarResponse.body().readAllBytes()));
throw createApiException(localVarResponse, "{{operationId}} call received non-success response");
}
return new ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>(
localVarResponse.statusCode(),

View File

@ -40,14 +40,8 @@ if(hasProperty('target') && target == 'android') {
targetSdkVersion 25
}
compileOptions {
{{#java8}}
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
{{/java8}}
{{^java8}}
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
{{/java8}}
}
// Rename the aar correctly
@ -92,14 +86,8 @@ if(hasProperty('target') && target == 'android') {
apply plugin: 'java'
apply plugin: 'maven'
{{#java8}}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
{{/java8}}
{{^java8}}
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
{{/java8}}
install {
repositories.mavenInstaller {
@ -116,8 +104,8 @@ if(hasProperty('target') && target == 'android') {
dependencies {
implementation 'io.swagger:swagger-annotations:1.5.24'
implementation "com.google.code.findbugs:jsr305:3.0.2"
implementation 'com.squareup.okhttp3:okhttp:3.14.7'
implementation 'com.squareup.okhttp3:logging-interceptor:3.14.7'
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'io.gsonfire:gson-fire:1.8.4'
{{#hasOAuthMethods}}

View File

@ -71,7 +71,7 @@ public class {{classname}} {
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientException {
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.web.multipart.MultipartFile>{{/collectionFormat}}{{^collectionFormat}}org.springframework.web.multipart.MultipartFile{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientException {
{{#returnType}}
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).getBody();
{{/returnType}}
@ -99,7 +99,7 @@ public class {{classname}} {
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public ResponseEntity<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientException {
public ResponseEntity<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.web.multipart.MultipartFile>{{/collectionFormat}}{{^collectionFormat}}org.springframework.web.multipart.MultipartFile{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientException {
Object postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set

View File

@ -34,7 +34,7 @@ public class {{classname}}Test {
@Test
public void {{operationId}}Test() {
{{#allParams}}
{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}} = null;
{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.web.multipart.MultipartFile>{{/collectionFormat}}{{^collectionFormat}}org.springframework.web.multipart.MultipartFile{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}} = null;
{{/allParams}}
{{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});

View File

@ -87,7 +87,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
{{{vendorExtensions.x-extra-annotation}}}
{{/vendorExtensions.x-extra-annotation}}
{{#jackson}}
@JsonProperty("{{baseName}}")
@JsonProperty(value = "{{baseName}}"{{#isReadOnly}}, access = JsonProperty.Access.READ_ONLY{{/isReadOnly}}{{#isWriteOnly}}, access = JsonProperty.Access.WRITE_ONLY{{/isWriteOnly}})
{{/jackson}}
@ApiModelProperty({{#example}}example = "{{{example}}}", {{/example}}{{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}}

View File

@ -4,7 +4,7 @@ package {{configPackage}};
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
{{/useSpringfox}}
import org.springframework.stereotype.Controller;
{{^useSpringfox}}

View File

@ -131,3 +131,4 @@ org.openapitools.codegen.languages.TypeScriptNestjsClientCodegen
org.openapitools.codegen.languages.TypeScriptNodeClientCodegen
org.openapitools.codegen.languages.TypeScriptReduxQueryClientCodegen
org.openapitools.codegen.languages.TypeScriptRxjsClientCodegen
org.openapitools.codegen.languages.GoEchoServerCodegen

View File

@ -1,7 +1,6 @@
FROM ubuntu:16.10
FROM alpine:3.12.0
RUN apt-get update -y && apt-get full-upgrade -y
RUN apt-get install -y bash-completion zsh curl cowsay git vim bsdmainutils
RUN apk add --update --no-cache curl ca-certificates bash bash-completion zsh curl git vim ncurses util-linux
ADD {{scriptName}} /usr/bin/{{scriptName}}
ADD _{{scriptName}} /usr/local/share/zsh/site-functions/_{{scriptName}}
@ -30,7 +29,7 @@ RUN echo 'export PROMPT="[{{appName}}] \$ "' >> ~/.zshrc
#
# Setup a welcome message with basic instruction
#
RUN echo 'cat << EOF\n\
RUN echo -e 'echo "\
\n\
This Docker provides preconfigured environment for running the command\n\
line REST client for $(tput setaf 6){{appName}}$(tput sgr0).\n\
@ -63,7 +62,14 @@ $ {{scriptName}} <operationId> -h\n\
By default you are logged into Zsh with full autocompletion for your REST API,\n\
but you can switch to Bash, where basic autocompletion is also supported.\n\
\n\
EOF\n\
"\
' | tee -a ~/.bashrc ~/.zshrc
ENTRYPOINT ["zsh"]
#
# Poormans chsh & cleanup to make image as compact as possible
#
RUN sed -i 's/root:x:0:0:root:\/root:\/bin\/ash/root:x:0:0:root:\/root:\/bin\/zsh/' /etc/passwd
RUN apk del git vim && rm -f /var/cache/apk/*
ENTRYPOINT ["/bin/zsh"]

View File

@ -9,47 +9,83 @@ namespace {{this}} {
class {{prefix}}SerializerSettings {
public:
static void setDateTimeFormat(const QString & dtFormat){
getInstance()->dateTimeFormat = dtFormat;
struct CustomDateTimeFormat{
bool isStringSet = false;
QString formatString;
bool isEnumSet = false;
Qt::DateFormat formatEnum;
};
static CustomDateTimeFormat getCustomDateTimeFormat() {
return getInstance()->customDateTimeFormat;
}
static QString getDateTimeFormat() {
return getInstance()->dateTimeFormat;
static void setDateTimeFormatString(const QString &dtFormat){
getInstance()->customDateTimeFormat.isStringSet = true;
getInstance()->customDateTimeFormat.isEnumSet = false;
getInstance()->customDateTimeFormat.formatString = dtFormat;
}
static void setDateTimeFormatEnum(const Qt::DateFormat &dtFormat){
getInstance()->customDateTimeFormat.isEnumSet = true;
getInstance()->customDateTimeFormat.isStringSet = false;
getInstance()->customDateTimeFormat.formatEnum = dtFormat;
}
static {{prefix}}SerializerSettings *getInstance(){
if(instance == nullptr){
instance = new {{prefix}}SerializerSettings();
}
return instance;
}
private:
explicit {{prefix}}SerializerSettings(){
instance = this;
dateTimeFormat.clear();
customDateTimeFormat.isStringSet = false;
customDateTimeFormat.isEnumSet = false;
}
static {{prefix}}SerializerSettings *instance;
QString dateTimeFormat;
CustomDateTimeFormat customDateTimeFormat;
};
{{prefix}}SerializerSettings * {{prefix}}SerializerSettings::instance = nullptr;
bool setDateTimeFormat(const QString& dateTimeFormat){
bool setDateTimeFormat(const QString &dateTimeFormat){
bool success = false;
auto dt = QDateTime::fromString(QDateTime::currentDateTime().toString(dateTimeFormat), dateTimeFormat);
if(dt.isValid()){
if (dt.isValid()) {
success = true;
{{prefix}}SerializerSettings::setDateTimeFormat(dateTimeFormat);
{{prefix}}SerializerSettings::setDateTimeFormatString(dateTimeFormat);
}
return success;
}
bool setDateTimeFormat(const Qt::DateFormat &dateTimeFormat){
bool success = false;
auto dt = QDateTime::fromString(QDateTime::currentDateTime().toString(dateTimeFormat), dateTimeFormat);
if (dt.isValid()) {
success = true;
{{prefix}}SerializerSettings::setDateTimeFormatEnum(dateTimeFormat);
}
return success;
}
QString toStringValue(const QString &value) {
return value;
}
QString toStringValue(const QDateTime &value) {
if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet) {
return value.toString({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatString);
}
if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet) {
return value.toString({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum);
}
// ISO 8601
return {{prefix}}SerializerSettings::getInstance()->getDateTimeFormat().isEmpty()? value.toString(Qt::ISODate):value.toString({{prefix}}SerializerSettings::getInstance()->getDateTimeFormat());
return value.toString(Qt::ISODate);
}
QString toStringValue(const QByteArray &value) {
@ -98,7 +134,16 @@ QJsonValue toJsonValue(const QString &value) {
}
QJsonValue toJsonValue(const QDateTime &value) {
return QJsonValue(value.toString({{prefix}}SerializerSettings::getInstance()->getDateTimeFormat().isEmpty()?value.toString(Qt::ISODate):value.toString({{prefix}}SerializerSettings::getInstance()->getDateTimeFormat())));
if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet) {
return QJsonValue(value.toString({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatString));
}
if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet) {
return QJsonValue(value.toString({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum));
}
// ISO 8601
return QJsonValue(value.toString(Qt::ISODate));
}
QJsonValue toJsonValue(const QByteArray &value) {
@ -151,7 +196,15 @@ bool fromStringValue(const QString &inStr, QDateTime &value) {
if (inStr.isEmpty()) {
return false;
} else {
auto dateTime = {{prefix}}SerializerSettings::getInstance()->getDateTimeFormat().isEmpty()?QDateTime::fromString(inStr, Qt::ISODate) :QDateTime::fromString(inStr, {{prefix}}SerializerSettings::getInstance()->getDateTimeFormat());
QDateTime dateTime;
if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet) {
dateTime = QDateTime::fromString(inStr, {{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatString);
} else if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet) {
dateTime = QDateTime::fromString(inStr, {{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum);
} else {
dateTime = QDateTime::fromString(inStr, Qt::ISODate);
}
if (dateTime.isValid()) {
value.setDate(dateTime.date());
value.setTime(dateTime.time());
@ -256,7 +309,13 @@ bool fromJsonValue(QString &value, const QJsonValue &jval) {
bool fromJsonValue(QDateTime &value, const QJsonValue &jval) {
bool ok = true;
if (!jval.isUndefined() && !jval.isNull() && jval.isString()) {
value = {{prefix}}SerializerSettings::getInstance()->getDateTimeFormat().isEmpty()?QDateTime::fromString(jval.toString(), Qt::ISODate): QDateTime::fromString(jval.toString(), {{prefix}}SerializerSettings::getInstance()->getDateTimeFormat());
if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isStringSet) {
value = QDateTime::fromString(jval.toString(), {{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatString);
} else if ({{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().isEnumSet) {
value = QDateTime::fromString(jval.toString(), {{prefix}}SerializerSettings::getInstance()->getCustomDateTimeFormat().formatEnum);
} else {
value = QDateTime::fromString(jval.toString(), Qt::ISODate);
}
ok = value.isValid();
} else {
ok = false;

View File

@ -11,6 +11,7 @@
#include <QList>
#include <QMap>
#include <QSet>
#include <QVariant>
#include "{{prefix}}Enum.h"
#include "{{prefix}}HttpFileElement.h"
@ -41,7 +42,8 @@ public:
}
};
bool setDateTimeFormat(const QString&);
bool setDateTimeFormat(const QString &format);
bool setDateTimeFormat(const Qt::DateFormat &format);
template <typename T>
QString toStringValue(const QList<T> &val);

View File

@ -105,6 +105,11 @@ inline FStringFormatArg ToStringFormatArg(const FDateTime& Value)
return FStringFormatArg(Value.ToIso8601());
}
inline FStringFormatArg ToStringFormatArg(const FGuid& Value)
{
return FStringFormatArg(Value.ToString(EGuidFormats::DigitsWithHyphens));
}
inline FStringFormatArg ToStringFormatArg(const TArray<uint8>& Value)
{
return FStringFormatArg(Base64UrlEncode(Value));
@ -220,6 +225,11 @@ inline void WriteJsonValue(JsonWriter& Writer, const FDateTime& Value)
Writer->WriteValue(Value.ToIso8601());
}
inline void WriteJsonValue(JsonWriter& Writer, const FGuid& Value)
{
Writer->WriteValue(Value.ToString(EGuidFormats::DigitsWithHyphens));
}
inline void WriteJsonValue(JsonWriter& Writer, const Model& Value)
{
Value.WriteJson(Writer);
@ -281,6 +291,17 @@ inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, FDateTime&
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, FGuid& Value)
{
FString TmpValue;
if (JsonValue->TryGetString(TmpValue))
{
return FGuid::Parse(TmpValue, Value);
}
else
return false;
}
inline bool TryGetJsonValue(const TSharedPtr<FJsonValue>& JsonValue, bool& Value)
{
bool TmpValue;

View File

@ -17,7 +17,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>{{testPackageName}}</RootNamespace>
<AssemblyName>{{testPackageName}}</AssemblyName>
<TargetFramework>{{testTargetFramework}}</TargetFramework>
<TargetFramework{{#multiTarget}}s{{/multiTarget}}>{{testTargetFramework}}</TargetFramework{{#multiTarget}}s{{/multiTarget}}>
<IsPackable>false</IsPackable>
<FileAlignment>512</FileAlignment>
</PropertyGroup>

View File

@ -168,9 +168,9 @@ namespace {{packageName}}.Client
{
private readonly String _baseUrl;
private readonly HttpClientHandler _httpClientHandler;
private readonly HttpClient _httpClient;
private readonly bool _disposeClient;
private readonly HttpClientHandler _httpClientHandler;
private readonly HttpClient _httpClient;
private readonly bool _disposeClient;
/// <summary>
/// Specifies the settings on a <see cref="JsonSerializer" /> object.
@ -192,6 +192,7 @@ namespace {{packageName}}.Client
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
/// </summary>
[Obsolete("Constructors without HttpClient have non-trivial drawbacks and are thus considered deprecated. Check README.md for details.")]
public ApiClient() :
this({{packageName}}.Client.GlobalConfiguration.Instance.BasePath)
{
@ -202,78 +203,52 @@ namespace {{packageName}}.Client
/// </summary>
/// <param name="basePath">The target service's base path in URL format.</param>
/// <exception cref="ArgumentException"></exception>
[Obsolete("Constructors without HttpClient have non-trivial drawbacks and are thus considered deprecated. Check README.md for details.")]
public ApiClient(String basePath)
{
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
_httpClientHandler = new HttpClientHandler();
_httpClient = new HttpClient(_httpClientHandler, true);
_httpClientHandler = new HttpClientHandler();
_httpClient = new HttpClient(_httpClientHandler, true);
_disposeClient = true;
_baseUrl = basePath;
_baseUrl = basePath;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
/// </remarks>
public ApiClient(HttpClient client) :
this(client, {{packageName}}.Client.GlobalConfiguration.Instance.BasePath)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="basePath">The target service's base path in URL format.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
/// </remarks>
public ApiClient(HttpClient client, String basePath)
{
if (client == null) throw new ArgumentNullException("client cannot be null");
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
_httpClient = client;
_baseUrl = basePath;
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />, defaulting to the global configurations' base url.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="handler">An instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
public ApiClient(HttpClient client, HttpClientHandler handler) :
this(client, handler, {{packageName}}.Client.GlobalConfiguration.Instance.BasePath)
public ApiClient(HttpClient client, HttpClientHandler handler = null) :
this(client, {{packageName}}.Client.GlobalConfiguration.Instance.BasePath, handler)
{
}
/// <summary>
/// <summary>
/// Initializes a new instance of the <see cref="ApiClient" />.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="handler">An instance of HttpClientHandler that is used by HttpClient.</param>
/// <param name="basePath">The target service's base path in URL format.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public ApiClient(HttpClient client, HttpClientHandler handler, String basePath)
/// <param name="basePath">The target service's base path in URL format.</param>
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
/// </remarks>
public ApiClient(HttpClient client, String basePath, HttpClientHandler handler = null)
{
if (client == null) throw new ArgumentNullException("client cannot be null");
if (handler == null) throw new ArgumentNullException("handler cannot be null");
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
if (client == null) throw new ArgumentNullException("client cannot be null");
if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("basePath cannot be empty");
_httpClientHandler = handler;
_httpClient = client;
_baseUrl = basePath;
_httpClientHandler = handler;
_httpClient = client;
_baseUrl = basePath;
}
/// <summary>

View File

@ -108,6 +108,7 @@ namespace {{packageName}}.{{apiPackage}}
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <returns></returns>
[Obsolete("Constructors without HttpClient have non-trivial drawbacks and are thus considered deprecated. Check README.md for details.")]
public {{classname}}() : this((string)null)
{
}
@ -116,8 +117,9 @@ namespace {{packageName}}.{{apiPackage}}
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <param name="basePath">The target service's base path in URL format.</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
[Obsolete("Constructors without HttpClient have non-trivial drawbacks and are thus considered deprecated. Check README.md for details.")]
public {{classname}}(String basePath)
{
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
@ -138,6 +140,7 @@ namespace {{packageName}}.{{apiPackage}}
/// <param name="configuration">An instance of Configuration.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
[Obsolete("Constructors without HttpClient have non-trivial drawbacks and are thus considered deprecated. Check README.md for details.")]
public {{classname}}({{packageName}}.Client.Configuration configuration)
{
if (configuration == null) throw new ArgumentNullException("configuration");
@ -158,13 +161,14 @@ namespace {{packageName}}.{{apiPackage}}
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
/// </remarks>
public {{classname}}(HttpClient client) : this(client, (string)null)
public {{classname}}(HttpClient client, HttpClientHandler handler = null) : this(client, (string)null, handler)
{
}
@ -173,14 +177,15 @@ namespace {{packageName}}.{{apiPackage}}
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="basePath">The target service's base path in URL format.</param>
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
/// </remarks>
public {{classname}}(HttpClient client, String basePath)
public {{classname}}(HttpClient client, String basePath, HttpClientHandler handler = null)
{
if (client == null) throw new ArgumentNullException("client");
@ -188,7 +193,7 @@ namespace {{packageName}}.{{apiPackage}}
{{packageName}}.Client.GlobalConfiguration.Instance,
new {{packageName}}.Client.Configuration { BasePath = basePath }
);
this.ApiClient = new {{packageName}}.Client.ApiClient(client, this.Configuration.BasePath);
this.ApiClient = new {{packageName}}.Client.ApiClient(client, this.Configuration.BasePath, handler);
this.Client = this.ApiClient;
{{#supportsAsync}}
this.AsynchronousClient = this.ApiClient;
@ -201,85 +206,23 @@ namespace {{packageName}}.{{apiPackage}}
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="configuration">An instance of Configuration.</param>
/// <param name="handler">An optional instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
/// <remarks>
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// Some configuration settings will not be applied without passing an HttpClientHandler.
/// The features affected are: Setting and Retrieving Cookies, Client Certificates, Proxy settings.
/// </remarks>
public {{classname}}(HttpClient client, {{packageName}}.Client.Configuration configuration)
public {{classname}}(HttpClient client, {{packageName}}.Client.Configuration configuration, HttpClientHandler handler = null)
{
if (configuration == null) throw new ArgumentNullException("configuration");
if (client == null) throw new ArgumentNullException("client");
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
{{packageName}}.Client.GlobalConfiguration.Instance,
configuration
);
this.ApiClient = new {{packageName}}.Client.ApiClient(client, this.Configuration.BasePath);
this.Client = this.ApiClient;
{{#supportsAsync}}
this.AsynchronousClient = this.ApiClient;
{{/supportsAsync}}
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="handler">An instance of HttpClientHandler that is used by HttpClient.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public {{classname}}(HttpClient client, HttpClientHandler handler) : this(client, handler, (string)null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="handler">An instance of HttpClientHandler that is used by HttpClient.</param>
/// <param name="basePath">The target service's base path in URL format.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public {{classname}}(HttpClient client, HttpClientHandler handler, String basePath)
{
if (client == null) throw new ArgumentNullException("client");
if (handler == null) throw new ArgumentNullException("handler");
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
{{packageName}}.Client.GlobalConfiguration.Instance,
new {{packageName}}.Client.Configuration { BasePath = basePath }
);
this.ApiClient = new {{packageName}}.Client.ApiClient(client, handler, this.Configuration.BasePath);
this.Client = this.ApiClient;
{{#supportsAsync}}
this.AsynchronousClient = this.ApiClient;
{{/supportsAsync}}
this.ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
}
/// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class using Configuration object.
/// </summary>
/// <param name="client">An instance of HttpClient.</param>
/// <param name="handler">An instance of HttpClientHandler that is used by HttpClient.</param>
/// <param name="configuration">An instance of Configuration.</param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public {{classname}}(HttpClient client, HttpClientHandler handler, {{packageName}}.Client.Configuration configuration)
{
if (configuration == null) throw new ArgumentNullException("configuration");
if (client == null) throw new ArgumentNullException("client");
if (handler == null) throw new ArgumentNullException("handler");
this.Configuration = {{packageName}}.Client.Configuration.MergeConfigurations(
{{packageName}}.Client.GlobalConfiguration.Instance,
configuration
);
this.ApiClient = new {{packageName}}.Client.ApiClient(client, handler, this.Configuration.BasePath);
this.ApiClient = new {{packageName}}.Client.ApiClient(client, this.Configuration.BasePath, handler);
this.Client = this.ApiClient;
{{#supportsAsync}}
this.AsynchronousClient = this.ApiClient;

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TargetFramework>{{targetFramework}}</TargetFramework>
<TargetFramework{{#multiTarget}}s{{/multiTarget}}>{{targetFramework}}</TargetFramework{{#multiTarget}}s{{/multiTarget}}>
<AssemblyName>{{packageName}}</AssemblyName>
<PackageId>{{packageName}}</PackageId>
<OutputType>Library</OutputType>

View File

@ -3,7 +3,7 @@
<PropertyGroup>
<AssemblyName>{{testPackageName}}</AssemblyName>
<RootNamespace>{{testPackageName}}</RootNamespace>
<TargetFramework>{{testTargetFramework}}</TargetFramework>
<TargetFramework{{#multiTarget}}s{{/multiTarget}}>{{testTargetFramework}}</TargetFramework{{#multiTarget}}s{{/multiTarget}}>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@ -4,10 +4,8 @@ import 'package:dio/dio.dart';
import 'package:built_value/serializer.dart';
{{#operations}}
{{#modelImports}}import 'package:{{pubName}}/model/{{.}}.dart';
{{/modelImports}}
{{#fullImports}}import '{{.}}';
{{/fullImports}}
{{#imports}}import '{{.}}';
{{/imports}}
class {{classname}} {

View File

@ -1,16 +1,22 @@
name: {{pubName}}
version: {{pubVersion}}
description: {{pubDescription}}
homepage: {{pubHomepage}}
authors:
- '{{{pubAuthor}}} <{{{pubAuthorEmail}}}>'
environment:
sdk: '>=2.7.0 <3.0.0'
sdk: '>=2.7.0 <3.0.0'
dependencies:
dio: '^3.0.9'
built_value: '>=7.1.0 <8.0.0'
built_collection: '>=4.3.2 <5.0.0'
dio: '^3.0.9'
built_value: '>=7.1.0 <8.0.0'
built_collection: '>=4.3.2 <5.0.0'
{{#timeMachine}}
time_machine: '^0.9.12'
time_machine: '^0.9.12'
{{/timeMachine}}
dev_dependencies:
built_value_generator: '>=7.1.0 <8.0.0'
build_runner: any
test: '>=1.3.0 <1.16.0'
built_value_generator: '>=7.1.0 <8.0.0'
build_runner: any
test: '>=1.3.0 <1.16.0'

View File

@ -21,25 +21,32 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
* Dart 2.12.0 or later OR Flutter 1.26.0 or later
* Dio 4.0.0+
{{#useDateLibTimeMachine}}
* timemachine option currently **DOES NOT** support sound null-safety and may not work
{{/useDateLibTimeMachine}}
## Installation & Usage
### Github
If this Dart package is published to Github, please include the following in pubspec.yaml
```
name: {{pubName}}
version: {{pubVersion}}
description: {{pubDescription}}
### pub.dev
To use the package from [pub.dev](https://pub.dev), please include the following in pubspec.yaml
```yaml
dependencies:
{{pubName}}:
git: https://github.com/{{gitUserId}}/{{gitRepoId}}.git
version: 'any'
{{pubName}}: {{pubVersion}}
```
### Local
To use the package in your local drive, please include the following in pubspec.yaml
### Github
If this Dart package is published to Github, please include the following in pubspec.yaml
```yaml
dependencies:
{{pubName}}:
git:
url: https://github.com/{{gitUserId}}/{{gitRepoId}}.git
#ref: main
```
### Local development
To use the package from your local drive, please include the following in pubspec.yaml
```yaml
dependencies:
{{pubName}}:
path: /path/to/{{pubName}}

View File

@ -5,10 +5,8 @@ import 'dart:async';
import 'package:dio/dio.dart';
{{#operations}}
{{#modelImports}}import 'package:{{pubName}}/src/model/{{.}}.dart';
{{/modelImports}}
{{#fullImports}}import '{{.}}';
{{/fullImports}}
{{#imports}}import '{{.}}';
{{/imports}}
class {{classname}} {

View File

@ -3,7 +3,8 @@ export 'package:{{pubName}}/src/api.dart';
export 'package:{{pubName}}/src/auth/api_key_auth.dart';
export 'package:{{pubName}}/src/auth/basic_auth.dart';
export 'package:{{pubName}}/src/auth/oauth.dart';
{{#useBuiltValue}}export 'package:{{pubName}}/src/serializers.dart';{{/useBuiltValue}}
{{#useBuiltValue}}export 'package:{{pubName}}/src/serializers.dart';
{{#useDateLibCore}}export 'package:{{pubName}}/src/model/date.dart';{{/useDateLibCore}}{{/useBuiltValue}}
{{#apiInfo}}{{#apis}}export 'package:{{pubName}}/src/api/{{classFilename}}.dart';
{{/apis}}{{/apiInfo}}

View File

@ -1,6 +1,9 @@
name: {{pubName}}
version: {{pubVersion}}
description: {{pubDescription}}
homepage: {{pubHomepage}}
authors:
- '{{{pubAuthor}}} <{{{pubAuthorEmail}}}>'
environment:
sdk: '>=2.12.0 <3.0.0'
@ -8,7 +11,7 @@ environment:
dependencies:
dio: '>=4.0.0 <5.0.0'
{{#useBuiltValue}}
built_value: '>=8.0.3 <9.0.0'
built_value: '>=8.0.4 <9.0.0'
built_collection: '>=5.0.0 <6.0.0'
{{/useBuiltValue}}
{{#useDateLibTimeMachine}}
@ -17,7 +20,7 @@ dependencies:
dev_dependencies:
{{#useBuiltValue}}
built_value_generator: '>=8.0.3 <9.0.0'
built_value_generator: '>=8.0.4 <9.0.0'
build_runner: any
{{/useBuiltValue}}
test: '>=1.16.0 <1.17.0'

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