Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for enums or collection of enums as root payload #4360

Merged
merged 9 commits into from
Mar 21, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added the init command as part of the experience revamp of [#3356](https://github.com/microsoft/kiota/issues/3356)
- Added uri-form encoded serialization for Python. [#2075](https://github.com/microsoft/kiota/issues/2075)
- Added support for multipart form data request body in Python. [#3030](https://github.com/microsoft/kiota/issues/3030)
- Added support for Enums or collection of enum values as root of the payload. [#1042](https://github.com/microsoft/kiota-typescript/issues/1042)

### Changed

Expand Down
33 changes: 23 additions & 10 deletions src/Kiota.Builder/Writers/TypeScript/CodeConstantWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ private void WriteRequestsMetadataConstant(CodeConstant codeElement, LanguageWri
var returnType = conventions.GetTypeString(executorMethod.ReturnType, codeElement);
var isVoid = "void".EqualsIgnoreCase(returnType);
var isStream = conventions.StreamTypeName.Equals(returnType, StringComparison.OrdinalIgnoreCase);
var isEnum = executorMethod.ReturnType is CodeType codeType && codeType.TypeDefinition is CodeEnum;
var returnTypeWithoutCollectionSymbol = GetReturnTypeWithoutCollectionSymbol(executorMethod, returnType);
var isPrimitive = conventions.IsPrimitiveType(returnTypeWithoutCollectionSymbol);
writer.StartBlock($"{executorMethod.Name.ToFirstCharacterLowerCase()}: {{");
var urlTemplateValue = executorMethod.HasUrlTemplateOverride ? $"\"{executorMethod.UrlTemplateOverride}\"" : uriTemplateConstant.Name.ToFirstCharacterUpperCase();
writer.WriteLine($"uriTemplate: {urlTemplateValue},");
Expand All @@ -115,10 +117,13 @@ private void WriteRequestsMetadataConstant(CodeConstant codeElement, LanguageWri
}
writer.CloseBlock("},");
}
writer.WriteLine($"adapterMethodName: \"{GetSendRequestMethodName(isVoid, isStream, executorMethod.ReturnType.IsCollection, returnTypeWithoutCollectionSymbol)}\",");
if (!isVoid)
writer.WriteLine($"adapterMethodName: \"{GetSendRequestMethodName(isVoid, isStream, executorMethod.ReturnType.IsCollection, isPrimitive, isEnum)}\",");
if (isEnum)
writer.WriteLine($"enumObject: \"{executorMethod.ReturnType.Name.ToFirstCharacterUpperCase()}\",");
else if (!isVoid)
writer.WriteLine($"responseBodyFactory: {GetTypeFactory(isVoid, isStream, executorMethod, writer)},");
var sanitizedRequestBodyContentType = executorMethod.RequestBodyContentType.SanitizeDoubleQuote();

if (!string.IsNullOrEmpty(sanitizedRequestBodyContentType))
writer.WriteLine($"requestBodyContentType: \"{sanitizedRequestBodyContentType}\",");
if (executorMethod.Parameters.FirstOrDefault(static x => x.Kind is CodeParameterKind.RequestBody) is CodeParameter requestBody)
Expand Down Expand Up @@ -186,17 +191,25 @@ currentType.TypeDefinition is CodeClass definitionClass &&
}
throw new InvalidOperationException($"Unable to find factory method for {targetClassName}");
}
private string GetSendRequestMethodName(bool isVoid, bool isStream, bool isCollection, string returnType)

private string GetSendRequestMethodName(bool isVoid, bool isStream, bool isCollection, bool isPrimitive, bool isEnum)
{
if (isVoid) return "sendNoResponseContent";
if (isCollection)
if (isVoid)
{
if (conventions.IsPrimitiveType(returnType)) return $"sendCollectionOfPrimitive";
return $"sendCollection";
return "sendNoResponseContent";
}
else if (isEnum)
{
return isCollection ? "sendCollectionOfEnum" : "sendEnum";
koros marked this conversation as resolved.
Show resolved Hide resolved
}
else if (isPrimitive)
{
return isCollection ? "sendCollectionOfPrimitive" : "sendPrimitive";
}
else
{
return isCollection ? "sendCollection" : isStream ? "sendPrimitive" : "send";
}

if (isStream || conventions.IsPrimitiveType(returnType)) return $"sendPrimitive";
return $"send";
}

private void WriteUriTemplateConstant(CodeConstant codeElement, LanguageWriter writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,108 @@ public void WritesRequestExecutorBodyForCollections()
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
public void WritesRequestExecutorForEnum()
{
AddCodeEnum();
method.Kind = CodeMethodKind.RequestExecutor;
method.HttpMethod = HttpMethod.Get;
method.ReturnType = new CodeType
{
Name = "SomeComplexTypeForRequestBody",
TypeDefinition = currentEnum,
};
AddRequestBodyParameters();
var constant = CodeConstant.FromRequestBuilderToRequestsMetadata(parentClass);
var codeFile = parentClass.GetImmediateParentOfType<CodeNamespace>().TryAddCodeFile("foo", constant);
codeFile.AddElements(new CodeConstant
{
Name = "UriTemplate",
Kind = CodeConstantKind.UriTemplate,
UriTemplate = "{baseurl+}/foo/bar"
});
writer.Write(constant);
var result = tw.ToString();
Assert.Contains("sendEnum", result);
Assert.Contains("enumObject:", result);
Assert.Contains(EnumName.ToFirstCharacterUpperCase(), result);
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
public void WritesRequestExecutorForEnumCollection()
{
AddCodeEnum();
method.Kind = CodeMethodKind.RequestExecutor;
method.HttpMethod = HttpMethod.Get;
method.ReturnType = new CodeType
{
Name = "SomeComplexTypeForRequestBody",
TypeDefinition = currentEnum,
CollectionKind = CodeTypeBase.CodeTypeCollectionKind.Array,
};
AddRequestBodyParameters();
var constant = CodeConstant.FromRequestBuilderToRequestsMetadata(parentClass);
var codeFile = parentClass.GetImmediateParentOfType<CodeNamespace>().TryAddCodeFile("foo", constant);
codeFile.AddElements(new CodeConstant
{
Name = "UriTemplate",
Kind = CodeConstantKind.UriTemplate,
UriTemplate = "{baseurl+}/foo/bar"
});
writer.Write(constant);
var result = tw.ToString();
Assert.Contains("sendCollectionOfEnum", result);
Assert.Contains("enumObject:", result);
Assert.Contains(EnumName.ToFirstCharacterUpperCase(), result);
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
public void WritesRequestExecutorForPrimitive()
{
method.Kind = CodeMethodKind.RequestExecutor;
method.HttpMethod = HttpMethod.Get;
method.ReturnType = new CodeType
{
Name = "string",
};
AddRequestBodyParameters();
var constant = CodeConstant.FromRequestBuilderToRequestsMetadata(parentClass);
var codeFile = parentClass.GetImmediateParentOfType<CodeNamespace>().TryAddCodeFile("foo", constant);
codeFile.AddElements(new CodeConstant
{
Name = "UriTemplate",
Kind = CodeConstantKind.UriTemplate,
UriTemplate = "{baseurl+}/foo/bar"
});
writer.Write(constant);
var result = tw.ToString();
Assert.Contains("sendPrimitive", result);
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
public void WritesRequestExecutorForPrimitiveCollection()
{
method.Kind = CodeMethodKind.RequestExecutor;
method.HttpMethod = HttpMethod.Get;
method.ReturnType = new CodeType
{
Name = "string",
CollectionKind = CodeTypeBase.CodeTypeCollectionKind.Array,
};
AddRequestBodyParameters();
var constant = CodeConstant.FromRequestBuilderToRequestsMetadata(parentClass);
var codeFile = parentClass.GetImmediateParentOfType<CodeNamespace>().TryAddCodeFile("foo", constant);
codeFile.AddElements(new CodeConstant
{
Name = "UriTemplate",
Kind = CodeConstantKind.UriTemplate,
UriTemplate = "{baseurl+}/foo/bar"
});
writer.Write(constant);
var result = tw.ToString();
Assert.Contains("sendCollectionOfPrimitive", result);
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
public void WritesRequestGeneratorBodyForScalar()
{
parentClass.Kind = CodeClassKind.RequestBuilder;
Expand Down
Loading