Skip to content

Commit 0e549ad

Browse files
committed
Add schema usage commands
1 parent 61160ef commit 0e549ad

65 files changed

Lines changed: 40903 additions & 23444 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFramework>net10.0</TargetFramework>
4+
<TargetFrameworks></TargetFrameworks>
45
<AssemblyName>HotChocolate.Demo.Catalog.Tests</AssemblyName>
56
<RootNamespace>HotChocolate.Demo.Catalog.Tests</RootNamespace>
67
</PropertyGroup>
78

89
<ItemGroup>
9-
<ProjectReference Include="..\..\src\Demo\Demo.Catalog\Demo.Catalog.csproj" />
10+
<ProjectReference Include="..\..\examples\Demo\Demo.Catalog\Demo.Catalog.csproj" />
1011
<ProjectReference Include="..\Mocha.Sagas.TestHelpers\Mocha.Sagas.TestHelpers.csproj" />
1112
</ItemGroup>
1213
</Project>
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
namespace ChilliCream.Nitro.Client.Coordinates;
2+
3+
internal sealed class CoordinatesClient(IApiClient apiClient) : ICoordinatesClient
4+
{
5+
public async Task<ICoordinateUsageQuery_ApiById_Stages?> GetCoordinateUsageAsync(
6+
string apiId,
7+
string stageName,
8+
string coordinate,
9+
DateTimeOffset from,
10+
DateTimeOffset to,
11+
CancellationToken cancellationToken)
12+
{
13+
var result = await apiClient.CoordinateUsageQuery.ExecuteAsync(
14+
apiId,
15+
coordinate,
16+
from,
17+
to,
18+
cancellationToken);
19+
20+
var data = OperationResultHelper.EnsureData(result);
21+
if (data.ApiById?.Stages is not { } stages)
22+
{
23+
return null;
24+
}
25+
26+
foreach (var stage in stages)
27+
{
28+
if (string.Equals(stage.Name, stageName, StringComparison.Ordinal))
29+
{
30+
return stage;
31+
}
32+
}
33+
34+
return null;
35+
}
36+
37+
public async Task<ICoordinateClientsQuery_ApiById_Stages?> GetCoordinateClientsAsync(
38+
string apiId,
39+
string stageName,
40+
string coordinate,
41+
DateTimeOffset from,
42+
DateTimeOffset to,
43+
CancellationToken cancellationToken)
44+
{
45+
var result = await apiClient.CoordinateClientsQuery.ExecuteAsync(
46+
apiId,
47+
coordinate,
48+
from,
49+
to,
50+
cancellationToken);
51+
52+
var data = OperationResultHelper.EnsureData(result);
53+
if (data.ApiById?.Stages is not { } stages)
54+
{
55+
return null;
56+
}
57+
58+
foreach (var stage in stages)
59+
{
60+
if (string.Equals(stage.Name, stageName, StringComparison.Ordinal))
61+
{
62+
return stage;
63+
}
64+
}
65+
66+
return null;
67+
}
68+
69+
public async Task<ICoordinateOperationsQuery_ApiById_Stages?> GetCoordinateOperationsAsync(
70+
string apiId,
71+
string stageName,
72+
string coordinate,
73+
DateTimeOffset from,
74+
DateTimeOffset to,
75+
CancellationToken cancellationToken)
76+
{
77+
var result = await apiClient.CoordinateOperationsQuery.ExecuteAsync(
78+
apiId,
79+
coordinate,
80+
from,
81+
to,
82+
100,
83+
cancellationToken);
84+
85+
var data = OperationResultHelper.EnsureData(result);
86+
if (data.ApiById?.Stages is not { } stages)
87+
{
88+
return null;
89+
}
90+
91+
foreach (var stage in stages)
92+
{
93+
if (string.Equals(stage.Name, stageName, StringComparison.Ordinal))
94+
{
95+
return stage;
96+
}
97+
}
98+
99+
return null;
100+
}
101+
102+
public async Task<ICoordinateImpactQuery_ApiById_Stages?> GetCoordinateImpactAsync(
103+
string apiId,
104+
string stageName,
105+
string coordinate,
106+
DateTimeOffset from,
107+
DateTimeOffset to,
108+
CancellationToken cancellationToken)
109+
{
110+
var result = await apiClient.CoordinateImpactQuery.ExecuteAsync(
111+
apiId,
112+
coordinate,
113+
from,
114+
to,
115+
100,
116+
cancellationToken);
117+
118+
var data = OperationResultHelper.EnsureData(result);
119+
if (data.ApiById?.Stages is not { } stages)
120+
{
121+
return null;
122+
}
123+
124+
foreach (var stage in stages)
125+
{
126+
if (string.Equals(stage.Name, stageName, StringComparison.Ordinal))
127+
{
128+
return stage;
129+
}
130+
}
131+
132+
return null;
133+
}
134+
135+
public async Task<IUnusedCoordinatesQuery_ApiById_Stages?> GetUnusedCoordinatesAsync(
136+
string apiId,
137+
string stageName,
138+
DateTimeOffset from,
139+
DateTimeOffset to,
140+
IReadOnlyList<CoordinateKind>? kinds,
141+
bool? isDeprecated,
142+
int first,
143+
CancellationToken cancellationToken)
144+
{
145+
var result = await apiClient.UnusedCoordinatesQuery.ExecuteAsync(
146+
apiId,
147+
from,
148+
to,
149+
kinds,
150+
isDeprecated,
151+
first,
152+
cancellationToken);
153+
154+
var data = OperationResultHelper.EnsureData(result);
155+
if (data.ApiById?.Stages is not { } stages)
156+
{
157+
return null;
158+
}
159+
160+
foreach (var stage in stages)
161+
{
162+
if (string.Equals(stage.Name, stageName, StringComparison.Ordinal))
163+
{
164+
return stage;
165+
}
166+
}
167+
168+
return null;
169+
}
170+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
namespace ChilliCream.Nitro.Client.Coordinates;
2+
3+
/// <summary>
4+
/// Provides the remote coordinate analytics queries used by the
5+
/// <c>nitro schema usage</c>, <c>clients</c>, <c>operations</c>, <c>unused</c>, and
6+
/// <c>impact</c> commands.
7+
/// </summary>
8+
public interface ICoordinatesClient
9+
{
10+
/// <summary>
11+
/// Loads the aggregate usage metrics for a single coordinate on the given stage.
12+
/// </summary>
13+
/// <returns>
14+
/// The matching stage node, or <see langword="null"/> if the API or stage could not
15+
/// be resolved.
16+
/// </returns>
17+
/// <exception cref="NitroClientGraphQLException">
18+
/// The server returned a GraphQL error.
19+
/// </exception>
20+
/// <exception cref="NitroClientHttpRequestException">
21+
/// The server returned an HTTP error without a GraphQL response body.
22+
/// </exception>
23+
/// <exception cref="NitroClientAuthorizationException">
24+
/// The request was rejected because the current credentials do not grant access.
25+
/// </exception>
26+
/// <exception cref="OperationCanceledException">The operation was canceled.</exception>
27+
Task<ICoordinateUsageQuery_ApiById_Stages?> GetCoordinateUsageAsync(
28+
string apiId,
29+
string stageName,
30+
string coordinate,
31+
DateTimeOffset from,
32+
DateTimeOffset to,
33+
CancellationToken cancellationToken);
34+
35+
/// <summary>
36+
/// Loads the per-client usage breakdown for a single coordinate on the given stage.
37+
/// </summary>
38+
/// <returns>
39+
/// The matching stage node, or <see langword="null"/> if the API or stage could not
40+
/// be resolved.
41+
/// </returns>
42+
/// <exception cref="NitroClientGraphQLException">
43+
/// The server returned a GraphQL error.
44+
/// </exception>
45+
/// <exception cref="NitroClientHttpRequestException">
46+
/// The server returned an HTTP error without a GraphQL response body.
47+
/// </exception>
48+
/// <exception cref="NitroClientAuthorizationException">
49+
/// The request was rejected because the current credentials do not grant access.
50+
/// </exception>
51+
/// <exception cref="OperationCanceledException">The operation was canceled.</exception>
52+
Task<ICoordinateClientsQuery_ApiById_Stages?> GetCoordinateClientsAsync(
53+
string apiId,
54+
string stageName,
55+
string coordinate,
56+
DateTimeOffset from,
57+
DateTimeOffset to,
58+
CancellationToken cancellationToken);
59+
60+
/// <summary>
61+
/// Loads the per-operation usage breakdown for a single coordinate on the given stage,
62+
/// flattened across clients.
63+
/// </summary>
64+
/// <returns>
65+
/// The matching stage node, or <see langword="null"/> if the API or stage could not
66+
/// be resolved.
67+
/// </returns>
68+
/// <exception cref="NitroClientGraphQLException">
69+
/// The server returned a GraphQL error.
70+
/// </exception>
71+
/// <exception cref="NitroClientHttpRequestException">
72+
/// The server returned an HTTP error without a GraphQL response body.
73+
/// </exception>
74+
/// <exception cref="NitroClientAuthorizationException">
75+
/// The request was rejected because the current credentials do not grant access.
76+
/// </exception>
77+
/// <exception cref="OperationCanceledException">The operation was canceled.</exception>
78+
Task<ICoordinateOperationsQuery_ApiById_Stages?> GetCoordinateOperationsAsync(
79+
string apiId,
80+
string stageName,
81+
string coordinate,
82+
DateTimeOffset from,
83+
DateTimeOffset to,
84+
CancellationToken cancellationToken);
85+
86+
/// <summary>
87+
/// Loads the combined impact payload (clients + operations + usage + deprecation) for a
88+
/// single coordinate on the given stage.
89+
/// </summary>
90+
/// <returns>
91+
/// The matching stage node, or <see langword="null"/> if the API or stage could not
92+
/// be resolved.
93+
/// </returns>
94+
/// <exception cref="NitroClientGraphQLException">
95+
/// The server returned a GraphQL error.
96+
/// </exception>
97+
/// <exception cref="NitroClientHttpRequestException">
98+
/// The server returned an HTTP error without a GraphQL response body.
99+
/// </exception>
100+
/// <exception cref="NitroClientAuthorizationException">
101+
/// The request was rejected because the current credentials do not grant access.
102+
/// </exception>
103+
/// <exception cref="OperationCanceledException">The operation was canceled.</exception>
104+
Task<ICoordinateImpactQuery_ApiById_Stages?> GetCoordinateImpactAsync(
105+
string apiId,
106+
string stageName,
107+
string coordinate,
108+
DateTimeOffset from,
109+
DateTimeOffset to,
110+
CancellationToken cancellationToken);
111+
112+
/// <summary>
113+
/// Loads the sorted unused coordinates for the given stage and kind filter.
114+
/// </summary>
115+
/// <returns>
116+
/// The matching stage node, or <see langword="null"/> if the API or stage could not
117+
/// be resolved.
118+
/// </returns>
119+
/// <exception cref="NitroClientGraphQLException">
120+
/// The server returned a GraphQL error.
121+
/// </exception>
122+
/// <exception cref="NitroClientHttpRequestException">
123+
/// The server returned an HTTP error without a GraphQL response body.
124+
/// </exception>
125+
/// <exception cref="NitroClientAuthorizationException">
126+
/// The request was rejected because the current credentials do not grant access.
127+
/// </exception>
128+
/// <exception cref="OperationCanceledException">The operation was canceled.</exception>
129+
Task<IUnusedCoordinatesQuery_ApiById_Stages?> GetUnusedCoordinatesAsync(
130+
string apiId,
131+
string stageName,
132+
DateTimeOffset from,
133+
DateTimeOffset to,
134+
IReadOnlyList<CoordinateKind>? kinds,
135+
bool? isDeprecated,
136+
int first,
137+
CancellationToken cancellationToken);
138+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
query coordinateClientsQuery(
2+
$apiId: ID!
3+
$coordinate: String!
4+
$from: DateTime!
5+
$to: DateTime!
6+
) {
7+
apiById(id: $apiId) {
8+
id
9+
name
10+
stages {
11+
name
12+
coordinate(coordinate: $coordinate) {
13+
coordinate
14+
isDeprecated
15+
metrics {
16+
clientUsages(from: $from, to: $to) {
17+
...CoordinateClientUsageFields
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}
24+
25+
fragment CoordinateClientUsageFields on CoordinateClientUsage {
26+
name
27+
totalVersions
28+
totalOperations
29+
totalRequests
30+
client {
31+
id
32+
name
33+
}
34+
}

0 commit comments

Comments
 (0)