From e950e2c3b243aa3d952160ae37ab42cba8c26b24 Mon Sep 17 00:00:00 2001 From: DavidGrath Date: Tue, 18 Mar 2025 21:45:24 +0100 Subject: [PATCH 1/4] Fix issue #20195 --- .../resources/typescript-fetch/apis.mustache | 2 +- .../TypeScriptFetchClientCodegenTest.java | 25 ++++++ .../src/test/resources/bugs/issue_20195.json | 77 +++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 modules/openapi-generator/src/test/resources/bugs/issue_20195.json diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache index 6c50de8a5a68..59fa1f75d57b 100644 --- a/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache @@ -265,7 +265,7 @@ export class {{classname}} extends runtime.BaseAPI { {{/isEnumRef}} {{^isEnumRef}} {{^withoutRuntimeChecks}} - formParams.append('{{baseName}}', new Blob([JSON.stringify({{{dataType}}}ToJSON(requestParameters['{{paramName}}']))], { type: "application/json", })); + formParams.append('{{baseName}}', new Blob([JSON.stringify({{returnType}}ToJSON(requestParameters['{{paramName}}']))], { type: "application/json", })); {{/withoutRuntimeChecks}}{{#withoutRuntimeChecks}} formParams.append('{{baseName}}', new Blob([JSON.stringify(requestParameters['{{paramName}}'])], { type: "application/json", })); {{/withoutRuntimeChecks}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java index 0145f4890f4a..d1a6d8e43016 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/fetch/TypeScriptFetchClientCodegenTest.java @@ -347,6 +347,31 @@ public void testGeneratedFilenamesInCamelCaseWithAdditionalModelPrefix() throws TestUtils.assertFileExists(Paths.get(output + "/apis/petControllerApi.ts")); } + @Test(description = "Issue #20195") + public void givenObjectHasAdditionalPropertiesWhenGenerateThenIndexSignatureNotUsedToGenerateMethodName() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + TypeScriptFetchClientCodegen clientCodegen = new TypeScriptFetchClientCodegen(); + clientCodegen.setWithoutRuntimeChecks(false); + clientCodegen.setOutputDir(output.getAbsolutePath()); + + Map properties = new HashMap<>(); + properties.put(TypeScriptFetchClientCodegen.WITH_INTERFACES, true); + properties.put(CodegenConstants.ENUM_PROPERTY_NAMING, "original"); + clientCodegen.additionalProperties().putAll(properties); + + DefaultGenerator defaultGenerator = new DefaultGenerator(); + defaultGenerator.opts( + new ClientOptInput().openAPI(TestUtils.parseSpec("src/test/resources/bugs/issue_20195.json")) + .config(clientCodegen) + ).generate(); + + String outputPath = output.getAbsolutePath(); + Path exampleApiPath = Paths.get(outputPath + "/apis/ExampleApi.ts"); + TestUtils.assertFileContains(exampleApiPath, "new Blob([JSON.stringify(ResponseOfStringToJSON"); + } + private static File generate(Map properties) throws IOException { File output = Files.createTempDirectory("test").toFile(); output.deleteOnExit(); diff --git a/modules/openapi-generator/src/test/resources/bugs/issue_20195.json b/modules/openapi-generator/src/test/resources/bugs/issue_20195.json new file mode 100644 index 000000000000..46b7c00b01fc --- /dev/null +++ b/modules/openapi-generator/src/test/resources/bugs/issue_20195.json @@ -0,0 +1,77 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Sample API", + "description": "This is sample api", + "version": "v1" + }, + "paths": { + "/example_api_101": { + "post": { + "tags": [ + "Example" + ], + "summary": "Process Auth", + "parameters": [ + { + "name": "Id", + "in": "query", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "paRes": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Form sent for Authentication" + } + } + }, + "encoding": { + "paRes": { + "style": "form" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseOfString" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ResponseOfString": { + "type": "object", + "properties": { + "message": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + } +} \ No newline at end of file From 4c82037a23174d5babf85264b19d1a943f49d018 Mon Sep 17 00:00:00 2001 From: DavidGrath Date: Tue, 18 Mar 2025 22:12:10 +0100 Subject: [PATCH 2/4] Ran export_docs_generators.sh --- docs/generators/fsharp-functions.md | 2 +- docs/generators/fsharp-giraffe-server.md | 2 +- docs/generators/java-inflector.md | 2 +- docs/generators/jaxrs-cxf-client.md | 2 +- docs/generators/swift5.md | 4 ++-- docs/generators/swift6.md | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/generators/fsharp-functions.md b/docs/generators/fsharp-functions.md index a20382152aab..33bd1f1c2922 100644 --- a/docs/generators/fsharp-functions.md +++ b/docs/generators/fsharp-functions.md @@ -34,7 +34,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |sortModelPropertiesByRequiredFlag|Sort model properties 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| |OpenAPI/src| +|sourceFolder|source folder for generated code| |OpenAPI\src| ## IMPORT MAPPING diff --git a/docs/generators/fsharp-giraffe-server.md b/docs/generators/fsharp-giraffe-server.md index abe079e504fa..fb3e25b3d776 100644 --- a/docs/generators/fsharp-giraffe-server.md +++ b/docs/generators/fsharp-giraffe-server.md @@ -30,7 +30,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |packageVersion|F# package version.| |1.0.0| |returnICollection|Return ICollection<T> instead of the concrete type.| |false| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|sourceFolder|source folder for generated code| |OpenAPI/src| +|sourceFolder|source folder for generated code| |OpenAPI\src| |useCollection|Deserialize array types to Collection<T> instead of List<T>.| |false| |useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false| |useSwashbuckle|Uses the Swashbuckle.AspNetCore NuGet package for documentation.| |false| diff --git a/docs/generators/java-inflector.md b/docs/generators/java-inflector.md index 210db1efcb9a..6fa2edb47f90 100644 --- a/docs/generators/java-inflector.md +++ b/docs/generators/java-inflector.md @@ -66,7 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |snapshotVersion|Uses a SNAPSHOT version.|
**true**
Use a SnapShot Version
**false**
Use a Release Version
|null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|sourceFolder|source folder for generated code| |src/gen/java| +|sourceFolder|source folder for generated code| |src\gen\java| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| |useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false| diff --git a/docs/generators/jaxrs-cxf-client.md b/docs/generators/jaxrs-cxf-client.md index 29a7923078b0..d89f12fbf3ab 100644 --- a/docs/generators/jaxrs-cxf-client.md +++ b/docs/generators/jaxrs-cxf-client.md @@ -66,7 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |snapshotVersion|Uses a SNAPSHOT version.|
**true**
Use a SnapShot Version
**false**
Use a Release Version
|null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|sourceFolder|source folder for generated code| |src/gen/java| +|sourceFolder|source folder for generated code| |src\gen\java| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false| |useBeanValidation|Use BeanValidation API annotations| |false| diff --git a/docs/generators/swift5.md b/docs/generators/swift5.md index 9d565bf5993f..df0b0e1f3ccd 100644 --- a/docs/generators/swift5.md +++ b/docs/generators/swift5.md @@ -49,13 +49,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl |responseAs|Optionally use libraries to manage response. Currently PromiseKit, RxSwift, Result, Combine, AsyncAwait are available.| |null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|swiftPackagePath|Set a custom source path instead of OpenAPIClient/Classes/OpenAPIs.| |null| +|swiftPackagePath|Set a custom source path instead of OpenAPIClient\Classes\OpenAPIs.| |null| |swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null| |useBacktickEscapes|Escape reserved words using backticks (default: false)| |false| |useClasses|Use final classes for models instead of structs (default: false)| |false| |useCustomDateWithoutTime|Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)| |false| |useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true| -|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null| +|useSPMFileStructure|Use SPM file structure and set the source path to Sources\{{projectName}} (default: false).| |null| |validatable|Make validation rules and validator for model properties (default: true)| |true| ## IMPORT MAPPING diff --git a/docs/generators/swift6.md b/docs/generators/swift6.md index a49865462eba..f19516ff2449 100644 --- a/docs/generators/swift6.md +++ b/docs/generators/swift6.md @@ -51,13 +51,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl |responseAs|Optionally use libraries to manage response. Currently AsyncAwait, Combine, Result, RxSwift, ObjcBlock, PromiseKit are available.| |null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|swiftPackagePath|Set a custom source path instead of Sources/{{projectName}}.| |null| +|swiftPackagePath|Set a custom source path instead of Sources\{{projectName}}.| |null| |swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null| |useBacktickEscapes|Escape reserved words using backticks (default: false)| |false| |useClasses|Use final classes for models instead of structs (default: false)| |false| |useCustomDateWithoutTime|Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)| |false| |useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true| -|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: true).| |null| +|useSPMFileStructure|Use SPM file structure and set the source path to Sources\{{projectName}} (default: true).| |null| |validatable|Make validation rules and validator for model properties (default: true)| |true| ## IMPORT MAPPING From 0d6041f53375a96320ba1020a48b51c61f934f54 Mon Sep 17 00:00:00 2001 From: DavidGrath Date: Wed, 19 Mar 2025 18:10:02 +0100 Subject: [PATCH 3/4] Generated path separators fixed --- docs/generators/fsharp-functions.md | 2 +- docs/generators/fsharp-giraffe-server.md | 2 +- docs/generators/java-inflector.md | 2 +- docs/generators/jaxrs-cxf-client.md | 2 +- docs/generators/swift5.md | 4 ++-- docs/generators/swift6.md | 4 ++-- .../tests/default/package-lock.json | 15 --------------- 7 files changed, 8 insertions(+), 23 deletions(-) diff --git a/docs/generators/fsharp-functions.md b/docs/generators/fsharp-functions.md index 33bd1f1c2922..a20382152aab 100644 --- a/docs/generators/fsharp-functions.md +++ b/docs/generators/fsharp-functions.md @@ -34,7 +34,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false| |sortModelPropertiesByRequiredFlag|Sort model properties 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| |OpenAPI\src| +|sourceFolder|source folder for generated code| |OpenAPI/src| ## IMPORT MAPPING diff --git a/docs/generators/fsharp-giraffe-server.md b/docs/generators/fsharp-giraffe-server.md index fb3e25b3d776..abe079e504fa 100644 --- a/docs/generators/fsharp-giraffe-server.md +++ b/docs/generators/fsharp-giraffe-server.md @@ -30,7 +30,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |packageVersion|F# package version.| |1.0.0| |returnICollection|Return ICollection<T> instead of the concrete type.| |false| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|sourceFolder|source folder for generated code| |OpenAPI\src| +|sourceFolder|source folder for generated code| |OpenAPI/src| |useCollection|Deserialize array types to Collection<T> instead of List<T>.| |false| |useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false| |useSwashbuckle|Uses the Swashbuckle.AspNetCore NuGet package for documentation.| |false| diff --git a/docs/generators/java-inflector.md b/docs/generators/java-inflector.md index 6fa2edb47f90..210db1efcb9a 100644 --- a/docs/generators/java-inflector.md +++ b/docs/generators/java-inflector.md @@ -66,7 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |snapshotVersion|Uses a SNAPSHOT version.|
**true**
Use a SnapShot Version
**false**
Use a Release Version
|null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|sourceFolder|source folder for generated code| |src\gen\java| +|sourceFolder|source folder for generated code| |src/gen/java| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| |useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false| diff --git a/docs/generators/jaxrs-cxf-client.md b/docs/generators/jaxrs-cxf-client.md index d89f12fbf3ab..29a7923078b0 100644 --- a/docs/generators/jaxrs-cxf-client.md +++ b/docs/generators/jaxrs-cxf-client.md @@ -66,7 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |snapshotVersion|Uses a SNAPSHOT version.|
**true**
Use a SnapShot Version
**false**
Use a Release Version
|null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|sourceFolder|source folder for generated code| |src\gen\java| +|sourceFolder|source folder for generated code| |src/gen/java| |testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi| |useAbstractionForFiles|Use alternative types instead of java.io.File to allow passing bytes without a file on disk.| |false| |useBeanValidation|Use BeanValidation API annotations| |false| diff --git a/docs/generators/swift5.md b/docs/generators/swift5.md index df0b0e1f3ccd..9d565bf5993f 100644 --- a/docs/generators/swift5.md +++ b/docs/generators/swift5.md @@ -49,13 +49,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl |responseAs|Optionally use libraries to manage response. Currently PromiseKit, RxSwift, Result, Combine, AsyncAwait are available.| |null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|swiftPackagePath|Set a custom source path instead of OpenAPIClient\Classes\OpenAPIs.| |null| +|swiftPackagePath|Set a custom source path instead of OpenAPIClient/Classes/OpenAPIs.| |null| |swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null| |useBacktickEscapes|Escape reserved words using backticks (default: false)| |false| |useClasses|Use final classes for models instead of structs (default: false)| |false| |useCustomDateWithoutTime|Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)| |false| |useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true| -|useSPMFileStructure|Use SPM file structure and set the source path to Sources\{{projectName}} (default: false).| |null| +|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: false).| |null| |validatable|Make validation rules and validator for model properties (default: true)| |true| ## IMPORT MAPPING diff --git a/docs/generators/swift6.md b/docs/generators/swift6.md index f19516ff2449..a49865462eba 100644 --- a/docs/generators/swift6.md +++ b/docs/generators/swift6.md @@ -51,13 +51,13 @@ These options may be applied as additional-properties (cli) or configOptions (pl |responseAs|Optionally use libraries to manage response. Currently AsyncAwait, Combine, Result, RxSwift, ObjcBlock, PromiseKit are available.| |null| |sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true| |sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true| -|swiftPackagePath|Set a custom source path instead of Sources\{{projectName}}.| |null| +|swiftPackagePath|Set a custom source path instead of Sources/{{projectName}}.| |null| |swiftUseApiNamespace|Flag to make all the API classes inner-class of {{projectName}}API| |null| |useBacktickEscapes|Escape reserved words using backticks (default: false)| |false| |useClasses|Use final classes for models instead of structs (default: false)| |false| |useCustomDateWithoutTime|Uses a custom type to decode and encode dates without time information to support OpenAPIs date format (default: false)| |false| |useJsonEncodable|Make models conform to JSONEncodable protocol (default: true)| |true| -|useSPMFileStructure|Use SPM file structure and set the source path to Sources\{{projectName}} (default: true).| |null| +|useSPMFileStructure|Use SPM file structure and set the source path to Sources/{{projectName}} (default: true).| |null| |validatable|Make validation rules and validator for model properties (default: true)| |true| ## IMPORT MAPPING diff --git a/samples/client/petstore/typescript-fetch/tests/default/package-lock.json b/samples/client/petstore/typescript-fetch/tests/default/package-lock.json index 609de4bb9fbd..b2d105cf7689 100644 --- a/samples/client/petstore/typescript-fetch/tests/default/package-lock.json +++ b/samples/client/petstore/typescript-fetch/tests/default/package-lock.json @@ -32,21 +32,6 @@ "webpack": "^1.13.0" } }, - "../../builds/with-npm-version": { - "name": "@openapitools/typescript-fetch-petstore", - "version": "1.0.0", - "devDependencies": { - "typescript": "^4.0 || ^5.0" - } - }, - "node_modules/@openapitools/typescript-fetch-petstore": { - "resolved": "../../builds/with-npm-version", - "link": true - }, - "node_modules/@swagger/typescript-fetch-petstore": { - "resolved": "../../builds/with-npm-version", - "link": true - }, "node_modules/@types/chai": { "version": "4.3.16", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", From 3207c6b80bda9dc89466d5029f1e1a6c85739f66 Mon Sep 17 00:00:00 2001 From: DavidGrath Date: Fri, 21 Mar 2025 20:43:54 +0100 Subject: [PATCH 4/4] Trigger Build