diff --git a/TopModel.Core/EndpointExtensions.cs b/TopModel.Core/EndpointExtensions.cs index c29043fc..4d0fc9ec 100644 --- a/TopModel.Core/EndpointExtensions.cs +++ b/TopModel.Core/EndpointExtensions.cs @@ -4,9 +4,14 @@ namespace TopModel.Core; public static class EndpointExtensions { - public static IProperty? GetBodyParam(this Endpoint endpoint) + public static IProperty? GetJsonBodyParam(this Endpoint endpoint) { - var bodyParams = endpoint.Params.Where(param => param is CompositionProperty || param is IFieldProperty { Domain.BodyParam: true }).Where(p => p.Domain?.MediaType != "multipart/form-data"); + if (endpoint.IsMultipart) + { + return null; + } + + var bodyParams = endpoint.Params.Where(param => param is CompositionProperty || param is IFieldProperty { Domain.BodyParam: true }); return bodyParams.Count() > 1 ? throw new ModelException(endpoint, $"L'endpoint '{endpoint.Name}' doit avoir une seule propriété dans le body. Propriétés trouvées : {string.Join(", ", bodyParams)}") : bodyParams.SingleOrDefault(); @@ -34,9 +39,9 @@ public static IEnumerable GetRouteParams(this Endpoint endpoint) return endpoint.Params.Where(param => endpoint.Route.Contains($"{{{param.GetParamName()}}}")); } - public static bool IsBodyParam(this IProperty property) + public static bool IsJsonBodyParam(this IProperty property) { - return property.Endpoint.GetBodyParam() == property; + return property.Endpoint.GetJsonBodyParam() == property; } public static bool IsQueryParam(this IProperty property) diff --git a/TopModel.Core/Model/Endpoint.cs b/TopModel.Core/Model/Endpoint.cs index 94ed9272..861c5772 100644 --- a/TopModel.Core/Model/Endpoint.cs +++ b/TopModel.Core/Model/Endpoint.cs @@ -39,6 +39,8 @@ public string FullRoute public IList Params { get; set; } = new List(); + public bool IsMultipart => Params.Any(p => p.Domain?.MediaType == "multipart/form-data"); + public IList Properties => Params.Concat(new[] { Returns! }).Where(p => p != null).ToList(); public bool PreservePropertyCasing { get; set; } diff --git a/TopModel.Generator.Csharp/CSharpApiClientGenerator.cs b/TopModel.Generator.Csharp/CSharpApiClientGenerator.cs index 3e322c4d..28ace3f9 100644 --- a/TopModel.Generator.Csharp/CSharpApiClientGenerator.cs +++ b/TopModel.Generator.Csharp/CSharpApiClientGenerator.cs @@ -33,7 +33,7 @@ protected override void HandleFile(string filePath, string fileName, string tag, { using var fw = new CSharpWriter(filePath, _logger); - var hasBody = endpoints.Any(e => e.GetBodyParam() != null); + var hasBody = endpoints.Any(e => e.GetJsonBodyParam() != null); var hasReturn = endpoints.Any(e => e.Returns != null); var hasJson = hasReturn || hasBody; @@ -166,7 +166,7 @@ protected override void HandleFile(string filePath, string fileName, string tag, fw.WriteLine(")"); fw.WriteLine(1, "{"); - var bodyParam = endpoint.GetBodyParam(); + var bodyParam = endpoint.GetJsonBodyParam(); fw.WriteLine(2, $"await EnsureAuthentication();"); diff --git a/TopModel.Generator.Csharp/CSharpApiServerGenerator.cs b/TopModel.Generator.Csharp/CSharpApiServerGenerator.cs index a4ffdd1f..3557982f 100644 --- a/TopModel.Generator.Csharp/CSharpApiServerGenerator.cs +++ b/TopModel.Generator.Csharp/CSharpApiServerGenerator.cs @@ -123,23 +123,18 @@ private string GetParam(IProperty param) { var sb = new StringBuilder(); - var hasForm = param.Endpoint.Params.Any(p => p.Domain?.MediaType == "multipart/form-data"); - - if (param.IsBodyParam()) + if (param.Endpoint.IsMultipart) { - if (hasForm) - { - sb.Append("[FromForm] "); - } - else - { - sb.Append("[FromBody] "); - } + sb.Append("[FromForm] "); + } + else if (param.IsJsonBodyParam()) + { + sb.Append("[FromBody] "); } - sb.Append($@"{Config.GetType(param, nonNullable: param.IsRouteParam() || param.IsQueryParam() && !hasForm && Config.GetValue(param, Classes) != "null")} {param.GetParamName().Verbatim()}"); + sb.Append($@"{Config.GetType(param, nonNullable: param.IsRouteParam() || param.IsQueryParam() && !param.Endpoint.IsMultipart && Config.GetValue(param, Classes) != "null")} {param.GetParamName().Verbatim()}"); - if (param.IsQueryParam() && !hasForm) + if (param.IsQueryParam() && !param.Endpoint.IsMultipart) { sb.Append($" = {Config.GetValue(param, Classes)}"); } diff --git a/TopModel.Generator.Javascript/AngularApiClientGenerator.cs b/TopModel.Generator.Javascript/AngularApiClientGenerator.cs index d0aaa541..88fe33e9 100644 --- a/TopModel.Generator.Javascript/AngularApiClientGenerator.cs +++ b/TopModel.Generator.Javascript/AngularApiClientGenerator.cs @@ -67,8 +67,7 @@ protected override void HandleFile(string filePath, string fileName, string tag, WriteEndpoint(endpoint, fw); } - var hasForm = endpoints.Any(endpoint => endpoint.Params.Any(p => p.Domain?.MediaType == "multipart/form-data")); - if (hasForm) + if (endpoints.Any(e => e.IsMultipart)) { fw.WriteLine(@" private fillFormData(data: any, formData: FormData, prefix = """") { @@ -106,7 +105,6 @@ private void WriteEndpoint(Endpoint endpoint, FileWriter fw) fw.WriteLine(1, " */"); fw.Write(1, $"{endpoint.NameCamel}("); - var hasForm = endpoint.Params.Any(p => p.Domain?.MediaType == "multipart/form-data"); var hasProperty = false; foreach (var param in endpoint.Params) { @@ -117,10 +115,10 @@ private void WriteEndpoint(Endpoint endpoint, FileWriter fw) hasProperty = true; var defaultValue = Config.GetValue(param, Classes); - fw.Write($"{param.GetParamName()}{(param.IsQueryParam() && !hasForm && defaultValue == "undefined" ? "?" : string.Empty)}: {Config.GetType(param, Classes)}{(defaultValue != "undefined" ? $" = {defaultValue}" : string.Empty)}"); + fw.Write($"{param.GetParamName()}{(param.IsQueryParam() && !endpoint.IsMultipart && defaultValue == "undefined" ? "?" : string.Empty)}: {Config.GetType(param, Classes)}{(defaultValue != "undefined" ? $" = {defaultValue}" : string.Empty)}"); } - if (endpoint.GetQueryParams().Any() && !hasForm) + if (endpoint.GetQueryParams().Any() && !endpoint.IsMultipart) { if (hasProperty) { @@ -145,7 +143,7 @@ private void WriteEndpoint(Endpoint endpoint, FileWriter fw) fw.Write(returnType); fw.WriteLine("> {"); - if (hasForm) + if (endpoint.IsMultipart) { fw.WriteLine(" const formData = new FormData();"); fw.WriteLine(" this.fillFormData("); @@ -178,7 +176,7 @@ private void WriteEndpoint(Endpoint endpoint, FileWriter fw) fw.WriteLine(2, $@"return this.http.{endpoint.Method.ToLower()}<{returnType}>(`/{endpoint.FullRoute}`, formData);"); fw.WriteLine("}"); return; - } + } if (endpoint.GetQueryParams().Any()) { @@ -205,9 +203,9 @@ private void WriteEndpoint(Endpoint endpoint, FileWriter fw) fw.Write(2, $@"return this.http.{endpoint.Method.ToLower()}<{returnType}>(`/{endpoint.FullRoute.Replace("{", "${")}`"); } - if (endpoint.GetBodyParam() != null) + if (endpoint.GetJsonBodyParam() != null) { - fw.Write($", {endpoint.GetBodyParam()!.GetParamName()}"); + fw.Write($", {endpoint.GetJsonBodyParam()!.GetParamName()}"); } else if (endpoint.Method != "OPTIONS" && endpoint.Method != "GET" && endpoint.Method != "DELETE") { diff --git a/TopModel.Generator.Javascript/JavascriptApiClientGenerator.cs b/TopModel.Generator.Javascript/JavascriptApiClientGenerator.cs index 21f3e499..f75bcd76 100644 --- a/TopModel.Generator.Javascript/JavascriptApiClientGenerator.cs +++ b/TopModel.Generator.Javascript/JavascriptApiClientGenerator.cs @@ -69,12 +69,10 @@ protected override void HandleFile(string filePath, string fileName, string tag, fw.WriteLine(" */"); fw.Write($"export function {endpoint.NameCamel}("); - var hasForm = endpoint.Params.Any(p => p.Domain?.MediaType == "multipart/form-data"); - foreach (var param in endpoint.Params) { var defaultValue = Config.GetValue(param, Classes); - fw.Write($"{param.GetParamName()}{(param.IsQueryParam() && !hasForm && defaultValue == "undefined" ? "?" : string.Empty)}: {Config.GetType(param, Classes)}{(defaultValue != "undefined" ? $" = {defaultValue}" : string.Empty)}, "); + fw.Write($"{param.GetParamName()}{(param.IsQueryParam() && !endpoint.IsMultipart && defaultValue == "undefined" ? "?" : string.Empty)}: {Config.GetType(param, Classes)}{(defaultValue != "undefined" ? $" = {defaultValue}" : string.Empty)}, "); } fw.Write("options: RequestInit = {}): Promise<"); @@ -89,7 +87,7 @@ protected override void HandleFile(string filePath, string fileName, string tag, fw.WriteLine("> {"); - if (hasForm) + if (endpoint.IsMultipart) { fw.WriteLine(" const body = new FormData();"); fw.WriteLine(" fillFormData("); @@ -126,12 +124,12 @@ protected override void HandleFile(string filePath, string fileName, string tag, fw.Write($@" return {fetch}(""{endpoint.Method}"", `./{endpoint.FullRoute.Replace("{", "${")}`, {{"); - if (endpoint.GetBodyParam() != null) + if (endpoint.GetJsonBodyParam() != null) { - fw.Write($"body: {endpoint.GetBodyParam()!.GetParamName()}"); + fw.Write($"body: {endpoint.GetJsonBodyParam()!.GetParamName()}"); } - if (endpoint.GetBodyParam() != null && endpoint.GetQueryParams().Any()) + if (endpoint.GetJsonBodyParam() != null && endpoint.GetQueryParams().Any()) { fw.Write(", "); } diff --git a/TopModel.Generator.Jpa/SpringClientApiGenerator.cs b/TopModel.Generator.Jpa/SpringClientApiGenerator.cs index 7b6b4899..92c50fd9 100644 --- a/TopModel.Generator.Jpa/SpringClientApiGenerator.cs +++ b/TopModel.Generator.Jpa/SpringClientApiGenerator.cs @@ -106,7 +106,7 @@ private List GetMethodParams(Endpoint endpoint, bool withType = true, bo } } - var bodyParam = endpoint.GetBodyParam(); + var bodyParam = endpoint.GetJsonBodyParam(); if (bodyParam != null && withBody) { if (withType) @@ -176,7 +176,7 @@ private void WriteEndpointCallMethod(JavaWriter fw, Endpoint endpoint) fw.WriteLine(1, $"public {returnType} {endpoint.NameCamel}({string.Join(", ", GetMethodParams(endpoint))}){{"); fw.WriteLine(2, $"HttpHeaders headers = this.getHeaders();"); fw.WriteLine(2, $"UriComponentsBuilder uri = this.{endpoint.NameCamel}UriComponentsBuilder({string.Join(", ", GetMethodParams(endpoint, false, false))});"); - var body = $"new HttpEntity<>({(endpoint.GetBodyParam()?.GetParamName() != null ? $"{endpoint.GetBodyParam()?.GetParamName()}, " : string.Empty)}headers)"; + var body = $"new HttpEntity<>({(endpoint.GetJsonBodyParam()?.GetParamName() != null ? $"{endpoint.GetJsonBodyParam()?.GetParamName()}, " : string.Empty)}headers)"; if (endpoint.Returns != null) { fw.WriteLine(2, $"return this.restTemplate.exchange(uri.build().toUri(), HttpMethod.{endpoint.Method}, {body}, {returnClass});"); diff --git a/TopModel.Generator.Jpa/SpringServerApiGenerator.cs b/TopModel.Generator.Jpa/SpringServerApiGenerator.cs index 263abf9c..848655f2 100644 --- a/TopModel.Generator.Jpa/SpringServerApiGenerator.cs +++ b/TopModel.Generator.Jpa/SpringServerApiGenerator.cs @@ -141,10 +141,7 @@ private void WriteEndpoint(JavaWriter fw, Endpoint endpoint, string tag) methodParams.Add($"{ann}{(decoratorAnnotations.Length > 0 ? $" {decoratorAnnotations}" : string.Empty)}{Config.GetType(param)} {param.GetParamName()}"); } - var bodyParam = endpoint.GetBodyParam(); - var hasForm = endpoint.Params.Any(p => p.Domain?.MediaType == "multipart/form-data"); - - if (hasForm) + if (endpoint.IsMultipart) { foreach (var param in endpoint.Params.Where(param => param is CompositionProperty || param is IFieldProperty { Domain.BodyParam: true })) { @@ -163,13 +160,17 @@ private void WriteEndpoint(JavaWriter fw, Endpoint endpoint, string tag) methodParams.Add($"{ann}{Config.GetType(param)} {param.GetParamName()}"); } } - else if (bodyParam != null) + else { - var ann = string.Empty; - ann += @$"@RequestBody @Valid "; - fw.AddImport("org.springframework.web.bind.annotation.RequestBody"); - fw.AddImport(Config.PersistenceMode.ToString().ToLower() + ".validation.Valid"); - methodParams.Add($"{ann}{Config.GetType(bodyParam)} {bodyParam.GetParamName()}"); + var bodyParam = endpoint.GetJsonBodyParam(); + if (bodyParam != null) + { + var ann = string.Empty; + ann += @$"@RequestBody @Valid "; + fw.AddImport("org.springframework.web.bind.annotation.RequestBody"); + fw.AddImport(Config.PersistenceMode.ToString().ToLower() + ".validation.Valid"); + methodParams.Add($"{ann}{Config.GetType(bodyParam)} {bodyParam.GetParamName()}"); + } } fw.WriteLine(1, $"{returnType} {endpoint.NameCamel}({string.Join(", ", methodParams)});");