Skip to content

Commit 191132d

Browse files
committed
Update Linq2GraphQL client generator with enum strategy support
A notable change in the client generator added a strategy for enums, which includes the option of mapping unknown values to a distinct member through command line option. Data type of quantity fields in different classes is also changed from float to double. The version of runtime in EnumTemplate is updated.
1 parent 8cb4d58 commit 191132d

File tree

15 files changed

+154
-71
lines changed

15 files changed

+154
-71
lines changed

docs/Linq2GraphQL.Docs/Components/GenerateClient.razor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ private async Task GenerateClientJson()
8686
try
8787
{
8888
isLoading = true;
89-
var generator = new Generator.ClientGenerator(options.Namespace, options.ClientName, options.IncludeSubscriptions);
89+
var generator = new Generator.ClientGenerator(options.Namespace, options.ClientName, options.IncludeSubscriptions, EnumGeneratorStrategy.FailIfMissing);
9090
var entries = generator.Generate(options.Schema);
9191
await SaveEntriesAsync(entries);
9292
}
@@ -107,7 +107,7 @@ private async Task GenerateClientAsync()
107107
try
108108
{
109109
isLoading = true;
110-
var generator = new ClientGenerator(options.Namespace, options.ClientName, options.IncludeSubscriptions);
110+
var generator = new ClientGenerator(options.Namespace, options.ClientName, options.IncludeSubscriptions, EnumGeneratorStrategy.FailIfMissing);
111111
var entries = await generator.GenerateAsync(new Uri(options.Url), options.Token);
112112
await SaveEntriesAsync(entries);
113113
}

src/Linq2GraphQL.Client/Converters/EnumConverter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial
207207
}
208208
}
209209

210+
if (_transformedToRaw.TryGetValue("", out var value))
211+
{
212+
return value.EnumValue;
213+
}
214+
210215
throw new NotSupportedException();
211216
}
212217

src/Linq2GraphQL.Generator/ClientGenerator.cs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ public class ClientGenerator
1414
private readonly string namespaceName;
1515
private readonly string clientName;
1616
private readonly bool includeSubscriptions;
17+
private readonly EnumGeneratorStrategy enumGeneratorStrategy;
1718
private readonly List<FileEntry> entries = new();
1819

19-
public ClientGenerator(string namespaceName, string clientName, bool includeSubscriptions)
20+
public ClientGenerator(string namespaceName, string clientName, bool includeSubscriptions,
21+
EnumGeneratorStrategy enumGeneratorStrategy)
2022
{
2123
this.namespaceName = namespaceName;
2224
this.clientName = clientName;
2325
this.includeSubscriptions = includeSubscriptions;
26+
this.enumGeneratorStrategy = enumGeneratorStrategy;
2427
}
2528

2629
private void AddFile(string directory, string fileName, string content)
@@ -56,7 +59,7 @@ public List<FileEntry> Generate(string schemaJson)
5659
{
5760
entries.Clear();
5861
var rootSchema = JsonSerializer.Deserialize<RootSchema>(schemaJson,
59-
new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
62+
new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
6063

6164
var schema = rootSchema.Data.Schema;
6265
var queryType = schema.QueryType;
@@ -88,17 +91,21 @@ public List<FileEntry> Generate(string schemaJson)
8891

8992
Console.WriteLine("Generate Interfaces");
9093

91-
var classInterfacesList = schema.GetClassTypes().Where(e => e.HasInterfaces).SelectMany(i => i.Interfaces.ToDictionary(e => i.Name, e => e.Name)).ToList();
94+
var classInterfacesList = schema.GetClassTypes().Where(e => e.HasInterfaces)
95+
.SelectMany(i => i.Interfaces.ToDictionary(e => i.Name, e => e.Name)).ToList();
9296
foreach (var interfaceType in schema.GetInterfaces())
9397
{
94-
var implementedBy = classInterfacesList.Where(e => e.Value == interfaceType.Name).Select(e=> e.Key).ToList();
98+
var implementedBy = classInterfacesList.Where(e => e.Value == interfaceType.Name).Select(e => e.Key)
99+
.ToList();
95100

96-
var interfaceTemplte = new InterfaceTemplate(interfaceType, namespaceName, implementedBy).TransformText();
101+
var interfaceTemplte =
102+
new InterfaceTemplate(interfaceType, namespaceName, implementedBy).TransformText();
97103
AddFile("Interfaces", interfaceType.FileName, interfaceTemplte);
98104
}
99105

100106
Console.WriteLine("Generate Types...");
101-
foreach (var classType in schema.GetClassTypes().Where(e => e.Kind != TypeKind.InputObject && !e.IsPageInfo()))
107+
foreach (var classType in schema.GetClassTypes()
108+
.Where(e => e.Kind != TypeKind.InputObject && !e.IsPageInfo()))
102109
{
103110
var classText = new ClassTemplate(classType, namespaceName).TransformText();
104111
AddFile("Types", classType.FileName, classText);
@@ -119,7 +126,7 @@ public List<FileEntry> Generate(string schemaJson)
119126
Console.WriteLine("Generate Enums...");
120127
foreach (var enumType in schema.GetEnums())
121128
{
122-
var enumText = new EnumTemplate(enumType, namespaceName).TransformText();
129+
var enumText = new EnumTemplate(enumType, namespaceName, enumGeneratorStrategy).TransformText();
123130
AddFile("Enums", enumType.FileName, enumText);
124131
}
125132

@@ -134,7 +141,8 @@ public List<FileEntry> Generate(string schemaJson)
134141
var includeMutation = mutationType != null;
135142

136143
Console.WriteLine("Generate Client...");
137-
var templateText = new ClientTemplate(namespaceName, clientName, queryType, mutationType, subscriptionType).TransformText();
144+
var templateText = new ClientTemplate(namespaceName, clientName, queryType, mutationType, subscriptionType)
145+
.TransformText();
138146
var fileName = clientName + ".cs";
139147
AddFile(clientDirName, fileName, templateText);
140148

@@ -146,16 +154,25 @@ public List<FileEntry> Generate(string schemaJson)
146154

147155
return entries;
148156
}
149-
157+
150158

151159
private void GenerateContextMethods(string namespaceName, string directory, GraphqlType methodType,
152160
string schemaType)
153161
{
154-
if (methodType == null) { return; }
162+
if (methodType == null)
163+
{
164+
return;
165+
}
155166

156167
var fileName = methodType.Name.ToPascalCase() + "Methods" + ".cs";
157168
var templateText = new MethodsTemplate(methodType, namespaceName, schemaType).TransformText();
158169
AddFile(directory, fileName, templateText);
159170
}
160171
}
161172
}
173+
174+
public enum EnumGeneratorStrategy
175+
{
176+
FailIfMissing = 0,
177+
AddUnknownOption = 1
178+
}

src/Linq2GraphQL.Generator/Program.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ private static async Task Main(string[] args)
1919
"Name of the generated client");
2020
var authToken = new Option<string>(new[] { "--token", "-t" }, "Bearertoken for authentication");
2121
var includeSubscriptions = new Option<bool>(new[] { "--subscriptions", "-s" }, "Include subscriptions");
22+
var enumStrategy = new Option<string>(new[] { "--enum-strategy", "-es" }, "Enum strategy");
2223

2324
var rootCommand = new RootCommand("Generate GraphQL client")
2425
{
@@ -27,7 +28,8 @@ private static async Task Main(string[] args)
2728
namespaceName,
2829
clientName,
2930
authToken,
30-
includeSubscriptions
31+
includeSubscriptions,
32+
enumStrategy
3133
};
3234

3335
rootCommand.SetHandler(async context =>
@@ -39,9 +41,10 @@ private static async Task Main(string[] args)
3941
var clientNameValue = result.GetValueForOption(clientName);
4042
var authTokenValue = result.GetValueForOption(authToken);
4143
var includeSubscriptionsValue = result.GetValueForOption(includeSubscriptions);
44+
var enumStrategyValue = result.GetValueForOption(enumStrategy);
4245

4346
await GenerateClientAsync(uriValue, outputFolderValue, namespaceValue, clientNameValue,
44-
includeSubscriptionsValue, authTokenValue);
47+
includeSubscriptionsValue, authTokenValue, enumStrategyValue);
4548
}
4649
);
4750

@@ -51,9 +54,13 @@ await GenerateClientAsync(uriValue, outputFolderValue, namespaceValue, clientNam
5154
}
5255

5356
private static async Task GenerateClientAsync(Uri uri, string outputFolder, string namespaceName, string name,
54-
bool includeSubscriptions, string authToken)
57+
bool includeSubscriptions, string authToken, string enumStrategy)
5558
{
56-
var generator = new ClientGenerator(namespaceName, name, includeSubscriptions);
59+
var enumStrat = enumStrategy.Equals("AddUnknownOption", StringComparison.InvariantCultureIgnoreCase)
60+
? EnumGeneratorStrategy.AddUnknownOption
61+
: EnumGeneratorStrategy.FailIfMissing;
62+
63+
var generator = new ClientGenerator(namespaceName, name, includeSubscriptions, enumStrat);
5764
var entries = await generator.GenerateAsync(uri, authToken);
5865

5966
var outputPath = Path.GetFullPath(outputFolder, Environment.CurrentDirectory);

src/Linq2GraphQL.Generator/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"profiles": {
33
"Linq2GraphQL.Generator": {
44
"commandName": "Project",
5-
"commandLineArgs": "https://localhost:7184/graphql/ -c=\"SampleClient\" -n=\"Linq2GraphQL.TestClient\" -o=\"C:\\temp\\Linq2GraphQL\\Linq2GraphQL.TestClient\\Generated\" -s=true\r\n"
5+
"commandLineArgs": "https://localhost:7184/graphql/ -c=\"SampleClient\" -n=\"Linq2GraphQL.TestClient\" -o=\"C:\\Code\\Linq2GraphQL\\test\\Linq2GraphQL.TestClient\\Generated\" -s=true -es=\"AddUnknownOption\""
66
}
77
}
88
}

src/Linq2GraphQL.Generator/Templates/Enum/EnumTemplate.cs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// ------------------------------------------------------------------------------
22
// <auto-generated>
33
// This code was generated by a tool.
4-
// Runtime Version: 17.0.0.0
4+
// Runtime Version: 16.0.0.0
55
//
66
// Changes to this file may cause incorrect behavior and will be lost if
77
// the code is regenerated.
@@ -15,8 +15,8 @@ namespace Linq2GraphQL.Generator.Templates.Enum
1515
/// Class to produce the template output
1616
/// </summary>
1717

18-
#line 1 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
19-
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
18+
#line 1 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
19+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")]
2020
public partial class EnumTemplate : EnumTemplateBase
2121
{
2222
#line hidden
@@ -25,24 +25,23 @@ public partial class EnumTemplate : EnumTemplateBase
2525
/// </summary>
2626
public virtual string TransformText()
2727
{
28-
this.Write("using Linq2GraphQL.Client;\r\nusing System.Runtime.Serialization;\r\nusing System.Tex" +
29-
"t.Json.Serialization;\r\n\r\nnamespace ");
28+
this.Write("using Linq2GraphQL.Client;\r\nusing System.Runtime.Serialization;\r\nusing System.Text.Json.Serialization;\r\n\r\nnamespace ");
3029

31-
#line 7 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
30+
#line 7 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
3231
this.Write(this.ToStringHelper.ToStringWithCulture(namespaceName));
3332

3433
#line default
3534
#line hidden
3635
this.Write(";\r\n\r\n[JsonConverter(typeof(JsonStringEnumMemberConverter))]\r\npublic enum ");
3736

38-
#line 10 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
37+
#line 10 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
3938
this.Write(this.ToStringHelper.ToStringWithCulture(enumType.Name));
4039

4140
#line default
4241
#line hidden
4342
this.Write("\r\n{\r\n");
4443

45-
#line 12 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
44+
#line 12 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
4645

4746
foreach (var enumValue in enumType.EnumValues)
4847
{
@@ -52,21 +51,39 @@ public virtual string TransformText()
5251
#line hidden
5352
this.Write(" [EnumMember(Value = \"");
5453

55-
#line 16 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
54+
#line 16 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
5655
this.Write(this.ToStringHelper.ToStringWithCulture(enumValue.Name));
5756

5857
#line default
5958
#line hidden
6059
this.Write("\")]\r\n ");
6160

62-
#line 17 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
61+
#line 17 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
6362
this.Write(this.ToStringHelper.ToStringWithCulture(enumValue.GetCSharpName()));
6463

6564
#line default
6665
#line hidden
6766
this.Write(",\r\n");
6867

69-
#line 18 "C:\Code\DevOps\Linq2GraphQL\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
68+
#line 18 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
69+
70+
}
71+
72+
73+
#line default
74+
#line hidden
75+
76+
#line 21 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
77+
78+
if (enumGeneratorStrategy == EnumGeneratorStrategy.AddUnknownOption)
79+
{
80+
81+
82+
#line default
83+
#line hidden
84+
this.Write(" /// <summary>\r\n /// Unknown values are mapped to this member. \r\n /// Generated via --es/-enum-strategy command line option upon generation. \r\n /// Don't set explicitly. \r\n /// </summary>\r\n [EnumMember(Value = \"\")]\r\n __Unknown\r\n");
85+
86+
#line 32 "C:\Code\Linq2GraphQL\src\Linq2GraphQL.Generator\Templates\Enum\EnumTemplate.tt"
7087

7188
}
7289

@@ -84,7 +101,7 @@ public virtual string TransformText()
84101
/// <summary>
85102
/// Base class for this transformation
86103
/// </summary>
87-
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
104+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "16.0.0.0")]
88105
public class EnumTemplateBase
89106
{
90107
#region Fields
@@ -99,7 +116,7 @@ public class EnumTemplateBase
99116
/// <summary>
100117
/// The string builder that generation-time code is using to assemble generated output
101118
/// </summary>
102-
public System.Text.StringBuilder GenerationEnvironment
119+
protected System.Text.StringBuilder GenerationEnvironment
103120
{
104121
get
105122
{

src/Linq2GraphQL.Generator/Templates/Enum/EnumTemplate.tt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,18 @@ public enum <#= enumType.Name #>
1818
<#
1919
}
2020
#>
21+
<#
22+
if (enumGeneratorStrategy == EnumGeneratorStrategy.AddUnknownOption)
23+
{
24+
#>
25+
/// <summary>
26+
/// Unknown values are mapped to this member.
27+
/// Generated via --es/-enum-strategy command line option upon generation.
28+
/// Don't set explicitly.
29+
/// </summary>
30+
[EnumMember(Value = "")]
31+
__Unknown
32+
<#
33+
}
34+
#>
2135
}

src/Linq2GraphQL.Generator/Templates/Enum/EnumTemplate.tt.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ public partial class EnumTemplate
44
{
55
private readonly GraphqlType enumType;
66
private readonly string namespaceName;
7+
private readonly EnumGeneratorStrategy enumGeneratorStrategy;
78

8-
public EnumTemplate(GraphqlType enumType, string namespaceName)
9+
public EnumTemplate(GraphqlType enumType, string namespaceName, EnumGeneratorStrategy enumGeneratorStrategy)
910
{
1011
this.enumType = enumType;
1112
this.namespaceName = namespaceName;
13+
this.enumGeneratorStrategy = enumGeneratorStrategy;
1214
}
1315
}

test/Linq2GraphQL.TestClient/Generated/Enums/AddressType.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,11 @@ public enum AddressType
1111
Delivery,
1212
[EnumMember(Value = "INVOICE")]
1313
Invoice,
14+
/// <summary>
15+
/// Unknown values are mapped to this member.
16+
/// Generated via --es/-enum-strategy command line option upon generation.
17+
/// Don't set explicitly.
18+
/// </summary>
19+
[EnumMember(Value = "")]
20+
__Unknown
1421
}

test/Linq2GraphQL.TestClient/Generated/Enums/CustomerStatus.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,11 @@ public enum CustomerStatus
1111
Active,
1212
[EnumMember(Value = "DISABLED")]
1313
Disabled,
14+
/// <summary>
15+
/// Unknown values are mapped to this member.
16+
/// Generated via --es/-enum-strategy command line option upon generation.
17+
/// Don't set explicitly.
18+
/// </summary>
19+
[EnumMember(Value = "")]
20+
__Unknown
1421
}

0 commit comments

Comments
 (0)