@team-supercharge/oasg 13.0.1 → 13.1.0-kmp-8a9ad834.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/bin/oasg +4 -3
- package/config.schema.yml +26 -0
- package/package.json +1 -1
- package/targets/kmp/generate.sh +21 -0
- package/targets/kmp/generator-config.json +12 -0
- package/targets/kmp/publish.sh +11 -0
- package/targets/kmp/templates/build.gradle.kts.mustache +121 -0
- package/targets/kmp/templates/libraries/multiplatform/api.mustache +136 -0
package/README.md
CHANGED
@@ -637,6 +637,33 @@ TBD
|
|
637
637
|
| repository | URL of the generated client api code repository | Y | - |
|
638
638
|
| generatorCustomArgs | Custom arguments of the generator | N | - |
|
639
639
|
|
640
|
+
#### `kmp`
|
641
|
+
|
642
|
+
```json
|
643
|
+
{
|
644
|
+
"id": "client-kmp",
|
645
|
+
"type": "kmp",
|
646
|
+
"source": "source-merged",
|
647
|
+
"packageName": "io.supercharge.oasg.example",
|
648
|
+
"groupId": "io.supercharge.oasg.example",
|
649
|
+
"artifactId": "client",
|
650
|
+
"generatorCustomArgs": "--model-name-suffix=ApiModel",
|
651
|
+
"formatter": "1.0.0",
|
652
|
+
"formatterCustomArgs": "--disabled_rules=no-wildcard-imports,max-line-length,enum-entry-name-case",
|
653
|
+
"repository": "https://gitlab.supercharge.io/api/v4/projects/1226/packages/maven"
|
654
|
+
}
|
655
|
+
```
|
656
|
+
|
657
|
+
|Parameter| Description| Required | Default |
|
658
|
+
|-|-|-|-|
|
659
|
+
| packageName | Kotlin package name of the generated client | Y | - |
|
660
|
+
| groupId | Generated artifact package's organization | Y | - |
|
661
|
+
| artifactId | Generated artifact id | Y | - |
|
662
|
+
| generatorCustomArgs | Custom arguments of the generator | N | - |
|
663
|
+
| formatter | `ktlint`: it can be a released version or a http(s) url | N | 1.0.0 |
|
664
|
+
| formatterCustomArgs | Custom arguments of the `ktlint` formatter | N | --disabled_rules=no-wildcard-imports,max-line-length,enum-entry-name-case |
|
665
|
+
| repository | URL of the Maven Repository | N | - |
|
666
|
+
|
640
667
|
#### `python`
|
641
668
|
|
642
669
|
```json
|
package/bin/oasg
CHANGED
@@ -39,6 +39,7 @@ const DEFAULT_GENERATOR_MAPPING = {
|
|
39
39
|
"feign-kotlin": { version: '7.0.1', generator: 'kotlin-spring' },
|
40
40
|
"flutter": { version: '7.0.1', generator: 'dart-dio' },
|
41
41
|
"ios": { version: '7.0.1', generator: 'swift5' },
|
42
|
+
"kmp": { version: 'https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.2.0-SNAPSHOT/openapi-generator-cli-7.2.0-20231208.144106-84.jar', generator: 'kotlin' },
|
42
43
|
"python": { version: '7.0.1', generator: 'python' },
|
43
44
|
"react": { version: '7.0.1', generator: 'typescript-fetch' },
|
44
45
|
// server targets
|
@@ -247,10 +248,10 @@ async function parseConfig() {
|
|
247
248
|
}
|
248
249
|
})
|
249
250
|
|
250
|
-
// set default ktlint to android targets with undefined
|
251
|
+
// set default ktlint to android and KMP targets with undefined
|
251
252
|
config.targets.forEach(t => {
|
252
253
|
//TODO: handle different types of platform
|
253
|
-
if (t.type === 'android') {
|
254
|
+
if (t.type === 'android' || t.type === 'kmp') {
|
254
255
|
if (!t.formatter) {
|
255
256
|
t.formatter = DEFAULT_KTLINT_VERSION;
|
256
257
|
}
|
@@ -482,7 +483,7 @@ async function generate(argv) {
|
|
482
483
|
let formatter;
|
483
484
|
|
484
485
|
//TODO: handle different types of platforms
|
485
|
-
if (target.type === 'android') {
|
486
|
+
if (target.type === 'android' || target.type === 'kmp') {
|
486
487
|
formatter = fetchFormatter(target);
|
487
488
|
}
|
488
489
|
|
package/config.schema.yml
CHANGED
@@ -24,6 +24,7 @@ properties:
|
|
24
24
|
- $ref: '#/targets/NestJS'
|
25
25
|
- $ref: '#/targets/OpenAPI'
|
26
26
|
- $ref: '#/targets/Flutter'
|
27
|
+
- $ref: '#/targets/Kmp'
|
27
28
|
required:
|
28
29
|
- targets
|
29
30
|
additionalProperties: false
|
@@ -346,6 +347,31 @@ targets:
|
|
346
347
|
- packageName
|
347
348
|
- repository
|
348
349
|
|
350
|
+
Kmp:
|
351
|
+
allOf:
|
352
|
+
- $ref: '#/targets/Base'
|
353
|
+
- properties:
|
354
|
+
type:
|
355
|
+
pattern: "^kmp$"
|
356
|
+
packageName:
|
357
|
+
type: string
|
358
|
+
groupId:
|
359
|
+
type: string
|
360
|
+
artifactId:
|
361
|
+
type: string
|
362
|
+
formatter:
|
363
|
+
type: string
|
364
|
+
pattern: '^(\d+\.\d+\.\d+(-.+)?)|(^http(s)?:\/\/.+$)$' # matches: 0.0.0(-pre) and http(s)://XXX
|
365
|
+
formatterCustomArgs:
|
366
|
+
type: string
|
367
|
+
repository:
|
368
|
+
type: string
|
369
|
+
required:
|
370
|
+
- packageName
|
371
|
+
- groupId
|
372
|
+
- artifactId
|
373
|
+
- repository
|
374
|
+
|
349
375
|
definitions:
|
350
376
|
# default
|
351
377
|
SourceOverrides:
|
package/package.json
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
#/bin/bash
|
2
|
+
|
3
|
+
source $(dirname "$0")/../common.sh
|
4
|
+
|
5
|
+
rm -rf out/$targetId
|
6
|
+
mkdir -p out/$targetId
|
7
|
+
|
8
|
+
if [ -z "$formatterCustomArgs" ]
|
9
|
+
then
|
10
|
+
formatterCustomArgs="--disabled_rules=no-wildcard-imports,max-line-length,enum-entry-name-case"
|
11
|
+
fi
|
12
|
+
|
13
|
+
java -jar $binary generate \
|
14
|
+
-g $generatorId \
|
15
|
+
-i $openApiFile \
|
16
|
+
-t $templateDir \
|
17
|
+
-o out/$targetId \
|
18
|
+
-c $(dirname "$0")/generator-config.json \
|
19
|
+
-p "artifactId=${artifactId},groupId=${groupId},packageName=${packageName},artifactVersion=${version}" $generatorCustomArgs
|
20
|
+
|
21
|
+
$formatterBinary -F "out/$targetId/src/**/*.kt" $formatterCustomArgs
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"library": "multiplatform",
|
3
|
+
"enumPropertyNaming": "original",
|
4
|
+
"dateLibrary": "kotlinx-datetime",
|
5
|
+
"useCoroutines": true,
|
6
|
+
"omitGradleWrapper": false,
|
7
|
+
"inlineSchemaOptions": {
|
8
|
+
"ARRAY_ITEM_SUFFIX": "",
|
9
|
+
"MAP_ITEM_SUFFIX": "",
|
10
|
+
"SKIP_SCHEMA_REUSE": "true"
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
2
|
+
|
3
|
+
plugins {
|
4
|
+
kotlin("multiplatform"){{^omitGradlePluginVersions}} version "1.9.20" // kotlin_version{{/omitGradlePluginVersions}}
|
5
|
+
kotlin("plugin.serialization"){{^omitGradlePluginVersions}} version "1.9.20" // kotlin_version{{/omitGradlePluginVersions}}
|
6
|
+
id("maven-publish") // OASg added for publication
|
7
|
+
}
|
8
|
+
|
9
|
+
group = "{{groupId}}"
|
10
|
+
version = "{{artifactVersion}}"
|
11
|
+
|
12
|
+
val kotlin_version = "1.9.20"
|
13
|
+
val coroutines_version = "1.7.3"
|
14
|
+
val serialization_version = "1.6.1"
|
15
|
+
val ktor_version = "2.3.6"
|
16
|
+
|
17
|
+
repositories {
|
18
|
+
mavenCentral()
|
19
|
+
}
|
20
|
+
|
21
|
+
kotlin {
|
22
|
+
jvm()
|
23
|
+
iosX64()
|
24
|
+
iosArm64()
|
25
|
+
iosSimulatorArm64()
|
26
|
+
js {
|
27
|
+
browser()
|
28
|
+
nodejs()
|
29
|
+
}
|
30
|
+
|
31
|
+
sourceSets {
|
32
|
+
commonMain {
|
33
|
+
dependencies {
|
34
|
+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
|
35
|
+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version")
|
36
|
+
|
37
|
+
api("io.ktor:ktor-client-core:$ktor_version")
|
38
|
+
api("io.ktor:ktor-client-serialization:$ktor_version")
|
39
|
+
api("io.ktor:ktor-client-content-negotiation:$ktor_version")
|
40
|
+
api("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
|
41
|
+
|
42
|
+
{{#kotlinx-datetime}}
|
43
|
+
api("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")
|
44
|
+
{{/kotlinx-datetime}}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
commonTest {
|
49
|
+
dependencies {
|
50
|
+
implementation(kotlin("test"))
|
51
|
+
implementation("io.ktor:ktor-client-mock:$ktor_version")
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
jvmMain {
|
56
|
+
dependencies {
|
57
|
+
implementation(kotlin("stdlib-jdk7"))
|
58
|
+
implementation("io.ktor:ktor-client-cio-jvm:$ktor_version")
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
jvmTest {
|
63
|
+
dependencies {
|
64
|
+
implementation(kotlin("test-junit"))
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
iosMain {
|
69
|
+
dependencies {
|
70
|
+
api("io.ktor:ktor-client-ios:$ktor_version")
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
jsMain {
|
75
|
+
dependencies {
|
76
|
+
api("io.ktor:ktor-client-js:$ktor_version")
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
all {
|
81
|
+
languageSettings.apply {
|
82
|
+
optIn("kotlin.Experimental")
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
tasks {
|
89
|
+
register("iosTest") {
|
90
|
+
val device = project.findProperty("device")?.toString() ?: "iPhone 8"
|
91
|
+
dependsOn("linkDebugTestIosX64")
|
92
|
+
group = JavaBasePlugin.VERIFICATION_GROUP
|
93
|
+
description = "Execute unit tests on ${device} simulator"
|
94
|
+
doLast {
|
95
|
+
val binary = kotlin.targets.getByName<KotlinNativeTarget>("iosX64").binaries.getTest("DEBUG")
|
96
|
+
exec {
|
97
|
+
commandLine("xcrun", "simctl", "spawn", device, binary.outputFile)
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
register("test") {
|
102
|
+
dependsOn("allTests")
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
// OASg added for publication
|
107
|
+
publishing {
|
108
|
+
repositories {
|
109
|
+
maven {
|
110
|
+
name = "Gitlab"
|
111
|
+
url = uri(project.property("repoUrl")!!)
|
112
|
+
credentials(HttpHeaderCredentials::class) {
|
113
|
+
name = "Job-Token"
|
114
|
+
value = System.getenv("CI_JOB_TOKEN")
|
115
|
+
}
|
116
|
+
authentication {
|
117
|
+
create<HttpHeaderAuthentication>("header")
|
118
|
+
}
|
119
|
+
}
|
120
|
+
}
|
121
|
+
}
|
@@ -0,0 +1,136 @@
|
|
1
|
+
{{>licenseInfo}}
|
2
|
+
package {{apiPackage}}
|
3
|
+
|
4
|
+
{{#imports}}import {{import}}
|
5
|
+
{{/imports}}
|
6
|
+
|
7
|
+
import {{packageName}}.infrastructure.*
|
8
|
+
import io.ktor.client.HttpClient
|
9
|
+
import io.ktor.client.HttpClientConfig
|
10
|
+
import io.ktor.client.call.body
|
11
|
+
import io.ktor.client.request.forms.formData
|
12
|
+
import io.ktor.client.engine.HttpClientEngine
|
13
|
+
import kotlinx.serialization.json.Json
|
14
|
+
import io.ktor.http.ParametersBuilder
|
15
|
+
import kotlinx.serialization.*
|
16
|
+
import kotlinx.serialization.descriptors.*
|
17
|
+
import kotlinx.serialization.encoding.*
|
18
|
+
|
19
|
+
{{#operations}}
|
20
|
+
{{#nonPublicApi}}internal {{/nonPublicApi}}open class {{classname}} : ApiClient {
|
21
|
+
|
22
|
+
constructor(
|
23
|
+
baseUrl: String = ApiClient.BASE_URL,
|
24
|
+
httpClientEngine: HttpClientEngine? = null,
|
25
|
+
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
|
26
|
+
jsonSerializer: Json = ApiClient.JSON_DEFAULT
|
27
|
+
) : super(baseUrl = baseUrl, httpClientEngine = httpClientEngine, httpClientConfig = httpClientConfig, jsonBlock = jsonSerializer)
|
28
|
+
|
29
|
+
constructor(
|
30
|
+
baseUrl: String,
|
31
|
+
httpClient: HttpClient
|
32
|
+
): super(baseUrl = baseUrl, httpClient = httpClient)
|
33
|
+
|
34
|
+
{{#operation}}
|
35
|
+
{{#allParams}}
|
36
|
+
{{#isEnum}}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* enum for parameter {{paramName}}
|
40
|
+
*/
|
41
|
+
@Serializable
|
42
|
+
{{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{enumName}}{{operationIdCamelCase}}(val value: {{^isContainer}}{{dataType}}{{/isContainer}}{{#isContainer}}kotlin.String{{/isContainer}}) {
|
43
|
+
{{^enumUnknownDefaultCase}}
|
44
|
+
{{#allowableValues}}{{#enumVars}}
|
45
|
+
@SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}})
|
46
|
+
{{&name}}({{{value}}}){{^-last}},{{/-last}}
|
47
|
+
{{/enumVars}}{{/allowableValues}}
|
48
|
+
{{/enumUnknownDefaultCase}}
|
49
|
+
{{#enumUnknownDefaultCase}}
|
50
|
+
{{#allowableValues}}{{#enumVars}}{{^-last}}
|
51
|
+
@SerialName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}})
|
52
|
+
{{&name}}({{{value}}}),
|
53
|
+
{{/-last}}{{/enumVars}}{{/allowableValues}}
|
54
|
+
{{/enumUnknownDefaultCase}}
|
55
|
+
}
|
56
|
+
|
57
|
+
{{/isEnum}}
|
58
|
+
{{/allParams}}
|
59
|
+
/**
|
60
|
+
* {{summary}}
|
61
|
+
* {{notes}}
|
62
|
+
{{#allParams}} * @param {{{paramName}}} {{description}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{#required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}{{/required}}
|
63
|
+
{{/allParams}} * @return {{{returnType}}}{{^returnType}}void{{/returnType}}
|
64
|
+
*/
|
65
|
+
{{#returnType}}
|
66
|
+
@Suppress("UNCHECKED_CAST")
|
67
|
+
{{/returnType}}
|
68
|
+
open suspend fun {{operationId}}({{#allParams}}{{{paramName}}}: {{#isEnum}}{{#isContainer}}kotlin.collections.List<{{enumName}}{{operationIdCamelCase}}>{{/isContainer}}{{^isContainer}}{{enumName}}{{operationIdCamelCase}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#required}}{{#defaultValue}} = {{^isNumber}}{{#isEnum}}{{enumName}}{{operationIdCamelCase}}.{{enumDefaultValue}}{{/isEnum}}{{^isEnum}}{{{defaultValue}}}{{/isEnum}}{{/isNumber}}{{#isNumber}}{{{defaultValue}}}.toDouble(){{/isNumber}}{{/defaultValue}}{{/required}}{{^required}}?{{#defaultValue}} = {{^isNumber}}{{#isEnum}}{{enumName}}{{operationIdCamelCase}}.{{enumDefaultValue}}{{/isEnum}}{{^isEnum}}{{{defaultValue}}}{{/isEnum}}{{/isNumber}}{{#isNumber}}{{{defaultValue}}}.toDouble(){{/isNumber}}{{/defaultValue}}{{^defaultValue}} = null{{/defaultValue}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}): {{{returnType}}}{{^returnType}}Unit{{/returnType}} {
|
69
|
+
|
70
|
+
val localVariableAuthNames = listOf<String>({{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}})
|
71
|
+
|
72
|
+
val localVariableBody = {{#hasBodyParam}}{{#bodyParam}}{{#isArray}}{{operationIdCamelCase}}Request({{{paramName}}}{{^isList}}.asList(){{/isList}}){{/isArray}}{{^isArray}}{{#isMap}}{{operationIdCamelCase}}Request({{{paramName}}}){{/isMap}}{{^isMap}}{{{paramName}}}{{/isMap}}{{/isArray}}{{/bodyParam}}{{/hasBodyParam}}
|
73
|
+
{{^hasBodyParam}}
|
74
|
+
{{#hasFormParams}}
|
75
|
+
{{#isMultipart}}
|
76
|
+
formData {
|
77
|
+
{{#formParams}}
|
78
|
+
{{#isArray}}
|
79
|
+
{{{paramName}}}?.onEach {
|
80
|
+
append("{{{baseName}}}[]", it)
|
81
|
+
}
|
82
|
+
{{/isArray}}
|
83
|
+
{{^isArray}}
|
84
|
+
{{{paramName}}}?.apply { append("{{{baseName}}}", {{{paramName}}}) }
|
85
|
+
{{/isArray}}
|
86
|
+
{{/formParams}}
|
87
|
+
}
|
88
|
+
{{/isMultipart}}
|
89
|
+
{{^isMultipart}}
|
90
|
+
ParametersBuilder().also {
|
91
|
+
{{#formParams}}
|
92
|
+
{{{paramName}}}?.apply { it.append("{{{baseName}}}", {{{paramName}}}.toString()) }
|
93
|
+
{{/formParams}}
|
94
|
+
}.build()
|
95
|
+
{{/isMultipart}}
|
96
|
+
{{/hasFormParams}}
|
97
|
+
{{^hasFormParams}}
|
98
|
+
io.ktor.client.utils.EmptyContent
|
99
|
+
{{/hasFormParams}}
|
100
|
+
{{/hasBodyParam}}
|
101
|
+
|
102
|
+
val localVariableQuery = mutableMapOf<String, List<String>>(){{#queryParams}}
|
103
|
+
{{{paramName}}}?.apply { localVariableQuery["{{baseName}}"] = {{#isContainer}}toMultiValue(this, "{{collectionFormat}}"){{/isContainer}}{{^isContainer}}listOf("${{{paramName}}}"){{/isContainer}} }{{/queryParams}}
|
104
|
+
val localVariableHeaders = mutableMapOf<String, String>(){{#headerParams}}
|
105
|
+
{{{paramName}}}?.apply { localVariableHeaders["{{baseName}}"] = {{#isContainer}}this.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}this.toString(){{/isContainer}} }{{/headerParams}}
|
106
|
+
|
107
|
+
val localVariableConfig = RequestConfig<kotlin.Any?>(
|
108
|
+
RequestMethod.{{httpMethod}},
|
109
|
+
"{{path}}"{{#pathParams}}.replace("{" + "{{baseName}}" + "}", {{#isContainer}}{{paramName}}.joinToString(","){{/isContainer}}{{^isContainer}}"${{{paramName}}}"{{/isContainer}}){{/pathParams}},
|
110
|
+
query = localVariableQuery,
|
111
|
+
headers = localVariableHeaders,
|
112
|
+
requiresAuthentication = {{#hasAuthMethods}}true{{/hasAuthMethods}}{{^hasAuthMethods}}false{{/hasAuthMethods}},
|
113
|
+
)
|
114
|
+
|
115
|
+
return {{#hasBodyParam}}jsonRequest{{/hasBodyParam}}{{^hasBodyParam}}{{#hasFormParams}}{{#isMultipart}}multipartFormRequest{{/isMultipart}}{{^isMultipart}}urlEncodedFormRequest{{/isMultipart}}{{/hasFormParams}}{{^hasFormParams}}request{{/hasFormParams}}{{/hasBodyParam}}(
|
116
|
+
localVariableConfig,
|
117
|
+
localVariableBody,
|
118
|
+
localVariableAuthNames
|
119
|
+
).body()
|
120
|
+
}
|
121
|
+
|
122
|
+
{{#hasBodyParam}}
|
123
|
+
{{#bodyParam}}
|
124
|
+
{{#isArray}}{{>serial_wrapper_request_list}}{{/isArray}}{{#isMap}}{{>serial_wrapper_request_map}}{{/isMap}}
|
125
|
+
{{/bodyParam}}
|
126
|
+
{{/hasBodyParam}}
|
127
|
+
{{#isArray}}
|
128
|
+
{{>serial_wrapper_response_list}}
|
129
|
+
{{/isArray}}
|
130
|
+
{{#isMap}}
|
131
|
+
{{>serial_wrapper_response_map}}
|
132
|
+
{{/isMap}}
|
133
|
+
|
134
|
+
{{/operation}}
|
135
|
+
}
|
136
|
+
{{/operations}}
|