|
19 | 19 |
|
20 | 20 | import com.google.common.collect.ImmutableMap; |
21 | 21 | import com.samskivert.mustache.Mustache; |
| 22 | +import io.swagger.v3.oas.models.OpenAPI; |
22 | 23 | import io.swagger.v3.oas.models.Operation; |
| 24 | +import io.swagger.v3.oas.models.PathItem; |
23 | 25 | import io.swagger.v3.oas.models.media.Schema; |
| 26 | +import io.swagger.v3.oas.models.parameters.HeaderParameter; |
24 | 27 | import io.swagger.v3.oas.models.parameters.Parameter; |
25 | 28 | import io.swagger.v3.oas.models.parameters.RequestBody; |
26 | 29 | import io.swagger.v3.oas.models.responses.ApiResponse; |
|
34 | 37 | import org.openapitools.codegen.model.ModelMap; |
35 | 38 | import org.openapitools.codegen.model.ModelsMap; |
36 | 39 | import org.openapitools.codegen.model.OperationsMap; |
| 40 | +import org.openapitools.codegen.model.WebhooksMap; |
37 | 41 | import org.openapitools.codegen.templating.mustache.IndentedLambda; |
38 | 42 | import org.openapitools.codegen.utils.ModelUtils; |
39 | 43 | import org.slf4j.Logger; |
@@ -355,6 +359,7 @@ public void processOpts() { |
355 | 359 | if (!withoutRuntimeChecks) { |
356 | 360 | this.modelTemplateFiles.put("models.mustache", ".ts"); |
357 | 361 | } |
| 362 | + additionalProperties.put("modelSerializersEnabled", !withoutRuntimeChecks); |
358 | 363 |
|
359 | 364 | // `date` needs the model (de)serialization to convert with, which |
360 | 365 | // withoutRuntimeChecks removes: the raw string would just be cast to Date. |
@@ -708,7 +713,81 @@ public List<CodegenParameter> fromRequestBodyToFormParameters(RequestBody body, |
708 | 713 | @Override |
709 | 714 | public ExtendedCodegenParameter fromParameter(Parameter parameter, Set<String> imports) { |
710 | 715 | CodegenParameter cp = super.fromParameter(parameter, imports); |
711 | | - return new ExtendedCodegenParameter(cp); |
| 716 | + ExtendedCodegenParameter result = new ExtendedCodegenParameter(cp); |
| 717 | + Parameter resolvedParameter = ModelUtils.getReferencedParameter(openAPI, parameter); |
| 718 | + result.jsonHeaderUsesModelSerializer = cp.headerIsJsonMimeType && cp.isModel |
| 719 | + && hasGeneratedModelHeaderSchema(openAPI, resolvedParameter); |
| 720 | + return result; |
| 721 | + } |
| 722 | + |
| 723 | + @Override |
| 724 | + public void processOpenAPI(OpenAPI openAPI) { |
| 725 | + super.processOpenAPI(openAPI); |
| 726 | + if (!withoutRuntimeChecks) { |
| 727 | + return; |
| 728 | + } |
| 729 | + if (openAPI.getPaths() != null) { |
| 730 | + for (PathItem path : openAPI.getPaths().values()) { |
| 731 | + if (hasJsonContentModelHeader(openAPI, path)) { |
| 732 | + enableJsonHeaderModelSerializers(); |
| 733 | + return; |
| 734 | + } |
| 735 | + } |
| 736 | + } |
| 737 | + if (openAPI.getWebhooks() != null) { |
| 738 | + for (PathItem webhook : openAPI.getWebhooks().values()) { |
| 739 | + if (hasJsonContentModelHeader(openAPI, webhook)) { |
| 740 | + enableJsonHeaderModelSerializers(); |
| 741 | + return; |
| 742 | + } |
| 743 | + } |
| 744 | + } |
| 745 | + } |
| 746 | + |
| 747 | + private boolean hasJsonContentModelHeader(OpenAPI openAPI, PathItem path) { |
| 748 | + if (hasJsonContentModelHeader(openAPI, path.getParameters())) { |
| 749 | + return true; |
| 750 | + } |
| 751 | + for (Operation operation : path.readOperations()) { |
| 752 | + if (hasJsonContentModelHeader(openAPI, operation.getParameters())) { |
| 753 | + return true; |
| 754 | + } |
| 755 | + } |
| 756 | + return false; |
| 757 | + } |
| 758 | + |
| 759 | + private boolean hasJsonContentModelHeader(OpenAPI openAPI, List<Parameter> parameters) { |
| 760 | + return parameters != null && parameters.stream() |
| 761 | + .map(parameter -> ModelUtils.getReferencedParameter(openAPI, parameter)) |
| 762 | + .anyMatch(parameter -> isJsonContentHeader(parameter) |
| 763 | + && hasGeneratedModelHeaderSchema(openAPI, parameter)); |
| 764 | + } |
| 765 | + |
| 766 | + private boolean isJsonContentHeader(Parameter parameter) { |
| 767 | + if (parameter == null |
| 768 | + || !(parameter instanceof HeaderParameter || "header".equalsIgnoreCase(parameter.getIn())) |
| 769 | + || parameter.getSchema() != null |
| 770 | + || parameter.getContent() == null |
| 771 | + || parameter.getContent().isEmpty()) { |
| 772 | + return false; |
| 773 | + } |
| 774 | + String contentType = parameter.getContent().keySet().iterator().next(); |
| 775 | + return isJsonMimeType(contentType) || isJsonVendorMimeType(contentType); |
| 776 | + } |
| 777 | + |
| 778 | + private boolean hasGeneratedModelHeaderSchema(OpenAPI openAPI, Parameter parameter) { |
| 779 | + if (parameter.getContent() == null || parameter.getContent().isEmpty()) { |
| 780 | + return false; |
| 781 | + } |
| 782 | + Schema schema = parameter.getContent().values().iterator().next().getSchema(); |
| 783 | + return schema != null && schema.get$ref() != null |
| 784 | + && ModelUtils.isModel(ModelUtils.getReferencedSchema(openAPI, schema)); |
| 785 | + } |
| 786 | + |
| 787 | + private void enableJsonHeaderModelSerializers() { |
| 788 | + modelTemplateFiles.put("models.mustache", ".ts"); |
| 789 | + additionalProperties.put("jsonHeaderModelSerializers", true); |
| 790 | + additionalProperties.put("modelSerializersEnabled", true); |
712 | 791 | } |
713 | 792 |
|
714 | 793 | @Override |
@@ -875,6 +954,20 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap operations, L |
875 | 954 | return operations; |
876 | 955 | } |
877 | 956 |
|
| 957 | + @Override |
| 958 | + public WebhooksMap postProcessWebhooksWithModels(WebhooksMap webhooks, List<ModelMap> allModels) { |
| 959 | + if (webhooks.getWebhooks().getOperation().stream() |
| 960 | + .anyMatch(operation -> operation.headerParams != null && operation.headerParams.stream() |
| 961 | + .anyMatch(parameter -> ((ExtendedCodegenParameter) parameter).jsonHeaderUsesModelSerializer))) { |
| 962 | + for (Map<String, String> im : webhooks.getImports()) { |
| 963 | + String className = im.get("import").replace(modelPackage() + ".", ""); |
| 964 | + im.put("className", className); |
| 965 | + im.put("classFileName", convertUsingFileNamingConvention(className)); |
| 966 | + } |
| 967 | + } |
| 968 | + return webhooks; |
| 969 | + } |
| 970 | + |
878 | 971 | @Override |
879 | 972 | public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) { |
880 | 973 | Map<String, Object> parentObjs = super.postProcessSupportingFileData(objs); |
@@ -1544,6 +1637,7 @@ private static String getItemsDataType(CodegenProperty items) { |
1544 | 1637 |
|
1545 | 1638 | public class ExtendedCodegenParameter extends CodegenParameter { |
1546 | 1639 | public String dataTypeAlternate; |
| 1640 | + public boolean jsonHeaderUsesModelSerializer; |
1547 | 1641 | public boolean isUniqueId; // this parameter represents a unique id (x-isUniqueId: true) |
1548 | 1642 | public List<CodegenProperty> readOnlyVars; // a list of read-only properties |
1549 | 1643 | public boolean hasReadOnly = false; // indicates the type has at least one read-only property |
@@ -1572,6 +1666,7 @@ public ExtendedCodegenParameter(CodegenParameter cp) { |
1572 | 1666 | this.isQueryParam = cp.isQueryParam; |
1573 | 1667 | this.isPathParam = cp.isPathParam; |
1574 | 1668 | this.isHeaderParam = cp.isHeaderParam; |
| 1669 | + this.headerIsJsonMimeType = cp.headerIsJsonMimeType; |
1575 | 1670 | this.isCookieParam = cp.isCookieParam; |
1576 | 1671 | this.isBodyParam = cp.isBodyParam; |
1577 | 1672 | this.isContainer = cp.isContainer; |
@@ -1660,6 +1755,7 @@ public ExtendedCodegenParameter copy() { |
1660 | 1755 | CodegenParameter superCopy = super.copy(); |
1661 | 1756 | ExtendedCodegenParameter output = new ExtendedCodegenParameter(superCopy); |
1662 | 1757 | output.dataTypeAlternate = this.dataTypeAlternate; |
| 1758 | + output.jsonHeaderUsesModelSerializer = this.jsonHeaderUsesModelSerializer; |
1663 | 1759 | output.isUniqueId = this.isUniqueId; |
1664 | 1760 | return output; |
1665 | 1761 | } |
|
0 commit comments