Skip to content

Commit a2fd144

Browse files
Bring Kotlin client code up-to-speed with changes (#23188)
* Convert static constants to CAPITALS. * Bring `responseBody` up-to-speed with regards to response nullability. * Keep previous constants so not to break existing code. * Generate samples code. * Apply suggestion from @cubic-dev-ai[bot] Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * Regenerate sample code. * Reorder statics, fix values of `ACCEPT` and `AUTHORIZATION` constants. * Regenerate sample code. * Add deprecation constant. * Regenerate sample code. * Remove unnecessary annotation. * Regenerate samples code. --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
1 parent a04b9a5 commit a2fd144

106 files changed

Lines changed: 2824 additions & 1127 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/api.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import {{packageName}}.infrastructure.Serializer
5555
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
5656
@JvmStatic
5757
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {
58-
System.getProperties().getProperty(ApiClient.baseUrlKey, "{{{basePath}}}")
58+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "{{{basePath}}}")
5959
}
6060
}
6161

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache

Lines changed: 99 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,81 @@ import com.squareup.moshi.adapter
6363

6464
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient({{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val baseUrl: String, {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val client: Call.Factory = defaultClient) {
6565
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
66-
protected const val ContentType: String = "Content-Type"
67-
protected const val Accept: String = "Accept"
68-
protected const val Authorization: String = "Authorization"
69-
protected const val JsonMediaType: String = "application/json"
70-
protected const val FormDataMediaType: String = "multipart/form-data"
71-
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
72-
protected const val XmlMediaType: String = "application/xml"
73-
protected const val OctetMediaType: String = "application/octet-stream"
74-
protected const val TextMediaType: String = "text/plain"
66+
protected const val CONTENT_TYPE: String = "Content-Type"
67+
@Deprecated(
68+
message = "Please use the capitalized constant `CONTENT_TYPE` instead.",
69+
replaceWith = ReplaceWith("CONTENT_TYPE")
70+
)
71+
protected const val ContentType: String = CONTENT_TYPE
72+
73+
protected const val ACCEPT: String = "Accept"
74+
@Deprecated(
75+
message = "Please use the capitalized constant `ACCEPT` instead.",
76+
replaceWith = ReplaceWith("ACCEPT")
77+
)
78+
protected const val Accept: String = ACCEPT
79+
80+
protected const val AUTHORIZATION: String = "Authorization"
81+
@Deprecated(
82+
message = "Please use the capitalized constant `AUTHORIZATION` instead.",
83+
replaceWith = ReplaceWith("AUTHORIZATION")
84+
)
85+
protected const val Authorization: String = AUTHORIZATION
86+
87+
protected const val JSON_MEDIA_TYPE: String = "application/json"
88+
@Deprecated(
89+
message = "Please use the capitalized constant `JSON_MEDIA_TYPE` instead.",
90+
replaceWith = ReplaceWith("JSON_MEDIA_TYPE")
91+
)
92+
protected const val JsonMediaType: String = JSON_MEDIA_TYPE
93+
94+
protected const val FORM_DATA_MEDIA_TYPE: String = "multipart/form-data"
95+
@Deprecated(
96+
message = "Please use the capitalized constant `FORM_DATA_MEDIA_TYPE` instead.",
97+
replaceWith = ReplaceWith("FORM_DATA_MEDIA_TYPE")
98+
)
99+
protected const val FormDataMediaType: String = FORM_DATA_MEDIA_TYPE
100+
101+
protected const val FORM_URL_ENC_MEDIA_TYPE: String = "application/x-www-form-urlencoded"
102+
@Deprecated(
103+
message = "Please use the capitalized constant `FORM_URL_ENC_MEDIA_TYPE` instead.",
104+
replaceWith = ReplaceWith("FORM_URL_ENC_MEDIA_TYPE")
105+
)
106+
protected const val FormUrlEncMediaType: String = FORM_URL_ENC_MEDIA_TYPE
107+
108+
protected const val XML_MEDIA_TYPE: String = "application/xml"
109+
@Deprecated(
110+
message = "Please use the capitalized constant `XML_MEDIA_TYPE` instead.",
111+
replaceWith = ReplaceWith("XML_MEDIA_TYPE")
112+
)
113+
protected const val XmlMediaType: String = XML_MEDIA_TYPE
114+
115+
protected const val OCTET_MEDIA_TYPE: String = "application/octet-stream"
116+
@Deprecated(
117+
message = "Please use the capitalized constant `OCTET_MEDIA_TYPE` instead.",
118+
replaceWith = ReplaceWith("OCTET_MEDIA_TYPE")
119+
)
120+
protected const val OctetMediaType: String = OCTET_MEDIA_TYPE
121+
122+
protected const val TEXT_MEDIA_TYPE: String = "text/plain"
123+
@Deprecated(
124+
message = "Please use the capitalized constant `TEXT_MEDIA_TYPE` instead.",
125+
replaceWith = ReplaceWith("TEXT_MEDIA_TYPE")
126+
)
127+
protected const val TextMediaType: String = TEXT_MEDIA_TYPE
128+
129+
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val BASE_URL_KEY: String = "{{packageName}}.baseUrl"
130+
@Deprecated(
131+
message = "Please use the capitalized constant `BASE_URL_KEY` instead.",
132+
replaceWith = ReplaceWith("BASE_URL_KEY")
133+
)
134+
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = BASE_URL_KEY
75135

76136
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val apiKey: MutableMap<String, String> = mutableMapOf()
77137
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
78138
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}var username: String? = null
79139
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}var password: String? = null
80140
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}var accessToken: String? = null
81-
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = "{{packageName}}.baseUrl"
82141

83142
@JvmStatic
84143
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultClient: OkHttpClient by lazy {
@@ -98,7 +157,7 @@ import com.squareup.moshi.adapter
98157
protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String {
99158
val contentType = try {
100159
URLConnection.guessContentTypeFromStream(byteArray.inputStream())
101-
} catch (io: IOException) {
160+
} catch (_: IOException) {
102161
"application/octet-stream"
103162
}
104163
return contentType
@@ -137,7 +196,7 @@ import com.squareup.moshi.adapter
137196
/**
138197
* Adds a File to a MultipartBody.Builder
139198
* Defined a helper in the requestBody method to not duplicate code
140-
* It will be used when the content is a FormDataMediaType and the body of the PartConfig is a File
199+
* It will be used when the content is a `FORM_DATA_MEDIA_TYPE` and the body of the PartConfig is a File
141200
*
142201
* @param name The field name to add in the request
143202
* @param headers The headers that are in the PartConfig
@@ -167,7 +226,7 @@ import com.squareup.moshi.adapter
167226
if (serializer != null) {
168227
return serializer(obj)
169228
}
170-
229+
171230
return if (contentType?.contains("json") == true) {
172231
{{#moshi}}
173232
Serializer.moshi.adapter(Any::class.java).toJson(obj)
@@ -191,7 +250,7 @@ import com.squareup.moshi.adapter
191250
/**
192251
* Adds any type to a MultipartBody.Builder
193252
* Defined a helper in the requestBody method to not duplicate code
194-
* It will be used when the content is a FormDataMediaType and the body of the PartConfig is not a File.
253+
* It will be used when the content is a `FORM_DATA_MEDIA_TYPE` and the body of the PartConfig is not a File.
195254
*
196255
* @param name The field name to add in the request
197256
* @param headers The headers that are in the PartConfig
@@ -214,7 +273,7 @@ import com.squareup.moshi.adapter
214273
when {
215274
content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull())
216275
content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull())
217-
mediaType == FormDataMediaType ->
276+
mediaType == FORM_DATA_MEDIA_TYPE ->
218277
MultipartBody.Builder()
219278
.setType(MultipartBody.FORM)
220279
.apply {
@@ -236,7 +295,7 @@ import com.squareup.moshi.adapter
236295
}
237296
}
238297
}.build()
239-
mediaType == FormUrlEncMediaType -> {
298+
mediaType == FORM_URL_ENC_MEDIA_TYPE -> {
240299
FormBody.Builder().apply {
241300
// content's type *must* be Map<String, PartConfig<*>>
242301
@Suppress("UNCHECKED_CAST")
@@ -261,23 +320,22 @@ import com.squareup.moshi.adapter
261320
{{#kotlinx_serialization}}
262321
Serializer.kotlinxSerializationJson.encodeToString(content)
263322
{{/kotlinx_serialization}}
264-
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
323+
.toRequestBody((mediaType ?: JSON_MEDIA_TYPE).toMediaTypeOrNull())
265324
}
266-
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
267-
mediaType == TextMediaType && content is String ->
268-
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
325+
mediaType == XML_MEDIA_TYPE -> throw UnsupportedOperationException("xml not currently supported.")
326+
mediaType == TEXT_MEDIA_TYPE && content is String ->
327+
content.toRequestBody(TEXT_MEDIA_TYPE.toMediaTypeOrNull())
269328
// TODO: this should be extended with other serializers
270329
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
271330
}
272331

273332
{{#moshi}}
274333
@OptIn(ExperimentalStdlibApi::class)
275334
{{/moshi}}
276-
protected inline fun <reified T: Any?> responseBody(response: Response, mediaType: String? = JsonMediaType): T? {
335+
protected inline fun <reified T: Any?> responseBody(response: Response, mediaType: String? = JSON_MEDIA_TYPE): T? {
277336
val body = response.body
278-
if(body == null) {
279-
return null
280-
} else if (T::class.java == Unit::class.java) {
337+
338+
if (T::class.java == Unit::class.java) {
281339
// No need to parse the body when we're not interested in the body
282340
// Useful when API is returning other Content-Type
283341
return null
@@ -352,8 +410,8 @@ import com.squareup.moshi.adapter
352410
}}{{#jackson}}Serializer.jacksonObjectMapper.readValue(bodyContent, object: TypeReference<T>() {}){{/jackson}}{{!
353411
}}{{#kotlinx_serialization}}Serializer.kotlinxSerializationJson.decodeFromString<T>(bodyContent){{/kotlinx_serialization}}
354412
}
355-
mediaType == OctetMediaType -> body.bytes() as? T
356-
mediaType == TextMediaType -> body.string() as? T
413+
mediaType == OCTET_MEDIA_TYPE -> body.bytes() as? T
414+
mediaType == TEXT_MEDIA_TYPE -> body.string() as? T
357415
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
358416
}
359417
}
@@ -394,26 +452,26 @@ import com.squareup.moshi.adapter
394452
{{/isApiKey}}
395453
{{#isBasic}}
396454
{{#isBasicBasic}}
397-
if (requestConfig.headers[Authorization].isNullOrEmpty()) {
455+
if (requestConfig.headers[AUTHORIZATION].isNullOrEmpty()) {
398456
username?.let { username ->
399457
password?.let { password ->
400-
requestConfig.headers[Authorization] = okhttp3.Credentials.basic(username, password)
458+
requestConfig.headers[AUTHORIZATION] = okhttp3.Credentials.basic(username, password)
401459
}
402460
}
403461
}
404462
{{/isBasicBasic}}
405463
{{#isBasicBearer}}
406-
if (requestConfig.headers[Authorization].isNullOrEmpty()) {
464+
if (requestConfig.headers[AUTHORIZATION].isNullOrEmpty()) {
407465
accessToken?.let { accessToken ->
408-
requestConfig.headers[Authorization] = "Bearer $accessToken"
466+
requestConfig.headers[AUTHORIZATION] = "Bearer $accessToken"
409467
}
410468
}
411469
{{/isBasicBearer}}
412470
{{/isBasic}}
413471
{{#isOAuth}}
414-
if (requestConfig.headers[Authorization].isNullOrEmpty()) {
472+
if (requestConfig.headers[AUTHORIZATION].isNullOrEmpty()) {
415473
accessToken?.let { accessToken ->
416-
requestConfig.headers[Authorization] = "Bearer $accessToken "
474+
requestConfig.headers[AUTHORIZATION] = "Bearer $accessToken "
417475
}
418476
}
419477
{{/isOAuth}}
@@ -440,21 +498,21 @@ import com.squareup.moshi.adapter
440498
}.build()
441499

442500
// take content-type/accept from spec or set to default (application/json) if not defined
443-
if (requestConfig.body != null && requestConfig.headers[ContentType].isNullOrEmpty()) {
444-
requestConfig.headers[ContentType] = JsonMediaType
501+
if (requestConfig.body != null && requestConfig.headers[CONTENT_TYPE].isNullOrEmpty()) {
502+
requestConfig.headers[CONTENT_TYPE] = JSON_MEDIA_TYPE
445503
}
446-
if (requestConfig.headers[Accept].isNullOrEmpty()) {
447-
requestConfig.headers[Accept] = JsonMediaType
504+
if (requestConfig.headers[ACCEPT].isNullOrEmpty()) {
505+
requestConfig.headers[ACCEPT] = JSON_MEDIA_TYPE
448506
}
449507
val headers = requestConfig.headers
450508

451-
if (headers[Accept].isNullOrEmpty()) {
452-
throw kotlin.IllegalStateException("Missing Accept header. This is required.")
509+
if (headers[ACCEPT].isNullOrEmpty()) {
510+
throw kotlin.IllegalStateException("Missing ACCEPT header. This is required.")
453511
}
454512

455-
val contentType = if (headers[ContentType] != null) {
513+
val contentType = if (headers[CONTENT_TYPE] != null) {
456514
// TODO: support multiple contentType options here.
457-
(headers[ContentType] as String).substringBefore(";").lowercase(Locale.US)
515+
(headers[CONTENT_TYPE] as String).substringBefore(";").lowercase(Locale.US)
458516
} else {
459517
null
460518
}
@@ -498,7 +556,7 @@ import com.squareup.moshi.adapter
498556
val response = client.newCall(request).execute()
499557
{{/useCoroutines}}
500558

501-
val accept = response.header(ContentType)?.substringBefore(";")?.lowercase(Locale.US)
559+
val accept = response.header(CONTENT_TYPE)?.substringBefore(";")?.lowercase(Locale.US)
502560

503561
// TODO: handle specific mapping types. e.g. Map<int, Class<?>>
504562
@Suppress("UNNECESSARY_SAFE_CALL")

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-retrofit2/infrastructure/ApiClient.kt.mustache

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,16 @@ import okhttp3.MediaType.Companion.toMediaType
376376
}
377377

378378
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
379-
@JvmStatic
380-
protected val baseUrlKey: String = "{{packageName}}.baseUrl"
379+
protected const val BASE_URL_KEY: String = "{{packageName}}.baseUrl"
380+
@Deprecated(
381+
message = "Please use the capitalized constant `BASE_URL_KEY` instead.",
382+
replaceWith = ReplaceWith("BASE_URL_KEY")
383+
)
384+
protected const val baseUrlKey: String = BASE_URL_KEY
381385
382386
@JvmStatic
383387
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {
384-
System.getProperties().getProperty(baseUrlKey, "{{{basePath}}}")
388+
System.getProperties().getProperty(BASE_URL_KEY, "{{{basePath}}}")
385389
}
386390
}
387391
}

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-vertx/infrastructure/ApiClient.kt.mustache

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ import com.google.gson.reflect.TypeToken
1212

1313
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient(val basePath: kotlin.String = defaultBasePath, val accessToken: String? = null, val apiKey: MutableMap<String, String> = mutableMapOf(), val apiKeyPrefix: MutableMap<String, String> = mutableMapOf(), var username: String? = null, var password: String? = null, val vertx: Vertx) {
1414
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
15-
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = "{{packageName}}.baseUrl"
15+
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val BASE_URL_KEY: String = "{{packageName}}.baseUrl"
16+
@Deprecated(
17+
message = "Please use the capitalized constant `BASE_URL_KEY` instead.",
18+
replaceWith = ReplaceWith("BASE_URL_KEY")
19+
)
20+
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = BASE_URL_KEY
1621

1722
@JvmStatic
1823
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {
19-
System.getProperties().getProperty(baseUrlKey, "{{{basePath}}}")
24+
System.getProperties().getProperty(BASE_URL_KEY, "{{{basePath}}}")
2025
}
2126
}
2227

samples/client/echo_api/kotlin-jvm-okhttp/src/main/kotlin/org/openapitools/client/apis/AuthApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ open class AuthApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
4040
companion object {
4141
@JvmStatic
4242
val defaultBasePath: String by lazy {
43-
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
43+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
4444
}
4545
}
4646

samples/client/echo_api/kotlin-jvm-okhttp/src/main/kotlin/org/openapitools/client/apis/BodyApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ open class BodyApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
4242
companion object {
4343
@JvmStatic
4444
val defaultBasePath: String by lazy {
45-
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
45+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
4646
}
4747
}
4848

samples/client/echo_api/kotlin-jvm-okhttp/src/main/kotlin/org/openapitools/client/apis/FormApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ open class FormApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
4040
companion object {
4141
@JvmStatic
4242
val defaultBasePath: String by lazy {
43-
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
43+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
4444
}
4545
}
4646

samples/client/echo_api/kotlin-jvm-okhttp/src/main/kotlin/org/openapitools/client/apis/HeaderApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ open class HeaderApi(basePath: kotlin.String = defaultBasePath, client: Call.Fac
4141
companion object {
4242
@JvmStatic
4343
val defaultBasePath: String by lazy {
44-
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
44+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
4545
}
4646
}
4747

samples/client/echo_api/kotlin-jvm-okhttp/src/main/kotlin/org/openapitools/client/apis/PathApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ open class PathApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
4141
companion object {
4242
@JvmStatic
4343
val defaultBasePath: String by lazy {
44-
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
44+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
4545
}
4646
}
4747

samples/client/echo_api/kotlin-jvm-okhttp/src/main/kotlin/org/openapitools/client/apis/QueryApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ open class QueryApi(basePath: kotlin.String = defaultBasePath, client: Call.Fact
4343
companion object {
4444
@JvmStatic
4545
val defaultBasePath: String by lazy {
46-
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
46+
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
4747
}
4848
}
4949

0 commit comments

Comments
 (0)