Skip to content
GitLab
    • Explore Projects Groups Snippets
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Merge requests
  • !3900
An error occurred while fetching the assigned milestone of the selected merge_request.

Kotlin multiplatform client

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Administrator requested to merge github/fork/andrewemery/kotlin-multiplatform-client into master 5 years ago
  • Overview 0
  • Commits 10
  • Pipelines 0
  • Changes 223

Created by: andrewemery

Support for the generation of Kotlin Multiplatform clients.

Background

The kotlin language defined in the Swagger Codegen project currently generates a Kotlin client that can run on the JVM. Somewhat recently, JetBrains introduced Kotlin Multiplatform, a platform that provides the ability to share code between various platforms: JVM, JS, iOS, Windows, etc. This pull request adds the ability to generate a Kotlin Multiplatform client.

Library

The pull request includes Kotlin Multiplatform generation under the kotlin language and introduces two library options:

  1. jvm: (default) to target the existing Kotlin JVM generation.
  2. multiplatform: to target Kotlin Multiplatform generation.

Limitations

The current pull request only currently adds support for JVM and iOS platforms but support for other platforms should be trivial to add.

At present, date and date-time objects are rendered as strings. No attempt is made to integrate any third-party date/time libraries.

Tests

The current implementation doesn't include any tests beyond those already included as part of the kotlin language implementation. A test project can be found here that generates the petstore sample and includes tests to verify the correctness of the implementation.

Comments welcome.

References

https://github.com/OpenAPITools/openapi-generator/issues/3899 https://github.com/andrewemery/openapi-generator-kotlin-multiplatform-petstore

Compare
  • master (base)

and
  • latest version
    4d05fec5
    10 commits, 2 years ago

223 files
+ 11192
- 58

    Preferences

    File browser
    Compare changes
b‎in‎
open‎api3‎
kotlin-client-petst‎ore-multiplatform.sh‎ +35 -0
win‎dows‎
kotlin-client-petsto‎re-multiplatform.bat‎ +10 -0
kotlin-client-petst‎ore-multiplatform.sh‎ +32 -0
docs/ge‎nerators‎
kotl‎in.md‎ +2 -1
modules/openapi-g‎enerator/src/main‎
java/org/openapitoo‎ls/codegen/languages‎
KotlinClient‎Codegen.java‎ +177 -19
resources/k‎otlin-client‎
infrast‎ructure‎
ApiAbstractio‎ns.kt.mustache‎ +5 -2
libr‎aries‎
jvm/infra‎structure‎
ApiClient.‎kt.mustache‎ +0 -0
ApiInfrastructureR‎esponse.kt.mustache‎ +0 -0
ApplicationDeleg‎ates.kt.mustache‎ +0 -0
ByteArrayAdapt‎er.kt.mustache‎ +0 -0
Errors.kt‎.mustache‎ +0 -0
LocalDateAdapt‎er.kt.mustache‎ +0 -0
LocalDateTimeAda‎pter.kt.mustache‎ +0 -0
ResponseExtensi‎ons.kt.mustache‎ +0 -0
Serializer.‎kt.mustache‎ +0 -0
UUIDAdapter‎.kt.mustache‎ +0 -0
multip‎latform‎
commo‎nTest‎
coroutine‎.mustache‎ +13 -0
infrast‎ructure‎
ApiClient.‎kt.mustache‎ +122 -0
HttpResponse‎.kt.mustache‎ +51 -0
ios‎Test‎
coroutine‎.mustache‎ +8 -0
jvm‎Test‎
coroutine‎.mustache‎ +8 -0
api.mu‎stache‎ +90 -0
build.grad‎le.mustache‎ +138 -0
gradle-wr‎apper.jar‎ +0 -0
gradle-wrapper.pr‎operties.mustache‎ +6 -0
gradlew.ba‎t.mustache‎ +90 -0
gradlew.‎mustache‎ +160 -0
serial_wrapper_req‎uest_list.mustache‎ +10 -0
serial_wrapper_re‎quest_map.mustache‎ +10 -0
serial_wrapper_res‎ponse_list.mustache‎ +10 -0
serial_wrapper_res‎ponse_map.mustache‎ +10 -0
README.‎mustache‎ +8 -1
data_clas‎s.mustache‎ +22 -3
data_class_op‎t_var.mustache‎ +3 -1
data_class_re‎q_var.mustache‎ +3 -1
enum_clas‎s.mustache‎ +13 -0
settings.gra‎dle.mustache‎ +1 -0
sam‎ples‎
client/‎petstore‎
kot‎lin‎
src/main/kotlin/org‎/openapitools/client‎
infrast‎ructure‎
ApiAbstra‎ctions.kt‎ +5 -2
mod‎els‎
ApiResp‎onse.kt‎ +1 -1
Categ‎ory.kt‎ +1 -1
Orde‎r.kt‎ +5 -2
Pet‎.kt‎ +5 -2
Tag‎.kt‎ +1 -1
Use‎r.kt‎ +1 -1
setting‎s.gradle‎ +1 -0
kotlin-mul‎tiplatform‎
.openapi-‎generator‎
VER‎SION‎ +1 -0
do‎cs‎
ApiResp‎onse.md‎ +12 -0
Categ‎ory.md‎ +11 -0
Orde‎r.md‎ +22 -0
Pet‎.md‎ +22 -0
PetA‎pi.md‎ +405 -0
Store‎Api.md‎ +196 -0
Tag‎.md‎ +11 -0
Use‎r.md‎ +17 -0
UserA‎pi.md‎ +376 -0
gradle/‎wrapper‎
gradle-wr‎apper.jar‎ +0 -0
gradle-wrapp‎er.properties‎ +6 -0
s‎rc‎
commonMain/kotlin/…‎/openapitools/client‎
ap‎is‎
PetA‎pi.kt‎ +365 -0
Store‎Api.kt‎ +196 -0
UserA‎pi.kt‎ +350 -0
infrast‎ructure‎
ApiAbstra‎ctions.kt‎ +23 -0
ApiCli‎ent.kt‎ +129 -0
HttpRes‎ponse.kt‎ +51 -0
RequestC‎onfig.kt‎ +16 -0
RequestM‎ethod.kt‎ +8 -0
mod‎els‎
ApiResp‎onse.kt‎ +30 -0
Categ‎ory.kt‎ +28 -0
Orde‎r.kt‎ +56 -0
Pet‎.kt‎ +58 -0
Tag‎.kt‎ +28 -0
Use‎r.kt‎ +41 -0
commonTest/‎kotlin/util‎
Corout‎ine.kt‎ +23 -0
iosTest/k‎otlin/util‎
Corout‎ine.kt‎ +18 -0
jvmTest/k‎otlin/util‎
Corout‎ine.kt‎ +18 -0
.openapi-gen‎erator-ignore‎ +23 -0
READ‎ME.md‎ +81 -0
build.‎gradle‎ +138 -0
gra‎dlew‎ +160 -0
gradl‎ew.bat‎ +90 -0
setting‎s.gradle‎ +2 -0
kotlin‎-string‎
src/main/kotlin/org‎/openapitools/client‎
infrast‎ructure‎
ApiAbstra‎ctions.kt‎ +5 -2
mod‎els‎
ApiResp‎onse.kt‎ +1 -1
Categ‎ory.kt‎ +1 -1
Orde‎r.kt‎ +5 -2
Pet‎.kt‎ +5 -2
Tag‎.kt‎ +1 -1
Use‎r.kt‎ +1 -1
setting‎s.gradle‎ +1 -0
kotlin-t‎hreetenbp‎
src/main/kotlin/org‎/openapitools/client‎
infrast‎ructure‎
ApiAbstra‎ctions.kt‎ +5 -2
mod‎els‎
ApiResp‎onse.kt‎ +1 -1
Categ‎ory.kt‎ +1 -1
Orde‎r.kt‎ +5 -2
Pet‎.kt‎ +5 -2
Tag‎.kt‎ +1 -1
Use‎r.kt‎ +1 -1
setting‎s.gradle‎ +1 -0
openapi3/client/…/k‎otlin-multiplatform‎
.openapi-‎generator‎
VER‎SION‎ +1 -0
do‎cs‎
200Resp‎onse.md‎ +11 -0
AdditionalProp‎ertiesClass.md‎ +11 -0
Anim‎al.md‎ +11 -0
AnotherF‎akeApi.md‎ +56 -0
ApiResp‎onse.md‎ +12 -0
ArrayOfArrayO‎fNumberOnly.md‎ +10 -0
ArrayOfNum‎berOnly.md‎ +10 -0
ArrayT‎est.md‎ +12 -0
Capitali‎zation.md‎ +15 -0
Cat‎.md‎ +10 -0
CatAl‎lOf.md‎ +10 -0
Categ‎ory.md‎ +11 -0
ClassM‎odel.md‎ +10 -0
Clie‎nt.md‎ +10 -0
Defaul‎tApi.md‎ +50 -0
Dog‎.md‎ +10 -0
DogAl‎lOf.md‎ +10 -0
EnumAr‎rays.md‎ +25 -0
EnumCl‎ass.md‎ +14 -0
EnumT‎est.md‎ +45 -0
FakeA‎pi.md‎ +727 -0
FakeClassname‎Tags123Api.md‎ +59 -0
FileSchemaT‎estClass.md‎ +11 -0
Foo‎.md‎ +10 -0
Format‎Test.md‎ +24 -0
HasOnlyRe‎adOnly.md‎ +11 -0
HealthChec‎kResult.md‎ +10 -0
InlineO‎bject.md‎ +11 -0
InlineOb‎ject1.md‎ +11 -0
InlineOb‎ject2.md‎ +25 -0
InlineOb‎ject3.md‎ +23 -0
InlineOb‎ject4.md‎ +11 -0
InlineOb‎ject5.md‎ +11 -0
InlineRespon‎seDefault.md‎ +10 -0
Lis‎t.md‎ +10 -0
MapTe‎st.md‎ +20 -0
MixedPropertiesAndAddit‎ionalPropertiesClass.md‎ +12 -0
Nam‎e.md‎ +13 -0
Nullable‎Class.md‎ +21 -0
Number‎Only.md‎ +10 -0
Orde‎r.md‎ +22 -0
OuterCom‎posite.md‎ +12 -0
OuterE‎num.md‎ +14 -0
OuterEnumDef‎aultValue.md‎ +14 -0
OuterEnum‎Integer.md‎ +14 -0
OuterEnumIntege‎rDefaultValue.md‎ +14 -0
Pet‎.md‎ +22 -0
PetA‎pi.md‎ +457 -0
ReadOnly‎First.md‎ +11 -0
Retu‎rn.md‎ +10 -0
SpecialMo‎delName.md‎ +10 -0
Store‎Api.md‎ +196 -0
Tag‎.md‎ +11 -0
Use‎r.md‎ +17 -0
UserA‎pi.md‎ +376 -0
gradle/‎wrapper‎
gradle-wr‎apper.jar‎ +0 -0
gradle-wrapp‎er.properties‎ +6 -0
s‎rc‎
commonMain/kotlin/…‎/openapitools/client‎
ap‎is‎
AnotherF‎akeApi.kt‎ +81 -0
Defaul‎tApi.kt‎ +80 -0
FakeA‎pi.kt‎ +641 -0
FakeClassname‎Tags123Api.kt‎ +81 -0
PetA‎pi.kt‎ +406 -0
Store‎Api.kt‎ +196 -0
UserA‎pi.kt‎ +350 -0
infrast‎ructure‎
ApiAbstra‎ctions.kt‎ +23 -0
ApiCli‎ent.kt‎ +179 -0
HttpRes‎ponse.kt‎ +51 -0
RequestC‎onfig.kt‎ +16 -0
RequestM‎ethod.kt‎ +8 -0
mod‎els‎
AdditionalProp‎ertiesClass.kt‎ +28 -0
Anim‎al.kt‎ +28 -0
ApiResp‎onse.kt‎ +30 -0
ArrayOfArrayO‎fNumberOnly.kt‎ +26 -0
ArrayOfNum‎berOnly.kt‎ +26 -0
ArrayT‎est.kt‎ +31 -0
Capitali‎zation.kt‎ +37 -0
Cat‎.kt‎ +30 -0
CatAl‎lOf.kt‎ +26 -0
Categ‎ory.kt‎ +28 -0
ClassM‎odel.kt‎ +26 -0
Clie‎nt.kt‎ +26 -0
Dog‎.kt‎ +30 -0
DogAl‎lOf.kt‎ +26 -0
EnumAr‎rays.kt‎ +62 -0
EnumCl‎ass.kt‎ +38 -0
EnumT‎est.kt‎ +116 -0
FileSchemaT‎estClass.kt‎ +28 -0
Foo‎.kt‎ +26 -0
Format‎Test.kt‎ +56 -0
HasOnlyRe‎adOnly.kt‎ +28 -0
HealthChec‎kResult.kt‎ +26 -0
InlineO‎bject.kt‎ +30 -0
InlineOb‎ject1.kt‎ +30 -0
InlineOb‎ject2.kt‎ +66 -0
InlineOb‎ject3.kt‎ +66 -0
InlineOb‎ject4.kt‎ +30 -0
InlineOb‎ject5.kt‎ +30 -0
InlineRespon‎seDefault.kt‎ +27 -0
Lis‎t.kt‎ +26 -0
MapTe‎st.kt‎ +49 -0
MixedPropertiesAndAddit‎ionalPropertiesClass.kt‎ +31 -0
Model200R‎esponse.kt‎ +28 -0
Nam‎e.kt‎ +32 -0
Nullable‎Class.kt‎ +48 -0
Number‎Only.kt‎ +26 -0
Orde‎r.kt‎ +56 -0
OuterCom‎posite.kt‎ +30 -0
OuterE‎num.kt‎ +38 -0
OuterEnumDef‎aultValue.kt‎ +38 -0
OuterEnum‎Integer.kt‎ +38 -0
OuterEnumIntege‎rDefaultValue.kt‎ +38 -0
Pet‎.kt‎ +58 -0
ReadOnly‎First.kt‎ +28 -0
Retu‎rn.kt‎ +26 -0
SpecialMo‎delname.kt‎ +26 -0
Tag‎.kt‎ +28 -0
Use‎r.kt‎ +41 -0
commonTest/‎kotlin/util‎
Corout‎ine.kt‎ +23 -0
iosTest/k‎otlin/util‎
Corout‎ine.kt‎ +18 -0
jvmTest/k‎otlin/util‎
Corout‎ine.kt‎ +18 -0
.openapi-gen‎erator-ignore‎ +23 -0
READ‎ME.md‎ +158 -0
build.‎gradle‎ +138 -0
gra‎dlew‎ +160 -0
gradl‎ew.bat‎ +90 -0
setting‎s.gradle‎ +2 -0
bin/openapi3/kotlin-client-petstore-multiplatform.sh 0 → 100755
+ 35
- 0
  • View file @ 4d05fec5

  • Edit in single-file editor

  • Open in Web IDE

#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
while [ -h "$SCRIPT" ] ; do
ls=$(ls -ld "$SCRIPT")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=$(dirname "$SCRIPT")/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=$(dirname "$SCRIPT")/..
APP_DIR=$(cd "${APP_DIR}"; pwd)
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn clean package
fi
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -t modules/openapi-generator/src/main/resources/kotlin-client -g kotlin --artifact-id kotlin-client-petstore-multiplatform --library multiplatform -o samples/openapi3/client/petstore/kotlin-multiplatform $@"
echo "Cleaning previously generated files if any from samples/openapi3/client/petstore/kotlin-multiplatform"
rm -rf samples/openapi3/client/petstore/kotlin-multiplatform
echo "Generating Kotling client..."
java $JAVA_OPTS -jar $executable $ags
bin/windows/kotlin-client-petstore-multiplatform.bat 0 → 100644
+ 10
- 0
  • View file @ 4d05fec5

  • Edit in single-file editor

  • Open in Web IDE

set executable=.\modules\openapi-generator-cli\target\openapi-generator-cli.jar
If Not Exist %executable% (
mvn clean package
)
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M -DloggerPath=conf/log4j.properties
set ags=generate --artifact-id "kotlin-client-petstore-multiplatform" -i modules\openapi-generator\src\test\resources\2_0\petstore.yaml -g kotlin --library multiplatform -o samples\client\petstore\kotlin-multiplatform
java %JAVA_OPTS% -jar %executable% %ags%
bin/kotlin-client-petstore-multiplatform.sh 0 → 100755
+ 32
- 0
  • View file @ 4d05fec5

  • Edit in single-file editor

  • Open in Web IDE

#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
while [ -h "$SCRIPT" ] ; do
ls=$(ls -ld "$SCRIPT")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=$(dirname "$SCRIPT")/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=$(dirname "$SCRIPT")/..
APP_DIR=$(cd "${APP_DIR}"; pwd)
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn -B clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/kotlin-client -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g kotlin --artifact-id kotlin-client-petstore-multiplatform --library multiplatform -o samples/client/petstore/kotlin-multiplatform $@"
java ${JAVA_OPTS} -jar ${executable} ${ags}
docs/generators/kotlin.md
+ 2
- 1
  • View file @ 4d05fec5

  • Edit in single-file editor

  • Open in Web IDE


@@ -16,5 +16,6 @@ sidebar_label: kotlin
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|serializationLibrary|What serialization library to use: 'moshi' (default), or 'gson'| |moshi|
|parcelizeModels|toggle "@Parcelize" for generated models| |null|
|dateLibrary|Option. Date library to use|<dl><dt>**string**</dt><dd>String</dd><dt>**java8**</dt><dd>Java 8 native JSR310</dd><dt>**threetenbp**</dt><dd>Threetenbp</dd><dl>|java8|
|dateLibrary|Option. Date library to use|<dl><dt>**string**</dt><dd>String</dd><dt>**java8**</dt><dd>Java 8 native JSR310 (jvm only)</dd><dt>**threetenbp**</dt><dd>Threetenbp (jvm only)</dd><dl>|java8|
|collectionType|Option. Collection type to use|<dl><dt>**array**</dt><dd>kotlin.Array</dd><dt>**list**</dt><dd>kotlin.collections.List</dd><dl>|array|
|library|Library template (sub-template) to use|<dl><dt>**jvm**</dt><dd>Platform: Java Virtual Machine. HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.8.1.</dd><dt>**multiplatform**</dt><dd>Platform: Kotlin multiplatform. HTTP client: Ktor 1.2.4. JSON processing: Kotlinx Serialization: 0.12.0.</dd><dl>|jvm|
modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java
+ 177
- 19
  • View file @ 4d05fec5

  • Edit in single-file editor

  • Open in Web IDE


@@ -19,21 +19,42 @@ package org.openapitools.codegen.languages;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
public class KotlinClientCodegen extends AbstractKotlinCodegen {
protected static final String VENDOR_EXTENSION_ESCAPED_NAME = "x-escapedName";
protected static final String JVM = "jvm";
protected static final String MULTIPLATFORM = "multiplatform";
public static final String DATE_LIBRARY = "dateLibrary";
public static final String COLLECTION_TYPE = "collectionType";
protected String dateLibrary = DateLibrary.JAVA8.value;
protected String collectionType = CollectionType.ARRAY.value;
// https://kotlinlang.org/docs/reference/grammar.html#Identifier
protected static final Pattern IDENTIFIER_PATTERN =
Pattern.compile("[\\p{Ll}\\p{Lm}\\p{Lo}\\p{Lt}\\p{Lu}\\p{Nl}_][\\p{Ll}\\p{Lm}\\p{Lo}\\p{Lt}\\p{Lu}\\p{Nl}\\p{Nd}_]*");
// https://kotlinlang.org/docs/reference/grammar.html#Identifier
protected static final String IDENTIFIER_REPLACEMENTS =
"[.;:/\\[\\]<>]";
public enum DateLibrary {
STRING("string"),
THREETENBP("threetenbp"),
@@ -81,9 +102,9 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use");
Map<String, String> dateOptions = new HashMap<>();
dateOptions.put(DateLibrary.THREETENBP.value, "Threetenbp");
dateOptions.put(DateLibrary.THREETENBP.value, "Threetenbp (jvm only)");
dateOptions.put(DateLibrary.STRING.value, "String");
dateOptions.put(DateLibrary.JAVA8.value, "Java 8 native JSR310");
dateOptions.put(DateLibrary.JAVA8.value, "Java 8 native JSR310 (jvm only)");
dateLibrary.setEnum(dateOptions);
dateLibrary.setDefault(this.dateLibrary);
cliOptions.add(dateLibrary);
@@ -95,6 +116,15 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
collectionType.setEnum(collectionOptions);
collectionType.setDefault(this.collectionType);
cliOptions.add(collectionType);
supportedLibraries.put(JVM, "Platform: Java Virtual Machine. HTTP client: OkHttp 2.7.5. JSON processing: Gson 2.8.1.");
supportedLibraries.put(MULTIPLATFORM, "Platform: Kotlin multiplatform. HTTP client: Ktor 1.2.4. JSON processing: Kotlinx Serialization: 0.12.0.");
CliOption libraryOption = new CliOption(CodegenConstants.LIBRARY, "Library template (sub-template) to use");
libraryOption.setEnum(supportedLibraries);
libraryOption.setDefault(JVM);
cliOptions.add(libraryOption);
setLibrary(JVM);
}
public CodegenType getTag() {
@@ -121,10 +151,80 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
public void processOpts() {
super.processOpts();
if (MULTIPLATFORM.equals(getLibrary())) {
sourceFolder = "src/commonMain/kotlin";
}
// infrastructure destination folder
final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", "/");
// additional properties
if (additionalProperties.containsKey(DATE_LIBRARY)) {
setDateLibrary(additionalProperties.get(DATE_LIBRARY).toString());
}
// common (jvm/multiplatform) supporting files
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle"));
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
supportingFiles.add(new SupportingFile("infrastructure/ApiClient.kt.mustache", infrastructureFolder, "ApiClient.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApiAbstractions.kt.mustache", infrastructureFolder, "ApiAbstractions.kt"));
supportingFiles.add(new SupportingFile("infrastructure/RequestConfig.kt.mustache", infrastructureFolder, "RequestConfig.kt"));
supportingFiles.add(new SupportingFile("infrastructure/RequestMethod.kt.mustache", infrastructureFolder, "RequestMethod.kt"));
if (JVM.equals(getLibrary())) {
additionalProperties.put(JVM, true);
// jvm specific supporting files
supportingFiles.add(new SupportingFile("infrastructure/ApplicationDelegates.kt.mustache", infrastructureFolder, "ApplicationDelegates.kt"));
supportingFiles.add(new SupportingFile("infrastructure/Errors.kt.mustache", infrastructureFolder, "Errors.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ResponseExtensions.kt.mustache", infrastructureFolder, "ResponseExtensions.kt"));
supportingFiles.add(new SupportingFile("infrastructure/Serializer.kt.mustache", infrastructureFolder, "Serializer.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApiInfrastructureResponse.kt.mustache", infrastructureFolder, "ApiInfrastructureResponse.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ByteArrayAdapter.kt.mustache", infrastructureFolder, "ByteArrayAdapter.kt"));
supportingFiles.add(new SupportingFile("infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt"));
supportingFiles.add(new SupportingFile("infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt"));
supportingFiles.add(new SupportingFile("infrastructure/UUIDAdapter.kt.mustache", infrastructureFolder, "UUIDAdapter.kt"));
} else if (MULTIPLATFORM.equals(getLibrary())) {
additionalProperties.put(MULTIPLATFORM, true);
setDateLibrary(DateLibrary.STRING.value);
// multiplatform default includes
defaultIncludes.add("io.ktor.client.request.forms.InputProvider");
// multiplatform type mapping
typeMapping.put("number", "kotlin.Double");
typeMapping.put("file", "InputProvider");
// multiplatform import mapping
importMapping.put("BigDecimal", "kotlin.Double");
importMapping.put("UUID", "kotlin.String");
importMapping.put("URI", "kotlin.String");
importMapping.put("InputProvider", "io.ktor.client.request.forms.InputProvider");
importMapping.put("File", "io.ktor.client.request.forms.InputProvider");
importMapping.put("Timestamp", "kotlin.String");
importMapping.put("LocalDateTime", "kotlin.String");
importMapping.put("LocalDate", "kotlin.String");
importMapping.put("LocalTime", "kotlin.String");
// multiplatform specific supporting files
supportingFiles.add(new SupportingFile("infrastructure/HttpResponse.kt.mustache", infrastructureFolder, "HttpResponse.kt"));
// multiplatform specific testing files
final String testFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", "/");
supportingFiles.add(new SupportingFile("commonTest/coroutine.mustache", "src/commonTest/kotlin/util", "Coroutine.kt"));
supportingFiles.add(new SupportingFile("iosTest/coroutine.mustache", "src/iosTest/kotlin/util", "Coroutine.kt"));
supportingFiles.add(new SupportingFile("jvmTest/coroutine.mustache", "src/jvmTest/kotlin/util", "Coroutine.kt"));
// gradle wrapper supporting files
supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew"));
supportingFiles.add(new SupportingFile("gradlew.bat.mustache", "", "gradlew.bat"));
supportingFiles.add(new SupportingFile("gradle-wrapper.properties.mustache", "gradle.wrapper".replace(".", File.separator), "gradle-wrapper.properties"));
supportingFiles.add(new SupportingFile("gradle-wrapper.jar", "gradle.wrapper".replace(".", File.separator), "gradle-wrapper.jar"));
}
// date library processing
if (DateLibrary.THREETENBP.value.equals(dateLibrary)) {
additionalProperties.put(DateLibrary.THREETENBP.value, true);
typeMapping.put("date", "LocalDate");
@@ -151,25 +251,83 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen {
typeMapping.put("list", "kotlin.collections.List");
additionalProperties.put("isList", true);
}
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("build.gradle.mustache", "", "build.gradle"));
supportingFiles.add(new SupportingFile("settings.gradle.mustache", "", "settings.gradle"));
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
objs = super.postProcessModels(objs);
return postProcessModelsEscapeNames(objs);
}
final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", "/");
@SuppressWarnings("unchecked")
private static Map<String, Object> postProcessModelsEscapeNames(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
supportingFiles.add(new SupportingFile("infrastructure/ApiClient.kt.mustache", infrastructureFolder, "ApiClient.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApiAbstractions.kt.mustache", infrastructureFolder, "ApiAbstractions.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApiInfrastructureResponse.kt.mustache", infrastructureFolder, "ApiInfrastructureResponse.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApplicationDelegates.kt.mustache", infrastructureFolder, "ApplicationDelegates.kt"));
supportingFiles.add(new SupportingFile("infrastructure/RequestConfig.kt.mustache", infrastructureFolder, "RequestConfig.kt"));
supportingFiles.add(new SupportingFile("infrastructure/RequestMethod.kt.mustache", infrastructureFolder, "RequestMethod.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ResponseExtensions.kt.mustache", infrastructureFolder, "ResponseExtensions.kt"));
supportingFiles.add(new SupportingFile("infrastructure/Serializer.kt.mustache", infrastructureFolder, "Serializer.kt"));
supportingFiles.add(new SupportingFile("infrastructure/Errors.kt.mustache", infrastructureFolder, "Errors.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ByteArrayAdapter.kt.mustache", infrastructureFolder, "ByteArrayAdapter.kt"));
supportingFiles.add(new SupportingFile("infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt"));
supportingFiles.add(new SupportingFile("infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt"));
supportingFiles.add(new SupportingFile("infrastructure/UUIDAdapter.kt.mustache", infrastructureFolder, "UUIDAdapter.kt"));
if (cm.vars != null) {
for (CodegenProperty var : cm.vars) {
var.vendorExtensions.put(VENDOR_EXTENSION_ESCAPED_NAME, escapeIdentifier(var.name));
}
}
if (cm.requiredVars != null) {
for (CodegenProperty var : cm.requiredVars) {
var.vendorExtensions.put(VENDOR_EXTENSION_ESCAPED_NAME, escapeIdentifier(var.name));
}
}
if (cm.optionalVars != null) {
for (CodegenProperty var : cm.optionalVars) {
var.vendorExtensions.put(VENDOR_EXTENSION_ESCAPED_NAME, escapeIdentifier(var.name));
}
}
}
return objs;
}
private static String escapeIdentifier(String identifier) {
// the kotlin grammar permits a wider set of characters in their identifiers that all target
// platforms permit (namely jvm). in order to remain compatible with target platforms, we
// initially replace all illegal target characters before escaping the identifier if required.
identifier = identifier.replaceAll(IDENTIFIER_REPLACEMENTS, "_");
if (IDENTIFIER_PATTERN.matcher(identifier).matches()) return identifier;
return '`' + identifier + '`';
}
private static void removeDuplicates(List<CodegenProperty> list) {
Set<String> set = new HashSet<>();
Iterator<CodegenProperty> iterator = list.iterator();
while (iterator.hasNext()) {
CodegenProperty item = iterator.next();
if (set.contains(item.name)) iterator.remove();
else set.add(item.name);
}
}
@Override
@SuppressWarnings("unchecked")
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
super.postProcessOperationsWithModels(objs, allModels);
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.hasConsumes == Boolean.TRUE) {
if (isMultipartType(operation.consumes)) {
operation.isMultipart = Boolean.TRUE;
}
}
}
}
return operations;
}
private static boolean isMultipartType(List<Map<String, String>> consumes) {
Map<String, String> firstType = consumes.get(0);
if (firstType != null) {
return "multipart/form-data".equals(firstType.get("mediaType"));
}
return false;
}
}
0 Assignees
None
Assign to
0 Reviewers
None
Request review from
Labels
0
None
0
None
    Assign labels
  • Manage project labels

Milestone
No milestone
None
None
Time tracking
No estimate or time spent
Lock merge request
Unlocked
1
1 participant
Administrator
Reference:
Source branch: github/fork/andrewemery/kotlin-multiplatform-client

Menu

Explore Projects Groups Snippets