private string ConstructNewRequestObject(Indent indent, ApiEndpoint apiEndpoint, string endpointPath) { var builder = new StringBuilder(); builder.AppendLine(); indent.Increment(); builder.AppendLine($"{indent}new {apiEndpoint.ToCSharpRequestBodyClassName(endpointPath)!}"); builder.AppendLine($"{indent}{{ "); indent.Increment(); var typeNameForDto = apiEndpoint.ToCSharpRequestBodyClassName(endpointPath); foreach (var field in apiEndpoint.RequestBody !.Fields) { if (field.Type.IsCSharpReferenceType()) { builder.AppendLine($"{indent}{field.ToCSharpPropertyName(typeNameForDto)} = {field.ToCSharpVariableInstanceOrDefaultValue(_codeGenerationContext)},"); } else { builder.AppendLine($"{indent}{field.ToCSharpPropertyName(typeNameForDto)} = {field.ToCSharpVariableName()},"); } } indent.Decrement(); builder.Append($"{indent}}}"); indent.Decrement(); return(builder.ToString()); }
private string GenerateEnumerableMethodForBatchApiEndpoint(ApiEndpoint apiEndpoint, string baseEndpointPath) { var indent = new Indent(); var builder = new StringBuilder(); var endpointPath = (baseEndpointPath + "/" + apiEndpoint.Path.Segments.ToPath()).TrimEnd('/'); var methodNameForEndpoint = apiEndpoint.ToCSharpMethodName(); var batchDataType = ((ApiFieldType.Object)apiEndpoint.ResponseBody !).GetBatchDataType() !; if (apiEndpoint.ResponseBody != null) { var methodParametersBuilder = new MethodParametersBuilder(_codeGenerationContext) .WithParametersForApiParameters(apiEndpoint.Parameters); if (apiEndpoint.RequestBody != null) { if (FeatureFlags.DoNotExposeRequestObjects) { methodParametersBuilder = methodParametersBuilder .WithParametersForApiFields(apiEndpoint.RequestBody.Fields); } else { methodParametersBuilder = methodParametersBuilder .WithParameter( apiEndpoint.ToCSharpRequestBodyClassName(endpointPath) !, "data"); } } var partialType = "Partial<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">"; var funcType = $"Func<{partialType}, {partialType}>?"; methodParametersBuilder = methodParametersBuilder .WithParameter( funcType, "partial", CSharpExpression.NullLiteral); methodParametersBuilder = methodParametersBuilder .WithParameter(CSharpType.CancellationToken.Value, "cancellationToken", CSharpExpression.DefaultLiteral); builder.Append( indent.Wrap(GenerateMethodDocumentationForEndpoint(apiEndpoint))); builder.Append($"{indent}public IAsyncEnumerable<"); builder.Append(batchDataType.ElementType.ToCSharpType(_codeGenerationContext)); builder.Append(">"); builder.Append($" {methodNameForEndpoint}AsyncEnumerable("); builder.Append(methodParametersBuilder.BuildMethodParametersList()); builder.AppendLine(")"); indent.Increment(); builder.Append($"{indent}=> BatchEnumerator.AllItems((batchSkip, batchCancellationToken) => "); builder.Append($"{methodNameForEndpoint}Async("); var partialTypeForBatch = "Partial<Batch<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">>"; builder.Append( methodParametersBuilder .WithDefaultValueForAllParameters(null) .WithDefaultValueForParameter("skip", "batchSkip") .WithDefaultValueForParameter("partial", $"builder => {partialTypeForBatch}.Default().WithNext().WithTotalCount().WithData(partial != null ? partial : _ => {partialType}.Default())") .WithDefaultValueForParameter(CSharpType.CancellationToken.Value, "batchCancellationToken") .BuildMethodCallParameters()); builder.Append("), skip, cancellationToken);"); indent.Decrement(); } else { builder.AppendLine($"{indent}#warning UNSUPPORTED CASE - " + apiEndpoint.ToCSharpMethodName() + " - " + apiEndpoint.Method.ToHttpMethod() + " " + endpointPath); } return(builder.ToString()); }
private string GenerateMethodForApiEndpoint(ApiEndpoint apiEndpoint, string baseEndpointPath) { var indent = new Indent(); var builder = new StringBuilder(); var endpointPath = (baseEndpointPath + "/" + apiEndpoint.Path.Segments.ToPath()).TrimEnd('/'); var apiCallMethod = apiEndpoint.Method.ToHttpMethod(); var methodNameForEndpoint = apiEndpoint.ToCSharpMethodName(); var isResponsePrimitiveOrArrayOfPrimitive = apiEndpoint.ResponseBody is ApiFieldType.Primitive || (apiEndpoint.ResponseBody is ApiFieldType.Array arrayField && arrayField.ElementType is ApiFieldType.Primitive); if (apiEndpoint.ResponseBody == null) { var methodParametersBuilder = new MethodParametersBuilder(_codeGenerationContext) .WithParametersForApiParameters(apiEndpoint.Parameters); if (apiEndpoint.RequestBody != null) { if (FeatureFlags.DoNotExposeRequestObjects) { methodParametersBuilder = methodParametersBuilder .WithParametersForApiFields(apiEndpoint.RequestBody.Fields); } else { methodParametersBuilder = methodParametersBuilder .WithParameter( apiEndpoint.ToCSharpRequestBodyClassName(endpointPath) !, "data"); } } methodParametersBuilder = methodParametersBuilder .WithParameter(CSharpType.CancellationToken.Value, "cancellationToken", CSharpExpression.DefaultLiteral); builder.Append( indent.Wrap(GenerateMethodDocumentationForEndpoint(apiEndpoint))); builder.Append($"{indent}public async Task {methodNameForEndpoint}Async("); builder.Append(methodParametersBuilder.BuildMethodParametersList()); builder.AppendLine(")"); builder.AppendLine($"{indent}{{"); indent.Increment(); // Generate query string var requestParametersBuilder = new QueryStringParameterConversionGenerator("queryParameters", _codeGenerationContext) .WithQueryStringParametersForEndpoint(apiEndpoint); if (apiEndpoint.ResponseBody != null && !isResponsePrimitiveOrArrayOfPrimitive) { var partialType = "Partial<" + apiEndpoint.ResponseBody.GetArrayElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">"; requestParametersBuilder = requestParametersBuilder .WithQueryStringParameter("$fields", $"(partial != null ? partial(new {partialType}()) : {partialType}.Default()).ToString()"); } builder.AppendLine($"{indent}var {requestParametersBuilder.TargetNameValueCollectionName} = new NameValueCollection();"); requestParametersBuilder.WriteTo(builder, indent); builder.AppendLine($"{indent}"); // Generate HTTP request builder.Append($"{indent}await _connection.RequestResourceAsync"); builder.Append("(\"" + apiCallMethod + "\", "); builder.Append("$\"api/http/" + endpointPath + "{" + requestParametersBuilder.TargetNameValueCollectionName + ".ToQueryString()}"); builder.Append("\""); if (apiEndpoint.RequestBody != null) { if (FeatureFlags.DoNotExposeRequestObjects) { // TODO MAARTEN REFACTOR WITH PROPER NEWLINES builder.Append(", " + ConstructNewRequestObject(indent, apiEndpoint, endpointPath)); } else { builder.Append(", data"); } } builder.Append(", cancellationToken"); builder.AppendLine(");"); indent.Decrement(); builder.AppendLine($"{indent}}}"); } else if (apiEndpoint.ResponseBody != null) { var methodParametersBuilder = new MethodParametersBuilder(_codeGenerationContext) .WithParametersForApiParameters(apiEndpoint.Parameters); if (apiEndpoint.RequestBody != null) { if (FeatureFlags.DoNotExposeRequestObjects) { methodParametersBuilder = methodParametersBuilder .WithParametersForApiFields(apiEndpoint.RequestBody.Fields); } else { methodParametersBuilder = methodParametersBuilder .WithParameter( apiEndpoint.ToCSharpRequestBodyClassName(endpointPath) !, "data"); } } if (apiEndpoint.ResponseBody != null && !isResponsePrimitiveOrArrayOfPrimitive) { var partialType = "Partial<" + apiEndpoint.ResponseBody.GetArrayElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">"; var funcType = $"Func<{partialType}, {partialType}>?"; methodParametersBuilder = methodParametersBuilder .WithParameter( funcType, "partial", CSharpExpression.NullLiteral); } methodParametersBuilder = methodParametersBuilder .WithParameter(CSharpType.CancellationToken.Value, "cancellationToken", CSharpExpression.DefaultLiteral); builder.Append( indent.Wrap(GenerateMethodDocumentationForEndpoint(apiEndpoint))); builder.Append($"{indent}public async Task<"); builder.Append(apiEndpoint.ResponseBody !.ToCSharpType(_codeGenerationContext)); builder.Append(">"); builder.Append($" {methodNameForEndpoint}Async("); builder.Append(methodParametersBuilder.BuildMethodParametersList()); builder.AppendLine(")"); builder.AppendLine($"{indent}{{"); indent.Increment(); // Generate query string var requestParametersBuilder = new QueryStringParameterConversionGenerator("queryParameters", _codeGenerationContext) .WithQueryStringParametersForEndpoint(apiEndpoint); if (apiEndpoint.ResponseBody != null && !isResponsePrimitiveOrArrayOfPrimitive) { var partialType = "Partial<" + apiEndpoint.ResponseBody.GetArrayElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">"; requestParametersBuilder = requestParametersBuilder .WithQueryStringParameter("$fields", $"(partial != null ? partial(new {partialType}()) : {partialType}.Default()).ToString()"); } builder.AppendLine($"{indent}var {requestParametersBuilder.TargetNameValueCollectionName} = new NameValueCollection();"); requestParametersBuilder.WriteTo(builder, indent); builder.AppendLine($"{indent}"); // Generate HTTP request builder.Append($"{indent}return await _connection.RequestResourceAsync<"); if (apiEndpoint.RequestBody != null) { builder.Append(apiEndpoint.ToCSharpRequestBodyClassName(endpointPath) !); builder.Append(", "); } builder.Append(apiEndpoint.ResponseBody !.ToCSharpType(_codeGenerationContext)); builder.Append(">"); builder.Append("(\"" + apiCallMethod + "\", "); builder.Append("$\"api/http/" + endpointPath + "{" + requestParametersBuilder.TargetNameValueCollectionName + ".ToQueryString()}"); builder.Append("\""); if (apiEndpoint.RequestBody != null) { if (FeatureFlags.DoNotExposeRequestObjects) { builder.Append(", " + ConstructNewRequestObject(indent, apiEndpoint, endpointPath)); } else { builder.Append(", data"); } } builder.Append(", cancellationToken"); builder.AppendLine(");"); indent.Decrement(); builder.AppendLine($"{indent}}}"); } else { builder.AppendLine($"{indent}#warning UNSUPPORTED CASE - " + apiEndpoint.ToCSharpMethodName() + " - " + apiEndpoint.Method.ToHttpMethod() + " " + endpointPath); } return(builder.ToString()); }