public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName) { valueType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType; // DateTime and Byte switch (valueType.Name) { case "Uuid": return(new ScalarFieldTypeDescription { NetTypeName = "Guid?", FormatMask = "N" }); case "Uuid!": return(new ScalarFieldTypeDescription { NetTypeName = "Guid", FormatMask = "N" }); case "Long": return(new ScalarFieldTypeDescription { NetTypeName = "long?", FormatMask = null }); case "DateTime": return(new ScalarFieldTypeDescription { NetTypeName = "DateTime?", FormatMask = null }); case "DateTime!": return(new ScalarFieldTypeDescription { NetTypeName = "DateTime", FormatMask = null }); } // fallback - not needed if all fields and arguments are resolved or the expected type is of "object" type return(DefaultScalarFieldTypeMappingProvider.Instance.GetCustomScalarFieldType(configuration, baseType, valueType, valueName)); }
public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName) { var isNotNull = valueType.Kind == GraphQlTypeKind.NonNull; var unwrappedType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType; var nullablePostfix = isNotNull ? null : "?"; if (unwrappedType.Name == "ID") { return new ScalarFieldTypeDescription { NetTypeName = "Guid" + nullablePostfix, FormatMask = "N" } } ; if (valueName == "before" || valueName == "after" || unwrappedType.Name == "DateTimeOffset") { return new ScalarFieldTypeDescription { NetTypeName = "DateTimeOffset" + nullablePostfix, FormatMask = "yyyy-MM-dd\"T\"HH:mm" } } ; return(DefaultScalarFieldTypeMappingProvider.Instance.GetCustomScalarFieldType(configuration, baseType, valueType, valueName)); } }
public void NewCSharpSyntaxWithClassPrefixAndSuffix() { var configuration = new GraphQlGeneratorConfiguration { CSharpVersion = CSharpVersion.Newest, ClassPrefix = "Test", ClassSuffix = "V1", MemberAccessibility = MemberAccessibility.Internal }; var schema = DeserializeTestSchema("TestSchema2"); var stringBuilder = new StringBuilder(); var generator = new GraphQlGenerator(configuration); generator.Generate(CreateGenerationContext(stringBuilder, schema)); var generatedSourceCode = StripBaseClasses(stringBuilder.ToString()); var expectedOutput = GetTestResource("ExpectedNewCSharpSyntaxWithClassPrefixAndSuffix"); generatedSourceCode.ShouldBe(expectedOutput); CompileIntoAssembly(stringBuilder.ToString(), "GraphQLTestAssembly"); Type.GetType("GraphQLTestAssembly.GraphQlQueryBuilder, GraphQLTestAssembly").ShouldNotBeNull(); }
public static async Task <IReadOnlyCollection <FileInfo> > GenerateClientSourceCode(ProgramOptions options) { var schema = await GraphQlGenerator.RetrieveSchema(options.ServiceUrl, options.Authorization); var generatorConfiguration = new GraphQlGeneratorConfiguration { CSharpVersion = options.CSharpVersion, ClassPostfix = options.ClassPostfix, GeneratePartialClasses = options.PartialClasses, MemberAccessibility = options.MemberAccessibility, IdTypeMapping = options.IdTypeMapping }; var generator = new GraphQlGenerator(generatorConfiguration); if (options.OutputType == OutputType.SingleFile) { await File.WriteAllTextAsync(options.OutputPath, generator.GenerateFullClientCSharpFile(schema, options.Namespace)); return(new[] { new FileInfo(options.OutputPath) }); } var multipleFileGenerationContext = new MultipleFileGenerationContext(schema, options.OutputPath, options.Namespace); generator.Generate(multipleFileGenerationContext); return(multipleFileGenerationContext.Files); }
public void GenerateDataClassesWithTypeConfiguration() { var configuration = new GraphQlGeneratorConfiguration { IntegerTypeMapping = IntegerTypeMapping.Int64, FloatTypeMapping = FloatTypeMapping.Double, BooleanTypeMapping = BooleanTypeMapping.Custom, IdTypeMapping = IdTypeMapping.String, GeneratePartialClasses = false, PropertyGeneration = PropertyGenerationOption.BackingField }; configuration.CustomScalarFieldTypeMapping = (baseType, valueType, valueName) => valueType.Name == "Boolean" ? new ScalarFieldTypeDescription { NetTypeName = "bool" } : configuration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName); var stringBuilder = new StringBuilder(); new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.DataClasses)); var expectedDataClasses = GetTestResource("ExpectedDataClassesWithTypeConfiguration"); stringBuilder.ToString().ShouldBe(expectedDataClasses); }
public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName) => valueType.Name == "Boolean" ? new ScalarFieldTypeDescription { NetTypeName = "bool" } : DefaultScalarFieldTypeMappingProvider.Instance.GetCustomScalarFieldType(configuration, baseType, valueType, valueName);
private static async Task GenerateClientSourceCode(ProgramOptions options, List <FileInfo> generatedFiles) { GraphQlSchema schema; if (String.IsNullOrWhiteSpace(options.ServiceUrl)) { schema = GraphQlGenerator.DeserializeGraphQlSchema(await File.ReadAllTextAsync(options.SchemaFileName)); } else { if (!KeyValueParameterParser.TryGetCustomHeaders(options.Header, out var headers, out var headerParsingErrorMessage)) { throw new InvalidOperationException(headerParsingErrorMessage); } schema = await GraphQlGenerator.RetrieveSchema(new HttpMethod(options.HttpMethod), options.ServiceUrl, headers); } var generatorConfiguration = new GraphQlGeneratorConfiguration { CSharpVersion = options.CSharpVersion, ClassPrefix = options.ClassPrefix, ClassSuffix = options.ClassSuffix, GeneratePartialClasses = options.PartialClasses, MemberAccessibility = options.MemberAccessibility, IdTypeMapping = options.IdTypeMapping, FloatTypeMapping = options.FloatTypeMapping, JsonPropertyGeneration = options.JsonPropertyAttribute }; if (!KeyValueParameterParser.TryGetCustomClassMapping(options.ClassMapping, out var customMapping, out var customMappingParsingErrorMessage)) { throw new InvalidOperationException(customMappingParsingErrorMessage); } foreach (var kvp in customMapping) { generatorConfiguration.CustomClassNameMapping.Add(kvp); } var generator = new GraphQlGenerator(generatorConfiguration); if (options.OutputType == OutputType.SingleFile) { await File.WriteAllTextAsync(options.OutputPath, generator.GenerateFullClientCSharpFile(schema, options.Namespace)); generatedFiles.Add(new FileInfo(options.OutputPath)); } else { var multipleFileGenerationContext = new MultipleFileGenerationContext(schema, options.OutputPath, options.Namespace); generator.Generate(multipleFileGenerationContext); generatedFiles.AddRange(multipleFileGenerationContext.Files); } }
public void GenerateDataClasses() { var configuration = new GraphQlGeneratorConfiguration(); configuration.CustomClassNameMapping.Add("AwayMode", "VacationMode"); var stringBuilder = new StringBuilder(); new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.DataClasses)); var expectedDataClasses = GetTestResource("ExpectedDataClasses"); stringBuilder.ToString().ShouldBe(expectedDataClasses); }
public void GenerateFullClientCSharpFile() { var configuration = new GraphQlGeneratorConfiguration { CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute }; var generator = new GraphQlGenerator(configuration); var generatedSourceCode = generator.GenerateFullClientCSharpFile(TestSchema, "GraphQlGenerator.Test"); var expectedOutput = GetTestResource("ExpectedFullClientCSharpFile"); generatedSourceCode.ShouldBe(expectedOutput); }
public void GenerateQueryBuilder() { var configuration = new GraphQlGeneratorConfiguration(); configuration.CustomClassNameMapping.Add("AwayMode", "VacationMode"); var stringBuilder = new StringBuilder(); new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.QueryBuilders)); var expectedQueryBuilders = GetTestResource("ExpectedQueryBuilders"); var generatedSourceCode = StripBaseClasses(stringBuilder.ToString()); generatedSourceCode.ShouldBe(expectedQueryBuilders); }
public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName) { valueName = NamingHelper.ToPascalCase(valueName); if (valueName == "From" || valueName == "ValidFrom" || valueName == "To" || valueName == "ValidTo" || valueName == "CreatedAt" || valueName == "UpdatedAt" || valueName == "ModifiedAt" || valueName == "DeletedAt" || valueName.EndsWith("Timestamp")) { return new ScalarFieldTypeDescription { NetTypeName = "DateTimeOffset?" } } ; return(GetFallbackFieldType(configuration, valueType)); }
public void GenerateFormatMasks() { var configuration = new GraphQlGeneratorConfiguration { IdTypeMapping = IdTypeMapping.Custom }; configuration.CustomScalarFieldTypeMapping = (baseType, valueType, valueName) => { var isNotNull = valueType.Kind == GraphQlTypeKind.NonNull; var unwrappedType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType; var nullablePostfix = isNotNull ? "?" : null; if (unwrappedType.Name == "ID") { return new ScalarFieldTypeDescription { NetTypeName = "Guid" + nullablePostfix, FormatMask = "N" } } ; if (valueName == "before" || valueName == "after") { return new ScalarFieldTypeDescription { NetTypeName = "DateTimeOffset" + nullablePostfix, FormatMask = "yyyy-MM-dd\"T\"HH:mm" } } ; return(configuration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName)); }; var stringBuilder = new StringBuilder(); var generator = new GraphQlGenerator(configuration); var schema = DeserializeTestSchema("TestSchema3"); generator.Generate(CreateGenerationContext(stringBuilder, schema)); var expectedDataClasses = GetTestResource("ExpectedFormatMasks"); var generatedSourceCode = StripBaseClasses(stringBuilder.ToString()); generatedSourceCode.ShouldBe(expectedDataClasses); }
public async Task RunAsync() { var config = new GraphQlGeneratorConfiguration() { IncludeDeprecatedFields = options.GenerateDeprecatedTypes, JsonPropertyGeneration = options.JsonPropertyGeneration, CSharpVersion = options.UseNullable ? CSharpVersion.NewestWithNullableReferences : CSharpVersion.Compatible }; var schema = await SchemaConverter.ReadAsync(options.Source).ConfigureAwait(false); var generator = new GraphQlGenerator(config); var content = generator.GenerateFullClientCSharpFile(schema, options.Namespace); Console.WriteLine($"writing client-code to {options.DestinationFile}"); File.WriteAllText(options.DestinationFile, content); }
public void WithNullableReferences() { var configuration = new GraphQlGeneratorConfiguration { CSharpVersion = CSharpVersion.NewestWithNullableReferences }; var schema = DeserializeTestSchema("TestSchema2"); var stringBuilder = new StringBuilder(); var generator = new GraphQlGenerator(configuration); generator.Generate(CreateGenerationContext(stringBuilder, schema)); var expectedOutput = GetTestResource("ExpectedWithNullableReferences"); var generatedSourceCode = StripBaseClasses(stringBuilder.ToString()); generatedSourceCode.ShouldBe(expectedOutput); }
public async Task GenerateAsync() { var schema = await GraphQlGenerator.RetrieveSchema("https://*****:*****@"C:\projects\SuSoClient\Repository\src\SurveySolutionsClient\Graphql.cs", csharpCode); }
public static ScalarFieldTypeDescription GetFallbackFieldType(GraphQlGeneratorConfiguration configuration, GraphQlTypeBase valueType) { valueType = (valueType as GraphQlFieldType)?.UnwrapIfNonNull() ?? valueType; if (valueType.Kind == GraphQlTypeKind.Enum) { return new ScalarFieldTypeDescription { NetTypeName = configuration.ClassPrefix + NamingHelper.ToPascalCase(valueType.Name) + configuration.ClassSuffix + "?" } } ; var dataType = valueType.Name == GraphQlTypeBase.GraphQlTypeScalarString ? "string" : "object"; return(new ScalarFieldTypeDescription { NetTypeName = GraphQlGenerator.AddQuestionMarkIfNullableReferencesEnabled(configuration, dataType) }); } }
public void DeprecatedAttributes() { var configuration = new GraphQlGeneratorConfiguration { CSharpVersion = CSharpVersion.Newest, CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute, IncludeDeprecatedFields = true, GeneratePartialClasses = false }; var schema = DeserializeTestSchema("TestSchemaWithDeprecatedFields"); var stringBuilder = new StringBuilder(); new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, schema, GeneratedObjectType.DataClasses)); var expectedOutput = GetTestResource("ExpectedDeprecatedAttributes").Replace("\r", String.Empty); stringBuilder.ToString().Replace("\r", String.Empty).ShouldBe(expectedOutput); }
public void GenerateFormatMasks() { var configuration = new GraphQlGeneratorConfiguration { IdTypeMapping = IdTypeMapping.Custom, ScalarFieldTypeMappingProvider = TestFormatMaskScalarFieldTypeMappingProvider.Instance }; var stringBuilder = new StringBuilder(); var generator = new GraphQlGenerator(configuration); var schema = DeserializeTestSchema("TestSchema3"); generator.Generate(CreateGenerationContext(stringBuilder, schema)); var expectedDataClasses = GetTestResource("ExpectedFormatMasks"); var generatedSourceCode = StripBaseClasses(stringBuilder.ToString()); generatedSourceCode.ShouldBe(expectedDataClasses); }
public void GenerateDataClassesWithTypeConfiguration() { var configuration = new GraphQlGeneratorConfiguration { IntegerTypeMapping = IntegerTypeMapping.Int64, FloatTypeMapping = FloatTypeMapping.Double, BooleanTypeMapping = BooleanTypeMapping.Custom, IdTypeMapping = IdTypeMapping.String, GeneratePartialClasses = false, PropertyGeneration = PropertyGenerationOption.BackingField, ScalarFieldTypeMappingProvider = new TestCustomBooleanTypeMappingProvider() }; var stringBuilder = new StringBuilder(); new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.DataClasses)); var expectedDataClasses = GetTestResource("ExpectedSingleFileGenerationContext.DataClassesWithTypeConfiguration"); stringBuilder.ToString().ShouldBe(expectedDataClasses); }
public void WithUnions() { var configuration = new GraphQlGeneratorConfiguration { CSharpVersion = CSharpVersion.NewestWithNullableReferences, JsonPropertyGeneration = JsonPropertyGenerationOption.UseDefaultAlias, ScalarFieldTypeMappingProvider = TestFormatMaskScalarFieldTypeMappingProvider.Instance }; var schema = DeserializeTestSchema("TestSchemaWithUnions"); var stringBuilder = new StringBuilder(); var generator = new GraphQlGenerator(configuration); generator.Generate(CreateGenerationContext(stringBuilder, schema)); var expectedOutput = GetTestResource("ExpectedWithUnions"); var generatedSourceCode = StripBaseClasses(stringBuilder.ToString()); generatedSourceCode.ShouldBe(expectedOutput); }
public static async Task GeneratAsync(this GraphqlGeneratorConfig config) { try { GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping = (baseType, valueType, valueName) => { valueType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType; return(config.FieldTypeMappings.TryGetValue(valueType.Name, out var overrideTypeName) ? overrideTypeName : GraphQlGeneratorConfiguration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName)); }; var httpClient = new HttpClient(); if (!string.IsNullOrEmpty(config.AuthenticationHeander.Key)) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(config.AuthenticationHeander.Key, config.AuthenticationHeander.Value); } foreach (var header in config.HttpHeaders) { httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); } using var response = await httpClient.PostAsync(config.SchemaUrl, new StringContent (JsonConvert.SerializeObject(new { query = IntrospectionQuery.Text }), Encoding.UTF8, "application/json")); var schema = response.Content == null ? "(no content)" : await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { throw new InvalidOperationException($"Status code: {(int)response.StatusCode} ({response.StatusCode}); content: {schema}"); } if (config.GenerateSchema) { var formattedSchema = JToken.Parse(schema).ToString(Formatting.Indented); using var schemaWriter = File.CreateText(config.DestinationPath + "schema.graphql"); await schemaWriter.WriteAsync(formattedSchema); } var deserializedSchema = GraphQlGenerator.DeserializeGraphQlSchema(schema); var builder = new StringBuilder(); GraphQlGenerator.GenerateQueryBuilder(deserializedSchema, builder); builder.AppendLine(); builder.AppendLine(); GraphQlGenerator.GenerateDataClasses(deserializedSchema, builder); using var writer = File.CreateText(config.DestinationPath + "QueryBuilder.cs"); writer.WriteLine(RequiredNamespaces); writer.WriteLine(); writer.WriteLine($"namespace {config.Namespace}"); writer.WriteLine("{"); var indentedLines = builder .ToString() .Split(new[] { Environment.NewLine }, StringSplitOptions.None) .Select(l => $" {l}"); foreach (var line in indentedLines) { writer.WriteLine(line); } writer.WriteLine("}"); } catch (Exception e) { Console.WriteLine(e); } }
public void GeneratedQuery() { var configuration = new GraphQlGeneratorConfiguration { JsonPropertyGeneration = JsonPropertyGenerationOption.Always }; var schema = DeserializeTestSchema("TestSchema2"); var stringBuilder = new StringBuilder(); var generator = new GraphQlGenerator(configuration); generator.Generate(CreateGenerationContext(stringBuilder, schema)); stringBuilder.AppendLine(); stringBuilder.AppendLine( @"public class TestQueryBuilder : GraphQlQueryBuilder<TestQueryBuilder> { private static readonly FieldMetadata[] AllFieldMetadata = new [] { new FieldMetadata { Name = ""testField"" }, new FieldMetadata { Name = ""objectParameter"" } }; protected override string TypeName { get; } = ""Test""; public override IReadOnlyList<FieldMetadata> AllFields { get; } = AllFieldMetadata; public TestQueryBuilder WithTestField( QueryBuilderParameter<short?> valueInt16 = null, QueryBuilderParameter<ushort?> valueUInt16 = null, QueryBuilderParameter<byte?> valueByte = null, QueryBuilderParameter<int?> valueInt32 = null, QueryBuilderParameter<uint?> valueUInt32 = null, QueryBuilderParameter<long?> valueInt64 = null, QueryBuilderParameter<ulong?> valueUInt64 = null, QueryBuilderParameter<float?> valueSingle = null, QueryBuilderParameter<double?> valueDouble = null, QueryBuilderParameter<decimal?> valueDecimal = null, QueryBuilderParameter<DateTime?> valueDateTime = null, QueryBuilderParameter<DateTimeOffset?> valueDateTimeOffset = null, QueryBuilderParameter<Guid?> valueGuid = null, QueryBuilderParameter<string> valueString = null) { var args = new List<QueryBuilderArgumentInfo>(); if (valueInt16 != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueInt16"", ArgumentValue = valueInt16 }); if (valueUInt16 != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueUInt16"", ArgumentValue = valueUInt16 }); if (valueByte != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueByte"", ArgumentValue = valueByte }); if (valueInt32 != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueInt32"", ArgumentValue = valueInt32 }); if (valueUInt32 != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueUInt32"", ArgumentValue = valueUInt32 }); if (valueInt64 != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueInt64"", ArgumentValue = valueInt64 }); if (valueUInt64 != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueUInt64"", ArgumentValue = valueUInt64 }); if (valueSingle != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueSingle"", ArgumentValue = valueSingle }); if (valueDouble != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDouble"", ArgumentValue = valueDouble }); if (valueDecimal != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDecimal"", ArgumentValue = valueDecimal }); if (valueDateTime != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDateTime"", ArgumentValue = valueDateTime, FormatMask = ""yy-MM-dd HH:mmZ"" }); if (valueDateTimeOffset != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDateTimeOffset"", ArgumentValue = valueDateTimeOffset }); if (valueGuid != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueGuid"", ArgumentValue = valueGuid }); if (valueString != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueString"", ArgumentValue = valueString }); return WithScalarField(""testField"", null, null, args); } public TestQueryBuilder WithObjectParameterField(QueryBuilderParameter<object> objectParameter = null) { var args = new List<QueryBuilderArgumentInfo>(); if (objectParameter != null) args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""objectParameter"", ArgumentValue = objectParameter }); return WithScalarField(""objectParameter"", ""fieldAlias"", new GraphQlDirective[] { new IncludeDirective(new GraphQlQueryParameter<bool>(""direct"", ""Boolean"", true)), new SkipDirective((QueryBuilderParameter<bool>)false) }, args); } public TestQueryBuilder WithTestFragment(MeQueryBuilder queryBuilder) => WithFragment(queryBuilder, null); }"); const string assemblyName = "GeneratedQueryTestAssembly"; CompileIntoAssembly(stringBuilder.ToString(), assemblyName); var builderType = Type.GetType($"{assemblyName}.TestQueryBuilder, {assemblyName}"); builderType.ShouldNotBeNull(); var formattingType = Type.GetType($"{assemblyName}.Formatting, {assemblyName}"); formattingType.ShouldNotBeNull(); var builderInstance = Activator.CreateInstance(builderType); builderType .GetMethod("WithTestField", BindingFlags.Instance | BindingFlags.Public) .Invoke( builderInstance, new object[] { (short)1, (ushort)2, (byte)3, 4, (uint)5, 6L, (ulong)7, 8.123f, 9.456d, 10.789m, new DateTime(2019, 6, 30, 0, 27, 47, DateTimeKind.Utc).AddTicks(1234567), new DateTimeOffset(2019, 6, 30, 2, 27, 47, TimeSpan.FromHours(2)).AddTicks(1234567), Guid.Empty, "string value" }.Select(p => CreateParameter(assemblyName, p)).ToArray()); builderType .GetMethod("WithObjectParameterField", BindingFlags.Instance | BindingFlags.Public) .Invoke( builderInstance, new object[] { new [] { JsonConvert.DeserializeObject("{ \"rootProperty1\": \"root value 1\", \"rootProperty2\": 123.456, \"rootProperty3\": true, \"rootProperty4\": null, \"rootProperty5\": { \"nestedProperty\": 987 } }"), JsonConvert.DeserializeObject("[{ \"rootProperty1\": \"root value 2\" }, { \"rootProperty1\": false }]") } }.Select(p => CreateParameter(assemblyName, p)).ToArray()); var query = builderType .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public) .Invoke(builderInstance, new [] { Enum.Parse(formattingType, "None"), (byte)2 }); query.ShouldBe("{testField(valueInt16:1,valueUInt16:2,valueByte:3,valueInt32:4,valueUInt32:5,valueInt64:6,valueUInt64:7,valueSingle:8.123,valueDouble:9.456,valueDecimal:10.789,valueDateTime:\"19-06-30 00:27Z\",valueDateTimeOffset:\"2019-06-30T02:27:47.1234567+02:00\",valueGuid:\"00000000-0000-0000-0000-000000000000\",valueString:\"string value\"),fieldAlias:objectParameter(objectParameter:[{rootProperty1:\"root value 1\",rootProperty2:123.456,rootProperty3:true,rootProperty4:null,rootProperty5:{nestedProperty:987}},[{rootProperty1:\"root value 2\"},{rootProperty1:false}]])@include(if:$direct)@skip(if:false)}"); query = builderType .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public) .Invoke(builderInstance, new[] { Enum.Parse(formattingType, "Indented"), (byte)2 }); query.ShouldBe($" {{{Environment.NewLine} testField(valueInt16: 1, valueUInt16: 2, valueByte: 3, valueInt32: 4, valueUInt32: 5, valueInt64: 6, valueUInt64: 7, valueSingle: 8.123, valueDouble: 9.456, valueDecimal: 10.789, valueDateTime: \"19-06-30 00:27Z\", valueDateTimeOffset: \"2019-06-30T02:27:47.1234567+02:00\", valueGuid: \"00000000-0000-0000-0000-000000000000\", valueString: \"string value\"){Environment.NewLine} fieldAlias: objectParameter(objectParameter: [{Environment.NewLine} {{{Environment.NewLine} rootProperty1: \"root value 1\",{Environment.NewLine} rootProperty2: 123.456,{Environment.NewLine} rootProperty3: true,{Environment.NewLine} rootProperty4: null,{Environment.NewLine} rootProperty5: {{{Environment.NewLine} nestedProperty: 987}}}},{Environment.NewLine} [{Environment.NewLine} {{{Environment.NewLine} rootProperty1: \"root value 2\"}},{Environment.NewLine} {{{Environment.NewLine} rootProperty1: false}}]]) @include(if: $direct) @skip(if: false){Environment.NewLine}}}"); var rootQueryBuilderType = Type.GetType($"{assemblyName}.QueryQueryBuilder, {assemblyName}"); rootQueryBuilderType.ShouldNotBeNull(); var rootQueryBuilderInstance = rootQueryBuilderType.GetConstructor(new [] { typeof(string) }).Invoke(new object[1]); rootQueryBuilderType.GetMethod("WithAllFields", BindingFlags.Instance | BindingFlags.Public).Invoke(rootQueryBuilderInstance, null); rootQueryBuilderType .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public) .Invoke(rootQueryBuilderInstance, new[] { Enum.Parse(formattingType, "None"), (byte)2 }); builderType .GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public) .Invoke(builderInstance, null); var meBuilderType = Type.GetType($"{assemblyName}.MeQueryBuilder, {assemblyName}"); var childFragmentBuilderInstance = Activator.CreateInstance(meBuilderType); meBuilderType.GetMethod("WithAllScalarFields", BindingFlags.Instance | BindingFlags.Public).Invoke(childFragmentBuilderInstance, null); builderType .GetMethod("WithTestFragment", BindingFlags.Instance | BindingFlags.Public) .Invoke(builderInstance, new [] { childFragmentBuilderInstance }); query = builderType .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public) .Invoke(builderInstance, new[] { Enum.Parse(formattingType, "None"), (byte)2 }); query.ShouldBe("{...on Me{id,firstName,lastName,fullName,ssn,email,language,tone,mobile}}"); }
public override void BeforeGeneration(GraphQlGeneratorConfiguration configuration) { _enums = _directives = _queryBuilders = _dataClasses = 0; base.BeforeGeneration(configuration); }
public void MultipleFileGeneration() { var configuration = new GraphQlGeneratorConfiguration { CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute, CSharpVersion = CSharpVersion.Newest }; var generator = new GraphQlGenerator(configuration); var tempPath = Path.GetTempPath(); var directoryInfo = Directory.CreateDirectory(Path.Combine(tempPath, "GraphQlGeneratorTest")); try { var context = new MultipleFileGenerationContext(DeserializeTestSchema("TestSchema2"), directoryInfo.FullName, "GraphQlGeneratorTest", "GraphQlGeneratorTest.csproj"); generator.Generate(context); var files = directoryInfo.GetFiles().OrderBy(f => f.Name).ToArray(); var fileNames = files.Select(f => f.Name); fileNames.ShouldBe( new[] { "About.cs", "AboutItem.cs", "AboutItemQueryBuilder.cs", "AboutQueryBuilder.cs", "Address.cs", "AddressQueryBuilder.cs", "AppState.cs", "AppStateFronScreen.cs", "AppStateFronScreenMutation.cs", "AppStateFronScreenQueryBuilder.cs", "AppStateJourney.cs", "AppStateJourneyMutation.cs", "AppStateJourneyQueryBuilder.cs", "AppStateMutation.cs", "AppStateQueryBuilder.cs", "Avatar.cs", "AwayMode.cs", "AwayModeQueryBuilder.cs", "AwayModeSettings.cs", "AwayModeSettingsQueryBuilder.cs", "BaseClasses.cs", "Comparison.cs", "ComparisonData.cs", "ComparisonDataQueryBuilder.cs", "ComparisonQueryBuilder.cs", "Consumption.cs", "ConsumptionMonth.cs", "ConsumptionMonthQueryBuilder.cs", "ConsumptionQueryBuilder.cs", "CreditCard.cs", "CreditCardQueryBuilder.cs", "DayNightSchedule.cs", "DayNightScheduleQueryBuilder.cs", "DayNightScheduleSettings.cs", "DayNightScheduleSettingsQueryBuilder.cs", "Disaggregation.cs", "DisaggregationQueryBuilder.cs", "EnergyDeal.cs", "EnergyDealQueryBuilder.cs", "Feed.cs", "FeedItem.cs", "FeedItemQueryBuilder.cs", "FeedQueryBuilder.cs", "GqlMutationError.cs", "GqlMutationErrorQueryBuilder.cs", "GqlMutationGeneralResponse.cs", "GqlMutationGeneralResponseQueryBuilder.cs", "GraphQlGeneratorTest.csproj", "GraphQlTypes.cs", "Greeting.cs", "GreetingQueryBuilder.cs", "Home.cs", "HomeMutation.cs", "HomeMutationQueryBuilder.cs", "HomeProfileQuestion.cs", "HomeProfileQuestionAnswer.cs", "HomeProfileQuestionInput.cs", "HomeProfileQuestionInputQueryBuilder.cs", "HomeProfileQuestionQueryBuilder.cs", "HomeQueryBuilder.cs", "IncludeDirective.cs", "Invoice.cs", "InvoicePayment.cs", "InvoicePaymentQueryBuilder.cs", "InvoiceQueryBuilder.cs", "InvoiceSection.cs", "InvoiceSectionQueryBuilder.cs", "Me.cs", "MeMutation.cs", "MeMutationQueryBuilder.cs", "MeQueryBuilder.cs", "Mutation.cs", "MutationQueryBuilder.cs", "PairableDevice.cs", "PairableDeviceOAuth.cs", "PairableDeviceOAuthQueryBuilder.cs", "PairableDeviceQueryBuilder.cs", "PairDeviceResult.cs", "PairDeviceResultQueryBuilder.cs", "PaymentMethod.cs", "PaymentMethodQueryBuilder.cs", "PreLiveComparison.cs", "PreLiveComparisonQueryBuilder.cs", "PriceRating.cs", "PriceRatingColorOffset.cs", "PriceRatingColorOffsetQueryBuilder.cs", "PriceRatingEntry.cs", "PriceRatingEntryQueryBuilder.cs", "PriceRatingQueryBuilder.cs", "PriceRatingRoot.cs", "PriceRatingRootQueryBuilder.cs", "ProcessStep.cs", "ProcessStepQueryBuilder.cs", "Producer.cs", "ProducerBullet.cs", "ProducerBulletQueryBuilder.cs", "ProducerQueryBuilder.cs", "Production.cs", "ProductionMonth.cs", "ProductionMonthQueryBuilder.cs", "ProductionQueryBuilder.cs", "ProductionValue.cs", "ProductionValueQueryBuilder.cs", "PushNotification.cs", "PushNotificationQueryBuilder.cs", "Query.cs", "QueryQueryBuilder.cs", "Report.cs", "ReportCell.cs", "ReportCellQueryBuilder.cs", "ReportQueryBuilder.cs", "ReportRoot.cs", "ReportRootQueryBuilder.cs", "Resolution.cs", "Sensor.cs", "SensorHistory.cs", "SensorHistoryQueryBuilder.cs", "SensorHistoryValue.cs", "SensorHistoryValueQueryBuilder.cs", "SensorQueryBuilder.cs", "SignupStatus.cs", "SignupStatusQueryBuilder.cs", "SkipDirective.cs", "Subscription.cs", "SubscriptionQueryBuilder.cs", "Thermostat.cs", "ThermostatCapability.cs", "ThermostatCapabilityQueryBuilder.cs", "ThermostatMeasurement.cs", "ThermostatMeasurementQueryBuilder.cs", "ThermostatMeasurements.cs", "ThermostatMeasurementsQueryBuilder.cs", "ThermostatMode.cs", "ThermostatModeQueryBuilder.cs", "ThermostatMutation.cs", "ThermostatMutationQueryBuilder.cs", "ThermostatQueryBuilder.cs", "ThermostatState.cs", "ThermostatStateQueryBuilder.cs", "Wallet.cs", "WalletQueryBuilder.cs", "Weather.cs", "WeatherEntry.cs", "WeatherEntryQueryBuilder.cs", "WeatherQueryBuilder.cs" }); var fileSizes = files.Where(f => f.Name != "BaseClasses.cs").Select(f => f.Length); fileSizes.ShouldBe( new long[] { 370, 399, 1295, 1082, 902, 4131, 443, 493, 2056, 1831, 379, 1038, 1076, 1609, 1675, 680, 418, 1507, 422, 1334, 716, 415, 1365, 4006, 887, 686, 3557, 4906, 402, 1312, 490, 2119, 537, 2296, 1149, 6812, 371, 1153, 495, 600, 2706, 2476, 413, 1389, 385, 1215, 368, 5985, 518, 2132, 1881, 845, 7805, 803, 1454, 417, 1433, 4626, 17076, 731, 1550, 551, 2587, 9743, 896, 5100, 1025, 476, 3221, 7042, 358, 1339, 467, 425, 1445, 1890, 499, 2175, 455, 1733, 545, 2501, 691, 495, 1921, 505, 2085, 3516, 679, 3759, 512, 2080, 600, 461, 1749, 2837, 996, 719, 3864, 5591, 822, 4380, 444, 1682, 347, 1283, 588, 675, 3451, 2781, 374, 1105, 404, 513, 483, 1902, 472, 1765, 2209, 483, 2143, 706, 777, 4324, 862, 454, 1756, 796, 4433, 508, 2005, 425, 1388, 413, 2590, 4949, 510, 2124, 482, 1874, 485, 1154, 3506, 1874 }); var expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Avatar"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "Avatar.cs")).ShouldBe(expectedOutput); expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Home"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "Home.cs")).ShouldBe(expectedOutput); expectedOutput = GetTestResource("ExpectedMultipleFilesContext.IncludeDirective"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "IncludeDirective.cs")).ShouldBe(expectedOutput); expectedOutput = GetTestResource("ExpectedMultipleFilesContext.MutationQueryBuilder"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "MutationQueryBuilder.cs")).ShouldBe(expectedOutput); } finally { Directory.Delete(directoryInfo.FullName, true); } }
public void MultipleFileGeneration() { var configuration = new GraphQlGeneratorConfiguration { CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute, CSharpVersion = CSharpVersion.Newest }; var generator = new GraphQlGenerator(configuration); var tempPath = Path.GetTempPath(); var directoryInfo = Directory.CreateDirectory(Path.Combine(tempPath, "GraphQlGeneratorTest")); try { var context = new MultipleFileGenerationContext(DeserializeTestSchema("TestSchema2"), directoryInfo.FullName, "GraphQlGeneratorTest", "GraphQlGeneratorTest.csproj"); generator.Generate(context); var files = directoryInfo.GetFiles().OrderBy(f => f.Name).ToArray(); var fileNames = files.Select(f => f.Name); fileNames.ShouldBe( new[] { "About.cs", "AboutItem.cs", "AboutItemQueryBuilder.cs", "AboutQueryBuilder.cs", "Address.cs", "AddressQueryBuilder.cs", "AppState.cs", "AppStateFronScreen.cs", "AppStateFronScreenMutation.cs", "AppStateFronScreenQueryBuilder.cs", "AppStateJourney.cs", "AppStateJourneyMutation.cs", "AppStateJourneyQueryBuilder.cs", "AppStateMutation.cs", "AppStateQueryBuilder.cs", "Avatar.cs", "AwayMode.cs", "AwayModeQueryBuilder.cs", "AwayModeSettings.cs", "AwayModeSettingsQueryBuilder.cs", "BaseClasses.cs", "Comparison.cs", "ComparisonData.cs", "ComparisonDataQueryBuilder.cs", "ComparisonQueryBuilder.cs", "Consumption.cs", "ConsumptionMonth.cs", "ConsumptionMonthQueryBuilder.cs", "ConsumptionQueryBuilder.cs", "CreditCard.cs", "CreditCardQueryBuilder.cs", "DayNightSchedule.cs", "DayNightScheduleQueryBuilder.cs", "DayNightScheduleSettings.cs", "DayNightScheduleSettingsQueryBuilder.cs", "Disaggregation.cs", "DisaggregationQueryBuilder.cs", "EnergyDeal.cs", "EnergyDealQueryBuilder.cs", "Feed.cs", "FeedItem.cs", "FeedItemQueryBuilder.cs", "FeedQueryBuilder.cs", "GqlMutationError.cs", "GqlMutationErrorQueryBuilder.cs", "GqlMutationGeneralResponse.cs", "GqlMutationGeneralResponseQueryBuilder.cs", "GraphQlGeneratorTest.csproj", "GraphQlTypes.cs", "Greeting.cs", "GreetingQueryBuilder.cs", "Home.cs", "HomeMutation.cs", "HomeMutationQueryBuilder.cs", "HomeProfileQuestion.cs", "HomeProfileQuestionAnswer.cs", "HomeProfileQuestionInput.cs", "HomeProfileQuestionInputQueryBuilder.cs", "HomeProfileQuestionQueryBuilder.cs", "HomeQueryBuilder.cs", "IncludeDirective.cs", "Invoice.cs", "InvoicePayment.cs", "InvoicePaymentQueryBuilder.cs", "InvoiceQueryBuilder.cs", "InvoiceSection.cs", "InvoiceSectionQueryBuilder.cs", "Me.cs", "MeMutation.cs", "MeMutationQueryBuilder.cs", "MeQueryBuilder.cs", "Mutation.cs", "MutationQueryBuilder.cs", "PairableDevice.cs", "PairableDeviceOAuth.cs", "PairableDeviceOAuthQueryBuilder.cs", "PairableDeviceQueryBuilder.cs", "PairDeviceResult.cs", "PairDeviceResultQueryBuilder.cs", "PaymentMethod.cs", "PaymentMethodQueryBuilder.cs", "PreLiveComparison.cs", "PreLiveComparisonQueryBuilder.cs", "PriceRating.cs", "PriceRatingColorOffset.cs", "PriceRatingColorOffsetQueryBuilder.cs", "PriceRatingEntry.cs", "PriceRatingEntryQueryBuilder.cs", "PriceRatingQueryBuilder.cs", "PriceRatingRoot.cs", "PriceRatingRootQueryBuilder.cs", "ProcessStep.cs", "ProcessStepQueryBuilder.cs", "Producer.cs", "ProducerBullet.cs", "ProducerBulletQueryBuilder.cs", "ProducerQueryBuilder.cs", "Production.cs", "ProductionMonth.cs", "ProductionMonthQueryBuilder.cs", "ProductionQueryBuilder.cs", "ProductionValue.cs", "ProductionValueQueryBuilder.cs", "PushNotification.cs", "PushNotificationQueryBuilder.cs", "Query.cs", "QueryQueryBuilder.cs", "Report.cs", "ReportCell.cs", "ReportCellQueryBuilder.cs", "ReportQueryBuilder.cs", "ReportRoot.cs", "ReportRootQueryBuilder.cs", "Resolution.cs", "Sensor.cs", "SensorHistory.cs", "SensorHistoryQueryBuilder.cs", "SensorHistoryValue.cs", "SensorHistoryValueQueryBuilder.cs", "SensorQueryBuilder.cs", "SignupStatus.cs", "SignupStatusQueryBuilder.cs", "SkipDirective.cs", "Subscription.cs", "SubscriptionQueryBuilder.cs", "Thermostat.cs", "ThermostatCapability.cs", "ThermostatCapabilityQueryBuilder.cs", "ThermostatMeasurement.cs", "ThermostatMeasurementQueryBuilder.cs", "ThermostatMeasurements.cs", "ThermostatMeasurementsQueryBuilder.cs", "ThermostatMode.cs", "ThermostatModeQueryBuilder.cs", "ThermostatMutation.cs", "ThermostatMutationQueryBuilder.cs", "ThermostatQueryBuilder.cs", "ThermostatState.cs", "ThermostatStateQueryBuilder.cs", "Wallet.cs", "WalletQueryBuilder.cs", "Weather.cs", "WeatherEntry.cs", "WeatherEntryQueryBuilder.cs", "WeatherQueryBuilder.cs" }); var fileSizes = files.Where(f => f.Name != "BaseClasses.cs").Select(f => f.Length); fileSizes.ShouldBe( new long[] { 446, 475, 1371, 1158, 978, 4207, 519, 569, 2132, 1907, 455, 1114, 1152, 1685, 1751, 756, 494, 1583, 498, 1410, 792, 491, 1441, 4082, 963, 762, 3633, 4982, 478, 1388, 566, 2195, 613, 2372, 1225, 6888, 447, 1229, 571, 676, 2782, 2552, 489, 1465, 461, 1291, 368, 6061, 594, 2208, 1957, 921, 7881, 879, 1530, 493, 1509, 4702, 17152, 807, 1626, 627, 2663, 9819, 972, 5176, 1101, 552, 3297, 7118, 434, 1415, 543, 501, 1521, 1966, 575, 2251, 531, 1809, 621, 2577, 767, 571, 1997, 581, 2161, 3592, 755, 3835, 588, 2156, 676, 537, 1825, 2913, 1072, 795, 3940, 5667, 898, 4456, 520, 1758, 423, 1359, 664, 751, 3527, 2857, 450, 1181, 480, 589, 559, 1978, 548, 1841, 2285, 559, 2219, 782, 853, 4400, 938, 530, 1832, 872, 4509, 584, 2081, 501, 1464, 489, 2666, 5025, 586, 2200, 558, 1950, 561, 1230, 3582, 1950 }); var expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Avatar"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "Avatar.cs")).ShouldBe(expectedOutput); expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Home"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "Home.cs")).ShouldBe(expectedOutput); expectedOutput = GetTestResource("ExpectedMultipleFilesContext.IncludeDirective"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "IncludeDirective.cs")).ShouldBe(expectedOutput); expectedOutput = GetTestResource("ExpectedMultipleFilesContext.MutationQueryBuilder"); File.ReadAllText(Path.Combine(directoryInfo.FullName, "MutationQueryBuilder.cs")).ShouldBe(expectedOutput); } finally { Directory.Delete(directoryInfo.FullName, true); } }
public void GenerateDataClassesWithTypeConfiguration() { GraphQlGeneratorConfiguration.IntegerTypeMapping = IntegerTypeMapping.Int64; GraphQlGeneratorConfiguration.FloatTypeMapping = FloatTypeMapping.Double; GraphQlGeneratorConfiguration.BooleanTypeMapping = BooleanTypeMapping.Custom; GraphQlGeneratorConfiguration.IdTypeMapping = IdTypeMapping.String; GraphQlGeneratorConfiguration.GeneratePartialClasses = false; GraphQlGeneratorConfiguration.PropertyGeneration = PropertyGenerationOption.BackingField; GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping = (baseType, valueType, valueName) => valueType.Name == "Boolean" ? "bool" : GraphQlGeneratorConfiguration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName); var stringBuilder = new StringBuilder(); GraphQlGenerator.GenerateDataClasses(TestSchema, stringBuilder); var expectedDataClasses = GetTestResource("ExpectedDataClassesWithTypeConfiguration"); stringBuilder.ToString().ShouldBe(expectedDataClasses); }
public void Execute(GeneratorExecutionContext context) { if (context.Compilation is not CSharpCompilation compilation) { context.ReportDiagnostic( Diagnostic.Create( DescriptorParameterError, Location.None, "incompatible language: " + context.Compilation.Language)); return; } try { context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "ServiceUrl", out var serviceUrl); var isServiceUrlMissing = String.IsNullOrWhiteSpace(serviceUrl); var graphQlSchemaFiles = context.AdditionalFiles.Where(f => Path.GetFileName(f.Path).EndsWith(".gql.schema.json", StringComparison.OrdinalIgnoreCase)).ToList(); var indexRegexScalarFieldTypeMappingProviderConfigurationFile = graphQlSchemaFiles.FindIndex(f => String.Equals(Path.GetFileName(f.Path), FileNameRegexScalarFieldTypeMappingProviderConfiguration, StringComparison.OrdinalIgnoreCase)); ICollection <RegexScalarFieldTypeMappingRule> regexScalarFieldTypeMappingProviderRules = null; if (indexRegexScalarFieldTypeMappingProviderConfigurationFile != -1) { regexScalarFieldTypeMappingProviderRules = JsonConvert.DeserializeObject <ICollection <RegexScalarFieldTypeMappingRule> >( graphQlSchemaFiles[indexRegexScalarFieldTypeMappingProviderConfigurationFile].GetText().ToString()); graphQlSchemaFiles.RemoveAt(indexRegexScalarFieldTypeMappingProviderConfigurationFile); } var isSchemaFileSpecified = graphQlSchemaFiles.Any(); if (isServiceUrlMissing && !isSchemaFileSpecified) { context.ReportDiagnostic( Diagnostic.Create( DescriptorInfo, Location.None, "Neither \"GraphQlClientGenerator_ServiceUrl\" parameter nor GraphQL JSON schema additional file specified; terminating. ")); return; } if (!isServiceUrlMissing && isSchemaFileSpecified) { context.ReportDiagnostic( Diagnostic.Create( DescriptorParameterError, Location.None, "\"GraphQlClientGenerator_ServiceUrl\" parameter and GraphQL JSON schema additional file are mutually exclusive. ")); return; } context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "Namespace", out var @namespace); if (String.IsNullOrWhiteSpace(@namespace)) { var root = (CompilationUnitSyntax)compilation.SyntaxTrees.FirstOrDefault()?.GetRoot(); var namespaceIdentifier = (IdentifierNameSyntax)root?.Members.OfType <NamespaceDeclarationSyntax>().FirstOrDefault()?.Name; if (namespaceIdentifier == null) { context.ReportDiagnostic( Diagnostic.Create( DescriptorParameterError, Location.None, "\"GraphQlClientGenerator_Namespace\" required")); return; } @namespace = namespaceIdentifier.Identifier.ValueText; context.ReportDiagnostic( Diagnostic.Create( DescriptorInfo, Location.None, $"\"GraphQlClientGenerator_Namespace\" not specified; using \"{@namespace}\"")); } var configuration = new GraphQlGeneratorConfiguration { TreatUnknownObjectAsScalar = true }; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "ClassPrefix", out var classPrefix); configuration.ClassPrefix = classPrefix; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "ClassSuffix", out var classSuffix); configuration.ClassSuffix = classSuffix; if (compilation.LanguageVersion >= LanguageVersion.CSharp6) { configuration.CSharpVersion = compilation.Options.NullableContextOptions == NullableContextOptions.Disable ? CSharpVersion.Newest : CSharpVersion.NewestWithNullableReferences; } var currentParameterName = "IncludeDeprecatedFields"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var includeDeprecatedFieldsRaw); configuration.IncludeDeprecatedFields = !String.IsNullOrWhiteSpace(includeDeprecatedFieldsRaw) && Convert.ToBoolean(includeDeprecatedFieldsRaw); currentParameterName = "HttpMethod"; if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var httpMethod)) { httpMethod = "POST"; } currentParameterName = "CommentGeneration"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var commentGenerationRaw); configuration.CommentGeneration = String.IsNullOrWhiteSpace(commentGenerationRaw) ? CommentGenerationOption.CodeSummary : (CommentGenerationOption)Enum.Parse(typeof(CommentGenerationOption), commentGenerationRaw, true); currentParameterName = "FloatTypeMapping"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var floatTypeMappingRaw); configuration.FloatTypeMapping = String.IsNullOrWhiteSpace(floatTypeMappingRaw) ? FloatTypeMapping.Decimal : (FloatTypeMapping)Enum.Parse(typeof(FloatTypeMapping), floatTypeMappingRaw, true); currentParameterName = "BooleanTypeMapping"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var booleanTypeMappingRaw); configuration.BooleanTypeMapping = String.IsNullOrWhiteSpace(booleanTypeMappingRaw) ? BooleanTypeMapping.Boolean : (BooleanTypeMapping)Enum.Parse(typeof(BooleanTypeMapping), booleanTypeMappingRaw, true); currentParameterName = "IdTypeMapping"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var idTypeMappingRaw); configuration.IdTypeMapping = String.IsNullOrWhiteSpace(idTypeMappingRaw) ? IdTypeMapping.Guid : (IdTypeMapping)Enum.Parse(typeof(IdTypeMapping), idTypeMappingRaw, true); currentParameterName = "JsonPropertyGeneration"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var jsonPropertyGenerationRaw); configuration.JsonPropertyGeneration = String.IsNullOrWhiteSpace(jsonPropertyGenerationRaw) ? JsonPropertyGenerationOption.CaseInsensitive : (JsonPropertyGenerationOption)Enum.Parse(typeof(JsonPropertyGenerationOption), jsonPropertyGenerationRaw, true); currentParameterName = "EnumValueNaming"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var enumValueNamingRaw); configuration.EnumValueNaming = String.IsNullOrWhiteSpace(enumValueNamingRaw) ? EnumValueNamingOption.CSharp : (EnumValueNamingOption)Enum.Parse(typeof(EnumValueNamingOption), enumValueNamingRaw, true); currentParameterName = "CustomClassMapping"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var customClassMappingRaw); if (!KeyValueParameterParser.TryGetCustomClassMapping( customClassMappingRaw?.Split(new[] { '|', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries), out var customMapping, out var customMappingParsingErrorMessage)) { context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, customMappingParsingErrorMessage)); return; } foreach (var kvp in customMapping) { configuration.CustomClassNameMapping.Add(kvp); } currentParameterName = "Headers"; context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var headersRaw); if (!KeyValueParameterParser.TryGetCustomHeaders( headersRaw?.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries), out var headers, out var headerParsingErrorMessage)) { context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, headerParsingErrorMessage)); return; } currentParameterName = "ScalarFieldTypeMappingProvider"; if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var scalarFieldTypeMappingProviderName)) { if (regexScalarFieldTypeMappingProviderRules != null) { context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, "\"GraphQlClientGenerator_ScalarFieldTypeMappingProvider\" and RegexScalarFieldTypeMappingProviderConfiguration are mutually exclusive")); return; } if (String.IsNullOrWhiteSpace(scalarFieldTypeMappingProviderName)) { context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, "\"GraphQlClientGenerator_ScalarFieldTypeMappingProvider\" value missing")); return; } var scalarFieldTypeMappingProviderType = Type.GetType(scalarFieldTypeMappingProviderName); if (scalarFieldTypeMappingProviderType == null) { context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, $"ScalarFieldTypeMappingProvider \"{scalarFieldTypeMappingProviderName}\" not found")); return; } var scalarFieldTypeMappingProvider = (IScalarFieldTypeMappingProvider)Activator.CreateInstance(scalarFieldTypeMappingProviderType); configuration.ScalarFieldTypeMappingProvider = scalarFieldTypeMappingProvider; } else if (regexScalarFieldTypeMappingProviderRules?.Count > 0) { configuration.ScalarFieldTypeMappingProvider = new RegexScalarFieldTypeMappingProvider(regexScalarFieldTypeMappingProviderRules); } var graphQlSchemas = new List <(string TargetFileName, GraphQlSchema Schema)>(); if (isSchemaFileSpecified) { foreach (var schemaFile in graphQlSchemaFiles) { var targetFileName = Path.GetFileNameWithoutExtension(schemaFile.Path) + ".cs"; graphQlSchemas.Add((targetFileName, GraphQlGenerator.DeserializeGraphQlSchema(schemaFile.GetText().ToString()))); } } else { graphQlSchemas.Add((FileNameGraphQlClientSource, GraphQlGenerator.RetrieveSchema(new HttpMethod(httpMethod), serviceUrl, headers).GetAwaiter().GetResult())); context.ReportDiagnostic( Diagnostic.Create( DescriptorInfo, Location.None, "GraphQl schema fetched successfully from " + serviceUrl)); } var generator = new GraphQlGenerator(configuration); foreach (var(targetFileName, schema) in graphQlSchemas) { var builder = new StringBuilder(); using (var writer = new StringWriter(builder)) generator.WriteFullClientCSharpFile(schema, @namespace, writer); context.AddSource(targetFileName, SourceText.From(builder.ToString(), Encoding.UTF8)); } context.ReportDiagnostic( Diagnostic.Create( DescriptorInfo, Location.None, "GraphQlClientGenerator task completed successfully. ")); } catch (Exception exception) { context.ReportDiagnostic(Diagnostic.Create(DescriptorGenerationError, Location.None, exception.Message)); } }
public static async Task <IReadOnlyCollection <FileInfo> > GenerateClientSourceCode(ProgramOptions options) { var isServiceUrlMissing = String.IsNullOrWhiteSpace(options.ServiceUrl); if (isServiceUrlMissing && String.IsNullOrWhiteSpace(options.SchemaFileName)) { System.Console.WriteLine("ERROR: Either \"serviceUrl\" or \"schemaFileName\" parameter must be specified. "); Environment.Exit(4); } if (!isServiceUrlMissing && !String.IsNullOrWhiteSpace(options.SchemaFileName)) { System.Console.WriteLine("ERROR: \"serviceUrl\" and \"schemaFileName\" parameters are mutually exclusive. "); Environment.Exit(5); } GraphQlSchema schema; if (isServiceUrlMissing) { schema = GraphQlGenerator.DeserializeGraphQlSchema(await File.ReadAllTextAsync(options.SchemaFileName)); } else { if (!KeyValueParameterParser.TryGetCustomHeaders(options.Headers, out var headers, out var headerParsingErrorMessage)) { System.Console.WriteLine("ERROR: " + headerParsingErrorMessage); Environment.Exit(3); } schema = await GraphQlGenerator.RetrieveSchema(options.ServiceUrl, headers); } var generatorConfiguration = new GraphQlGeneratorConfiguration { CSharpVersion = options.CSharpVersion, ClassPrefix = options.ClassPrefix, ClassSuffix = options.ClassSuffix, GeneratePartialClasses = options.PartialClasses, MemberAccessibility = options.MemberAccessibility, IdTypeMapping = options.IdTypeMapping, FloatTypeMapping = options.FloatTypeMapping, JsonPropertyGeneration = options.JsonPropertyAttribute }; if (!KeyValueParameterParser.TryGetCustomClassMapping(options.ClassMapping, out var customMapping, out var customMappingParsingErrorMessage)) { System.Console.WriteLine("ERROR: " + customMappingParsingErrorMessage); Environment.Exit(3); } foreach (var kvp in customMapping) { generatorConfiguration.CustomClassNameMapping.Add(kvp); } var generator = new GraphQlGenerator(generatorConfiguration); if (options.OutputType == OutputType.SingleFile) { await File.WriteAllTextAsync(options.OutputPath, generator.GenerateFullClientCSharpFile(schema, options.Namespace)); return(new[] { new FileInfo(options.OutputPath) }); } var multipleFileGenerationContext = new MultipleFileGenerationContext(schema, options.OutputPath, options.Namespace); generator.Generate(multipleFileGenerationContext); return(multipleFileGenerationContext.Files); }
public GraphQlGeneratorTest(ITestOutputHelper outputHelper) { _outputHelper = outputHelper; GraphQlGeneratorConfiguration.Reset(); }
public virtual void BeforeGeneration(GraphQlGeneratorConfiguration configuration) => Configuration = configuration;