Compare commits

..

18 Commits

Author SHA1 Message Date
William Cheng
3d25263e32 use localhost 2025-09-27 16:33:24 +08:00
William Cheng
9a2d997398 skip host table update 2025-09-27 16:19:59 +08:00
William Cheng
d920f72020 test with ruby 3.4 2025-09-27 16:17:40 +08:00
William Cheng
152c87ee18 Revert "test with mac"
This reverts commit 3acc76a48b.
2025-09-27 15:53:48 +08:00
William Cheng
3acc76a48b test with mac 2025-09-27 15:32:08 +08:00
William Cheng
efd2fe60ad Merge remote-tracking branch 'origin/master' into ruby-github-test 2025-09-24 16:24:15 +08:00
William Cheng
43c78856f5 add new files 2025-09-21 17:51:01 +08:00
William Cheng
564f4e023d cat hosts 2025-09-21 17:34:07 +08:00
William Cheng
117773f14c update samples 2025-09-21 17:29:03 +08:00
William Cheng
260787b0a1 update 2025-09-21 17:07:40 +08:00
William Cheng
ef0aef28d7 use 127.0.0.1 2025-09-21 17:02:14 +08:00
William Cheng
324d773123 update tests 2025-09-21 16:56:52 +08:00
William Cheng
2760903274 update config to use ruby petstore fake spec 2025-09-21 16:48:43 +08:00
William Cheng
9d29eb98bc localhost 2025-09-21 16:44:59 +08:00
William Cheng
c2a8e11b45 add petstore, update host table 2025-09-21 16:39:50 +08:00
William Cheng
2b3947ea1a fix workflow 2025-09-21 16:38:06 +08:00
William Cheng
33fdad9554 add echo client tests 2025-09-21 16:35:55 +08:00
William Cheng
dceb03a8f0 migrate ruby tests to github workflow 2025-09-21 16:33:18 +08:00
9921 changed files with 33869 additions and 202803 deletions

View File

@@ -1,6 +1,6 @@
<!-- <!--
Please follow the issue template below for bug reports and feature requests. Please follow the issue template below for bug reports and feature requests.
Also please indicate in the issue title which language/library is concerned. E.g.: [JAVA] Bug generating foo with bar Also please indicate in the issue title which language/library is concerned. Eg: [JAVA] Bug generating foo with bar
--> -->
##### Description ##### Description

View File

@@ -18,7 +18,7 @@ assignees: ''
<!-- <!--
Please follow the issue template below for bug reports. Please follow the issue template below for bug reports.
Also please indicate in the issue title which language/library is concerned. E.g.: [BUG][JAVA] Bug generating foo with bar Also please indicate in the issue title which language/library is concerned. Eg: [BUG][JAVA] Bug generating foo with bar
--> -->
##### Description ##### Description

View File

@@ -19,7 +19,6 @@ jobs:
with: with:
java-version: 11 java-version: 11
distribution: 'temurin' distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -37,7 +37,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 11 java-version: 11
cache: gradle
# Cache Gradle Dependencies # Cache Gradle Dependencies
- name: Setup Gradle Dependencies Cache - name: Setup Gradle Dependencies Cache
uses: actions/cache@v4 uses: actions/cache@v4

View File

@@ -27,7 +27,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
cache: gradle
- uses: actions/cache@v4 - uses: actions/cache@v4
with: with:
@@ -45,12 +44,12 @@ jobs:
restore-keys: | restore-keys: |
${{ runner.os }}-gradle- ${{ runner.os }}-gradle-
- uses: gradle/actions/setup-gradle@v5 - uses: gradle/actions/setup-gradle@v4
with: with:
gradle-version: '8.14.3' gradle-version: '8.14.3'
- name: Setup Maven - name: Setup Maven
uses: s4u/setup-maven-action@v1.19.0 uses: s4u/setup-maven-action@v1.18.0
with: with:
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
maven-version: 3.8.8 maven-version: 3.8.8
@@ -62,7 +61,7 @@ jobs:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- name: Upload Maven build artifact - name: Upload Maven build artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
if: matrix.java == '11' && matrix.os == 'ubuntu-latest' if: matrix.java == '11' && matrix.os == 'ubuntu-latest'
with: with:
name: artifact name: artifact
@@ -92,13 +91,12 @@ jobs:
- name: Check out code - name: Check out code
uses: actions/checkout@v5 uses: actions/checkout@v5
- name: Setup Maven - name: Setup Maven
uses: s4u/setup-maven-action@v1.19.0 uses: s4u/setup-maven-action@v1.18.0
with: with:
java-version: 11 java-version: 11
maven-version: 3.8.8 maven-version: 3.8.8
cache: gradle
- name: Download build artifact - name: Download build artifact
uses: actions/download-artifact@v6 uses: actions/download-artifact@v5
with: with:
name: artifact name: artifact
- name: Run Ensures Script - name: Run Ensures Script

View File

@@ -21,7 +21,6 @@ jobs:
with: with:
java-version: 11 java-version: 11
distribution: 'temurin' distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:
@@ -42,7 +41,7 @@ jobs:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- run: ls -la modules/openapi-generator-cli/target - run: ls -la modules/openapi-generator-cli/target
- name: Upload openapi-generator-cli.jar artifact - name: Upload openapi-generator-cli.jar artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: openapi-generator-cli.jar name: openapi-generator-cli.jar
path: modules/openapi-generator-cli/target/openapi-generator-cli.jar path: modules/openapi-generator-cli/target/openapi-generator-cli.jar
@@ -60,7 +59,6 @@ jobs:
with: with:
java-version: 11 java-version: 11
distribution: 'temurin' distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:
@@ -81,7 +79,7 @@ jobs:
GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
- name: Publish unit test reports - name: Publish unit test reports
if: ${{ always() }} if: ${{ always() }}
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: surefire-test-results name: surefire-test-results
path: '**/surefire-reports/TEST-*.xml' path: '**/surefire-reports/TEST-*.xml'
@@ -99,7 +97,7 @@ jobs:
java-version: 11 java-version: 11
distribution: 'temurin' distribution: 'temurin'
- name: Download openapi-generator-cli.jar artifact - name: Download openapi-generator-cli.jar artifact
uses: actions/download-artifact@v6 uses: actions/download-artifact@v5
with: with:
name: openapi-generator-cli.jar name: openapi-generator-cli.jar
path: modules/openapi-generator-cli/target path: modules/openapi-generator-cli/target
@@ -138,7 +136,7 @@ jobs:
java-version: 11 java-version: 11
distribution: 'temurin' distribution: 'temurin'
- name: Download openapi-generator-cli.jar artifact - name: Download openapi-generator-cli.jar artifact
uses: actions/download-artifact@v6 uses: actions/download-artifact@v5
with: with:
name: openapi-generator-cli.jar name: openapi-generator-cli.jar
path: modules/openapi-generator-cli/target path: modules/openapi-generator-cli/target

View File

@@ -6,13 +6,13 @@ on:
- 'samples/server/petstore/go-echo-server/**' - 'samples/server/petstore/go-echo-server/**'
- 'samples/server/petstore/go-api-server/**' - 'samples/server/petstore/go-api-server/**'
- 'samples/server/petstore/go-chi-server/**' - 'samples/server/petstore/go-chi-server/**'
- 'samples/server/others/go-server/**' - 'samples/server/others/go-server/no-body-path-params/**'
pull_request: pull_request:
paths: paths:
- 'samples/server/petstore/go-echo-server/**' - 'samples/server/petstore/go-echo-server/**'
- 'samples/server/petstore/go-api-server/**' - 'samples/server/petstore/go-api-server/**'
- 'samples/server/petstore/go-chi-server/**' - 'samples/server/petstore/go-chi-server/**'
- 'samples/server/others/go-server/**' - 'samples/server/others/go-server/no-body-path-params/**'
jobs: jobs:
build: build:
@@ -26,7 +26,6 @@ jobs:
- samples/server/petstore/go-api-server/ - samples/server/petstore/go-api-server/
- samples/server/petstore/go-chi-server/ - samples/server/petstore/go-chi-server/
- samples/server/others/go-server/no-body-path-params/ - samples/server/others/go-server/no-body-path-params/
- samples/server/others/go-server/optional-body/
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
- uses: actions/setup-go@v6 - uses: actions/setup-go@v6
@@ -59,4 +58,4 @@ jobs:
go mod tidy go mod tidy
- name: Run tests - name: Run tests
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: go test ./samples_tests -v run: go test ./samples_tests -v

View File

@@ -26,7 +26,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 8 java-version: 8
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- 'samples/client/petstore/java/**' - 'samples/client/petstore/java/**'
- samples/client/petstore/jaxrs-cxf-client/** - samples/client/petstore/jaxrs-cxf-client/**
- samples/client/petstore/jaxrs-cxf-client-swagger2/**
- samples/client/petstore/java-micronaut-client/** - samples/client/petstore/java-micronaut-client/**
- 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-swagger1/** - samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
@@ -28,7 +27,6 @@ on:
paths: paths:
- 'samples/client/petstore/java/**' - 'samples/client/petstore/java/**'
- samples/client/petstore/jaxrs-cxf-client/** - samples/client/petstore/jaxrs-cxf-client/**
- samples/client/petstore/jaxrs-cxf-client-swagger2/**
- samples/client/petstore/java-micronaut-client/** - samples/client/petstore/java-micronaut-client/**
- 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-swagger1/** - samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
@@ -56,7 +54,6 @@ jobs:
matrix: matrix:
sample: sample:
# clients # clients
- samples/client/petstore/jaxrs-cxf-client-swagger2
- samples/client/petstore/jaxrs-cxf-client - samples/client/petstore/jaxrs-cxf-client
- samples/client/petstore/java/native - samples/client/petstore/java/native
- samples/client/petstore/java/native-async - samples/client/petstore/java/native-async
@@ -118,7 +115,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 11 java-version: 11
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -42,7 +42,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -1,51 +0,0 @@
name: Samples JS clients
on:
push:
paths:
#- samples/client/petstore/javascript-flowtyped/**
- samples/client/petstore/javascript-es6/**
- samples/client/petstore/javascript-promise-es6/**
pull_request:
paths:
#- samples/client/petstore/javascript-flowtyped/**
- samples/client/petstore/javascript-es6/**
- samples/client/petstore/javascript-promise-es6/**
jobs:
build:
name: Build projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node:
- "18.x"
- "20.x"
sample:
# clients
- samples/client/petstore/javascript-es6/
- samples/client/petstore/javascript-promise-es6/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps:
- uses: actions/checkout@v5
- name: Add hosts to /etc/hosts
run: |
sudo echo "127.0.0.1 petstore.swagger.io" | sudo tee -a /etc/hosts
- name: Use Node.js 20.x
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: 'npm' # Or 'yarn'
- name: npm install
working-directory: ${{ matrix.sample }}
run: npm install
- name: npm test
working-directory: ${{ matrix.sample }}
run: npm test

View File

@@ -20,7 +20,10 @@ jobs:
- samples/server/petstore/jaxrs/jersey2-useTags - samples/server/petstore/jaxrs/jersey2-useTags
- samples/server/petstore/jaxrs-jersey - samples/server/petstore/jaxrs-jersey
- samples/server/petstore/jaxrs-spec - samples/server/petstore/jaxrs-spec
- samples/server/petstore/jaxrs-spec-withxml - samples/server/petstore/jaxrs-spec-interface
- samples/server/petstore/jaxrs-spec-interface-response
- samples/server/petstore/jaxrs-jersey
- samples/server/petstore/jaxrs-spec
- samples/server/petstore/jaxrs-spec-interface - samples/server/petstore/jaxrs-spec-interface
- samples/server/petstore/jaxrs-spec-interface-response - samples/server/petstore/jaxrs-spec-interface-response
- samples/server/petstore/jaxrs-datelib-j8 - samples/server/petstore/jaxrs-datelib-j8

View File

@@ -77,7 +77,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 11 java-version: 11
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -26,7 +26,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -34,7 +34,6 @@ jobs:
# server # server
- samples/server/petstore/kotlin-server-required-and-nullable-properties - samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3 - samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-additionalproperties
- samples/server/petstore/kotlin-springboot-delegate-nodefaults - samples/server/petstore/kotlin-springboot-delegate-nodefaults
- samples/server/petstore/kotlin-springboot-request-cookie - samples/server/petstore/kotlin-springboot-request-cookie
- samples/server/petstore/kotlin-server/jaxrs-spec - samples/server/petstore/kotlin-server/jaxrs-spec
@@ -52,7 +51,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 17 java-version: 17
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:
@@ -69,4 +67,4 @@ jobs:
arguments: wrapper arguments: wrapper
- name: Build - name: Build
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test run: ./gradlew build -x test

View File

@@ -32,7 +32,6 @@ jobs:
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 21 java-version: 21
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:

View File

@@ -59,8 +59,7 @@ jobs:
- uses: actions/setup-java@v5 - uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 11 java-version: 8
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:
@@ -77,4 +76,4 @@ jobs:
arguments: wrapper arguments: wrapper
- name: Build - name: Build
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: ./gradlew build -x test run: ./gradlew build -x test

View File

@@ -34,7 +34,6 @@ jobs:
- "3.13" - "3.13"
sample: sample:
- samples/openapi3/client/petstore/python-aiohttp - samples/openapi3/client/petstore/python-aiohttp
- samples/openapi3/client/petstore/python-httpx
- samples/openapi3/client/petstore/python - samples/openapi3/client/petstore/python
- samples/openapi3/client/petstore/python-lazyImports - samples/openapi3/client/petstore/python-lazyImports
services: services:

View File

@@ -0,0 +1,43 @@
name: Samples Ruby
on:
push:
paths:
- 'samples/client/echo_api/ruby-httpx/**'
- 'samples/client/echo_api/ruby-faraday/**'
- 'samples/client/echo_api/ruby-typhoeus/**'
pull_request:
paths:
- 'samples/client/echo_api/ruby-httpx/**'
- 'samples/client/echo_api/ruby-faraday/**'
- 'samples/client/echo_api/ruby-typhoeus/**'
jobs:
build:
name: Build Ruby
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- 'samples/client/echo_api/ruby-httpx/'
- 'samples/client/echo_api/ruby-faraday/'
- 'samples/client/echo_api/ruby-typhoeus/'
steps:
- uses: actions/checkout@v5
- name: Setup node.js
uses: actions/setup-node@v5
- name: Run echo server
run: |
git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server
(cd http-echo-server && npm install && npm start &)
- uses: actions/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- name: Install bundle
working-directory: ${{ matrix.sample }}
run: bundle install
- name: Run rspec
working-directory: ${{ matrix.sample }}
run: rspec

View File

@@ -1,16 +1,18 @@
name: Samples Ruby name: Samples Ruby
on: on:
push: push:
paths: paths:
- 'samples/client/echo_api/ruby-httpx/**' - samples/client/petstore/ruby/**
- 'samples/client/echo_api/ruby-faraday/**' - samples/client/petstore/ruby-faraday/**
- 'samples/client/echo_api/ruby-typhoeus/**' - samples/client/petstore/ruby-httpx/**
- samples/client/petstore/ruby-autoload/**
pull_request: pull_request:
paths: paths:
- 'samples/client/echo_api/ruby-httpx/**' - samples/client/petstore/ruby/**
- 'samples/client/echo_api/ruby-faraday/**' - samples/client/petstore/ruby-faraday/**
- 'samples/client/echo_api/ruby-typhoeus/**' - samples/client/petstore/ruby-httpx/**
- samples/client/petstore/ruby-autoload/**
jobs: jobs:
build: build:
@@ -20,21 +22,28 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
sample: sample:
- 'samples/client/echo_api/ruby-httpx/' - samples/client/petstore/ruby/
- 'samples/client/echo_api/ruby-faraday/' #- samples/client/petstore/ruby-faraday/
- 'samples/client/echo_api/ruby-typhoeus/' #- samples/client/petstore/ruby-httpx/
#- samples/client/petstore/ruby-autoload/
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
- name: Setup node.js #- name: Add hosts to /etc/hosts
uses: actions/setup-node@v5 # run: |
- name: Run echo server # sudo echo "127.0.0.1 petstore.swagger.io" | sudo tee -a /etc/hosts
run: | # cat /etc/hosts
git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server - uses: ruby/setup-ruby@v1
(cd http-echo-server && npm install && npm start &)
- uses: actions/setup-ruby@v1
with: with:
ruby-version: 3.0 ruby-version: '3.4' # Not needed with a .ruby-version, .tool-versions or mise.toml
bundler-cache: true bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Install bundle - name: Install bundle
working-directory: ${{ matrix.sample }} working-directory: ${{ matrix.sample }}
run: bundle install run: bundle install

View File

@@ -1,142 +0,0 @@
name: Samples TS clients
on:
push:
paths:
- samples/client/others/typescript-angular/**
# comment out angular released before Nov 2023
#- samples/client/petstore/typescript-angular-v12-provided-in-root/**
#- samples/client/petstore/typescript-angular-v13-provided-in-root/**
#- samples/client/petstore/typescript-angular-v14-provided-in-root/**
#- samples/client/petstore/typescript-angular-v15-provided-in-root/**
- samples/client/petstore/typescript-angular-v16-provided-in-root/**
- samples/client/petstore/typescript-angular-v17-provided-in-root/**
- samples/client/petstore/typescript-angular-v18-provided-in-root/**
- samples/client/petstore/typescript-angular-v19-provided-in-root/**
- samples/client/petstore/typescript-angular-v20-provided-in-root/**
- samples/openapi3/client/petstore/typescript/builds/default/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/default/**
- samples/openapi3/client/petstore/typescript/builds/jquery/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/jquery/**
- samples/openapi3/client/petstore/typescript/builds/object_params/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/object_params/**
#- samples/openapi3/client/petstore/typescript/builds/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/deno/**
- samples/openapi3/client/petstore/typescript/builds/browser/**
# comment out due to build failure
#- samples/openapi3/client/petstore/typescript/tests/browser/**
#- samples/openapi3/client/petstore/typescript/builds/nullable-enum/**
- samples/client/petstore/typescript-fetch/builds/default/**
- samples/client/petstore/typescript-fetch/builds/es6-target/**
- samples/client/petstore/typescript-fetch/builds/with-npm-version/**
- samples/client/petstore/typescript-fetch/tests/default/**
# comment out due to build failure
#- samples/client/petstore/typescript-node/npm/**
- samples/client/petstore/typescript-rxjs/builds/with-npm-version/**
- samples/client/petstore/typescript-axios/builds/with-npm-version/**
# comment out due to build failure
#- samples/client/petstore/typescript-axios/tests/default/**
pull_request:
paths:
- samples/client/others/typescript-angular/**
#- samples/client/petstore/typescript-angular-v12-provided-in-root/**
#- samples/client/petstore/typescript-angular-v13-provided-in-root/**
#- samples/client/petstore/typescript-angular-v14-provided-in-root/**
#- samples/client/petstore/typescript-angular-v15-provided-in-root/**
- samples/client/petstore/typescript-angular-v16-provided-in-root/**
- samples/client/petstore/typescript-angular-v17-provided-in-root/**
- samples/client/petstore/typescript-angular-v18-provided-in-root/**
- samples/client/petstore/typescript-angular-v19-provided-in-root/**
- samples/client/petstore/typescript-angular-v20-provided-in-root/**
- samples/openapi3/client/petstore/typescript/builds/default/**
#- samples/openapi3/client/petstore/typescript/tests/default/**
- samples/openapi3/client/petstore/typescript/builds/jquery/**
#- samples/openapi3/client/petstore/typescript/tests/jquery/**
- samples/openapi3/client/petstore/typescript/builds/object_params/**
#- samples/openapi3/client/petstore/typescript/tests/object_params/**
#- samples/openapi3/client/petstore/typescript/builds/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/inversify/**
#- samples/openapi3/client/petstore/typescript/tests/deno/**
- samples/openapi3/client/petstore/typescript/builds/browser/**
#- samples/openapi3/client/petstore/typescript/tests/browser/**
#- samples/openapi3/client/petstore/typescript/builds/nullable-enum/**
- samples/client/petstore/typescript-fetch/builds/default/**
- samples/client/petstore/typescript-fetch/builds/es6-target/**
- samples/client/petstore/typescript-fetch/builds/with-npm-version/**
- samples/client/petstore/typescript-fetch/tests/default/**
#- samples/client/petstore/typescript-node/npm/**
- samples/client/petstore/typescript-rxjs/builds/with-npm-version/**
- samples/client/petstore/typescript-axios/builds/with-npm-version/**
#- samples/client/petstore/typescript-axios/tests/default/**
jobs:
build:
name: Build projects
runs-on: ubuntu-latest
services:
petstore-api:
image: swaggerapi/petstore
ports:
- 80:8080
env:
SWAGGER_HOST: http://petstore.swagger.io
SWAGGER_BASE_PATH: /v2
strategy:
fail-fast: false
matrix:
node:
#- "18.x"
- "20.x"
sample:
- samples/client/others/typescript-angular/
#- samples/client/petstore/typescript-angular-v12-provided-in-root/
#- samples/client/petstore/typescript-angular-v13-provided-in-root/
#- samples/client/petstore/typescript-angular-v14-provided-in-root/
#- samples/client/petstore/typescript-angular-v15-provided-in-root/
- samples/client/petstore/typescript-angular-v16-provided-in-root/
- samples/client/petstore/typescript-angular-v17-provided-in-root/
- samples/client/petstore/typescript-angular-v18-provided-in-root/
- samples/client/petstore/typescript-angular-v19-provided-in-root/
- samples/client/petstore/typescript-angular-v20-provided-in-root/
- samples/openapi3/client/petstore/typescript/builds/default/
#- samples/openapi3/client/petstore/typescript/tests/default/
- samples/openapi3/client/petstore/typescript/builds/jquery/
#- samples/openapi3/client/petstore/typescript/tests/jquery/
- samples/openapi3/client/petstore/typescript/builds/object_params/
#- samples/openapi3/client/petstore/typescript/tests/object_params/
#- samples/openapi3/client/petstore/typescript/builds/inversify/
#- samples/openapi3/client/petstore/typescript/tests/inversify/
#- samples/openapi3/client/petstore/typescript/tests/deno/
- samples/openapi3/client/petstore/typescript/builds/browser/
#- samples/openapi3/client/petstore/typescript/tests/browser/
#- samples/openapi3/client/petstore/typescript/builds/nullable-enum/
- samples/client/petstore/typescript-fetch/builds/default/
- samples/client/petstore/typescript-fetch/builds/es6-target/
- samples/client/petstore/typescript-fetch/builds/with-npm-version/
- samples/client/petstore/typescript-fetch/tests/default/
#- samples/client/petstore/typescript-node/npm/
- samples/client/petstore/typescript-rxjs/builds/with-npm-version/
- samples/client/petstore/typescript-axios/builds/with-npm-version/
#- samples/client/petstore/typescript-axios/tests/default/
steps:
- uses: actions/checkout@v5
- name: Add hosts to /etc/hosts
run: |
sudo echo "127.0.0.1 petstore.swagger.io" | sudo tee -a /etc/hosts
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: '17' # Specify your desired Java version
distribution: 'temurin' # Or 'adopt', 'oracle', etc.
cache: maven # Cache Maven dependencies for faster builds
- name: Use Node.js
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: 'npm' # Or 'yarn'
- name: mvn integration-test
working-directory: ${{ matrix.sample }}
run: mvn integration-test

View File

@@ -1,34 +0,0 @@
name: Samples TS servers
on:
push:
paths:
- samples/server/petstore/typescript-nestjs-server/**
pull_request:
paths:
- samples/server/petstore/typescript-nestjs-server/**
jobs:
build:
name: Build projects
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node:
- "18.x"
- "20.x"
sample:
- samples/server/petstore/typescript-nestjs-server/
steps:
- uses: actions/checkout@v5
- name: Use Node.js 20.x
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: 'npm' # Or 'yarn'
- name: npm install
working-directory: ${{ matrix.sample }}
run: npm install
- name: npm test
working-directory: ${{ matrix.sample }}
run: npm test

View File

@@ -24,7 +24,6 @@ jobs:
with: with:
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
distribution: 'temurin' distribution: 'temurin'
cache: gradle
- name: Cache maven dependencies - name: Cache maven dependencies
uses: actions/cache@v4 uses: actions/cache@v4
env: env:
@@ -40,7 +39,7 @@ jobs:
${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build- ${{ runner.os }}-build-
- name: Setup Maven - name: Setup Maven
uses: s4u/setup-maven-action@v1.19.0 uses: s4u/setup-maven-action@v1.18.0
with: with:
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
maven-version: 3.8.8 maven-version: 3.8.8

2
.gitignore vendored
View File

@@ -49,8 +49,6 @@ nb-configuration.xml
*.xml~ *.xml~
*.t~ *.t~
**/.angular
/target /target
/generated-files /generated-files
test-output/ test-output/

View File

@@ -11,15 +11,43 @@ export NODE_ENV=test
if [ "$NODE_INDEX" = "1" ]; then if [ "$NODE_INDEX" = "1" ]; then
echo "Running node $NODE_INDEX ..." echo "Running node $NODE_INDEX ..."
java -version
sudo apt-get -y install cpanminus sudo apt-get -y install cpanminus
# install rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
echo "Testing perl" echo "Testing perl"
(cd samples/client/petstore/perl && /bin/bash ./test.bash) (cd samples/client/petstore/perl && /bin/bash ./test.bash)
echo "Testing ruby"
(cd samples/client/petstore/ruby && mvn integration-test)
(cd samples/client/petstore/ruby-faraday && mvn integration-test)
(cd samples/client/petstore/ruby-httpx && mvn integration-test)
(cd samples/client/petstore/ruby-autoload && mvn integration-test)
echo "Testing rust"
(cd samples/server/petstore/rust-axum && mvn integration-test)
elif [ "$NODE_INDEX" = "2" ]; then elif [ "$NODE_INDEX" = "2" ]; then
echo "Running node $NODE_INDEX to test cpp-restsdk" echo "Running node $NODE_INDEX to test Go"
# install haskell
#curl -sSLk https://get.haskellstack.org/ | sh
#stack upgrade
#stack --version
# install curl
#sudo apt-get -y build-dep libcurl4-gnutls-dev
#sudo apt-get -y install libcurl4-gnutls-dev
# Install golang version 1.18
go version
sudo mkdir /usr/local/go1.18
wget -c https://dl.google.com/go/go1.18.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local/go1.18
export PATH="/usr/local/go1.18/go/bin:$PATH"
go version
# install cpprestsdk # install cpprestsdk
sudo apt-get install libcpprest-dev sudo apt-get install libcpprest-dev
@@ -34,15 +62,58 @@ elif [ "$NODE_INDEX" = "3" ]; then
echo "Running node $NODE_INDEX ... " echo "Running node $NODE_INDEX ... "
echo "Testing ruby" # Install node@stable (for angular 6)
(cd samples/client/petstore/ruby && mvn integration-test) set +e
(cd samples/client/petstore/ruby-faraday && mvn integration-test) curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
(cd samples/client/petstore/ruby-httpx && mvn integration-test) export NVM_DIR="/opt/circleci/.nvm"
(cd samples/client/petstore/ruby-autoload && mvn integration-test) [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
#nvm install stable
# install v16 instead of the latest stable version
nvm install 18
nvm alias default 18
node --version
# Each step uses the same `$BASH_ENV`, so need to modify it
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
(cd samples/client/others/typescript-angular && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v12-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v13-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v14-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v15-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v16-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v17-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v18-provided-in-root && mvn integration-test)
(cd samples/client/petstore/typescript-angular-v19-provided-in-root && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/default && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/default && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/jquery && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/jquery && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/object_params && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/object_params && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/inversify && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/inversify && mvn integration-test)
#(cd samples/openapi3/client/petstore/typescript/tests/deno && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/browser && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/tests/browser && mvn integration-test)
(cd samples/openapi3/client/petstore/typescript/builds/nullable-enum && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/builds/default && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/builds/es6-target && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/builds/with-npm-version && mvn integration-test)
(cd samples/client/petstore/typescript-fetch/tests/default && mvn integration-test)
(cd samples/client/petstore/typescript-node/npm && mvn integration-test)
(cd samples/client/petstore/typescript-rxjs/builds/with-npm-version && mvn integration-test)
(cd samples/client/petstore/typescript-axios/builds/with-npm-version && mvn integration-test)
(cd samples/client/petstore/typescript-axios/tests/default && mvn integration-test)
(cd samples/client/petstore/typescript-axios/tests/with-complex-headers && mvn integration-test)
(cd samples/client/petstore/javascript-flowtyped && mvn integration-test)
(cd samples/client/petstore/javascript-es6 && mvn integration-test)
(cd samples/client/petstore/javascript-promise-es6 && mvn integration-test)
(cd samples/server/petstore/typescript-nestjs-server && mvn integration-test)
else else
echo "Running node $NODE_INDEX ..." echo "Running node $NODE_INDEX ..."
java -version java -version
./mvnw clean install
fi fi

View File

@@ -15,7 +15,7 @@
<div align="center"> <div align="center">
[Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.17.0`): [Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`7.16.0`):
[![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)
[![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)
@@ -148,8 +148,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.17.0 (upcoming minor release) [SNAPSHOT](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) | 24.10.2025 | Minor release with breaking changes (with fallback) | | 7.16.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.16.0-SNAPSHOT/) | 22.09.2025 | Minor release with breaking changes (with fallback) |
| [7.16.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.16.0) (latest stable release) | 28.09.2025 | Minor release with breaking changes (with fallback) | | [7.15.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.15.0) (latest stable release) | 22.08.2025 | Minor release with breaking changes (with fallback) |
| [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.2023 | Minor release with breaking changes (with fallback) | | [6.6.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.6.0) | 11.05.2023 | 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) | | [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) |
@@ -212,16 +212,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 11 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar` JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar`
For **Mac/Linux** users: For **Mac/Linux** users:
```sh ```sh
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar -O openapi-generator-cli.jar wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar -O openapi-generator-cli.jar
``` ```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g. 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/7.16.0/openapi-generator-cli-7.16.0.jar Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.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.
@@ -456,7 +456,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 7.16.0 openapi-generator-cli version-manager set 7.15.0
``` ```
Or install it as dev-dependency: Or install it as dev-dependency:
@@ -480,7 +480,7 @@ pip install openapi-generator-cli
To install a specific version To install a specific version
``` ```
pip install openapi-generator-cli==7.16.0 pip install openapi-generator-cli==7.15.0
``` ```
You can also install with [jdk4py](https://github.com/activeviam/jdk4py) instead of java binary. (python>=3.10 is required) You can also install with [jdk4py](https://github.com/activeviam/jdk4py) instead of java binary. (python>=3.10 is required)
@@ -506,7 +506,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/7.16.0/openapi-generator-cli-7.16.0.jar) You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.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`

View File

@@ -1,8 +0,0 @@
generatorName: go-server
outputDir: samples/server/others/go-server/optional-body
inputSpec: modules/openapi-generator/src/test/resources/3_0/optional_body.yaml
templateDir: modules/openapi-generator/src/main/resources/go-server
additionalProperties:
hideGenerationTimestamp: "true"
packageName: petstoreserver
addResponseHeaders: true

View File

@@ -1,8 +0,0 @@
generatorName: jaxrs-cxf-client
outputDir: samples/client/petstore/jaxrs-cxf-client-swagger2
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS/cxf
additionalProperties:
artifactId: jaxrs-cxf-petstore-swagger2
documentationProvider: swagger2
annotationLibrary: swagger2

View File

@@ -1,10 +0,0 @@
generatorName: jaxrs-spec
outputDir: samples/server/petstore/jaxrs-spec-withxml/
inputSpec: modules/openapi-generator/src/test/resources/3_0/jaxrs-spec/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS/spec
additionalProperties:
artifactId: jaxrs-spec-withxml-petstore-server
serializableModel: "true"
hideGenerationTimestamp: "true"
generateBuilders: "true"
withXml: true

View File

@@ -1,14 +0,0 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-additionalproperties
library: spring-boot
inputSpec: samples/server/petstore/kotlin-springboot-additionalproperties/src/main/resources/openapi.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: none
annotationLibrary: none
useSwaggerUI: "false"
serviceImplementation: "true"
serializableModel: "true"
beanValidations: "true"
useSpringBoot3: "true"
requestMappingMode: api_interface

View File

@@ -1,15 +0,0 @@
generatorName: python
outputDir: samples/openapi3/client/petstore/python-httpx
inputSpec: modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/python
library: httpx
additionalProperties:
packageName: petstore_api
mapNumberTo: float
poetry1: true
nameMappings:
_type: underscore_type
type_: type_with_underscore
modelNameMappings:
# The OpenAPI spec ApiResponse conflicts with the internal ApiResponse
ApiResponse: ModelApiResponse

View File

@@ -1,9 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v19-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 19.0.0
supportsES6: true
enumNameMappings:
delivered: SHIPPED

View File

@@ -1,9 +0,0 @@
generatorName: typescript-angular
outputDir: samples/client/petstore/typescript-angular-v20-provided-in-root/builds/default
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-angular
additionalProperties:
ngVersion: 20.0.0
supportsES6: true
enumNameMappings:
delivered: SHIPPED

View File

@@ -1,7 +0,0 @@
generatorName: typescript-fetch
outputDir: samples/client/others/typescript-fetch/infinite-recursion-issue
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/infinite-recursion-issue.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch
additionalProperties:
enumPropertyNaming: "original"
enumUnknownDefaultCase: true

View File

@@ -5,11 +5,11 @@ Running `./save_dart_keywords.sh` from this directory will generate `dart-keywor
## When should the keywords be generated? ## When should the keywords be generated?
`save_dart_keywords.sh` should be run when a new version of Dart is released to update the keywords file. `save_dart_keywords.sh` should be run when a new version of Dart is release to update the keywords file.
The last Dart version that was used to generate the keywords can be found in `dart-version.txt`. The last Dart version that was used to generate the keywords can be found in `dart-version.txt`.
## What does the shell script do? ## What does the shellscript do?
1. run the dart app 1. run the dart app
- `dart run save-dart-keywords.dart` - `dart run save-dart-keywords.dart`

View File

@@ -59,6 +59,6 @@
sha256: 45cdaba3d2adc212cd4f0184ad475419a95e2326254c2ef84175e210c922b2f3 sha256: 45cdaba3d2adc212cd4f0184ad475419a95e2326254c2ef84175e210c922b2f3
# rust axum test files # rust axum test files
- filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs" - filename: "samples/server/petstore/rust-axum/output/rust-axum-oneof/tests/oneof_with_discriminator.rs"
sha256: b2093528aac971193f2863a70f46eea45cf8bda79120b133a614599e80d8b46d sha256: 2d4f5a069fdcb3057bb078d5e75b3de63cd477b97725e457079df24bd2c30600
- filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs" - filename: "samples/server/petstore/rust-axum/output/openapi-v3/tests/oneof_untagged.rs"
sha256: 1d3fb01f65e98290b1d3eece28014c7d3e3f2fdf18e7110249d3c591cc4642ab sha256: e72fbf81a9849dc7abb7e2169f2fc355c8b1cf991c0e2ffc083126abd9e966e7

View File

@@ -538,7 +538,6 @@ OpenAPI Normalizer transforms the input OpenAPI doc/spec (which may not perfectl
- SIMPLIFY_ONEOF_ANYOF - SIMPLIFY_ONEOF_ANYOF
- SIMPLIFY_BOOLEAN_ENUM - SIMPLIFY_BOOLEAN_ENUM
- REFACTOR_ALLOF_WITH_PROPERTIES_ONLY
(One can use `DISABLE_ALL=true` to disable all the rules) (One can use `DISABLE_ALL=true` to disable all the rules)
@@ -644,16 +643,9 @@ Example:
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer NORMALIZER_CLASS=org.openapitools.codegen.OpenAPINormalizerTest$RemoveRequiredNormalizer java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer NORMALIZER_CLASS=org.openapitools.codegen.OpenAPINormalizerTest$RemoveRequiredNormalizer
``` ```
- `REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT`: When set to true, remove the "properties" of a schema with type other than "object".
Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/required-properties.yaml -o /tmp/java-okhttp/ --openapi-normalizer REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT=true
```
- `FILTER` - `FILTER`
The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated. Multiple filters can be separated by a semicolon. The `FILTER` parameter allows selective inclusion of API operations based on specific criteria. It applies the `x-internal: true` property to operations that do **not** match the specified values, preventing them from being generated.
### Available Filters ### Available Filters
@@ -666,9 +658,6 @@ The `FILTER` parameter allows selective inclusion of API operations based on spe
- **`tag`** - **`tag`**
When set to `tag:person|basic`, operations **not** tagged with `person` or `basic` will be marked as internal (`x-internal: true`), and will not be generated. When set to `tag:person|basic`, operations **not** tagged with `person` or `basic` will be marked as internal (`x-internal: true`), and will not be generated.
- **`path`**
When set to `path:/v1|/v2`, operations on paths **not** starting with `/v1` or with `/v2` will be marked as internal (`x-internal: true`), and will not be generated.
### Example Usage ### Example Usage
```sh ```sh
@@ -676,7 +665,7 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat
-g java \ -g java \
-i modules/openapi-generator/src/test/resources/3_0/petstore.yaml \ -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml \
-o /tmp/java-okhttp/ \ -o /tmp/java-okhttp/ \
--openapi-normalizer FILTER="operationId:addPet|getPetById ; tag:store" --openapi-normalizer FILTER="operationId:addPet|getPetById"
``` ```
- `SET_CONTAINER_TO_NULLABLE`: When set to `array|set|map` (or just `array`) for example, it will set `nullable` in array, set and map to true. - `SET_CONTAINER_TO_NULLABLE`: When set to `array|set|map` (or just `array`) for example, it will set `nullable` in array, set and map to true.

View File

@@ -5,7 +5,7 @@ title: Debugging
## Generation ## Generation
As a user there may be times when generated outputs don't match your expectations and it's unclear why. The CLI supports a `--dry-run` option which may be used to inspect the anticipated file operations without making changes to the file system. As a user there may be times when generated outputs don't match your expectations it's unclear why. The CLI supports a `--dry-run` option which may be used to inspect the anticipated file operations without making changes to the file system.
Suppose you generate using the `--minimal-update` option, and you notice on subsequent generations of a client that no files have changed. This is by design. Suppose you generate using the `--minimal-update` option, and you notice on subsequent generations of a client that no files have changed. This is by design.

View File

@@ -3,7 +3,6 @@ id: generators
title: Generators List title: Generators List
--- ---
[main] INFO o.o.c.l.PythonFastAPIServerCodegen - Skipping sorting of path operations, order matters, let the developer decide via their specification file.
The following generators are available: The following generators are available:
## CLIENT generators ## CLIENT generators

View File

@@ -95,7 +95,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|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|
|sourceFolder|source folder for generated code| |src/main/java| |sourceFolder|source folder for generated code| |src/main/java|
|springApiVersion|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|server title name or client service name| |OpenAPI Spring| |title|server title name or client service name| |OpenAPI Spring|
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false| |unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
@@ -133,10 +132,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false |x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null |x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null |x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-spring-api-version|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).|OPERATION|null
## IMPORT MAPPING ## IMPORT MAPPING

View File

@@ -67,9 +67,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-discriminator-value|Used with model inheritance to specify value for discriminator that identifies current model|MODEL| |x-discriminator-value|Used with model inheritance to specify value for discriminator that identifies current model|MODEL|
|x-field-extra-annotation|List of custom annotations to be added to property|FIELD, OPERATION_PARAMETER|null |x-field-extra-annotation|List of custom annotations to be added to property|FIELD, OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null |x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-kotlin-implements|Ability to specify interfaces that model must implement|MODEL|empty array |x-kotlin-implements|Ability to specify interfaces that model must implement|MODEL|empty array
|x-kotlin-implements-fields|Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`|MODEL|empty array |x-kotlin-implements-fields|Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`|MODEL|empty array

167
docs/generators/postman.md Normal file
View File

@@ -0,0 +1,167 @@
---
title: Documentation for the postman Generator
---
## METADATA
| Property | Value | Notes |
| -------- | ----- | ----- |
| generator name | postman | pass this to the generate command after -g |
| generator stability | BETA | |
| generator type | DOCUMENTATION | |
| generator default templating engine | mustache | |
| helpTxt | Generates a postman JSON file | |
## CONFIG OPTIONS
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|folderStrategy|whether to create folders according to the spec&rsquo;s paths or tags| |null|
|pathParamsAsVariables|whether to create Postman variables for path parameters| |false|
|postmanGuid|whether to convert placeholders (i.e. {{UNIQUE_REFERENCE}}) into Postman formula {{$guid}}| |null|
|postmanGuidPlaceholderName|name of the placeholder (i.e. {{UNIQUE_REFERENCE}}) to replace with Postman formula {{$guid}}| |null|
|postmanIsoTimestamp|whether to convert placeholders (i.e. {{ISO_TIMESTAMP}}) into Postman formula {{$isoTimestamp}}| |null|
|postmanIsoTimestampPlaceholderName|name of the placeholder (i.e. {{ISO_TIMESTAMP}}) to replace with Postman formula {{$isoTimestamp}}| |null|
|postmanVariables|whether to convert placeholders (i.e. {{VAR_1}}) into Postman variables| |null|
|requestParameterGeneration|whether to generate the request parameters based on the schema or the examples| |null|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
## LANGUAGE PRIMITIVES
<ul class="column-ul">
</ul>
## RESERVED WORDS
<ul class="column-ul">
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Uuid|✗|
|Array|✓|OAS2,OAS3
|Null|✗|OAS3
|AnyType|✗|OAS2,OAS3
|Object|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✗|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✓|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✓|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✓|OAS2,OAS3
|Union|✗|OAS3
|allOf|✗|OAS2,OAS3
|anyOf|✗|OAS3
|oneOf|✗|OAS3
|not|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✓|OAS2,OAS3
|ApiKey|✓|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✓|OAS3
|OAuth2_Implicit|✓|OAS2,OAS3
|OAuth2_Password|✓|OAS2,OAS3
|OAuth2_ClientCredentials|✓|OAS2,OAS3
|OAuth2_AuthorizationCode|✓|OAS2,OAS3
|SignatureAuth|✗|OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@@ -25,7 +25,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false| |generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true| |hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|lazyImports|Enable lazy imports.| |false| |lazyImports|Enable lazy imports.| |false|
|library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3, httpx| |urllib3| |library|library template (sub-template) to use: asyncio, tornado (deprecated), urllib3| |urllib3|
|mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictStr or float.| |Union[StrictFloat, StrictInt]| |mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictStr or float.| |Union[StrictFloat, StrictInt]|
|packageName|python package name (convention: snake_case).| |openapi_client| |packageName|python package name (convention: snake_case).| |openapi_client|
|packageUrl|python package URL.| |null| |packageUrl|python package URL.| |null|

View File

@@ -77,7 +77,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>dyn</li> <li>dyn</li>
<li>else</li> <li>else</li>
<li>enum</li> <li>enum</li>
<li>errors</li>
<li>extern</li> <li>extern</li>
<li>false</li> <li>false</li>
<li>final</li> <li>final</li>
@@ -208,8 +207,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|Composite|✓|OAS2,OAS3 |Composite|✓|OAS2,OAS3
|Polymorphism|✗|OAS2,OAS3 |Polymorphism|✗|OAS2,OAS3
|Union|✗|OAS3 |Union|✗|OAS3
|allOf||OAS2,OAS3 |allOf||OAS2,OAS3
|anyOf||OAS3 |anyOf||OAS3
|oneOf|✓|OAS3 |oneOf|✓|OAS3
|not|✗|OAS3 |not|✗|OAS3

View File

@@ -27,7 +27,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|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| |preferUnsignedInt|Prefer unsigned integers where minimum value is &gt;= 0| |false|
|reqwestDefaultFeatures|Default features for the reqwest dependency (comma-separated). Use empty for no defaults. This option is for 'reqwest' and 'reqwest-trait' library only.| |native-tls|
|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|
|supportMiddleware|If set, add support for reqwest-middleware. This option is for 'reqwest' and 'reqwest-trait' library only| |false| |supportMiddleware|If set, add support for reqwest-middleware. This option is for 'reqwest' and 'reqwest-trait' library only| |false|
|supportMultipleResponses|If set, return type wraps an enum of all possible 2xx schemas. This option is for 'reqwest' and 'reqwest-trait' library only| |false| |supportMultipleResponses|If set, return type wraps an enum of all possible 2xx schemas. This option is for 'reqwest' and 'reqwest-trait' library only| |false|

View File

@@ -88,7 +88,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|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|
|sourceFolder|source folder for generated code| |src/main/java| |sourceFolder|source folder for generated code| |src/main/java|
|springApiVersion|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).| |null|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|server title name or client service name| |OpenAPI Spring| |title|server title name or client service name| |OpenAPI Spring|
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false| |unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
@@ -126,10 +125,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false |x-spring-paginated|Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.|OPERATION|false
|x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null |x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null
|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null |x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null
|x-size-message|Add this property whenever you need to customize the invalidation error message for the size or length of a variable|FIELD, OPERATION_PARAMETER|null
|x-minimum-message|Add this property whenever you need to customize the invalidation error message for the minimum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-maximum-message|Add this property whenever you need to customize the invalidation error message for the maximum value of a variable|FIELD, OPERATION_PARAMETER|null
|x-spring-api-version|Value for 'version' attribute in @RequestMapping (for Spring 7 and above).|OPERATION|null
## IMPORT MAPPING ## IMPORT MAPPING

View File

@@ -44,7 +44,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|supportsES6|Generate code that conforms to ES6.| |false| |supportsES6|Generate code that conforms to ES6.| |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|
|useSquareBracketsInArrayNames|Setting this property to true will add brackets to array attribute names, e.g. my_values[].| |false| |useSquareBracketsInArrayNames|Setting this property to true will add brackets to array attribute names, e.g. my_values[].| |false|
|withAWSV4Signature|whether to include AWS v4 signature support| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false| |withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|withNodeImports|Setting this property to true adds imports for NodeJS| |false| |withNodeImports|Setting this property to true adds imports for NodeJS| |false|
|withSeparateModelsAndApi|Put the model and api in separate folders and in separate classes. This requires in addition a value for 'apiPackage' and 'modelPackage'| |false| |withSeparateModelsAndApi|Put the model and api in separate folders and in separate classes. This requires in addition a value for 'apiPackage' and 'modelPackage'| |false|
@@ -292,7 +291,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|OAuth2_ClientCredentials|✗|OAS2,OAS3 |OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3 |OAuth2_AuthorizationCode|✗|OAS2,OAS3
|SignatureAuth|✗|OAS3 |SignatureAuth|✗|OAS3
|AWSV4Signature||ToolingExtension |AWSV4Signature||ToolingExtension
### Wire Format Feature ### Wire Format Feature
| Name | Supported | Defined By | | Name | Supported | Defined By |

View File

@@ -22,7 +22,7 @@ npm install @openapitools/openapi-generator-cli -g
To install a specific version of the tool, pass the version during installation: To install a specific version of the tool, pass the version during installation:
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
```bash ```bash
openapi-generator-cli version-manager set 7.16.0 openapi-generator-cli version-manager set 7.15.0
``` ```
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
To install the tool as a dev dependency in your current project: To install the tool as a dev dependency in your current project:
@@ -119,18 +119,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 11 runtime at a minimum): If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 11 runtime at a minimum):
JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar` JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar`
For **Mac/Linux** users: For **Mac/Linux** users:
```bash ```bash
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.16.0/openapi-generator-cli-7.16.0.jar -O openapi-generator-cli.jar wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar -O openapi-generator-cli.jar
``` ```
For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g. 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/7.16.0/openapi-generator-cli-7.16.0.jar Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.15.0/openapi-generator-cli-7.15.0.jar
``` ```
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->

View File

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

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -29,7 +29,6 @@ import io.airlift.airline.Arguments;
import io.airlift.airline.Command; import io.airlift.airline.Command;
import io.airlift.airline.Option; import io.airlift.airline.Option;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.CodegenConfig;
@@ -249,7 +248,7 @@ public class GenerateBatch extends OpenApiGeneratorCommand {
Path filesMeta = Paths.get(outDir.toAbsolutePath().toString(), ".openapi-generator", "FILES"); Path filesMeta = Paths.get(outDir.toAbsolutePath().toString(), ".openapi-generator", "FILES");
if (filesMeta.toFile().exists()) { if (filesMeta.toFile().exists()) {
FileUtils.readLines(filesMeta.toFile(), StandardCharsets.UTF_8).forEach(relativePath -> { FileUtils.readLines(filesMeta.toFile(), StandardCharsets.UTF_8).forEach(relativePath -> {
if (!Strings.CS.startsWith(relativePath, ".")) { if (!StringUtils.startsWith(relativePath, ".")) {
Path file = outDir.resolve(relativePath).toAbsolutePath(); Path file = outDir.resolve(relativePath).toAbsolutePath();
// hack: disallow directory traversal outside of output directory. we don't want to delete wrong files. // hack: disallow directory traversal outside of output directory. we don't want to delete wrong files.
if (file.toString().startsWith(outDir.toAbsolutePath().toString())) { if (file.toString().startsWith(outDir.toAbsolutePath().toString())) {

View File

@@ -6,7 +6,7 @@
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

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 "7.16.0" id "org.openapi.generator" version "7.15.0"
} }
---- ----
@@ -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:7.16.0" classpath "org.openapitools:openapi-generator-gradle-plugin:7.15.0"
} }
} }
@@ -759,7 +759,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:7.16.0') { classpath('org.openapitools:openapi-generator-gradle-plugin:7.15.0') {
exclude group: 'com.google.guava' exclude group: 'com.google.guava'
} }
} }

View File

@@ -1,5 +1,5 @@
# RELEASE_VERSION # RELEASE_VERSION
openApiGeneratorVersion=7.17.0 openApiGeneratorVersion=7.16.0-SNAPSHOT
# /RELEASE_VERSION # /RELEASE_VERSION
# BEGIN placeholders # BEGIN placeholders

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -19,5 +19,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=7.16.0 openApiValidate gradle -PopenApiGeneratorVersion=7.15.0 openApiValidate
``` ```

View File

@@ -1,3 +1,3 @@
# RELEASE_VERSION # RELEASE_VERSION
openApiGeneratorVersion=7.17.0 openApiGeneratorVersion=7.16.0-SNAPSHOT
# /RELEASE_VERSION # /RELEASE_VERSION

View File

@@ -81,12 +81,12 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* The template directory holding a custom template. * The template directory holding a custom template.
*/ */
val templateDir = project.objects.property<String>() val templateDir = project.objects.property<String?>()
/** /**
* The template location (which may be a directory or a classpath location) holding custom templates. * The template location (which may be a directory or a classpath location) holding custom templates.
*/ */
val templateResourcePath = project.objects.property<String>() val templateResourcePath = project.objects.property<String?>()
/** /**
* Adds authorization headers when fetching the OpenAPI definitions remotely. * Adds authorization headers when fetching the OpenAPI definitions remotely.
@@ -109,7 +109,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* Specifies if the existing files should be overwritten during the generation. * Specifies if the existing files should be overwritten during the generation.
*/ */
val skipOverwrite = project.objects.property<Boolean>() val skipOverwrite = project.objects.property<Boolean?>()
/** /**
* Package for generated classes (where supported) * Package for generated classes (where supported)
@@ -244,32 +244,32 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* Reference the library template (sub-template) of a generator. * Reference the library template (sub-template) of a generator.
*/ */
val library = project.objects.property<String>() val library = project.objects.property<String?>()
/** /**
* Git host, e.g. gitlab.com. * Git host, e.g. gitlab.com.
*/ */
val gitHost = project.objects.property<String>() val gitHost = project.objects.property<String?>()
/** /**
* Git user ID, e.g. openapitools. * Git user ID, e.g. openapitools.
*/ */
val gitUserId = project.objects.property<String>() val gitUserId = project.objects.property<String?>()
/** /**
* Git repo ID, e.g. openapi-generator. * Git repo ID, e.g. openapi-generator.
*/ */
val gitRepoId = project.objects.property<String>() val gitRepoId = project.objects.property<String?>()
/** /**
* Release note, default to 'Minor update'. * Release note, default to 'Minor update'.
*/ */
val releaseNote = project.objects.property<String>() val releaseNote = project.objects.property<String?>()
/** /**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}/{language}' * HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}/{language}'
*/ */
val httpUserAgent = project.objects.property<String>() val httpUserAgent = project.objects.property<String?>()
/** /**
* Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used. * Specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used.
@@ -279,17 +279,17 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation. * Specifies an override location for the .openapi-generator-ignore file. Most useful on initial generation.
*/ */
val ignoreFileOverride = project.objects.property<String>() val ignoreFileOverride = project.objects.property<String?>()
/** /**
* Remove prefix of operationId, e.g. config_getId => getId * Remove prefix of operationId, e.g. config_getId => getId
*/ */
val removeOperationIdPrefix = project.objects.property<Boolean>() val removeOperationIdPrefix = project.objects.property<Boolean?>()
/** /**
* Skip examples defined in the operation * Skip examples defined in the operation
*/ */
val skipOperationExample = project.objects.property<Boolean>() val skipOperationExample = project.objects.property<Boolean?>()
/** /**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all). * Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
@@ -394,7 +394,7 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
/** /**
* Templating engine: "mustache" (default) or "handlebars" (beta) * Templating engine: "mustache" (default) or "handlebars" (beta)
*/ */
val engine = project.objects.property<String>() val engine = project.objects.property<String?>()
/** /**
* Defines whether the output dir should be cleaned up before generating the output. * Defines whether the output dir should be cleaned up before generating the output.

View File

@@ -55,6 +55,7 @@ import org.openapitools.codegen.config.MergedSpecBuilder
* *
* @author Jim Schubert * @author Jim Schubert
*/ */
@Suppress("UnstableApiUsage")
@CacheableTask @CacheableTask
open class GenerateTask @Inject constructor(private val objectFactory: ObjectFactory) : DefaultTask() { open class GenerateTask @Inject constructor(private val objectFactory: ObjectFactory) : DefaultTask() {
@@ -153,14 +154,14 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@get:Optional @get:Optional
@get:InputDirectory @get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE) @get:PathSensitive(PathSensitivity.RELATIVE)
val templateDir = project.objects.property<String>() val templateDir = project.objects.property<String?>()
/** /**
* Resource path containing template files. * Resource path containing template files.
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val templateResourcePath = project.objects.property<String>() val templateResourcePath = project.objects.property<String?>()
/** /**
* Adds authorization headers when fetching the OpenAPI definitions remotely. * Adds authorization headers when fetching the OpenAPI definitions remotely.
@@ -192,7 +193,7 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val skipOverwrite = project.objects.property<Boolean>() val skipOverwrite = project.objects.property<Boolean?>()
/** /**
* Package for generated classes (where supported) * Package for generated classes (where supported)
@@ -383,42 +384,42 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val library = project.objects.property<String>() val library = project.objects.property<String?>()
/** /**
* Git host, e.g. gitlab.com. * Git host, e.g. gitlab.com.
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val gitHost = project.objects.property<String>() val gitHost = project.objects.property<String?>()
/** /**
* Git user ID, e.g. openapitools. * Git user ID, e.g. openapitools.
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val gitUserId = project.objects.property<String>() val gitUserId = project.objects.property<String?>()
/** /**
* Git repo ID, e.g. openapi-generator. * Git repo ID, e.g. openapi-generator.
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val gitRepoId = project.objects.property<String>() val gitRepoId = project.objects.property<String?>()
/** /**
* Release note, default to 'Minor update'. * Release note, default to 'Minor update'.
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val releaseNote = project.objects.property<String>() val releaseNote = project.objects.property<String?>()
/** /**
* HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}/{language}' * HTTP user agent, e.g. codegen_csharp_api_client, default to 'OpenAPI-Generator/{packageVersion}/{language}'
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val httpUserAgent = project.objects.property<String>() val httpUserAgent = project.objects.property<String?>()
/** /**
* Specifies how a reserved name should be escaped to. * Specifies how a reserved name should be escaped to.
@@ -433,21 +434,21 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@get:Optional @get:Optional
@get:InputFile @get:InputFile
@get:PathSensitive(PathSensitivity.RELATIVE) @get:PathSensitive(PathSensitivity.RELATIVE)
val ignoreFileOverride = project.objects.property<String>() val ignoreFileOverride = project.objects.property<String?>()
/** /**
* Remove prefix of operationId, e.g. config_getId => getId * Remove prefix of operationId, e.g. config_getId => getId
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val removeOperationIdPrefix = project.objects.property<Boolean>() val removeOperationIdPrefix = project.objects.property<Boolean?>()
/** /**
* Remove examples defined in the operation * Remove examples defined in the operation
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val skipOperationExample = project.objects.property<Boolean>() val skipOperationExample = project.objects.property<Boolean?>()
/** /**
* Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all). * Defines which API-related files should be generated. This allows you to create a subset of generated files (or none at all).
@@ -580,7 +581,7 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
*/ */
@get:Optional @get:Optional
@get:Input @get:Input
val engine = project.objects.property<String>() val engine = project.objects.property<String?>()
/** /**
* Defines whether the output dir should be cleaned up before generating the output. * Defines whether the output dir should be cleaned up before generating the output.
@@ -597,11 +598,19 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@get:Input @get:Input
val dryRun = project.objects.property<Boolean>() val dryRun = project.objects.property<Boolean>()
private fun <T> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) { private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
if (isPresent) { if (isPresent) {
when (val value = get()) { val item: T? = get()
is String -> if (value.isNotEmpty()) block(value) if (item != null) {
else -> block(value) when (get()) {
is String -> if ((get() as String).isNotEmpty()) {
block(get())
}
is String? -> if (true == (get() as String?)?.isNotEmpty()) {
block(get())
}
else -> block(get())
}
} }
} }
} }
@@ -716,7 +725,7 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
} }
skipOverwrite.ifNotEmpty { value -> skipOverwrite.ifNotEmpty { value ->
configurator.setSkipOverwrite(value) configurator.setSkipOverwrite(value ?: false)
} }
generatorName.ifNotEmpty { value -> generatorName.ifNotEmpty { value ->
@@ -811,11 +820,11 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
} }
removeOperationIdPrefix.ifNotEmpty { value -> removeOperationIdPrefix.ifNotEmpty { value ->
configurator.setRemoveOperationIdPrefix(value) configurator.setRemoveOperationIdPrefix(value!!)
} }
skipOperationExample.ifNotEmpty { value -> skipOperationExample.ifNotEmpty { value ->
configurator.setSkipOperationExample(value) configurator.setSkipOperationExample(value!!)
} }
logToStderr.ifNotEmpty { value -> logToStderr.ifNotEmpty { value ->

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>7.16.0</version> <version>7.15.0</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

@@ -13,7 +13,7 @@
<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>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

@@ -15,7 +15,7 @@
<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>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

@@ -19,7 +19,7 @@
<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>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<dependencies> <dependencies>
<dependency> <dependency>

View File

@@ -13,7 +13,7 @@
<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>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

@@ -13,7 +13,7 @@
<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>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

@@ -20,7 +20,7 @@
<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>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<executions> <executions>
<execution> <execution>

View File

@@ -5,7 +5,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -4,7 +4,7 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator-project</artifactId> <artifactId>openapi-generator-project</artifactId>
<!-- RELEASE_VERSION --> <!-- RELEASE_VERSION -->
<version>7.17.0</version> <version>7.16.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION --> <!-- /RELEASE_VERSION -->
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>

View File

@@ -456,31 +456,4 @@ public class CodegenConstants {
public static final String USE_DEFAULT_VALUES_FOR_REQUIRED_VARS = "useDefaultValuesForRequiredVars"; public static final String USE_DEFAULT_VALUES_FOR_REQUIRED_VARS = "useDefaultValuesForRequiredVars";
public static final String DEFAULT_TO_EMPTY_CONTAINER = "defaultToEmptyContainer"; public static final String DEFAULT_TO_EMPTY_CONTAINER = "defaultToEmptyContainer";
// Vendor extensions
public static final String X_INTERNAL = "x-internal";
public static final String X_PARENT = "x-parent";
public static final String X_COMPOSED_DATA_TYPE = "x-composed-data-type";
public static final String X_BASE_NAME = "x-base-name";
public static final String X_IS_VALUE_TYPE = "x-is-value-type";
public static final String X_IS_REFERENCE_TYPE = "x-is-reference-type";
public static final String X_IS_NULLABLE_TYPE = "x-is-nullable-type";
public static final String X_IS_BASE_OR_NEW_DISCRIMINATOR = "x-is-base-or-new-discriminator";
public static final String X_ENUM_BYTE = "x-enum-byte";
public static final String X_HTTP_STATUS = "x-http-status";
public static final String X_HTTP_STATUSES_WITH_RETURN = "x-http-statuses-with-return";
public static final String X_SET_COOKIE = "x-set-cookie";
public static final String X_DUPLICATES = "x-duplicates";
public static final String X_HTTP_STATUS_IS_DEFAULT = "x-http-status-is-default";
public static final String X_ONLY_DEFAULT = "x-only-default";
public static final String X_HTTP_STATUS_RANGE = "x-http-status-range";
public static final String X_NOT_NULLABLE_REFERENCE_TYPES = "x-not-nullable-reference-types";
public static final String X_HAS_NOT_NULLABLE_REFERENCE_TYPES = "x-has-not-nullable-reference-types";
public static final String X_NULLABLE_VALUE_TYPE = "x-nullable-value-type";
public static final String X_NULLABLE_TYPE = "x-nullable-type";
public static final String X_CSHARP_VALUE_TYPE = "x-csharp-value-type";
public static final String X_REGEX = "x-regex";
public static final String X_MODIFIERS = "x-modifiers";
public static final String X_MODIFIER_PREFIX = "x-modifier-";
public static final String X_MODEL_IS_MUTABLE = "x-model-is-mutable";
} }

View File

@@ -115,15 +115,6 @@ public class CodegenOperation {
return nonEmpty(bodyParams); return nonEmpty(bodyParams);
} }
/**
* Check if there's at least one optional body parameter
*
* @return true if optional body parameter exists, false otherwise
*/
public boolean getHasOptionalBodyParam() {
return nonEmpty(bodyParams) && nonEmpty(optionalParams) && bodyParams.stream().anyMatch(optionalParams::contains);
}
/** /**
* Check if there's at least one query parameter * Check if there's at least one query parameter
* *

View File

@@ -88,7 +88,8 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static org.openapitools.codegen.CodegenConstants.*; import static org.openapitools.codegen.CodegenConstants.DEFAULT_TO_EMPTY_CONTAINER;
import static org.openapitools.codegen.CodegenConstants.UNSUPPORTED_V310_SPEC_MSG;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.OnceLogger.once; import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
@@ -5196,7 +5197,7 @@ public class DefaultCodegen implements CodegenConfig {
String method = p.getKey(); String method = p.getKey();
Operation op = p.getValue(); Operation op = p.getValue();
if (op.getExtensions() != null && Boolean.TRUE.equals(op.getExtensions().get(X_INTERNAL))) { if (op.getExtensions() != null && Boolean.TRUE.equals(op.getExtensions().get("x-internal"))) {
// skip operation if x-internal sets to true // skip operation if x-internal sets to true
LOGGER.info("Operation ({} {} - {}) not generated since x-internal is set to true", LOGGER.info("Operation ({} {} - {}) not generated since x-internal is set to true",
method, expression, op.getOperationId()); method, expression, op.getOperationId());
@@ -5734,7 +5735,7 @@ public class DefaultCodegen implements CodegenConfig {
cs.name = key; cs.name = key;
cs.description = securityScheme.getDescription(); cs.description = securityScheme.getDescription();
cs.type = securityScheme.getType().toString(); cs.type = securityScheme.getType().toString();
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = cs.isOpenId = cs.isOAuth = false; cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = cs.isOpenId = false;
cs.isHttpSignature = false; cs.isHttpSignature = false;
cs.isBasicBasic = cs.isBasicBearer = false; cs.isBasicBasic = cs.isBasicBearer = false;
cs.scheme = securityScheme.getScheme(); cs.scheme = securityScheme.getScheme();

View File

@@ -61,7 +61,6 @@ import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.removeStart; import static org.apache.commons.lang3.StringUtils.removeStart;
import static org.openapitools.codegen.CodegenConstants.X_INTERNAL;
import static org.openapitools.codegen.utils.OnceLogger.once; import static org.openapitools.codegen.utils.OnceLogger.once;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@@ -487,7 +486,7 @@ public class DefaultGenerator implements Generator {
Schema schema = ModelUtils.getSchemas(this.openAPI).get(name); Schema schema = ModelUtils.getSchemas(this.openAPI).get(name);
if (schema.getExtensions() != null && Boolean.TRUE.equals(schema.getExtensions().get(X_INTERNAL))) { if (schema.getExtensions() != null && Boolean.TRUE.equals(schema.getExtensions().get("x-internal"))) {
LOGGER.info("Model {} not generated since x-internal is set to true", name); LOGGER.info("Model {} not generated since x-internal is set to true", name);
continue; continue;
} else if (ModelUtils.isFreeFormObject(schema, openAPI)) { // check to see if it's a free-form object } else if (ModelUtils.isFreeFormObject(schema, openAPI)) { // check to see if it's a free-form object
@@ -1565,7 +1564,7 @@ public class DefaultGenerator implements Generator {
final List<SecurityRequirement> globalSecurities = openAPI.getSecurity(); final List<SecurityRequirement> globalSecurities = openAPI.getSecurity();
for (Tag tag : tags) { for (Tag tag : tags) {
try { try {
if (operation.getExtensions() != null && Boolean.TRUE.equals(operation.getExtensions().get(X_INTERNAL))) { if (operation.getExtensions() != null && Boolean.TRUE.equals(operation.getExtensions().get("x-internal"))) {
// skip operation if x-internal sets to true // skip operation if x-internal sets to true
LOGGER.info("Operation ({} {} - {}) not generated since x-internal is set to true", LOGGER.info("Operation ({} {} - {}) not generated since x-internal is set to true",
httpMethod, resourcePath, operation.getOperationId()); httpMethod, resourcePath, operation.getOperationId());

View File

@@ -356,9 +356,7 @@ public class InlineModelResolver {
} else if (schema.getProperties() != null) { } else if (schema.getProperties() != null) {
// If non-object type is specified but also properties // If non-object type is specified but also properties
LOGGER.error("Illegal schema found with non-object type combined with properties," + LOGGER.error("Illegal schema found with non-object type combined with properties," +
" no properties should be defined:" + " no properties should be defined:\n " + schema.toString());
" consider using --openapi-normalizer REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT=true\n " +
schema.toString());
return; return;
} else if (schema.getAdditionalProperties() != null) { } else if (schema.getAdditionalProperties() != null) {
// If non-object type is specified but also additionalProperties // If non-object type is specified but also additionalProperties

View File

@@ -37,8 +37,6 @@ import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.X_INTERNAL;
import static org.openapitools.codegen.CodegenConstants.X_PARENT;
import static org.openapitools.codegen.utils.ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema; import static org.openapitools.codegen.utils.ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema;
import static org.openapitools.codegen.utils.StringUtils.getUniqueString; import static org.openapitools.codegen.utils.StringUtils.getUniqueString;
@@ -49,7 +47,7 @@ public class OpenAPINormalizer {
private TreeSet<String> anyTypeTreeSet = new TreeSet<>(); private TreeSet<String> anyTypeTreeSet = new TreeSet<>();
protected static final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class); protected final Logger LOGGER = LoggerFactory.getLogger(OpenAPINormalizer.class);
Set<String> ruleNames = new TreeSet<>(); Set<String> ruleNames = new TreeSet<>();
Set<String> rulesDefaultToTrue = new TreeSet<>(); Set<String> rulesDefaultToTrue = new TreeSet<>();
@@ -124,18 +122,20 @@ public class OpenAPINormalizer {
// the allOf contains a new schema containing the properties in the top level // the allOf contains a new schema containing the properties in the top level
final String REFACTOR_ALLOF_WITH_PROPERTIES_ONLY = "REFACTOR_ALLOF_WITH_PROPERTIES_ONLY"; final String REFACTOR_ALLOF_WITH_PROPERTIES_ONLY = "REFACTOR_ALLOF_WITH_PROPERTIES_ONLY";
// when set to true, remove the "properties" of a schema with type other than "object"
final String REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT = "REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT";
// when set to true, normalize OpenAPI 3.1 spec to make it work with the generator // when set to true, normalize OpenAPI 3.1 spec to make it work with the generator
final String NORMALIZE_31SPEC = "NORMALIZE_31SPEC"; final String NORMALIZE_31SPEC = "NORMALIZE_31SPEC";
// when set to true, remove x-internal: true from models, operations // when set to true, remove x-internal: true from models, operations
final String REMOVE_X_INTERNAL = "REMOVE_X_INTERNAL"; final String REMOVE_X_INTERNAL = "REMOVE_X_INTERNAL";
final String X_INTERNAL = "x-internal";
boolean removeXInternal; boolean removeXInternal;
// when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else // when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else
final String FILTER = "FILTER"; final String FILTER = "FILTER";
HashSet<String> operationIdFilters = new HashSet<>();
HashSet<String> methodFilters = new HashSet<>();
HashSet<String> tagFilters = new HashSet<>();
// when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else // when set (e.g. operationId:getPetById|addPet), filter out (or remove) everything else
final String SET_CONTAINER_TO_NULLABLE = "SET_CONTAINER_TO_NULLABLE"; final String SET_CONTAINER_TO_NULLABLE = "SET_CONTAINER_TO_NULLABLE";
@@ -209,13 +209,11 @@ public class OpenAPINormalizer {
ruleNames.add(SET_CONTAINER_TO_NULLABLE); ruleNames.add(SET_CONTAINER_TO_NULLABLE);
ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE); ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE);
ruleNames.add(SIMPLIFY_ONEOF_ANYOF_ENUM); ruleNames.add(SIMPLIFY_ONEOF_ANYOF_ENUM);
ruleNames.add(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT);
// rules that are default to true // rules that are default to true
rules.put(SIMPLIFY_ONEOF_ANYOF, true); rules.put(SIMPLIFY_ONEOF_ANYOF, true);
rules.put(SIMPLIFY_BOOLEAN_ENUM, true); rules.put(SIMPLIFY_BOOLEAN_ENUM, true);
rules.put(SIMPLIFY_ONEOF_ANYOF_ENUM, true); rules.put(SIMPLIFY_ONEOF_ANYOF_ENUM, true);
rules.put(REFACTOR_ALLOF_WITH_PROPERTIES_ONLY, true);
processRules(inputRules); processRules(inputRules);
@@ -276,7 +274,30 @@ public class OpenAPINormalizer {
if (inputRules.get(FILTER) != null) { if (inputRules.get(FILTER) != null) {
rules.put(FILTER, true); rules.put(FILTER, true);
// actual parsing is delayed to allow customization of the Filter processing
String[] filterStrs = inputRules.get(FILTER).split(":");
if (filterStrs.length != 2) { // only support operationId with : at the moment
LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3`: {}", inputRules.get(FILTER));
} else {
if ("operationId".equals(filterStrs[0])) {
operationIdFilters = Arrays.stream(filterStrs[1].split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
} else if ("method".equals(filterStrs[0])) {
methodFilters = Arrays.stream(filterStrs[1].split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
} else if ("tag".equals(filterStrs[0])) {
tagFilters = Arrays.stream(filterStrs[1].split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
} else {
LOGGER.error("FILTER rule must be in the form of `operationId:name1|name2|name3` or `method:get|post|put` or `tag:tag1|tag2|tag3`: {}", inputRules.get(FILTER));
}
}
} }
if (inputRules.get(SET_CONTAINER_TO_NULLABLE) != null) { if (inputRules.get(SET_CONTAINER_TO_NULLABLE) != null) {
@@ -322,19 +343,6 @@ public class OpenAPINormalizer {
} }
} }
/**
* Create the filter to process the FILTER normalizer.
* Override this to create a custom filter normalizer.
*
* @param openApi Contract used in the filtering (could be used for customization).
* @param filters full FILTER value
*
* @return a Filter containing the parsed filters.
*/
protected Filter createFilter(OpenAPI openApi, String filters) {
return new Filter(filters);
}
/** /**
* Normalizes the OpenAPI input, which may not perfectly conform to * Normalizes the OpenAPI input, which may not perfectly conform to
* the specification. * the specification.
@@ -396,15 +404,15 @@ public class OpenAPINormalizer {
"trace", PathItem::getTrace "trace", PathItem::getTrace
); );
if (Boolean.TRUE.equals(getRule(FILTER))) { // Iterates over each HTTP method in methodMap, retrieves the corresponding Operation from the PathItem,
String filters = inputRules.get(FILTER); // and marks it as internal (`x-internal`) if the method is not in methodFilters.
Filter filter = createFilter(this.openAPI, filters); methodMap.forEach((method, getter) -> {
if (filter.parse()) { Operation operation = getter.apply(path);
// Iterates over each HTTP method in methodMap, retrieves the corresponding Operations from the PathItem, if (operation != null && !methodFilters.isEmpty()) {
// and marks it as internal (`x-internal=true`) if the method/operationId/tag/path is not in the filters. LOGGER.info("operation `{}` marked internal only (x-internal: `{}`) by the method FILTER", operation.getOperationId(), !methodFilters.contains(method));
filter.apply(pathsEntry.getKey(), path, methodMap); operation.addExtension("x-internal", !methodFilters.contains(method));
} }
} });
// Include callback operation as well // Include callback operation as well
for (Operation operation : path.readOperations()) { for (Operation operation : path.readOperations()) {
@@ -421,6 +429,22 @@ public class OpenAPINormalizer {
normalizeParameters(path.getParameters()); normalizeParameters(path.getParameters());
for (Operation operation : operations) { for (Operation operation : operations) {
if (operationIdFilters.size() > 0) {
if (operationIdFilters.contains(operation.getOperationId())) {
operation.addExtension("x-internal", false);
} else {
LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the operationId FILTER", operation.getOperationId());
operation.addExtension("x-internal", true);
}
} else if (!tagFilters.isEmpty()) {
if (operation.getTags().stream().anyMatch(tagFilters::contains)) {
operation.addExtension("x-internal", false);
} else {
LOGGER.info("operation `{}` marked as internal only (x-internal: true) by the tag FILTER", operation.getOperationId());
operation.addExtension("x-internal", true);
}
}
normalizeOperation(operation); normalizeOperation(operation);
normalizeRequestBody(operation); normalizeRequestBody(operation);
normalizeParameters(operation.getParameters()); normalizeParameters(operation.getParameters());
@@ -699,19 +723,15 @@ public class OpenAPINormalizer {
if (skipNormalization(schema, visitedSchemas)) { if (skipNormalization(schema, visitedSchemas)) {
return schema; return schema;
} }
if (ModelUtils.isNullTypeSchema(openAPI, schema)) {
return schema;
}
markSchemaAsVisited(schema, visitedSchemas); markSchemaAsVisited(schema, visitedSchemas);
processNormalizeOtherThanObjectWithProperties(schema);
if (ModelUtils.isArraySchema(schema)) { // array if (ModelUtils.isArraySchema(schema)) { // array
Schema result = normalizeArraySchema(schema); Schema result = normalizeArraySchema(schema);
normalizeSchema(result.getItems(), visitedSchemas); normalizeSchema(result.getItems(), visitedSchemas);
return result; return result;
} else if (schema.getAdditionalProperties() instanceof Schema) { // map
normalizeMapSchema(schema);
normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas);
} else if (ModelUtils.isOneOf(schema)) { // oneOf } else if (ModelUtils.isOneOf(schema)) { // oneOf
return normalizeOneOf(schema, visitedSchemas); return normalizeOneOf(schema, visitedSchemas);
} else if (ModelUtils.isAnyOf(schema)) { // anyOf } else if (ModelUtils.isAnyOf(schema)) { // anyOf
@@ -748,9 +768,6 @@ public class OpenAPINormalizer {
return schema; return schema;
} else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) { } else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
normalizeProperties(schema.getProperties(), visitedSchemas); normalizeProperties(schema.getProperties(), visitedSchemas);
} else if (schema.getAdditionalProperties() instanceof Schema) { // map
normalizeMapSchema(schema);
normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas);
} else if (schema instanceof BooleanSchema) { } else if (schema instanceof BooleanSchema) {
normalizeBooleanSchema(schema, visitedSchemas); normalizeBooleanSchema(schema, visitedSchemas);
} else if (schema instanceof IntegerSchema) { } else if (schema instanceof IntegerSchema) {
@@ -832,20 +849,6 @@ public class OpenAPINormalizer {
} }
for (Map.Entry<String, Schema> propertiesEntry : properties.entrySet()) { for (Map.Entry<String, Schema> propertiesEntry : properties.entrySet()) {
Schema property = propertiesEntry.getValue(); Schema property = propertiesEntry.getValue();
// remove x-internal if needed (same logic as normalizeComponentsSchemas)
if (property.getExtensions() != null && getRule(REMOVE_X_INTERNAL)) {
Object xInternalValue = property.getExtensions().get(X_INTERNAL);
boolean isInternal = false;
if (xInternalValue instanceof Boolean) {
isInternal = (Boolean) xInternalValue;
} else if (xInternalValue instanceof String) {
isInternal = Boolean.parseBoolean((String) xInternalValue);
}
if (isInternal) {
property.getExtensions().remove(X_INTERNAL);
}
}
Schema newProperty = normalizeSchema(property, new HashSet<>()); Schema newProperty = normalizeSchema(property, new HashSet<>());
propertiesEntry.setValue(newProperty); propertiesEntry.setValue(newProperty);
} }
@@ -1008,7 +1011,6 @@ public class OpenAPINormalizer {
if (schema.getAnyOf() == null) { if (schema.getAnyOf() == null) {
return schema; return schema;
} }
for (int i = 0; i < schema.getAnyOf().size(); i++) { for (int i = 0; i < schema.getAnyOf().size(); i++) {
// normalize anyOf sub schemas one by one // normalize anyOf sub schemas one by one
Object item = schema.getAnyOf().get(i); Object item = schema.getAnyOf().get(i);
@@ -1081,10 +1083,10 @@ public class OpenAPINormalizer {
refSchema.setExtensions(new HashMap<>()); refSchema.setExtensions(new HashMap<>());
} }
if (refSchema.getExtensions().containsKey(X_PARENT)) { if (refSchema.getExtensions().containsKey("x-parent")) {
// doing nothing as x-parent already exists // doing nothing as x-parent already exists
} else { } else {
refSchema.getExtensions().put(X_PARENT, true); refSchema.getExtensions().put("x-parent", true);
} }
LOGGER.debug("processUseAllOfRefAsParent added `x-parent: true` to {}", refSchema); LOGGER.debug("processUseAllOfRefAsParent added `x-parent: true` to {}", refSchema);
@@ -1106,7 +1108,7 @@ public class OpenAPINormalizer {
return; return;
} }
if (Boolean.parseBoolean(String.valueOf(operation.getExtensions().get(X_INTERNAL)))) { if (Boolean.parseBoolean(String.valueOf(operation.getExtensions().get("x-internal")))) {
operation.getExtensions().remove(X_INTERNAL); operation.getExtensions().remove(X_INTERNAL);
} }
} }
@@ -1340,7 +1342,7 @@ public class OpenAPINormalizer {
* *
* @param schema Schema to modify * @param schema Schema to modify
* @param subSchemas List of sub-schemas to check * @param subSchemas List of sub-schemas to check
* @param composedType Type of composed schema ("oneOf" or "anyOf") * @param schemaType Type of composed schema ("oneOf" or "anyOf")
* @return Simplified schema * @return Simplified schema
*/ */
protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> subSchemas, String composedType) { protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> subSchemas, String composedType) {
@@ -1809,181 +1811,4 @@ public class OpenAPINormalizer {
} }
// ===================== end of rules ===================== // ===================== end of rules =====================
protected static class Filter {
public static final String OPERATION_ID = "operationId";
public static final String METHOD = "method";
public static final String TAG = "tag";
public static final String PATH = "path";
private final String filters;
protected Set<String> operationIdFilters = Collections.emptySet();
protected Set<String> methodFilters = Collections.emptySet();
protected Set<String> tagFilters = Collections.emptySet();
protected Set<String> pathStartingWithFilters = Collections.emptySet();
private boolean hasFilter;
protected Filter(String filters) {
this.filters = filters.trim();
}
/**
* Perform the parsing of the filter string.
*
* @return true if filters need to be processed
*/
public boolean parse() {
if (StringUtils.isEmpty(filters)) {
return false;
}
try {
doParse();
return hasFilter();
} catch (RuntimeException e) {
String message = String.format(Locale.ROOT, "FILTER rule [%s] must be in the form of `%s:name1|name2|name3` or `%s:get|post|put` or `%s:tag1|tag2|tag3` or `%s:/v1|/v2`. Error: %s",
filters, Filter.OPERATION_ID, Filter.METHOD, Filter.TAG, Filter.PATH, e.getMessage());
// throw an exception. This is a breaking change compared to pre 7.16.0
// Workaround: fix the syntax!
throw new IllegalArgumentException(message);
}
}
private void doParse() {
for (String filter : filters.split(";")) {
filter = filter.trim();
String[] filterStrs = filter.split(":");
if (filterStrs.length != 2) { // only support filter with : at the moment
throw new IllegalArgumentException("filter with no value not supported :[" + filter + "]");
} else {
String filterKey = filterStrs[0].trim();
String filterValue = filterStrs[1];
Set<String> parsedFilters = splitByPipe(filterValue);
hasFilter = true;
if (OPERATION_ID.equals(filterKey)) {
operationIdFilters = parsedFilters;
} else if (METHOD.equals(filterKey)) {
methodFilters = parsedFilters;
} else if (TAG.equals(filterKey)) {
tagFilters = parsedFilters;
} else if (PATH.equals(filterKey)) {
pathStartingWithFilters = parsedFilters;
} else {
parse(filterKey, filterValue);
}
}
}
}
/**
* Split the filterValue by pipe.
*
* @return the split values.
*/
protected Set<String> splitByPipe(String filterValue) {
return Arrays.stream(filterValue.split("[|]"))
.filter(Objects::nonNull)
.map(String::trim)
.collect(Collectors.toCollection(HashSet::new));
}
/**
* Parse non default filters.
*
* Override this method to add custom parsing logic.
*
* By default throws IllegalArgumentException.
*
* @param filterName name of the filter
* @param filterValue value of the filter
*/
protected void parse(String filterName, String filterValue) {
parseFails(filterName, filterValue);
}
protected void parseFails(String filterName, String filterValue) {
throw new IllegalArgumentException("filter not supported :[" + filterName + ":" + filterValue + "]");
}
/**
* Test if the OpenAPI contract match an extra filter.
*
* Override this method to add custom logic.
*
* @param operation Openapi Operation
* @param path Path of the operation
*
* @return true if the operation of path match the filter
*/
protected boolean hasCustomFilterMatch(String path, Operation operation) {
return false;
}
public boolean hasFilter() {
return hasFilter;
}
public void apply(String path, PathItem pathItem, Map<String, Function<PathItem, Operation>> methodMap) {
methodMap.forEach((method, getter) -> {
Operation operation = getter.apply(pathItem);
if (operation != null) {
boolean found = false;
found |= logIfMatch(PATH, operation, hasPathStarting(path));
found |= logIfMatch(TAG, operation, hasTag(operation));
found |= logIfMatch(OPERATION_ID, operation, hasOperationId(operation));
found |= logIfMatch(METHOD, operation, hasMethod(method));
found |= hasCustomFilterMatch(path, operation);
operation.addExtension(X_INTERNAL, !found);
}
});
}
protected boolean logIfMatch(String filterName, Operation operation, boolean filterMatched) {
if (filterMatched) {
logMatch(filterName, operation);
}
return filterMatched;
}
protected void logMatch(String filterName, Operation operation) {
getLogger().info("operation `{}` marked as internal only (x-internal: true) by the {} FILTER", operation.getOperationId(), filterName);
}
protected Logger getLogger() {
return OpenAPINormalizer.LOGGER;
}
private boolean hasPathStarting(String path) {
return pathStartingWithFilters.stream().anyMatch(filter -> path.startsWith(filter));
}
private boolean hasTag( Operation operation) {
return operation.getTags() != null && operation.getTags().stream().anyMatch(tagFilters::contains);
}
private boolean hasOperationId(Operation operation) {
return operationIdFilters.contains(operation.getOperationId());
}
private boolean hasMethod(String method) {
return methodFilters.contains(method);
}
}
/**
* When set to true, remove "properties" attribute on schema other than "object"
* since it should be ignored and may result in odd generated code
*
* @param schema Schema
* @return Schema
*/
protected void processNormalizeOtherThanObjectWithProperties(Schema schema) {
if (getRule(REMOVE_PROPERTIES_FROM_TYPE_OTHER_THAN_OBJECT)) {
// Check object models / any type models / composed models for properties,
// if the schema has a type defined that is not "object" it should not define
// any properties
if (schema.getType() != null && !"object".equals(schema.getType())) {
schema.setProperties(null);
}
}
}
} }

View File

@@ -13,7 +13,6 @@ public enum VendorExtension {
X_KOTLIN_IMPLEMENTS("x-kotlin-implements", ExtensionLevel.MODEL, "Ability to specify interfaces that model must implement", "empty array"), X_KOTLIN_IMPLEMENTS("x-kotlin-implements", ExtensionLevel.MODEL, "Ability to specify interfaces that model must implement", "empty array"),
X_KOTLIN_IMPLEMENTS_FIELDS("x-kotlin-implements-fields", ExtensionLevel.MODEL, "Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`", "empty array"), X_KOTLIN_IMPLEMENTS_FIELDS("x-kotlin-implements-fields", ExtensionLevel.MODEL, "Specify attributes that are implemented by the interface(s) added via `x-kotlin-implements`", "empty array"),
X_SPRING_PAGINATED("x-spring-paginated", ExtensionLevel.OPERATION, "Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.", "false"), X_SPRING_PAGINATED("x-spring-paginated", ExtensionLevel.OPERATION, "Add `org.springframework.data.domain.Pageable` to controller method. Can be used to handle `page`, `size` and `sort` query parameters. If these query parameters are also specified in the operation spec, they will be removed from the controller method as their values can be obtained from the `Pageable` object.", "false"),
X_SPRING_API_VERSION("x-spring-api-version", ExtensionLevel.OPERATION, "Value for 'version' attribute in @RequestMapping (for Spring 7 and above).", null),
X_SPRING_PROVIDE_ARGS("x-spring-provide-args", ExtensionLevel.OPERATION, "Allows adding additional hidden parameters in the API specification to allow access to content such as header values or properties", "empty array"), X_SPRING_PROVIDE_ARGS("x-spring-provide-args", ExtensionLevel.OPERATION, "Allows adding additional hidden parameters in the API specification to allow access to content such as header values or properties", "empty array"),
X_DISCRIMINATOR_VALUE("x-discriminator-value", ExtensionLevel.MODEL, "Used with model inheritance to specify value for discriminator that identifies current model", ""), X_DISCRIMINATOR_VALUE("x-discriminator-value", ExtensionLevel.MODEL, "Used with model inheritance to specify value for discriminator that identifies current model", ""),
X_SETTER_EXTRA_ANNOTATION("x-setter-extra-annotation", ExtensionLevel.FIELD, "Custom annotation that can be specified over java setter for specific field", "When field is array & uniqueItems, then this extension is used to add `@JsonDeserialize(as = LinkedHashSet.class)` over setter, otherwise no value"), X_SETTER_EXTRA_ANNOTATION("x-setter-extra-annotation", ExtensionLevel.FIELD, "Custom annotation that can be specified over java setter for specific field", "When field is array & uniqueItems, then this extension is used to add `@JsonDeserialize(as = LinkedHashSet.class)` over setter, otherwise no value"),
@@ -27,10 +26,8 @@ public enum VendorExtension {
X_OPERATION_EXTRA_ANNOTATION("x-operation-extra-annotation", ExtensionLevel.OPERATION, "List of custom annotations to be added to operation", null), X_OPERATION_EXTRA_ANNOTATION("x-operation-extra-annotation", ExtensionLevel.OPERATION, "List of custom annotations to be added to operation", null),
X_VERSION_PARAM("x-version-param", ExtensionLevel.OPERATION_PARAMETER, "Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false", null), X_VERSION_PARAM("x-version-param", ExtensionLevel.OPERATION_PARAMETER, "Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false", null),
X_PATTERN_MESSAGE("x-pattern-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable", null), X_PATTERN_MESSAGE("x-pattern-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable", null),
X_SIZE_MESSAGE("x-size-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the size or length of a variable", null), X_ZERO_BASED_ENUM("x-zero-based-enum", ExtensionLevel.MODEL, "When used on an enum, the index will not be generated and the default numbering will be used, zero-based", "false"),
X_MINIMUM_MESSAGE("x-minimum-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the minimum value of a variable", null), ;
X_MAXIMUM_MESSAGE("x-maximum-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the maximum value of a variable", null),
X_ZERO_BASED_ENUM("x-zero-based-enum", ExtensionLevel.MODEL, "When used on an enum, the index will not be generated and the default numbering will be used, zero-based", "false");
private final String name; private final String name;
private final List<ExtensionLevel> levels; private final List<ExtensionLevel> levels;

View File

@@ -46,7 +46,6 @@ import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.*;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.ModelUtils.getSchemaItems; import static org.openapitools.codegen.utils.ModelUtils.getSchemaItems;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -117,9 +116,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
// A cache to efficiently lookup schema `toModelName()` based on the schema Key // A cache to efficiently lookup schema `toModelName()` based on the schema Key
private final Map<String, String> schemaKeyToModelNameCache = new HashMap<>(); private final Map<String, String> schemaKeyToModelNameCache = new HashMap<>();
// A cache to efficiently lookup CodegenModel `fromModel(codegenModelName, parentModelSchema)` based on the pair of model name and schema
private final Map<Map.Entry<String, Schema>, CodegenModel> codegenModelNameAndSchemaKeyToCodegenModelCache = new HashMap<>();
public AbstractCSharpCodegen() { public AbstractCSharpCodegen() {
super(); super();
@@ -547,7 +543,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (dataTypeSet.contains(oneOfProperty.dataType)) { if (dataTypeSet.contains(oneOfProperty.dataType)) {
// add "x-duplicated-data-type" to indicate if the dataType already occurs before // add "x-duplicated-data-type" to indicate if the dataType already occurs before
// in other sub-schemas of allOf/anyOf/oneOf // in other sub-schemas of allOf/anyOf/oneOf
oneOfProperty.vendorExtensions.putIfAbsent(X_COMPOSED_DATA_TYPE, true); oneOfProperty.vendorExtensions.putIfAbsent("x-composed-data-type", true);
} else { } else {
dataTypeSet.add(oneOfProperty.dataType); dataTypeSet.add(oneOfProperty.dataType);
} }
@@ -561,7 +557,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (dataTypeSet.contains(anyOfProperty.dataType)) { if (dataTypeSet.contains(anyOfProperty.dataType)) {
// add "x-duplicated-data-type" to indicate if the dataType already occurs before // add "x-duplicated-data-type" to indicate if the dataType already occurs before
// in other sub-schemas of allOf/anyOf/oneOf // in other sub-schemas of allOf/anyOf/oneOf
anyOfProperty.vendorExtensions.putIfAbsent(X_COMPOSED_DATA_TYPE, true); anyOfProperty.vendorExtensions.putIfAbsent("x-composed-data-type", true);
} else { } else {
dataTypeSet.add(anyOfProperty.dataType); dataTypeSet.add(anyOfProperty.dataType);
} }
@@ -623,7 +619,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
continue; continue;
} }
model.vendorExtensions.put(X_MODEL_IS_MUTABLE, modelIsMutable(model, null)); model.vendorExtensions.put("x-model-is-mutable", modelIsMutable(model, null));
CodegenComposedSchemas composedSchemas = model.getComposedSchemas(); CodegenComposedSchemas composedSchemas = model.getComposedSchemas();
if (composedSchemas != null) { if (composedSchemas != null) {
@@ -643,7 +639,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchProperty(enumRefs, model, property); patchProperty(enumRefs, model, property);
property.name = patchPropertyName(model, property, camelize(property.baseType), composedPropertyNames); property.name = patchPropertyName(model, property, camelize(property.baseType), composedPropertyNames);
property.isNullable = true; property.isNullable = true;
property.vendorExtensions.put(X_BASE_NAME, model.name.substring(model.name.lastIndexOf('_') + 1)); property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
} }
} }
@@ -654,7 +650,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchProperty(enumRefs, model, property); patchProperty(enumRefs, model, property);
property.name = patchPropertyName(model, property, camelize(property.baseType), composedPropertyNames); property.name = patchPropertyName(model, property, camelize(property.baseType), composedPropertyNames);
property.isNullable = true; property.isNullable = true;
property.vendorExtensions.put(X_BASE_NAME, model.name.substring(model.name.lastIndexOf('_') + 1)); property.vendorExtensions.put("x-base-name", model.name.substring(model.name.lastIndexOf('_') + 1));
} }
} }
} }
@@ -788,10 +784,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
private void patchPropertyVendorExtensions(CodegenProperty property) { private void patchPropertyVendorExtensions(CodegenProperty property) {
boolean isValueType = isValueType(property); boolean isValueType = isValueType(property);
property.vendorExtensions.put(X_IS_VALUE_TYPE, isValueType); property.vendorExtensions.put("x-is-value-type", isValueType);
property.vendorExtensions.put(X_IS_REFERENCE_TYPE, !isValueType); property.vendorExtensions.put("x-is-reference-type", !isValueType);
property.vendorExtensions.put(X_IS_NULLABLE_TYPE, this.getNullableReferencesTypes() || isValueType); property.vendorExtensions.put("x-is-nullable-type", this.getNullableReferencesTypes() || isValueType);
property.vendorExtensions.put(X_IS_BASE_OR_NEW_DISCRIMINATOR, (property.isDiscriminator && !property.isInherited) || (property.isDiscriminator && property.isNew)); property.vendorExtensions.put("x-is-base-or-new-discriminator", (property.isDiscriminator && !property.isInherited) || (property.isDiscriminator && property.isNew));
} }
protected void patchPropertyIsInherited(CodegenModel model, CodegenProperty property) { protected void patchPropertyIsInherited(CodegenModel model, CodegenProperty property) {
@@ -892,7 +888,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
// Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here. // Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here.
if (var.isEnum) { if (var.isEnum) {
if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums. if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums.
var.vendorExtensions.put(X_ENUM_BYTE, true); var.vendorExtensions.put("x-enum-byte", true);
var.isString = false; var.isString = false;
var.isLong = false; var.isLong = false;
var.isInteger = false; var.isInteger = false;
@@ -913,7 +909,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
} }
private void postProcessResponseCode(CodegenResponse response, String status, Set<String> httpStatusesWithReturn) { private void postProcessResponseCode(CodegenResponse response, String status, Set<String> httpStatusesWithReturn) {
response.vendorExtensions.put(X_HTTP_STATUS, status); response.vendorExtensions.put("x-http-status", status);
if (response.dataType != null) { if (response.dataType != null) {
httpStatusesWithReturn.add(status); httpStatusesWithReturn.add(status);
} }
@@ -946,11 +942,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
} }
private void postProcessOperations(OperationMap operations, List<ModelMap> allModels) { private void postProcessOperations(OperationMap operations, List<ModelMap> allModels) {
Set<String> httpStatusesWithReturn = additionalProperties.get(X_HTTP_STATUSES_WITH_RETURN) instanceof Set<?> Set<String> httpStatusesWithReturn = additionalProperties.get("x-http-statuses-with-return") instanceof Set<?>
? (Set<String>) additionalProperties.get(X_HTTP_STATUSES_WITH_RETURN) ? (Set<String>) additionalProperties.get("x-http-statuses-with-return")
: new HashSet<String>(); : new HashSet<String>();
additionalProperties.put(X_HTTP_STATUSES_WITH_RETURN, httpStatusesWithReturn); additionalProperties.put("x-http-statuses-with-return", httpStatusesWithReturn);
HashMap<String, CodegenModel> modelMaps = ModelMap.toCodegenModelMap(allModels); HashMap<String, CodegenModel> modelMaps = ModelMap.toCodegenModelMap(allModels);
@@ -959,7 +955,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
for (CodegenOperation operation : ops) { for (CodegenOperation operation : ops) {
String duplicates = duplicateOf.get(operation.operationId); String duplicates = duplicateOf.get(operation.operationId);
if (duplicates != null) { if (duplicates != null) {
operation.vendorExtensions.put(X_DUPLICATES, duplicates); operation.vendorExtensions.put("x-duplicates", duplicates);
} else { } else {
duplicateOf.put(operation.operationId, operations.getClassname()); duplicateOf.put(operation.operationId, operations.getClassname());
} }
@@ -968,13 +964,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
if (response.returnProperty != null) { if (response.returnProperty != null) {
Boolean isValueType = isValueType(response.returnProperty); Boolean isValueType = isValueType(response.returnProperty);
response.vendorExtensions.put(X_IS_VALUE_TYPE, isValueType); response.vendorExtensions.put("x-is-value-type", isValueType);
response.vendorExtensions.put(X_IS_REFERENCE_TYPE, !isValueType); response.vendorExtensions.put("x-is-reference-type", !isValueType);
} }
if (response.headers != null && response.headers.stream().anyMatch(h -> h.baseName.equals("Set-Cookie"))) { if (response.headers != null && response.headers.stream().anyMatch(h -> h.baseName.equals("Set-Cookie"))) {
response.vendorExtensions.put(X_SET_COOKIE, true); response.vendorExtensions.put("x-set-cookie", true);
operation.vendorExtensions.put(X_SET_COOKIE, true); operation.vendorExtensions.put("x-set-cookie", true);
} }
String code = response.code.toLowerCase(Locale.ROOT); String code = response.code.toLowerCase(Locale.ROOT);
@@ -982,9 +978,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
case "default": case "default":
case "0": case "0":
postProcessResponseCode(response, "Default", httpStatusesWithReturn); postProcessResponseCode(response, "Default", httpStatusesWithReturn);
response.vendorExtensions.put(X_HTTP_STATUS_IS_DEFAULT, true); response.vendorExtensions.put("x-http-status-is-default", true);
if ((long) operation.responses.size() == 1) { if ((long) operation.responses.size() == 1) {
response.vendorExtensions.put(X_ONLY_DEFAULT, true); response.vendorExtensions.put("x-only-default", true);
} }
break; break;
case "100": case "100":
@@ -1165,23 +1161,23 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
postProcessResponseCode(response, "NetworkAuthenticationRequired", httpStatusesWithReturn); postProcessResponseCode(response, "NetworkAuthenticationRequired", httpStatusesWithReturn);
break; break;
case "1xx": case "1xx":
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 1); response.vendorExtensions.put("x-http-status-range", 1);
postProcessResponseCode(response, "HttpStatusCode1XX", httpStatusesWithReturn); postProcessResponseCode(response, "HttpStatusCode1XX", httpStatusesWithReturn);
break; break;
case "2xx": case "2xx":
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 2); response.vendorExtensions.put("x-http-status-range", 2);
postProcessResponseCode(response, "HttpStatusCode2XX", httpStatusesWithReturn); postProcessResponseCode(response, "HttpStatusCode2XX", httpStatusesWithReturn);
break; break;
case "3xx": case "3xx":
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 3); response.vendorExtensions.put("x-http-status-range", 3);
postProcessResponseCode(response, "HttpStatusCode3XX", httpStatusesWithReturn); postProcessResponseCode(response, "HttpStatusCode3XX", httpStatusesWithReturn);
break; break;
case "4xx": case "4xx":
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 4); response.vendorExtensions.put("x-http-status-range", 4);
postProcessResponseCode(response, "HttpStatusCode4XX", httpStatusesWithReturn); postProcessResponseCode(response, "HttpStatusCode4XX", httpStatusesWithReturn);
break; break;
case "5xx": case "5xx":
response.vendorExtensions.put(X_HTTP_STATUS_RANGE, 5); response.vendorExtensions.put("x-http-status-range", 5);
postProcessResponseCode(response, "HttpStatusCode5XX", httpStatusesWithReturn); postProcessResponseCode(response, "HttpStatusCode5XX", httpStatusesWithReturn);
break; break;
default: default:
@@ -1282,9 +1278,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
patchParameter(model, parameter); patchParameter(model, parameter);
} }
List<CodegenParameter> referenceTypes = operation.allParams.stream().filter(p -> p.vendorExtensions.get(X_IS_VALUE_TYPE) == null && !p.isNullable).collect(Collectors.toList()); List<CodegenParameter> referenceTypes = operation.allParams.stream().filter(p -> p.vendorExtensions.get("x-is-value-type") == null && !p.isNullable).collect(Collectors.toList());
operation.vendorExtensions.put(X_NOT_NULLABLE_REFERENCE_TYPES, referenceTypes); operation.vendorExtensions.put("x-not-nullable-reference-types", referenceTypes);
operation.vendorExtensions.put(X_HAS_NOT_NULLABLE_REFERENCE_TYPES, referenceTypes.size() > 0); operation.vendorExtensions.put("x-has-not-nullable-reference-types", referenceTypes.size() > 0);
processOperation(operation); processOperation(operation);
// Remove constant params from allParams list and add to constantParams // Remove constant params from allParams list and add to constantParams
@@ -1295,7 +1291,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
protected void patchVendorExtensionNullableValueType(CodegenParameter parameter) { protected void patchVendorExtensionNullableValueType(CodegenParameter parameter) {
if (parameter.isNullable && !parameter.isContainer && (this.getValueTypes().contains(parameter.dataType) || parameter.isEnum)) { if (parameter.isNullable && !parameter.isContainer && (this.getValueTypes().contains(parameter.dataType) || parameter.isEnum)) {
parameter.vendorExtensions.put(X_NULLABLE_VALUE_TYPE, true); parameter.vendorExtensions.put("x-nullable-value-type", true);
} }
} }
@@ -1311,15 +1307,15 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
*/ */
protected void patchVendorExtensionNullableValueTypeLegacy(CodegenParameter parameter) { protected void patchVendorExtensionNullableValueTypeLegacy(CodegenParameter parameter) {
if (parameter.isNullable && !parameter.isContainer && (this.getNullableTypes().contains(parameter.dataType) || parameter.isEnum)) { if (parameter.isNullable && !parameter.isContainer && (this.getNullableTypes().contains(parameter.dataType) || parameter.isEnum)) {
parameter.vendorExtensions.put(X_NULLABLE_VALUE_TYPE, true); parameter.vendorExtensions.put("x-nullable-value-type", true);
} }
} }
private void patchParameter(CodegenModel model, CodegenParameter parameter) { private void patchParameter(CodegenModel model, CodegenParameter parameter) {
patchVendorExtensionNullableValueType(parameter); patchVendorExtensionNullableValueType(parameter);
if (this.getNullableReferencesTypes() || (parameter.vendorExtensions.get(X_NULLABLE_VALUE_TYPE) != null)) { if (this.getNullableReferencesTypes() || (parameter.vendorExtensions.get("x-nullable-value-type") != null)) {
parameter.vendorExtensions.put(X_NULLABLE_TYPE, true); parameter.vendorExtensions.put("x-nullable-type", true);
} }
if (!isSupportNullable()) { if (!isSupportNullable()) {
@@ -1366,12 +1362,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
parameter.isEnum = true; parameter.isEnum = true;
parameter.allowableValues = model.allowableValues; parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true; parameter.isPrimitiveType = true;
parameter.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true); parameter.vendorExtensions.put("x-csharp-value-type", true);
} }
} }
if (!parameter.isContainer && this.getNullableTypes().contains(parameter.dataType)) { if (!parameter.isContainer && this.getNullableTypes().contains(parameter.dataType)) {
parameter.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true); parameter.vendorExtensions.put("x-csharp-value-type", true);
} }
} }
@@ -1381,12 +1377,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
parameter.isEnum = true; parameter.isEnum = true;
parameter.allowableValues = model.allowableValues; parameter.allowableValues = model.allowableValues;
parameter.isPrimitiveType = true; parameter.isPrimitiveType = true;
parameter.vendorExtensions.put(X_IS_VALUE_TYPE, true); parameter.vendorExtensions.put("x-is-value-type", true);
} }
} }
if (!parameter.isContainer && this.getValueTypes().contains(parameter.dataType)) { if (!parameter.isContainer && this.getValueTypes().contains(parameter.dataType)) {
parameter.vendorExtensions.put(X_IS_VALUE_TYPE, true); parameter.vendorExtensions.put("x-is-value-type", true);
} }
} }
@@ -1628,7 +1624,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema; Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) { if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems(schema); Schema<?> items = getSchemaItems(schema);
return typeMapping.get("array") + "<" + getTypeDeclarationForArray(items) + ">"; return getSchemaType(target) + "<" + getTypeDeclarationForArray(items) + ">";
} else if (ModelUtils.isMapSchema(p)) { } else if (ModelUtils.isMapSchema(p)) {
// Should we also support maps of maps? // Should we also support maps of maps?
Schema<?> inner = ModelUtils.getAdditionalProperties(p); Schema<?> inner = ModelUtils.getAdditionalProperties(p);
@@ -1707,17 +1703,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
return toModelName(name) + "Tests"; return toModelName(name) + "Tests";
} }
protected CodegenModel getCodegenModel(String codegenModelName, Schema schema){
var key = new AbstractMap.SimpleEntry<>(codegenModelName, schema);
if(codegenModelNameAndSchemaKeyToCodegenModelCache.containsKey(key)){
return codegenModelNameAndSchemaKeyToCodegenModelCache.get(key);
}
CodegenModel model = super.fromModel(codegenModelName, schema);
codegenModelNameAndSchemaKeyToCodegenModelCache.put(key, model);
return model;
}
public void setNullableReferenceTypes(final Boolean nullReferenceTypesFlag) { public void setNullableReferenceTypes(final Boolean nullReferenceTypesFlag) {
this.nullReferenceTypesFlag = nullReferenceTypesFlag; this.nullReferenceTypesFlag = nullReferenceTypesFlag;
additionalProperties.put("nullableReferenceTypes", nullReferenceTypesFlag); additionalProperties.put("nullableReferenceTypes", nullReferenceTypesFlag);
@@ -2065,13 +2050,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen {
} else if (c == 'l') { } else if (c == 'l') {
modifiers.remove("CultureInvariant"); modifiers.remove("CultureInvariant");
} else { } else {
vendorExtensions.put(X_MODIFIER_PREFIX + c, c); vendorExtensions.put("x-modifier-" + c, c);
} }
} }
String regex = pattern.substring(start, end).replace("\"", "\"\""); String regex = pattern.substring(start, end).replace("\"", "\"\"");
vendorExtensions.put(X_REGEX, regex); vendorExtensions.put("x-regex", regex);
vendorExtensions.put(X_MODIFIERS, modifiers); vendorExtensions.put("x-modifiers", modifiers);
} }
} }

View File

@@ -37,7 +37,6 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.CodegenConstants.X_ENUM_BYTE;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -434,7 +433,7 @@ public abstract class AbstractFSharpCodegen extends DefaultCodegen implements Co
if (model.dataType.startsWith("byte")) { if (model.dataType.startsWith("byte")) {
// F# Actually supports byte and short enums, swagger spec only supports byte. // F# Actually supports byte and short enums, swagger spec only supports byte.
isByte = true; isByte = true;
model.vendorExtensions.put(X_ENUM_BYTE, true); model.vendorExtensions.put("x-enum-byte", true);
} else if (model.dataType.startsWith("int32")) { } else if (model.dataType.startsWith("int32")) {
isInteger = true; isInteger = true;
model.vendorExtensions.put("x-enum-integer", true); model.vendorExtensions.put("x-enum-integer", true);
@@ -488,7 +487,7 @@ public abstract class AbstractFSharpCodegen extends DefaultCodegen implements Co
// Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here. // Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here.
if (var.isEnum) { if (var.isEnum) {
if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums. if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums.
var.vendorExtensions.put(X_ENUM_BYTE, true); var.vendorExtensions.put("x-enum-byte", true);
var.isString = false; var.isString = false;
var.isLong = false; var.isLong = false;
var.isInteger = false; var.isInteger = false;

View File

@@ -1891,7 +1891,6 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
model.imports.add("Arrays"); model.imports.add("Arrays");
} else if ("set".equals(property.containerType)) { } else if ("set".equals(property.containerType)) {
model.imports.add("LinkedHashSet"); model.imports.add("LinkedHashSet");
model.imports.add("Arrays");
if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable if ((!openApiNullable || !property.isNullable) && jackson) { // cannot be wrapped to nullable
model.imports.add("JsonDeserialize"); model.imports.add("JsonDeserialize");
property.vendorExtensions.put("x-setter-extra-annotation", "@JsonDeserialize(as = LinkedHashSet.class)"); property.vendorExtensions.put("x-setter-extra-annotation", "@JsonDeserialize(as = LinkedHashSet.class)");

View File

@@ -119,7 +119,6 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen
convertPropertyToStringAndWriteBack(CodegenConstants.IMPL_FOLDER, this::setImplFolder); convertPropertyToStringAndWriteBack(CodegenConstants.IMPL_FOLDER, this::setImplFolder);
convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION, this::setUseBeanValidation); convertPropertyToBooleanAndWriteBack(USE_BEANVALIDATION, this::setUseBeanValidation);
convertPropertyToBooleanAndWriteBack(USE_TAGS, this::setUseTags); convertPropertyToBooleanAndWriteBack(USE_TAGS, this::setUseTags);
convertPropertyToBooleanAndWriteBack(JACKSON, this::setJackson);
} }
@Override @Override

View File

@@ -40,8 +40,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.X_MODIFIERS;
import static org.openapitools.codegen.CodegenConstants.X_REGEX;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
@@ -1355,9 +1353,9 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co
} }
} }
vendorExtensions.put(X_REGEX, regex.replace("\"", "\\\"")); vendorExtensions.put("x-regex", regex.replace("\"", "\\\""));
vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\"")); vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\""));
vendorExtensions.put(X_MODIFIERS, modifiers); vendorExtensions.put("x-modifiers", modifiers);
} }
} }

View File

@@ -34,7 +34,6 @@ import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.security.SecurityScheme;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.DocumentationFeature; import org.openapitools.codegen.meta.features.DocumentationFeature;
@@ -47,8 +46,6 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.CodegenConstants.X_MODIFIERS;
import static org.openapitools.codegen.CodegenConstants.X_REGEX;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public abstract class AbstractPythonConnexionServerCodegen extends AbstractPythonCodegen implements CodegenConfig { public abstract class AbstractPythonConnexionServerCodegen extends AbstractPythonCodegen implements CodegenConfig {
@@ -602,7 +599,7 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
@Override @Override
public String toModelImport(String name) { public String toModelImport(String name) {
String modelImport; String modelImport;
if (Strings.CS.startsWithAny(name, "import", "from")) { if (StringUtils.startsWithAny(name, "import", "from")) {
modelImport = name; modelImport = name;
} else { } else {
modelImport = "from "; modelImport = "from ";
@@ -746,8 +743,8 @@ public abstract class AbstractPythonConnexionServerCodegen extends AbstractPytho
} }
} }
vendorExtensions.put(X_REGEX, regex); vendorExtensions.put("x-regex", regex);
vendorExtensions.put(X_MODIFIERS, modifiers); vendorExtensions.put("x-modifiers", modifiers);
} }
} }
} }

View File

@@ -39,8 +39,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.openapitools.codegen.CodegenConstants.X_MODIFIERS;
import static org.openapitools.codegen.CodegenConstants.X_REGEX;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
public abstract class AbstractPythonPydanticV1Codegen extends DefaultCodegen implements CodegenConfig { public abstract class AbstractPythonPydanticV1Codegen extends DefaultCodegen implements CodegenConfig {
@@ -1917,9 +1915,9 @@ public abstract class AbstractPythonPydanticV1Codegen extends DefaultCodegen imp
} }
} }
vendorExtensions.put(X_REGEX, regex.replace("\"", "\\\"")); vendorExtensions.put("x-regex", regex.replace("\"", "\\\""));
vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\"")); vendorExtensions.put("x-pattern", pattern.replace("\"", "\\\""));
vendorExtensions.put(X_MODIFIERS, modifiers); vendorExtensions.put("x-modifiers", modifiers);
} }
} }

View File

@@ -37,7 +37,6 @@ import java.net.URL;
import java.util.*; import java.util.*;
import static java.util.UUID.randomUUID; import static java.util.UUID.randomUUID;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
public class AspNetServerCodegen extends AbstractCSharpCodegen { public class AspNetServerCodegen extends AbstractCSharpCodegen {
@@ -348,7 +347,7 @@ public class AspNetServerCodegen extends AbstractCSharpCodegen {
protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) { protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) {
super.updateCodegenParameterEnumLegacy(parameter, model); super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
parameter.dataType = parameter.dataType + "?"; parameter.dataType = parameter.dataType + "?";
} }
} }
@@ -628,7 +627,7 @@ public class AspNetServerCodegen extends AbstractCSharpCodegen {
super.patchProperty(enumRefs, model, property); super.patchProperty(enumRefs, model, property);
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) { if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true); property.vendorExtensions.put("x-csharp-value-type", true);
} }
} }

View File

@@ -39,7 +39,6 @@ import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isEmpty; import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -410,7 +409,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
super.updateCodegenParameterEnumLegacy(parameter, model); super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
parameter.dataType = parameter.dataType + "?"; parameter.dataType = parameter.dataType + "?";
} }
} }
@@ -437,7 +436,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) { if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) {
final Schema<?> parentModel = allDefinitions.get(toModelName(codegenModel.parent)); final Schema<?> parentModel = allDefinitions.get(toModelName(codegenModel.parent));
if (parentModel != null) { if (parentModel != null) {
final CodegenModel parentCodegenModel = getCodegenModel(codegenModel.parent, parentModel); final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
if (codegenModel.hasEnums) { if (codegenModel.hasEnums) {
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel); codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
} }
@@ -1627,7 +1626,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
if (!GENERICHOST.equals(getLibrary())) { if (!GENERICHOST.equals(getLibrary())) {
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) { if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true); property.vendorExtensions.put("x-csharp-value-type", true);
} }
} }
} }

View File

@@ -36,7 +36,6 @@ import java.net.URL;
import java.util.*; import java.util.*;
import static java.util.UUID.randomUUID; import static java.util.UUID.randomUUID;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen { public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen {
@@ -288,7 +287,7 @@ public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen {
super.patchProperty(enumRefs, model, property); super.patchProperty(enumRefs, model, property);
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) { if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true); property.vendorExtensions.put("x-csharp-value-type", true);
} }
} }
@@ -296,7 +295,7 @@ public class CSharpFunctionsServerCodegen extends AbstractCSharpCodegen {
protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) { protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) {
super.updateCodegenParameterEnumLegacy(parameter, model); super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
parameter.dataType = parameter.dataType + "?"; parameter.dataType = parameter.dataType + "?";
} }
} }

View File

@@ -37,7 +37,6 @@ import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isEmpty; import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.openapitools.codegen.CodegenConstants.X_CSHARP_VALUE_TYPE;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@@ -351,7 +350,7 @@ public class CSharpReducedClientCodegen extends AbstractCSharpCodegen {
super.patchProperty(enumRefs, model, property); super.patchProperty(enumRefs, model, property);
if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) { if (!property.isContainer && (this.getNullableTypes().contains(property.dataType) || property.isEnum)) {
property.vendorExtensions.put(X_CSHARP_VALUE_TYPE, true); property.vendorExtensions.put("x-csharp-value-type", true);
} }
} }
@@ -359,7 +358,7 @@ public class CSharpReducedClientCodegen extends AbstractCSharpCodegen {
protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) { protected void updateCodegenParameterEnum(CodegenParameter parameter, CodegenModel model) {
super.updateCodegenParameterEnumLegacy(parameter, model); super.updateCodegenParameterEnumLegacy(parameter, model);
if (!parameter.required && parameter.vendorExtensions.get(X_CSHARP_VALUE_TYPE) != null) { //optional if (!parameter.required && parameter.vendorExtensions.get("x-csharp-value-type") != null) { //optional
parameter.dataType = parameter.dataType + "?"; parameter.dataType = parameter.dataType + "?";
} }
} }
@@ -381,7 +380,7 @@ public class CSharpReducedClientCodegen extends AbstractCSharpCodegen {
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) { if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) {
final Schema parentModel = allDefinitions.get(toModelName(codegenModel.parent)); final Schema parentModel = allDefinitions.get(toModelName(codegenModel.parent));
if (parentModel != null) { if (parentModel != null) {
final CodegenModel parentCodegenModel = getCodegenModel(codegenModel.parent, parentModel); final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
if (codegenModel.hasEnums) { if (codegenModel.hasEnums) {
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel); codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
} }

View File

@@ -226,7 +226,6 @@ public class ElixirClientCodegen extends DefaultCodegen {
typeMapping.put("date", "Date.t"); typeMapping.put("date", "Date.t");
typeMapping.put("date-time", "DateTime.t"); typeMapping.put("date-time", "DateTime.t");
// other // other
typeMapping.put("AnyType", "any()");
typeMapping.put("ByteArray", "binary()"); typeMapping.put("ByteArray", "binary()");
typeMapping.put("DateTime", "DateTime.t"); typeMapping.put("DateTime", "DateTime.t");
typeMapping.put("UUID", "String.t"); typeMapping.put("UUID", "String.t");

View File

@@ -17,7 +17,6 @@
package org.openapitools.codegen.languages; package org.openapitools.codegen.languages;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Mustache;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
@@ -441,17 +440,6 @@ public class GoClientCodegen extends AbstractGoCodegen {
return null; return null;
} }
if (ModelUtils.isArraySchema(p)) {
StringJoiner joinedDefaultValues = new StringJoiner(", ");
Object defaultValues = p.getDefault();
if (defaultValues instanceof ArrayNode) {
for (var value : (ArrayNode) defaultValues) {
joinedDefaultValues.add(value.toString());
}
return "{" + joinedDefaultValues + "}";
}
}
return super.toDefaultValue(p); return super.toDefaultValue(p);
} }

View File

@@ -410,7 +410,6 @@ public class GoServerCodegen extends AbstractGoCodegen {
private void addConditionalImportInformation(OperationsMap operations) { private void addConditionalImportInformation(OperationsMap operations) {
boolean hasPathParams = false; boolean hasPathParams = false;
boolean hasBodyParams = false; boolean hasBodyParams = false;
boolean hasOptionalBodyParams = false;
for (CodegenOperation op : operations.getOperations().getOperation()) { for (CodegenOperation op : operations.getOperations().getOperation()) {
if (op.getHasPathParams()) { if (op.getHasPathParams()) {
@@ -419,14 +418,10 @@ public class GoServerCodegen extends AbstractGoCodegen {
if (op.getHasBodyParam()) { if (op.getHasBodyParam()) {
hasBodyParams = true; hasBodyParams = true;
} }
if (op.getHasOptionalBodyParam()) {
hasOptionalBodyParams = true;
}
} }
additionalProperties.put("hasPathParams", hasPathParams); additionalProperties.put("hasPathParams", hasPathParams);
additionalProperties.put("hasBodyParams", hasBodyParams); additionalProperties.put("hasBodyParams", hasBodyParams);
additionalProperties.put("hasOptionalBodyParams", hasOptionalBodyParams);
} }

View File

@@ -187,22 +187,19 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen supportingFiles.clear(); // Don't need extra files provided by AbstractJAX-RS & Java Codegen
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md") supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite()); .doNotOverwrite());
supportingFiles.add(new SupportingFile("RestResourceRoot.mustache",
if (!interfaceOnly) { (sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestResourceRoot.java")
supportingFiles.add(new SupportingFile("RestResourceRoot.mustache", .doNotOverwrite());
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestResourceRoot.java")
.doNotOverwrite());
supportingFiles.add(new SupportingFile("RestApplication.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestApplication.java")
.doNotOverwrite());
}
if (generatePom) { if (generatePom) {
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml") supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")
.doNotOverwrite()); .doNotOverwrite());
} }
supportingFiles.add(new SupportingFile("RestApplication.mustache",
(sourceFolder + '/' + invokerPackage).replace(".", "/"), "RestApplication.java")
.doNotOverwrite());
if (StringUtils.isNotEmpty(openApiSpecFileLocation)) { if (StringUtils.isNotEmpty(openApiSpecFileLocation)) {
int index = openApiSpecFileLocation.lastIndexOf('/'); int index = openApiSpecFileLocation.lastIndexOf('/');
String fileFolder; String fileFolder;
@@ -279,7 +276,6 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
if (!jackson) { if (!jackson) {
codegenModel.imports.remove("JsonValue"); codegenModel.imports.remove("JsonValue");
codegenModel.imports.remove("JsonProperty"); codegenModel.imports.remove("JsonProperty");
codegenModel.imports.remove("JsonTypeName");
} }
return codegenModel; return codegenModel;
} }

View File

@@ -996,7 +996,6 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
} }
return objs; return objs;
} }
private Stream<List<CodegenProperty>> getAllVarProperties(CodegenModel model) { private Stream<List<CodegenProperty>> getAllVarProperties(CodegenModel model) {
return Stream.of(model.vars, model.allVars, model.optionalVars, model.requiredVars, model.readOnlyVars, model.readWriteVars); return Stream.of(model.vars, model.allVars, model.optionalVars, model.requiredVars, model.readOnlyVars, model.readWriteVars);
} }
@@ -1114,27 +1113,6 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
return false; return false;
} }
@Override
public void postProcessParameter(CodegenParameter parameter) {
super.postProcessParameter(parameter);
adjustEnumRefDefault(parameter);
}
/**
* Properly set the default value for enum (reference).
*
* @param param codegen parameter
*/
private void adjustEnumRefDefault(CodegenParameter param) {
if (StringUtils.isEmpty(param.defaultValue) || !(param.isEnum || param.isEnumRef)) {
return;
}
String type = StringUtils.defaultIfEmpty(param.datatypeWithEnum, param.dataType);
param.enumDefaultValue = toEnumVarName(param.defaultValue, type);
param.defaultValue = type + "." + param.enumDefaultValue;
}
@Override @Override
public void postProcess() { public void postProcess() {
System.out.println("################################################################################"); System.out.println("################################################################################");

View File

@@ -1012,9 +1012,6 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
extensions.add(VendorExtension.X_DISCRIMINATOR_VALUE); extensions.add(VendorExtension.X_DISCRIMINATOR_VALUE);
extensions.add(VendorExtension.X_FIELD_EXTRA_ANNOTATION); extensions.add(VendorExtension.X_FIELD_EXTRA_ANNOTATION);
extensions.add(VendorExtension.X_PATTERN_MESSAGE); extensions.add(VendorExtension.X_PATTERN_MESSAGE);
extensions.add(VendorExtension.X_SIZE_MESSAGE);
extensions.add(VendorExtension.X_MINIMUM_MESSAGE);
extensions.add(VendorExtension.X_MAXIMUM_MESSAGE);
extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS); extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS);
extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS); extensions.add(VendorExtension.X_KOTLIN_IMPLEMENTS_FIELDS);
return extensions; return extensions;

View File

@@ -20,7 +20,7 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.Strings; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.meta.Stability;
@@ -157,8 +157,7 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
supportedLibraries.put("urllib3", "urllib3-based client"); supportedLibraries.put("urllib3", "urllib3-based client");
supportedLibraries.put("asyncio", "asyncio-based client"); supportedLibraries.put("asyncio", "asyncio-based client");
supportedLibraries.put("tornado", "tornado-based client (deprecated)"); supportedLibraries.put("tornado", "tornado-based client (deprecated)");
supportedLibraries.put("httpx", "httpx-based client"); CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use: asyncio, tornado (deprecated), urllib3, httpx");
libraryOption.setDefault(DEFAULT_LIBRARY); libraryOption.setDefault(DEFAULT_LIBRARY);
cliOptions.add(libraryOption); cliOptions.add(libraryOption);
setLibrary(DEFAULT_LIBRARY); setLibrary(DEFAULT_LIBRARY);
@@ -331,15 +330,10 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
if ("asyncio".equals(getLibrary())) { if ("asyncio".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packagePath(), "rest.py")); supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("async", "true");
additionalProperties.put("asyncio", "true"); additionalProperties.put("asyncio", "true");
} else if ("tornado".equals(getLibrary())) { } else if ("tornado".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packagePath(), "rest.py")); supportingFiles.add(new SupportingFile("tornado/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("tornado", "true"); additionalProperties.put("tornado", "true");
} else if ("httpx".equals(getLibrary())) {
supportingFiles.add(new SupportingFile("httpx/rest.mustache", packagePath(), "rest.py"));
additionalProperties.put("async", "true");
additionalProperties.put("httpx", "true");
} else { } else {
supportingFiles.add(new SupportingFile("rest.mustache", packagePath(), "rest.py")); supportingFiles.add(new SupportingFile("rest.mustache", packagePath(), "rest.py"));
} }
@@ -355,7 +349,7 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege
@Override @Override
public String toModelImport(String name) { public String toModelImport(String name) {
String modelImport; String modelImport;
if (Strings.CS.startsWithAny(name, "import", "from")) { if (StringUtils.startsWithAny(name, "import", "from")) {
modelImport = name; modelImport = name;
} else { } else {
modelImport = "from "; modelImport = "from ";

View File

@@ -23,7 +23,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.module.SimpleModule;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.GeneratorMetadata;
@@ -90,11 +89,6 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
public PythonFastAPIServerCodegen() { public PythonFastAPIServerCodegen() {
super(); super();
// Skip sorting of operations to preserve the order found in the OpenAPI spec file. See
// https://fastapi.tiangolo.com/tutorial/path-params/?h=path#order-matters for details on why order matters.
LOGGER.info("Skipping sorting of path operations, order matters, let the developer decide via their specification file.");
setSkipSortingOperations(true);
modifyFeatureSet(features -> features.includeSecurityFeatures( modifyFeatureSet(features -> features.includeSecurityFeatures(
SecurityFeature.OAuth2_AuthorizationCode, SecurityFeature.OAuth2_AuthorizationCode,
SecurityFeature.OAuth2_Password SecurityFeature.OAuth2_Password
@@ -204,7 +198,7 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
@Override @Override
public String toModelImport(String name) { public String toModelImport(String name) {
String modelImport; String modelImport;
if (Strings.CS.startsWithAny(name, "import", "from")) { if (StringUtils.startsWithAny(name, "import", "from")) {
modelImport = name; modelImport = name;
} else { } else {
modelImport = "from "; modelImport = "from ";

View File

@@ -20,7 +20,6 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.Strings;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.GeneratorMetadata;
@@ -354,7 +353,7 @@ public class PythonPydanticV1ClientCodegen extends AbstractPythonPydanticV1Codeg
@Override @Override
public String toModelImport(String name) { public String toModelImport(String name) {
String modelImport; String modelImport;
if (Strings.CS.startsWithAny(name, "import", "from")) { if (StringUtils.startsWithAny(name, "import", "from")) {
modelImport = name; modelImport = name;
} else { } else {
modelImport = "from "; modelImport = "from ";

View File

@@ -271,7 +271,6 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
supportingFiles.add(new SupportingFile("gem.mustache", libFolder, gemName + ".rb")); supportingFiles.add(new SupportingFile("gem.mustache", libFolder, gemName + ".rb"));
String gemFolder = libFolder + File.separator + gemName; String gemFolder = libFolder + File.separator + gemName;
supportingFiles.add(new SupportingFile("api_error.mustache", gemFolder, "api_error.rb")); supportingFiles.add(new SupportingFile("api_error.mustache", gemFolder, "api_error.rb"));
supportingFiles.add(new SupportingFile("api_model_base.mustache", gemFolder, "api_model_base.rb"));
supportingFiles.add(new SupportingFile("version.mustache", gemFolder, "version.rb")); supportingFiles.add(new SupportingFile("version.mustache", gemFolder, "version.rb"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));

View File

@@ -99,18 +99,6 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
public RustAxumServerCodegen() { public RustAxumServerCodegen() {
super(); super();
// The `#[validate(nested)]` macro relies on an internal field named `errors` to accumulate validation results. Therefore, defining a struct like this will fail:
//
// ```rust
// struct A {
// #[validate(nested)]
// errors: B,
// }
// ```
//
// To avoid this, either rename the field to something other than "errors", or reserve it.
this.reservedWords.add("errors");
modifyFeatureSet(features -> features modifyFeatureSet(features -> features
.wireFormatFeatures(EnumSet.of( .wireFormatFeatures(EnumSet.of(
WireFormatFeature.JSON, WireFormatFeature.JSON,
@@ -124,9 +112,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
.schemaSupportFeatures(EnumSet.of( .schemaSupportFeatures(EnumSet.of(
SchemaSupportFeature.Simple, SchemaSupportFeature.Simple,
SchemaSupportFeature.Composite, SchemaSupportFeature.Composite,
SchemaSupportFeature.oneOf, SchemaSupportFeature.oneOf
SchemaSupportFeature.anyOf,
SchemaSupportFeature.allOf
)) ))
.excludeGlobalFeatures( .excludeGlobalFeatures(
GlobalFeature.Info, GlobalFeature.Info,
@@ -647,180 +633,105 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
return op; return op;
} }
private void postProcessPolymorphism(final List<ModelMap> allModels) { private void postProcessOneOfModels(List<ModelMap> allModels) {
final HashMap<String, List<CodegenDiscriminator>> discriminatorsForModel = new HashMap<>(); final HashMap<String, List<String>> oneOfMapDiscriminator = new HashMap<>();
for (final ModelMap mo : allModels) { for (ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel(); final CodegenModel cm = mo.getModel();
final CodegenComposedSchemas cs = cm.getComposedSchemas(); final CodegenComposedSchemas cs = cm.getComposedSchemas();
if (cs != null) { if (cs != null) {
final List<CodegenProperty> csOneOf = cs.getOneOf(); final List<CodegenProperty> csOneOf = cs.getOneOf();
CodegenDiscriminator discriminator = cm.getDiscriminator();
if (csOneOf != null) { if (csOneOf != null) {
processPolymorphismDataType(csOneOf, discriminator); for (CodegenProperty model : csOneOf) {
// Generate a valid name for the enum variant.
// Mainly needed for primitive types.
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
.replace("<", "Of").replace(">", ""));
// Primitive type is not properly set, this overrides it to guarantee adequate model generation.
if (!model.getDataType().matches(String.format(Locale.ROOT, ".*::%s", model.getDatatypeWithEnum()))) {
model.isPrimitiveType = true;
}
}
cs.setOneOf(csOneOf); cs.setOneOf(csOneOf);
cm.setComposedSchemas(cs); cm.setComposedSchemas(cs);
} }
final List<CodegenProperty> csAnyOf = cs.getAnyOf();
if (csAnyOf != null) {
processPolymorphismDataType(csAnyOf, discriminator);
cs.setAnyOf(csAnyOf);
cm.setComposedSchemas(cs);
}
} }
if (cm.discriminator != null) { if (cm.discriminator != null) {
for (final String model : cm.oneOf) { for (String model : cm.oneOf) {
final List<CodegenDiscriminator> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>()); List<String> discriminators = oneOfMapDiscriminator.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator); discriminators.add(cm.discriminator.getPropertyName());
discriminatorsForModel.put(model, discriminators); oneOfMapDiscriminator.put(model, discriminators);
}
for (final String model : cm.anyOf) {
final List<CodegenDiscriminator> discriminators = discriminatorsForModel.getOrDefault(model, new ArrayList<>());
discriminators.add(cm.discriminator);
discriminatorsForModel.put(model, discriminators);
} }
} }
} }
final var blocking = new HashSet<String>();
for (ModelMap mo : allModels) { for (ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel(); final CodegenModel cm = mo.getModel();
final List<CodegenDiscriminator> discriminators = discriminatorsForModel.get(cm.getSchemaName()); for (CodegenProperty var : cm.vars) {
if (discriminators != null) { var.isDiscriminator = false;
// If the discriminator field is not a defined attribute in the variant structure, create it. }
if (!discriminating(discriminators, cm)) {
final CodegenDiscriminator discriminator = discriminators.get(0);
CodegenProperty property = new CodegenProperty(); final List<String> discriminatorsForModel = oneOfMapDiscriminator.get(cm.getSchemaName());
// Static attributes if (discriminatorsForModel != null) {
// Only strings are supported by serde for tag field types, so it's the only one we'll deal with for (String discriminator : discriminatorsForModel) {
property.openApiType = "string"; boolean hasDiscriminatorDefined = false;
property.complexType = "string";
property.dataType = "String";
property.datatypeWithEnum = "String";
property.baseType = "string";
property.required = true;
property.isPrimitiveType = true;
property.isString = true;
property.isDiscriminator = true;
// Attributes based on the discriminator value for (CodegenProperty var : cm.vars) {
property.baseName = discriminator.getPropertyBaseName(); if (var.baseName.equals(discriminator)) {
property.name = discriminator.getPropertyName(); var.isDiscriminator = true;
property.nameInCamelCase = camelize(discriminator.getPropertyName()); hasDiscriminatorDefined = true;
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1); break;
property.nameInSnakeCase = underscore(discriminator.getPropertyName()).toUpperCase(Locale.ROOT); }
property.getter = String.format(Locale.ROOT, "get%s", property.nameInPascalCase); }
property.setter = String.format(Locale.ROOT, "set%s", property.nameInPascalCase);
property.defaultValueWithParam = String.format(Locale.ROOT, " = data.%s;", property.name);
// Attributes based on the model name // If the discriminator field is not a defined attribute in the variant structure, create it.
property.defaultValue = String.format(Locale.ROOT, "r#\"%s\"#.to_string()", cm.getSchemaName()); if (!hasDiscriminatorDefined) {
property.discriminatorValue = getDiscriminatorValue(cm.getClassname(), discriminator); CodegenProperty property = new CodegenProperty();
property.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());
cm.vars.add(property); // Static attributes
// Only strings are supported by serde for tag field types, so it's the only one we'll deal with
property.openApiType = "string";
property.complexType = "string";
property.dataType = "String";
property.datatypeWithEnum = "String";
property.baseType = "string";
property.required = true;
property.isPrimitiveType = true;
property.isString = true;
property.isDiscriminator = true;
// Attributes based on the discriminator value
property.baseName = discriminator;
property.name = discriminator;
property.nameInCamelCase = camelize(discriminator);
property.nameInPascalCase = property.nameInCamelCase.substring(0, 1).toUpperCase(Locale.ROOT) + property.nameInCamelCase.substring(1);
property.nameInSnakeCase = underscore(discriminator).toUpperCase(Locale.ROOT);
property.getter = String.format(Locale.ROOT, "get%s", property.nameInPascalCase);
property.setter = String.format(Locale.ROOT, "set%s", property.nameInPascalCase);
property.defaultValueWithParam = String.format(Locale.ROOT, " = data.%s;", property.name);
// Attributes based on the model name
property.defaultValue = String.format(Locale.ROOT, "r#\"%s\"#.to_string()", cm.getSchemaName());
property.jsonSchema = String.format(Locale.ROOT, "{ \"default\":\"%s\"; \"type\":\"string\" }", cm.getSchemaName());
cm.vars.add(property);
}
} }
} }
if (cm.vars.stream().noneMatch(v -> v.isDiscriminator)) {
blocking.add(cm.getSchemaName());
}
}
for (final ModelMap mo : allModels) {
final CodegenModel cm = mo.getModel();
if (cm.discriminator != null) {
// if no discriminator in any of variant -> disable discriminator
if (cm.oneOf.stream().anyMatch(blocking::contains) || cm.anyOf.stream().anyMatch(blocking::contains)) {
cm.discriminator = null;
}
}
}
}
private static String getDiscriminatorValue(String modelName, CodegenDiscriminator discriminator) {
if (discriminator == null || discriminator.getMappedModels() == null) {
return modelName;
}
return discriminator
.getMappedModels()
.stream()
.filter(m -> m.getModelName().equals(modelName) && m.getMappingName() != null)
.map(CodegenDiscriminator.MappedModel::getMappingName)
.findFirst()
.orElse(modelName);
}
private static boolean discriminating(final List<CodegenDiscriminator> discriminatorsForModel, final CodegenModel cm) {
resetDiscriminatorProperty(cm);
// Discriminator will be presented as enum tag -> One and only one tag is allowed
int countString = 0;
int countNonString = 0;
for (final CodegenProperty var : cm.vars) {
if (discriminatorsForModel.stream().anyMatch(discriminator -> var.baseName.equals(discriminator.getPropertyBaseName()) || var.name.equals(discriminator.getPropertyName()))) {
if (var.isString) {
var.isDiscriminator = true;
++countString;
} else
++countNonString;
}
}
if (countString > 0 && (countNonString > 0 || countString > 1)) {
// at least two discriminator, one of them is string -> should not render serde tag
resetDiscriminatorProperty(cm);
}
return countNonString > 0 || countString > 0;
}
private static void resetDiscriminatorProperty(final CodegenModel cm) {
for (final CodegenProperty var : cm.vars) {
var.isDiscriminator = false;
}
}
private static void processPolymorphismDataType(final List<CodegenProperty> cp, CodegenDiscriminator discriminator) {
final HashSet<String> dedupDataTypeWithEnum = new HashSet<>();
final HashMap<String, Integer> dedupDataType = new HashMap<>();
int idx = 0;
for (CodegenProperty model : cp) {
// Generate a valid name for the enum variant.
// Mainly needed for primitive types.
model.datatypeWithEnum = camelize(model.dataType.replaceAll("(?:\\w+::)+(\\w+)", "$1")
.replace("<", "Of").replace(">", "")).replace(" ", "").replace(",", "");
model.discriminatorValue = getDiscriminatorValue(model.datatypeWithEnum, discriminator);
if (!dedupDataTypeWithEnum.add(model.datatypeWithEnum)) {
model.datatypeWithEnum += ++idx;
}
dedupDataType.put(model.getDataType(), dedupDataType.getOrDefault(model.getDataType(), 0) + 1);
if (!model.getDataType().matches(String.format(Locale.ROOT, ".*::%s", model.getDatatypeWithEnum()))) {
model.isPrimitiveType = true;
}
}
for (CodegenProperty model : cp) {
if (dedupDataType.get(model.getDataType()) == 1) {
model.vendorExtensions.put("x-from-trait", true);
}
} }
} }
@Override @Override
public OperationsMap postProcessOperationsWithModels(final OperationsMap operationsMap, List<ModelMap> allModels) { public OperationsMap postProcessOperationsWithModels(final OperationsMap operationsMap, List<ModelMap> allModels) {
postProcessPolymorphism(allModels); postProcessOneOfModels(allModels);
final OperationMap operations = operationsMap.getOperations(); final OperationMap operations = operationsMap.getOperations();
operations.put("classnamePascalCase", camelize(operations.getClassname())); operations.put("classnamePascalCase", camelize(operations.getClassname()));
@@ -878,24 +789,6 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
} }
if (op.bodyParam != null) { if (op.bodyParam != null) {
final var dataType = op.bodyParam.dataType;
if (dataType.startsWith(vecType + "<String")) {
op.bodyParam.vendorExtensions.put("is-vec-string", true);
} else if (dataType.startsWith(vecType + "<models::")) {
op.bodyParam.vendorExtensions.put("is-vec-nested", true);
} else if (dataType.startsWith(mapType + "<String, String")) {
op.bodyParam.vendorExtensions.put("is-map-string", true);
} else if (dataType.startsWith(mapType + "<String, models::")) {
op.bodyParam.vendorExtensions.put("is-map-nested", true);
} else if (dataType.startsWith(mapType + "<String")) {
op.bodyParam.vendorExtensions.put("is-map", true);
} else if (dataType.startsWith("models::")) {
op.bodyParam.isModel = true;
} else if (dataType.equals("String")) {
op.bodyParam.isString = true;
op.bodyParam.vendorExtensions.put("is-string", true);
}
if (consumesJson) { if (consumesJson) {
op.bodyParam.vendorExtensions.put("x-consumes-json", true); op.bodyParam.vendorExtensions.put("x-consumes-json", true);
} else if (consumesFormUrlEncoded) { } else if (consumesFormUrlEncoded) {
@@ -1008,7 +901,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
// restore things to sensible values. // restore things to sensible values.
@Override @Override
public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) { public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) {
final var original_schema = ModelUtils.getSchemaFromRequestBody(body); final Schema original_schema = ModelUtils.getSchemaFromRequestBody(body);
CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName); CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName);
if (StringUtils.isNotBlank(original_schema.get$ref())) { if (StringUtils.isNotBlank(original_schema.get$ref())) {
@@ -1027,10 +920,10 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
@Override @Override
public String toInstantiationType(final Schema p) { public String toInstantiationType(final Schema p) {
if (ModelUtils.isArraySchema(p)) { if (ModelUtils.isArraySchema(p)) {
final var inner = ModelUtils.getSchemaItems(p); final Schema inner = ModelUtils.getSchemaItems(p);
return instantiationTypes.get("array") + "<" + getSchemaType(inner) + ">"; return instantiationTypes.get("array") + "<" + getSchemaType(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) { } else if (ModelUtils.isMapSchema(p)) {
final var inner = ModelUtils.getAdditionalProperties(p); final Schema inner = ModelUtils.getAdditionalProperties(p);
return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSchemaType(inner) + ">"; return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSchemaType(inner) + ">";
} else { } else {
return null; return null;
@@ -1059,10 +952,6 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
@Override @Override
public String toDefaultValue(final Schema p) { public String toDefaultValue(final Schema p) {
String defaultValue = null; String defaultValue = null;
if (ModelUtils.isEnumSchema(p))
return null;
if ((ModelUtils.isNullable(p)) && (p.getDefault() != null) && ("null".equalsIgnoreCase(p.getDefault().toString()))) if ((ModelUtils.isNullable(p)) && (p.getDefault() != null) && ("null".equalsIgnoreCase(p.getDefault().toString())))
return "Nullable::Null"; return "Nullable::Null";
@@ -1076,9 +965,6 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
} else if (ModelUtils.isNumberSchema(p)) { } else if (ModelUtils.isNumberSchema(p)) {
if (p.getDefault() != null) { if (p.getDefault() != null) {
defaultValue = p.getDefault().toString(); defaultValue = p.getDefault().toString();
if (!defaultValue.contains(".")) {
defaultValue += ".0";
}
} }
} else if (ModelUtils.isIntegerSchema(p)) { } else if (ModelUtils.isIntegerSchema(p)) {
if (p.getDefault() != null) { if (p.getDefault() != null) {
@@ -1195,7 +1081,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
String cmd = System.getenv("RUST_POST_PROCESS_FILE"); String cmd = System.getenv("RUST_POST_PROCESS_FILE");
if (StringUtils.isEmpty(cmd)) { if (StringUtils.isEmpty(cmd)) {
cmd = "rustfmt"; cmd = "rustfmt";
command = new String[]{cmd, "--edition", "2024", fileName}; command = new String[]{cmd, "--edition", "2021", fileName};
} else { } else {
command = new String[]{cmd, fileName}; command = new String[]{cmd, fileName};
} }
@@ -1207,7 +1093,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
} }
@Override @Override
protected void updateParameterForString(CodegenParameter codegenParameter, final Schema parameterSchema) { protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema) {
if (ModelUtils.isEmailSchema(parameterSchema)) { if (ModelUtils.isEmailSchema(parameterSchema)) {
codegenParameter.isEmail = true; codegenParameter.isEmail = true;
} else if (ModelUtils.isUUIDSchema(parameterSchema)) { } else if (ModelUtils.isUUIDSchema(parameterSchema)) {
@@ -1234,7 +1120,7 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
codegenParameter.isDecimal = true; codegenParameter.isDecimal = true;
codegenParameter.isPrimitiveType = true; codegenParameter.isPrimitiveType = true;
} }
if (codegenParameter.isString) { if (Boolean.TRUE.equals(codegenParameter.isString)) {
codegenParameter.isPrimitiveType = true; codegenParameter.isPrimitiveType = true;
} }
} }
@@ -1266,16 +1152,6 @@ public class RustAxumServerCodegen extends AbstractRustCodegen implements Codege
return null; return null;
} }
@Override
public String toVarName(String name) {
final var varName = super.toVarName(name);
if (varName.startsWith("r#"))
return "r_" + varName.substring(2);
return varName;
}
static class PathMethodOperations { static class PathMethodOperations {
public String path; public String path;
public ArrayList<MethodOperation> methodOperations; public ArrayList<MethodOperation> methodOperations;

View File

@@ -58,7 +58,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
@Setter private boolean preferUnsignedInt = false; @Setter private boolean preferUnsignedInt = false;
@Setter private boolean bestFitInt = false; @Setter private boolean bestFitInt = false;
@Setter private boolean avoidBoxedModels = false; @Setter private boolean avoidBoxedModels = false;
private List<String> reqwestDefaultFeatures = Arrays.asList("native-tls");
public static final String PACKAGE_NAME = "packageName"; public static final String PACKAGE_NAME = "packageName";
public static final String EXTERN_CRATE_NAME = "externCrateName"; public static final String EXTERN_CRATE_NAME = "externCrateName";
@@ -78,7 +77,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
public static final String TOP_LEVEL_API_CLIENT = "topLevelApiClient"; public static final String TOP_LEVEL_API_CLIENT = "topLevelApiClient";
public static final String MOCKALL = "mockall"; public static final String MOCKALL = "mockall";
public static final String BON_BUILDER = "useBonBuilder"; public static final String BON_BUILDER = "useBonBuilder";
public static final String REQWEST_DEFAULT_FEATURES = "reqwestDefaultFeatures";
@Setter protected String packageName = "openapi"; @Setter protected String packageName = "openapi";
@Setter protected String packageVersion = "1.0.0"; @Setter protected String packageVersion = "1.0.0";
@@ -229,8 +227,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
.defaultValue(Boolean.FALSE.toString())); .defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(BON_BUILDER, "Use the bon crate for building parameter types. This option is for the 'reqwest-trait' library only", SchemaTypeUtil.BOOLEAN_TYPE) cliOptions.add(new CliOption(BON_BUILDER, "Use the bon crate for building parameter types. This option is for the 'reqwest-trait' library only", SchemaTypeUtil.BOOLEAN_TYPE)
.defaultValue(Boolean.FALSE.toString())); .defaultValue(Boolean.FALSE.toString()));
cliOptions.add(new CliOption(REQWEST_DEFAULT_FEATURES, "Default features for the reqwest dependency (comma-separated). Use empty for no defaults. This option is for 'reqwest' and 'reqwest-trait' library only.")
.defaultValue("native-tls"));
supportedLibraries.put(HYPER_LIBRARY, "HTTP client: Hyper (v1.x)."); supportedLibraries.put(HYPER_LIBRARY, "HTTP client: Hyper (v1.x).");
supportedLibraries.put(HYPER0X_LIBRARY, "HTTP client: Hyper (v0.x)."); supportedLibraries.put(HYPER0X_LIBRARY, "HTTP client: Hyper (v0.x).");
@@ -311,6 +307,69 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
mdl.getComposedSchemas().setOneOf(newOneOfs); mdl.getComposedSchemas().setOneOf(newOneOfs);
} }
// Handle anyOf schemas similarly to oneOf
// This is pragmatic since Rust's untagged enum will deserialize to the first matching variant
if (mdl.getComposedSchemas() != null && mdl.getComposedSchemas().getAnyOf() != null
&& !mdl.getComposedSchemas().getAnyOf().isEmpty()) {
List<CodegenProperty> newAnyOfs = mdl.getComposedSchemas().getAnyOf().stream()
.map(CodegenProperty::clone)
.collect(Collectors.toList());
List<Schema> schemas = ModelUtils.getInterfaces(model);
if (newAnyOfs.size() != schemas.size()) {
// For safety reasons, this should never happen unless there is an error in the code
throw new RuntimeException("anyOf size does not match the model");
}
Map<String, String> refsMapping = Optional.ofNullable(model.getDiscriminator())
.map(Discriminator::getMapping).orElse(Collections.emptyMap());
// Reverse mapped references to use as baseName for anyOf, but different keys may point to the same $ref.
// Thus, we group them by the value
Map<String, List<String>> mappedNamesByRef = refsMapping.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())
));
for (int i = 0; i < newAnyOfs.size(); i++) {
CodegenProperty anyOf = newAnyOfs.get(i);
Schema schema = schemas.get(i);
if (mappedNamesByRef.containsKey(schema.get$ref())) {
// prefer mapped names if present
// remove mapping not in order not to reuse for the next occurrence of the ref
List<String> names = mappedNamesByRef.get(schema.get$ref());
String mappedName = names.remove(0);
anyOf.setBaseName(mappedName);
anyOf.setName(toModelName(mappedName));
} else if (!org.apache.commons.lang3.StringUtils.isEmpty(schema.get$ref())) {
// use $ref if it's reference
String refName = ModelUtils.getSimpleRef(schema.get$ref());
if (refName != null) {
String modelName = toModelName(refName);
anyOf.setName(modelName);
anyOf.setBaseName(refName);
}
} else if (anyOf.isArray) {
// If the type is an array, extend the name with the inner type to prevent name collisions
// in case multiple arrays with different types are defined. If the user has manually specified
// a name, use that name instead.
String collectionWithTypeName = toModelName(schema.getType()) + anyOf.containerTypeMapped + anyOf.items.dataType;
String anyOfName = Optional.ofNullable(schema.getTitle()).orElse(collectionWithTypeName);
anyOf.setName(anyOfName);
}
else {
// In-placed type (primitive), because there is no mapping or ref for it.
// use camelized `title` if present, otherwise use `type`
String anyOfName = Optional.ofNullable(schema.getTitle()).orElseGet(schema::getType);
anyOf.setName(toModelName(anyOfName));
}
}
// Set anyOf as oneOf for template processing since we want the same output
mdl.getComposedSchemas().setOneOf(newAnyOfs);
}
return mdl; return mdl;
} }
@@ -435,21 +494,6 @@ public class RustClientCodegen extends AbstractRustCodegen implements CodegenCon
} }
writePropertyBack(AVOID_BOXED_MODELS, getAvoidBoxedModels()); writePropertyBack(AVOID_BOXED_MODELS, getAvoidBoxedModels());
if (additionalProperties.containsKey(REQWEST_DEFAULT_FEATURES)) {
Object value = additionalProperties.get(REQWEST_DEFAULT_FEATURES);
if (value instanceof List) {
reqwestDefaultFeatures = (List<String>) value;
} else if (value instanceof String) {
String str = (String) value;
if (str.isEmpty()) {
reqwestDefaultFeatures = new ArrayList<>();
} else {
reqwestDefaultFeatures = Arrays.asList(str.split(",\\s*"));
}
}
}
additionalProperties.put(REQWEST_DEFAULT_FEATURES, reqwestDefaultFeatures);
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion); additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
additionalProperties.put(EXTERN_CRATE_NAME, getExternCrateName()); additionalProperties.put(EXTERN_CRATE_NAME, getExternCrateName());

View File

@@ -1408,7 +1408,6 @@ public class RustServerCodegen extends AbstractRustCodegen implements CodegenCon
* *
* @deprecated Avoid using this - use a different mechanism instead. * @deprecated Avoid using this - use a different mechanism instead.
*/ */
@Deprecated
private static String stripNullable(String type) { private static String stripNullable(String type) {
if (type.startsWith("swagger::Nullable<") && type.endsWith(">")) { if (type.startsWith("swagger::Nullable<") && type.endsWith(">")) {
return type.substring("swagger::Nullable<".length(), type.length() - 1); return type.substring("swagger::Nullable<".length(), type.length() - 1);

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