@@ -28,7 +28,11 @@ class KotlinGenerator : SharedCodegen() {
2828 * This number represents the version of the kotlin template
2929 * Please note that is independent from the Plugin version
3030 */
31- @JvmStatic val VERSION = 11
31+ @JvmStatic val VERSION = 12
32+
33+ // Vendor Extension use to generate the list of top level headers
34+ const val HAS_OPERATION_HEADERS = " hasOperationHeaders"
35+ const val OPERATION_HEADERS = " operationHeaders"
3236 }
3337
3438 private val apiDocPath = " docs/"
@@ -404,7 +408,6 @@ class KotlinGenerator : SharedCodegen() {
404408
405409 codegenOperation.imports.add(" retrofit2.http.Headers" )
406410 codegenOperation.vendorExtensions[X_OPERATION_ID ] = operation?.operationId
407-
408411 getHeadersToIgnore().forEach { headerName ->
409412 ignoreHeaderParameter(headerName, codegenOperation)
410413 }
@@ -413,6 +416,7 @@ class KotlinGenerator : SharedCodegen() {
413416 if (! basePath.isNullOrBlank()) {
414417 codegenOperation.path = codegenOperation.path.removePrefix(" /" )
415418 }
419+ processTopLevelHeaders(codegenOperation)
416420 return codegenOperation
417421 }
418422
@@ -451,4 +455,30 @@ class KotlinGenerator : SharedCodegen() {
451455 override fun removeNonNameElementToCamelCase (name : String? ): String {
452456 return super .removeNonNameElementToCamelCase(name, " [-_:;#\\ [\\ ]]" )
453457 }
458+
459+ /* *
460+ * Function to check if there are Headers that should be applied at the Top level on Retrofit
461+ * with the @Headers annotation. This method will populate the `hasOperationHeaders` and `operationHeaders`
462+ * vendor extensions to support the mustache template.
463+ */
464+ internal fun processTopLevelHeaders (operation : CodegenOperation ) {
465+ val topLevelHeaders = mutableListOf<Pair <String , String >>()
466+
467+ // Send the X-Operation-Id header only if a custom operation ID was set.
468+ val operationId = operation.vendorExtensions[X_OPERATION_ID ] as String?
469+ if (! operationId.isNullOrBlank()) {
470+ topLevelHeaders.add(HEADER_X_OPERATION_ID to operationId)
471+ }
472+
473+ // Send the Content-Type header for the first `consume` mediaType specified.
474+ val firstContentType = operation.consumes?.firstOrNull()
475+ if (operation.formParams.isNullOrEmpty() && firstContentType != null ) {
476+ firstContentType[" mediaType" ]?.let {
477+ topLevelHeaders.add(HEADER_CONTENT_TYPE to it)
478+ }
479+ }
480+
481+ operation.vendorExtensions[HAS_OPERATION_HEADERS ] = topLevelHeaders.isNotEmpty()
482+ operation.vendorExtensions[OPERATION_HEADERS ] = topLevelHeaders
483+ }
454484}
0 commit comments