Skip to content

Commit

Permalink
fix(lib): Handle enums as query parameters #133
Browse files Browse the repository at this point in the history
  • Loading branch information
PerfectlyNormal committed Feb 16, 2025
1 parent f418b21 commit e959395
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Better support for generic types (#123)

### Fixed

- Allow enums to be used as query parameters in API clients (#133)

## [0.16.0] - 2024-12-17

### Added
Expand Down
59 changes: 59 additions & 0 deletions TypeContractor.Tests/TypeScript/ApiClientWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,59 @@ public void Writes_Get_With_Route()
.And.NotContain("url.searchParams.append(");
}

[Fact]
public void Handles_Get_With_Route_And_Query_Parameters()
{
// Arrange
var apiClient = new ApiClient("TestClient", "TestController", "test", null);
apiClient.AddEndpoint(new ApiClientEndpoint("getLatestId", "latest/{year}", EndpointMethod.GET, null, typeof(Guid), false,
[new EndpointParameter("year", typeof(int), null, false, false, true, false, false, false, false, false),
new EndpointParameter("reverse", typeof(bool?), null, false, false, false, true, false, false, false, true)], null));

// Act
var result = Sut.Write(apiClient, [], _converter, true, _templateFn, Casing.Pascal);

// Assert
var file = File.ReadAllText(result).Trim();
file.Should()
.NotBeEmpty()
.And.Contain("import { z } from 'zod';")
.And.Contain("export class TestClient {")
.And.Contain("public async getLatestId(year: number, reverse: boolean | undefined, cancellationToken: AbortSignal = null): Promise<string> {")
.And.Contain("const url = new URL(`test/latest/${year}`, window.location.origin);")
.And.Contain("if (!!reverse)")
.And.Contain("url.searchParams.append('reverse', reverse.toString());");
}

[Fact]
public void Handles_Enum_As_Query_Parameter()
{
// Arrange
var outputTypes = new List<OutputType>
{
_converter.Convert(typeof(ReportType))
};

var apiClient = new ApiClient("TestClient", "TestController", "test", null);
apiClient.AddEndpoint(new ApiClientEndpoint("getLatestId", "latest/{year}", EndpointMethod.GET, null, typeof(Guid), false,
[new EndpointParameter("year", typeof(int), null, false, false, true, false, false, false, false, false),
new EndpointParameter("reportType", typeof(ReportType), null, false, false, false, true, false, false, false, false)], null));

// Act
var result = Sut.Write(apiClient, outputTypes, _converter, true, _templateFn, Casing.Pascal);

// Assert
var file = File.ReadAllText(result).Trim();
file.Should()
.NotBeEmpty()
.And.Contain("import { z } from 'zod';")
.And.Contain("export class TestClient {")
.And.Contain("public async getLatestId(year: number, reportType: ReportType, cancellationToken: AbortSignal = null): Promise<string> {")
.And.Contain("const url = new URL(`test/latest/${year}`, window.location.origin);")
.And.NotContain("if (!!reportType)")
.And.Contain("url.searchParams.append('reportType', reportType.toString());");
}

[Fact]
public void Unpacks_Complex_Object_To_Query()
{
Expand Down Expand Up @@ -290,6 +343,12 @@ private class PaginatedRequest
public int PageSize { get; set; }
}

private enum ReportType
{
Summary = 0,
Detailed = 1,
}

private MetadataLoadContext BuildMetadataLoadContext()
{
// Get the array of runtime assemblies.
Expand Down
2 changes: 1 addition & 1 deletion TypeContractor/Helpers/CasingHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Globalization;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

Expand Down
6 changes: 6 additions & 0 deletions TypeContractor/TypeScript/ApiClientWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ public string Write(ApiClient apiClient, IEnumerable<OutputType> allTypes, TypeS
continue;
}

if (outputType.IsEnum)
{
queryParamsDto.Add(new QueryParameterTemplateDto(queryParam.Name, true, false, false, queryParam.IsOptional, null));
continue;
}

foreach (var property in outputType.Properties ?? [])
{
queryParamsDto.Add(new QueryParameterTemplateDto(queryParam.Name, false, property.IsNullable, false, queryParam.IsOptional, property.DestinationName));
Expand Down

0 comments on commit e959395

Please sign in to comment.