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

This commit is contained in:
William Cheng
2022-07-19 11:54:20 +08:00
2800 changed files with 126318 additions and 33030 deletions

View File

@@ -16,5 +16,5 @@
These must match the expectations made by your contribution. These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example `./bin/generate-samples.sh bin/configs/java*`. You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example `./bin/generate-samples.sh bin/configs/java*`.
For Windows users, please run the script in [Git BASH](https://gitforwindows.org/). For Windows users, please run the script in [Git BASH](https://gitforwindows.org/).
- [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (6.0.1) (patch release), `6.1.x` (breaking changes with fallbacks), `7.0.x` (breaking changes without fallbacks) - [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (6.1.0) (minor release - breaking changes with fallbacks), `7.0.x` (breaking changes without fallbacks)
- [ ] If your PR is targeting a particular programming language, @mention the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) members, so they are more likely to review the pull request. - [ ] If your PR is targeting a particular programming language, @mention the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) members, so they are more likely to review the pull request.

View File

@@ -32,6 +32,7 @@ jobs:
- samples/openapi3/client/petstore/java/jersey2-java8-special-characters - samples/openapi3/client/petstore/java/jersey2-java8-special-characters
- samples/openapi3/client/petstore/java/jersey2-java8 - samples/openapi3/client/petstore/java/jersey2-java8
- samples/client/petstore/java/okhttp-gson - samples/client/petstore/java/okhttp-gson
- samples/client/petstore/java/okhttp-gson-group-parameter
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-java@v3 - uses: actions/setup-java@v3

View File

@@ -5,10 +5,12 @@ on:
paths: paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/' - 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/server/petstore/aspnetcore-6.0/**' - 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
pull_request: pull_request:
paths: paths:
- 'samples/client/petstore/csharp-netcore/**net6.0**/' - 'samples/client/petstore/csharp-netcore/**net6.0**/'
- 'samples/server/petstore/aspnetcore-6.0/**' - 'samples/server/petstore/aspnetcore-6.0/**'
- 'samples/server/petstore/aspnetcore-6.0-pocoModels/**'
jobs: jobs:
build: build:
name: Build .Net projects name: Build .Net projects
@@ -21,6 +23,7 @@ jobs:
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0 - samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0
- samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0-nrt - samples/client/petstore/csharp-netcore/OpenAPIClient-generichost-net6.0-nrt
- samples/server/petstore/aspnetcore-6.0 - samples/server/petstore/aspnetcore-6.0
- samples/server/petstore/aspnetcore-6.0-pocoModels
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v2

43
.github/workflows/samples-jdk17.yaml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Samples JDK17
on:
push:
paths:
# clients
- samples/openapi3/client/petstore/spring-cloud-3
# servers
- samples/openapi3/server/petstore/springboot-3
pull_request:
paths:
# clients
- samples/openapi3/client/petstore/spring-cloud-3
# servers
- samples/openapi3/server/petstore/springboot-3
jobs:
build:
name: Build with JDK17
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# clients
- samples/openapi3/client/petstore/spring-cloud-3
# servers
- samples/openapi3/server/petstore/springboot-3
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
- name: Cache maven dependencies
uses: actions/cache@v3
env:
cache-name: maven-repository
with:
path: |
~/.m2
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package

32
.github/workflows/samples-php7.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Samples PHP 7.x
on:
push:
paths:
- samples/server/petstore/php-laravel/lib/
pull_request:
paths:
- samples/server/petstore/php-laravel/lib/
jobs:
build:
name: Build PHP projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# servers
- samples/server/petstore/php-laravel/lib/
steps:
- uses: actions/checkout@v3
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
tools: php-cs-fixer, phpunit
- name: composer install
working-directory: ${{ matrix.sample }}
run: composer install
- name: phpunit
working-directory: ${{ matrix.sample }}
run: vendor/bin/phpunit

32
.github/workflows/samples-php8.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Samples PHP 8.x
on:
push:
paths:
- samples/server/petstore/php-symfony/SymfonyBundle-php/
pull_request:
paths:
- samples/server/petstore/php-symfony/SymfonyBundle-php/
jobs:
build:
name: Build PHP projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# servers
- samples/server/petstore/php-symfony/SymfonyBundle-php/
steps:
- uses: actions/checkout@v3
- name: Setup PHP with tools
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: php-cs-fixer, phpunit
- name: composer install
working-directory: ${{ matrix.sample }}
run: composer install
- name: phpunit
working-directory: ${{ matrix.sample }}
run: vendor/bin/phpunit

View File

@@ -40,6 +40,7 @@ jobs:
- samples/server/petstore/spring-boot-nullable-set - samples/server/petstore/spring-boot-nullable-set
- samples/server/petstore/spring-boot-defaultInterface-unhandledException - samples/server/petstore/spring-boot-defaultInterface-unhandledException
- samples/openapi3/server/petstore/spring-boot-oneof - samples/openapi3/server/petstore/spring-boot-oneof
- samples/server/petstore/springboot-virtualan
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-java@v3 - uses: actions/setup-java@v3

5
.gitignore vendored
View File

@@ -222,6 +222,8 @@ samples/server/petstore/haskell-yesod/stack.yaml.lock
.Rproj.user .Rproj.user
samples/client/petstore/R/**/petstore.Rcheck/ samples/client/petstore/R/**/petstore.Rcheck/
samples/client/petstore/R/**/*.tar.gz samples/client/petstore/R/**/*.tar.gz
samples/client/petstore/R/R.Rproj
samples/client/petstore/R/man/
# elixir # elixir
samples/client/petstore/elixir/_build/ samples/client/petstore/elixir/_build/
@@ -266,3 +268,6 @@ samples/client/petstore/crystal/lib
# Go # Go
samples/openapi3/client/petstore/go/privatekey.pem samples/openapi3/client/petstore/go/privatekey.pem
## OCaml
samples/client/petstore/ocaml/_build/

137
.gitpod.yml Normal file
View File

@@ -0,0 +1,137 @@
## Learn more about this file at 'https://www.gitpod.io/docs/references/gitpod-yml'
##
## This '.gitpod.yml' file when placed at the root of a project instructs
## Gitpod how to prepare & build the project, start development environments
## and configure continuous prebuilds. Prebuilds when enabled builds a project
## like a CI server so you can start coding right away - no more waiting for
## dependencies to download and builds to finish when reviewing pull-requests
## or hacking on something new.
##
## With Gitpod you can develop software from any device (even iPads) via
## desktop or browser based versions of VS Code or any JetBrains IDE and
## customise it to your individual needs - from themes to extensions, you
## have full control.
##
## The easiest way to try out Gitpod is install the browser extenion:
## 'https://www.gitpod.io/docs/browser-extension' or by prefixing
## 'https://gitpod.io#' to the source control URL of any project.
##
## For example: 'https://gitpod.io#https://github.com/gitpod-io/gitpod'
## The 'image' section defines which Docker image Gitpod should use.
## By default, Gitpod uses a standard Docker Image called 'workspace-full'
## which can be found at 'https://github.com/gitpod-io/workspace-images'
##
## Workspaces started based on this default image come pre-installed with
## Docker, Go, Java, Node.js, C/C++, Python, Ruby, Rust, PHP as well as
## tools such as Homebrew, Tailscale, Nginx and several more.
##
## If this image does not include the tools needed for your project then
## a public Docker image or your own Docker file can be configured.
##
## Learn more about images at 'https://www.gitpod.io/docs/config-docker'
#image: node:buster # use 'https://hub.docker.com/_/node'
#
#image: # leave image undefined if using a Dockerfile
# file: .gitpod.Dockerfile # relative path to the Dockerfile from the
# # root of the project
## The 'tasks' section defines how Gitpod prepares and builds this project
## or how Gitpod can start development servers. With Gitpod, there are three
## types of tasks:
##
## - before: Use this for tasks that need to run before init and before command.
## - init: Use this to configure prebuilds of heavy-lifting tasks such as
## downloading dependencies or compiling source code.
## - command: Use this to start your database or application when the workspace starts.
##
## Learn more about these tasks at 'https://www.gitpod.io/docs/config-start-tasks'
#tasks:
# - before: |
# # commands to execute...
#
# - init: |
# # sudo apt-get install python3 # can be used to install operating system
# # dependencies but these are not kept after the
# # prebuild completes thus Gitpod recommends moving
# # operating system dependency installation steps
# # to a custom Dockerfile to make prebuilds faster
# # and to keep your codebase DRY.
# # 'https://www.gitpod.io/docs/config-docker'
#
# # pip install -r requirements.txt # install codebase dependencies
# # cmake # precompile codebase
#
# - name: Web Server
# openMode: split-left
# env:
# WEBSERVER_PORT: 8080
# command: |
# python3 -m http.server $WEBSERVER_PORT
#
# - name: Web Browser
# openMode: split-right
# env:
# WEBSERVER_PORT: 8080
# command: |
# gp await-port $WEBSERVER_PORT
# lynx `gp url`
tasks:
- init: ./mvnw package -DskipTests
## The 'ports' section defines various ports your may listen on are
## configured in Gitpod on an authenticated URL. By default, all ports
## are in private visibility state.
##
## Learn more about ports at 'https://www.gitpod.io/docs/config-ports'
#ports:
# - port: 8080 # alternatively configure entire ranges via '8080-8090'
# visibility: private # either 'public' or 'private' (default)
# onOpen: open-browser # either 'open-browser', 'open-preview' or 'ignore'
## The 'vscode' section defines a list of Visual Studio Code extensions from
## the OpenVSX.org registry to be installed upon workspace startup. OpenVSX
## is an open alternative to the proprietary Visual Studio Code Marketplace
## and extensions can be added by sending a pull-request with the extension
## identifier to https://github.com/open-vsx/publish-extensions
##
## The identifier of an extension is always ${publisher}.${name}.
##
## For example: 'vscodevim.vim'
##
## Learn more at 'https://www.gitpod.io/docs/ides-and-editors/vscode'
vscode:
extensions:
- redhat.java
- vscjava.vscode-java-pack
## The 'github' section defines configuration of continuous prebuilds
## for GitHub repositories when the GitHub application
## 'https://github.com/apps/gitpod-io' is installed in GitHub and granted
## permissions to access the repository.
##
## Learn more at 'https://www.gitpod.io/docs/prebuilds'
github:
prebuilds:
# enable for the default branch
master: true
# enable for all branches in this repo
branches: true
# enable for pull requests coming from this repo
pullRequests: true
# enable for pull requests coming from forks
pullRequestsFromForks: true
# add a check to pull requests
addCheck: true
# add a "Review in Gitpod" button as a comment to pull requests
addComment: true
# add a "Review in Gitpod" button to the pull request's description
addBadge: false

View File

@@ -111,11 +111,9 @@ before_install:
- cmake --version - cmake --version
# install Qt5 # install Qt5
#- sudo apt install -y --no-install-recommends qt5-default #- sudo apt install -y --no-install-recommends qt5-default
# -- skip perl test to shorten build time
# perl dep # perl dep
#- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib) - cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
#- cpanm --quiet --no-interactive Test::Exception Test::More Log::Any LWP::UserAgent URI::Query Module::Runtime DateTime Module::Find Moose::Role JSON || echo "Ignored failure from cpanm" - cpanm --quiet --no-interactive Test::Exception Test::More Log::Any LWP::UserAgent URI::Query Module::Runtime DateTime Module::Find Moose::Role JSON || echo "Ignored failure from cpanm"
# -- skip perl test end
# show host table to confirm petstore.swagger.io is mapped to localhost # show host table to confirm petstore.swagger.io is mapped to localhost
- cat /etc/hosts - cat /etc/hosts
# show java version # show java version

View File

@@ -80,6 +80,7 @@ elif [ "$NODE_INDEX" = "4" ]; then
#mvn --no-snapshot-updates --quiet verify -Psamples.circleci.node4 -Dorg.slf4j.simpleLogger.defaultLogLevel=error #mvn --no-snapshot-updates --quiet verify -Psamples.circleci.node4 -Dorg.slf4j.simpleLogger.defaultLogLevel=error
(cd samples/openapi3/client/petstore/python && make test) (cd samples/openapi3/client/petstore/python && make test)
(cd samples/openapi3/client/petstore/python-experimental && make test) (cd samples/openapi3/client/petstore/python-experimental && make test)
(cd samples/openapi3/client/3_0_3_unit_test/python-experimental && make test)
else else
echo "Running node $NODE_INDEX to test 'samples.circleci.others' defined in pom.xml ..." echo "Running node $NODE_INDEX to test 'samples.circleci.others' defined in pom.xml ..."

View File

@@ -3,25 +3,19 @@
<div align="center"> <div align="center">
[![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22) [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE) [![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator) [![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g) [![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator) [![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22) [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE) [![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator) [![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g) [![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator) [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/OpenAPITools/openapi-generator)
</div> </div>
<div align="center"> <div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.0.1`): [Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.1.0`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator) [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator) [![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator) [![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67) [![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/openapitools/openapi-generator/Check%20Supported%20Java%20Versions/master?label=Check%20Supported%20Java%20Versions&logo=github&logoColor=green)](https://github.com/OpenAPITools/openapi-generator/actions?query=workflow%3A%22Check+Supported+Java+Versions%22) [![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/openapitools/openapi-generator/Check%20Supported%20Java%20Versions/master?label=Check%20Supported%20Java%20Versions&logo=github&logoColor=green)](https://github.com/OpenAPITools/openapi-generator/actions?query=workflow%3A%22Check+Supported+Java+Versions%22)
[6.1.x](https://github.com/OpenAPITools/openapi-generator/tree/6.1.x) (`6.1.x`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/6.1.x.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/6.1.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
[![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=6.1.x&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator)
[![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/6.1.x?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67)
[7.0.x](https://github.com/OpenAPITools/openapi-generator/tree/7.0.x) (`7.0.x`): [7.0.x](https://github.com/OpenAPITools/openapi-generator/tree/7.0.x) (`7.0.x`):
[![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/7.0.x.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator) [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/7.0.x.svg?label=Integration%20Test)](https://travis-ci.com/OpenAPITools/openapi-generator)
[![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/7.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator) [![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/7.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator)
@@ -119,9 +113,8 @@ The OpenAPI Specification has undergone 3 revisions since initial creation in 20
| OpenAPI Generator Version | Release Date | Notes | | OpenAPI Generator Version | Release Date | Notes |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- | | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- |
| 7.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.0-SNAPSHOT/) | Feb/Mar 2023 | Major release with breaking changes (no fallback) | | 7.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.0-SNAPSHOT/) | Feb/Mar 2023 | Major release with breaking changes (no fallback) |
| 6.1.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.1.0-SNAPSHOT/) | 26.07 2022 | Minor release with breaking changes (with fallbac) | | 6.1.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.1.0-SNAPSHOT/) | 03.08 2022 | Minor release with breaking changes (with fallback) |
| 6.0.1 (upcoming patch release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.0.1-SNAPSHOT/) | 26.06 2022 | Patch release (enhancements, bug fixes, etc) | | [6.0.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.0.1) (latest stable release) | 03.07.2022 | Patch release (enhancements, bug fixes, etc) |
| [6.0.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.0.0) (latest stable release) | 26.05.2022 | Major release with breaking changes (no fallback) |
| [5.4.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.4.0) | 31.01.2022 | Minor release with breaking changes (with fallback) | | [5.4.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.4.0) | 31.01.2022 | Minor release with breaking changes (with fallback) |
| [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) | | [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) |
@@ -179,16 +172,16 @@ See the different versions of the [openapi-generator-cli](https://search.maven.o
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar` JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar`
For **Mac/Linux** users: For **Mac/Linux** users:
```sh ```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar -O openapi-generator-cli.jar wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar -O openapi-generator-cli.jar
``` ```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g. For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
``` ```
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar
``` ```
After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage. After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage.
@@ -413,7 +406,7 @@ openapi-generator-cli version
To use a specific version of "openapi-generator-cli" To use a specific version of "openapi-generator-cli"
```sh ```sh
openapi-generator-cli version-manager set 6.0.0 openapi-generator-cli version-manager set 6.0.1
``` ```
Or install it as dev-dependency: Or install it as dev-dependency:
@@ -437,7 +430,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
(if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`) (if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`)
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar) You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar)
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate` To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate`
@@ -578,6 +571,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Aalborg University](https://www.aau.dk) - [Aalborg University](https://www.aau.dk)
- [Adaptant Solutions AG](https://www.adaptant.io/) - [Adaptant Solutions AG](https://www.adaptant.io/)
- [adesso SE](https://www.adesso.de/) - [adesso SE](https://www.adesso.de/)
- [Adyen](https://www.adyen.com/)
- [Agoda](https://www.agoda.com/) - [Agoda](https://www.agoda.com/)
- [Airthings](https://www.airthings.com/) - [Airthings](https://www.airthings.com/)
- [Allianz](https://www.allianz.com) - [Allianz](https://www.allianz.com)
@@ -614,6 +608,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Element AI](https://www.elementai.com/) - [Element AI](https://www.elementai.com/)
- [Embotics](https://www.embotics.com/) - [Embotics](https://www.embotics.com/)
- [emineo](https://www.emineo.ch) - [emineo](https://www.emineo.ch)
- [fastly](https://www.fastly.com/)
- [Fenergo](https://www.fenergo.com/) - [Fenergo](https://www.fenergo.com/)
- [freee](https://corp.freee.co.jp/en/) - [freee](https://corp.freee.co.jp/en/)
- [FreshCells](https://www.freshcells.de/) - [FreshCells](https://www.freshcells.de/)
@@ -621,6 +616,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- [Gantner](https://www.gantner.com) - [Gantner](https://www.gantner.com)
- [GenFlow](https://github.com/RepreZen/GenFlow) - [GenFlow](https://github.com/RepreZen/GenFlow)
- [GetYourGuide](https://www.getyourguide.com/) - [GetYourGuide](https://www.getyourguide.com/)
- [Glovo](https://glovoapp.com/)
- [GMO Pepabo](https://pepabo.com/en/) - [GMO Pepabo](https://pepabo.com/en/)
- [GoDaddy](https://godaddy.com) - [GoDaddy](https://godaddy.com)
- [Gumtree](https://gumtree.com) - [Gumtree](https://gumtree.com)
@@ -868,6 +864,7 @@ Here are some companies/projects (alphabetical order) using OpenAPI Generator in
- 2022-04-01 - [OpenAPI Generatorのコード生成とSpring Frameworkのカスタムデータバインディングを共存させる](https://techblog.zozo.com/entry/coexistence-of-openapi-and-spring) in [ZOZO Tech Blog](https://techblog.zozo.com/) - 2022-04-01 - [OpenAPI Generatorのコード生成とSpring Frameworkのカスタムデータバインディングを共存させる](https://techblog.zozo.com/entry/coexistence-of-openapi-and-spring) in [ZOZO Tech Blog](https://techblog.zozo.com/)
- 2022-04-06 - [Effective Software Development using OpenAPI Generator](https://apexlabs.ai/post/openapi-generator) by Ajil Oommen (Senior Flutter Developer) - 2022-04-06 - [Effective Software Development using OpenAPI Generator](https://apexlabs.ai/post/openapi-generator) by Ajil Oommen (Senior Flutter Developer)
- 2022-05-13 - [A Path From an API To Client Libraries](https://www.youtube.com/watch?v=XC8oVn_efTw) by [Filip Srnec](https://www.devoxx.co.uk/talk/?id=11211) at Infobip - 2022-05-13 - [A Path From an API To Client Libraries](https://www.youtube.com/watch?v=XC8oVn_efTw) by [Filip Srnec](https://www.devoxx.co.uk/talk/?id=11211) at Infobip
- 2022-06-01 - [API First, using OpenAPI and Spring Boot](https://medium.com/xgeeks/api-first-using-openapi-and-spring-boot-2602c04bb0d3) by [Micael Estrázulas Vianna](https://estrazulas.medium.com/)
## [6 - About Us](#table-of-contents) ## [6 - About Us](#table-of-contents)

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-3.0 outputDir: samples/server/petstore/aspnetcore-3.0
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0 templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties: additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}' packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-3.1 outputDir: samples/server/petstore/aspnetcore-3.1
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0 templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties: additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}' packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-5.0 outputDir: samples/server/petstore/aspnetcore-5.0
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0 templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties: additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}' packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -0,0 +1,9 @@
generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-6.0-pocoModels
inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'
aspnetCoreVersion: "6.0"
userSecretsGuid: 'cb87e868-8646-48ef-9bb6-344b537d0d37'
pocoModels: true

View File

@@ -1,6 +1,6 @@
generatorName: aspnetcore generatorName: aspnetcore
outputDir: samples/server/petstore/aspnetcore-6.0 outputDir: samples/server/petstore/aspnetcore-6.0
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/aspnetcore/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0 templateDir: modules/openapi-generator/src/main/resources/aspnetcore/3.0
additionalProperties: additionalProperties:
packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}' packageGuid: '{3C799344-F285-4669-8FD5-7ED9B795D5C5}'

View File

@@ -0,0 +1,10 @@
generatorName: java
outputDir: samples/client/petstore/java/okhttp-gson-group-parameter
library: okhttp-gson
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/petstore-group-parameter.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: petstore-okhttp-gson-group-parameter
hideGenerationTimestamp: "true"
disallowAdditionalPropertiesIfNotPresent: false
useSingleRequestParameter: true

View File

@@ -0,0 +1,9 @@
generatorName: kotlin
outputDir: samples/client/petstore/kotlin-allOff-discriminator
inputSpec: modules/openapi-generator/src/test/resources/3_0/issue_10792.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
additionalProperties:
artifactId: kotlin-allOff-discriminator
serializableModel: "false"
dateLibrary: java8
enumUnknownDefaultCase: true

View File

@@ -1,6 +1,6 @@
generatorName: typescript-angular generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v2/default outputDir: samples/client/petstore/typescript-angular/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties: additionalProperties:
ngVersion: "2" ngVersion: 13.3.2

View File

@@ -1,10 +1,10 @@
generatorName: typescript-angular generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v4.3/npm outputDir: samples/client/petstore/typescript-angular/npm
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties: additionalProperties:
npmVersion: 0.0.1 npmVersion: 0.0.1
ngVersion: "4.3" ngVersion: 13.3.2
npmName: '@openapitools/angular2-typescript-petstore' npmName: '@openapitools/angular2-typescript-petstore'
npmRepository: https://skimdb.npmjs.com/registry npmRepository: https://skimdb.npmjs.com/registry
snapshot: false snapshot: false

View File

@@ -1,7 +1,7 @@
generatorName: typescript-angular generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v2/with-interfaces outputDir: samples/client/petstore/typescript-angular/with-interfaces
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties: additionalProperties:
withInterfaces: "true" withInterfaces: "true"
ngVersion: "2" ngVersion: 13.3.2

View File

@@ -2,3 +2,5 @@ generatorName: php-laravel
outputDir: samples/server/petstore/php-laravel outputDir: samples/server/petstore/php-laravel
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/php-laravel templateDir: modules/openapi-generator/src/main/resources/php-laravel
gitUserId: openapitools
gitRepoId: petstore

View File

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

View File

@@ -0,0 +1,6 @@
generatorName: python-experimental
outputDir: samples/openapi3/client/3_0_3_unit_test/python-experimental
inputSpec: modules/openapi-generator/src/test/resources/3_0/unit_test_spec/3_0_3_unit_test_spec.yaml
templateDir: modules/openapi-generator/src/main/resources/python-experimental
additionalProperties:
packageName: unit_test_api

View File

@@ -5,3 +5,7 @@ templateDir: modules/openapi-generator/src/main/resources/r
httpUserAgent: PetstoreAgent httpUserAgent: PetstoreAgent
additionalProperties: additionalProperties:
packageName: petstore packageName: petstore
exceptionPackage: rlang
useRlangExceptionHandling: true
returnExceptionOnFailure: true
errorObjectType: "ModelApiResponse"

View File

@@ -1,7 +1,7 @@
generatorName: rust generatorName: rust
outputDir: samples/client/petstore/rust/hyper/petstore outputDir: samples/client/petstore/rust/hyper/petstore
library: hyper library: hyper
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties: additionalProperties:
supportAsync: "false" supportAsync: "false"

View File

@@ -1,7 +1,7 @@
generatorName: rust generatorName: rust
outputDir: samples/client/petstore/rust/reqwest/petstore outputDir: samples/client/petstore/rust/reqwest/petstore
library: reqwest library: reqwest
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/rust templateDir: modules/openapi-generator/src/main/resources/rust
additionalProperties: additionalProperties:
supportAsync: false supportAsync: false

View File

@@ -0,0 +1,12 @@
generatorName: spring
outputDir: samples/openapi3/server/petstore/springboot-3
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties:
groupId: org.openapitools.openapi3
documentationProvider: springdoc
artifactId: springboot
snapshotVersion: "true"
useSpringBoot3: true
useBeanValidation: true
hideGenerationTimestamp: "true"

View File

@@ -4,7 +4,7 @@ library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/2_0/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/JavaSpring templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties: additionalProperties:
documentationProvider: springfox documentationProvider: springdoc
apiPackage: org.openapitools.virtualan.api apiPackage: org.openapitools.virtualan.api
modelPackage: org.openapitools.virtualan.model modelPackage: org.openapitools.virtualan.model
virtualService: true virtualService: true

View File

@@ -0,0 +1,13 @@
generatorName: spring
library: spring-cloud
outputDir: samples/openapi3/client/petstore/spring-cloud-3
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaSpring
additionalProperties:
groupId: org.openapitools.openapi3
documentationProvider: springdoc
artifactId: spring-cloud-oas3
useSpringBoot3: "true"
interfaceOnly: "true"
singleContentTypes: "true"
hideGenerationTimestamp: "true"

View File

@@ -1,10 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v10-provided-in-root/builds/with-npm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 10.0.0
npmVersion: 1.0.0
npmName: '@openapitools/typescript-angular-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,10 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v11-provided-in-root/builds/with-npm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 11.0.0
npmVersion: 1.0.0
npmName: '@openapitools/typescript-angular-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,6 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v11-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 11.0.0

View File

@@ -1,6 +1,6 @@
generatorName: typescript-angular generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v11-oneOf/builds/default outputDir: samples/client/petstore/typescript-angular-v12-oneOf/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties: additionalProperties:
ngVersion: 11.0.0 ngVersion: 12.2.0

View File

@@ -1,7 +1,7 @@
generatorName: typescript-angular generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v9-provided-in-any/builds/default outputDir: samples/client/petstore/typescript-angular-v12-provided-in-any/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties: additionalProperties:
ngVersion: 9.0.0 ngVersion: 12.2.0
providedIn: any providedIn: any

View File

@@ -0,0 +1,6 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v13-oneOf/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 13.0.1

View File

@@ -1,6 +1,7 @@
generatorName: typescript-angular generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v10-provided-in-root/builds/default outputDir: samples/client/petstore/typescript-angular-v13-provided-in-any/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties: additionalProperties:
ngVersion: 10.0.0 ngVersion: 13.0.1
providedIn: any

View File

@@ -1,10 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v9-provided-in-root/builds/with-npm
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 9.0.0
npmVersion: 1.0.0
npmName: '@openapitools/typescript-angular-petstore'
npmRepository: https://skimdb.npmjs.com/registry
snapshot: false

View File

@@ -1,6 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v9-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 9.0.0

View File

@@ -53,9 +53,7 @@ if [[ ${#files[@]} -eq 1 && "${files[0]}" != *'*'* ]]; then
java ${JAVA_OPTS} -jar "$executable" generate -c ${files[0]} ${args[@]} java ${JAVA_OPTS} -jar "$executable" generate -c ${files[0]} ${args[@]}
else else
echo "Please press CTRL+C to stop or the script will continue in 5 seconds." echo "Please press CTRL+C to stop or the script will continue in 5 seconds."
sleep 5 sleep 5
if [ ${#files[@]} -eq 0 ]; then if [ ${#files[@]} -eq 0 ]; then
files=("${root}"/bin/configs/*.yaml) files=("${root}"/bin/configs/*.yaml)
fi fi

View File

@@ -394,3 +394,51 @@ or
``` ```
--import-mappings Pet=my.models.MyPet --import-mappings Order=my.models.MyOrder --import-mappings Pet=my.models.MyPet --import-mappings Order=my.models.MyOrder
``` ```
## Schema Mapping
One can map the schema to someting else (e.g. external objects/models outside of the package) using the `schemaMappings` option, e.g. in CLI
```sh
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/type-alias.yaml -o /tmp/java2/ --schema-mapping TypeAlias=foo.bar.TypeAlias
```
Another example (in conjunction with --type-mappings):
```sh
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i /tmp/alias.yaml -o /tmp/alias/ --schema-mappings stream=org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody --type-mappings string+binary=stream
```
while /tmp/alias.yaml is as follows:
```yaml
openapi: 3.0.3
info:
title: Demo app
version: 1.0.0
servers:
- url: /api/v1
paths:
/demo:
get:
summary: Demo
operationId: demo
responses:
'200':
description: Demo response
content:
text/csv:
schema:
type: string
format: binary
```
## Inline Schema Naming
Inline schemas are created as separate schemas automatically and the auto-generated schema name may not look good to everyone. One can customize the name using the `title` field or the `inlineSchemaNameMapping` option, e.g. in CLI
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/inline_model_resolver.yaml -o /tmp/java3/ --skip-validate-spec --inline-schema-name-mappings inline_object_2=SomethingMapped,inline_object_4=nothing_new
```
Another useful option is `inlineSchemaNameDefaults`, which allows you to customize the suffix of the auto-generated inline schema name, e.g. in CLI
```
--inline-schema-name-defaults arrayItemSuffix=_array_item
```
Note: Only arrayItemSuffix, mapItemSuffix are supported at the moment.

View File

@@ -41,6 +41,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|packageName|C# package name (convention: Title.Case).| |Org.OpenAPITools| |packageName|C# package name (convention: Title.Case).| |Org.OpenAPITools|
|packageTitle|Specifies an AssemblyTitle for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |OpenAPI Library| |packageTitle|Specifies an AssemblyTitle for the .NET Framework global assembly attributes stored in the AssemblyInfo file.| |OpenAPI Library|
|packageVersion|C# package version.| |1.0.0| |packageVersion|C# package version.| |1.0.0|
|pocoModels|Build POCO Models| |false|
|returnICollection|Return ICollection&lt;T&gt; instead of the concrete type.| |false| |returnICollection|Return ICollection&lt;T&gt; instead of the concrete type.| |false|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src| |sourceFolder|source folder for generated code| |src|

View File

@@ -38,6 +38,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Imports | | Type/Alias | Imports |
| ---------- | ------- | | ---------- | ------- |
|OAIHttpFileElement|#include &quot;OAIHttpFileElement.h&quot;| |OAIHttpFileElement|#include &quot;OAIHttpFileElement.h&quot;|
|QJsonValue|#include &lt;QJsonValue&gt;|
## INSTANTIATION TYPES ## INSTANTIATION TYPES

View File

@@ -54,6 +54,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>TArray</li> <li>TArray</li>
<li>TArray&lt;uint8&gt;</li> <li>TArray&lt;uint8&gt;</li>
<li>TMap</li> <li>TMap</li>
<li>TSet</li>
<li>TSharedPtr&lt;FJsonObject&gt;</li> <li>TSharedPtr&lt;FJsonObject&gt;</li>
<li>TSharedPtr&lt;FJsonValue&gt;</li> <li>TSharedPtr&lt;FJsonValue&gt;</li>
<li>bool</li> <li>bool</li>

View File

@@ -29,6 +29,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|serveStatic|serve will serve files from the directory 'static'.| |true| |serveStatic|serve will serve files from the directory 'static'.| |true|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|useCustomMonad|use a custom monad instead of the default Handler| |false|
## IMPORT MAPPING ## IMPORT MAPPING
@@ -195,7 +196,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|BasicAuth|✓|OAS2,OAS3 |BasicAuth|✓|OAS2,OAS3
|ApiKey|✓|OAS2,OAS3 |ApiKey|✓|OAS2,OAS3
|OpenIDConnect|✗|OAS3 |OpenIDConnect|✗|OAS3
|BearerToken||OAS3 |BearerToken||OAS3
|OAuth2_Implicit|✓|OAS2,OAS3 |OAuth2_Implicit|✓|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3 |OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3 |OAuth2_ClientCredentials|✗|OAS2,OAS3

View File

@@ -80,7 +80,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator| |scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false| |serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false|
|singleContentTypes|Whether to select only one produces/consumes content-type by operation.| |false| |singleContentTypes|Whether to select only one produces/consumes content-type by operation.| |false|
|skipDefaultInterface|Whether to generate default implementations for java8 interfaces| |false| |skipDefaultInterface|Whether to skip generation of default implementations for java8 interfaces| |false|
|snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null| |snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
@@ -91,6 +91,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true| |useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true| |useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useOptional|Use Optional container for optional parameters| |false| |useOptional|Use Optional container for optional parameters| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).| |true|
|useSpringController|Annotate the generated API as a Spring Controller| |false| |useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true| |useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false| |useTags|use tags for creating interface and controller classnames| |false|

View File

@@ -85,6 +85,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception| |false| |useRuntimeException|Use RuntimeException instead of Exception| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false| |useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false| |useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson support this option.| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false| |withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS ## SUPPORTED VENDOR EXTENSIONS

View File

@@ -26,10 +26,12 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase| |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|generateRoomModels|Generate Android Room database models in addition to API models (JVM Volley library only)| |false| |generateRoomModels|Generate Android Room database models in addition to API models (JVM Volley library only)| |false|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|idea|Add IntellJ Idea plugin and mark Kotlin main and test folders as source folders.| |false|
|library|Library template (sub-template) to use|<dl><dt>**jvm-ktor**</dt><dd>Platform: Java Virtual Machine. HTTP client: Ktor 1.6.7. JSON processing: Gson, Jackson (default).</dd><dt>**jvm-okhttp4**</dt><dd>[DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0.</dd><dt>**jvm-okhttp3**</dt><dd>Platform: Java Virtual Machine. HTTP client: OkHttp 3.12.4 (Android 2.3+ and Java 7+). JSON processing: Moshi 1.8.0.</dd><dt>**jvm-retrofit2**</dt><dd>Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2.</dd><dt>**multiplatform**</dt><dd>Platform: Kotlin multiplatform. HTTP client: Ktor 1.6.7. JSON processing: Kotlinx Serialization: 1.2.1.</dd><dt>**jvm-volley**</dt><dd>Platform: JVM for Android. HTTP client: Volley 1.2.1. JSON processing: gson 2.8.9</dd></dl>|jvm-okhttp4| |library|Library template (sub-template) to use|<dl><dt>**jvm-ktor**</dt><dd>Platform: Java Virtual Machine. HTTP client: Ktor 1.6.7. JSON processing: Gson, Jackson (default).</dd><dt>**jvm-okhttp4**</dt><dd>[DEFAULT] Platform: Java Virtual Machine. HTTP client: OkHttp 4.2.0 (Android 5.0+ and Java 8+). JSON processing: Moshi 1.8.0.</dd><dt>**jvm-okhttp3**</dt><dd>Platform: Java Virtual Machine. HTTP client: OkHttp 3.12.4 (Android 2.3+ and Java 7+). JSON processing: Moshi 1.8.0.</dd><dt>**jvm-retrofit2**</dt><dd>Platform: Java Virtual Machine. HTTP client: Retrofit 2.6.2.</dd><dt>**multiplatform**</dt><dd>Platform: Kotlin multiplatform. HTTP client: Ktor 1.6.7. JSON processing: Kotlinx Serialization: 1.2.1.</dd><dt>**jvm-volley**</dt><dd>Platform: JVM for Android. HTTP client: Volley 1.2.1. JSON processing: gson 2.8.9</dd></dl>|jvm-okhttp4|
|modelMutable|Create mutable models| |false| |modelMutable|Create mutable models| |false|
|moshiCodeGen|Whether to enable codegen with the Moshi library. Refer to the [official Moshi doc](https://github.com/square/moshi#codegen) for more info.| |false| |moshiCodeGen|Whether to enable codegen with the Moshi library. Refer to the [official Moshi doc](https://github.com/square/moshi#codegen) for more info.| |false|
|omitGradlePluginVersions|Whether to declare Gradle plugin versions in build files.| |false| |omitGradlePluginVersions|Whether to declare Gradle plugin versions in build files.| |false|
|omitGradleWrapper|Whether to omit Gradle wrapper for creating a sub project.| |false|
|packageName|Generated artifact package name.| |org.openapitools.client| |packageName|Generated artifact package name.| |org.openapitools.client|
|parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null| |parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null|
|requestDateConverter|JVM-Option. Defines in how to handle date-time objects that are used for a request (as query or parameter)|<dl><dt>**toJson**</dt><dd>[DEFAULT] Date formatter option using a json converter.</dd><dt>**toString**</dt><dd>Use the 'toString'-method of the date-time object to retrieve the related string representation.</dd></dl>|toJson| |requestDateConverter|JVM-Option. Defines in how to handle date-time objects that are used for a request (as query or parameter)|<dl><dt>**toJson**</dt><dd>[DEFAULT] Date formatter option using a json converter.</dd><dt>**toString**</dt><dd>Use the 'toString'-method of the date-time object to retrieve the related string representation.</dd></dl>|toJson|

View File

@@ -41,7 +41,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<ul class="column-ul"> <ul class="column-ul">
<li>ARRAY</li> <li>ARRAY</li>
<li>DateTime</li> <li>DATE</li>
<li>DATE_TIME</li>
<li>HASH</li> <li>HASH</li>
<li>boolean</li> <li>boolean</li>
<li>double</li> <li>double</li>

View File

@@ -18,6 +18,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default | | Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- | | ------ | ----------- | ------ | ------- |
|errorObjectType|Error object type.| |null|
|exceptionPackage|Specify the exception handling package|<dl><dt>**default**</dt><dd>Use stop() for raising exceptions.</dd><dt>**rlang**</dt><dd>Use rlang package for exceptions.</dd></dl>|default| |exceptionPackage|Specify the exception handling package|<dl><dt>**default**</dt><dd>Use stop() for raising exceptions.</dd><dt>**rlang**</dt><dd>Use rlang package for exceptions.</dd></dl>|default|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true| |hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|packageName|R package name (convention: lowercase).| |openapi| |packageName|R package name (convention: lowercase).| |openapi|

View File

@@ -18,11 +18,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Option | Description | Values | Default | | Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- | | ------ | ----------- | ------ | ------- |
|bestFitInt|Use best fitting integer type where minimum or maximum is set| |false|
|enumNameSuffix|Suffix that will be appended to all enum names.| || |enumNameSuffix|Suffix that will be appended to all enum names.| ||
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true| |hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|library|library template (sub-template) to use.|<dl><dt>**hyper**</dt><dd>HTTP client: Hyper.</dd><dt>**reqwest**</dt><dd>HTTP client: Reqwest.</dd></dl>|reqwest| |library|library template (sub-template) to use.|<dl><dt>**hyper**</dt><dd>HTTP client: Hyper.</dd><dt>**reqwest**</dt><dd>HTTP client: Reqwest.</dd></dl>|reqwest|
|packageName|Rust package name (convention: lowercase).| |openapi| |packageName|Rust package name (convention: lowercase).| |openapi|
|packageVersion|Rust package version.| |1.0.0| |packageVersion|Rust package version.| |1.0.0|
|preferUnsignedInt|Prefer unsigned integers where minimum value is &gt;= 0| |false|
|supportAsync|If set, generate async function call instead. This option is for 'reqwest' library only| |true| |supportAsync|If set, generate async function call instead. This option is for 'reqwest' library only| |true|
|supportMultipleResponses|If set, return type wraps an enum of all possible 2xx schemas. This option is for 'reqwest' library only| |false| |supportMultipleResponses|If set, return type wraps an enum of all possible 2xx schemas. This option is for 'reqwest' library only| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false| |useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|

View File

@@ -73,7 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator| |scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false| |serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false|
|singleContentTypes|Whether to select only one produces/consumes content-type by operation.| |false| |singleContentTypes|Whether to select only one produces/consumes content-type by operation.| |false|
|skipDefaultInterface|Whether to generate default implementations for java8 interfaces| |false| |skipDefaultInterface|Whether to skip generation of default implementations for java8 interfaces| |false|
|snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null| |snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
@@ -84,6 +84,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true| |useBeanValidation|Use BeanValidation API annotations| |true|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true| |useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useOptional|Use Optional container for optional parameters| |false| |useOptional|Use Optional container for optional parameters| |false|
|useSpringBoot3|Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports).| |true|
|useSpringController|Annotate the generated API as a Spring Controller| |false| |useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true| |useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
|useTags|use tags for creating interface and controller classnames| |false| |useTags|use tags for creating interface and controller classnames| |false|

View File

@@ -53,6 +53,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null| |swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null|
|useBacktickEscapes|Escape reserved words using backticks (default: false)| |false| |useBacktickEscapes|Escape reserved words using backticks (default: false)| |false|
|useClasses|Use final classes for models instead of structs (default: false)| |false| |useClasses|Use final classes for models instead of structs (default: false)| |false|
|useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true|
|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null| |useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null|
## IMPORT MAPPING ## IMPORT MAPPING

View File

@@ -103,18 +103,18 @@ docker run --rm \
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.3.0/openapi-generator-cli-5.3.0.jar` JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar`
For **Mac/Linux** users: For **Mac/Linux** users:
```bash ```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.3.0/openapi-generator-cli-5.3.0.jar -O openapi-generator-cli.jar wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar -O openapi-generator-cli.jar
``` ```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g. For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g.
```powershell ```powershell
Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.3.0/openapi-generator-cli-5.3.0.jar Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar
``` ```
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->

View File

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

View File

@@ -71,9 +71,15 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
@Option(name = {"--import-mappings"}, title = "import mappings", description = "displays the default import mappings (types and aliases, and what imports they will pull into the template)") @Option(name = {"--import-mappings"}, title = "import mappings", description = "displays the default import mappings (types and aliases, and what imports they will pull into the template)")
private Boolean importMappings; private Boolean importMappings;
@Option(name = {"--schema-mappings"}, title = "schema mappings", description = "display the schema mappings (none)")
private Boolean schemaMappings;
@Option(name = {"--inline-schema-name-mappings"}, title = "inline schema name mappings", description = "displays the inline schema name mappings (none)") @Option(name = {"--inline-schema-name-mappings"}, title = "inline schema name mappings", description = "displays the inline schema name mappings (none)")
private Boolean inlineSchemaNameMappings; private Boolean inlineSchemaNameMappings;
@Option(name = {"--inline-schema-name-defaults"}, title = "inline schema name defaults", description = "default values used when naming inline schema name")
private Boolean inlineSchemaNameDefaults;
@Option(name = {"--metadata"}, title = "metadata", description = "displays the generator metadata like the help txt for the generator and generator type etc") @Option(name = {"--metadata"}, title = "metadata", description = "displays the generator metadata like the help txt for the generator and generator type etc")
private Boolean metadata; private Boolean metadata;
@@ -452,6 +458,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
sb.append(newline); sb.append(newline);
} }
if (Boolean.TRUE.equals(schemaMappings)) {
sb.append(newline).append("SCHEMA MAPPING").append(newline).append(newline);
Map<String, String> map = config.schemaMapping()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b));
}, TreeMap::new));
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Scheme", "Mapped to");
sb.append(newline);
}
if (Boolean.TRUE.equals(inlineSchemaNameMappings)) { if (Boolean.TRUE.equals(inlineSchemaNameMappings)) {
sb.append(newline).append("INLINE SCHEMA NAME MAPPING").append(newline).append(newline); sb.append(newline).append("INLINE SCHEMA NAME MAPPING").append(newline).append(newline);
Map<String, String> map = config.inlineSchemaNameMapping() Map<String, String> map = config.inlineSchemaNameMapping()
@@ -464,6 +482,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand {
sb.append(newline); sb.append(newline);
} }
if (Boolean.TRUE.equals(inlineSchemaNameDefaults)) {
sb.append(newline).append("INLINE SCHEMA NAME DEFAULTS").append(newline).append(newline);
Map<String, String> map = config.inlineSchemaNameDefault()
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b));
}, TreeMap::new));
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Inline scheme naming convention", "Defaulted to");
sb.append(newline);
}
if (Boolean.TRUE.equals(instantiationTypes)) { if (Boolean.TRUE.equals(instantiationTypes)) {
sb.append(newline).append("INSTANTIATION TYPES").append(newline).append(newline); sb.append(newline).append("INSTANTIATION TYPES").append(newline).append(newline);
Map<String, String> map = config.instantiationTypes() Map<String, String> map = config.instantiationTypes()

View File

@@ -159,6 +159,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " You can also have multiple occurrences of this option.") + " You can also have multiple occurrences of this option.")
private List<String> importMappings = new ArrayList<>(); private List<String> importMappings = new ArrayList<>();
@Option(
name = {"--schema-mappings"},
title = "schema mappings",
description = "specifies mappings between the schema and the new name in the format of schema_a=Cat,schema_b=Bird."
+ " You can also have multiple occurrences of this option.")
private List<String> schemaMappings = new ArrayList<>();
@Option( @Option(
name = {"--inline-schema-name-mappings"}, name = {"--inline-schema-name-mappings"},
title = "inline schema name mappings", title = "inline schema name mappings",
@@ -166,6 +173,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " You can also have multiple occurrences of this option.") + " You can also have multiple occurrences of this option.")
private List<String> inlineSchemaNameMappings = new ArrayList<>(); private List<String> inlineSchemaNameMappings = new ArrayList<>();
@Option(
name = {"--inline-schema-name-defaults"},
title = "inline schema name defaults",
description = "specifies the default values used when naming inline schema as such array items in the format of arrayItemSuffix=_inner,mapItemSuffix=_value. "
+ " ONLY arrayItemSuffix, mapItemSuffix at the moment.")
private List<String> inlineSchemaNameDefaults = new ArrayList<>();
@Option( @Option(
name = {"--server-variables"}, name = {"--server-variables"},
title = "server variables", title = "server variables",
@@ -430,7 +444,9 @@ public class Generate extends OpenApiGeneratorCommand {
} }
applyInstantiationTypesKvpList(instantiationTypes, configurator); applyInstantiationTypesKvpList(instantiationTypes, configurator);
applyImportMappingsKvpList(importMappings, configurator); applyImportMappingsKvpList(importMappings, configurator);
applySchemaMappingsKvpList(schemaMappings, configurator);
applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator); applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator);
applyInlineSchemaNameDefaultsKvpList(inlineSchemaNameDefaults, configurator);
applyTypeMappingsKvpList(typeMappings, configurator); applyTypeMappingsKvpList(typeMappings, configurator);
applyAdditionalPropertiesKvpList(additionalProperties, configurator); applyAdditionalPropertiesKvpList(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator); applyLanguageSpecificPrimitivesCsvList(languageSpecificPrimitives, configurator);

View File

@@ -50,7 +50,9 @@ public final class GeneratorSettings implements Serializable {
private final Map<String, String> typeMappings; private final Map<String, String> typeMappings;
private final Map<String, Object> additionalProperties; private final Map<String, Object> additionalProperties;
private final Map<String, String> importMappings; private final Map<String, String> importMappings;
private final Map<String, String> schemaMappings;
private final Map<String, String> inlineSchemaNameMappings; private final Map<String, String> inlineSchemaNameMappings;
private final Map<String, String> inlineSchemaNameDefaults;
private final Set<String> languageSpecificPrimitives; private final Set<String> languageSpecificPrimitives;
private final Map<String, String> reservedWordsMappings; private final Map<String, String> reservedWordsMappings;
private final Map<String, String> serverVariables; private final Map<String, String> serverVariables;
@@ -235,6 +237,15 @@ public final class GeneratorSettings implements Serializable {
return importMappings; return importMappings;
} }
/**
* Gets schema mappings between a schema and the new name.
*
* @return the schema mappings
*/
public Map<String, String> getSchemaMappings() {
return schemaMappings;
}
/** /**
* Gets inline schema name mappings between an inline schema name and the new name. * Gets inline schema name mappings between an inline schema name and the new name.
* *
@@ -244,6 +255,15 @@ public final class GeneratorSettings implements Serializable {
return inlineSchemaNameMappings; return inlineSchemaNameMappings;
} }
/**
* Gets inline schema name defaults between an inline schema naming convention and the default values.
*
* @return the inline schema name defaults
*/
public Map<String, String> getInlineSchemaNameDefaults() {
return inlineSchemaNameDefaults;
}
/** /**
* Gets language specific primitives. These are in addition to the "base" primitives defined in a generator. * Gets language specific primitives. These are in addition to the "base" primitives defined in a generator.
* <p> * <p>
@@ -359,7 +379,9 @@ public final class GeneratorSettings implements Serializable {
instantiationTypes = Collections.unmodifiableMap(builder.instantiationTypes); instantiationTypes = Collections.unmodifiableMap(builder.instantiationTypes);
typeMappings = Collections.unmodifiableMap(builder.typeMappings); typeMappings = Collections.unmodifiableMap(builder.typeMappings);
importMappings = Collections.unmodifiableMap(builder.importMappings); importMappings = Collections.unmodifiableMap(builder.importMappings);
schemaMappings = Collections.unmodifiableMap(builder.schemaMappings);
inlineSchemaNameMappings = Collections.unmodifiableMap(builder.inlineSchemaNameMappings); inlineSchemaNameMappings = Collections.unmodifiableMap(builder.inlineSchemaNameMappings);
inlineSchemaNameDefaults = Collections.unmodifiableMap(builder.inlineSchemaNameDefaults);
languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives); languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives);
reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings); reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings);
serverVariables = Collections.unmodifiableMap(builder.serverVariables); serverVariables = Collections.unmodifiableMap(builder.serverVariables);
@@ -430,7 +452,9 @@ public final class GeneratorSettings implements Serializable {
typeMappings = Collections.unmodifiableMap(new HashMap<>(0)); typeMappings = Collections.unmodifiableMap(new HashMap<>(0));
additionalProperties = Collections.unmodifiableMap(new HashMap<>(0)); additionalProperties = Collections.unmodifiableMap(new HashMap<>(0));
importMappings = Collections.unmodifiableMap(new HashMap<>(0)); importMappings = Collections.unmodifiableMap(new HashMap<>(0));
schemaMappings = Collections.unmodifiableMap(new HashMap<>(0));
inlineSchemaNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); inlineSchemaNameMappings = Collections.unmodifiableMap(new HashMap<>(0));
inlineSchemaNameDefaults = Collections.unmodifiableMap(new HashMap<>(0));
languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0)); languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0));
reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0)); reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0));
serverVariables = Collections.unmodifiableMap(new HashMap<>(0)); serverVariables = Collections.unmodifiableMap(new HashMap<>(0));
@@ -482,9 +506,15 @@ public final class GeneratorSettings implements Serializable {
if (copy.getImportMappings() != null) { if (copy.getImportMappings() != null) {
builder.importMappings.putAll(copy.getImportMappings()); builder.importMappings.putAll(copy.getImportMappings());
} }
if (copy.getSchemaMappings() != null) {
builder.schemaMappings.putAll(copy.getSchemaMappings());
}
if (copy.getInlineSchemaNameMappings() != null) { if (copy.getInlineSchemaNameMappings() != null) {
builder.inlineSchemaNameMappings.putAll(copy.getInlineSchemaNameMappings()); builder.inlineSchemaNameMappings.putAll(copy.getInlineSchemaNameMappings());
} }
if (copy.getInlineSchemaNameDefaults() != null) {
builder.inlineSchemaNameDefaults.putAll(copy.getInlineSchemaNameDefaults());
}
if (copy.getLanguageSpecificPrimitives() != null) { if (copy.getLanguageSpecificPrimitives() != null) {
builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives()); builder.languageSpecificPrimitives.addAll(copy.getLanguageSpecificPrimitives());
} }
@@ -524,7 +554,9 @@ public final class GeneratorSettings implements Serializable {
private Map<String, String> typeMappings; private Map<String, String> typeMappings;
private Map<String, Object> additionalProperties; private Map<String, Object> additionalProperties;
private Map<String, String> importMappings; private Map<String, String> importMappings;
private Map<String, String> schemaMappings;
private Map<String, String> inlineSchemaNameMappings; private Map<String, String> inlineSchemaNameMappings;
private Map<String, String> inlineSchemaNameDefaults;
private Set<String> languageSpecificPrimitives; private Set<String> languageSpecificPrimitives;
private Map<String, String> reservedWordsMappings; private Map<String, String> reservedWordsMappings;
private Map<String, String> serverVariables; private Map<String, String> serverVariables;
@@ -542,7 +574,9 @@ public final class GeneratorSettings implements Serializable {
typeMappings = new HashMap<>(); typeMappings = new HashMap<>();
additionalProperties = new HashMap<>(); additionalProperties = new HashMap<>();
importMappings = new HashMap<>(); importMappings = new HashMap<>();
schemaMappings = new HashMap<>();
inlineSchemaNameMappings = new HashMap<>(); inlineSchemaNameMappings = new HashMap<>();
inlineSchemaNameDefaults = new HashMap<>();
languageSpecificPrimitives = new HashSet<>(); languageSpecificPrimitives = new HashSet<>();
reservedWordsMappings = new HashMap<>(); reservedWordsMappings = new HashMap<>();
serverVariables = new HashMap<>(); serverVariables = new HashMap<>();
@@ -759,6 +793,32 @@ public final class GeneratorSettings implements Serializable {
return this; return this;
} }
/**
* Sets the {@code schemaMappings} and returns a reference to this Builder so that the methods can be chained together.
*
* @param schemaMappings the {@code schemaMappings} to set
* @return a reference to this Builder
*/
public Builder withSchemaMappings(Map<String, String> schemaMappings) {
this.schemaMappings = schemaMappings;
return this;
}
/**
* Sets a single {@code schemaMappings} and returns a reference to this Builder so that the methods can be chained together.
*
* @param key A key for some schema mapping
* @param value The value of some schema mapping
* @return a reference to this Builder
*/
public Builder withSchemaMapping(String key, String value) {
if (this.schemaMappings == null) {
this.schemaMappings = new HashMap<>();
}
this.schemaMappings.put(key, value);
return this;
}
/** /**
* Sets the {@code importMappings} and returns a reference to this Builder so that the methods can be chained together. * Sets the {@code importMappings} and returns a reference to this Builder so that the methods can be chained together.
* *
@@ -785,6 +845,32 @@ public final class GeneratorSettings implements Serializable {
return this; return this;
} }
/**
* Sets the {@code inlineSchemaNameDefaults} and returns a reference to this Builder so that the methods can be chained together.
*
* @param inlineSchemaNameDefaults the {@code inlineSchemaNameDefaults} to set
* @return a reference to this Builder
*/
public Builder withInlineSchemaNameDefaults(Map<String, String> inlineSchemaNameDefaults) {
this.inlineSchemaNameDefaults = inlineSchemaNameDefaults;
return this;
}
/**
* Sets a single {@code inlineSchemaNameDefaults} and returns a reference to this Builder so that the methods can be chained together.
*
* @param key Default naming convention
* @param value The value
* @return a reference to this Builder
*/
public Builder withInlineSchemaNameDefault(String key, String value) {
if (this.inlineSchemaNameDefaults == null) {
this.inlineSchemaNameDefaults = new HashMap<>();
}
this.inlineSchemaNameDefaults.put(key, value);
return this;
}
/** /**
* Sets the {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together. * Sets the {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together.
* *
@@ -799,8 +885,8 @@ public final class GeneratorSettings implements Serializable {
/** /**
* Sets a single {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together. * Sets a single {@code inlineSchemaNameMappings} and returns a reference to this Builder so that the methods can be chained together.
* *
* @param key A key for some import mapping * @param key A key for the inline schema mapping
* @param value The value of some import mapping * @param value The value of inline schema mapping
* @return a reference to this Builder * @return a reference to this Builder
*/ */
public Builder withInlineSchemaNameMapping(String key, String value) { public Builder withInlineSchemaNameMapping(String key, String value) {
@@ -996,7 +1082,9 @@ public final class GeneratorSettings implements Serializable {
Objects.equals(getTypeMappings(), that.getTypeMappings()) && Objects.equals(getTypeMappings(), that.getTypeMappings()) &&
Objects.equals(getAdditionalProperties(), that.getAdditionalProperties()) && Objects.equals(getAdditionalProperties(), that.getAdditionalProperties()) &&
Objects.equals(getImportMappings(), that.getImportMappings()) && Objects.equals(getImportMappings(), that.getImportMappings()) &&
Objects.equals(getSchemaMappings(), that.getSchemaMappings()) &&
Objects.equals(getInlineSchemaNameMappings(), that.getInlineSchemaNameMappings()) && Objects.equals(getInlineSchemaNameMappings(), that.getInlineSchemaNameMappings()) &&
Objects.equals(getInlineSchemaNameDefaults(), that.getInlineSchemaNameDefaults()) &&
Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) && Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) &&
Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) && Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) &&
Objects.equals(getGitHost(), that.getGitHost()) && Objects.equals(getGitHost(), that.getGitHost()) &&
@@ -1025,7 +1113,9 @@ public final class GeneratorSettings implements Serializable {
getTypeMappings(), getTypeMappings(),
getAdditionalProperties(), getAdditionalProperties(),
getImportMappings(), getImportMappings(),
getSchemaMappings(),
getInlineSchemaNameMappings(), getInlineSchemaNameMappings(),
getInlineSchemaNameDefaults(),
getLanguageSpecificPrimitives(), getLanguageSpecificPrimitives(),
getReservedWordsMappings(), getReservedWordsMappings(),
getGitHost(), getGitHost(),

View File

@@ -71,6 +71,7 @@ public class WorkflowSettings {
this.outputDir = builder.outputDir; this.outputDir = builder.outputDir;
this.verbose = builder.verbose; this.verbose = builder.verbose;
this.skipOverwrite = builder.skipOverwrite; this.skipOverwrite = builder.skipOverwrite;
this.skipOperationExample = builder.skipOperationExample;
this.removeOperationIdPrefix = builder.removeOperationIdPrefix; this.removeOperationIdPrefix = builder.removeOperationIdPrefix;
this.logToStderr = builder.logToStderr; this.logToStderr = builder.logToStderr;
this.validateSpec = builder.validateSpec; this.validateSpec = builder.validateSpec;

View File

@@ -97,7 +97,7 @@ task validateGoodSpec(type: org.openapitools.generator.gradle.plugin.tasks.Valid
[source,group] [source,group]
---- ----
plugins { plugins {
id "org.openapi.generator" version "6.0.0" id "org.openapi.generator" version "6.0.1"
} }
---- ----
@@ -113,7 +113,7 @@ buildscript {
// url "https://plugins.gradle.org/m2/" // url "https://plugins.gradle.org/m2/"
} }
dependencies { dependencies {
classpath "org.openapitools:openapi-generator-gradle-plugin:6.0.0" classpath "org.openapitools:openapi-generator-gradle-plugin:6.0.1"
} }
} }
@@ -695,7 +695,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.android.tools.build:gradle:3.2.1'
classpath('org.openapitools:openapi-generator-gradle-plugin:6.0.0') { classpath('org.openapitools:openapi-generator-gradle-plugin:6.0.1') {
exclude group: 'com.google.guava' exclude group: 'com.google.guava'
} }
} }

View File

@@ -18,5 +18,5 @@ gradle generateGoWithInvalidSpec # expected outcome: BUILD FAILED
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example: The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
```bash ```bash
gradle -PopenApiGeneratorVersion=5.3.0 openApiValidate gradle -PopenApiGeneratorVersion=6.0.1 openApiValidate
``` ```

View File

@@ -89,7 +89,8 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
register("openApiGenerate", GenerateTask::class.java).configure { register("openApiGenerate", GenerateTask::class.java).configure {
group = pluginGroup group = pluginGroup
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents." description =
"Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
verbose.set(generate.verbose) verbose.set(generate.verbose)
validateSpec.set(generate.validateSpec) validateSpec.set(generate.validateSpec)
@@ -113,7 +114,9 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
serverVariables.set(generate.serverVariables) serverVariables.set(generate.serverVariables)
languageSpecificPrimitives.set(generate.languageSpecificPrimitives) languageSpecificPrimitives.set(generate.languageSpecificPrimitives)
importMappings.set(generate.importMappings) importMappings.set(generate.importMappings)
schemaMappings.set(generate.schemaMappings)
inlineSchemaNameMappings.set(generate.inlineSchemaNameMappings) inlineSchemaNameMappings.set(generate.inlineSchemaNameMappings)
inlineSchemaNameDefaults.set(generate.inlineSchemaNameDefaults)
invokerPackage.set(generate.invokerPackage) invokerPackage.set(generate.invokerPackage)
groupId.set(generate.groupId) groupId.set(generate.groupId)
id.set(generate.id) id.set(generate.id)

View File

@@ -22,19 +22,18 @@ import org.gradle.kotlin.dsl.mapProperty
import org.gradle.kotlin.dsl.property import org.gradle.kotlin.dsl.property
/** /**
* Gradle project level extension object definition for the generate task * Gradle project level extension object definition for the `generate` task
* *
* @author Jim Schubert * @author Jim Schubert
*/ */
open class OpenApiGeneratorGenerateExtension(project: Project) { open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* The verbosity of generation * The verbosity of generation
*/ */
val verbose = project.objects.property<Boolean>() val verbose = project.objects.property<Boolean>()
/** /**
* Whether or not an input specification should be validated upon generation. * Whether an input specification should be validated upon generation.
*/ */
val validateSpec = project.objects.property<Boolean>() val validateSpec = project.objects.property<Boolean>()
@@ -141,28 +140,38 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
*/ */
val importMappings = project.objects.mapProperty<String, String>() val importMappings = project.objects.mapProperty<String, String>()
/**
* Specifies mappings between a given schema and the new one
*/
val schemaMappings = project.objects.mapProperty<String, String>()
/** /**
* Specifies mappings between an inline schema name and the new name * Specifies mappings between an inline schema name and the new name
*/ */
val inlineSchemaNameMappings = project.objects.mapProperty<String, String>() val inlineSchemaNameMappings = project.objects.mapProperty<String, String>()
/**
* Specifies default values for inline schema naming convention
*/
val inlineSchemaNameDefaults = project.objects.mapProperty<String, String>()
/** /**
* Root package for generated code. * Root package for generated code.
*/ */
val invokerPackage = project.objects.property<String>() val invokerPackage = project.objects.property<String>()
/** /**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators. * GroupId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/ */
val groupId = project.objects.property<String>() val groupId = project.objects.property<String>()
/** /**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators. * ArtifactId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/ */
val id = project.objects.property<String>() val id = project.objects.property<String>()
/** /**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators. * Artifact version in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/ */
val version = project.objects.property<String>() val version = project.objects.property<String>()
@@ -237,7 +246,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all). * Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
* *
* Supporting files are those related to projects/frameworks which may be modified * Supporting files are those related to `projects/frameworks` which may be modified
* by consumers. * by consumers.
* *
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results * NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
@@ -247,7 +256,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val supportingFilesConstrainedTo = project.objects.listProperty<String>() val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/** /**
* Defines whether or not model-related _test_ files should be generated. * Defines whether model-related _test_ files should be generated.
* *
* This option enables/disables generation of ALL model-related _test_ files. * This option enables/disables generation of ALL model-related _test_ files.
* *
@@ -257,7 +266,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val generateModelTests = project.objects.property<Boolean>() val generateModelTests = project.objects.property<Boolean>()
/** /**
* Defines whether or not model-related _documentation_ files should be generated. * Defines whether model-related _documentation_ files should be generated.
* *
* This option enables/disables generation of ALL model-related _documentation_ files. * This option enables/disables generation of ALL model-related _documentation_ files.
* *
@@ -267,7 +276,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val generateModelDocumentation = project.objects.property<Boolean>() val generateModelDocumentation = project.objects.property<Boolean>()
/** /**
* Defines whether or not api-related _test_ files should be generated. * Defines whether api-related _test_ files should be generated.
* *
* This option enables/disables generation of ALL api-related _test_ files. * This option enables/disables generation of ALL api-related _test_ files.
* *
@@ -277,7 +286,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
val generateApiTests = project.objects.property<Boolean>() val generateApiTests = project.objects.property<Boolean>()
/** /**
* Defines whether or not api-related _documentation_ files should be generated. * Defines whether api-related _documentation_ files should be generated.
* *
* This option enables/disables generation of ALL api-related _documentation_ files. * This option enables/disables generation of ALL api-related _documentation_ files.
* *

View File

@@ -17,7 +17,6 @@
package org.openapitools.generator.gradle.plugin.extensions package org.openapitools.generator.gradle.plugin.extensions
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.tasks.Internal
import org.gradle.kotlin.dsl.listProperty import org.gradle.kotlin.dsl.listProperty
import org.openapitools.codegen.meta.Stability import org.openapitools.codegen.meta.Stability
@@ -37,7 +36,6 @@ open class OpenApiGeneratorGeneratorsExtension(project: Project) {
} }
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){ fun applyDefaults() =
include.set(Stability.values().map { s -> s.value() }.filterNot { it == Stability.DEPRECATED.value() }) include.set(Stability.values().map { it.value() }.filterNot { it == Stability.DEPRECATED.value() })
}
} }

View File

@@ -31,7 +31,7 @@ open class OpenApiGeneratorValidateExtension(project: Project) {
val inputSpec = project.objects.property<String>() val inputSpec = project.objects.property<String>()
/** /**
* Whether or not to offer recommendations related to the validated specification document. * Whether to offer recommendations related to the validated specification document.
*/ */
val recommend = project.objects.property<Boolean?>() val recommend = project.objects.property<Boolean?>()
@@ -40,7 +40,5 @@ open class OpenApiGeneratorValidateExtension(project: Project) {
} }
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
fun applyDefaults(){ fun applyDefaults() = recommend.set(true)
recommend.set(true)
}
} }

View File

@@ -51,7 +51,6 @@ import org.openapitools.codegen.config.GlobalSettings
@Suppress("UnstableApiUsage") @Suppress("UnstableApiUsage")
@CacheableTask @CacheableTask
open class GenerateTask : DefaultTask() { open class GenerateTask : DefaultTask() {
/** /**
* The verbosity of generation * The verbosity of generation
*/ */
@@ -60,7 +59,7 @@ open class GenerateTask : DefaultTask() {
val verbose = project.objects.property<Boolean>() val verbose = project.objects.property<Boolean>()
/** /**
* Whether or not an input specification should be validated upon generation. * Whether an input specification should be validated upon generation.
*/ */
@Optional @Optional
@Input @Input
@@ -219,6 +218,13 @@ open class GenerateTask : DefaultTask() {
@Input @Input
val importMappings = project.objects.mapProperty<String, String>() val importMappings = project.objects.mapProperty<String, String>()
/**
* Specifies mappings between a given schema and the new one.
*/
@Optional
@Input
val schemaMappings = project.objects.mapProperty<String, String>()
/** /**
* Specifies mappings between the inline scheme name and the new name * Specifies mappings between the inline scheme name and the new name
*/ */
@@ -226,6 +232,13 @@ open class GenerateTask : DefaultTask() {
@Input @Input
val inlineSchemaNameMappings = project.objects.mapProperty<String, String>() val inlineSchemaNameMappings = project.objects.mapProperty<String, String>()
/**
* Specifies default values for inline schema naming convention
*/
@Optional
@Input
val inlineSchemaNameDefaults = project.objects.mapProperty<String, String>()
/** /**
* Root package for generated code. * Root package for generated code.
*/ */
@@ -234,21 +247,21 @@ open class GenerateTask : DefaultTask() {
val invokerPackage = project.objects.property<String>() val invokerPackage = project.objects.property<String>()
/** /**
* GroupId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators. * GroupId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/ */
@Optional @Optional
@Input @Input
val groupId = project.objects.property<String>() val groupId = project.objects.property<String>()
/** /**
* ArtifactId in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators. * ArtifactId in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/ */
@Optional @Optional
@Input @Input
val id = project.objects.property<String>() val id = project.objects.property<String>()
/** /**
* Artifact version in generated pom.xml/build.gradle or other build script. Language-specific conversions occur in non-jvm generators. * Artifact version in generated pom.xml/build.gradle.kts or other build script. Language-specific conversions occur in non-jvm generators.
*/ */
@Optional @Optional
@Input @Input
@@ -351,7 +364,7 @@ open class GenerateTask : DefaultTask() {
/** /**
* Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all). * Defines which supporting files should be generated. This allows you to create a subset of generated files (or none at all).
* *
* Supporting files are those related to projects/frameworks which may be modified * Supporting files are those related to `projects/frameworks` which may be modified
* by consumers. * by consumers.
* *
* NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results * NOTE: Configuring any one of [apiFilesConstrainedTo], [modelFilesConstrainedTo], or [supportingFilesConstrainedTo] results
@@ -363,7 +376,7 @@ open class GenerateTask : DefaultTask() {
val supportingFilesConstrainedTo = project.objects.listProperty<String>() val supportingFilesConstrainedTo = project.objects.listProperty<String>()
/** /**
* Defines whether or not model-related _test_ files should be generated. * Defines whether model-related _test_ files should be generated.
* *
* This option enables/disables generation of ALL model-related _test_ files. * This option enables/disables generation of ALL model-related _test_ files.
* *
@@ -375,7 +388,7 @@ open class GenerateTask : DefaultTask() {
val generateModelTests = project.objects.property<Boolean>() val generateModelTests = project.objects.property<Boolean>()
/** /**
* Defines whether or not model-related _documentation_ files should be generated. * Defines whether model-related _documentation_ files should be generated.
* *
* This option enables/disables generation of ALL model-related _documentation_ files. * This option enables/disables generation of ALL model-related _documentation_ files.
* *
@@ -387,7 +400,7 @@ open class GenerateTask : DefaultTask() {
val generateModelDocumentation = project.objects.property<Boolean>() val generateModelDocumentation = project.objects.property<Boolean>()
/** /**
* Defines whether or not api-related _test_ files should be generated. * Defines whether api-related _test_ files should be generated.
* *
* This option enables/disables generation of ALL api-related _test_ files. * This option enables/disables generation of ALL api-related _test_ files.
* *
@@ -399,7 +412,7 @@ open class GenerateTask : DefaultTask() {
val generateApiTests = project.objects.property<Boolean>() val generateApiTests = project.objects.property<Boolean>()
/** /**
* Defines whether or not api-related _documentation_ files should be generated. * Defines whether api-related _documentation_ files should be generated.
* *
* This option enables/disables generation of ALL api-related _documentation_ files. * This option enables/disables generation of ALL api-related _documentation_ files.
* *
@@ -497,7 +510,10 @@ open class GenerateTask : DefaultTask() {
} }
if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) { if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(",")) GlobalSettings.setProperty(
CodegenConstants.SUPPORTING_FILES,
supportingFilesConstrainedTo.get().joinToString(",")
)
} else { } else {
GlobalSettings.clearProperty(CodegenConstants.SUPPORTING_FILES) GlobalSettings.clearProperty(CodegenConstants.SUPPORTING_FILES)
} }
@@ -685,12 +701,24 @@ open class GenerateTask : DefaultTask() {
} }
} }
if (schemaMappings.isPresent) {
schemaMappings.get().forEach { entry ->
configurator.addSchemaMapping(entry.key, entry.value)
}
}
if (inlineSchemaNameMappings.isPresent) { if (inlineSchemaNameMappings.isPresent) {
inlineSchemaNameMappings.get().forEach { entry -> inlineSchemaNameMappings.get().forEach { entry ->
configurator.addInlineSchemaNameMapping(entry.key, entry.value) configurator.addInlineSchemaNameMapping(entry.key, entry.value)
} }
} }
if (inlineSchemaNameDefaults.isPresent) {
inlineSchemaNameDefaults.get().forEach { entry ->
configurator.addInlineSchemaNameDefault(entry.key, entry.value)
}
}
if (typeMappings.isPresent) { if (typeMappings.isPresent) {
typeMappings.get().forEach { entry -> typeMappings.get().forEach { entry ->
configurator.addTypeMapping(entry.key, entry.value) configurator.addTypeMapping(entry.key, entry.value)
@@ -722,11 +750,11 @@ open class GenerateTask : DefaultTask() {
} }
val clientOptInput = configurator.toClientOptInput() val clientOptInput = configurator.toClientOptInput()
val codgenConfig = clientOptInput.config val codegenConfig = clientOptInput.config
if (configOptions.isPresent) { if (configOptions.isPresent) {
val userSpecifiedConfigOptions = configOptions.get() val userSpecifiedConfigOptions = configOptions.get()
codgenConfig.cliOptions().forEach { codegenConfig.cliOptions().forEach {
if (userSpecifiedConfigOptions.containsKey(it.opt)) { if (userSpecifiedConfigOptions.containsKey(it.opt)) {
clientOptInput.config.additionalProperties()[it.opt] = userSpecifiedConfigOptions[it.opt] clientOptInput.config.additionalProperties()[it.opt] = userSpecifiedConfigOptions[it.opt]
} }

View File

@@ -43,7 +43,6 @@ open class GeneratorsTask : DefaultTask() {
@get:Internal @get:Internal
val include = project.objects.listProperty<String>() val include = project.objects.listProperty<String>()
@Suppress("unused")
@TaskAction @TaskAction
fun doWork() { fun doWork() {
val generators = CodegenConfigLoader.getAll() val generators = CodegenConfigLoader.getAll()

View File

@@ -44,7 +44,6 @@ import java.nio.charset.Charset
*/ */
@CacheableTask @CacheableTask
open class MetaTask : DefaultTask() { open class MetaTask : DefaultTask() {
@get:Input @get:Input
val generatorName = project.objects.property<String>() val generatorName = project.objects.property<String>()
@@ -54,10 +53,8 @@ open class MetaTask : DefaultTask() {
@get:OutputDirectory @get:OutputDirectory
val outputFolder = project.objects.property<String>() val outputFolder = project.objects.property<String>()
@Suppress("unused")
@TaskAction @TaskAction
fun doWork() { fun doWork() {
val packageToPath = packageName.get().replace(".", File.separator) val packageToPath = packageName.get().replace(".", File.separator)
val dir = File(outputFolder.get()) val dir = File(outputFolder.get())
val klass = "${generatorName.get().titleCasedTextOnly()}Generator" val klass = "${generatorName.get().titleCasedTextOnly()}Generator"
@@ -79,15 +76,22 @@ open class MetaTask : DefaultTask() {
SupportingFile("api.template", dir("src", "main", "resources", templateResourceDir), "api.mustache"), SupportingFile("api.template", dir("src", "main", "resources", templateResourceDir), "api.mustache"),
SupportingFile("model.template", dir("src", "main", "resources", templateResourceDir), "model.mustache"), SupportingFile("model.template", dir("src", "main", "resources", templateResourceDir), "model.mustache"),
SupportingFile("myFile.template", dir("src", "main", "resources", templateResourceDir), "myFile.mustache"), SupportingFile("myFile.template", dir("src", "main", "resources", templateResourceDir), "myFile.mustache"),
SupportingFile("services.mustache", dir("src", "main", "resources", "META-INF", "services"), CodegenConfig::class.java.canonicalName)) SupportingFile(
"services.mustache",
dir("src", "main", "resources", "META-INF", "services"),
CodegenConfig::class.java.canonicalName
)
)
val currentVersion = CodegenConstants::class.java.`package`.implementationVersion val currentVersion = CodegenConstants::class.java.`package`.implementationVersion
val data = mapOf("generatorPackage" to packageToPath, val data = mapOf(
"generatorPackage" to packageToPath,
"generatorClass" to klass, "generatorClass" to klass,
"name" to templateResourceDir, "name" to templateResourceDir,
"fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass", "fullyQualifiedGeneratorClass" to "${packageName.get()}.$klass",
"openapiGeneratorVersion" to currentVersion) "openapiGeneratorVersion" to currentVersion
)
supportingFiles.map { supportingFiles.map {
try { try {
@@ -131,11 +135,10 @@ open class MetaTask : DefaultTask() {
} }
private fun String.titleCasedTextOnly(): String = private fun String.titleCasedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize) split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "", transform = String::capitalize)
private fun String.hyphenatedTextOnly(): String = private fun String.hyphenatedTextOnly(): String =
this.split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase) split(Regex("[^a-zA-Z0-9]")).joinToString(separator = "-", transform = String::toLowerCase)
private fun dir(vararg parts: String): String = private fun dir(vararg parts: String): String = parts.joinToString(separator = File.separator)
parts.joinToString(separator = File.separator)
} }

View File

@@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("UnstableApiUsage")
package org.openapitools.generator.gradle.plugin.tasks package org.openapitools.generator.gradle.plugin.tasks
import io.swagger.parser.OpenAPIParser import io.swagger.parser.OpenAPIParser
@@ -45,7 +43,7 @@ import org.openapitools.codegen.validations.oas.RuleConfiguration
* *
* ./gradlew openApiValidate --input=/path/to/file * ./gradlew openApiValidate --input=/path/to/file
* *
* build.gradle: * build.gradle.kts:
* *
* openApiMeta { * openApiMeta {
* inputSpec = "path/to/spec.yaml" * inputSpec = "path/to/spec.yaml"
@@ -62,7 +60,6 @@ open class ValidateTask : DefaultTask() {
@Input @Input
val recommend = project.objects.property<Boolean?>() val recommend = project.objects.property<Boolean?>()
@Suppress("unused")
@get:Internal @get:Internal
@set:Option(option = "input", description = "The input specification.") @set:Option(option = "input", description = "The input specification.")
var input: String? = null var input: String? = null
@@ -70,7 +67,6 @@ open class ValidateTask : DefaultTask() {
inputSpec.set(value) inputSpec.set(value)
} }
@Suppress("unused")
@TaskAction @TaskAction
fun doWork() { fun doWork() {
val logger = Logging.getLogger(javaClass) val logger = Logging.getLogger(javaClass)
@@ -105,7 +101,6 @@ open class ValidateTask : DefaultTask() {
} }
if (messages.isNotEmpty() || validationResult.errors.isNotEmpty()) { if (messages.isNotEmpty() || validationResult.errors.isNotEmpty()) {
out.withStyle(StyledTextOutput.Style.Error) out.withStyle(StyledTextOutput.Style.Error)
out.println("\nSpec is invalid.\nIssues:\n") out.println("\nSpec is invalid.\nIssues:\n")

View File

@@ -4,12 +4,13 @@ import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome import org.gradle.testkit.runner.TaskOutcome
import org.testng.annotations.Test import org.testng.annotations.Test
import java.io.File import java.io.File
import java.nio.file.Files.createTempDirectory
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
class GenerateTaskDslTest : TestBase() { class GenerateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName) override var temp: File = createTempDirectory(javaClass.simpleName).toFile()
private val defaultBuildGradle = """ private val defaultBuildGradle = """
plugins { plugins {
@@ -61,7 +62,7 @@ class GenerateTaskDslTest : TestBase() {
"build/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt" "build/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt"
).map { ).map {
val f = File(temp, it) val f = File(temp, it)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation.") assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation: $f")
} }
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome, assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,
@@ -110,7 +111,7 @@ class GenerateTaskDslTest : TestBase() {
"build/java/src/main/java/org/openapitools/example/api/PetsApiClassSuffix.java" "build/java/src/main/java/org/openapitools/example/api/PetsApiClassSuffix.java"
).map { ).map {
val f = File(temp, it) val f = File(temp, it)
assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation. - " + f) assertTrue(f.exists() && f.isFile, "An expected file was not generated when invoking the generation. - $f")
} }
assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome, assertEquals(TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,

View File

@@ -27,7 +27,7 @@ class GeneratorsTaskDslTest : TestBase() {
.build() .build()
// Assert // Assert
assertTrue(result.output.contains("The following generators are available:"), "User friendly generator notice is missing.") assertTrue(result.output.contains("The following generators are available:"), "User-friendly generator notice is missing.")
assertTrue(result.output.contains("CLIENT generators:"), "Expected client generator header is missing.") assertTrue(result.output.contains("CLIENT generators:"), "Expected client generator header is missing.")
assertTrue(result.output.contains("android"), "Spot-checking listed client generators is missing a client generator.") assertTrue(result.output.contains("android"), "Spot-checking listed client generators is missing a client generator.")
assertTrue(result.output.contains("SERVER generators:"), "Expected server generator header is missing.") assertTrue(result.output.contains("SERVER generators:"), "Expected server generator header is missing.")

View File

@@ -34,7 +34,7 @@ class MetaTaskDslTest : TestBase() {
.build() .build()
// Assert // Assert
assertTrue(result.output.contains("Wrote file to"), "User friendly write notice is missing.") assertTrue(result.output.contains("Wrote file to"), "User-friendly write notice is missing.")
// To avoid any OS-specific output causing issues with our stdout comparisons, only compare on expected filenames. // To avoid any OS-specific output causing issues with our stdout comparisons, only compare on expected filenames.
listOf( listOf(

View File

@@ -4,27 +4,24 @@ import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod import org.testng.annotations.BeforeMethod
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.nio.file.Files.createTempDirectory
abstract class TestBase { abstract class TestBase {
protected open lateinit var temp: File protected open lateinit var temp: File
@BeforeMethod @BeforeMethod
protected fun before() { protected fun before() {
temp = createTempDir(javaClass.simpleName) temp = createTempDirectory(javaClass.simpleName).toFile()
temp.deleteOnExit() temp.deleteOnExit()
} }
@AfterMethod @AfterMethod
protected fun after(){ protected fun after() {
temp.deleteRecursively() temp.deleteRecursively()
} }
protected fun withProject( protected fun withProject(buildContents: String, projectFiles: Map<String, InputStream> = mapOf()) {
buildContents: String, File(temp, "build.gradle").writeText(buildContents)
projectFiles: Map<String, InputStream> = mapOf()
) {
val buildFile = File(temp,"build.gradle")
buildFile.writeText(buildContents)
projectFiles.forEach { entry -> projectFiles.forEach { entry ->
val target = File(temp, entry.key) val target = File(temp, entry.key)

View File

@@ -7,18 +7,20 @@ import org.gradle.util.GradleVersion
import org.testng.annotations.DataProvider import org.testng.annotations.DataProvider
import org.testng.annotations.Test import org.testng.annotations.Test
import java.io.File import java.io.File
import java.nio.file.Files.createTempDirectory
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
class ValidateTaskDslTest : TestBase() { class ValidateTaskDslTest : TestBase() {
override var temp: File = createTempDir(javaClass.simpleName) override var temp: File = createTempDirectory(javaClass.simpleName).toFile()
@DataProvider(name = "gradle_version_provider") @DataProvider(name = "gradle_version_provider")
fun gradleVersionProvider(): Array<Array<String?>> = arrayOf( fun gradleVersionProvider(): Array<Array<String?>> = arrayOf(
arrayOf(null), // uses the version of Gradle used to build the plugin itself arrayOf(null), // uses the version of Gradle used to build the plugin itself
arrayOf("5.6.4"), arrayOf("5.6.4"),
arrayOf("6.9"), arrayOf("6.9"),
arrayOf("7.0")) arrayOf("7.0")
)
private fun getGradleRunner(gradleVersion: String?): GradleRunner { private fun getGradleRunner(gradleVersion: String?): GradleRunner {
val gradleRunner = GradleRunner.create() val gradleRunner = GradleRunner.create()
@@ -33,7 +35,8 @@ class ValidateTaskDslTest : TestBase() {
@Test(dataProvider = "gradle_version_provider") @Test(dataProvider = "gradle_version_provider")
fun `openApiValidate should fail on non-file spec`(gradleVersion: String?) { fun `openApiValidate should fail on non-file spec`(gradleVersion: String?) {
// Arrange // Arrange
withProject(""" withProject(
"""
| plugins { | plugins {
| id 'org.openapi.generator' | id 'org.openapi.generator'
| } | }
@@ -41,7 +44,8 @@ class ValidateTaskDslTest : TestBase() {
| openApiValidate { | openApiValidate {
| inputSpec = "some_location" | inputSpec = "some_location"
| } | }
""".trimMargin()) """.trimMargin()
)
// Act // Act
val result = getGradleRunner(gradleVersion) val result = getGradleRunner(gradleVersion)
@@ -59,9 +63,14 @@ class ValidateTaskDslTest : TestBase() {
} else { } else {
"An input file was expected to be present but it doesn't exist." "An input file was expected to be present but it doesn't exist."
} }
assertTrue(result.output.contains(expectedMessage), "Unexpected/no message presented to the user for a spec pointing to an invalid URI.") assertTrue(
assertEquals(FAILED, result.task(":openApiValidate")?.outcome, result.output.contains(expectedMessage),
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}") "Unexpected/no message presented to the user for a spec pointing to an invalid URI."
)
assertEquals(
FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}"
)
} }
@Test(dataProvider = "gradle_version_provider") @Test(dataProvider = "gradle_version_provider")
@@ -71,7 +80,8 @@ class ValidateTaskDslTest : TestBase() {
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml") "spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
) )
withProject(""" withProject(
"""
| plugins { | plugins {
| id 'org.openapi.generator' | id 'org.openapi.generator'
| } | }
@@ -79,7 +89,8 @@ class ValidateTaskDslTest : TestBase() {
| openApiValidate { | openApiValidate {
| inputSpec = file("spec.yaml").absolutePath | inputSpec = file("spec.yaml").absolutePath
| } | }
""".trimMargin(), projectFiles) """.trimMargin(), projectFiles
)
// Act // Act
val result = getGradleRunner(gradleVersion) val result = getGradleRunner(gradleVersion)
@@ -89,9 +100,14 @@ class ValidateTaskDslTest : TestBase() {
.build() .build()
// Assert // Assert
assertTrue(result.output.contains("Spec is valid."), "Unexpected/no message presented to the user for a valid spec.") assertTrue(
assertEquals(SUCCESS, result.task(":openApiValidate")?.outcome, result.output.contains("Spec is valid."),
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}") "Unexpected/no message presented to the user for a valid spec."
)
assertEquals(
SUCCESS, result.task(":openApiValidate")?.outcome,
"Expected a successful run, but found ${result.task(":openApiValidate")?.outcome}"
)
} }
@Test(dataProvider = "gradle_version_provider") @Test(dataProvider = "gradle_version_provider")
@@ -100,7 +116,8 @@ class ValidateTaskDslTest : TestBase() {
val projectFiles = mapOf( val projectFiles = mapOf(
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml") "spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
) )
withProject(""" withProject(
"""
| plugins { | plugins {
| id 'org.openapi.generator' | id 'org.openapi.generator'
| } | }
@@ -108,7 +125,8 @@ class ValidateTaskDslTest : TestBase() {
| openApiValidate { | openApiValidate {
| inputSpec = file('spec.yaml').absolutePath | inputSpec = file('spec.yaml').absolutePath
| } | }
""".trimMargin(), projectFiles) """.trimMargin(), projectFiles
)
// Act // Act
val result = getGradleRunner(gradleVersion) val result = getGradleRunner(gradleVersion)
@@ -118,9 +136,13 @@ class ValidateTaskDslTest : TestBase() {
.buildAndFail() .buildAndFail()
// Assert // Assert
assertTrue(result.output.contains("Spec is invalid."), "Unexpected/no message presented to the user for an invalid spec.") assertTrue(
assertEquals(FAILED, result.task(":openApiValidate")?.outcome, result.output.contains("Spec is invalid."),
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}") "Unexpected/no message presented to the user for an invalid spec."
)
assertEquals(
FAILED, result.task(":openApiValidate")?.outcome,
"Expected a failed run, but found ${result.task(":openApiValidate")?.outcome}"
)
} }
} }

View File

@@ -12,7 +12,7 @@ Add to your `build->plugins` section (default phase is `generate-sources` phase)
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId> <artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>6.0.0</version> <version>6.0.1</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>
@@ -55,7 +55,7 @@ mvn clean compile
| `templateResourcePath` | `openapi.generator.maven.plugin.templateResourcePath` | directory with mustache templates via resource path. This option will overwrite any option defined in `templateDirectory`. | `templateResourcePath` | `openapi.generator.maven.plugin.templateResourcePath` | directory with mustache templates via resource path. This option will overwrite any option defined in `templateDirectory`.
| `engine` | `openapi.generator.maven.plugin.engine` | The name of templating engine to use, "mustache" (default) or "handlebars" (beta) | `engine` | `openapi.generator.maven.plugin.engine` | The name of templating engine to use, "mustache" (default) or "handlebars" (beta)
| `auth` | `openapi.generator.maven.plugin.auth` | adds authorization headers when fetching the OpenAPI definitions remotely. Pass in a URL-encoded string of `name:header` with a comma separating multiple values | `auth` | `openapi.generator.maven.plugin.auth` | adds authorization headers when fetching the OpenAPI definitions remotely. Pass in a URL-encoded string of `name:header` with a comma separating multiple values
| `configurationFile` | `openapi.generator.maven.plugin.configurationFile` | Path to separate json configuration file. File content should be in a json format {"optionKey":"optionValue", "optionKey1":"optionValue1"...} Supported options can be different for each language. Run `config-help -g {generator name}` command for language specific config options | `configurationFile` | `openapi.generator.maven.plugin.configurationFile` | Path to separate json configuration file. File content should be in a json format {"optionKey":"optionValue", "optionKey1":"optionValue1"...} Supported options can be different for each generator. Run `config-help -g {generator name}` command for generator-specific config options
| `skipOverwrite` | `openapi.generator.maven.plugin.skipOverwrite` | Specifies if the existing files should be overwritten during the generation. (`false` by default) | `skipOverwrite` | `openapi.generator.maven.plugin.skipOverwrite` | Specifies if the existing files should be overwritten during the generation. (`false` by default)
| `apiPackage` | `openapi.generator.maven.plugin.apiPackage` | the package to use for generated api objects/classes | `apiPackage` | `openapi.generator.maven.plugin.apiPackage` | the package to use for generated api objects/classes
| `modelPackage` | `openapi.generator.maven.plugin.modelPackage` | the package to use for generated model objects/classes | `modelPackage` | `openapi.generator.maven.plugin.modelPackage` | the package to use for generated model objects/classes
@@ -72,12 +72,12 @@ mvn clean compile
| `httpUserAgent` | `openapi.generator.maven.plugin.httpUserAgent` | Sets custom User-Agent header value | `httpUserAgent` | `openapi.generator.maven.plugin.httpUserAgent` | Sets custom User-Agent header value
| `removeOperationIdPrefix` | `openapi.generator.maven.plugin.removeOperationIdPrefix` | remove operationId prefix (e.g. user_getName => getName) | `removeOperationIdPrefix` | `openapi.generator.maven.plugin.removeOperationIdPrefix` | remove operationId prefix (e.g. user_getName => getName)
| `skipOperationExample` | `openapi.generator.maven.plugin.skipOperationExample` | skip examples defined in the operation | `skipOperationExample` | `openapi.generator.maven.plugin.skipOperationExample` | skip examples defined in the operation
| `logToStderr` | `openapi.generator.maven.plugin.logToStderr` | write all log messages (not just errors) to STDOUT | `logToStderr` | `openapi.generator.maven.plugin.logToStderr` | write all log messages (not just errors) to STDERR
| `enablePostProcessFile` | `openapi.generator.maven.plugin.` | enable file post-processing hook | `enablePostProcessFile` | `openapi.generator.maven.plugin.` | enable file post-processing hook
| `skipValidateSpec` | `openapi.generator.maven.plugin.skipValidateSpec` | Whether or not to skip validating the input spec prior to generation. By default, invalid specifications will result in an error. | `skipValidateSpec` | `openapi.generator.maven.plugin.skipValidateSpec` | Whether or not to skip validating the input spec prior to generation. By default, invalid specifications will result in an error.
| `strictSpec` | `openapi.generator.maven.plugin.strictSpec` | Whether or not to treat an input document strictly against the spec. 'MUST' and 'SHALL' wording in OpenAPI spec is strictly adhered to. e.g. when false, no fixes will be applied to documents which pass validation but don't follow the spec. | `strictSpec` | `openapi.generator.maven.plugin.strictSpec` | Whether or not to treat an input document strictly against the spec. 'MUST' and 'SHALL' wording in OpenAPI spec is strictly adhered to. e.g. when false, no fixes will be applied to documents which pass validation but don't follow the spec.
| `generateAliasAsModel` | `openapi.generator.maven.plugin.generateAliasAsModel` | generate alias (array, map) as model | `generateAliasAsModel` | `openapi.generator.maven.plugin.generateAliasAsModel` | generate alias (array, map) as model
| `configOptions` | N/A | a **map** of language-specific parameters. To show a full list of generator-specified parameters (options), please use `configHelp` (explained below) | `configOptions` | N/A | a **map** of generator-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 | `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 | `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. To map a specified format, use type+format, e.g. string+password=EncryptedString will map `type: string, format: password` to `EncryptedString`. | `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`.
@@ -127,7 +127,7 @@ The `key` and `value` text are any values you'd like to provide for that option.
</configuration> </configuration>
``` ```
Not that some of these environment variable options may overwrite or conflict with other options available to the maven plugin. For example, the above `globalProperties` example is equivalent to the following: Notice that some of these environment variable options may overwrite or conflict with other options available to the maven plugin. For example, the above `globalProperties` example is equivalent to the following:
```xml ```xml
<configuration> <configuration>

View File

@@ -27,11 +27,11 @@
<!-- specify the swagger yaml --> <!-- specify the swagger yaml -->
<inputSpec>${project.basedir}/swagger.yaml</inputSpec> <inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code --> <!-- target to generate kotlin client code -->
<generatorName>kotlin</generatorName> <generatorName>kotlin</generatorName>
<!-- hint: if you want to generate java server code, e.g. based on Spring Boot, <!-- hint: if you want to generate kotlin server code, e.g. based on Spring Boot,
you can use the following target: <generatorName>spring</generatorName> --> you can use the following generator: <generatorName>kotlin-spring</generatorName> -->
<!-- pass any necessary config options --> <!-- pass any necessary config options -->
<configOptions> <configOptions>

View File

@@ -32,11 +32,11 @@
<!-- specify the swagger yaml --> <!-- specify the swagger yaml -->
<inputSpec>${project.basedir}/swagger.yaml</inputSpec> <inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code --> <!-- target to generate java server code -->
<generatorName>spring</generatorName> <generatorName>spring</generatorName>
<!-- hint: if you want to generate java server code, e.g. based on Spring Boot, <!-- hint: if you want to generate java client code
you can use the following target: <generatorName>spring</generatorName> --> you can use the following generator: <generatorName>java</generatorName> -->
<!-- pass any necessary config options --> <!-- pass any necessary config options -->
<configOptions> <configOptions>

View File

@@ -298,12 +298,24 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "importMappings", property = "openapi.generator.maven.plugin.importMappings") @Parameter(name = "importMappings", property = "openapi.generator.maven.plugin.importMappings")
private List<String> importMappings; private List<String> importMappings;
/**
* A map of scheme and the new one
*/
@Parameter(name = "schemaMappings", property = "openapi.generator.maven.plugin.schemaMappings")
private List<String> schemaMappings;
/** /**
* A map of inline scheme names and the new names * A map of inline scheme names and the new names
*/ */
@Parameter(name = "inlineSchemaNameMappings", property = "openapi.generator.maven.plugin.inlineSchemaNameMappings") @Parameter(name = "inlineSchemaNameMappings", property = "openapi.generator.maven.plugin.inlineSchemaNameMappings")
private List<String> inlineSchemaNameMappings; private List<String> inlineSchemaNameMappings;
/**
* A map of inline scheme naming convention and the value
*/
@Parameter(name = "inlineSchemaNameDefaults", property = "openapi.generator.maven.plugin.inlineSchemaNameDefaults")
private List<String> inlineSchemaNameDefaults;
/** /**
* A map of swagger spec types and the generated code types to use for them * A map of swagger spec types and the generated code types to use for them
*/ */
@@ -665,12 +677,24 @@ public class CodeGenMojo extends AbstractMojo {
configurator); configurator);
} }
// Retained for backwards-compatibility with configOptions -> schema-mappings
if (schemaMappings == null && configOptions.containsKey("schema-mappings")) {
applySchemaMappingsKvp(configOptions.get("schema-mappings").toString(),
configurator);
}
// Retained for backwards-compatibility with configOptions -> inline-schema-name-mappings // Retained for backwards-compatibility with configOptions -> inline-schema-name-mappings
if (importMappings == null && configOptions.containsKey("inline-schema-name-mappings")) { if (inlineSchemaNameMappings == null && configOptions.containsKey("inline-schema-name-mappings")) {
applyInlineSchemaNameMappingsKvp(configOptions.get("inline-schema-name-mappings").toString(), applyInlineSchemaNameMappingsKvp(configOptions.get("inline-schema-name-mappings").toString(),
configurator); configurator);
} }
// Retained for backwards-compatibility with configOptions -> inline-schema-name-defaults
if (inlineSchemaNameDefaults == null && configOptions.containsKey("inline-schema-name-defaults")) {
applyInlineSchemaNameDefaultsKvp(configOptions.get("inline-schema-name-defaults").toString(),
configurator);
}
// Retained for backwards-compatibility with configOptions -> type-mappings // Retained for backwards-compatibility with configOptions -> type-mappings
if (typeMappings == null && configOptions.containsKey("type-mappings")) { if (typeMappings == null && configOptions.containsKey("type-mappings")) {
applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator); applyTypeMappingsKvp(configOptions.get("type-mappings").toString(), configurator);
@@ -709,11 +733,21 @@ public class CodeGenMojo extends AbstractMojo {
applyImportMappingsKvpList(importMappings, configurator); applyImportMappingsKvpList(importMappings, configurator);
} }
// Apply Schema Mappings
if (schemaMappings != null && (configOptions == null || !configOptions.containsKey("schema-mappings"))) {
applySchemaMappingsKvpList(schemaMappings, configurator);
}
// Apply Inline Schema Name Mappings // Apply Inline Schema Name Mappings
if (inlineSchemaNameMappings != null && (configOptions == null || !configOptions.containsKey("inline-schema-name-mappings"))) { if (inlineSchemaNameMappings != null && (configOptions == null || !configOptions.containsKey("inline-schema-name-mappings"))) {
applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator); applyInlineSchemaNameMappingsKvpList(inlineSchemaNameMappings, configurator);
} }
// Apply Inline Schema Name Defaults
if (inlineSchemaNameDefaults != null && (configOptions == null || !configOptions.containsKey("inline-schema-name-defaults"))) {
applyInlineSchemaNameDefaultsKvpList(inlineSchemaNameDefaults, configurator);
}
// Apply Type Mappings // Apply Type Mappings
if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) { if (typeMappings != null && (configOptions == null || !configOptions.containsKey("type-mappings"))) {
applyTypeMappingsKvpList(typeMappings, configurator); applyTypeMappingsKvpList(typeMappings, configurator);

View File

@@ -141,8 +141,12 @@ public interface CodegenConfig {
Map<String, String> importMapping(); Map<String, String> importMapping();
Map<String, String> schemaMapping();
Map<String, String> inlineSchemaNameMapping(); Map<String, String> inlineSchemaNameMapping();
Map<String, String> inlineSchemaNameDefault();
Map<String, String> apiTemplateFiles(); Map<String, String> apiTemplateFiles();
Map<String, String> modelTemplateFiles(); Map<String, String> modelTemplateFiles();
@@ -309,7 +313,7 @@ public interface CodegenConfig {
void setRemoveEnumValuePrefix(boolean removeEnumValuePrefix); void setRemoveEnumValuePrefix(boolean removeEnumValuePrefix);
Schema unaliasSchema(Schema schema, Map<String, String> usedImportMappings); Schema unaliasSchema(Schema schema);
String defaultTemplatingEngine(); String defaultTemplatingEngine();

View File

@@ -398,4 +398,7 @@ public class CodegenConstants {
public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC = "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."; public static final String USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC = "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.";
public static final String INIT_REQUIRED_VARS = "initRequiredVars"; public static final String INIT_REQUIRED_VARS = "initRequiredVars";
public static final String INIT_REQUIRED_VARS_DESC = "If set to true then the required variables are included as positional arguments in __init__ and _from_openapi_data methods. Note: this can break some composition use cases. To learn more read PR #8802."; public static final String INIT_REQUIRED_VARS_DESC = "If set to true then the required variables are included as positional arguments in __init__ and _from_openapi_data methods. Note: this can break some composition use cases. To learn more read PR #8802.";
public static final String ERROR_OBJECT_TYPE = "errorObjectType";
} }

View File

@@ -75,6 +75,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
public List<CodegenProperty> readOnlyVars = new ArrayList<>(); // a list of read-only properties public List<CodegenProperty> readOnlyVars = new ArrayList<>(); // a list of read-only properties
public List<CodegenProperty> readWriteVars = new ArrayList<>(); // a list of properties for read, write public List<CodegenProperty> readWriteVars = new ArrayList<>(); // a list of properties for read, write
public List<CodegenProperty> parentVars = new ArrayList<>(); public List<CodegenProperty> parentVars = new ArrayList<>();
public List<CodegenProperty> nonNullableVars = new ArrayList<>(); // a list of non-nullable properties
public Map<String, Object> allowableValues; public Map<String, Object> allowableValues;
// Sorted sets of required parameters. // Sorted sets of required parameters.
@@ -109,6 +110,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
public Map<String, Object> vendorExtensions = new HashMap<>(); public Map<String, Object> vendorExtensions = new HashMap<>();
private CodegenComposedSchemas composedSchemas; private CodegenComposedSchemas composedSchemas;
private boolean hasMultipleTypes = false; private boolean hasMultipleTypes = false;
public HashMap<String, SchemaTestCase> testCases = new HashMap<>();
/** /**
* The type of the value for the additionalProperties keyword in the OAS document. * The type of the value for the additionalProperties keyword in the OAS document.
@@ -195,6 +197,14 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
this.allVars = allVars; this.allVars = allVars;
} }
public List<CodegenProperty> getNonNullableVars() {
return nonNullableVars;
}
public void setNonNullableVars(List<CodegenProperty> nonNullableVars) {
this.nonNullableVars = nonNullableVars;
}
public Map<String, Object> getAllowableValues() { public Map<String, Object> getAllowableValues() {
return allowableValues; return allowableValues;
} }
@@ -946,6 +956,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
Objects.equals(arrayModelType, that.arrayModelType) && Objects.equals(arrayModelType, that.arrayModelType) &&
Objects.equals(vars, that.vars) && Objects.equals(vars, that.vars) &&
Objects.equals(allVars, that.allVars) && Objects.equals(allVars, that.allVars) &&
Objects.equals(nonNullableVars, that.nonNullableVars) &&
Objects.equals(requiredVars, that.requiredVars) && Objects.equals(requiredVars, that.requiredVars) &&
Objects.equals(optionalVars, that.optionalVars) && Objects.equals(optionalVars, that.optionalVars) &&
Objects.equals(readOnlyVars, that.readOnlyVars) && Objects.equals(readOnlyVars, that.readOnlyVars) &&
@@ -981,7 +992,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
getXmlName(), getClassFilename(), getUnescapedDescription(), getDiscriminator(), getDefaultValue(), getXmlName(), getClassFilename(), getUnescapedDescription(), getDiscriminator(), getDefaultValue(),
getArrayModelType(), isAlias, isString, isInteger, isLong, isNumber, isNumeric, isFloat, isDouble, getArrayModelType(), isAlias, isString, isInteger, isLong, isNumber, isNumeric, isFloat, isDouble,
isDate, isDateTime, isNull, hasValidation, isShort, isUnboundedInteger, isBoolean, isDate, isDateTime, isNull, hasValidation, isShort, isUnboundedInteger, isBoolean,
getVars(), getAllVars(), getRequiredVars(), getOptionalVars(), getReadOnlyVars(), getReadWriteVars(), getVars(), getAllVars(), getNonNullableVars(), getRequiredVars(), getOptionalVars(), getReadOnlyVars(), getReadWriteVars(),
getParentVars(), getAllowableValues(), getMandatory(), getAllMandatory(), getImports(), hasVars, getParentVars(), getAllowableValues(), getMandatory(), getAllMandatory(), getImports(), hasVars,
isEmptyVars(), hasMoreModels, hasEnums, isEnum, isNullable, hasRequired, hasOptional, isArray, isEmptyVars(), hasMoreModels, hasEnums, isEnum, isNullable, hasRequired, hasOptional, isArray,
hasChildren, isMap, isDeprecated, hasOnlyReadOnly, getExternalDocumentation(), getVendorExtensions(), hasChildren, isMap, isDeprecated, hasOnlyReadOnly, getExternalDocumentation(), getVendorExtensions(),
@@ -999,10 +1010,10 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
sb.append(", parent='").append(parent).append('\''); sb.append(", parent='").append(parent).append('\'');
sb.append(", parentSchema='").append(parentSchema).append('\''); sb.append(", parentSchema='").append(parentSchema).append('\'');
sb.append(", interfaces=").append(interfaces); sb.append(", interfaces=").append(interfaces);
sb.append(", interfaceModels=").append(interfaceModels!=null?interfaceModels.size():"[]"); sb.append(", interfaceModels=").append(interfaceModels !=null ? interfaceModels.size() : "[]");
sb.append(", allParents=").append(allParents); sb.append(", allParents=").append(allParents);
sb.append(", parentModel=").append(parentModel); sb.append(", parentModel=").append(parentModel);
sb.append(", children=").append(children!=null?children.size():"[]"); sb.append(", children=").append(children != null ? children.size() : "[]");
sb.append(", anyOf=").append(anyOf); sb.append(", anyOf=").append(anyOf);
sb.append(", oneOf=").append(oneOf); sb.append(", oneOf=").append(oneOf);
sb.append(", allOf=").append(allOf); sb.append(", allOf=").append(allOf);
@@ -1035,6 +1046,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
sb.append(", isDateTime=").append(isDateTime); sb.append(", isDateTime=").append(isDateTime);
sb.append(", vars=").append(vars); sb.append(", vars=").append(vars);
sb.append(", allVars=").append(allVars); sb.append(", allVars=").append(allVars);
sb.append(", nonNullableVars=").append(nonNullableVars);
sb.append(", requiredVars=").append(requiredVars); sb.append(", requiredVars=").append(requiredVars);
sb.append(", optionalVars=").append(optionalVars); sb.append(", optionalVars=").append(optionalVars);
sb.append(", readOnlyVars=").append(readOnlyVars); sb.append(", readOnlyVars=").append(readOnlyVars);
@@ -1122,6 +1134,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties {
requiredVars = removeDuplicatedProperty(requiredVars); requiredVars = removeDuplicatedProperty(requiredVars);
parentVars = removeDuplicatedProperty(parentVars); parentVars = removeDuplicatedProperty(parentVars);
allVars = removeDuplicatedProperty(allVars); allVars = removeDuplicatedProperty(allVars);
nonNullableVars = removeDuplicatedProperty(nonNullableVars);
readOnlyVars = removeDuplicatedProperty(readOnlyVars); readOnlyVars = removeDuplicatedProperty(readOnlyVars);
readWriteVars = removeDuplicatedProperty(readWriteVars); readWriteVars = removeDuplicatedProperty(readWriteVars);
} }

View File

@@ -27,10 +27,11 @@ public class CodegenOperation {
public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, hasRequiredParams, public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, hasRequiredParams,
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isArray, isMultipart,
isResponseBinary = false, isResponseFile = false, hasReference = false, isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false, isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false,
hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined
public CodegenProperty returnProperty;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType, public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse; returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public CodegenDiscriminator discriminator; public CodegenDiscriminator discriminator;
@@ -298,10 +299,12 @@ public class CodegenOperation {
sb.append(", returnSimpleType=").append(returnSimpleType); sb.append(", returnSimpleType=").append(returnSimpleType);
sb.append(", subresourceOperation=").append(subresourceOperation); sb.append(", subresourceOperation=").append(subresourceOperation);
sb.append(", isMap=").append(isMap); sb.append(", isMap=").append(isMap);
sb.append(", returnProperty=").append(returnProperty);
sb.append(", isArray=").append(isArray); sb.append(", isArray=").append(isArray);
sb.append(", isMultipart=").append(isMultipart); sb.append(", isMultipart=").append(isMultipart);
sb.append(", isResponseBinary=").append(isResponseBinary); sb.append(", isResponseBinary=").append(isResponseBinary);
sb.append(", isResponseFile=").append(isResponseFile); sb.append(", isResponseFile=").append(isResponseFile);
sb.append(", isResponseFile=").append(isResponseOptional);
sb.append(", hasReference=").append(hasReference); sb.append(", hasReference=").append(hasReference);
sb.append(", hasDefaultResponse=").append(hasDefaultResponse); sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject); sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject);
@@ -377,6 +380,7 @@ public class CodegenOperation {
isMultipart == that.isMultipart && isMultipart == that.isMultipart &&
isResponseBinary == that.isResponseBinary && isResponseBinary == that.isResponseBinary &&
isResponseFile == that.isResponseFile && isResponseFile == that.isResponseFile &&
isResponseOptional == that.isResponseOptional &&
hasReference == that.hasReference && hasReference == that.hasReference &&
hasDefaultResponse == that.hasDefaultResponse && hasDefaultResponse == that.hasDefaultResponse &&
hasErrorResponseObject == that.hasErrorResponseObject && hasErrorResponseObject == that.hasErrorResponseObject &&
@@ -389,6 +393,7 @@ public class CodegenOperation {
isDeprecated == that.isDeprecated && isDeprecated == that.isDeprecated &&
isCallbackRequest == that.isCallbackRequest && isCallbackRequest == that.isCallbackRequest &&
uniqueItems == that.uniqueItems && uniqueItems == that.uniqueItems &&
Objects.equals(returnProperty, that.returnProperty) &&
Objects.equals(responseHeaders, that.responseHeaders) && Objects.equals(responseHeaders, that.responseHeaders) &&
Objects.equals(path, that.path) && Objects.equals(path, that.path) &&
Objects.equals(operationId, that.operationId) && Objects.equals(operationId, that.operationId) &&
@@ -437,14 +442,14 @@ public class CodegenOperation {
return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, return Objects.hash(responseHeaders, hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams,
hasRequiredParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap, hasRequiredParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isResponseBinary, isResponseFile, hasReference, hasDefaultResponse, isRestfulIndex, isArray, isMultipart, isResponseBinary, isResponseFile, isResponseOptional, hasReference,
isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful, isDeprecated, hasDefaultResponse, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod, returnBaseType, isRestful, isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse, discriminator, consumes, returnBaseType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse,
produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams, pathParams, queryParams, discriminator, consumes, produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams,
headerParams, formParams, cookieParams, requiredParams, optionalParams, authMethods, tags, pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, returnProperty, optionalParams,
responses, callbacks, imports, examples, requestBodyExamples, externalDocs, vendorExtensions, authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs,
nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase, operationIdSnakeCase, vendorExtensions, nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase,
hasErrorResponseObject); operationIdSnakeCase, hasErrorResponseObject);
} }
} }

View File

@@ -153,8 +153,12 @@ public class DefaultCodegen implements CodegenConfig {
protected Set<String> reservedWords; protected Set<String> reservedWords;
protected Set<String> languageSpecificPrimitives = new HashSet<>(); protected Set<String> languageSpecificPrimitives = new HashSet<>();
protected Map<String, String> importMapping = new HashMap<>(); protected Map<String, String> importMapping = new HashMap<>();
// a map to store the mappping between a schema and the new one
protected Map<String, String> schemaMapping = new HashMap<>();
// a map to store the mappping between inline schema and the name provided by the user // a map to store the mappping between inline schema and the name provided by the user
protected Map<String, String> inlineSchemaNameMapping = new HashMap<>(); protected Map<String, String> inlineSchemaNameMapping = new HashMap<>();
// a map to store the inline schema naming conventions
protected Map<String, String> inlineSchemaNameDefault = new HashMap<>();
protected String modelPackage = "", apiPackage = "", fileSuffix; protected String modelPackage = "", apiPackage = "", fileSuffix;
protected String modelNamePrefix = "", modelNameSuffix = ""; protected String modelNamePrefix = "", modelNameSuffix = "";
protected String apiNamePrefix = "", apiNameSuffix = "Api"; protected String apiNamePrefix = "", apiNameSuffix = "Api";
@@ -694,6 +698,10 @@ public class DefaultCodegen implements CodegenConfig {
updateCodegenPropertyEnum(var); updateCodegenPropertyEnum(var);
} }
for (CodegenProperty var : cm.nonNullableVars) {
updateCodegenPropertyEnum(var);
}
for (CodegenProperty var : cm.requiredVars) { for (CodegenProperty var : cm.requiredVars) {
updateCodegenPropertyEnum(var); updateCodegenPropertyEnum(var);
} }
@@ -1058,11 +1066,21 @@ public class DefaultCodegen implements CodegenConfig {
return importMapping; return importMapping;
} }
@Override
public Map<String, String> schemaMapping() {
return schemaMapping;
}
@Override @Override
public Map<String, String> inlineSchemaNameMapping() { public Map<String, String> inlineSchemaNameMapping() {
return inlineSchemaNameMapping; return inlineSchemaNameMapping;
} }
@Override
public Map<String, String> inlineSchemaNameDefault() {
return inlineSchemaNameDefault;
}
@Override @Override
public String testPackage() { public String testPackage() {
return testPackage; return testPackage;
@@ -1721,6 +1739,7 @@ public class DefaultCodegen implements CodegenConfig {
specialCharReplacements.put("<=", "Less_Than_Or_Equal_To"); specialCharReplacements.put("<=", "Less_Than_Or_Equal_To");
specialCharReplacements.put(">=", "Greater_Than_Or_Equal_To"); specialCharReplacements.put(">=", "Greater_Than_Or_Equal_To");
specialCharReplacements.put("!=", "Not_Equal"); specialCharReplacements.put("!=", "Not_Equal");
specialCharReplacements.put("<>", "Not_Equal");
specialCharReplacements.put("~=", "Tilde_Equal"); specialCharReplacements.put("~=", "Tilde_Equal");
} }
@@ -2184,8 +2203,8 @@ public class DefaultCodegen implements CodegenConfig {
} }
@Override @Override
public Schema unaliasSchema(Schema schema, Map<String, String> usedImportMappings) { public Schema unaliasSchema(Schema schema) {
return ModelUtils.unaliasSchema(this.openAPI, schema, usedImportMappings); return ModelUtils.unaliasSchema(this.openAPI, schema, schemaMapping);
} }
/** /**
@@ -2195,13 +2214,13 @@ public class DefaultCodegen implements CodegenConfig {
* @return the string representation of the schema type. * @return the string representation of the schema type.
*/ */
protected String getSingleSchemaType(Schema schema) { protected String getSingleSchemaType(Schema schema) {
Schema unaliasSchema = unaliasSchema(schema, importMapping); Schema unaliasSchema = unaliasSchema(schema);
if (StringUtils.isNotBlank(unaliasSchema.get$ref())) { // reference to another definition/schema if (StringUtils.isNotBlank(unaliasSchema.get$ref())) { // reference to another definition/schema
// get the schema/model name from $ref // get the schema/model name from $ref
String schemaName = ModelUtils.getSimpleRef(unaliasSchema.get$ref()); String schemaName = ModelUtils.getSimpleRef(unaliasSchema.get$ref());
if (StringUtils.isNotEmpty(schemaName)) { if (StringUtils.isNotEmpty(schemaName)) {
if (importMapping.containsKey(schemaName)) { if (schemaMapping.containsKey(schemaName)) {
return schemaName; return schemaName;
} }
return getAlias(schemaName); return getAlias(schemaName);
@@ -2297,8 +2316,8 @@ public class DefaultCodegen implements CodegenConfig {
} else if (ModelUtils.isAnyType(schema)) { } else if (ModelUtils.isAnyType(schema)) {
return "AnyType"; return "AnyType";
} else if (StringUtils.isNotEmpty(schema.getType())) { } else if (StringUtils.isNotEmpty(schema.getType())) {
if (!importMapping.containsKey(schema.getType())) { if (!schemaMapping.containsKey(schema.getType())) {
LOGGER.warn("Unknown type found in the schema: {}", schema.getType()); LOGGER.warn("Unknown type found in the schema: {}. To map it, please use the schema mapping option (e.g. --schema-mappings in CLI)", schema.getType());
} }
return schema.getType(); return schema.getType();
} }
@@ -2437,26 +2456,29 @@ public class DefaultCodegen implements CodegenConfig {
} }
private static class NamedSchema { private static class NamedSchema {
private NamedSchema(String name, Schema s) { private NamedSchema(String name, Schema s, boolean required) {
this.name = name; this.name = name;
this.schema = s; this.schema = s;
this.required = required;
} }
private String name; private String name;
private Schema schema; private Schema schema;
private boolean required;
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
NamedSchema that = (NamedSchema) o; NamedSchema that = (NamedSchema) o;
return Objects.equals(name, that.name) && return Objects.equals(required, that.required) &&
Objects.equals(name, that.name) &&
Objects.equals(schema, that.schema); Objects.equals(schema, that.schema);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(name, schema); return Objects.hash(name, schema, required);
} }
} }
@@ -2524,12 +2546,12 @@ public class DefaultCodegen implements CodegenConfig {
m.interfaces = new ArrayList<>(); m.interfaces = new ArrayList<>();
for (Schema interfaceSchema : interfaces) { for (Schema interfaceSchema : interfaces) {
interfaceSchema = unaliasSchema(interfaceSchema, importMapping); interfaceSchema = unaliasSchema(interfaceSchema);
if (StringUtils.isBlank(interfaceSchema.get$ref())) { if (StringUtils.isBlank(interfaceSchema.get$ref())) {
// primitive type // primitive type
String languageType = getTypeDeclaration(interfaceSchema); String languageType = getTypeDeclaration(interfaceSchema);
CodegenProperty interfaceProperty = fromProperty(languageType, interfaceSchema); CodegenProperty interfaceProperty = fromProperty(languageType, interfaceSchema, false);
if (ModelUtils.isArraySchema(interfaceSchema) || ModelUtils.isMapSchema(interfaceSchema)) { if (ModelUtils.isArraySchema(interfaceSchema) || ModelUtils.isMapSchema(interfaceSchema)) {
while (interfaceProperty != null) { while (interfaceProperty != null) {
addImport(m, interfaceProperty.complexType); addImport(m, interfaceProperty.complexType);
@@ -2565,9 +2587,10 @@ public class DefaultCodegen implements CodegenConfig {
refSchema = allDefinitions.get(ref); refSchema = allDefinitions.get(ref);
} }
final String modelName = toModelName(ref); final String modelName = toModelName(ref);
CodegenProperty interfaceProperty = fromProperty(modelName, interfaceSchema); CodegenProperty interfaceProperty = fromProperty(modelName, interfaceSchema, false);
m.interfaces.add(modelName); m.interfaces.add(modelName);
addImport(m, modelName); addImport(composed, refSchema, m, modelName);
if (allDefinitions != null && refSchema != null) { if (allDefinitions != null && refSchema != null) {
if (allParents.contains(ref) && supportsMultipleInheritance) { if (allParents.contains(ref) && supportsMultipleInheritance) {
// multiple inheritance // multiple inheritance
@@ -2689,6 +2712,52 @@ public class DefaultCodegen implements CodegenConfig {
setAddProps(schema, m); setAddProps(schema, m);
} }
protected String toTestCaseName(String specTestCaseName) {
return specTestCaseName;
}
/**
* A method that allows generators to pre-process test example payloads
* This can be useful if one needs to change how values like null in string are represnted
* @param data the test data payload
* @return the updated test data payload
*/
protected Object processTestExampleData(Object data) {
return data;
}
/**
* Processes any test cases if they exist in the components.x-test-examples vendor extensions
* If they exist then cast them to java class instances and return them back in a map
* @param schemaName the component schema name that the test cases are for
* @param vendorExtensions the extensions that may or may not hold the data
*/
private HashMap<String, SchemaTestCase> extractSchemaTestCases(String schemaName, HashMap<String, Object> vendorExtensions) {
String testExamplesKey = "x-schema-test-examples";
// schemaName to a map of test case name to test case
if (vendorExtensions == null || !vendorExtensions.containsKey(testExamplesKey)) {
return null;
}
HashMap<String, SchemaTestCase> schemaTestCases = new HashMap<>();
LinkedHashMap<String, Object> schemaNameToTestCases = (LinkedHashMap<String, Object>) vendorExtensions.get(testExamplesKey);
if (!schemaNameToTestCases.containsKey(schemaName)) {
return null;
}
LinkedHashMap<String, LinkedHashMap<String, Object>> testNameToTesCase = (LinkedHashMap<String, LinkedHashMap<String, Object>>) schemaNameToTestCases.get(schemaName);
for (Entry<String, LinkedHashMap<String, Object>> entry: testNameToTesCase.entrySet()) {
LinkedHashMap<String, Object> testExample = (LinkedHashMap<String, Object>) entry.getValue();
String nameInSnakeCase = toTestCaseName(entry.getKey());
Object data = processTestExampleData(testExample.get("data"));
SchemaTestCase testCase = new SchemaTestCase(
(String) testExample.getOrDefault("description", ""),
new ObjectWithTypeBooleans(data),
(boolean) testExample.get("valid")
);
schemaTestCases.put(nameInSnakeCase, testCase);
}
return schemaTestCases;
}
/** /**
* Convert OAS Model object to Codegen Model object. * Convert OAS Model object to Codegen Model object.
@@ -2706,7 +2775,7 @@ public class DefaultCodegen implements CodegenConfig {
} }
// unalias schema // unalias schema
schema = unaliasSchema(schema, importMapping); schema = unaliasSchema(schema);
if (schema == null) { if (schema == null) {
LOGGER.warn("Schema {} not found", name); LOGGER.warn("Schema {} not found", name);
return null; return null;
@@ -2714,6 +2783,11 @@ public class DefaultCodegen implements CodegenConfig {
CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL); CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
ModelUtils.syncValidationProperties(schema, m); ModelUtils.syncValidationProperties(schema, m);
if (openAPI != null) {
HashMap<String, Object> vendorExtensions = (HashMap<String, Object>) openAPI.getComponents().getExtensions();
HashMap<String, SchemaTestCase> schemaTestCases = extractSchemaTestCases(name, vendorExtensions);
m.testCases = schemaTestCases;
}
if (reservedWords.contains(name)) { if (reservedWords.contains(name)) {
m.name = escapeReservedWord(name); m.name = escapeReservedWord(name);
@@ -2764,7 +2838,7 @@ public class DefaultCodegen implements CodegenConfig {
m.setTypeProperties(schema); m.setTypeProperties(schema);
m.setComposedSchemas(getComposedSchemas(schema)); m.setComposedSchemas(getComposedSchemas(schema));
if (ModelUtils.isArraySchema(schema)) { if (ModelUtils.isArraySchema(schema)) {
CodegenProperty arrayProperty = fromProperty(name, schema); CodegenProperty arrayProperty = fromProperty(name, schema, false);
m.setItems(arrayProperty.items); m.setItems(arrayProperty.items);
m.arrayModelType = arrayProperty.complexType; m.arrayModelType = arrayProperty.complexType;
addParentContainer(m, name, schema); addParentContainer(m, name, schema);
@@ -2884,17 +2958,17 @@ public class DefaultCodegen implements CodegenConfig {
if (schema.getAdditionalProperties() == null) { if (schema.getAdditionalProperties() == null) {
if (!disallowAdditionalPropertiesIfNotPresent) { if (!disallowAdditionalPropertiesIfNotPresent) {
isAdditionalPropertiesTrue = true; isAdditionalPropertiesTrue = true;
addPropProp = fromProperty("", new Schema()); addPropProp = fromProperty("", new Schema(), false);
additionalPropertiesIsAnyType = true; additionalPropertiesIsAnyType = true;
} }
} else if (schema.getAdditionalProperties() instanceof Boolean) { } else if (schema.getAdditionalProperties() instanceof Boolean) {
if (Boolean.TRUE.equals(schema.getAdditionalProperties())) { if (Boolean.TRUE.equals(schema.getAdditionalProperties())) {
isAdditionalPropertiesTrue = true; isAdditionalPropertiesTrue = true;
addPropProp = fromProperty("", new Schema()); addPropProp = fromProperty("", new Schema(), false);
additionalPropertiesIsAnyType = true; additionalPropertiesIsAnyType = true;
} }
} else { } else {
addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties()); addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties(), false);
if (ModelUtils.isAnyType((Schema) schema.getAdditionalProperties())) { if (ModelUtils.isAnyType((Schema) schema.getAdditionalProperties())) {
additionalPropertiesIsAnyType = true; additionalPropertiesIsAnyType = true;
} }
@@ -3374,13 +3448,13 @@ public class DefaultCodegen implements CodegenConfig {
property.maxItems = p.getMaxProperties(); property.maxItems = p.getMaxProperties();
// handle inner property // handle inner property
Schema innerSchema = unaliasSchema(getAdditionalProperties(p), importMapping); Schema innerSchema = unaliasSchema(getAdditionalProperties(p));
if (innerSchema == null) { if (innerSchema == null) {
LOGGER.error("Undefined map inner type for `{}`. Default to String.", p.getName()); LOGGER.error("Undefined map inner type for `{}`. Default to String.", p.getName());
innerSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to undefined type"); innerSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to undefined type");
p.setAdditionalProperties(innerSchema); p.setAdditionalProperties(innerSchema);
} }
CodegenProperty cp = fromProperty("inner", innerSchema); CodegenProperty cp = fromProperty("inner", innerSchema, false);
updatePropertyForMap(property, cp); updatePropertyForMap(property, cp);
} }
@@ -3451,6 +3525,19 @@ public class DefaultCodegen implements CodegenConfig {
property.pattern = toRegularExpression(p.getPattern()); property.pattern = toRegularExpression(p.getPattern());
} }
/**
* TODO remove this in 7.0.0 as a breaking change
* This method was kept when required was added to the fromProperty signature
* to ensure that the change was non-breaking
*
* @param name name of the property
* @param p OAS property schema
* @return Codegen Property object
*/
public CodegenProperty fromProperty(String name, Schema p) {
return fromProperty(name, p, false);
}
/** /**
* Convert OAS Property object to Codegen Property object. * Convert OAS Property object to Codegen Property object.
* <p> * <p>
@@ -3462,24 +3549,26 @@ public class DefaultCodegen implements CodegenConfig {
* *
* @param name name of the property * @param name name of the property
* @param p OAS property schema * @param p OAS property schema
* @param required true if the property is required in the next higher object schema, false otherwise
* @return Codegen Property object * @return Codegen Property object
*/ */
public CodegenProperty fromProperty(String name, Schema p) { public CodegenProperty fromProperty(String name, Schema p, boolean required) {
if (p == null) { if (p == null) {
LOGGER.error("Undefined property/schema for `{}`. Default to type:string.", name); LOGGER.error("Undefined property/schema for `{}`. Default to type:string.", name);
return null; return null;
} }
LOGGER.debug("debugging fromProperty for {} : {}", name, p); LOGGER.debug("debugging fromProperty for {} : {}", name, p);
NamedSchema ns = new NamedSchema(name, p); NamedSchema ns = new NamedSchema(name, p, required);
CodegenProperty cpc = schemaCodegenPropertyCache.get(ns); CodegenProperty cpc = schemaCodegenPropertyCache.get(ns);
if (cpc != null) { if (cpc != null) {
LOGGER.debug("Cached fromProperty for {} : {}", name, p.getName()); LOGGER.debug("Cached fromProperty for {} : {} required={}", name, p.getName(), required);
return cpc; return cpc;
} }
// unalias schema // unalias schema
p = unaliasSchema(p, importMapping); p = unaliasSchema(p);
CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY); CodegenProperty property = CodegenModelFactory.newInstance(CodegenModelType.PROPERTY);
property.required = required;
ModelUtils.syncValidationProperties(p, property); ModelUtils.syncValidationProperties(p, property);
property.name = toVarName(name); property.name = toVarName(name);
@@ -3645,8 +3734,8 @@ public class DefaultCodegen implements CodegenConfig {
itemName = property.name; itemName = property.name;
} }
ArraySchema arraySchema = (ArraySchema) p; ArraySchema arraySchema = (ArraySchema) p;
Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema), importMapping); Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema));
CodegenProperty cp = fromProperty(itemName, innerSchema); CodegenProperty cp = fromProperty(itemName, innerSchema, false);
updatePropertyForArray(property, cp); updatePropertyForArray(property, cp);
} else if (ModelUtils.isTypeObjectSchema(p)) { } else if (ModelUtils.isTypeObjectSchema(p)) {
updatePropertyForObject(property, p); updatePropertyForObject(property, p);
@@ -3884,24 +3973,24 @@ public class DefaultCodegen implements CodegenConfig {
* @param schemas a map of the schemas in the openapi spec * @param schemas a map of the schemas in the openapi spec
* @param op endpoint CodegenOperation * @param op endpoint CodegenOperation
* @param methodResponse the default ApiResponse for the endpoint * @param methodResponse the default ApiResponse for the endpoint
* @param importMappings mappings of external types to be omitted by unaliasing * @param schemaMappings mappings of external types to be omitted by unaliasing
*/ */
protected void handleMethodResponse(Operation operation, protected void handleMethodResponse(Operation operation,
Map<String, Schema> schemas, Map<String, Schema> schemas,
CodegenOperation op, CodegenOperation op,
ApiResponse methodResponse, ApiResponse methodResponse,
Map<String, String> importMappings) { Map<String, String> schemaMappings) {
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(methodResponse), importMapping); Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(methodResponse));
if (responseSchema != null) { if (responseSchema != null) {
CodegenProperty cm = fromProperty("response", responseSchema); CodegenProperty cm = fromProperty("response", responseSchema, false);
if (ModelUtils.isArraySchema(responseSchema)) { if (ModelUtils.isArraySchema(responseSchema)) {
ArraySchema as = (ArraySchema) responseSchema; ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty innerProperty = fromProperty("response", getSchemaItems(as)); CodegenProperty innerProperty = fromProperty("response", getSchemaItems(as), false);
op.returnBaseType = innerProperty.baseType; op.returnBaseType = innerProperty.baseType;
} else if (ModelUtils.isMapSchema(responseSchema)) { } else if (ModelUtils.isMapSchema(responseSchema)) {
CodegenProperty innerProperty = fromProperty("response", getAdditionalProperties(responseSchema)); CodegenProperty innerProperty = fromProperty("response", getAdditionalProperties(responseSchema), false);
op.returnBaseType = innerProperty.baseType; op.returnBaseType = innerProperty.baseType;
} else { } else {
if (cm.complexType != null) { if (cm.complexType != null) {
@@ -3955,6 +4044,7 @@ public class DefaultCodegen implements CodegenConfig {
if (languageSpecificPrimitives().contains(op.returnBaseType) || op.returnBaseType == null) { if (languageSpecificPrimitives().contains(op.returnBaseType) || op.returnBaseType == null) {
op.returnTypeIsPrimitive = true; op.returnTypeIsPrimitive = true;
} }
op.returnProperty = cm;
} }
addHeaders(methodResponse, op.responseHeaders); addHeaders(methodResponse, op.responseHeaders);
} }
@@ -4078,6 +4168,13 @@ public class DefaultCodegen implements CodegenConfig {
op.hasErrorResponseObject = Boolean.TRUE; op.hasErrorResponseObject = Boolean.TRUE;
} }
} }
// check if the operation can both return a 2xx response with a body and without
if (op.responses.stream().anyMatch(response -> response.is2xx && response.dataType != null) &&
op.responses.stream().anyMatch(response -> response.is2xx && response.dataType == null)) {
op.isResponseOptional = Boolean.TRUE;
}
op.responses.sort((a, b) -> { op.responses.sort((a, b) -> {
int aScore = a.isWildcard() ? 2 : a.isRange() ? 1 : 0; int aScore = a.isWildcard() ? 2 : a.isRange() ? 1 : 0;
int bScore = b.isWildcard() ? 2 : b.isRange() ? 1 : 0; int bScore = b.isWildcard() ? 2 : b.isRange() ? 1 : 0;
@@ -4323,7 +4420,7 @@ public class DefaultCodegen implements CodegenConfig {
Schema responseSchema; Schema responseSchema;
if (this.openAPI != null && this.openAPI.getComponents() != null) { if (this.openAPI != null && this.openAPI.getComponents() != null) {
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(response), importMapping); responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(response));
} else { // no model/alias defined } else { // no model/alias defined
responseSchema = ModelUtils.getSchemaFromResponse(response); responseSchema = ModelUtils.getSchemaFromResponse(response);
} }
@@ -4351,7 +4448,7 @@ public class DefaultCodegen implements CodegenConfig {
r.setPattern(toRegularExpression(responseSchema.getPattern())); r.setPattern(toRegularExpression(responseSchema.getPattern()));
} }
CodegenProperty cp = fromProperty("response", responseSchema); CodegenProperty cp = fromProperty("response", responseSchema, false);
r.dataType = getTypeDeclaration(responseSchema); r.dataType = getTypeDeclaration(responseSchema);
if (!ModelUtils.isArraySchema(responseSchema)) { if (!ModelUtils.isArraySchema(responseSchema)) {
@@ -4374,7 +4471,7 @@ public class DefaultCodegen implements CodegenConfig {
r.isArray = true; r.isArray = true;
r.containerType = cp.containerType; r.containerType = cp.containerType;
ArraySchema as = (ArraySchema) responseSchema; ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty items = fromProperty("response", getSchemaItems(as)); CodegenProperty items = fromProperty("response", getSchemaItems(as), false);
r.setItems(items); r.setItems(items);
CodegenProperty innerCp = items; CodegenProperty innerCp = items;
@@ -4533,7 +4630,7 @@ public class DefaultCodegen implements CodegenConfig {
private void updateParameterForMap(CodegenParameter codegenParameter, Schema parameterSchema, Set<String> imports) { private void updateParameterForMap(CodegenParameter codegenParameter, Schema parameterSchema, Set<String> imports) {
CodegenProperty codegenProperty = fromProperty("inner", getAdditionalProperties(parameterSchema)); CodegenProperty codegenProperty = fromProperty("inner", getAdditionalProperties(parameterSchema), false);
codegenParameter.items = codegenProperty; codegenParameter.items = codegenProperty;
codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; codegenParameter.mostInnerItems = codegenProperty.mostInnerItems;
codegenParameter.baseType = codegenProperty.dataType; codegenParameter.baseType = codegenProperty.dataType;
@@ -4615,17 +4712,17 @@ public class DefaultCodegen implements CodegenConfig {
String parameterModelName = null; String parameterModelName = null;
if (parameter.getSchema() != null) { if (parameter.getSchema() != null) {
parameterSchema = parameter.getSchema(); parameterSchema = unaliasSchema(parameter.getSchema());
parameterModelName = getParameterDataType(parameter, parameterSchema); parameterModelName = getParameterDataType(parameter, parameterSchema);
CodegenProperty prop; CodegenProperty prop;
if (this instanceof RustServerCodegen) { if (this instanceof RustServerCodegen) {
// for rust server, we need to do somethings special as it uses // for rust server, we need to do somethings special as it uses
// $ref (e.g. #components/schemas/Pet) to determine whether it's a model // $ref (e.g. #components/schemas/Pet) to determine whether it's a model
prop = fromProperty(parameter.getName(), parameterSchema); prop = fromProperty(parameter.getName(), parameterSchema, false);
} else if (getUseInlineModelResolver()) { } else if (getUseInlineModelResolver()) {
prop = fromProperty(parameter.getName(), getReferencedSchemaWhenNotEnum(parameterSchema)); prop = fromProperty(parameter.getName(), getReferencedSchemaWhenNotEnum(parameterSchema), false);
} else { } else {
prop = fromProperty(parameter.getName(), parameterSchema); prop = fromProperty(parameter.getName(), parameterSchema, false);
} }
codegenParameter.setSchema(prop); codegenParameter.setSchema(prop);
} else if (parameter.getContent() != null) { } else if (parameter.getContent() != null) {
@@ -4661,7 +4758,8 @@ public class DefaultCodegen implements CodegenConfig {
return codegenParameter; return codegenParameter;
} }
parameterSchema = unaliasSchema(parameterSchema, Collections.emptyMap()); // TODO need to reivew replacing empty map with schemaMapping instead
parameterSchema = unaliasSchema(parameterSchema);
if (parameterSchema == null) { if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \" {} \"", parameter.getName()); LOGGER.warn("warning! Schema not found for parameter \" {} \"", parameter.getName());
finishUpdatingParameter(codegenParameter, parameter); finishUpdatingParameter(codegenParameter, parameter);
@@ -4747,7 +4845,7 @@ public class DefaultCodegen implements CodegenConfig {
collectionFormat = getCollectionFormat(parameter); collectionFormat = getCollectionFormat(parameter);
// default to csv: // default to csv:
collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat; collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
CodegenProperty itemsProperty = fromProperty("inner", inner); CodegenProperty itemsProperty = fromProperty("inner", inner, false);
codegenParameter.items = itemsProperty; codegenParameter.items = itemsProperty;
codegenParameter.mostInnerItems = itemsProperty.mostInnerItems; codegenParameter.mostInnerItems = itemsProperty.mostInnerItems;
codegenParameter.baseType = itemsProperty.dataType; codegenParameter.baseType = itemsProperty.dataType;
@@ -4763,15 +4861,10 @@ public class DefaultCodegen implements CodegenConfig {
; ;
} }
CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema); CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema, false);
if (Boolean.TRUE.equals(codegenProperty.isModel)) { if (Boolean.TRUE.equals(codegenProperty.isModel)) {
codegenParameter.isModel = true; codegenParameter.isModel = true;
} }
// TODO revise below which seems not working
//if (parameterSchema.getRequired() != null && !parameterSchema.getRequired().isEmpty() && parameterSchema.getRequired().contains(codegenProperty.baseName)) {
codegenProperty.required = Boolean.TRUE.equals(parameter.getRequired()) ? true : false;
//}
//codegenProperty.required = true;
if (parameterModelName != null) { if (parameterModelName != null) {
codegenParameter.dataType = parameterModelName; codegenParameter.dataType = parameterModelName;
@@ -4785,7 +4878,9 @@ public class DefaultCodegen implements CodegenConfig {
imports.add(codegenProperty.baseType); imports.add(codegenProperty.baseType);
} }
codegenParameter.dataFormat = codegenProperty.dataFormat; codegenParameter.dataFormat = codegenProperty.dataFormat;
codegenParameter.required = codegenProperty.required; if (parameter.getRequired() != null) {
codegenParameter.required = parameter.getRequired().booleanValue();
}
if (codegenProperty.isEnum) { if (codegenProperty.isEnum) {
codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum;
@@ -4822,15 +4917,19 @@ public class DefaultCodegen implements CodegenConfig {
if (schema.get$ref() != null) { if (schema.get$ref() != null) {
schema = ModelUtils.getReferencedSchema(openAPI, schema); schema = ModelUtils.getReferencedSchema(openAPI, schema);
} }
codegenParameter.items = fromProperty(codegenParameter.paramName, schema); codegenParameter.items = fromProperty(codegenParameter.paramName, schema, false);
// https://swagger.io/docs/specification/serialization/ // https://swagger.io/docs/specification/serialization/
if (schema != null) { if (schema != null) {
Map<String, Schema<?>> properties = schema.getProperties(); Map<String, Schema<?>> properties = schema.getProperties();
List<String> requiredVarNames = new ArrayList<>();
if (schema.getRequired() != null) {
requiredVarNames.addAll(schema.getRequired());
}
if (properties != null) { if (properties != null) {
codegenParameter.items.vars = codegenParameter.items.vars =
properties.entrySet().stream() properties.entrySet().stream()
.map(entry -> { .map(entry -> {
CodegenProperty property = fromProperty(entry.getKey(), entry.getValue()); CodegenProperty property = fromProperty(entry.getKey(), entry.getValue(), requiredVarNames.contains(entry.getKey()));
property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]"; property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]";
return property; return property;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@@ -4865,7 +4964,7 @@ public class DefaultCodegen implements CodegenConfig {
* @return data type * @return data type
*/ */
protected String getParameterDataType(Parameter parameter, Schema schema) { protected String getParameterDataType(Parameter parameter, Schema schema) {
Schema unaliasSchema = ModelUtils.unaliasSchema(openAPI, schema); Schema unaliasSchema = unaliasSchema(schema);
if (unaliasSchema.get$ref() != null) { if (unaliasSchema.get$ref() != null) {
return toModelName(ModelUtils.getSimpleRef(unaliasSchema.get$ref())); return toModelName(ModelUtils.getSimpleRef(unaliasSchema.get$ref()));
} }
@@ -5109,7 +5208,7 @@ public class DefaultCodegen implements CodegenConfig {
} else { } else {
schema = header.getSchema(); schema = header.getSchema();
} }
CodegenProperty cp = fromProperty(headerEntry.getKey(), schema); CodegenProperty cp = fromProperty(headerEntry.getKey(), schema, false);
cp.setDescription(escapeText(description)); cp.setDescription(escapeText(description));
cp.setUnescapedDescription(description); cp.setUnescapedDescription(description);
if (header.getRequired() != null) { if (header.getRequired() != null) {
@@ -5177,7 +5276,7 @@ public class DefaultCodegen implements CodegenConfig {
* @param schema the input OAS schema. * @param schema the input OAS schema.
*/ */
protected void addParentContainer(CodegenModel model, String name, Schema schema) { protected void addParentContainer(CodegenModel model, String name, Schema schema) {
final CodegenProperty property = fromProperty(name, schema); final CodegenProperty property = fromProperty(name, schema, false);
addImport(model, property.complexType); addImport(model, property.complexType);
model.parent = toInstantiationType(schema); model.parent = toInstantiationType(schema);
final String containerType = property.containerType; final String containerType = property.containerType;
@@ -5230,13 +5329,30 @@ public class DefaultCodegen implements CodegenConfig {
addImport(m.imports, type); addImport(m.imports, type);
} }
private void addImport(Set<String> importsToBeAddedTo, String type) { protected void addImport(Set<String> importsToBeAddedTo, String type) {
if (shouldAddImport(type)) { if (shouldAddImport(type)) {
importsToBeAddedTo.add(type); importsToBeAddedTo.add(type);
} }
} }
private boolean shouldAddImport(String type) { /**
* Add the model name of the child schema in a composed schema to the set of imports
*
* @param composed composed schema
* @param childSchema composed schema
* @param model codegen model
* @param modelName model name
*/
protected void addImport(ComposedSchema composed, Schema childSchema, CodegenModel model, String modelName ) {
// import only if it's not allOf composition schema (without discriminator)
if (!(composed.getAllOf() != null && childSchema.getDiscriminator() == null)) {
addImport(model, modelName);
} else {
LOGGER.debug("Skipped import for allOf composition schema {}", modelName);
}
}
protected boolean shouldAddImport(String type) {
return type != null && needToImport(type); return type != null && needToImport(type);
} }
@@ -5249,7 +5365,7 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, Schema> unaliasPropertySchema(Map<String, Schema> properties) { protected Map<String, Schema> unaliasPropertySchema(Map<String, Schema> properties) {
if (properties != null) { if (properties != null) {
for (String key : properties.keySet()) { for (String key : properties.keySet()) {
properties.put(key, unaliasSchema(properties.get(key), importMapping())); properties.put(key, unaliasSchema(properties.get(key)));
} }
} }
@@ -5326,13 +5442,18 @@ public class DefaultCodegen implements CodegenConfig {
if (prop == null) { if (prop == null) {
LOGGER.warn("Please report the issue. There shouldn't be null property for {}", key); LOGGER.warn("Please report the issue. There shouldn't be null property for {}", key);
} else { } else {
final CodegenProperty cp = fromProperty(key, prop); final CodegenProperty cp = fromProperty(key, prop, mandatory.contains(key));
cp.required = mandatory.contains(key);
vars.add(cp); vars.add(cp);
m.setHasVars(true);
if (cp.required) {
m.setHasRequired(true);
m.getRequiredVars().add(cp);
}
if (cm == null) { if (cm == null) {
continue; continue;
} }
cm.hasRequired = cm.hasRequired || cp.required;
cm.hasOptional = cm.hasOptional || !cp.required; cm.hasOptional = cm.hasOptional || !cp.required;
if (cp.isEnum) { if (cp.isEnum) {
// FIXME: if supporting inheritance, when called a second time for allProperties it is possible for // FIXME: if supporting inheritance, when called a second time for allProperties it is possible for
@@ -5348,9 +5469,7 @@ public class DefaultCodegen implements CodegenConfig {
addImportsForPropertyType(cm, cp); addImportsForPropertyType(cm, cp);
// if required, add to the list "requiredVars" // if required, add to the list "requiredVars"
if (Boolean.TRUE.equals(cp.required)) { if (Boolean.FALSE.equals(cp.required)) {
cm.requiredVars.add(cp);
} else { // else add to the list "optionalVars" for optional property
cm.optionalVars.add(cp); cm.optionalVars.add(cp);
} }
@@ -5361,6 +5480,10 @@ public class DefaultCodegen implements CodegenConfig {
// duplicated properties will be removed by removeAllDuplicatedProperty later // duplicated properties will be removed by removeAllDuplicatedProperty later
cm.readWriteVars.add(cp); cm.readWriteVars.add(cp);
} }
if (Boolean.FALSE.equals(cp.isNullable)){
cm.nonNullableVars.add(cp);
}
} }
} }
return; return;
@@ -5375,9 +5498,18 @@ public class DefaultCodegen implements CodegenConfig {
* @param property The codegen representation of the OAS schema's property. * @param property The codegen representation of the OAS schema's property.
*/ */
protected void addImportsForPropertyType(CodegenModel model, CodegenProperty property) { protected void addImportsForPropertyType(CodegenModel model, CodegenProperty property) {
if (property.isContainer) { if (property.isArray) {
if (property.getUniqueItems()) { // set
addImport(model.imports, typeMapping.get("set"));
} else { // array
addImport(model.imports, typeMapping.get("array")); addImport(model.imports, typeMapping.get("array"));
} }
}
if (property.isMap) { // map
addImport(model.imports, typeMapping.get("map"));
}
addImports(model, property); addImports(model, property);
} }
@@ -6180,7 +6312,7 @@ public class DefaultCodegen implements CodegenConfig {
// skip as it implies `consumes` in OAS2 is not defined // skip as it implies `consumes` in OAS2 is not defined
continue; continue;
} else { } else {
mediaType.put("mediaType", escapeText(escapeQuotationMark(key))); mediaType.put("mediaType", escapeQuotationMark(key));
} }
mediaTypeList.add(mediaType); mediaTypeList.add(mediaType);
} }
@@ -6246,7 +6378,7 @@ public class DefaultCodegen implements CodegenConfig {
for (String key : produces) { for (String key : produces) {
// escape quotation to avoid code injection, "*/*" is a special case, do nothing // escape quotation to avoid code injection, "*/*" is a special case, do nothing
String encodedKey = "*/*".equals(key) ? key : escapeText(escapeQuotationMark(key)); String encodedKey = "*/*".equals(key) ? key : escapeQuotationMark(key);
//Only unique media types should be added to "produces" //Only unique media types should be added to "produces"
if (!existingMediaTypes.contains(encodedKey)) { if (!existingMediaTypes.contains(encodedKey)) {
Map<String, String> mediaType = new HashMap<>(); Map<String, String> mediaType = new HashMap<>();
@@ -6357,9 +6489,9 @@ public class DefaultCodegen implements CodegenConfig {
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER); CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
LOGGER.debug("Debugging fromFormProperty {}: {}", name, propertySchema); LOGGER.debug("Debugging fromFormProperty {}: {}", name, propertySchema);
CodegenProperty codegenProperty = fromProperty(name, propertySchema); CodegenProperty codegenProperty = fromProperty(name, propertySchema, false);
Schema ps = unaliasSchema(propertySchema, importMapping); Schema ps = unaliasSchema(propertySchema);
ModelUtils.syncValidationProperties(ps, codegenParameter); ModelUtils.syncValidationProperties(ps, codegenParameter);
codegenParameter.setTypeProperties(ps); codegenParameter.setTypeProperties(ps);
codegenParameter.setComposedSchemas(getComposedSchemas(ps)); codegenParameter.setComposedSchemas(getComposedSchemas(ps));
@@ -6443,7 +6575,7 @@ public class DefaultCodegen implements CodegenConfig {
; ;
} else if (ModelUtils.isArraySchema(ps)) { } else if (ModelUtils.isArraySchema(ps)) {
Schema inner = getSchemaItems((ArraySchema) ps); Schema inner = getSchemaItems((ArraySchema) ps);
CodegenProperty arrayInnerProperty = fromProperty("inner", inner); CodegenProperty arrayInnerProperty = fromProperty("inner", inner, false);
codegenParameter.items = arrayInnerProperty; codegenParameter.items = arrayInnerProperty;
codegenParameter.mostInnerItems = arrayInnerProperty.mostInnerItems; codegenParameter.mostInnerItems = arrayInnerProperty.mostInnerItems;
codegenParameter.isPrimitiveType = false; codegenParameter.isPrimitiveType = false;
@@ -6538,7 +6670,7 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.isNullable = codegenModel.isNullable; codegenParameter.isNullable = codegenModel.isNullable;
imports.add(codegenParameter.baseType); imports.add(codegenParameter.baseType);
} else { } else {
CodegenProperty codegenProperty = fromProperty("property", schema); CodegenProperty codegenProperty = fromProperty("property", schema, false);
if (codegenProperty != null && codegenProperty.getComplexType() != null && codegenProperty.getComplexType().contains(" | ")) { if (codegenProperty != null && codegenProperty.getComplexType() != null && codegenProperty.getComplexType().contains(" | ")) {
List<String> parts = Arrays.asList(codegenProperty.getComplexType().split(" \\| ")); List<String> parts = Arrays.asList(codegenProperty.getComplexType().split(" \\| "));
@@ -6603,7 +6735,7 @@ public class DefaultCodegen implements CodegenConfig {
inner = new StringSchema().description("//TODO automatically added by openapi-generator"); inner = new StringSchema().description("//TODO automatically added by openapi-generator");
schema.setAdditionalProperties(inner); schema.setAdditionalProperties(inner);
} }
CodegenProperty codegenProperty = fromProperty("property", schema); CodegenProperty codegenProperty = fromProperty("property", schema, false);
imports.add(codegenProperty.baseType); imports.add(codegenProperty.baseType);
@@ -6635,7 +6767,7 @@ public class DefaultCodegen implements CodegenConfig {
} }
protected void updateRequestBodyForPrimitiveType(CodegenParameter codegenParameter, Schema schema, String bodyParameterName, Set<String> imports) { protected void updateRequestBodyForPrimitiveType(CodegenParameter codegenParameter, Schema schema, String bodyParameterName, Set<String> imports) {
CodegenProperty codegenProperty = fromProperty("PRIMITIVE_REQUEST_BODY", schema); CodegenProperty codegenProperty = fromProperty("PRIMITIVE_REQUEST_BODY", schema, false);
if (codegenProperty != null) { if (codegenProperty != null) {
if (StringUtils.isEmpty(bodyParameterName)) { if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "body"; // default to body codegenParameter.baseName = "body"; // default to body
@@ -6669,7 +6801,7 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.isFreeFormObject = true; codegenParameter.isFreeFormObject = true;
// HTTP request body is free form object // HTTP request body is free form object
CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema); CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema, false);
if (codegenProperty != null) { if (codegenProperty != null) {
if (StringUtils.isEmpty(bodyParameterName)) { if (StringUtils.isEmpty(bodyParameterName)) {
codegenParameter.baseName = "body"; // default to body codegenParameter.baseName = "body"; // default to body
@@ -6698,7 +6830,7 @@ public class DefaultCodegen implements CodegenConfig {
} else { } else {
final ArraySchema arraySchema = (ArraySchema) schema; final ArraySchema arraySchema = (ArraySchema) schema;
Schema inner = getSchemaItems(arraySchema); Schema inner = getSchemaItems(arraySchema);
CodegenProperty codegenProperty = fromProperty("property", arraySchema); CodegenProperty codegenProperty = fromProperty("property", arraySchema, false);
imports.add(codegenProperty.baseType); imports.add(codegenProperty.baseType);
CodegenProperty innerCp = codegenProperty; CodegenProperty innerCp = codegenProperty;
CodegenProperty mostInnerItem = innerCp; CodegenProperty mostInnerItem = innerCp;
@@ -6822,8 +6954,8 @@ public class DefaultCodegen implements CodegenConfig {
enc.getContentType(), enc.getContentType(),
headers, headers,
enc.getStyle().toString(), enc.getStyle().toString(),
enc.getExplode().booleanValue(), enc.getExplode() == null ? false : enc.getExplode().booleanValue(),
enc.getAllowReserved().booleanValue() enc.getAllowReserved() == null ? false : enc.getAllowReserved().booleanValue()
); );
String propName = encodingEntry.getKey(); String propName = encodingEntry.getKey();
ceMap.put(propName, ce); ceMap.put(propName, ce);
@@ -6832,7 +6964,7 @@ public class DefaultCodegen implements CodegenConfig {
String contentType = contentEntry.getKey(); String contentType = contentEntry.getKey();
CodegenProperty schemaProp = null; CodegenProperty schemaProp = null;
if (mt.getSchema() != null) { if (mt.getSchema() != null) {
schemaProp = fromProperty(toMediaTypeSchemaName(contentType, mediaTypeSchemaSuffix), mt.getSchema()); schemaProp = fromProperty(toMediaTypeSchemaName(contentType, mediaTypeSchemaSuffix), mt.getSchema(), false);
} }
CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap); CodegenMediaType codegenMt = new CodegenMediaType(schemaProp, ceMap);
cmtContent.put(contentType, codegenMt); cmtContent.put(contentType, codegenMt);
@@ -6870,7 +7002,7 @@ public class DefaultCodegen implements CodegenConfig {
name = ModelUtils.getSimpleRef(schema.get$ref()); name = ModelUtils.getSimpleRef(schema.get$ref());
} }
Schema unaliasedSchema = unaliasSchema(schema, importMapping); Schema unaliasedSchema = unaliasSchema(schema);
schema = ModelUtils.getReferencedSchema(this.openAPI, schema); schema = ModelUtils.getReferencedSchema(this.openAPI, schema);
ModelUtils.syncValidationProperties(unaliasedSchema, codegenParameter); ModelUtils.syncValidationProperties(unaliasedSchema, codegenParameter);
@@ -6939,27 +7071,9 @@ public class DefaultCodegen implements CodegenConfig {
protected void addVarsRequiredVarsAdditionalProps(Schema schema, IJsonSchemaValidationProperties property) { protected void addVarsRequiredVarsAdditionalProps(Schema schema, IJsonSchemaValidationProperties property) {
setAddProps(schema, property); setAddProps(schema, property);
if (!"object".equals(schema.getType())) { Set<String> mandatory = schema.getRequired() == null ? Collections.emptySet()
return; : new TreeSet<>(schema.getRequired());
} addVars(property, property.getVars(), schema.getProperties(), mandatory);
if (schema instanceof ObjectSchema) {
ObjectSchema objSchema = (ObjectSchema) schema;
HashSet<String> requiredVars = new HashSet<>();
if (objSchema.getRequired() != null) {
requiredVars.addAll(objSchema.getRequired());
}
if (objSchema.getProperties() != null && objSchema.getProperties().size() > 0) {
property.setHasVars(true);
}
addVars(property, property.getVars(), objSchema.getProperties(), requiredVars);
List<CodegenProperty> requireCpVars = property.getVars()
.stream()
.filter(p -> Boolean.TRUE.equals(p.required)).collect(Collectors.toList());
property.setRequiredVars(requireCpVars);
if (property.getRequiredVars() != null && property.getRequiredVars().size() > 0) {
property.setHasRequired(true);
}
}
} }
private void addJsonSchemaForBodyRequestInCaseItsNotPresent(CodegenParameter codegenParameter, RequestBody body) { private void addJsonSchemaForBodyRequestInCaseItsNotPresent(CodegenParameter codegenParameter, RequestBody body) {
@@ -7466,7 +7580,7 @@ public class DefaultCodegen implements CodegenConfig {
Schema notSchema = schema.getNot(); Schema notSchema = schema.getNot();
CodegenProperty notProperty = null; CodegenProperty notProperty = null;
if (notSchema != null) { if (notSchema != null) {
notProperty = fromProperty("NotSchema", notSchema); notProperty = fromProperty("NotSchema", notSchema, false);
} }
List<CodegenProperty> allOf = new ArrayList<>(); List<CodegenProperty> allOf = new ArrayList<>();
List<CodegenProperty> oneOf = new ArrayList<>(); List<CodegenProperty> oneOf = new ArrayList<>();
@@ -7492,7 +7606,7 @@ public class DefaultCodegen implements CodegenConfig {
List<CodegenProperty> xOf = new ArrayList<>(); List<CodegenProperty> xOf = new ArrayList<>();
int i = 0; int i = 0;
for (Schema xOfSchema : xOfCollection) { for (Schema xOfSchema : xOfCollection) {
CodegenProperty cp = fromProperty(collectionName + "_" + i, xOfSchema); CodegenProperty cp = fromProperty(collectionName + "_" + i, xOfSchema, false);
xOf.add(cp); xOf.add(cp);
i += 1; i += 1;
} }

View File

@@ -441,6 +441,19 @@ public class DefaultGenerator implements Generator {
// process models only // process models only
for (String name : modelKeys) { for (String name : modelKeys) {
try { try {
//don't generate models that have an import mapping
if (config.schemaMapping().containsKey(name)) {
LOGGER.debug("Model {} not imported due to import mapping", name);
for (String templateName : config.modelTemplateFiles().keySet()) {
// HACK: Because this returns early, could lead to some invalid model reporting.
String filename = config.modelFilename(templateName, name);
Path path = java.nio.file.Paths.get(filename);
this.templateProcessor.skip(path,"Skipped prior to model processing due to schema mapping." );
}
continue;
}
// don't generate models that are not used as object (e.g. form parameters) // don't generate models that are not used as object (e.g. form parameters)
if (unusedModels.contains(name)) { if (unusedModels.contains(name)) {
if (Boolean.FALSE.equals(skipFormModel)) { if (Boolean.FALSE.equals(skipFormModel)) {
@@ -464,7 +477,7 @@ public class DefaultGenerator implements Generator {
// generators may choose to make models for use case 2 + 3 // generators may choose to make models for use case 2 + 3
Schema refSchema = new Schema(); Schema refSchema = new Schema();
refSchema.set$ref("#/components/schemas/" + name); refSchema.set$ref("#/components/schemas/" + name);
Schema unaliasedSchema = config.unaliasSchema(refSchema, config.importMapping()); Schema unaliasedSchema = config.unaliasSchema(refSchema);
if (unaliasedSchema.get$ref() == null) { if (unaliasedSchema.get$ref() == null) {
LOGGER.info("Model {} not generated since it's a free-form object", name); LOGGER.info("Model {} not generated since it's a free-form object", name);
continue; continue;
@@ -508,6 +521,11 @@ public class DefaultGenerator implements Generator {
ModelsMap models = allProcessedModels.get(modelName); ModelsMap models = allProcessedModels.get(modelName);
models.put("modelPackage", config.modelPackage()); models.put("modelPackage", config.modelPackage());
try { try {
//don't generate models that have a schema mapping
if (config.schemaMapping().containsKey(modelName)) {
continue;
}
// TODO revise below as we've already performed unaliasing so that the isAlias check may be removed // TODO revise below as we've already performed unaliasing so that the isAlias check may be removed
List<ModelMap> modelList = models.getModels(); List<ModelMap> modelList = models.getModels();
if (modelList != null && !modelList.isEmpty()) { if (modelList != null && !modelList.isEmpty()) {
@@ -875,6 +893,7 @@ public class DefaultGenerator implements Generator {
if (config.getUseInlineModelResolver()) { if (config.getUseInlineModelResolver()) {
InlineModelResolver inlineModelResolver = new InlineModelResolver(); InlineModelResolver inlineModelResolver = new InlineModelResolver();
inlineModelResolver.setInlineSchemaNameMapping(config.inlineSchemaNameMapping()); inlineModelResolver.setInlineSchemaNameMapping(config.inlineSchemaNameMapping());
inlineModelResolver.setInlineSchemaNameDefaults(config.inlineSchemaNameDefault());
inlineModelResolver.flatten(openAPI); inlineModelResolver.flatten(openAPI);
} }

View File

@@ -129,7 +129,7 @@ public interface IJsonSchemaValidationProperties {
boolean getHasVars(); boolean getHasVars();
void setHasVars(boolean hasRequiredVars); void setHasVars(boolean hasVars);
boolean getHasRequired(); boolean getHasRequired();

View File

@@ -42,6 +42,7 @@ public class InlineModelResolver {
private Map<String, Schema> addedModels = new HashMap<>(); private Map<String, Schema> addedModels = new HashMap<>();
private Map<String, String> generatedSignature = new HashMap<>(); private Map<String, String> generatedSignature = new HashMap<>();
private Map<String, String> inlineSchemaNameMapping = new HashMap<>(); private Map<String, String> inlineSchemaNameMapping = new HashMap<>();
private Map<String, String> inlineSchemaNameDefaults = new HashMap<>();
private Set<String> inlineSchemaNameMappingValues = new HashSet<>(); private Set<String> inlineSchemaNameMappingValues = new HashSet<>();
public boolean resolveInlineEnums = false; public boolean resolveInlineEnums = false;
@@ -60,11 +61,20 @@ public class InlineModelResolver {
final Logger LOGGER = LoggerFactory.getLogger(InlineModelResolver.class); final Logger LOGGER = LoggerFactory.getLogger(InlineModelResolver.class);
public InlineModelResolver() {
this.inlineSchemaNameDefaults.put("arrayItemSuffix", "_inner");
this.inlineSchemaNameDefaults.put("mapItemSuffix", "_value");
}
public void setInlineSchemaNameMapping(Map inlineSchemaNameMapping) { public void setInlineSchemaNameMapping(Map inlineSchemaNameMapping) {
this.inlineSchemaNameMapping = inlineSchemaNameMapping; this.inlineSchemaNameMapping = inlineSchemaNameMapping;
this.inlineSchemaNameMappingValues = new HashSet<>(inlineSchemaNameMapping.values()); this.inlineSchemaNameMappingValues = new HashSet<>(inlineSchemaNameMapping.values());
} }
public void setInlineSchemaNameDefaults(Map inlineSchemaNameDefaults) {
this.inlineSchemaNameDefaults.putAll(inlineSchemaNameDefaults);
}
void flatten(OpenAPI openAPI) { void flatten(OpenAPI openAPI) {
this.openAPI = openAPI; this.openAPI = openAPI;
@@ -147,6 +157,26 @@ public class InlineModelResolver {
* @param schema target schema * @param schema target schema
*/ */
private boolean isModelNeeded(Schema schema) { private boolean isModelNeeded(Schema schema) {
return isModelNeeded(schema, new HashSet<>());
}
/**
* Return false if model can be represented by primitives e.g. string, object
* without properties, array or map of other model (model contanier), etc.
* <p>
* Return true if a model should be generated e.g. object with properties,
* enum, oneOf, allOf, anyOf, etc.
*
* @param schema target schema
* @param visitedSchemas Visited schemas
*/
private boolean isModelNeeded(Schema schema, Set<Schema> visitedSchemas) {
if (visitedSchemas.contains(schema)) { // circular reference
return true;
} else {
visitedSchemas.add(schema);
}
if (resolveInlineEnums && schema.getEnum() != null && schema.getEnum().size() > 0) { if (resolveInlineEnums && schema.getEnum() != null && schema.getEnum().size() > 0) {
return true; return true;
} }
@@ -162,7 +192,7 @@ public class InlineModelResolver {
if (m.getAllOf() != null && !m.getAllOf().isEmpty()) { if (m.getAllOf() != null && !m.getAllOf().isEmpty()) {
// check to ensure at least of the allOf item is model // check to ensure at least of the allOf item is model
for (Schema inner : m.getAllOf()) { for (Schema inner : m.getAllOf()) {
if (isModelNeeded(ModelUtils.getReferencedSchema(openAPI, inner))) { if (isModelNeeded(ModelUtils.getReferencedSchema(openAPI, inner), visitedSchemas)) {
return true; return true;
} }
} }
@@ -230,7 +260,7 @@ public class InlineModelResolver {
if (schema.getAdditionalProperties() != null) { if (schema.getAdditionalProperties() != null) {
if (schema.getAdditionalProperties() instanceof Schema) { if (schema.getAdditionalProperties() instanceof Schema) {
Schema inner = (Schema) schema.getAdditionalProperties(); Schema inner = (Schema) schema.getAdditionalProperties();
String schemaName = resolveModelName(schema.getTitle(), modelPrefix + "_value"); String schemaName = resolveModelName(schema.getTitle(), modelPrefix + this.inlineSchemaNameDefaults.get("mapItemSuffix"));
// Recurse to create $refs for inner models // Recurse to create $refs for inner models
gatherInlineModels(inner, schemaName); gatherInlineModels(inner, schemaName);
if (isModelNeeded(inner)) { if (isModelNeeded(inner)) {
@@ -265,7 +295,7 @@ public class InlineModelResolver {
" items must be defined for array schemas:\n " + schema.toString()); " items must be defined for array schemas:\n " + schema.toString());
return; return;
} }
String schemaName = resolveModelName(items.getTitle(), modelPrefix + "_inner"); String schemaName = resolveModelName(items.getTitle(), modelPrefix + this.inlineSchemaNameDefaults.get("arrayItemSuffix"));
// Recurse to create $refs for inner models // Recurse to create $refs for inner models
gatherInlineModels(items, schemaName); gatherInlineModels(items, schemaName);

View File

@@ -0,0 +1,62 @@
package org.openapitools.codegen;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
public class ObjectWithTypeBooleans {
public boolean isUnboundedInteger;
public boolean isNumber;
public boolean isString;
public boolean isMap;
public boolean isArray;
public boolean isBoolean;
public boolean isNull;
public Object value;
/**
* A wrapper class that is used to store payloads to be ingested by schemas
* This class includes the payload value in the value property
* Other booleans: isUnboundedInteger/isNumber/isString/isMap/isArray/isBoolean/isNull
* allow generator templates to decide how to render each payload into code
* based upon what type it is. The booleans isX describe the value in value.
* @param value the input payload that is stored
*/
public ObjectWithTypeBooleans(Object value) {
Object usedValue = null;
if (value instanceof Integer){
this.isUnboundedInteger = true;
this.value = value;
} else if (value instanceof Double || value instanceof Float){
this.isNumber = true;
this.value = value;
} else if (value instanceof String) {
this.isString = true;
this.value = value;
} else if (value instanceof LinkedHashMap) {
LinkedHashMap<String, Object> castValue = (LinkedHashMap<String, Object>) value;
LinkedHashMap<ObjectWithTypeBooleans, ObjectWithTypeBooleans> castMap = new LinkedHashMap<>();
for (Map.Entry entry: castValue.entrySet()) {
ObjectWithTypeBooleans entryKey = new ObjectWithTypeBooleans(entry.getKey());
ObjectWithTypeBooleans entryValue = new ObjectWithTypeBooleans(entry.getValue());
castMap.put(entryKey, entryValue);
}
this.value = castMap;
this.isMap = true;
} else if (value instanceof ArrayList) {
ArrayList<ObjectWithTypeBooleans> castList = new ArrayList<>();
for (Object item: (ArrayList<Object>) value) {
castList.add(new ObjectWithTypeBooleans(item));
}
this.value = castList;
this.isArray = true;
} else if (value instanceof Boolean) {
this.isBoolean = true;
this.value = value;
} else if (value == null) {
this.isNull = true;
this.value = value;
}
}
}

View File

@@ -0,0 +1,14 @@
package org.openapitools.codegen;
public class SchemaTestCase {
public String description;
public ObjectWithTypeBooleans data;
// true means the test case should pass, false means it should fail
public boolean valid;
public SchemaTestCase(String description, ObjectWithTypeBooleans data, boolean valid) {
this.description = description;
this.data = data;
this.valid = valid;
}
}

View File

@@ -68,7 +68,9 @@ public class CodegenConfigurator {
private Map<String, String> typeMappings = new HashMap<>(); private Map<String, String> typeMappings = new HashMap<>();
private Map<String, Object> additionalProperties = new HashMap<>(); private Map<String, Object> additionalProperties = new HashMap<>();
private Map<String, String> importMappings = new HashMap<>(); private Map<String, String> importMappings = new HashMap<>();
private Map<String, String> schemaMappings = new HashMap<>();
private Map<String, String> inlineSchemaNameMappings = new HashMap<>(); private Map<String, String> inlineSchemaNameMappings = new HashMap<>();
private Map<String, String> inlineSchemaNameDefaults = new HashMap<>();
private Set<String> languageSpecificPrimitives = new HashSet<>(); private Set<String> languageSpecificPrimitives = new HashSet<>();
private Map<String, String> reservedWordsMappings = new HashMap<>(); private Map<String, String> reservedWordsMappings = new HashMap<>();
private Map<String, String> serverVariables = new HashMap<>(); private Map<String, String> serverVariables = new HashMap<>();
@@ -112,9 +114,15 @@ public class CodegenConfigurator {
if(generatorSettings.getImportMappings() != null) { if(generatorSettings.getImportMappings() != null) {
configurator.importMappings.putAll(generatorSettings.getImportMappings()); configurator.importMappings.putAll(generatorSettings.getImportMappings());
} }
if(generatorSettings.getSchemaMappings() != null) {
configurator.schemaMappings.putAll(generatorSettings.getSchemaMappings());
}
if(generatorSettings.getInlineSchemaNameMappings() != null) { if(generatorSettings.getInlineSchemaNameMappings() != null) {
configurator.inlineSchemaNameMappings.putAll(generatorSettings.getInlineSchemaNameMappings()); configurator.inlineSchemaNameMappings.putAll(generatorSettings.getInlineSchemaNameMappings());
} }
if(generatorSettings.getInlineSchemaNameDefaults() != null) {
configurator.inlineSchemaNameDefaults.putAll(generatorSettings.getInlineSchemaNameDefaults());
}
if(generatorSettings.getLanguageSpecificPrimitives() != null) { if(generatorSettings.getLanguageSpecificPrimitives() != null) {
configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives()); configurator.languageSpecificPrimitives.addAll(generatorSettings.getLanguageSpecificPrimitives());
} }
@@ -184,12 +192,24 @@ public class CodegenConfigurator {
return this; return this;
} }
public CodegenConfigurator addSchemaMapping(String key, String value) {
this.schemaMappings.put(key, value);
generatorSettingsBuilder.withSchemaMapping(key, value);
return this;
}
public CodegenConfigurator addInlineSchemaNameMapping(String key, String value) { public CodegenConfigurator addInlineSchemaNameMapping(String key, String value) {
this.inlineSchemaNameMappings.put(key, value); this.inlineSchemaNameMappings.put(key, value);
generatorSettingsBuilder.withInlineSchemaNameMapping(key, value); generatorSettingsBuilder.withInlineSchemaNameMapping(key, value);
return this; return this;
} }
public CodegenConfigurator addInlineSchemaNameDefault(String key, String value) {
this.inlineSchemaNameDefaults.put(key, value);
generatorSettingsBuilder.withInlineSchemaNameDefault(key, value);
return this;
}
public CodegenConfigurator addInstantiationType(String key, String value) { public CodegenConfigurator addInstantiationType(String key, String value) {
this.instantiationTypes.put(key, value); this.instantiationTypes.put(key, value);
generatorSettingsBuilder.withInstantiationType(key, value); generatorSettingsBuilder.withInstantiationType(key, value);
@@ -344,12 +364,24 @@ public class CodegenConfigurator {
return this; return this;
} }
public CodegenConfigurator setSchemaMappings(Map<String, String> schemaMappings) {
this.schemaMappings = schemaMappings;
generatorSettingsBuilder.withSchemaMappings(schemaMappings);
return this;
}
public CodegenConfigurator setInlineSchemaNameMappings(Map<String, String> inlineSchemaNameMappings) { public CodegenConfigurator setInlineSchemaNameMappings(Map<String, String> inlineSchemaNameMappings) {
this.inlineSchemaNameMappings = inlineSchemaNameMappings; this.inlineSchemaNameMappings = inlineSchemaNameMappings;
generatorSettingsBuilder.withInlineSchemaNameMappings(inlineSchemaNameMappings); generatorSettingsBuilder.withInlineSchemaNameMappings(inlineSchemaNameMappings);
return this; return this;
} }
public CodegenConfigurator setInlineSchemaNameDefaults(Map<String, String> inlineSchemaNameDefaults) {
this.inlineSchemaNameDefaults = inlineSchemaNameDefaults;
generatorSettingsBuilder.withInlineSchemaNameDefaults(inlineSchemaNameDefaults);
return this;
}
public CodegenConfigurator setInputSpec(String inputSpec) { public CodegenConfigurator setInputSpec(String inputSpec) {
this.inputSpec = inputSpec; this.inputSpec = inputSpec;
workflowSettingsBuilder.withInputSpec(inputSpec); workflowSettingsBuilder.withInputSpec(inputSpec);
@@ -626,7 +658,9 @@ public class CodegenConfigurator {
config.instantiationTypes().putAll(generatorSettings.getInstantiationTypes()); config.instantiationTypes().putAll(generatorSettings.getInstantiationTypes());
config.typeMapping().putAll(generatorSettings.getTypeMappings()); config.typeMapping().putAll(generatorSettings.getTypeMappings());
config.importMapping().putAll(generatorSettings.getImportMappings()); config.importMapping().putAll(generatorSettings.getImportMappings());
config.schemaMapping().putAll(generatorSettings.getSchemaMappings());
config.inlineSchemaNameMapping().putAll(generatorSettings.getInlineSchemaNameMappings()); config.inlineSchemaNameMapping().putAll(generatorSettings.getInlineSchemaNameMappings());
config.inlineSchemaNameDefault().putAll(generatorSettings.getInlineSchemaNameDefaults());
config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives()); config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives());
config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings()); config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings());
config.additionalProperties().putAll(generatorSettings.getAdditionalProperties()); config.additionalProperties().putAll(generatorSettings.getAdditionalProperties());

View File

@@ -81,6 +81,19 @@ public final class CodegenConfiguratorUtils {
} }
} }
public static void applySchemaMappingsKvpList(List<String> schemaMappings, CodegenConfigurator configurator) {
for (String propString : schemaMappings) {
applySchemaMappingsKvp(propString, configurator);
}
}
public static void applySchemaMappingsKvp(String schemaMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(schemaMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addSchemaMapping(entry.getKey().trim(), entry.getValue().trim());
}
}
public static void applyInlineSchemaNameMappingsKvpList(List<String> inlineSchemaNameMappings, CodegenConfigurator configurator) { public static void applyInlineSchemaNameMappingsKvpList(List<String> inlineSchemaNameMappings, CodegenConfigurator configurator) {
for (String propString : inlineSchemaNameMappings) { for (String propString : inlineSchemaNameMappings) {
applyInlineSchemaNameMappingsKvp(propString, configurator); applyInlineSchemaNameMappingsKvp(propString, configurator);
@@ -94,6 +107,19 @@ public final class CodegenConfiguratorUtils {
} }
} }
public static void applyInlineSchemaNameDefaultsKvpList(List<String> inlineSchemaNameDefaults, CodegenConfigurator configurator) {
for (String propString : inlineSchemaNameDefaults) {
applyInlineSchemaNameDefaultsKvp(propString, configurator);
}
}
public static void applyInlineSchemaNameDefaultsKvp(String inlineSchemaNameDefaults, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(inlineSchemaNameDefaults);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addInlineSchemaNameDefault(entry.getKey().trim(), entry.getValue().trim());
}
}
public static void applyTypeMappingsKvpList(List<String> typeMappings, CodegenConfigurator configurator) { public static void applyTypeMappingsKvpList(List<String> typeMappings, CodegenConfigurator configurator) {
for (String propString : typeMappings) { for (String propString : typeMappings) {
applyTypeMappingsKvp(propString, configurator); applyTypeMappingsKvp(propString, configurator);

View File

@@ -170,6 +170,9 @@ public class ExampleGenerator {
kv.put(EXAMPLE, example); kv.put(EXAMPLE, example);
output.add(kv); output.add(kv);
} }
} else {
kv.put(EXAMPLE, "Custom MIME type example not yet supported: " + mediaType);
output.add(kv);
} }
} }
} else { } else {

View File

@@ -385,8 +385,8 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
} }
@Override @Override
public CodegenProperty fromProperty(String name, Schema p) { public CodegenProperty fromProperty(String name, Schema p, boolean required) {
CodegenProperty property = super.fromProperty(name, p); CodegenProperty property = super.fromProperty(name, p, required);
if (property != null) { if (property != null) {
String nameInCamelCase = property.nameInCamelCase; String nameInCamelCase = property.nameInCamelCase;
nameInCamelCase = sanitizeName(nameInCamelCase); nameInCamelCase = sanitizeName(nameInCamelCase);
@@ -566,7 +566,7 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
if (operation.getResponses() != null && !operation.getResponses().isEmpty()) { if (operation.getResponses() != null && !operation.getResponses().isEmpty()) {
ApiResponse methodResponse = findMethodResponse(operation.getResponses()); ApiResponse methodResponse = findMethodResponse(operation.getResponses());
if (methodResponse != null && ModelUtils.getSchemaFromResponse(methodResponse) != null) { if (methodResponse != null && ModelUtils.getSchemaFromResponse(methodResponse) != null) {
CodegenProperty cm = fromProperty("response", ModelUtils.getSchemaFromResponse(methodResponse)); CodegenProperty cm = fromProperty("response", ModelUtils.getSchemaFromResponse(methodResponse), false);
op.vendorExtensions.put("x-codegen-response", cm); op.vendorExtensions.put("x-codegen-response", cm);
op.vendorExtensions.put("x-is-model-type", isModelType(cm)); op.vendorExtensions.put("x-is-model-type", isModelType(cm));
op.vendorExtensions.put("x-is-stream-type", isStreamType(cm)); op.vendorExtensions.put("x-is-stream-type", isStreamType(cm));

View File

@@ -1070,10 +1070,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
@Override @Override
public String toModelName(String name) { public String toModelName(String name) {
// We need to check if import-mapping has a different model for this class, so we use it // We need to check if schema-mapping has a different model for this class, so we use it
// instead of the auto-generated one. // instead of the auto-generated one.
if (importMapping.containsKey(name)) { if (schemaMapping.containsKey(name)) {
return importMapping.get(name); return schemaMapping.get(name);
} }
// memoization and lookup in the cache // memoization and lookup in the cache
@@ -1410,8 +1410,15 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
} else { } else {
example = "new List<" + p.items.dataType + ">()"; example = "new List<" + p.items.dataType + ">()";
} }
} else if (Boolean.TRUE.equals(p.isModel)) {
example = "new " + p.dataType + "()";
} else if (Boolean.TRUE.equals(p.isMap)) { } else if (Boolean.TRUE.equals(p.isMap)) {
if (p.items != null) {
example = "new Dictionary<String, " + p.items.dataType + ">"; example = "new Dictionary<String, " + p.items.dataType + ">";
} else {
// default to String if item is not defined
example = "new Dictionary<String, String>";
}
} }
p.example = example; p.example = example;

View File

@@ -251,8 +251,8 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public CodegenProperty fromProperty(String name, Schema p) { public CodegenProperty fromProperty(String name, Schema p, boolean required) {
CodegenProperty property = super.fromProperty(name, p); CodegenProperty property = super.fromProperty(name, p, required);
String nameInCamelCase = property.nameInCamelCase; String nameInCamelCase = property.nameInCamelCase;
if (nameInCamelCase.length() > 1) { if (nameInCamelCase.length() > 1) {
nameInCamelCase = sanitizeName(Character.toLowerCase(nameInCamelCase.charAt(0)) + nameInCamelCase.substring(1)); nameInCamelCase = sanitizeName(Character.toLowerCase(nameInCamelCase.charAt(0)) + nameInCamelCase.substring(1));

View File

@@ -109,7 +109,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
apiTestTemplateFiles.put("api_test.mustache", ".dart"); apiTestTemplateFiles.put("api_test.mustache", ".dart");
final List<String> reservedWordsList = new ArrayList<>(); final List<String> reservedWordsList = new ArrayList<>();
try(BufferedReader reader = new BufferedReader( try (BufferedReader reader = new BufferedReader(
new InputStreamReader(DartClientCodegen.class.getResourceAsStream("/dart/dart-keywords.txt"), new InputStreamReader(DartClientCodegen.class.getResourceAsStream("/dart/dart-keywords.txt"),
StandardCharsets.UTF_8))) { StandardCharsets.UTF_8))) {
while (reader.ready()) { while (reader.ready()) {
@@ -445,7 +445,8 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
return underscore(toModelName(name)); return underscore(toModelName(name));
} }
@Override public String toModelDocFilename(String name) { @Override
public String toModelDocFilename(String name) {
return toModelName(name); return toModelName(name);
} }
@@ -488,7 +489,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
@Override @Override
public String getTypeDeclaration(Schema p) { public String getTypeDeclaration(Schema p) {
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping); Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema; Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) { if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema); Schema<?> items = getSchemaItems((ArraySchema) schema);
@@ -551,8 +552,8 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
} }
@Override @Override
public CodegenProperty fromProperty(String name, Schema p) { public CodegenProperty fromProperty(String name, Schema p, boolean required) {
final CodegenProperty property = super.fromProperty(name, p); final CodegenProperty property = super.fromProperty(name, p, required);
// Handle composed properties // Handle composed properties
if (ModelUtils.isComposedSchema(p)) { if (ModelUtils.isComposedSchema(p)) {
@@ -819,5 +820,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen {
} }
@Override @Override
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.DART; } public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.DART;
}
} }

View File

@@ -177,10 +177,10 @@ public abstract class AbstractEiffelCodegen extends DefaultCodegen implements Co
@Override @Override
public String toModelFilename(String name) { public String toModelFilename(String name) {
// We need to check if import-mapping has a different model for this class, so we use it // We need to check if schema-mapping has a different model for this class, so we use it
// instead of the auto-generated one. // instead of the auto-generated one.
if (importMapping.containsKey(name)) { if (schemaMapping.containsKey(name)) {
return importMapping.get(name); return schemaMapping.get(name);
} }
if (!StringUtils.isEmpty(modelNamePrefix)) { if (!StringUtils.isEmpty(modelNamePrefix)) {

View File

@@ -346,7 +346,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
// specification is aligned with the JSON schema specification. // specification is aligned with the JSON schema specification.
// When "items" is not specified, the elements of the array may be anything at all. // When "items" is not specified, the elements of the array may be anything at all.
if (inner != null) { if (inner != null) {
inner = ModelUtils.unaliasSchema(this.openAPI, inner); inner = unaliasSchema(inner);
} }
String typDecl; String typDecl;
if (inner != null) { if (inner != null) {
@@ -360,10 +360,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
return "[]" + typDecl; return "[]" + typDecl;
} else if (ModelUtils.isMapSchema(p)) { } else if (ModelUtils.isMapSchema(p)) {
Schema inner = getAdditionalProperties(p); Schema inner = getAdditionalProperties(p);
return getSchemaType(p) + "[string]" + getTypeDeclaration(ModelUtils.unaliasSchema(this.openAPI, inner)); return getSchemaType(p) + "[string]" + getTypeDeclaration(unaliasSchema(inner));
} }
//return super.getTypeDeclaration(p);
//return super.getTypeDeclaration(p);
// Not using the supertype invocation, because we want to UpperCamelize // Not using the supertype invocation, because we want to UpperCamelize
// the type. // the type.
String openAPIType = getSchemaType(p); String openAPIType = getSchemaType(p);
@@ -792,7 +792,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
@Override @Override
public String toDefaultValue(Schema schema) { public String toDefaultValue(Schema schema) {
schema = ModelUtils.unaliasSchema(this.openAPI, schema); schema = unaliasSchema(schema);
if (schema.getDefault() != null) { if (schema.getDefault() != null) {
return schema.getDefault().toString(); return schema.getDefault().toString();
} else { } else {

View File

@@ -824,6 +824,12 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override @Override
public String toModelName(final String name) { public String toModelName(final String name) {
// We need to check if schema-mapping has a different model for this class, so we use it
// instead of the auto-generated one.
if (schemaMapping.containsKey(name)) {
return schemaMapping.get(name);
}
final String sanitizedName = sanitizeName(name); final String sanitizedName = sanitizeName(name);
String nameWithPrefixSuffix = sanitizedName; String nameWithPrefixSuffix = sanitizedName;
@@ -867,7 +873,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
@Override @Override
public String getTypeDeclaration(Schema p) { public String getTypeDeclaration(Schema p) {
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping); Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema; Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) { if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema); Schema<?> items = getSchemaItems((ArraySchema) schema);
@@ -1330,6 +1336,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
if (property.isReadOnly) { if (property.isReadOnly) {
model.getVendorExtensions().put("x-has-readonly-properties", true); model.getVendorExtensions().put("x-has-readonly-properties", true);
} }
// if data type happens to be the same as the property name and both are upper case
if (property.dataType != null && property.dataType.equals(property.name) && property.dataType.toUpperCase(Locale.ROOT).equals(property.name)) {
property.name = property.name.toLowerCase(Locale.ROOT);
}
} }
@Override @Override
@@ -2042,6 +2053,22 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
} }
} }
/**
* Search for property by {@link CodegenProperty#name}
* @param name - name to search for
* @param properties - list of properties
* @return either found property or {@link Optional#empty()} if nothing has been found
*/
protected Optional<CodegenProperty> findByName(String name, List<CodegenProperty> properties) {
if (properties == null || properties.isEmpty()) {
return Optional.empty();
}
return properties.stream()
.filter(p -> p.name.equals(name))
.findFirst();
}
/** /**
* This method removes all implicit header parameters from the list of parameters * This method removes all implicit header parameters from the list of parameters
* *

View File

@@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.media.StringSchema;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
@@ -364,7 +365,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
*/ */
@Override @Override
public String getTypeDeclaration(Schema p) { public String getTypeDeclaration(Schema p) {
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping); Schema<?> schema = unaliasSchema(p);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema; Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) { if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema); Schema<?> items = getSchemaItems((ArraySchema) schema);
@@ -673,6 +674,12 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
return name; return name;
} }
// If schemaMapping contains name, assume this is a legitimate model name.
if (schemaMapping.containsKey(name)) {
return schemaMapping.get(name);
}
// TODO review importMapping below as we've added schema mapping support
// If importMapping contains name, assume this is a legitimate model name. // If importMapping contains name, assume this is a legitimate model name.
if (importMapping.containsKey(name)) { if (importMapping.containsKey(name)) {
return importMapping.get(name); return importMapping.get(name);
@@ -1045,4 +1052,30 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
public GeneratorLanguage generatorLanguage() { public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.KOTLIN; return GeneratorLanguage.KOTLIN;
} }
@Override
protected void updateModelForObject(CodegenModel m, Schema schema) {
/**
* we have a custom version of this function so we only set isMap to true if
* ModelUtils.isMapSchema
* In other generators, isMap is true for all type object schemas
*/
if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) {
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null);
}
if (ModelUtils.isMapSchema(schema)) {
// an object or anyType composed schema that has additionalProperties set
addAdditionPropertiesToCodeGenModel(m, schema);
} else {
m.setIsMap(false);
if (ModelUtils.isFreeFormObject(openAPI, schema)) {
// non-composed object type with no properties + additionalProperties
// additionalProperties must be null, ObjectSchema, or empty Schema
addAdditionPropertiesToCodeGenModel(m, schema);
}
}
// process 'additionalProperties'
setAddProps(schema, m);
}
} }

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